
Arabic: 
[MUSIC PLAYING]
[MUSIC - FERGIE & Q TIP & GOONROCK,
"A LITTLE PARTY NEVER KILLED NOBODY"]
FERGIE & Q-TIP & GOONROCK:
(SINGING) ليلة واحدة فقط،
هي كل ما لدينا، ليلة واحدة فقط، هي كل
كل ما لدينا، ليلة واحدة فقط ، هي كل ما
لدينا، ليلة واحدة فقط، هي كل ما لدينا.

English: 
[MUSIC PLAYING]
[MUSIC - FERGIE & Q TIP & GOONROCK,
"A LITTLE PARTY NEVER KILLED NOBODY"]
FERGIE & Q-TIP & GOONROCK:
(SINGING) Just one night,
all we got, just one nigh, all
we got, just one night, all we
got, just one night, all we got.

Arabic: 
حفلة صغيرة لم تقتل أحدًا.
لذلك سنرقص
حتى ننسى، ننسى، ننسى.
امم، حفلة صغيرة لم تقتل أحدًا.
هنا الآن، هنا الآن، هي كل ما
لدينا. سكيتن-بود-أوب-بوب.
[MUSIC - FERGIE & Q TIP &
GOONROCK, "A LITTLE PARTY
NEVER KILLED NOBODY"]
(SINGING) حفلة صغيرة
لم تقتل أحدًا.
لذلك سنرقص حتى ننسى.
هيا بنا.
حفلة صغيرة لم تقتل أحدًا.
هنا الآن، هي كل ما لدينا.
أوه، حفلة صغيرة لم تقتل أحدًا.
لذلك سنرقص حتى ننسى.
حفلة صغيرة لم تقتل أحدًا.

English: 
A little party never killed nobody.
So we going to dance
until we drop, drop, drop.
Mm, a little party never killed nobody.
Right here, right now, is all
we got. skeeten-bod-op-bop.
[MUSIC - FERGIE & Q TIP &
GOONROCK, "A LITTLE PARTY
NEVER KILLED NOBODY"]
(SINGING) A little party
never killed nobody.
So we're going to dance until we drop.
Let's go.
A little party never killed nobody.
Right here, right now is all we got.
Oh, a little party never killed nobody.
So we're going to dance until we drop.
A little party never killed nobody.

Arabic: 
[MUSIC - FERGIE & Q TIP &
GOONROCK, "A LITTLE PARTY
NEVER KILLED NOBODY"]
الدمية: [SNORING]
ديفيد ج. مالان: حسنًا.
هذه هي دورة CS50، وهذه هي المحاضرة 8.
وتلك كانت نظرة على ما يُسمى 
بالهاكاثون الخاص بدورة CS50، هذا التقليد السنوي
الذي ننهي به الفصل الدراسي تقريبًا
والذي سيبدأ حوالي الساعة 7:00 مساءً هنا
في كامبريدج، وسينتهي حوالي الساعة
7 صباحًا من اليوم التالي في كامبريدج.
ويتخلل الأمسية
قدر لا بأس به من العمل
على المشاريع النهائية، وهو 
الهدف الأسمى من الأمسية
لمنح الطلاب،
بيئة أكاديمية
واجتماعية وتعاونية
للغاية حيث يتناولون
إنجازاتهم النهائية في الدورة.
ولكن أيضًا، كما لاحظتم سيكون
هناك القليل من اللهو، والطعام
من مطاعم فيليبز، عادةً، حوالي الساعة 9:00
مساءً، وقليلاً من دومينوز بيتزا
حوالي الساعة 1:00 صباحًا.

English: 
[MUSIC - FERGIE & Q TIP &
GOONROCK, "A LITTLE PARTY
NEVER KILLED NOBODY"]
MUPPET: [SNORING]
DAVID J. MALAN: All right.
This is CS50, and this is lecture 8.
And that was a look at the so-called
CS50 hackathon, this annual tradition
with which we nearly end the semester
that will start around 7:00 PM here
in Cambridge, will then end around
7:00 AM the next day in Cambridge.
And punctuating the evening
will be quite a bit of work
on final projects, which is the
overarching goal of the evening
to give students, both
an academic and a very
social and collaborative
environment in which to tackle
their final achievements in the course.
But also, as you gleaned there will
be a bit of distraction, a bit of food
from Felipe's, typically, around 9:00
PM, a little bit of Domino's Pizza
around 1:00 AM.

Arabic: 
وبالنسبة لهؤلاء الذين ما زالوا صامدين
كالدمية هناك،
سندعوكم إلى وجبة الإفطار في
IHOP إذا ما تزال لديكم الطاقة.
بعد ذلك، سنتواجد فيما يُسمى
بمعرض CS50، ذروة كل شيء
قمتم به في دورة CS50.
والمزيد حول ذلك في الأسابيع القادمة.
لن أسترسل وأضجركم بكثرة الكلام، ما الذي
تحدّثنا عنه في هذه الأسابيع القليلة الماضية؟
حسنًا، تذكرون أنه، على
مدار الأسبوعين الماضيين،
قمنا بتقديم ​​برمجة الويب.
وفي الآونة الأخيرة، حاولنا
ربط العديد من الموضوعات معًا
من الأسابيع القليلة الماضية.
HTML وCSS وJavaScript، ومن ثم
Python، ثم إطار عمل آخر،
جزء آخر من البرامج
يُسمى Flask والذي
جعل إنشاء تطبيقات قائمة
على الويب تحديدًا أمرًا سهلاً وممكنًا بشكل أكبر.
والمثال الأبسط 
لذلك الأسبوع الماضي، تذكرون،
بدا إلى حد ما شيئًا كهذا.
وقمتم في هذا الأسبوع الماضي مع
المشاكل في أوجه التشابه والاستقصاء،
ببناء تطبيقاتكم القائمة على الويب.
لكنها لا تحتوي 
إلى حد ما على جميع الأجزاء
التي قد ترغبون في
تجمعيها في تطبيق قائم على الويب.
ولذلك فاليوم، سنملأ
تلك الفراغات النهائية.
لكن تذكرون أننا نحاول
وضع أُطُر لهذه التطبيقات، ليس
كأشياء منفردة أو فقط أدوات
قمتم بإنشائها، ولكن كجزء
من نموذج شائع أو منهجية.
وبالفعل، عندما تتعلمون
علوم الكمبيوتر وهندسة

English: 
And for those still standing
as in the muppet there,
we'll treat you to breakfast at
IHOP if you still have the energy.
Thereafter, we'll be the so-called
CS50 Fair, the climax of everything
that you've done in CS50.
And more on that in the weeks to come.
So without further ado, where have
we been these past several weeks?
Well, recall that, over
the past couple of weeks,
we've been introducing web programming.
And most recently, did we try to
tie together a lot of the topics
from the past few weeks.
HTML and CSS and JavaScript, and then
Python, and then another framework,
another piece of software
called Flask that
just made it easier and more possible
to build web-based applications.
And the simplest example
of that last week, recall,
looked a little something like this.
And this past week with the
problems on similarities and survey,
have you been building your
own web-based applications.
But they haven't quite
had all of the pieces
that you might want to
assemble into a web-based app.
And so today, we'll fill
in those final blanks.
But recall that we've been trying
to frame these applications, not
as one-offs or just tools
that you built, but as part
of a common paradigm or a methodology.
And indeed, when you're learning
computer science and software

English: 
engineering, you start to
notice patterns in the software,
in the code that you're writing.
And humans tend to adopt these
patterns because they save you time.
And then everyone can speak
the same language, so to speak.
So MVC was the acronym we introduced
last week, Model View Controller.
And that just speaks to
this paradigm whereby
you organized certain type of code in
one file, certain types of other code
and another file.
So your Python code
goes in application.py.
Your HTML goes in your HTML files, your
CSS in your CSS files, and so forth.
But what we didn't have last
week was this thing here, really.
Model generally refers to your data.
And while survey, your
most recent problem,
did have data, a CSV file
that's arguably a model,
CSV is not terribly expressive.
You can pretty much just write rows to
a text file, not unlike a spreadsheet.
But you can't really query it.
You can't easily insert or delete.
You pretty much would have to
reconstruct the whole file.
And indeed, that's exactly
what I did back in the day.
The very first web-based application I
wrote back in sophomore or junior year
was the freshman intramural website.

Arabic: 
البرمجيات، ستبدؤون
ملاحظة الأنماط في البرامج،
في التعليمة البرمجية التي تكتبونها.
ويميل الأشخاص إلى تبنّي هذه
الأنماط لأنها توفر لكم الوقت.
ومن ثم يمكن لأي شخص أن يتحدث
اللغة نفسها، إذا جاز التعبير.
إذن كان MVC هو الاختصار الذي قدمناه
الأسبوع الماضي، النموذج والعرض ووحدة التحكم.
وهذا فقط يتحدث إلى
هذا النموذج حيث
قمتم بتنظيم نوع معين من تعليمة برمجية في
ملف واحد، وأنواع معينة من تعليمة برمجية أخرى
وملف آخر.
إذن تنتقل تعليمة Python البرمجية
الخاصة بكم إلى application.py.
تنتقل HTML إلى ملفات HTML الخاصة بكم،
وCSS إلى ملفات CSS الخاصة بكم، وهكذا.
ولكن ما لم يكن لدينا في
الأسبوع الماضي هو هذا الشيء هنا، بالفعل.
يشير النموذج إلى بياناتكم بشكل عام.
وبينما كان الاستقصاء، الذي
يعدّ هو مشكلتكم الأخيرة،
يحتوي على بيانات، عبارة عن ملف CSV
يمكن القول إنه عبارة عن نموذج،
إلا أن CSV ليس معبرًا للغاية.
يمكنكم فقط كتابة الصفوف إلى حد كبير إلى
ملف نصي، لا يختلف عن جدول البيانات.
لكن لا يمكنكم حقًا الاستعلام عنها.
لا يمكنكم إدراجها أو حذفها بسهولة.
يجب أن تعيدوا إلى حد كبير 
بناء الملف بالكامل.
وبالفعل، هذا بالضبط
ما فعلته سابقًا.
كان أول تطبيق قائم على الويب
كتبتُه في السنة الثانية أو السنة الثالثة
الجامعية هو موقع الويب الداخلي للطلاب الجدد.

English: 
And all I had available to me, both
technologically and conceptually,
we're CSV files.
I had no idea what databases were,
didn't realize how much easier they
could make my life.
So I stored all of the data
behind these links here just
in very simple text files.
But today, will give
you so much more power.
And especially, if you're coming
into the class with an interest
in applying CS to other
fields in medicine or the arts
or any world in which
there's data, particularly,
in STEM and data science
and the like, realize
that SQL has really become this
incredibly powerful language
with which to solve problems
in those and so many domains.
And ultimately, what your
build, this coming week--
your very last CS50 problem set--
you have now peaked just
about-- will be CD50
Finance, a web-based application
by which you can buy,
or "buy" and sell stocks.
And so what you're going to do
this coming week is write code
that implements a web application
that resembles this whereby
your users and yourself will be
able to register for an account,
log into that account.

Arabic: 
وكل ما كان متاحًا لي، من الناحية
التقنية والنظرية،
هو ملفات CSV.
لم تكن لديّ أي فكرة عن قواعد البيانات،
لم أدرك كيف يمكنها
أن تجعل حياتي أسهل بكثير.
لذلك قمتُ بتخزين جميع البيانات
خلف هذه الروابط هنا تحديدًا
في ملفات نصية بسيطة للغاية.
لكن اليوم، سنمنحكم
قوة أكبر بكثير.
وبشكل خاص، إذا كنتم قادمين
إلى الصف مهتمين بأمر
تطبيق CS في حقول
أخرى في الطب أو الفنون
أو أي عالم يوجد
به بيانات، بشكل خاص،
في STEM وعلوم البيانات
وما شابه ذلك، فأدركوا
أن SQL أصبحت بالفعل تلك
اللغة القوية بشكل لا يصدق
التي نحل المشاكل بها
في تلك المجالات ومجالات كثيرة جدًا.
وفي النهاية، ستكون البنية الخاصة بكم،
في هذا الأسبوع القادم--
وهي آخر مجموعة مشاكل CS50 لديكم--
التي وصلتم الآن إلى ذروتها تقريبًا--
هي CD50
Finance، وهو تطبيق قائم على الويب
يمكنكم بواسطته شراء الأسهم،
أو "شراء" الأسهم وبيعها.
ولذا ما ستقومون به في
الأسبوع القادم هو كتابة تعليمة برمجية
تنفذ تطبيق ويب
يشبه هذا حيث
سيكون بمقدوركم أنتم والمستخدمين لديكم
التسجيل للحصول على حساب،
وتسجيل الدخول إلى ذلك الحساب.

Arabic: 
سيتم منحكم إياه مجانًا، وذلك 
بفضلنا، 10000 دولار افتراضية.
ومن ثم يمكنكم المضي قدمًا وشراء
الأسهم وبيعها عبر الرمز الخاص بها
باستخدام هذا التطبيق.
إذن على سبيل المثال، إذا مضيتُ قدمًا
وقمتُ بتسجيل نفسي هنا.
لنقل، اسم المستخدم
مالان، كلمة المرور 12345--
لا يجب أن أقول ذلك.
وأمضي قدمًا وأقوم بالتسجيل هنا.
سترون ذلك، بشكل افتراضي، حصلتُ على
10 آلاف دولار المجانية هذه كنقود افتراضية.
أتعلمون ماذا، سأمضي
قدمًا وأشتري بنفسي
سهمًا ربما من Netflix،
ورمزها هو NFLX.
سأمضي قدمًا
وأحاول شراء سهم واحد.
ها هو ذا.
والآن سترون أنه، فقط ليست لديّ
نقود قليلة متبقية، حوالي 9600 دولار أمريكي،
الآن أمتلك سهمًا.
وإذا قمنا بإعادة تحميل ذلك 
على مدار المحاضرة، بصراحة،
قد يرتفع السعر
قليلاً أو ينخفض قليلاً
لأن تطبيق الويب
هذا الذي ستقومون بإنشائه
سيتحدّث أيضًا إلى API،
وهي واجهة برمجة التطبيقات--
إذن بعض مواقع ويب الجهة الخارجية التي
توفر لكم بيانات الأسهم.
لذلك تطلبون منها 
السعر الحالي للسهم.
تمنحنكم إجابة
بتنسيق JSON، إذا كنتم
تذكرون مناقشتنا القصيرة حول ذلك.
وستقومون بدمجها،
في النهاية، في هذه الواجهة.

English: 
You'll be given for free, thanks
to us, 10,000 virtual dollars.
And then you can go ahead and buy
and sell stocks via their symbol
using this application.
So for instance, if I go ahead
and register myself here.
Let's say, username
Malan, password 12345--
shouldn't have said that.
Go ahead and register here.
You'll see that, by default, I get
this free $10,000 in virtual cash.
You know what, I'm going
to go ahead and buy myself
a share of maybe Netflix,
whose symbol is NFLX.
I'm going to go ahead
and try to buy one share.
Voila.
And now you'll see that, not only do
I have less cash left, about $9,600,
I now own a share of stock.
And if we reload this
throughout the lecture, frankly,
the price might go a
little up or a little down
because this web
application you'll build
will also talk to an API, an
Application Programming Interface--
so some third-party website that
provides you with stock data.
So you ask it for the
current price of a stock.
It gives you an answer
in JSON format, if you
recall our short discussion of that.
And you'll integrate it,
ultimately, into this interface.

English: 
So this will be the culmination
of so many of the ideas
and the building blocks with
which you've experimented.
But we need a few final pieces today.
So first and foremost, when I registered
for this site, I created an account.
And indeed, I can go
ahead and log out now.
And if I go ahead and log back in--
if no one's stolen my password yet, I
can see my account and only my account.
But we haven't yet seen
any mechanism in code
whereby you can implement this
notion of logging in, right?
What is the underlying logic via which
a website knows that you are logged in
or you're not logged in, right?
Clearly, when I went to this
website just a moment ago,
it prompted me to log in because I
was not because I had logged out.
But how did it know that?
And now that I am logged in, how does
it know that I can click on "quote"
to get just the stock quote or
"buy" just to buy a stock or "sell."
Why does it not prompt me every
time I click a link to log back
in with my username or password?
What do you think?
AUDIENCE: Isn't cookies
little files that

Arabic: 
إذن سيكون ذلك تتويجًا
لكثير من الأفكار
والكتل البنائية التي 
قد قمتم بتجربتها.
لكننا نحتاج إلى بعض الأجزاء النهائية اليوم.
إذن أولاً وقبل كل شيء ، عندما قمتُ بالتسجيل
في هذا الموقع، وقمتُ بإنشاء حساب.
وبالفعل، يمكنني المضي
قدمًا وتسجيل الخروج الآن.
وإذا مضيتُ قدمًا وقمتُ بتسجيل الدخول مجددًا--
إذا لم يسرق أحد كلمة المرور الخاصة بي حتى الآن، 
يمكنني رؤية حسابي وحسابي فقط.
لكننا لم نرَ بعد
أي آلية في التعليمة البرمجية
حيث يمكنكم تنفيذ فكرة
تسجيل الدخول هذه، أليس كذلك؟
ما هو المنطق الأساسي الذي يعرف من خلاله
موقع ويب أنكم تقومون بتسجيل الدخول
أو أنكم لا تقومون بتسجيل الدخول، أليس كذلك؟
بوضوح، عندما انتقلتُ إلى هذا
الموقع منذ لحظات،
طلب مني تسجيل الدخول لأنني
لم أكن لأنني قمتُ بتسجيل الخروج.
لكن كيف عرف ذلك؟
والآن بعد أن قمتُ بتسجيل الدخول، كيف
يعرف أنه يمكنني النقر فوق "علامة اقتباس"
للحصول فقط على علامة اقتباس السهم أو
"شراء" فقط لشراء سهم أو "بيعه."
لماذا لا يطلب مني كل مرة
أن أنقر فوق رابط تسجيل الدخول مجددًا
باستخدام اسم المستخدم أو كلمة المرور الخاصة بي؟
ما هو رأيكم؟
الجمهور: أليست ملفات تعريف
الارتباط الصغيرة التي

Arabic: 
تحفظ البيانات داخل ذاكرة التخزين المؤقت
الخاصة بمتصفحك وتتيح له معرفة ما يحدث.
ديفيد ج. مالان: أجل، ملفات تعريف الارتباط--
الملفات الصغيرة التي يتم حفظها
بواسطة مواقع الويب على جهاز الكمبيوتر الخاص بكم.
الآن احتمالات هي، من المحتمل أن الجميع تقريبًا هنا
قد سمعوا بشكل ما،
أن ملفات تعريف الارتباط-- سيئة.
ربما سيئة، تخترق الخصوصية، صحيح؟
حسنًا.
صحيح جدًا.
ولكن لن يعمل معظم ما على الويب
بدونها.
إذن شخص آخر، ما الذي تعرفونه عن
ماهية ملف تعريف ارتباط؟
ما هو ملف تعريف الارتباط؟
الجمهور: يحفظ معلوماتك
بشكل أساسي
وبذلك لا يجب أن
تضعها في كل مرة.
ديفيد ج. مالان: أجل.
إنه يحفظ معلوماتكم وبذلك
لا يجب أن تضعوها في كل مرة.
إذن في أبسط أشكاله، هو بالضبط
مزيج من تلك الإجابات.
حيث عندما أقوم بتسجيل الدخول إلى
موقع ويب، يمكنكم
أن تخيلوا أن موقع الويب فقط يتذكر
اسم المستخدم وكلمة المرور
فقط عن طريق حفظهم في
ملف صغير على جهاز Mac أو جهاز الكمبيوتر الشخصي
بحيث في المرة القادمة
التي أزور فيها صفحة ويب،
تقوم فقط بإرسالها تلقائيًا
من أجلي، وبذلك لا يجب أن
أكتبها مرارًا وتكرارًا.
الآن دعونا نعثر على خطأ في ذلك.
يبدو أنه سينجح، ولكن ما هو
الجانب السلبي من هذا التنفيذ الساذج؟
ما الذي تعتقدونه بشكل بديهي؟
الجمهور: البيانات فقط موجودة هناك؟
ديفيد ج. مالان: البيانات فقط
موجودة هناك، أليس كذلك؟

English: 
saves the data inside your browser's
cache that let it know what's going on.
DAVID J. MALAN: Yeah, cookies--
little files that get saved
by websites on your computer.
Now odds are, most everyone here
has probably heard in some form,
cookies-- bad.
Maybe bad, privacy-invading, yes?
OK.
So true.
But most of the web would
not work without them.
So someone else, what do you
understand a cookie to be?
What is a cookie?
AUDIENCE: Basically
saves your information
so you don't have to
put it in every time.
DAVID J. MALAN: Yeah.
It saves your information so you
don't have to put it in every time.
So in simplest form, it's exactly
a combination of those answers.
Whereby, when I log into
a website, you could
imagine that website just remembering
my username and my password
by just saving them in a
little file on my Mac or PC
so that the next time
I visit a web page,
it just automatically sends them
for me, so that the human doesn't
have to type them again and again.
Now let's find fault with that.
Feels like that would work, but what's
a downside of that naive implementation?
What do you think instinctively?
AUDIENCE: The data is just out there?
DAVID J. MALAN: The data
is just out there, right?

Arabic: 
لديّ أشخاص في المكتب
أو في المنزل أو في المكتبة
قد لا أريد فقط أن يتمكنوا من
الانتقال إلى جهاز الكمبيوتر ذلك
ورؤية هذا الملف النصي
الصغير فقط الموجود على جهاز الكمبيوتر الخاص بي.
لأنه بعد ذلك يمكنهم تسجيل الدخول إلى
حسابي عن طريق البحث فقط.
لذلك يبدو الأمر مزعجًا إلى حد ما.
في الواقع، هذا أحد
تهديدات ملفات تعريف الارتباط.
إذن يتضح أن ملفات تعريف الارتباط أو مواقع الويب
لا تميل إلى القيام بذلك، على الأقل،
إذا تم تنفيذها بشكل جيد.
وبدلاً من ذلك تقوم فقط بوضع رقم
عشوائي كبير بالفعل على محرك الأقراص الصلبة
أو في ذاكرة الوصول العشوائي أو ذاكرة الكمبيوتر الخاص بكم.
إذن 1234567-- على سبيل المثال، رقم كبير
بالفعل ربما مع حروف وأرقام
ربما بعض علامات الترقيم
التي تحدّد هويتي بشكل فريد.
وبعد ذلك، في أي وقت أنقر فوق
رابط على موقع الويب هذا نفسه،
بعد تسجيل الدخول، فإن
متصفحي، بفضل HTTP--
اللغة التي تتحدث بها المتصفحات والخوادم
التي ناقشناها منذ بضعة
أسابيع--
فقط يقوم بإرسال ذلك الرقم العشوائي
الكبير نفسه بطريقة سحرية
إلى الخادم مرارًا وتكرارًا.
وطالما أن الخادم يتذكر
أن هذا الرقم العشوائي الكبير يتوافق
مع اسم المستخدم مالان، فيمكنه
معرفة أي حساب ليقوم بعرضه.
ولماذا هو رقم عشوائي كبير؟

English: 
I have people in the office
or at home or in a library
that I might not want to just be
able to walk up to that computer
and just see this little text
file planted on my computer.
Because then they could log in to
my account by just digging around.
So it feels a little invasive.
Indeed, that's one of
the threats of cookies.
So it turns out cookies or websites
tend not to do that, at least,
if they're implemented well.
They instead just plant a really
big random number on your hard drive
or in your computer's ram or memory.
So 1234567-- like, some really big
number maybe with letters and numbers
maybe even some punctuation
that uniquely identifies me.
And thereafter, any time I click
a link on that same website,
after logging in, my
browser, thanks to HTTP--
the language that browsers and servers
speak that we discussed a few weeks
back--
just magically sends that
same big random number
to the server again and again.
And so long as the server remembers
that that big random number corresponds
to user name Malan, it can
figure out whose account to show.
And why is it a big random number?

Arabic: 
لمَ هو ليس فقط كلمة المرور الخاصة بي
أو اسم المستخدم الخاص بي؟
لماذا أقترح أنه
سيكون رقمًا عشوائيًا كبيرًا؟
الجمهور: في بعض الأحيان يمكن أن يخمنه
الأشخاص فقط باستخدام مُنشئ عشوائي.
ديفيد ج. مالان: بالضبط.
في علم الكمبيوتر، العشوائية هي
ذلك المكوّن القويّ بشكل لا يصدق.
إذا اخترتم كلمة كبيرة بما فيه الكفاية
أو سلسلة كبيرة بما فيه الكفاية
أو جملة، فإن احتمالية أن
يتمكّن خصم عشوائي، أو شخص سيئ
على الإنترنت، من
تخمين أو يحاول
تخمين أن هذه القيمة منخفضة
جدًا فقط، ولن يحدث ذلك في الواقع فقط
في حياتكم
من الناحية الإحصائية.
وبذلك تمنحنا هذه
العشوائية تلك القدرة.
ولذا يمكنكم التفكير في ذلك
بشكل مجازي في العالم الحقيقي
كأنه ختم يدّ.
إذا ذهبتم من قبل
إلى منتزه ترفيهي أو حانة
أو نادي حيث يجب أن
تظهروا هوياتكم الشخصية أو يجب أن
تدفعوا ثمن التذكرة للدخول،
أحيانًا يقومون
بختم أيديكم باستخدام
حبر مرئي أو غير مرئي.
وهذا إلى حد كبير لأجل
الكفاءة بحيث، بعد ذلك،
عندما تكونون في المنتزه 
الترفيهي، يمكنكم الخروج والدخول.
ولا يجب أن
تعيدوا الدفع أو تعيدوا الختم.
إذا كنتم في الحانة أو النادي، فلا 
يجب أن تظهروا هوياتكم الشخصية.
يمكنهم التحقق مرة واحدة، ومن ثم بفعالية
أكبر يتيحون لكم الدخول والخروج
كما تشاؤون.

English: 
Why is it not just my
password or my username?
Why am I proposing that
it be a big random number?
AUDIENCE: Sometimes people can guess
it by just using a random generator.
DAVID J. MALAN: Exactly.
In computer science, randomness is
this incredibly powerful ingredient.
If you pick a big enough
word or a big enough string
or sentence, the probability that
some random adversary, or bad person
on the internet, is going
to be able to guess or try
to guess that value is just so
low, it's just not realistically
ever going to happen in
your lifetime statistically.
And so random this gives
us that capability.
And so you can think about this
metaphorically in the real world
as being like a hand stamp.
If you've ever gone to an
amusement park or a bar
or a club where you have
to show your ID or you
have to pay for a ticket on
the way in, sometimes they'll
stamp you with either
visible or invisible ink.
And that's largely for
efficiency so that, thereafter,
when you're in the amusement
park, you can come and go.
And you don't have to
repay or reprocess.
If you're in the bar or the club, you
don't have to keep showing your ID.
They can check once, and then more
efficiently let you come and go
as you please.

English: 
Because you're just presenting
your hand or this virtual hand
stamp to the bouncer or to the
gatekeeper at those places.
So cookies are exactly like that.
Unbeknownst to us all this time, anytime
you visit a website into which you've
logged in, your browser
is secretly but usefully
presenting a hand stamp to that
server to remind it who you are.
Or rather, not really who you
are, but of that big random number
so that, if the server remembers
who that number belongs to,
it can figure out whose
account to then show.
So put more concretely, if I actually
pull up some of the HTTP examples
that we looked at in the past,
let's consider this in context.
So almost everyone here has
probably used Gmail at some point.
And you log in generally
via page like this.
So it might be infrequent
because you're not often
prompted to log into email because
of-- surprise, surprise-- cookies
from Google being on your computer.
But let's see where those come from.
So when you request Google or gmail.com,
you might send, in a virtual envelope,
so to speak, from your Mac or PC
to the server, a message like this.
Families who've not
seen this before, this

Arabic: 
لأنكم فقط تظهرون
أيديكم أو ختم اليد
الافتراضي هذا للحارس أو
حارس البوابة في تلك الأماكن.
إذن تكون ملفات تعريف الارتباط بالضبط هكذا.
بدون علمنا طوال هذا الوقت، في أي وقت
تقوم بزيارة موقع ويب قمتَ
بتسجيل الدخول فيه، فإن متصفحك
يقوم سرًا ولكن بشكل مفيد
بتقديم ختم اليد إلى ذلك
الخادم لتذكيره مَن تكون.
أو بالأحرى، ليس حقًا مَن 
تكون، ولكن هذا الرقم العشوائي الكبير
بحيث إذا كان الخادم يتذكر
إلى مَن ينتمي هذا الرقم،
فيمكنه معرفة صاحب
الحساب ليقوم بإظهاره لاحقًا.
لذا لجعل الأمر محدّد أكثر، إذا سحبتُ
بالفعل بعض أمثلة HTTP
التي ألقينا نظرة عليها في الماضي،
دعونا نفكر في ذلك في السياق.
إذن من المحتمل أن معظمكم
هنا قد استخدموا Gmail في مرحلة ما.
وتقومون بتسجيل الدخول بشكل عام
عبر صفحة مثل هذه.
لذلك قد يكون حدوث ذلك أمرًا
نادرًا لأنه لا يُطلب منكم في
كثير من الأحيان تسجيل الدخول إلى البريد الإلكتروني 
بسبب-- مفاجأة، مفاجأة-- وجود ملفات تعريف الارتباط
من Google على جهاز الكمبيوتر الخاص بكم.
ولكن دعونا نرى من أين تأتي تلك.
إذن عندما تقومون بطلب Google أو gmail.com،
قد ترسلون، في ظرف افتراضي،
إذا جاز التعبير، من جهاز Mac أو
الكمبيوتر الشخصي لديكم إلى الخادم، رسالة كهذه.
لمَن لم يرى
هذا من قبل، هذا

Arabic: 
ما يرسله متصفحك
بالفعل إلى الخادم من أجل
طلب صفحة رئيسية من gmail.com.
الآن، سأقوم
بتبسيط ذلك قليلاً
لوجود مجموعة من عمليات إعادة التوجيه--
تتضمن برتوكولات HTTP 302 و301 وهذا
ليس أمرًا مثيرًا للاهتمام اليوم.
لذلك دعونا نفترض أن
Gmail يستجيب على الفور.
عادة، ما يستجيب Gmail 
بهذا، يقول 200 حسنًا.
ها هي صفحة تسجيل الدخول.
وها هي صفحة ويب
بتنسيق نص/html.
ولكن بمجرد تسجيلكم الدخول،
فإن ما يقوم به Gmail الخاص بكم في الواقع
هو إرسال ذلك أيضًا.
تذكرون أننا نسمي هذه 
الأشياء رؤوس HTTP--
أزواج قيمة رئيسية مفصولة بنقطتين
يتم إرسالها بشكل شبه سرى من المتصفح
إلى الخادم ومن الخادم إلى المتصفح.
الآن، نحن كمطوِّرين أكثر تطورًا
يمكننا رؤية هذه الأمور، أليس كذلك؟
يمكنكم فتح علامة تبويب شبكة
Chrome والبدء في التدقيق.
وهي ليست سرية في حد ذاتها.
فقط لا يعرف معظم الأشخاص
أنها هناك.
وما يقوم به Google والشركات
الأخرى هو
أنها حرفيًا تقوم بإرسال رأس تُسمى
تعيين ملف تعريف الارتباط، القيمة التي منها
تلك القيمة العشوائية الكبيرة التي
قررها الخادم من أجلكم.

English: 
is what your browser is actually
sending to a server in order
to request a home page of gmail.com.
Now, I'm going to
simplify this a little bit
because there's a bunch of redirects--
HTTP 302s and 301's involved that
aren't that interesting today.
So let's just assume that
Gmail responds immediately.
Typically, Gmail would respond
with this, saying 200 OK.
Here's the login page.
And here's a web page
in text/html format.
But once you've logged in,
what your Gmail actually does
is it also sends this.
Recall that we call these
things HTTP headers--
key value pairs separated by colons
that are semi-secretly sent from browser
to server and from server to browser.
Now we, more sophisticated developer
types can see this stuff, right?
You can open up Chrome's network
tab and start poking around.
And it's not secret per se.
It's just most people
don't know it's there.
And what Google and other
companies are doing is
they literally send a header called
set-cookie, the value of which
is that big random value that
the server has decided for you.

Arabic: 
متصفحكم، لنفتراض أنه
يتحدث HTTP بشكل صحيح،
يجب أن يحفظ تلك القيمة لاحقًا في
RAM، ذاكرة الوصول العشوائي لجهاز الكمبيوتر،
أو على محرك الأقراص الصلبة.
ومن ثم يجب أن ترسلوا كل نقرة أخرى
تقومون بها على gmail.com،
ليس فقط رؤوس مثل هذه، ولكن
يجب أن ترسلوا الرأس المقابلة--
مجرد ملف تعريف الارتباط، وليست مجموعة ملفات تعريف الارتباط،
بل ملف تعريف الارتباط، وهو
عرض تقديمي لختم اليدّ هذا.
وبالتالي في كل مرة تنقرون فيها فوق
صفحة على Gmail، أو Facebook،
أو أي موقع ويب تقريبًا
قمتم بتسجيل الدخول فيه.
تم وضع ملفات تعريف الارتباط هذه
على جهاز الكمبيوتر الخاص بكم.
الآن مؤخرًا، في كل من
أوروبا وفي الولايات المتحدة،
تم تمرير القوانين التي
تضغط على نحو متزايد
على الشركات التي تعمل
دوليًا لتقديم
معلومات قائمة على ملفات تعريف الارتباط لكم، أليس كذلك؟
تحصلون على هذه القوائم
المنبثقة الصغيرة بشكل متزايد.
وتحصلون عليها
منذ سنوات في أوروبا لنقل،
هل يمكننا وضع ملفات تعريف الارتباط على جهاز الكمبيوتر؟
إذن بالنظر إلى كل هذا، ما الذي
يمكن أن يحدث إذا قلتم
لا، لا توجد ملفات تعريف الارتباط على جهاز الكمبيوتر؟
الجمهور: يجب تسجيل الدخول في كل مرة.
ديفيد ج. مالان: يجب أن تقوموا
بتسجيل الدخول في كل مرة، أليس كذلك؟
إذا قمتم بإزالة ميزة HTTP
الأساسية هذه، سيتدهور العديد من تقسيمات

English: 
Your browser, assuming that
it speaks HTTP properly,
should then save that value in
RAM, your computer's memory,
or on your hard drive.
And then, every other click you
make on gmail.com should send,
not just headers like this, but it
should send the opposite header--
just cookie, not set-cookie,
but cookie, which
is the presentation of that hand stamp.
And so every time you click
a page on Gmail, or Facebook,
or almost any website into
which you've logged in.
Those cookies have been
planted on your computer.
Now recently, in both
Europe and in the US,
have laws been passed that are
increasingly putting pressure
on companies that operate
internationally to present you
with cookie-based information, right?
You get these little
pop-ups increasingly.
And you've been getting them
for years in Europe saying,
can we plant cookies on your computer?
So given all of this, what
might happen if you say
no, no cookies on my computer?
AUDIENCE: You have to keep logging in.
DAVID J. MALAN: You're going to
have to keep logging in, right?
If you take away this fundamental
HTTP feature, much of the web

English: 
breaks, or the user experience
deteriorates significantly.
Now the flip side is cookies can be
used, not only for good, so to speak,
but also for evil.
It turns out that there are a lot
of ads on the internet, of course.
And that's what drives a lot of the
revenue that makes it all possible.
Those ads typically come from image
tags in your HTML or script tags
or some of the HTML tags
we have seen in the class.
But they go to third-party
servers, somewhereelse.com.
And the problem arises with cookies
when those third parties are allowed
to plant cookies on your computer.
Because if you go to Google,
and you go to Facebook,
and you go to Twitter--
bunches of websites.
Suppose they all have some middlemen
advertising service advertising
on each of these websites.
That middlemen, so to
speak, because they
have their ads and, therefore,
their HTTP headers on this site,
and this site, and this site,
there are big third parties
out there-- lots of them advertising
networks-- that know everywhere
little old you is going because
they see your cookie appearing
from multiple different other sites.

Arabic: 
الويب، أو تجربة المستخدم
بشكل ملحوظ.
الآن الجانب الآخر هو أن ملفات تعريف الارتباط يمكن
استخدامها، ليس فقط للاستخدام الجيد، إذا جاز التعبير،
ولكن للاستخدام الضار أيضًا.
يتضح أنه توجد
إعلانات كثيرة على الإنترنت، بالطبع.
وهذا ما يحرك العديد من
الإيرادات التي تجعل كل شيء ممكن.
عادة ما تأتي هذه الإعلانات من علامات الصور
في HTML الخاصة بكم أو علامات النص
أو بعض علامات HTML
التي رأيناها في الفصل الدراسي.
لكنها تنتقل إلى خوادم
تابعة لجهة خارجية، somewhereelse.com.
وتنشأ المشكلة بملفات تعريف الارتباط
عندما يتم السماح لتلك الجهات الخارجية
بوضع ملفات تعريف الارتباط على جهاز الكمبيوتر الخاص بكم.
لأنه إذا انتقلتم إلى Google،
وانتقلتم إلى Facebook،
وإلى Twitter--
مجموعة مواقع الويب.
لنفترض أن لدى جميعها بعض الوسطاء
الذين يقومون بالإعلان عن خدمة والإعلان
على كل مواقع الويب هذه.
هؤلاء الوسطاء، إذا
جاز التعبير، لأن
لديهم إعلاناتهم، وبالتالي،
رؤوس HTTP الخاصة بهم على هذا الموقع،
وهذا الموقع، وهذا الموقع،
هناك جهات خارجية كبيرة
هناك-- العديد منها تعلن عن شبكات--
تعرف كل مكان
تنتقلون إليه أيها الشباب لأنها
ترى ملف تعريف الارتباط الخاص بكم الذي يظهر
من عدة مواقع أخرى مختلفة.

English: 
And so here's where cookies become, not
a computer science, engineering feat,
but really a threat to
one's privacy because they
can be used so easily for tracking.
And frankly, AT&T and Verizon,
as an aside, got into trouble--
not enough people know this--
some years back when they started
injecting, forcibly, additional HTTP
headers similar in spirit to this to
all of people's cell phone traffic--
so not things you could
even opt out of initially.
Because this was a way for
advertisers and for themselves
to be able to track users.
So these HTTP headers on
which cookies are based
are very powerful, but
also very invasive.
And we're only now starting to
see, societally and politically,
pushback on this very simple mechanism
that, hopefully, we as CS types
just understand the mechanics of
and, therefore, now the implications.
So let's see this in
context, for instance.
Let me go ahead and open up a
relatively small example in CS50 IDE.
For those unfamiliar, CS50
IDE is a web-based application
via which you can write
programs in the cloud,

Arabic: 
ولذا هنا توجد ملفات تعريف الارتباط، ليس
علم الكمبيوتر، الهندسة الفذّة،
ولكنها في الحقيقة تشكل تهديدًا 
لخصوصية الفرد لأنه
يمكن استخدامها بسهولة للتعقب.
وبصراحة، AT&T وVerizon،
كملاحظة جانبية، واجهتا المتاعب--
لا يعرف عدد كافي من الأشخاص ذلك--
قبل بضعة أعوام عندما بدأوا
بشكل قسري، بضخ، رؤوس HTTP
إضافية متشابهة في جوهرها مع هذه
لنقل جميع بيانات الهواتف الخلوية للأشخاص--
بذلك لا توجد أشياء يمكنكم
رفضها بشكل قطعي من البداية.
لأن هذه كانت طريقة
للمعلنين ولأنفسهم
ليتمكّنوا من تعقب المستخدمين.
إذن رؤوس HTTP هذه التي
تقوم عليها ملفات تعريف الارتباط
قوية جدًا، ولكنها
أيضًا مزعجة للغاية.
والآن فقط نبدأ
برؤية، على الصعيد الاجتماعي والسياسي،
تراجع الإقبال على هذه الآلية البسيطة
التي، آمل، أننا كمطوِّري علم الكمبيوتر
نفهم فقط آلياتها
وبالتالي، الآثار الآن.
إذن دعونا نرى ذلك في
سياق، على سبيل المثال.
دعوني أمضي قدمًا وأفتح
مثالاً صغيرًا نسبيًا في CS50 IDE.
بالنسبة لمَن لم يعتادوا على ذلك، CS50
IDE هو تطبيق قائم على الويب
يمكنكم عبره كتابة
برامج في السحابة،

English: 
just using any browser on a Mac or PC.
I'm going to go ahead
into my account here.
And I'm going to go into Store.
And I'm going to go into
the Templates directory
and show that this example
here has a few files.
This will look familiar
to students in the room.
Application.py is the
web-based application.
And then we have some
template files, so to speak.
In my Terminal window here, I'm going
to go ahead and, with just my keyboard,
go into this directory called Store in
source 8, which is available online.
And I'm going to go ahead and do a
flask run, which, for those unfamiliar,
is the command via which
you can start a web server
and start running a
web-based application.
So now that I have that, I'm going to go
ahead and visit exactly this URL here.
And we'll see a relatively
simple and super ugly web store.
Let me go ahead and zoom in a bit.
And this web store allows me to
buy three things-- foos, bars,
and bazes, whatever those are.
And this is a very simple
e-commerce-like site
where I just have to type the quantity
of foos, bars, and bazes that I want.
And then I can go ahead and buy them.

Arabic: 
فقط باستخدام أي متصفح على جهاز Mac أو الكمبيوتر الشخصي.
سأمضي قدمًا
إلى حسابي هنا.
سأقوم بالانتقال إلى المتجر.
وسأنتقل إلى
دليل القوالب
وأعرض هذا المثال
هنا الذي يحتوي على بعض الملفات.
سيبدو هذا مألوفًا
للطلاب في الغرفة.
Application.py هو
تطبيق قائم على الويب.
ومن ثم لدينا بعض ملفات 
القوالب، إذا جاز التعبير.
في النافذة الطرفية الخاصة بي هنا، سأمضي
قدمًا، وفقط باستخدام لوحة المفاتيح الخاصة بي،
سأنتقل إلى هذا الدليل المُسمى المتجر في 
source8، وهو متاح على الإنترنت.
سأمضي قدمًا وأقوم بتشغيل 
flask، والذي، بالنسبة لمَن لم يعتادوا الأمر،
هو الأمر الذي
يمكنكم عبره بدء خادم ويب
والبدء بتشغيل 
تطبيق قائم على الويب.
إذن لديّ ذلك الآن، سأمضي
قدمًا وأقوم بزيارة عنوان URL بالضبط هنا.
وسنرى متجر ويب
بسيط نسبيًا وقبيح للغاية.
دعوني أمضي قدمًا وأقوم بالتكبير قليلاً.
ويتيح ليّ متجر الويب هذا
شراء ثلاثة أشياء-- foos، وbars،
وbazes، أيًا كانت تلك.
وهذه موقع يشبه التجارة الإلكترونية
البسيطة للغاية
حيث يجب أن أكتب فقط كمية
foos، وbars، وbazes التي أريدها.
ومن ثم يمكنني المضي قدمًا وشراؤها.

English: 
So I'm going to go ahead and say,
give me one foo, how about zero bars,
and these two bazes.
And I'm going to go
ahead and click Purchase.
And now you'll see my shopping cart.
But if I continue shopping,
you'll see that it
resets, just like if you keep browsing
Amazon or whatever other website.
But if you want to check
shopping cart again,
notice it's remembered
what I'm looking for.
And in fact, you know what?
I'm going to go ahead
and close the window.
Oops.
I actually lost the website.
But you know what?
If I go back to that URL and
reopen, I see the storefront.
But if I view my shopping cart,
it has remembered my state.
So notice the power now of cookies.
It's not just to remember
with a hand stamp who you are.
But now you can remember anything
about that user that you want, right?
A shopping cart on Amazon or any
website is the best example of this
because it would be horrible, horrible,
horrible for a User Experience or UX
if every time you click
the darn link, you
lost the contents of your shopping cart
because the website forgot who you are.
So this is a compelling
feature to remember.
And it's cookies that
implement this feature too.

Arabic: 
إذن سأمضي قدمًا وأقول،
أعطني foo واحدة، ماذا عن صفر bars،
واثنتين من baze.
وسأمضي قدمًا
وأنقر فوق شراء.
والآن سترون عربة التسوق الخاصة بي.
ولكن إذا تابعتُ التسوق،
سترون أنه
يقوم بإعادة التعيين، تمامًا كما لو كنتم تتصفحون
Amazon أو أي موقع ويب آخر.
ولكن إذا كنتم تريدون التحقق
من عربة التسوق مجددًا،
لاحظوا أنه تذكر
ما كنتُ أبحث عنه.
وفي الواقع، أتعلمون ماذا؟
سأمضي قدمًا
وأقوم بإغلاق النافذة.
عذرًا.
لقد فقدتُ الموقع بالفعل.
ولكن أتعلمون ماذا؟
إذا رجعتُ إلى عنوان URL هذا 
وأعدتُ فتحه، أرى واجهة المتجر.
ولكن إذا قمتُ بعرض عربة التسوق الخاصة بي،
لقد تذكر حالتي.
لذلك لاحظوا الآن قوة ملفات تعريف الارتباط.
إنها لا تتذكر مَن تكون
من ختم اليدّ فقط.
ولكن الآن يمكنكم تذكر أي شيء
عن هذا المستخدم الذي تريدونه، أليس كذلك؟
عربة التسوق على Amazon أو أي
موقع ويب هو أفضل مثال على ذلك
لأنه سيكون أمرًا فظيعًا، فظيعًا،
فظيعًا بالنسبة إلى تجربة المستخدم أو UX
إذا قمتم في كل مرة بالنقر 
فوق الرابط، وفقدتم
محتويات عربة التسوق الخاصة بكم
لأن الموقع نسي مَن تكونوا.
إذن هذه ميزة
جذابة للتذكر.
وملفات تعريف الارتباط الخاصة بها التي
تقوم بتنفيذ هذه الميزة أيضًا.

English: 
Because more generally, what's
going on with cookies is this.
When you set a cookie using
the set-cookie header that
looked like this, there
is a key value pair
to the right that we might call
session, and that has the value.
Value is the hand stamp.
Session is just a term of art
that refers to this abstraction
that you can think of
really as a shopping cart.
But it doesn't have to have anything to
do with actual shopping or e-commerce.
It's just a container in
which you can store stuff.
So this is telling the website that
my session value, my hand stamp
is 12345-- and big really random number.
The website can then say, you know what?
I'm going to store a container for you.
Let's call it a Python
dictionary, or dict for you,
inside of which I can
put anything I want.
And so in fact, when you go
to a shopping cart like this,
what is the server actually doing?
Well, upon seeing your hand stamp, and
realizing, oh, you are user 1234567.
Oh, that's username Malan.
Let me go ahead and grab the
dictionary, the Python dict

Arabic: 
لأنه بشكل عام، ما
يحدث باستخدام ملفات تعريف الارتباط هو ذلك.
عندما تقومون بتعيين ملف تعريف ارتباط باستخدام
رأس تعيين ملف تعريف الذي
بدا مثل هذا، هناك
زوج قيمة رئيسية
على اليمين والذي يمكن أن نسميه
جلسة، وهو يحتوي على قيمة.
القيمة هي ختم اليدّ.
الجلسة مجرد مصطلح فني
يشير إلى هذا التجريد
الذي يمكنكم التفكير فيه
حقًا كعربة تسوق.
ولكن لا يجب أن تقوموا بأي شيء باستخدام
التسوق الفعلي أو التجارة الإلكترونية.
إنه مجرد وعاء
يمكنكم تخزين الأشياء فيه.
إذن هذا يقوم بإخبار الموقع أن
قيمة الجلسة الخاصة بي، ختم اليد الخاص بي
هو 12345-- وهو رقم عشوائي كبير بالفعل.
ثم يمكن أن يقول الموقع، أتعلمون ماذا؟
سأقوم بتخزين وعاء من أجلكم.
دعونا نسميه قاموس
Python، أو dict من أجلكم،
بداخله يمكنني
وضع أي شيء أريده.
ولذا في الواقع، عندما تنتقلون
إلى عربة تسوق كهذه،
ما الذي يقوم به الخادم بالفعل؟
حسنًا، عندما يرى ختم اليدّ الخاص بك، 
ويدرك أنه، أوه، أنت المستخدم 1234567.
أوه، هذا اسم المستخدم مالان.
دعوني أمضي قدمًا وأسحب
القاموس، Python dict

English: 
from memory, or even from
a CSV file if you want,
and show you the contents
of your shopping cart.
Meanwhile, someone else, Brian
visits the same exact website
and logs in with his account.
He's going to present a
different hand stamp, presumably.
And so the website can look
for a different dictionary
and show Brian the different
contents of his shopping cart.
And the same for everyone in this room.
So this simple mechanism--
I mean, consider the power.
This is just a stupid
text value key:value.
And from all of that does all of
the web's capabilities now come.
And we won't look in too much
detail into the code here,
but let me show one snippet of it.
If I go into application.py, the magic
that makes this possible in flask
is just to import this
additional feature.
You'll recall, from the
past couple of problems
you've worked on, you import
from flask a few things--
render template, redirect, request.
Well, if you Add session
to that list, which
is the code abstraction of this
hand-stamp idea, what you can now do
is this.
Let me scroll down to
the juicy part here.
And notice that you can
do lines of code now,

Arabic: 
من الذاكرة، أو حتى من
ملف CSV إذا أردتم،
وأعرض لكم محتويات
عربة التسوق الخاصة بكم.
وفي الوقت نفسه، شخص آخر، يقوم
براين بزيارة الموقع نفسه بالضبط
ويُسجِّل الدخول فيه باستخدام حسابه.
يقوم بتقديم
ختم يدّ مختلف، بشكل افتراضي.
وبالتالي يمكن أن يبحث موقع الويب
عن قاموس مختلف
ويعرض لبراين محتويات مختلفة
من عربة التسوق الخاصة به.
والأمر نفسه لكل شخص في هذه الغرفة.
إذن هذه الآلية البسيطة--
أعني، فكّروا في القوة.
هذه مجرد قيمة
نص غبية key:value.
وبسبب كل ذلك تأتي
جميع قدرات الويب الآن.
ولن نلقي نظرة بشكل تفصيلي
للغاية على التعليمة البرمجية هنا،
لكن دعوني أعرض مقتطفًا واحدًا منها.
إذا انتقلتُ إلى application.py، فإن السحر
الذي يجعل ذلك ممكنًا في flask
هو فقط استيراد هذه
الميزة الإضافية.
ستتذكرون، من المشكلات
القليلة الماضية
التي عملتم عليها، تقومون باستيراد
بعض الأشياء من flask--
وتقديم قالب، وإعادة التوجيه، والطلب.
حسنًا، إذا قمتم بإضافة جلسة
إلى تلك القائمة، والتي
هي تجريد التعليمة البرمجية
لفكرة ختم اليدّ هذه، ما يمكنكم القيام به الآن
هو ذلك.
دعوني أقوم بالتمرير إلى
الجزء الهام هنا.
ولاحظوا أنه يمكنكم
تنفيذ سطور التعليمة البرمجية الآن،

English: 
and for the next CS50 finance
problem, lines of code like this.
Session is just a Python
dictionary, or dict.
You can index into it using any word--
foo, or bar, or baz, just like you
could with dictionaries more generally.
And you can store in
it anything you want.
In my case, I want to store a number--
0 foos, or 1 foo, or 2 foos or whatever.
So I can simply convert to an
int, the user's request forms
item, whatever that is.
And let me wave my hand at some
of the code above because it just
sets the whole thing up.
But the new line of
code, the new feature
that now will empower us to build
something like a stock trading website
is quite simply this line here.
Because what you can also do to
remember that a user is logged in,
just go ahead and store
in this so-called session,
a value of, like, true.
And if the value true is there, you
can infer that the human is logged in.
And if there's no such value in the
dictionary, they are not logged in.
And so we'll hold your hand a
bit more in the next problem set
with this introduction of CS50 Finance.
And we'll write some of the
code that handles the login,

Arabic: 
وبالنسبة لمشكلة CS50 finance
المقبلة، سطور تعليمة برمجية كهذه.
الجلسة هي قاموس
Python، أو dict فقط.
يمكنكم فهرستها باستخدام أي كلمة--
foo، أو bar، أو baz، تمامًا كما
يمكنكم ذلك باستخدام القواميس بشكل عام أكثر.
ويمكنكم تخزين
أي شيء تريدونه فيها.
في حالتي، أريد تخزين رقم--
0 foos، أو 1 foo، أو 2 foos أو أيًا كان.
إذن يمكنني ببساطة التحويل إلى
int، عنصر أشكال طلب
المستخدم، أيًا كان ذلك.
ولن أتطرق إلى بعض التعليمة
البرمجية في الأعلى لأنها فقط
تقوم بتعيين الشيء بالكامل.
لكن السطر الجديد من
التعليمة البرمجية، الميزة الجديدة
التي ستمكننا الآن من بناء
شيء مثل موقع تداول الأسهم
على الويب وهو ببساطة هذا السطر هنا.
نظرًا لما يمكنكم القيام به أيضًا 
لتذكر أن المستخدم قام بتسجيل الدخول،
فقط امضوا قدمًا وقوموا بتخزين
في هذه التي تُسمى بالجلسة،
قيمة، مثل، صحيح.
وإذا كانت القيمة صحيحة هناك، فيمكنكم
استنتاج أن الشخص قام بتسجيل الدخول.
وإذا لم تكن هناك هذه القيمة في 
القاموس، فلم يقم بتسجيل الدخول.
ومن ثم سنقوم بإرشادكم بشكل أكبر قليلاً
في مجموعة المشاكل التالية
باستخدام مقدمة CS50 Finance هذه.
وسنكتب بعض التعليمة البرمجية
التي تعالج تسجيل الدخول،

English: 
so you can see by
example how to do this.
But it'll be up to you
thereafter to start
remembering what stocks
a user actually has
using sessions to retain the fact
that they've logged in already.
All right.
So that was a lot all at once.
But any questions on cookies
and the feature they provide,
these things called sessions?
Anything at a all?
Yeah?
AUDIENCE: Is the session saved
on the user side or the server?
DAVID J. MALAN: Is the session saved
on the user side or the server?
Really good question.
And the answer can be it depends.
You could store on the user's
client, on their browser.
And as the gentleman over here proposed,
you could theoretically store literally
their user name and password--
maybe I proposed that earlier--
on their computer.
And that's bad for the reasons
that we surmised earlier.
But you could also store the contents
of their shopping cart, foos, bars,
and bazes.
That's not quite as invasive
as storing their password.
But if you're buying things you
don't really want people knowing,
that is then invasive.
So maybe we can do better.

Arabic: 
وبذلك يمكنكم رؤية كيفية القيام 
بذلك من خلال المثال.
لكن الأمر سيكون متروكًا لكم
بعد ذلك للبدء
بتذكُر الأسهم
قام المستخدم باستخدام
الجلسات في الواقع للإبقاء على حقيقة
قيامه بتسجيل الدخول بالفعل.
حسنًا.
إذن كان ذلك كثيرًا في مرة واحدة.
ولكن أي أسئلة حول ملفات تعريف الارتباط
والميزة التي تقدمها،
هذه الأشياء التي تُسمى بالجلسات؟
أي شيء على الإطلاق؟
أجل؟
الجمهور: هل يتم حفظ الجلسة 
من جانب المستخدم أم الخادم؟
ديفيد ج. مالان: هل يتم حفظ الجلسة
من جانب المستخدم أم الخادم؟
سؤال جيد حقًا.
ويمكن أن تكون الإجابة على حسب.
يمكنك التخزين في عميل
المستخدم، على متصفحه.
وكما اقترح الرجل الفاضل هنا،
أنه يمكنك من الناحية النظرية تخزين اسم المستخدم
وكلمة المرور الخاصة به حرفيًا--
ربما اقترحتُ ذلك في وقت سابق--
على جهاز الكمبيوتر الخاص به.
وهذا أمر سيء للأسباب
التي ذكرناها سابقًا.
ولكن يمكنكم أيضًا تخزين محتويات
عربة التسوق الخاصة به، foos، وbars،
وbazes.
هذا ليس أمرًا مزعجًا تمامًا 
كتخزين كلمة المرور الخاصة به.
ولكن إذا كنتم تقومون بشراء أشياء لا
تريدون أن يعرف عنها الأشخاص حقًا،
فذلك يكون أمرًا مزعجًا.
لذلك ربما يمكننا فعل ما هو أفضل.

Arabic: 
والأفضل غالبًا،
هو تخزينها على الخادم.
إذن سيقوم موقع الويب 
المُصمم جيدًا عادة
بتخزين هذه القيمة العشوائية الكبيرة فقط،
ختم اليدّ، على جهاز Mac أو الكمبيوتر الشخصي.
ومن ثم يتم تخزين جميع الأشياء 
المثيرة للاهتمام وربما الحساسة
في قاعدة البيانات أو في ملف CSV
أو فقط في ذاكرة الوصول العشوائي للخادم أو في الذاكرة
كما في المتغير الشامل.
سؤال جيد.
أي أسئلة أخرى؟
أي أسئلة أخرى؟
لا.
حسنًا.
إذن هذه المشكلة قد حُلّت.
نعلم الآن أنه يمكننا
تنفيذ أشكال تسجيل الدخول.
ونعلم أنه يمكننا تذكّر
هؤلاء الأشخاص الذين قاموا بتسجيل الدخول.
إذن دعونا فقط نقوم بتحديد
أن ذلك ممكن الآن.
ولكن على مدار الأسبوعين الماضيين،
لم يكن الوصول إلى أشياء كملفات CSV،
القيم المفصولة بفاصلة، والتي
تقوم بإنشاء وهم
جداول بيانات Google وExcel
وApple Numbers مثل الأعمدة والصفوف أمرًا قويًا بشكل لا يصدق.
لماذا؟
حسنًا، إنه بحث خطي إلى حد كبير 
عن كل شيء، أليس كذلك؟
ملف CSV هو عبارة عن مجرد صفوف
وصفوف وصفوف وصفوف من البيانات.
وإذا كنتم تريدون البحث عن
أي شيء في ذلك
الملف، على النحو الذي ربما كنتم تريدونه
لتنفيذ الاستقصاء الخاص بكم،
كيف يمكنكم العثور عليه؟

English: 
And better is often,
store it on the server.
So a well-designed
website will typically
store only this big random value,
the hand stamp, on the Mac or PC.
And then all of the interesting
and maybe sensitive stuff
is stored in a database or CSV file
or just the server's RAM or memory
like in a global variable.
Good question.
Other questions?
Other questions?
No.
All right.
So that's one problem solved.
We know now we can
implement login forms.
And we know that we can remember
that people are logged in.
So let's just stipulate
that is now possible.
But over the past couple of weeks,
it's not been incredibly powerful
to only have access to things like CSV
files, comma separated values, which
create the illusion of Excel
and Google Spreadsheets
and Apple Numbers like columns and rows.
Why?
Well, it's pretty much a linear
search for everything, right?
A CSV file is just rows and
rows and rows and rows of data.
And if you want to search
for anything in that
file, like you might have wanted
to for your survey implementation,
how do you find it?

English: 
Well, you open the file with Open.
You maybe use a for loop and
iterate over every single line
looking for some value, and
then you close the file.
That is big O of n.
And in the worst case, the thing
you care about is at the very end.
And it's not terribly efficient.
Now, you can append to
files pretty efficiently.
Recall that when we opened files with
quote unquote, "A" for Append mode.
We did this with a brief example,
instead of "W" for Write.
You get the operating system's
help and add rose to the file
at the very bottom,
which is more efficient.
But you can't insert things in
the middle very efficiently.
You can't delete things very easily.
You would have to literally, for those
kinds of scenarios, open the file,
read the whole darn thing,
then write out parts of it
or add to it as you're writing out.
And so humans years ago
realized, well, this is stupid.
All of us humans in the
world are constantly
writing code to open files,
change files, save files.
Why don't a few of us do an even better
job of implementing that feature,
then share it with the world?
And thus were born,
effectively, databases.
And these days, there are so many
different types of databases--
you might be familiar with tools,
commercial software like Oracle,

Arabic: 
حسنًا، تقومون بفتح الملف باستخدام Open.
ربما تستخدمون تكرار حلقي من النوع for
وتقومون بتكرار كل سطر
للبحث عن بعض القيم، ومن
ثم تقومون بإغلاق الملف.
هذا هو حرف O كبير من n.
وفي أسوأ الحالات، الأمر
الذي يهمكم يكون في النهاية.
وهو ليس فعّالاً للغاية.
الآن، يمكنكم إلحاق
الملفات بشكل فعّال للغاية.
تذكرون عندما فتحنا الملفات 
باستخدامعلامة اقتباس وعلامة إنهاء الاقتباس، "إ" لوضع الإلحاق.
فعلنا ذلك باستخدام مثال موجز،
بدلاً من "ك" للكتابة.
حصلتم على مساعدة نظام
التشغيل ووصلتم إلى الملف
في الأسفل،
وهو فعّال أكثر.
ولكن لا يمكنكم إدراج الأشياء في
المنتصف بفاعلية عالية.
لا يمكنكم حذف الأشياء بسهولة.
بالنسبة إلى تلك الأنواع من السيناريوهات،
يجب عليكم حرفيًا، فتح الملف،
قراءة كل شيء،
ثم كتابة أجزاء منه
أو إضافة شيء إليه أثناء قيامكم بالكتابة.
وهكذا أدرك الأشخاص منذ
سنوات، حسنًا، هذا أمر غبي.
نحن البشر جميعًا في
العالم نكتب باستمرار
تعليمة برمجية لفتح الملفات،
وتغييرها، وحفظها.
لمَ لا يقوم بعض منا بعمل 
أفضل لتنفيذ هذه الميزة،
ثم مشاركتها مع العالم؟
وهكذا تم إنشاء
قواعد البيانات، بشكل فعّال.
وهذه الأيام، هناك عدة أنواع
مختلفة من قواعد البيانات--
قد تكونوا على دراية باستخدام الأدوات،
برنامج تجاري مثل Oracle،

English: 
or SQL Server, or Microsoft Access.
And in the open source world,
there's Postgres and MySQL,
and SQLite and others.
And many of them, as
even those names imply,
use a special language called SQL,
Structured Query Language, which
is the very last
language we'll introduce
you to in CS50 unless you go off
on your own with final projects
to pick up something more.
But with SQL, you have the ability
to select data from a database,
to insert it, to delete
it, to updated it.
All of the things that you could
absolutely do with Python and CSVs,
it would just be so darn tedious to
write those lines of code yourself.
So what's the right mental model?
Here is, I claim,
essentially a database.
Like most everyone in
this room has probably
used Google Spreadsheets,
and if you've not, probably
Excel or maybe Apple Numbers.
So these are spreadsheets.
And they're essentially what you
could call a relational database.
Relational-- implying
that there's relationships
among the various data in the rows
and the columns decided by you
or whoever made it.
And this is a spreadsheet of course.

Arabic: 
أو خادم SQL، أو Microsoft Access.
وفي العالم مفتوح المصدر، هناك
Postgres وMySQL،
وSQLite وغيرها.
والعديد منها، حيث
هذه الأسماء تشير إلى،
استخدام لغة خاصة تُسمى SQL،
لغة الاستعلامات المركبة، وهي
آخر لغة سنقوم بتقديمها
لكم في دورة CS50 ما لم تختاروا بأنفسكم
شيئًا آخر
في المشاريع النهائية.
ولكن باستخدام SQL، يمكنكم
تحديد البيانات من قاعدة البيانات،
وإدراجها، وحذفها،
وتحديثها.
جميع الأشياء التي يمكنكم فعلها
بالتأكيد باستخدام Python وملفات CSV،
ستكون كتابة سطور تلك التعليمة البرمجية بأنفسكم
 أمرًا مملاً للغاية فقط.
إذن ما هو النموذج العقلي المناسب؟
هنا، أزعم،
وجود قاعدة بيانات بشكل أساسي.
على سبيل المثال من المحتمل أن
معظم الحاضرين في هذه الغرفة
استخدموا جداول بيانات Google،
وإذا لم تفعلوا ذلك، فعلى الأرجح
Excel أو ربما أرقام Apple.
إذن هذه هي جداول البيانات.
وهي في الأساس ما يمكنكم
تسميته بقاعدة بيانات ارتباطية.
ارتباطية-- تشير إلى
وجود علاقات
بين البيانات المختلفة في الصفوف
والأعمدة المُقرَّرة من قِبلكم
أو أيًا مَن قام بإعدادها.
وهذا هو جدول البيانات بالطبع.

English: 
And it has rows where
your actual data goes.
And columns-- and what's
noteworthy about the columns?
It's just conventional to
do what with the columns,
especially in that first row?
AUDIENCE: Headers.
DAVID J. MALAN: Yeah, put
some header values, right?
You could certainly
put them in the left.
It's just humans prefer,
it seems, to read top
to bottom instead of left
to all the way to the right.
So we just adopted a conventioneers
ago that your columns represent
different types of data, and the
rows represent different values
for those fields or for
those columns, so to speak.
So if you wanted to store
a spreadsheet of values
for a bunch of students in
a class or in a university,
one column might be ID number, like
their Harvard ID or the Yale ID.
Another column might be their name,
their email address, phone number, age,
and so forth.
And you could just lay that all out.
You can make it pretty and boldface the
top and organize things and sort it.
But at some point, this
isn't quite the right tool.
And in fact, I ran into
this in grad school years
ago where I was analyzing
large sets of data.
And it was just convenient to
double-click on the CSV file,
open it in Excel, and just
manipulate it and answer the data
questions that I had.

Arabic: 
ويحتوي على صفوف حيث
تنتقل بياناتكم الفعلية.
والأعمدة-- وما هو
جدير بالذكر بشأن الأعمدة؟
ما الذي يكون القيام به أمرًا تقليديًا
باستخدام الأعمدة،
على وجه الخصوص في هذا الصف الأول؟
الجمهور: الرؤوس.
ديفيد ج. مالان: نعم، وضع
بعض من قيم الرؤوس، أليس كذلك؟
يمكنكم بالتأكيد
وضعها على اليسار.
إنه مجرد تفضيل بشري،
على ما يبدو، للقراءة من أعلى
إلى أسفل بدلاً من اليسار
على طول الطريق إلى اليمين.
إذن قمنا منذ سنوات فقط
بتبنّي التقاليد حيث تمثل الأعمدة الخاصة بكم
أنواعًا مختلفة من البيانات،
وتمثل الصفوف قيمًا مختلفة
لهذه الحقول أو
لهذه الأعمدة، إذا جاز التعبير.
إذن إذا أردتم تخزين
جدول بيانات القيم
لمجموعة من الطلاب في
الصف الدراسي أو في الجامعة،
قد يكون أحد الأعمدة عبارة عن رقم معرّف، مثل
معرّف هارفارد أو معرّف يال.
وقد يكون عمود آخر عبارة عن أسمائهم،
وعناوين بريدهم الإلكتروني، وأرقام هواتفهم، وأعمارهم،
وما إلى ذلك.
ويمكنكم فقط وضع كل ذلك.
يمكنكم جعلها جميلة وكتابة 
الجزء العلوي بالخط الغامق وتنظيم الأشياء وفرزها.
لكن في مرحلة ما، لا تكون
هذه هي الأداة المناسبة تمامًا.
وفي الواقع، واجهتُ ذلك الأمر
في الدراسات العليا منذ
سنوات حيث كنتُ أقوم بتحليل
مجموعات كبيرة من البيانات.
وكان النقر المزدوج فوق ملف CSV فقط،
وفتحه في Excel،
ومعالجته فقط والإجابة
على أسئلة البيانات التي كانت لديّ
أمرًا مناسبًا تمامًا.

Arabic: 
ولكن في الماضي، كان Excel 
يحتوي على حد قدره 65536 صف.
هذا يبدو عددًا كبيرًا--
وهذا يمثل 2 إلى القوة 16،
إذا كنتم تستدعون المرجع هناك.
وهكذا قرر البشر منذ سنوات
في Microsoft، أن هذا يكفي.
وبصراحة، كان الأمر كذلك.
لأنه حتى في
آلاف الصفوف، على سبيل المثال،
أصبح جهاز Mac الخاص بي غير صالح للاستخدام بسبب
استخدام مساحة كبيرة من الذاكرة فقط.
لذلك كان ذلك مجرد حد
غير عملي على أي حال.
ولكن في مرحلة ما،
قد تريدون تخزين
65537 صفًا من البيانات أو مئات
الآلاف من الصفوف أو الملايين من الصفوف
أو حتى أكثر.
أعني، هناك العديد من
مواقع الويب، Google وFacebook
وغيرها التي تفعل ذلك بالتأكيد.
لا يمكنكم فقط استخدام برنامج
على جهاز Mac أو الكمبيوتر الشخصي لديكم بعد الآن.
تحتاجون إلى استخدام برنامج رائع أكثر.
لكن هذا البرنامج الرائع
غالبًا ما يزال يعمل بالطريقة نفسها.
لديكم ملف رئيسي واحد يُسمى
جدول البيانات في عالمنا البشري.
ولكن في عالم الخوادم، قد 
تسمونه بقاعدة بيانات بدلاً من ذلك.
وفي حين أنه في
عالمنا البشري، قد تكون
لدينا أشياء تُسمى أوراق أو جداول
بيانات فردية ضمن الملف الأكبر،

English: 
But back in the day, Excel actually
had a limit of 65,536 rows.
Sounds like a lot--
and that's 2 to the 16th power,
if you call the reference there.
And so humans at Microsoft
decided years ago, that's enough.
And frankly, it kind of was.
Because even in the
thousands of rows, like,
my Mac just became unusable because it
was just too much memory being used.
So it was just an
impractical limit anyway.
But at some point, you
might want to store
65,537 rows of data or hundreds of
thousands of rows or millions of rows
or even more.
I mean, there are so many
websites, Google and Facebook
and others that surely do this already.
You can't just use a program
on your Mac or PC anymore.
You need to use fancier software.
But that fancier software
often still works the same way.
You have one main file called a
spreadsheet in our human world.
But in the server world, you
might call it a database instead.
And whereas, in our
human world, we might
have things called Sheets or individual
spreadsheets within the bigger file,

English: 
in a database, you're going
to have things called tables.
But they're the exact same
thing with rows and columns.
And so when we want to
actually store data,
we can actually store it
in exactly those ways.
So let me go ahead and do this.
Let me go ahead and open
up Google Spreadsheets just
as representative of a database.
And let me go ahead and
create a new file here.
So New Spreadsheet-- and just so that
we can represent things like students.
I'm going to call this
spreadsheet Students.
And over here I'm going to put their
ID number and their name, and what
are some other fields I
rattled off that come to mind?
AUDIENCE: Email.
DAVID J. MALAN: Email.
AUDIENCE: Dorm.
DAVID J. MALAN: Say again.
AUDIENCE: Dorm.
DAVID J. MALAN: Dorm.
Good.
AUDIENCE: Sports and
stuff they want to do.
DAVID J. MALAN: OK.
So sports they want to do, sure.
That's fine-- a little longer.
What else?
AUDIENCE: Graduation year.
DAVID J. MALAN: Graduation
year, age, OK, good.
So graduation year, age, concentration--
OK, and we can probably keep going,
and it just gets wider and wider.
And these are my columns, if you
will, or the fields in the database.

Arabic: 
في قاعدة بيانات، ستكون
لديكم أشياء تُسمى جداول.
لكنها بالضبط الشيء نفسه
باستخدام الصفوف والأعمدة.
وبذلك عندما نريد تخزين
البيانات بالفعل،
يمكننا بالفعل تخزينها
بهذه الطرق بالضبط.
إذن دعوني أمضي قدمًا وأفعل هذا.
دعوني أمضي قدمًا وأفتح
جداول بيانات Google فقط
بصفتها ممثل قاعدة بيانات.
ودعوني أمضي قدمًا 
وأقوم بإنشاء ملف جديد هنا.
إذن جدول بيانات جديد-- وبذلك يمكننا
فقط تمثيل أشياء مثل الطلاب.
وسأقوم بتسمية جدول
البيانات هذا بالطلاب.
وسأقوم هنا بوضع أرقام هويتهم
الشخصية وأسمائهم، وما هي
بعض الحقول الأخرى التي تحدثتُ 
عنها وتتبادر إلى أذهانكم؟
الجمهور: البريد الإلكتروني.
ديفيد ج. مالان: البريد الإلكتروني.
الجمهور: السكن.
ديفيد ج. مالان: كررها مرة أخرى.
الجمهور: السكن.
ديفيد ج. مالان: السكن.
جيد.
الجمهور: الرياضات والأمور
التي يريدون القيام بها.
ديفيد ج. مالان: حسنًا.
إذن الرياضات التي يريدون القيام بها، بالتأكيد.
هذا جيد-- يبدو طويلاً إلى حد ما.
ماذا أيضًا؟
الجمهور: عام التخرج.
ديفيد ج. مالان: عام
التخرج، العمر، حسنًا، جيد.
إذن عام التخرج، العمر، التركيز--
حسنًا، وربما يمكننا المتابعة،
ويزداد الجدول اتساعًا فقط.
وهذه هي الأعمدة، إذا صح
التعبير، أو الحقول في قاعدة البيانات.

English: 
And frankly, I could name this
if I really want to be tidy here,
and I could call this Students.
And you know what?
Maybe I should call this
not students but university.
Because I might want to have another
tab here that we'll preemptively
name to, say, faculty.
And faculty probably have ID
numbers, and they have names,
and they probably have
departments, for instance.
And they also probably
have emails and so forth.
So phone number is another one.
But I might want to kind of
cluster these different types
of data in different
spreadsheets because they're
kind of apples and oranges.
There might be some overlap, but they're
distinct inside different sheets.
In the database world, you
do the exact same thing,
except you call the
whole thing a database,
and you call these things
tables to be clear.
But more importantly, with a
real database, so to speak,
you have to be a little more proactive
about telling the database what
types of data you want to store.
Now, those of you who've used
Google Spreadsheets and Apple
numbers and Excel know that you can
go to the format menu or the data menu
or whatever, and you can show
things to different decimal places.
You can turn things to percents.
And you can format the data.

Arabic: 
وبصراحة، يمكنني تسمية ذلك
إذا أردتُ حقًا أن يكون مُرتبًا هنا،
ويمكنني أن أسمي ذلك بالطلاب.
وأتعلمون ماذا؟
ربما يجب أن أسمي ذلك
بالجامعة وليس بالطلاب.
لأنني قد أريد الحصول على علامة
تبويب أخرى هنا سنسميها بشكل استباقي
باسم، لنقل، الكلية.
وربما يكون لدى الكلية أرقام 
هوية، ولديها أسماء،
ولديها أقسام على
الأرجح، على سبيل المثال.
ولديها بريد إلكتروني أيضًا 
على الأرجح وهكذا.
إذن رقم الهاتف هو أمر آخر.
لكنني ربما أريد تجميع
هذه الأنواع المختلفة من
البيانات في جداول بيانات
مختلفة لأنها
مختلفة عن بعضها البعض إلى حد ما.
قد يكون هناك بعض التداخل، ولكنها
تكون مميزة داخل أوراق مختلفة.
في عالم قاعدة البيانات، تقومون
بالشيء نفسه بالضبط،
باستثناء أنكم تسمون
كل شيء بقاعدة بيانات،
ويمكنكم تسمية هذه الأشياء
بالجداول للتوضيح.
لكن الأهم من ذلك، باستخدام
قاعدة بيانات حقيقية، إذا جاز التعبير،
يجب أن تكونوا استباقيين أكثر
بشأن إخبار قاعدة البيانات
أي أنواع البيانات التي تريدون تخزينها.
الآن، هؤلاء الذين استخدموا
جداول بيانات Google وأرقام
apple وExcel يعلمون أنه يمكنكم
الانتقال إلى قائمة التنسيق أو قائمة البيانات
أو أيًا كان، ويمكنكم عرض
الأشياء في أماكن نقاط عشرية مختلفة.
يمكنكم تحويل الأشياء إلى نسب مئوية.
ويمكنكم تنسيق البيانات.

English: 
But that doesn't tend to have any
functional impact on your data.
It's just an aesthetic detail,
like, how long or short do
you want to show the numbers to
be in your columns and cells.
But with databases, you can
actually provide juicy hints
to the database that will help that
database store and find data for you
more efficiently.
For instance, there's this
laundry list of data types
to which we have access in SQL.
So SQL is the language with which we're
going to be able to query a database.
Frankly, in something like Google
Spreadsheets and Microsoft Excel,
how do you find data?
We'll usually hit Command-F or
Control-F, and you search for it.
That's not very programmatic.
You can do it with macros and such.
And we'll do this with code.
But with SQL, you're going to have
to make a few decisions first.
SQL supports a few different data
types, at least, in one of its forms.
So it turns out there's a
lot of competition out there.
SQL is a general language.
But different companies and
different nonprofit groups
have come up with their own dialects.
So much like we humans might speak--
bunches of us might speak Spanish.

Arabic: 
ولكن لا يميل ذلك إلى أن يكون له
أي تأثير وظيفي على بياناتكم.
إنه تفصيل جمالي فقط،
على سبيل المثال، مدى كبر أو صغر
الأرقام التي تريدون عرضها 
في الأعمدة والخلايا الخاصة بكم.
ولكن باستخدام قواعد البيانات، يمكنكم
في الواقع تقديم تلميحات هامة
إلى قاعدة البيانات التي ستساعد قاعدة البيانات هذه
في تخزين البيانات والعثور عليها من أجلكم
بشكل أكثر كفاءة.
على سبيل المثال، هناك قائمة
مُطولة من أنواع البيانات
التي لدينا حق الوصول إليها في SQL.
إذن SQL هي اللغة التي باستخدامها يمكننا
الاستعلام عن قاعدة بيانات.
بصراحة، في شيء مثل جدوال بيانات 
Google وMicrosoft Excel،
كيف يمكنكم العثور على البيانات؟
سنقوم عادة بالضغط على Command-F أو
Control-F، وستقومون بالبحث عنها.
هذا ليس أمرًا برمجيًا للغاية.
يمكنكم القيام بذلك باستخدام وحدات ماكرو وما شابه ذلك.
وسنقوم بذلك باستخدام تعليمة برمجية.
ولكن باستخدام SQL، يجب أن
تتخذوا بعض القرارات أولاً.
تدعم SQL بضعة أنواع مختلفة من
البيانات، على الأقل، في أحد أشكالها.
إذن يتضح أنه توجد
منافسة كبيرة هناك.
SQL هي لغة عامة.
ولكن قد توصّلت شركات مختلفة 
ومجموعات غير ربحية مختلفة
إلى لهجاتهم الخاصة.
لذا تشبه إلى حد كبير ما قد نتحدّث عنه نحن البشر--
قد تتحدث مجموعات منا باللغة الإسبانية.

Arabic: 
حسنًا، هناك اختلافات متنوعة
باللغة الأسبانية، بخلاف
العديد، والعديد، والعديد من اللغات الأخرى.
وهكذا بالمثل، في
عالم البرمجة،
نظرًا لوجود مجموعة فرعية شائعة
من الكلمات في لغة إلى حد ما.
ولكن بعد ذلك ربما قد قامت
شركات مختلفة وأشخاص
مختلفون بإضافة ميزاتهم الخاصة 
وطرحها فقط لأنهم يعتقدون
أن ذلك أفضل لحالات استخدامهم.
إذن في SQLite، وهي تقنية
قاعدة البيانات التي سنستخدمها في CS50 IDE،
ويستخدم Android هذه، وهي
شائعة للغاية في سياقات أخرى
أيضًا، IOS كذلك--
إنها تحتوي فقط على بعض الأنواع من البيانات.
البيانات الثنائية الكبيرة، من كل الأشياء، العدد الصحيح،
والرقمي، والحقيقي، والنص.
الآن ماذا يعني ذلك؟
حسنًا، يتضح أنه يعني أشياء
مختلفة باستخدام قواعد بيانات مختلفة.
في قاعدة بيانات شائعة أخرى، تُسمى
Postgres أو PostgreSQL.
هذه لغة شائعة للغاية
لمواقع الويب عالية الأداء.
إذن إذا كنتم تحاولون
إنشاء أعمال تجارية، فأنتم
تحاولون إنشاء تطبيق يتم استخدامه
من قِبل الجميع في الحرم الجامعي، بشكل عام،
ستستخدمون تقنية أفضل 
من SQLite، وهي، حسب التعريف،
خفيفة الوزن.
وستفعلون شيئًا مثل Postgres.
وهكذا سنقدم لكم
هاتين اللهجتين على طول الطريق
لأنه تتيح كل واحدة منها
لنا القيام بأشياء مختلفة
بدرجة دقة مختلفة.

English: 
Well, there are different variations
of Spanish, not to mention
many, many, many other languages.
And so similarly, in
the programming world,
as there's sort of a common
subset of words in a language.
But then different companies
and different people
might have added and subtracted their
own features just because they think
that's better for their use cases.
So in SQLite, which is the database
technology we will use in CS50 IDE,
and Android uses this, and it's
very popular in other contexts
too, IOS as well--
they only have a few data types.
Blob, of all things, integer,
numeric, real, and text.
Now what does that mean?
Well, it turns out, it means different
things with different databases.
In another popular database, it's
called Postgres or PostgreSQL.
This is a very popular one
for high-performing websites.
So if you're trying to
build a business, you're
trying to make an application used
by everyone on campus, generally,
you would use a fancier technology
than SQLite, which is, by definition,
lightweight.
And you'd do something like Postgres.
And so we'll introduce you to both
of these dialects along the way
because each of them allows
us to do different things
with a different degree of precision.

Arabic: 
إذن في SQL، دعونا نزعم، حتى
على الرغم من أنه تبسيط،
أن هناك على الأقل هذه الأنواع من البيانات.
عند تحديد نوع البيانات
المراد تخزينه في جدول قاعدة بياناتكم،
يجب أن تحددوا، ليس فقط ما يُسمى،
على سبيل المثال بالمعرّف، والاسم، والبريد الإلكتروني،
والسكن.
يجب أن تحددوا أي نوع من البيانات هو.
إذن لدينا دائرة مفرغة إلى حد ما.
لأن آخر مرة فعلنا فيها ذلك
كانت في أي لغة؟
C.
إذن تفعلون ذلك في SQL أيضًا،
ولكنها لا تتصيد الأخطاء.
إنها ستحسّن الأداء في الواقع.
إذن هذه لمساعدتكم في الحصول على
تلك البيانات بشكل أكثر كفاءة.
لأنه كلما عرف الخادم، وقاعدة
البيانات، بياناتكم،
كان بإمكانهما العثور عليها بسرعة وبشكل أساسي.
إذن في عالم
قواعد البيانات، يجب
أن تقرروا بشكل عام، ليس فقط لتخزين
عدد صحيح، ولكن
int صغير من العدد الصحيح، أو int كبير.
وبشكل عام، على الأقل في
معظم قواعد البيانات، قد تكون هذه وحدتي بايت.
قد تكون هذه 4 وحدات بايت.
قد تكون هذه 8 وحدات بايت.
إذن دعونا نثير إعجاب
الحضور هنا.
إذا كان لديكم عدد صحيح 
قدره 32 وحدة بت، أو 4 وحدات بايت،
ما هو أكبر عدد صحيح يمكنكم
تخزينه في قاعدة بياناتكم؟
(WHISPERS) 4 مليار.
شخص واحد من فضلكم، مثير للإعجاب.
الجمهور: 4 مليار.

English: 
So in SQL, let's claim, even
though it's a simplification,
there are at least these data types.
When deciding what type of data
to store in your database table,
you have to decide, not just what it's
called, like ID, and name, and email,
and dorm.
You have to decide what data type it is.
So we've kind of come full circle.
Because the last time we did
this was in what language?
C.
So in SQL too you do this,
but it's not to be nitpicky.
It's to actually improve performance.
So this is to help you get at
that data more efficiently.
Because the more the server, the
database, knows about your data,
the faster it can find it essentially.
So in the world of
databases, you generally
have to decide, not just to
store an integer, but either
a small int of integer, or a big int.
And generally speaking, at least in
most databases, this might be 2 bytes.
This might be 4 bytes.
This might be 8 bytes.
So let's maybe impress
the families here.
If you have a 32-bit
integer, or 4 bytes,
what's the biggest integer you
can store in your database?
(WHISPERS) 4 billion.
Someone please, impress.
AUDIENCE: 4 billion.

English: 
DAVID J. MALAN: 4 billion
is exactly correct.
And it might be 4 billion positive
values, or maybe it's only 2 billion
if you also want to have 2 billion
or so negative numbers as well.
Big int uses 64-bit, which is
just massively, massively bigger.
And tiny int or small int rather--
there's also tiny int in some
dialects-- small int is just 2 bytes,
and it actually counts up as high
as 65,535, as I alluded to earlier.
So you just need to decide.
Now, why would you choose one or the
other, when you could just use big int
and store small numbers
and big numbers alike?
Well, why might you just intuitively not
want to make all of your integer values
in a database big ints.
It's just simple-- give me
as much headroom as I want.
AUDIENCE: You would be using memory.
DAVID J. MALAN: Yeah.
You're just using memory
unnecessarily, right?
Why use more memory than you need to?
Now, arguably-- god, memory
is so cheap these days.
Computers are getting bigger and faster.
So in some contexts,
it's not a big deal.
But if you have lots of data, and
every one of your rows in a database
is 2 bytes bigger than needs to
be, and you have 1 million rows,

Arabic: 
ديفيد ج. مالان: 4 مليار
صحيح تمامًا.
وقد تكون 4 مليار من القيم
الإيجابية، أو ربما 2 مليار فقط
إذا كنتم تريدون أيضًا أن يكون لديكم 2
مليار أو ما يقارب ذلك من الأرقام السلبية أيضًا.
يستخدم int الكبير 64 وحدة بت، وهذا يُعد
كبيرًا، كبيرًا جدًا فقط.
وint ضئيل أو int صغير بدلاً من ذلك--
يوجد أيضًا int صغير في بعض اللهجات--
int صغير هو وحدتا بايت فقط،
وهو يحسب في الواقع شيئًا كبيرًا
كـ 65535، كما أشرتُ في وقت سابق.
إذن تحتاجون إلى اتخاذ القرار فقط.
الآن، لماذا ستختارون واحد أو الآخر،
بينما يمكنكم فقط استخدام int كبير
وتخزين أرقام صغيرة وأرقام
كبيرة على حد سواء؟
حسنًا، لماذا قد لا ترغبون ببساطة
في جعل جميع قيم الأعداد الصحيحة
في قاعدة بياناتكم أعدادًا صحيحة كبيرة.
إنه أمر بسيط-- أعطني مساحة
بالقدر الذي أريده.
الجمهور: ستستخدم الذاكرة.
ديفيد ج. مالان: أجل.
أنتم تستخدمون الذاكرة
دون داعٍ، أليس كذلك؟
لماذا تستخدمون الذاكرة بقدر أكبر مما تحتاجون إليه؟
الآن، بشكل مثير للجدل-- يا إلهي،
الذاكرة رخيصة جدًا هذه الأيام.
أصبحت أجهزة الكمبيوتر أكبر وأسرع.
لذا في بعض السياقات،
ليست مشكلة كبيرة.
ولكن إذا كانت لديكم بيانات كثيرة،
وكل صف من صفوفكم في قاعدة بيانات
أكبر بمقدار وحدتي بايت مما هو ضروري،
ولديكم مليون واحد من الصفوف،

Arabic: 
فهذه أعداد هائلة من
وحدات البايت التي تهدرونها
وتلقونها.
لذلك يجب أن تفكروا قليلاً
في أنواع البيانات هذه.
بالطبع، أنتم لا تريدون أن
تكون صغيرة للغاية،
لأنكم، إذا استخدمتم
int صغير أو ربما عددًا صحيحًا،
ولكن إذا كان العمل يسير بشكل جيد جدًا لدرجة
أن لديكم أكثر من 4 مليار مستخدم أو 4 مليار من الصفوف
أو 4 مليار من قيم foo وbar
وbaze التي تم بيعها،
وهذا بالتأكيد الذي يحدث
ببيانات Google وFacebook في العالم،
من الأفضل أن تبدأوا باستخدام 64 وحدة بت
لتمثيل قيم فريدة بدلاً من
32 فقط.
لأنه في نهاية المطاف، ستنفد منكم.
حسنًا، ماذا أيضًا؟
بالإضافة إلى القيم الصحيحة في SQL،
قد ترغبون في استخدام قيم كسرية حقيقية.
هذه أرقام حقيقية تحتوي
على نقاط عشرية.
هذا تمامًا مثل لغة C. إنها
تُسمى بشيء مختلف قليلاً.
وبشكل مزعج، تستخدم
كلمتين في هذه الحالة.
ولكن الرقم الحقيقي هو قيمة
قدرها 32 وحدة بت وهي قيمة كسرية
حقيقية، مثل float في C،
والدقة المزدوجة
مثل تلك المزدوجة في لغة C، وهي 64 وحدة بت.
ويتيح هذا لكم فقط الحصول
على تحكم دقيق أكثر
في النقطة العشرية كما رأينا.
لأنه بالطبع، لا يمكنكم تمثيل
الأرقام بشكل دقيق

English: 
that's already huge numbers of bytes
that you're just wasting and throwing
away.
So it behooves you to actually give
some thought to these data types.
Of course, you don't
want to go too small
because, if you use a small
int or maybe even an integer,
but business is so darn good that
you have over 4 billion users or 4
billion rows or 4 billion foos and
bars and bazes that have been sold,
which absolutely happens to the
Googles and Facebooks of the world,
you better start using 64 bits to
represent unique values instead of just
32.
Because eventually, you'll run out.
Well, what else?
Besides integer values in SQL, you
might want to use floating point values.
Those are real numbers that
have decimal points in them.
This is quite like C. They're
called a little something different.
And annoyingly, it uses
two words in this case.
But a real number is a 32-bit
value that is a floating point
value, like a float in
C, and double precision
is like a double in C, which is 64-bits.
And that just lets you get
even finer-grained control
over the decimal point as we've seen.
Because of course, you can't
represent numbers precisely

Arabic: 
بسبب عدم الدقة، كما رأينا
في Python وC.
رقمي هي كلمة شاملة لمجموعة
من الأشياء المتعلقة بالأرقام
وهي ليست أعدادًا صحيحة
أو حقيقية بالضرورة.
قيمة صحيحة أو خاطئة،
ومنطقية، التواريخ إذا كنتم تريدون
تخزينها حرفيًا، مثل، سنة، سنة، سنة، سنة،
شرطة، شهر، شهر،
شرطة، يوم، يوم
بتنسيق الكمبيوتر القياسي،
على الرغم من اختلاف الثقافات البشرية
في كيفية كتابة ذلك.
التاريخ والوقت إذا كنتم تريدون أن
يكون لديكم تاريخ ووقت بعده--
كلمة رقمي في الواقع هي
حل للمشكلة.
يتضح أنه، في النهاية،
بعد كل هذا الوقت،
لدينا آلية مدمجة
لتخزين الأرقام بدقة.
وهذا توقيته مثالي لأنه،
في CS50 Finance، عندما
تتعاملون مع النقود،
إذا لم تقوموا عن طريق الخطأ
بتقريب مقدار الأموال التي يملكها
شخص ما إما أقل أو
أكثر قليلاً.
ربما يوجد منكم مَن لديه تجمع على وجه الخصوص،
لأنه، بالعودة إلى بعض الأفلام في الماضي،
إذا رأيتم
فيلم سوبرمان 3،
فهذه هي الكيفية التي تم صنع
بعض المال بها عن طريق إزالة السنتات
من أنظمة الكمبيوتر، وبشكل
معتدل أكثر، Office Space.

English: 
because of imprecision, as
we've seen in both Python and C.
Numeric is kind of a catch-all for
a bunch of number-related things
that aren't quite integers
or reals necessarily.
Boolean, a true or false
value, dates if you
want to literally store, like, year,
year, year, year, dash, month, month,
dash, day, day in a
standard computer format,
even though human cultures
vary how they write that.
Datetime if you want have a
date and a time right after it--
numeric is actually a
solution to a problem.
Turns out that, finally,
after all this time,
we have a built-in mechanism
for storing numbers precisely.
And this is perfectly timed
because, in CS50 Finance, when
you're dealing with money, it would kind
of be nice if you don't accidentally
round off how much money someone has
either slightly lower or slightly
higher.
Those of you may be families especially
because, from a few movies back
in the day, if you
ever saw Superman III,
this is how some money was made
by shaving fractions of pennies
off of computer systems and,
more moderately, Office Space.

Arabic: 
قام Office Space بذلك أيضًا-- خدعة
كبيرة في محاولة تقريب هذه السنتات.
حسنًا، إذا كنتم تستخدمون التقنية
واللغة الصحيحتين، باستخدام SQL،
يمكنكم بالفعل تحديد نوع بيانات
رقمي، يشبه قيمة كسرية حقيقية،
ولكنكم تحددون، بشكل أساسي،
العدد الإجمالي للأرقام
التي تريدون معالجتها والعدد الذي
يجب أن يكون بعد النقطة العشرية منها.
لذا من الشائع في
أسواق الأسهم المالية استخدام
أربع نقاط عشرية من الدقة.
لذا ليست فقط السنتات إلى مكان
العشرات والمئات،
ولكن إلى مكان الآلاف
والعشرة آلاف،
يمكنكم الآن تحديد ذلك
باستخدام قيمة أربعة من الدقة.
ولا داعي للقلق 
بشأن أخطاء هذا التقريب
التي تحدثنا عنها من قبل.
الطوابع الزمنية والوقت--
فقط كم من الوقت
قد مر منذ التاريخ والتاريخ
والوقت يتوفران لكم أيضًا في SQL.
ثم أخيرًا هنا،
القيم النصية--
يتضح أن لديكم خيار
القيم عندما يتعلق الأمر
بتحديد عدد الأحرف التي
تستخدمونها لتخزين بياناتكم.
يمكنكم استخدام char، كما
هو الحال في C باستخدام مصفوفة،
يجب أن تقرروا مسبقًا
لسلسلة كم عدد وحدات البايت التي ستستخدمونها.
وإذا قلتم char 8،
فستحصلون على 8 وحدات بايت.
وإذا كان الاسم هو مالان،
م-ا-ل-ا-ن، فأنتم تهدرون 3 وحدات بايت،

English: 
Office Space did this as well-- big
scam trying to round off these pennies.
Well, if you use the right
technology and language, with SQL,
you can actually specify a numeric data
type, which is like a floating point
value, but you specify, essentially,
the total number of digits you
want it to handle and how many of them
should be after the decimal point.
So it's common in stock
markets to actually use
four decimal points of precision.
So not just cents to the tenths
and the hundredths place,
but to the thousandths
and ten-thousandths place,
you can now specify that with
a value of four for precision.
And you don't have to
worry about those round
off errors we talked about before.
Time and time stamps--
just how much time
has passed since the date and date and
time are also available to you in SQL.
And then lastly here, text values--
turns out you have a
choice of values for when
it comes to deciding how many characters
do you use to store your data.
You can use char, which just
like in C with an array,
you have to decide in advance for
a string how many bytes to use.
And if you say char 8,
you are getting 8 bytes.
And if the name is Malan,
M-A-L-A-N, you are wasting 3,

Arabic: 
أو إذا قمنا بإنهائها،
2 من وحدات البايت تلك.
لكن تقدم SQL حلاً
أعطته لنا Python أيضًا.
Varchar كما يوحي الاسم--
يتيح لكم عدد متغير من الأحرف
تحديد
الحد الأعلى فقط.
لذا إذا كنتم تعرفون أنه سيُطلق على أحد الأعمدة
الخاصة بكم الاسم.
وقد يكون اسم شخص ما هو
م-ا-ل-ا-ن-- على سبيل المثال خمسة أحرف،
أو ربما أكثر بالتأكيد بالنسبة للأشخاص الذين
لديهم ألقاب أطول وهي الأسماء الأولى،
يمكنكم قول varchar 100.
وهذا هو الحد الأعلى
لمقدار طوله.
لكن ستكون قاعدة البيانات ذكية.
إذا كنتم تحتاجون فقط إلى خمسة
أحرف أو 5 وحدات بايت،
فلن تهدر 95 حرفًا آخر من أجلكم.
وسيتحسن ذلك من أجلكم.
ومن ثم النص في النهاية، إذا أردتم
تخزين عشرات الآلاف،
مثل فقرات أو صفحات النص،
فهذه أكبر من varchar
حيث لا تريدون بالضرورة حدًا
أعلى تم تحديده بصورة جيدة.
تريدون فقط جزءًا جيدًا من الذاكرة.
ولكن توجد آثار هنا.
وبسرعة فقط، يبدو أن char
وvarchar ليستا تكميليتين.
يبدو أن char فقط غير ضرورية.
لماذا تضعوا أنفسكم في موقف حرج
وتقولوا
أعطني 8 وحدات بايت فقط بينما
يمكنكم فقط قول، أوه، أعطني

English: 
or if we null terminate
it, 2 of those bytes.
But SQL introduces a solution
that Python kind of gave us too.
Varchar as the name implies--
variable number of chars
allows you to specify
just an upper bound.
So if you know that one of your
columns is going to be called Name.
And a person's name might be
M-A-L-A-N-- like five letters,
or maybe certainly more for people
with longer last names are first names,
you can say varchar 100.
And that's the upper
bound on how long it is.
But the database will be smart.
If you only need five
characters or 5 bytes,
it won't waste 95 others for you.
It will optimize that for you.
And then lastly text, if you
want to store tens of thousands,
like paragraphs or pages of text,
that's even bigger than varchar
where you don't necessarily
want a well-defined upper bound.
You just want a good chunk of memory.
But there are implications here.
And just quickly, char and varchar
seem not even complimentary.
Just char seems unnecessary.
Why paint yourself into
a corner and say give me
only 8 bytes when you
could just say, eh, give me

Arabic: 
ما يصل إلى 100 وحدة بت،
وهل يمكنك، كخادم قاعدة البيانات،
اكتشاف عدد وحدات البايت التي استخدمها بالفعل؟
لمَ يوجد هذان النوعان من البيانات؟
أجل؟
الجمهور: الوقت.
ديفيد ج. مالان: الوقت.
الجمهور: سيكون أطول لتشغيله.
ديفيد ج. مالان: أجل.
لذا الوقت دقيق.
قد يستغرق استخدام نوع بيانات
واحد أو آخر وقتًا أطول.
كيف يمكن أن يحدث هذا؟
حسنًا، إذا كنت قد حصلتم على
قيمة مثل char حيث تحددون
عددًا دقيقًا من الأحرف مثل 8.
إذا فكرتم بشأن الأعمدة
في جداول بيانات Google وExcel،
فكل واحد من هذه الأعمدة،
تلك الخلايا هي بالضبط نفس العرض، أليس كذلك؟
إنها 8 وحدات بايت، 8 وحدات بايت مجددًا.
وبمجرد حصولك على
تعويضات ثابتة تمامًا--
هذا هو البايت 0، وهذا هو البايت 8، وهذا هو البايت 16،
وهذا هو البايت 24، وهذا هو البايت 32،
وما إلى ذلك،
يمكنكم إعادة تقديم القدرة
التي كانت لدينا في C باستخدام المصفوفات.
يمكنكم الوصول بشكل عشوائي لتقوموا
بعمليات حسابية بسيطة جدًا- الضرب،
والجمع، والطرح، يمكنكم الانتقال
إلى أي عنصر في عمود
إذا كان يستخدم نفس
عدد وحدات البايت لكل خلية.

English: 
up to 100 bites, and
you, the database server,
figure out how many to actually use?
Why do these two data types exist?
Yeah?
AUDIENCE: Time.
DAVID J. MALAN: Time.
AUDIENCE: It would be longer to run.
DAVID J. MALAN: Yeah.
So time is spot on.
It might actually take longer to
use one data type or the other.
How could that possibly be?
Well, if you've got a value
like char where you specify
a precise number of characters like 8.
If you think about the columns
in Google Spreadsheets and Excel,
every one of those columns, those
cells is exactly the same width, right?
It's 8 bytes, 8 bytes, 8 bytes, 8 bytes.
And as soon as you have
perfectly constant offsets--
this is byte 0, this is 8, this
is 16, this is 24, this is 32,
and so forth, you
reintroduce the capability
that in C we had with arrays.
You have random access doing simple,
simple arithmetic-- multiplication,
addition, and subtraction, you can
just jump to any element in a column
if it's using the same number
of bytes for every cell.

Arabic: 
ولكن باستخدام varchar، إذا احتجتم إلى
خلايا ضيقة صغيرة وخلايا واسعة،
فستحصلون على ما يُطلق
عليه مصفوفة غير متناسقة حيث
أحد جانبيها، الجانب
الأيسر، إذا جاز التعبير،
سوف يكون صلبًا ومستقيمًا جدًا.
لكن الجانب الآخر يختلف النوع
حسب طول الكلمة في هذا العمود.
ولوجهة نظركة بشأن الوقت،
سيستغرق جهاز الكمبيوتر وقتًا أكبر
للبحث في حقل varchar.
لأنه لا يمكن فقط الانتقال
إلى العنصر الثالث.
يجب أن تبحثوا
عنها جميعًا.
ولكن لحسن الحظ، في نهاية
اليوم، لا تقوم قواعد البيانات بذلك.
انها لا تتحول فقط
إلى البحث الخطي.
تتحول ملفات CSV، لأغراضنا،
إلى البحث الخطي.
إن السحر والملكية الفكرية
والخلطة السرية، إذا جاز التعبير،
التي تنتقل إلى قواعد البيانات--
خادم Oracle SQL، وMicrosoft
Access، وPostgres، وMySQL، وSQLite،
هي التي قررها علماء الكمبيوتر الأذكياء
حقًا لتنفيذ خوارزميات
وبنيات بيانات رائعة،
غالباً قائمة على الشجرة--
إذا كنتم تتذكرون مناقشتنا
بشأن الأشجار الثنائية
أو المحاولات على جداول علامات التجزئة
وبنيات البيانات الرائعة تلك-- لقد
أعدّوا هذه الأنواع من
بنيات البيانات والتصميمات
في برامج قواعد البيانات الخاصة بهم.

English: 
But with varchar, if you need to have
small narrow cells and wide cells,
you're going to have what's
called a ragged array where
one side of it, the
left-hand side, so to speak,
is going to be very straight and rigid.
But the other side my kind of vary based
on how long the word is in that column.
And to your point about time, it's
going to take the computer more time
to search a varchar field.
Because it can't just
jump to the third element.
It has to search all
of them, potentially.
But thankfully, at the end of
the day, databases don't do that.
They don't just devolve
into linear search.
CSVs devolve, for our
purposes, into linear search.
The magic and the intellectual property
and the secret sauce, so to speak,
that goes into databases--
Oracle SQL Server, Microsoft
Access, Postgres, MySQL, and SQLite
is that really smart computer scientists
have decided to implement algorithms
and fancy data structures,
often tree-based--
if you recall our
discussion of binary trees
or tries on a hash tables and those
fancier data structures-- they
had baked those kinds of
data structures and designs
into their database software.

English: 
They've made it freely available
or commercially available.
And so we now just have an
abstraction called a database
into which we can store data and
just read it, update it, write it,
and change it quickly without
having to implement all
of that low-level plumbing ourselves.
And so that's ultimately what
a database is going to give us.
But we have to actually have
access to a database to do that.
And we need to actually
decide first to help
the database by telling it what to store
where and how to store it as a type.
So why don't we do this?
Let me go ahead and do exactly
that with a couple of examples.
Let me go ahead and
open up CS50 IDE again,
our web-based programming environment.
And let me go into our Terminal window.
So for those unfamiliar, a terminal
window is just this black and white
or this blue and white window
in which you can type commands.
And rather than point and click
and double click on things,
you can only do things
textually in this window.
And it turns out that,
in the world of SQLite,
we can actually use a
command called SQLite3,

Arabic: 
لقد جعلوها متاحة مجانًا
أو متاحة تجاريًا.
وهكذا أصبح لدينا الآن فقط
تجريد يُسمى قاعدة بيانات
يمكننا تخزين البيانات وقراءتها
وتحديثها وكتابتها،
وتغييرها بسرعة فقط دون
الحاجة إلى تنفيذ كل هذه الأشياء
على مستوى منخفض بأنفسنا.
ولذا هذا ما ستقدمه لنا
قاعدة البيانات في النهاية.
ولكن يجب أن نمتلك حق
الوصول إلى قاعدة بيانات للقيام بذلك.
ونحتاج إلى
أن نقرر أولاً مساعدة
قاعدة البيانات من خلال إخبارها
بما يجب تخزينه وكيفية تخزينه كنوع.
لذا لمَ لا نفعل هذا؟
دعوني أمضي قدمًا وأقوم
بذلك بالضبط باستخدام بضعة أمثلة.
دعوني أمضي قدمًا
وأفتح CS50 IDE مجددًا،
بيئة البرمجة القائمة على الويب الخاصة بنا.
ودعوني أنتقل إلى النافذة الطرفية.
لذلك بالنسبة لمَن لم يعتادوا الأمر،
فإن النافذة الطرفية هي فقط تلك النافذة بالأبيض والأسود
أو هذه النافذة بالأبيض والأزرق
حيث يمكنكم كتابة الأوامر.
بدلًا من الإشارة والنقر والنقر
المزدوج فوق أشياء،
يمكنكم القيام فقط بالأشياء
نصيًا في هذه النافذة.
ويتضح أنه في
عالم SQLite،
يمكننا بالفعل استخدام
أمر يُسمى SQLite3،

Arabic: 
والذي يتيح لنا إنشاء قاعدة بيانات.
لذلك في عالمنا البشري، بالنسبة إلى
ملفات CSV، لاحظتم كيف يمكننا، في تعليمة برمجية،
فقط إنشاء صفوف وأعمدة.
يمكنكم كتابتها حرفيًا في مربع النص.
SQLite هي تقنية قاعدة بيانات
تستخدم التنسيق الثنائي، الأصفار والواحدات.
وبالتالي يجب أن تقوموا بالفعل
بتخزين بياناتكم بشكل مختلف
باستخدام برنامج.
لذلك إذا كنتم تريدون إنشاء ملف
يُسمى، على سبيل المثال، froshims.db،
يمكنني أن أقول حرفيًا SQLite
ثلاثة froshims.db،
ومن ثم أنا في هذا البرنامج.
هذا برنامج قائم على نص
يمكنني من خلاله إنشاء الصفوف والأعمدة.
وهذا، من خلال المصمم
سيكون غامضًا قليلاً للحظة.
سيبدو هذا مشفرًا قليلاً.
ولكن إذا أردتُ المضي قدمًا وإنشاء
جدول، مثل جدول البيانات هنا،
سأكتب حرفيًا نوع
CREATE TABLE.
سأستدعي المسجَّلين هذا
تمامًا كما في الأسبوع الماضي
عندما كنا ننظر في
أمثلة froshims.
ويحتوي برنامج الرياضة الداخلي
للطلاب الجدد
على طلاب يقومون بالتسجيل للرياضية.
ﻟذا سيكون لدي ﺟدول المسجَّلين هنا.
سأمضي قدمًا الآن
وأحدّد أنني أريد
بضعة أعمدة لجدول قاعدة البيانات هذا،
أحد الأعمدة أريد أن أُطلق عليه المعرّف،
وعمود ثاني أريد أن أسميه اسمًا،
وثالث أريد أن أسميه سكن.

English: 
which allows us to create a database.
So in our human world, for CSVs,
you've seen how, in code, you
can just create rows and columns.
You can literally type it in a text box.
SQLite is a database technology
that uses binary format, 0s and 1s.
And so you're going to have to
actually store your data differently
using a program.
So if I want to make a file
called, for instance, froshims.db,
I can literally say
SQLite three froshims.db,
and then I'm in this program.
This is a text-based program via which
I can create my rows and columns.
And it, by designer, is going to
be a little arcane for a moment.
It's going to look a little cryptic.
But if I want to go ahead and create
a table, like a spreadsheet in here,
I'm going to literally
type CREATE TABLE.
I'm going to call this
registrants just like last week
when we were looking
at froshims examples.
And the freshman
intramural sports program
has students registering for sports.
So I'm going to have a
registrants table here.
I'm going to go ahead
now and specify that I
want a few columns for this database
table, one of which I want to call ID,
one of which I want to call name,
and one of which I want to call dorm.

Arabic: 
لذا سأحتفظ- عذرًا.
لم أقصد الضغط على Enter.
دعوني فقط أنظف هذا.
لذا الآن لدي ثلاثة أعمدة
والمعرّف، والاسم، والسكن.
وإذا كنتُ سأضغط على Enter،
من الناحية النظرية،
فيجب أن يتم إنشاء قاعدة بيانات.
لن تكون بيانية مثل
جداول بيانات Google أو Excel،
ولكنها ستكون موجودة في IDE في
ملف يُسمى froshims.db.
ولكن لا يمكنني فقط الضغط على Enter بعد.
لأنه يجب أن أخبر
قاعدة البيانات أكثر قليلاً.
أنا أحتاج إلى إخبارها بذلك، أتعلمون ماذا؟
من المحتمل أنه يجب أن تكون قيمة
المعرّف الخاص بي عددًا صحيحًا.
أتعلمون ما الأمر؟
من المحتمل أنه يجب أن يكون
اسمي char، أو varchar؟
ما الذي يجب أن يتم تخزين
اسم الطالب عليه؟
الجمهور: varchar.
ديفيد ج. مالان: Varchar، حسنًا؟
إذن varchar لأنها
ستختلف، أليس كذلك؟
إذا أمكنكم التفكير في
مجموعات من أصدقائكم،
فربما تكون لديهم أسماء
قصيرة أو أسماء طويلة.
حسنًا، ما هو الحد الأعلى؟
ما هو مدى طول أطول
اسم من أسماء أصدقائكم؟
الجمهور: 50.
ديفيد ج. مالان: 16؟
حسنًا.
هل يوجد أي أحد هنا اسمه، الأول
والأخير، أطول من 16؟
الجمهور: إنه 50، معذرة.
ديفيد ج. مالان: أوه، 50.
معذرة.
اعتقدتُ، أنني سمعتُ 16.

English: 
So I'm going to keep-- whoops.
I didn't mean to hit Enter.
Let me just clean this up.
So now I have three
columns, ID, name, and dorm.
And if I were to hit
Enter, theoretically, it
should create a database.
It's not going to be graphical
like Excel or Google Spreadsheets,
but it will exist in my IDE
in a file called froshims.db.
But I can't just hit Enter yet.
Because I have to tell
the database a bit more.
I need to tell it that, you know what?
My ID value should
probably be an integer.
And you know what?
My name should probably
be char, or varchar?
What should the name of
a student be stored as?
AUDIENCE: varchar.
DAVID J. MALAN: Varchar, OK?
So varchar because they're
going to vary, right?
If you can think of
bunches of your friends,
they might have short
names or long names.
OK, what's the upper bound?
What's the length of your
friends' longest name?
AUDIENCE: 50.
DAVID J. MALAN: 16?
All right.
Is anyone in here having a name, first
name and last, that's longer than 16?
AUDIENCE: That's 50, sorry.
DAVID J. MALAN: Oh, 50.
Sorry.
I heard 16, I thought.

Arabic: 
لأنكم لن تتمكّنول
من التسجيل في froshims
لأنه سيتم اقتطاع
قاعدة البيانات.
وكملاحظة جانبية، إذا انتقلتم من قبل إلى
موقع ويب وحاولتم الكتابة في حقل
شكل وتوقفت لوحة المفاتيح
عن العمل
أو قمتم بكتابة كلمة طويلة أو
فقرة، ومن ثم ضغطتم على Enter،
فاختفى بعض مما كتبتم، حسنًا،
لأن قاعدة البيانات على الأرجح
يمكنها تخزين العديد من وحدات البايت فقط.
وبصراحة، هذا يحدث غالبًا
في منتديات خدمة العملاء، أليس كذلك؟
لا يريدون حقًا أن تقوموا
بالإسهاب مع فريق دعم
العملاء.
سيقومون بإخفاء طول
الحقل الذي تكتبون فيه.
وسيفعلون ذلك أيضًا
على قاعدة البيانات،
ولكن من المحتمل أيضًا أنهم
لأسباب شخصية عملية،
لا يريدون قراءة شكوى
كبيرة بهذا الحجم كذلك.
إذن 50--هل يوجد أي شخص اسمه
أطول من 50 حرفًا؟
الجمهور: [INAUDIBLE]
ديفيد ج. مالان: نعم، ليست أسماء عديدة.
ولكن أتعلمون ماذا؟
لدينا تقنية للإجابة عن ذلك.
أطول اسم في العالم--
وهو ذلك الرجل.
من المحتمل أن تكون موسوعة غينيس
للأرقام القياسية محقة.
إذن اسمه هو بارنابي مارمادوك
ألويسيوس بنغي كوبويب دارتانيان إغبرت

English: 
Because you're not going be
able to register for froshims
because the database
is going to truncate.
And as an aside, if you've ever gone to
a website and tried typing into a form
field and either your
keyboard stops working
or you do type a long word or
paragraph in, and then you hit Enter,
and it's some of it's gone, well,
that's because the database likely
can only store so many bytes.
And frankly, this often happens
on customer service forums, right?
They don't really want you being too
verbose with the customer support
staff.
They'll cap the length of the
field into which you're typing.
And they're also doing
that on the database,
but also probably for
practical human reasons,
they don't want to read a big
complaint that's this long as well.
So 50-- anyone have a name
longer than 50 characters?
AUDIENCE: [INAUDIBLE]
DAVID J. MALAN: Yeah, not many names.
But you know what?
We have technology to answer this.
Longest name in world--
and it's this guy.
Guinness Book of World
Records is probably right.
So his name is Barnaby Marmaduke
Aloysius Benjy Cobweb Dartagnan Egbert

Arabic: 
فيلكس غاسبر هامبرت إغناطيوس غايدن
كاسبر ليروي ماكسيمليان نيدي أوبياغلو
بيبين كيليام روزنكرانز سيكستون تيدي
يوبوود فيفاتما وايلاند آزيلون ياردلي
زكاري أوسنسكاي.
ومن الواضح أنه يُسمى نيك أيضًا.
لكن لا بأس.
دعوني أمضي قدمًا وأظلل ذلك.
ويمكنني عدّ ذلك يدويًا.
ولكنني متأكد من قيام شخص ما بإنشاء موقع ويب
لعدّ الأحرف في سلسلة.
ها نحن ذا، lettercount.com.
حسنًا.
دعونا نمضي قدمًا ونلصق ذلك،
نعدّ الأحرف، 225--
إذن لن يتم تسجيل نيك
ما لم تقوموا فقط بتدعيم 16 أو 50.
يبدو أننا بحاجة إلى 225 على الأقل.
إذن في مرحلة ما، يجب
أن تتخذوا قرارًا.
وبصراحة، لا يكون الأمر واضحًا دائمًا.
يجب أن تحددوا أن varchar
سيكون-- آه، يمكن أن يكون 16،
يمكن أن يكون 50، يمكن أن يكون 225.
ولكن أتعلمون ماذا؟ إذا كان لديه أطفال--
إذن دعونا فقط نقوم بالتقريب قليلاً 
ونسميه varchar 255، بصراحة،
فقط لأنه كان تقليدًا.
إذن في وقت سابق من اليوم، كان 255
يميل إلى أن يكون الحد الأقصى من الطول
لهذا الحقل في قواعد البيانات القديمة.
وهذه تبدو مساحة كافية على الأقل
للتلاعب بالأسماء على الأرجح.

English: 
Felix Gaspar Humbert Ignatius Jayden
Kasper Leroy Maximilian Neddy Obiajulu
Pepin Quilliam Rosenkranz Sexton Teddy
Upwood Vivatma Wayland Xylon Yardley
Zachary Usansky.
But he also goes by Nick, apparently.
But OK.
Let me go ahead and highlight this.
And I could count this manually.
But I'm sure someone has made a website
to count characters in a string.
There we go, lettercount.com.
OK.
Let's go ahead and paste that
in, count the characters, 225--
so nick will not be registering
unless we don't support just 16 or 50.
Looks like we need at least 225.
So at some point, you do
have to make a decision.
And honestly, it's not always obvious.
You do have to specify that varchar
is going to be-- eh, it could be 16,
could be 50, could be 225.
But you know what? if he has kids--
so let's just round up a bit and
call it varchar 255, honestly,
only because it was a convention.
So back in the day, 255
tended to be the max length
for this field in older databases.
And that at least feels like it's
probably enough wiggle room for names.

Arabic: 
ولكن يجب أن تتخذوا قرارًا
تحكيميًا في مرحلة ما.
يمكننا تجاهل المشكلة
بقول 1000 حرف.
ولكن إذا لم يحدث
هذا مطلقًا حقًا،
وعلى الأرجح تقومون بإهدار
المساحة، فعلى الأرجح لا يجب.
لأنه على الرغم من أنه الحد الأعلى،
فأنتم تضحون بشيء مثل الوقت،
على الأرجح، للبحث عن
ذلك الحقل إذا كنتم فقط
تقومون بإخبار قاعدة البيانات بأنها 
ستصبح أكبر مما ستكون
عليه بالفعل.
يجب أن تكون واضحة أكثر.
إذن ماذا عن السكن؟
يا إلهي، يجب أن نقوم بذلك مجددًا الآن.
كيف نفعل ذلك باستخدام السكن؟
ما هو المدى الأطول 
لسكن أو منزل في الحرم الجامعي؟
الجمهور: [INAUDIBLE]
ديفيد ج. مالان: أنا، على سبيل المثال،
حسنًا [INAUDIBLE]،، منزل ربما.
ولكن بصراحة، في مرحلة ما،
لا يهم الأمر كثيرًا.
لكن كونه متناسقًا هو ما يهم.
إنها مسألة أسلوب.
إنها مسألة تصميم.
في مرحلة ما، لا يجب
أن تتصيدوا أخطاء كل قيمة صغيرة.
ولكن ربما يجب أن
تختاروا قيمة معقولة
يمكنكم تبريرها لرفيق سكن أو
لزميل أو زميل تدريس.
ومن ثم لنقل هذا يبدو كافيًا
دون أن يكون بشكل مفرط في الواقع.
ويوجد شيء واحد أخير
سأفعله هنا هو فقط

English: 
But you have to make a
judgment call at some point.
We could ignore the problem
say 1,000 characters.
But if that's never
really going to happen,
and your potentially wasting
space, you probably shouldn't.
Because even though it's an upper bound,
you're sacrificing something like time,
potentially, to search
that field if you're just
telling the database that it's going
to be bigger than it ever actually
will be.
It needs to be more finely hinted.
So what about dorm?
Oh, god, now we have to do this again.
How do we do it with dorm?
What's the longest length of
a dorm or a house on campus?
AUDIENCE: [INAUDIBLE]
DAVID J. MALAN: I'm, like,
OK [INAUDIBLE],, house maybe.
But honestly, at some point,
it doesn't matter too much.
But being consistent is what matters.
It's a matter of style.
It's a matter of design.
At some point, you don't have
to nitpick every little value.
But you should probably
pick some reasonable value
that you could justify to a roommate or
to a colleague or to a teaching fellow.
And then say this feels like enough
without it being actually excessive.
And there's one last thing
I'm going to do here is just

Arabic: 
إنهاء فكرتي بفاصلة منقوطة.
أعتذر، لقد عادت.
ولكن في نهاية نقطة بدايتي هنا، إذا لم
أقم بارتكاب أي أخطاء مطبعية،
وسأمضي قدمًا وأضغط على Enter.
يبدو أن لا شيء يحدث.
وبشكل ساخر، في دورة CS50،
في البرمجة، لا يحدث عادة
أي شيء جيد لأن ذلك
يعني عدم حدوث أخطاء.
إذا قمتُ، في SQLite، بكتابة
المخطط، يمكنني في الواقع
رؤية إرتجاع الجدول
الذي قمتُ بإنشائه للتو.
ولكن الأهم من ذلك، يمكنني
البدء في إدخال البيانات في هذا.
الآن لسوء الحظ،
إنها ليست بيانية حتى الآن.
ولكن إذا أردتُ إدراج بيانات في هذا،
يمكنني القيام بذلك.
أدرج في المسجَّلين-- حسنًا،
ما الذي تريدون إدراجه؟
أريد المضي قدمًا وإدراج
معرّف، واسم، وسكن.
حسنًا، بأي قيم؟
حسنًا، بهذه القيم--
سيكون المعرّف-- سيكون
المُسجَّل الأول هو 1.
سيكون براين أول شخص يتم تسجيله.
وسكنه، براين أين كنت تعيش؟
براين: بالخارج في بيني بايكر.
ديفيد ج. مالان: بيني بايكر.
إذن هذا جيد.
قد يكون ذلك قريبًا من
أربع مرات كذلك.
لذا سأمضي قدمًا وأقوم بذلك.
ها هو مثال على عبارة SQL.
CREATE TABLE هو فعل
أو تعبير واحد يمكنك استخدامه.
INSERT INTO فعل آخر.

English: 
end my thought with a semicolon.
I apologize, they're back.
But at the end of my start here, if I
haven't made any typographical errors,
and I'm going to go and hit Enter.
Nothing seems to happen.
And ironically, in CS50, in
programming, nothing happening
is usually a good thing because
it means no errors have happened.
If, in SQLite, I type
schema, I can actually
just see a regurgitation of
the table I just created.
But more importantly, I can
start to insert data into this.
Now unfortunately,
it's not yet graphical.
But if I want to insert data
into this, I can do this.
INSERT INTO registrants-- well,
what do you want to insert?
I want to go ahead and insert
an ID, a name, and a dorm.
Well, with what values?
Well, with these values--
the ID will be-- the first
registrant will be 1.
The first one to register will be Brian.
And his dorm, Brian where did you live?
BRIAN: Out on Pennypacker.
DAVID J. MALAN: Pennypacker.
So it's good.
That might be close to
four timer too lengthwise.
So I'm going to go ahead and do this.
Here is an example of a SQL statement.
CREATE TABLE is one verb
or expression you can use.
INSERT INTO is another.

English: 
You specify the name of the table, the
fields of the table, and then values.
And now I'm capitalizing just to
make clear what are SQL commands
and what are actually just words
I, the human developer, chose.
But it's just a convention.
These uppercase words could probably
be lower case in most contexts too.
But it helps things, I think
visually, to distinguish.
Now I go ahead and enter.
Nothing seemed to happen.
That's probably a good thing.
Let's go ahead and
register one other person.
I'll be the second registrant.
So maybe David from Matthews.
And so Matthews here, Enter.
And now, if I want to select all
of the students in the database,
I can go ahead and say SELECT FROM--
or you know what?
Let's select everything as
denoted in many languages by star,
from registrants semicolon
enter, and there we have it.
It's kind of a tiny super
simple, lightweight database.
But there are my rows and
columns much like Excel
and Google Spreadsheets
would lay them out for me.
But it gets better than this.
Suppose I want to search this
database for all of the students who
registered for Matthews.

Arabic: 
تقومون بتحديد اسم الجدول،
وحقول الجدول، ومن ثم القيم.
والآن أقوم بالتكبير
فقط لتوضيح ما هي أوامر SQL
وما هي الكلمات فقط في الواقع،
التي اخترتُها، كمطوِّر.
ولكنه مجرد تقليد.
من المحتمل أن تكون هذه الكلمات المكتوبة بالأحرف
الكبيرة بأحرف صغيرة في معظم السياقات أيضًا.
لكنها تساعد الأشياء، على ما أعتقد
بشكل مرئي، في التمييز.
الآن سأمضي قدمًا وأقم بالإدخال.
يبدو أن لا شيء يحدث.
ربما هذا شيء جيد.
دعونا نمضي قدمًا
ونقوم بتسجيل شخص آخر.
سأكون المسجَّل الثاني.
لذا ربما ديفيد من ماثيوز.
إذن ماثيوز هنا، Enter.
والآن، إذا أردتُ تحديد جميع
الطلاب في قاعدة البيانات،
يمكنني المضي قدمًا وقول تحديد من--
أو أتعلمون ماذا؟
دعونا نختار كل شيء كما هو
معروف في لغات كثيرة من خلال نجمة،
من المسجَّلين فاصلة منقوطة
enter، ولدينا ذلك هناك.
إنها قاعدة بيانات خفيفة الوزن وبسيطة
وصغيرة جدًا إلى حد ما.
ولكن هناك صفوف وأعمدة كثيرة
تشبه إلى حد كبير جداول بيانات Excel
وGoogle
التي ستضعها من أجلي.
لكنها تصبح أفضل من هذا.
لنفترض أنني أريد البحث في قاعدة
البيانات هذه عن جميع الطلاب
المسجَّلين من ماثيوز.

English: 
And suppose that time
passes and more students
actually register for forshims.
I can actually filter this data.
I can do something like SELECT
star FROM registrants WHERE
dorm equals quote unquote, "Matthews."
And so I can filter it, hit Enter,
and now I get back just one row.
And if your should
mind starts to wander--
wow, if I could introduce
Python or JavaScript into this,
you know what I could do?
I could probably get back, not this
and this ASCII-based table, this text
table.
Maybe I could get back
an actual list of rows
so that I can actually do
something with that data.
And that's, indeed, where
we're going with this.
So if I want to select
someone else, I could do hmm--
maybe SELECT just the
NAME from registrants
where dorm equals "Mathews."
If I only care about
knowing who registered,
I could do that and whittle
it down to even less data.
So already, in just
these few commands, I
can express so much more functionality
than you could with a CSV.
To do this and CSV, you
would have had to write all
of these lines of Python code yourself.
What if Brian moved?
So Brian really didn't
like the Union dorm,

Arabic: 
ولنفترض أن الوقت يمر وأن
العديد من الطلاب
يسجّلون حقًا في forshims.
يمكنني تصفية هذه البيانات في الواقع.
يمكنني أن أفعل شيئًا مثل
تحديد نجمة من المسجَّلين حيث
سكن يساوي علامة اقتباس وعلامة إنهاء الاقتباس، "ماثيوز."
ولذا يمكنني تصفيتها، والضغط على
Enter، والآن استرجعتُ صفًا واحدًا فقط.
وإذا بدأ عقلك
في التساؤل--
مدهش، إذا كان بإمكاني تقديم
Python أو JavaScript في هذا،
أتعرفون ما يمكنني فعله؟
ربما يمكنني العودة، وليس هذا
وهذا الجدول القائم على ASCII، وجدول
النص هذا.
ربما يمكنني استعادة
قائمة صفوف فعلية
حتى أتمكن بالفعل من القيام
بشيء ما باستخدام هذه البيانات.
وهذا، في الواقع،
حيث سنمضي في هذا.
لذا إذا أردتُ تحديد
شخص آخر، فقد أتمكن من القيام اممم--
ربما تحديد الاسم
فقط من المسجَّلين
حيث سكنه يساوي "ماثيوز."
إذا كنتُ أهتم فقط
بمعرفة مَن تم تسجيله،
يمكنني القيام بذلك
وتقليصه إلى بيانات أقل.
لذلك بالفعل، في هذه الأوامر
القليلة فقط،
يمكنني التعبير عن دالات أكثر
مما يمكنكم القيام به باستخدام ملف CSV.
للقيام بهذا وCSV،
كان يجب أن تكتبوا جميع
هذه السطور من تعليمات Python البرمجية بأنفسكم.
ماذا لو انتقل براين؟
لذا، لم يعجب براين
بسكن الطلاب بالفعل،

Arabic: 
لذا سنمضي قدمًا ونستمر
في تحديث المسجَّلين
وتعيين السكن يساوي--
إلى أين تريد الانتقال؟
براين: Canaday.
ديفيد ج. مالان: "Canaday" حيث--
يمكنني القيام بذلك بطرق قليلة.
ما هو حدسك؟
كيف يمكنني تحديد
برين و براين فقط--
لا أريد الانتقال إلى Canaday.
كيف يمكننا نقل براين فقط؟
الجمهور: [INAUDIBLE]
ديفيد ج. مالان: أجل.
ربما يمكننا أن نقول أن الاسم
يساوي علامة اقتباس وعلامة إنهاء الاقتباس "براين" وEnter.
يعجبني هذا، لكن سيجد شخص ما
خطأ في هذا إذا أمكنك ذلك.
الجمهور: شخصان باسم براين.
ديفبد ج. مالان: إذا كان هناك
شخصان باسم يراين، سننقلهما
سننقل الثلاثة أشخاص.
لذلك ربما يكون أفضل،
بصراحة، أن نقول، مم،
دعونا نقول فقط أن المعرّف يساوي 1.
الآن، بالطبع، أحتاج إلى رقم
بطاقة هوية هارفرد الخاص ببراين أو أي شيء.
لكن هذا سيكون أكثر دقة.
لأن الافتراض هنا هو أن العمود الموجود
في أقصى اليسار أو حقل المعرّف،
حسب التقليد البشري،
يجب أن يكون فريدًا بحيث يعرّف
المساحة بشكل فريد حتى يمكننا الحصول
على أكبر عدد ممكن من الأشخاص باسم براين كما نريد،
لكن لن يختلط علينا الأمر بشأنهم.
إذا مضيتُ قدمًا وضغطتُ فوق
Enter الآن، فلن يحدث شيء.

English: 
so we're going to go ahead
and UPDATE registrants
and SET dorm equal to--
where do want to move to?
BRIAN: Canaday.
DAVID J. MALAN: "Canaday" WHERE--
I could do this a few ways.
What's your instinct?
How could I identify
Brian and only Brian so--
I don't want to move to Canaday.
How do we move just Brian?
AUDIENCE: [INAUDIBLE]
DAVID J. MALAN: Yeah.
Maybe we could WHERE name equals
quote unquote "Brian" and Enter.
I like this, but someone find
fault with this if you could.
AUDIENCE: Two Brians.
DAVID J. MALAN: If there are two
Brians, we're moving both of them
are all three of them.
So maybe better, honestly,
would be to say, mm,
let's just say where the ID equals 1.
Now, of course, I need to know
Brian's Harvard ID number or whatnot.
But this is going to be more precise.
Because the supposition here is
that the leftmost column or ID
field, by human convention, should be
unique so that it uniquely identifies
the room so we can have
as many Brians as we want,
but we're not going to confuse them.
If I go ahead and hit Enter
now, nothing seems to happen.

English: 
But if I select star from registrants
again, and hit Enter, notice now,
Brian has indeed been moved to Canaday.
So there are so many other things.
Brian, you know what?
You're not very good at
sports the team concluded.
So delete from registrants
WHERE ID equals 1.
And now if we select star from
registrants, we have just me left.
But Brian is gone as well.
So we have the ability to INSERT,
to SELECT, to UPDATE, and DELETE,
and CREATE, all the while filtering.
And we've only just scratched the
surface here of what's possible.
Because it turns out, we can store
so much data in these databases.
All of our students,
all of our faculty--
if you're a company,
you can start to store
all of the products in your
database, all of the orders,
all of your customers.
But as soon as you start going down
that road, well, gee, what's a customer?
Customers have names and ID
numbers and maybe email addresses
and postal addresses.
Those are going to get
messy-- phone numbers,
which are kind of like
integers, but not quite.
So there are so many questions
we still need to answer.
But feels like it's time for
some fruit and some muffins.
So why don't we go ahead and take a
five-minute break, turn on some music.

Arabic: 
ولكن إذا قمتُ بتحديد نجمة من المسجَّلين مرة
أخرى، وضغطتُ فوق Enter، لاحظوا الآن،
تم نقل براين بالفعل إلى Canaday.
لذا هناك الكثير من الأشياء الأخرى.
براين، أتعرف ماذا؟
أنت لستَ جيدًا
جدًا في الرياضة لقد اكتمل الفريق.
لذا سيتم حذفك من المسجَّلين
حيث المعرّف يساوي 1.
والآن إذا حدّدنا نجمة من
المسجَّلين، لقد تبقيتُ أنا فقط.
لكن تم نقل براين أيضًا.
لذا لدينا القدرة على إدراج
وتحديد وتحديث وحذف،
وإنشاء، كل ذلك أثناء التصفية.
ونحن فقط بدأنا في
سكراتش بالسطح هنا لما هو ممكن.
لأنه يتضح أنه، يمكننا تخزين الكثير
من البيانات في قواعد البيانات هذه.
جميع طلابنا،
جميع مَن في الكلية--
إذا كنتم شركة،
يمكنكم البدء بتخزين
جميع المنتجات في قاعدة بياناتكم،
جميع الطلبات،
جميع العملاء.
ولكن بمجرد أن تبدأ بالسير في
هذا الطريق، حسنًا ، يا إلهي، ما هو العميل؟
لدى العملاء أسماء وأرقام الهوية
وربما عناوين البريد الإلكتروني
والعناوين البريدية.
ستصبح هذه الأمور فوضوية--
أرقام هواتف،
تشبه الأعداد الصحيحة إلى حد ما،
لكن ليس تمامًا.
لذلك هناك العديد من الأسئلة التي
ما نزال نحتاج إلى الإجابة عليها.
ولكن يبدو أنه حان الوقت
لبعض الفاكهة وبعض الكعك.
لذا لمَ لا نمضي قدمًا ونأخذ استراحة
لمدة خمس دقائق، ونقوم بتشغيل بعض الموسيقى.

English: 
If parents need to depart, that's fine.
And we'll see you back
here in five or so minutes.
All right.
So we're back.
And where we left off
was exactly here using
SQLite3, which is the version
3 of the SQLite command, which
is just a text-based
interface to the technology
that we should think of as SQLite.
SQLite is interesting and
it's lightweight in the sense
that it's not a server, it's not
fancy software that you have to run.
It literally stores all of your data
in a file, but that, by convention,
ends in .db or maybe even .sqlite.
But it's just a binary file, 0s and 1s.
It's not text that you can open
with Excel or something like that.
So it's not a CSV.
So it's stored on file.
This means that you don't
need particular experience
with setting up a database server.
You don't need memory and software
to actually run on the computer.
You can store everything
locally, but you do pay a price.
Because recall from our past
discussions, disks are slow.
And if you're storing
your data on the disk,
it's not going to be nearly as
fast as storing it only in RAM.
And that's why these other
technologies like Postgres and MySQL,

Arabic: 
إذا احتاج الآباء إلى المغادرة، فلا بأس بذلك.
وسنراكم هنا بعد
خمس دقائق أو عدة دقائق.
حسنًا.
حسنًا لقد عدنا.
وكنا قد توقفنا بالضبط
هنا حيث نستخدم
SQLite3، الإصدار 3
من أمر SQLite، وهو
مجرد واجهة
نصية للتقنية
التي يجب أن نفكر فيها على أنها SQLite.
SQLite مثير للاهتمام وخفيف
الوزن بمعنى أنه ليس خادمًا،
إنه ليس برنامجًا
خياليًا يجب أن تقوم بتشغيله.
إنه يخزِّن حرفيًا جميع البيانات الخاصة
بك في ملف، ولكن، حسب التقليد،
ينتهي بـ .db أو ربما .sqlite.
ولكنه مجرد ملف ثنائي، أصفار وواحدات.
إنه ليس نصًا يمكنك فتحه باستخدام
Excel أو شيء من هذا القبيل.
لذا إنه ليس CSV.
لذا يتم تخزينه في ملف.
هذا يعني أنك لا تحتاجون
إلى خبرة خاصة
في إعداد خادم قاعدة البيانات.
لا تحتاجون إلى الذاكرة والبرامج
لتشغيله على جهاز الكمبيوتر بالفعل.
يمكنكم تخزين كل شيء
محليًا، ولكنكم ستدفعون الثمن.
لأنه تذكرون من مناقشاتنا
السابقة، كانت الأقراص بطيئة.
وإذا كنتم تقومون بتخزين
بياناتكم على القرص،
فلن تكون بنفس سرعة تخزينها في
ذاكرة الوصول العشوائي فقط.
وهذا هو السبب وراء وجود تقنيات
أخرى مثل Postgres وMySQL وMicrosoft Access

English: 
and Microsoft Access, and
SQL Server, and Oracle exist.
Those are fancier products where someone
literally does double-click an icon
or run a command that
runs a program that
stays running in the computer's memory
and gives you even better performance.
But for our purposes,
pedagogically SQLite is handy.
But we're still going to ask
the questions about data types
because SQLite does support fancier
data types like those in Postgres
and SQL Server, MySQL, and Oracle,
and those are the lower-case ones
we introduced a bit ago.
But honestly, this is going
to get tedious quickly.
Even I rarely remember exactly the
right syntax when creating tables,
the order in which everything has to go.
So I tend to use a Graphical
User Interface, or GUI myself.
And there are lots of tools out there.
But we've built one that's
free and open source the CS50
IDE that just makes it a little
easier to edit your SQL tables.
So I'm going to go ahead
and Exit out of SQLite.
And I'm going to go ahead over here.
And you'll notice that
we have all of the files
from today including, most
recently, froshims.db.

Arabic: 
وخادم SQL وOracle.
تلك منتجات رائعة حيث يقوم
شخص ما حرفيًا بالنقر المزدوج فوق رمز
أو تشغيل أمر
يقوم بتشغيل برنامج
يظل يعمل في ذاكرة
الكمبيوتر ويعطيك أداء أفضل.
ولكن بالنسبة لأغراضنا، SQLite من
الناحية الموضوعية مفيد.
ولكننا سنستمر في طرح
الأسئلة حول أنواع البيانات
لأن SQLite تدعم أنواع البيانات الرائجة أكثر
مثل تلك الموجودة في Postgres
وخادم SQL، وMySQL، وOracle،
وهذه هي الأمور المكتوبة بالأدوات الصغيرة
التي قدمناها قبل قليل.
لكن بصراحة، سيصبح هذا
مملاً بسرعة.
حتى أنا نادرًا ما أتذكر بالضبط الصيغة
الصحيحة عند إنشاء الجداول،
الترتيب الذي يجب أن يتم عليه كل شيء.
لذلك أميل إلى استخدام واجهة المستخدم
الرسومية أو GUI بنفسي.
وهناك الكثير من الأدوات هناك.
ولكننا قمنا بإنشاء واحدة مجانية
ومفتوحة المصدر CS50 IDE
التي تجعل تحرير جداول SQL الخاصة بك
أسهل قليلاً.
لذا سأمضي قدمًا
وأخرج من SQLite.
وسأمضي قدمًا إلى هنا.
وستلاحظون أن لدينا جميع الملفات
من اليوم بما في ذلك،
الملف الأخير،
froshims.db.

Arabic: 
هذا هو الملف الذي قمتُ بإنشائه باستخدام SQLite3.
ولكن إذا قمتُ بالنقر المزدوج فوقه
عند استخدام CS50 IDE،
فسيقوم بفتح برنامج يُسمى
phpLiteAdmin.
يصادف أنه تتم مكتوبته
بلغة أخرى تُسمى PHP،
ولا علاقة لها بقواعد البيانات،
فقط اسم المنتج هنا.
لكنها أداة تستخدم جداول
HTML البسيطة جدًا،
تمنحنا فقط واجهة مستخدم رسومية
على نفس الدالة بالضبط.
وبشكل شخصي، أجد هذا
أسهل في الاستخدام.
ومن الناحية الموضوعية،
سيكون الأمر أفضل
لأنه سيعرض لنا أنواع
البيانات المتاحة لجدولنا.
لذا على سبيل المثال، لاحظوا هنا--
هناك الكثير على الشاشة.
لكن الكثير من هذا
مجرد تفاصيل غير مثيرة للاهتمام.
لكن لاحظوا هنا، أرى
جدولاً يسمى المُسجَّلون.
ومن ثم يمكنني تصفحه.
يمكنني رؤية بنيته.
يمكنني تنفيذ SQL يدويًا
عن طريق كتابتها.
يمكنني البحث عنها، إدراج.
يمكنني أن أقوم بمجموعة أشياء بها.
هذا هو السبب في أن واجهة
المستخدم الرسومية هذه مناسبة فقط.
دعوني أمضي قدمًا
وأضغط فوق المُسجَّلون.
وبشكل افتراضي، سترون علامات التبويب
هذه الآن، تصفح، وبنية، وSQL،
ومن ثم مجموعة علامات أخرى.
ولاحظوا هنا.

English: 
That is the file I created with SQLite3.
But if you double-click
it when using CS50 IDE,
it's actually going to open a
program that's called phpLiteAdmin.
It happens to be written in
another language called PHP,
has nothing to do with databases,
just the name of the product here.
But it's a tool that, using
pretty simple HTML tables,
just gives us a graphical user interface
over the exact same functionality.
And personally, I just
find this easier to use.
And pedagogically,
it's going to be better
because it's going to show us the
available data types for our table.
So for instance, notice here--
there's a lot going on the screen.
But a lot of this is just
uninteresting details.
But notice here, I see a
table called registrants.
And then I can browse it.
I can see its structure.
I can execute manual
SQL by typing it in.
I can search it, insert.
I can do bunches of things to it.
And that's why this graphical
user interface is just convenient.
Let me go ahead and
click on registrants.
And by default, you'll see these tabs
now, Browse, Structure, SQL, and then
a bunch of others.
And notice over here.

Arabic: 
سترون الصف الوحيد والمُسجَّل
الوحيد الذي يبقى بالفعل.
لأنه عندما غادرنا آخر مرة،
أزلنا براين بشكل قسري من الفريق.
لذا لنفترض أنني أريد المضي قدمًا
وإضافة المزيد من الصفوف
فقط من أجل المناقشة.
يمكنني فقط القيام بذلك يدويًا هنا.
يمكنني الانتقال إلى هنا ويمكنني
القول، لنفترض أن اللاعب الثالث
سيكون فيرونيكا.
أعتقد أنها كانت أيضًا في ماثيوز
لذا يمكنني كتابة ذلك هنا.
ويمكنني فقط المضي قدمًا
والنقر على إدراج.
ولكن ما هو لطيف بشأن
phpLiteAdmin هو أنه لن يقوم فقط
بإدراج الصفوف من أجلكم،
بل سيعرض لكم التعليمة
sQLite البرمجية التي يمكنكم
القيام بها بأنفسكم.
لذا فهذا تعزيز بصري لطيف
لهذا الأمر نفسه بالضبط.
وستلاحظون أنها تستخدم علامات اقتباس مزدوجة
بدلاً من علامات الاقتباس الفردية الخاصة بي من قبل.
إنها قابلة للتبادل أحيانًا،
لكن ليس بشكل دائم.
لذا هي طريقة رائعة فقط لتعلم
كيفية القيام بذلك بالفعل
باستخدام تعليمة SQL البرمجية
الصحيحة لذا لن تقوموا بتبسيطها
باستخدام واجهة المستخدم الرسومية.
ولكن أتعرفون ماذا؟
لنقم بذلك.
سأمضي قدمًا
وأبدأ لأنني
أريد اتخاذ قرارات أفضل.
سأمضي قدمًا، حرفيًا،
وأنقر بزر الماوس الأيمن أو أنقر بزر التحكم فوق هذا،
وأحذف froshims.db.

English: 
You'll see the one row and the one
registrant who actually remains.
Because when we last left off, we
removed Brian forcibly from the team.
So suppose I want to go
ahead and add more rows just
for the sake of discussion.
I can just do it manually here.
I can go in here and I can
say, let's say the third player
is going to be Veronica.
I think she was also in Matthews
so I can just type that in here.
And I can just go
ahead and click Insert.
But what's nice about phpLiteAdmin
is that it will not only
insert the rows for
you, it will show you
the SQLite code with which you
could have done it yourself.
So it's a nice visual reinforcement
of that exact same command.
And you'll notice they use double quotes
instead of my single quotes before.
They're sometimes
interchangeable, but not always.
So it's a wonderful way of just
learning how you can actually
do this with the right SQL code
so you're not oversimplifying it
with the GUI.
But you know what?
Let's do this.
I'm going to go ahead
and start over because I
want to make some better decisions.
I'm going to go ahead and, literally,
right-click or Control-click
this, delete froshims.db.

English: 
And let's actually
start this from scratch.
Now previously when I
did this, I could have,
in my Terminal window, gone ahead and
done SQLite3 and then, what was it?
Froshims.db and created the file.
For now, I'm going to actually
just go ahead and touch
a file called that name,
which is a simple command that
just literally creates it,
but puts nothing in it,
just so I have an empty file.
And you'll see that it
just popped up again
on the left-hand side, which is handy.
And now I can double-click this version
of it, which has nothing in it yet.
And I'm back to phpLiteAdmin.
But notice no table in database.
So let's start to ask some
of the harder questions
as to actually how to
create data in a database.
So let me go ahead and go
to this field here-- create
new table on database froshims.
I'll go ahead and call
it registrants again.
But how many fields?
So let's go with ID,
name, and dorm, what else?
Email I heard earlier.
Age I heard earlier.
AUDIENCE: Sports you want to be in.
DAVID J. MALAN: Sorry.
So sports you want-- excuse me--
sports you want to be in.

Arabic: 
ودعونا بالفعل نبدأ
من سكراتش.
الآن في السابق عندما
قمتُ بهذا، كان بإمكاني المضي قدمًا،
في النافذة الطرفية الخاصة بي،
وإنهاء SQLite3 وبعد ذلك، ما كان ذلك؟
Froshims.db وأقوم بإنشاء الملف.
في الوقت الحالي، سأمضي قدمًا
فقط في الواقع وأنقر فوق
ملف يُسمى بهذا الاسم،
وهو أمر بسيط
يقوم بإنشاؤه حرفيًا، لكنه
لا يضع أي شيء فيه،
لذا لدي ملف فارغ.
وسترون أنه انبث
مجددًا فقط على
الجانب الأيسر، وهو مفيد.
والآن يمكنني النقر بشكل مزدوج فوق هذا الإصدار
منه، وهو لا يحتوي على أي شيء بعد.
وها قد عدتُ إلى phpLiteAdmin.
لكن لاحظوا أنه لا يوجد جدول في قاعدة البيانات.
لذا لنبدأ في طرح
بعض الأسئلة الصعبة
بالفعل حول كيفية إنشاء البيانات
في قاعدة البيانات.
لذا دعوني أمضي قدمًا وأنتقل
إلى هذا الحقل هنا-- وأقوم بإنشاء
جدول جديد على قاعدة البيانات froshims.
سأمضي قدمًا وأطلق عليه
المُسجَّلون مجددًا.
لكن كم عدد الحقول؟
لذا دعونا نحدّد المعرّف،
والاسم، والسكن، ماذا أيضًا؟
البريد الإلكتروني سمعتُه في وقت سابق.
العمر سمعتُه في وقت سابق.
الجمهور: الرياضة التي تريد الانضمام إليها.
ديفيد ج. مالان: معذرة.
لذا الرياضة التي تريد-- عذرًا--
الرياضة التي تريد الانضمام إليها.

Arabic: 
حسنًا. ستة حقول، ستة حقول،
دعونا نكمل ذلك.
إذن، في الواقع، أتعرفون ماذا؟
سبعة حقول.
أريد أرقام الهواتف أيضًا هذه المرة.
لذا دعوني أمضي قُدمًا وأضغط فوق Go.
والآن سترون فقط طريقة GUI
لطلب جميع الإجابات
على الأسئلة نفسها منكم كما كان الأمر من قبل.
وربما هذا أكثر وضوحًا.
وربما لا.
لكن لا يوجد بديل
عن حفظ
ما تحتاج أن تكون عليه الأوامر بالضبط.
لذا من الأعلى إلى الأسفل، في ما يلي
جميع الحقول التي أحتاج إلى اتخاذ قرار بشأنها.
بشكل ساخر، الحقول
هي مجرد كلمة مرادفة للأعمدة.
ومع ذلك، يتم حاليًا وضع
أعمدتي في صفوف،
ولكن هذه مجرد مشكلة في واجهة المستخدم.
لذا دعوني أمضي قدمًا وأقرر.
حسب التقليد، يكون حقلي الأول
دائمًا المعرّف أو ربما يجب أن يكون كذلك.
وسنرى لماذا هذا
قوي وقليل فقط.
يجب أن يكون نوع البيانات لذلك،
حسب التقليد، عددًا صحيحًا،
ما لم يكن لديكم الكثير من
البيانات مثل Facebook،
ومن ثم قد يكون العدد الصحيح الكبير منطقيًا أكثر.
ولكن لاحظوا أن هذه القائمة
المنسدلة تعطينا في الواقع
قائمة لطيفة من الخيارات كما كان الأمر من قبل.
وسترون في النص
باللون الرمادي، الفئة،
أو بمصطلحات منمقة، تقارب
هذه الأنواع المختلفة في SQLite
وفي الكلمات المكتوبة
بالأسود وبأحرف صغيرة،سترون

English: 
OK. six fields, six
fields, let's go with that.
So it's, actually, you know what?
Seven fields.
I want phone numbers too this time.
So let me go ahead and click Go.
And now you'll see just a GUI way
of prompting you for all the answers
to the same questions as before.
And maybe this is clearer.
Maybe it's not.
But just no alternative
to the memorizing
exactly what the commands need to be.
So top to bottom, here are all of
the fields I need to decide on.
Ironically, the fields is
just a synonym for columns.
And yet my columns are
currently laid out in rows,
but that's just a UI issue.
So let me go ahead and decide.
By convention, my first field is
almost always ID or probably should be.
And we'll see why this is
powerful and just a little bit.
The data type for that, by
convention, should be integer,
unless you've got a lot
of data like a Facebook,
and then big int might make more sense.
But notice this Dropdown
actually gives us
a nice menu of options just as before.
And you'll see in gray
text, the category,
or in fancy terms, the affinity
of these various types in SQLite
and in lower case black
words here, you'll

English: 
see the actual data type supported by
big popular databases like Postgres
that you might want to use
for your final projects.
In fact, we're
introducing these with eye
toward your using these for final
projects in the cloud, not in CS50 IDE,
but actually getting
your own domain name
and putting your website, if
you do a web app, out there.
So here, we have all
of my available types.
And under Integer, I'm going to go ahead
and literally choose Integer for my ID.
All right.
Next, go ahead and Zoom Out.
Let me go ahead and
choose a student's name.
Before did we do did we
decide on char or varchar?
AUDIENCE: varchar.
DAVID J. MALAN: OK,
varchar, and what size?
AUDIENCE: 255.
DAVID J. MALAN: 255.
So the user interface here
just allows me to type it in.
So the syntax is a little different
because it's a GUI, but 255.
But you know what?
The last field was dorm.
That too, I think we said varchar.
So let me choose that.
And 255, though, this one's
a little more debatable.
I'm not sure what the right number
is, so in the absence of clarity,
I'm just going to standardize on some
same value without being too wasteful.
But notice there are a few questions
here that we haven't come to.
But our perfect segue
earlier hinted at this.
It turns out, you need to
make a few other decisions
when designing a database.

Arabic: 
نوع البيانات الفعلي المدعوم من قِبل قواعد
بيانات شائعة كبيرة مثل Postgres
التي قد ترغبون في استخدامها
لمشاريعكم النهائية.
في الواقع، نحن نضع
هذه الأمور بعين الاعتبار
لكي تستخدموا هذه في المشاريع النهائية
في السحابة، وليس في CS50 IDE،
ولكن في الواقع للحصول
على اسم المجال الخاص بكم
ووضع موقع الويب الخاص بكم،
إذا قمتم بتطبيق ويب، هناك.
لذا هنا، لدينا كل
الأنواع المتاحة.
وأسفل العدد الصحيح، سأمضي قدمًا وأختار
حرفيًا عدد صحيح للمعرّف الخاص بي.
حسنًا.
التالي، أمضي قدمًا وأقوم بالتصغير.
دعوني أمضي قدمًا
وأختار اسم طالب.
قبل أن نفعل ذلك
هل قررنا بشأن char أو varchar؟
الجمهور: varchar.
ديفيد ج. مالان: حسنًا،
varchar، وبأي حجم؟
الجمهور: 255.
ديفيد ج. مالان: 255.
لذا فإن واجهة المستخدم هنا
تسمح لي فقط بكتابتها.
وبالتالي فإن الصيغة تختلف قليلاً
لأنها GUI، ولكن 255.
لكن أتعرفون ماذا؟
كان الحقل الأخير هو السكن.
هذا أيضًا، أعتقد أننا قلنا varchar.
لذا دعوني أختار ذلك.
و255، على الرغم من أن هذا
أحد الأمور الخلافية بشكل كبير قليلاً.
لستُ متأكدًا ما هو الرقم الصحيح،
لذا في حالة عدم وضوح الأمر،
سأقوم فقط بتوحيد القيمة
نفسها دون أن تكون مهدرة للغاية.
لكن لاحظوا أن هناك بعض الأسئلة
هنا لم نحدّد إجابتها بعد.
لكن أشار تحولنا المثالي في
وقت سابق إلى هذا.
يتضح أنكم، تحتاجون إلى
اتخاذ بعض القرارات الأخرى
عند تصميم قاعدة بيانات.

Arabic: 
إذا كنتم تعرفون مسبقًا
أن أحد الحقول
هو الجزء الأساسي من
البيانات لتحديد المستخدمين بشكل فريد،
فهذا هو ما
يسمى بمفتاح أساسي--
العمود أو الحقول التي، تضمن،
تحديد المستخدمين بشكل فريد.
لذا إذا كان لديكم شخصين باسم براين،
فإن كل واحد منهما سيكون له معرّفه الخاص.
لذلك، هو مفتاحك الأساسي،
وليس حقل الاسم براين.
لذلك سأقوم بإخبار قاعدة البيانات،
هذا هو المفتاح الأساسي.
وستساعدني
في تتبع هذا الطابع الفريد.
علاوة على ذلك، هذه ميزة خيالية.
قبل ذلك، كنت أقول
بشكل يدوي وتعسفي جدًا
أن براين سيكون رقم 1، سأكون
رقم 2، وستكون فيرونيكا رقم 3.
هذا مُمل.
على سبيل المثال، يجب أن يكون الكمبيوتر
قادرًا على حل هذه المشكلة من أجلي.
لا أريد أن أفكر في
ما هو رقم الفكرة.
يمكنكم زيادة الحقل تلقائيًا.
لذا، إذا قمتُ بالفعل بفحص
هذا المربع، فإن SQL
ستقوم بكتابة فقط زائد-زائد، زائد-زائد
حقل الفكرة في كل مرة
وسأدرج اسم جديد وسكن جديد.
لستُ مضطرًا حتى إلى أن أتحمّل عناء
تحديد المعرّف بعد الآن.
الآن هناك عمود
آخر هنا، ليس فارغًا،
حيث يمكنكم تحديد أن هذا
العمود يجب ألا يكون فارغًا أبدًا.
وهذا أمر هام لأنه إذا كنتم تقومون بإنشاء
موقع ويب يحتوي على بيانات هامة

English: 
If you know in advance
that one of your fields
is the primary piece of data
to uniquely identify users,
that's what's going to
be called a primary key--
the column or fields that, guaranteed,
is going to identify users uniquely.
So if you've got two Brians, each
of them is going to have its own ID.
That therefore, is your primary
key, not the name field Brian.
So I'm going to tell the
database, this is the primary key.
And it's going to help me
keep track of that uniqueness.
Moreover, this is a fancy feature.
Before, I was manually
and very arbitrarily
saying Brian will be number 1, I'll be
number 2, Veronica will be number 3.
That's tedious.
Like, computer should be able
to solve that problem for me.
I don't want to think about
who is idea number what.
You can auto-increment the field.
So if I actually check
this box, SQL for me
will just plus-plus, plus-plus
the idea field every time
I insert a new name and a new dorm.
I don't have to even bother
specifying an ID anymore.
Now there's another
column here, not null,
where you can specify this
column should never be null.
And this is important because, if you're
building a website that has important

English: 
data that you must have
from the users-- like,
your app won't work without the
user's username or their password
or their email address--
you can say not null.
And your database will
ensure that you can't even
insert a row into this database unless
you give it a value for that field.
So it helps you protect
you against yourself.
Because you could
certainly implement that
logically in Python or any language.
But the database is a
final gauntlet as well.
A default value doesn't
really make sense here.
But for certain types of
fields, you can say, database,
insert the current time or
the current date for me?
Now, why might you want that?
Why date and time by default?
Why might that be useful?
AUDIENCE: When the account was created?
DAVID J. MALAN: When the account
was created, when they bought
a foo, when they shipped a
bar-- any number of reasons.
You might just want to know,
what is the time right now?
But you don't have to
write code for that.
The database can answer
those questions for you.
So just so much more functionality than
we got, of course, with CSVs alone.
So name, should it be a primary key?
No.

Arabic: 
يجب أن تكون لديكم من المستخدمين--
مثل،
لن يعمل تطبيقك بدون اسم المستخدم الخاص
بالمستخدم أو كلمة المرور الخاصة به
أو عنوان بريده الإلكتروني--
يمكنكم أن تقولوا ليس فارغًا.
وستضمن قاعدة البيانات
الخاصة بكم أنه لا يمكنكم حتى
إدراج صف في قاعدة البيانات هذه
ما لم تعطوا قيمة لهذا الحقل.
لذا يساعدكم على
حمايتكم من أنفسكم.
لأنه يمكنكم
بالتأكيد تنفيذ ذلك
منطقيًا في Python أو في أي لغة.
لكن قاعدة البيانات هي
تحدي نهائي أيضًا.
القيمة الافتراضية
ليست منطقية بالفعل هنا.
ولكن بالنسبة لأنواع معينة من الحقول،
يمكنكم قول، قاعدة البيانات،
أدرجي الوقت الحالي أو
التاريخ الحالي من أجلي؟
الآن، لماذا قد تريدون ذلك؟
لماذا التاريخ والوقت بشكل افتراضي؟
لماذا قد يكون ذلك مفيدًا؟
الجمهور: متى تم إنشاء الحساب؟
ديفيد ج. مالان: عندما تم إنشاء الحساب،
عندما اشتروا
foo، عندما نقلوا شريطًا--
أي عدد من الأسباب.
قد ترغبون فقط في معرفة،
ما هو الوقت الآن؟
لكن لا يجب أن تكتبوا
التعليمة البرمحية لذلك.
يمكن أن تجيب قاعدة البيانات
على هذه الأسئلة من أجلكم.
إذن، فقط الكثير من الدالات التي
حصلنا عليها، بالطبع، باستخدام ملفات CSV فقط.
إذن الاسم، هل يجب أن
يكون مفتاحًا أساسيًا؟
لا.

Arabic: 
وإلا لا يمكننا الحصول على شخصين باسم براين.
وبشكل عام، سيكون مفتاحكم الأساسي
حقلًا واحدًا، على الرغم من ذلك،
يمكنك من الناحية النظرية إنشاء أعمدة
مشتركة إذا كنتم تريدون ذلك.
لكن بشكل عام، سيكون عمود واحد.
هل يجب علينا زيادة براين
تلقائيًا-- لذلك، على سبيل المثال، حسنًا--
مثل براين28، أو براين2،
أو براين3، وما إلى ذلك؟
لا.
لا يبدو منطقيًا حقًا.
ليس فارغًا؟
من المحتمل.
أريد كل أسماء
الطلاب الجدد حتى نعرف
مَن يقوم بالتسجيل للرياضة.
والسكن؟
أجل، ليس فارغًا.
لكن أوه، حالة حرجة--
هل يمكن أن يفكر أي شخص في
حالة حرجة حيث من المحتمل
أن يكون السكن نوعًا ما فارغًا؟
الجمهور: خارج الحرم الجامعي.
ديفيد ج. مالان: إنهم يتنقلون،
وهم خارج الحرم الجامعي--
إنهم ليسوا طلابًا كُثر.
ولكن إذا كان لديكم 1٪، 5٪ من الطلاب
الذين يعيشون خارج الحرم الجامعي،
فهذا هو سؤال التصميم الآن.
وقد زرنا جميعًا على
الأرجح بعض مواقع الويب
حيث لا يمكنكم ملء النموذج
بالطريقة الصحيحة
لأنكم لا تلبون
معاييرهم أو توقعاتهم.
وهذا فقط بسبب
قرار التصميم السيئ.
لذلك دعونا نتيح له أن
يكون فارغًا فقط في هذه الحالة.
الآن ماذا أيضًا؟
قلنا رقم الهاتف 
عندما اقترحتُ ذلك.
يا إلهي، لا يوجد نوع رقم الهاتف.
إذن ما الذي تريدون إنهائه؟

English: 
Otherwise, we couldn't have two Brians.
And generally, your primary
key will be one field, though,
theoretically you could make
joint columns if you wanted.
But generally, it'll be a single one.
Should we auto-increment
Brian-- so it's, like, well--
Brian28, or Brian2,
Brian3, and so forth?
No.
Doesn't really make sense.
Not null?
Probably.
I want all of the
freshmen's names so that we
know who is signing up for sports.
And dorm?
Yeah, not null.
But oh, corner case--
can anyone think of a
corner case where dorm maybe
should kind of sort of be null?
AUDIENCE: They're off-campus.
DAVID J. MALAN: They
commute, they're off-campus--
it's not many students.
But if you have 1%, 5% of
students living off-campus,
this is a design question now.
And all of us have probably
visited some website
where you just can't fill
out the form in the right way
because you don't fit their
mold or their expectations.
And that's just because
of a poor design decision.
So let's allow it to
be null just in case.
Now what else?
We said a phone number
was when I proposed.
Gosh, there's no phone number type.
So what do you want to go with?

Arabic: 
الجمهور: [INAUDIBLE]
ديفيد ج. مالان: معذرة؟
الجمهور: [INAUDIBLE] varchar.
ديفيد ج. مالان: Varchar.
حسنًا.
حتى نتمكن من اختيار varchar وربما استخدام
10 أو حتى 10 أرقام في الولايات المتحدة،
على الأقل، على الرغم من، ربما، على سبيل المثال،
12 باستخدام علامات التجزئة، أو 13 باستخدام الأقواس،
أو--
الجمهور: [INAUDIBLE]
ديفيد ج. مالان: ما هذا؟
الجمهور: [INAUDIBLE]
ديفيد ج. مالان: أسمع همهمة.
معذرة.
الجمهور: int صغير.
ديفيد ج. مالان: int صغير
ومعاملته فقط
كرقم، ربما يمكن أن ينجح هذا أيضًا.
بديل آخر؟
أي شيء آخر؟
الجمهور: [INAUDIBLE] الدقة.
ديفيد ج. مالان: الدقة--
لذا رقم محدد.
الجمهور: [INAUDIBLE] تأكد من
حصولك على الرقم الصحيح.
ديفيد مالان: جيد.
لذا ليس حدسًا سيئًا.
ولكن يتضح أنه باستخدام نوع البيانات الرقمية،
حيث تحدّدون معيارًا
كما أطلقنا عليه-- العدد
الإجمالي للأرقام في الدقة--
والذي يُقصد به عمومًا
قيم النقاط العائمة--
أي الأرقام الحقيقية ذات النقاط العشرية.
لأنه على الرغم من
أنكم تحددون حدًا أقصى،
فأنتم لا تحتاجون إلى تلك الأرقام الكثيرة.
إنه مجرد حد أقصى.
أجل؟
الجمهور: أعتقد أن إعطائه--
سيكون القيام بنوع من chars
تصميمًا سيئًا لأنه

English: 
AUDIENCE: [INAUDIBLE]
DAVID J. MALAN: I'm sorry?
AUDIENCE: [INAUDIBLE] varchar.
DAVID J. MALAN: Varchar.
OK.
So we can pick varchar and maybe use
10 or so for 10 digits in the US,
at least, though, maybe, like, 12 with
the dashes, or 13 with the parentheses,
or--
AUDIENCE: [INAUDIBLE]
DAVID J. MALAN: What's that?
AUDIENCE: [INAUDIBLE]
DAVID J. MALAN: I hear murmuring.
Sorry.
AUDIENCE: A small int.
DAVID J. MALAN: A small
int and just treated
as a number, maybe that could work too.
Another alternative?
Anything else?
AUDIENCE: [INAUDIBLE] precision.
DAVID J. MALAN: Precision--
so a specific number.
AUDIENCE: [INAUDIBLE] make sure
you have the correct number.
DAVID J. MALAN: Good.
So not a bad instinct.
But it turns out with the numeric
data type, where you specify scale
as it's called-- the total
number of digits in precision--
that's generally meant for
floating point values-- so
real numbers with decimal points.
Because even though you're
specifying a max limit,
you don't require that many digits.
It's just a max.
Yeah?
AUDIENCE: I would think that giving it--
doing some sort of chars would
be a bad design because then you

Arabic: 
يمكنكم إدخال قيم غير رقمية بعد ذلك.
ديفيد ج. مالان: أجل.
يمكننا أن نجد الخطأ،
أعتقد أنه، في هاتين الفكرتين، على الرغم من أن
كلا الفكرتين معقولتان.
إذا سمحتم باستخدام char أو
varchar، يمكنني كتابة
على سبيل المثال foo أو bar أو
baz وليس رقمًا.
لذلك ربما يجب أن نكتب int.
ولكن هل يمكن أن يفكر أي شخص
في مثال مضاد
لمَ لا يجب أن تستخدموا عددًا صحيحًا؟
الجمهور: لقد حصل على طول
متغير له، أليس كذلك؟
لذا ستحصل على أي رقم--
ديفيد ج. مالان: طول المتغير.
لكن إذا قمنا بالفعل
بإجراء العملية الحسابية، ربما 65،
ربما-- توجد وحدات بايت كافية هناك.
يمكننا استخدام int كبير، وهذا
يعطينا رقم هاتف طويل حقًا.
لذا ربما يكون هناك حد أقصى معقول.
أجل؟
الجمهور: دعنا نقل [INAUDIBLE]
بين [INAUDIBLE] عدد صحيح.
ديفيد ج. مالان: الشُرط والأقواس.
يجب أن نقرر،
هل نريد دعم ذلك؟
وبصراحة، ربما نعيش جميعًا
في الولايات المتحدة الآن، معظمنا
هنا.
ولكن عند إجراء مكالمة محلية في
بعض المناطق، على سبيل المثال، تكتبون 0 أولاً.
وقد يكتب بعض الأشخاص
0 كرقمهم.
ولكن ما الذي سيحدث إذا
كتبتم 0 في حقل عدد صحيح؟
الجمهور: ستتجاهله.
ديفيد ج. مالان: ستقومون
بتجاهله.
لذا الآن توجد هذه الحالة الحرجة.
إذن اللعنة.

English: 
can enter nonnumerical values.
DAVID J. MALAN: Yeah.
We can kind of find fault, I think,
both of these ideas, though both of them
are reasonable.
If you allow for char
or varchar, I could
type in like foo or bar
or baz and not a number.
So maybe we should go with int.
But can someone think of
a counter-example to why
you shouldn't use integer?
AUDIENCE: It's got a variable
length to it, doesn't it?
So you'd get whatever number--
DAVID J. MALAN: Variable length.
But if we actually do
the math, maybe 65,
maybe-- there are enough bytes there.
We could use a big int, and that
gives us a really long phone number.
So there's probably a reasonable max.
Yeah?
AUDIENCE: Let's say [INAUDIBLE]
in between [INAUDIBLE] integer.
DAVID J. MALAN: Hyphens and parentheses.
We have to decide, do we
want to support those?
And honestly, all of us are perhaps a
little US-centric right now, most of us
here.
But when you make a local call in
some zones, like, you type 0 first.
And some human might
type 0 as their number.
But what's going to happen if
you type 0 into an integer field?
AUDIENCE: You're going to ignore it.
DAVID J. MALAN: You're
going to ignore it.
So now there's that corner case.
So dammit.

Arabic: 
على سبيل المثال، من الواضح أنه لا توجد طريقة لحل
هذه المشكلة.
إذن ما هو الأفضل؟
يجب أن نتوصل إلى حل
وسط وأن نقبل فقط
أنه يجب حل هذا باستخدام تعليمة برمجية.
الجمهور: Varchar.
ديفيد ج. مالان: Varchar؟
حسنًا.
إذن varchars أو char.
حسنًا.
إذن ربما دعونا نعمل على تبسيط المشكلة.
لا يمكن لأي شخص خارج الولايات المتحدة
أن ينضم إلى رياضة داخلية جديدة.
هذا يُبسّط الأمر.
لأنه إذا كنا ندعم فقط أرقام الهواتف في
الولايات المتحدة، يمكننا الآن أن نقول 10 أرقام.
وإذا قلنا ذلك، أتعرفون ماذا؟
لا تهمني
الشُرط أو الأقواس.
يمكنني استخدام تعليمة برمجية
أو JavaScript أو Python، للتخلص من الصيغة.
ويمكنني فقط تخزين 10 أرقام.
ربما char 10 كافية--
3 لرمز المنطقة، ثم باقي
الرقم، سبعة أرقام جميعها
فيه.
لكن قد تجدون خطأ في هذا أيضًا.
ونحن بالفعل نعزل
الطلاب الدوليين في الحرم الجامعي.
لكن مجددًا، هذه مجرد
قرارات تصميم غير واضحة.
ولذا نحن هنا،
في نهاية الفصل الدراسي.
ليست لدينا دائمًا إجابات جيدة.
ولن يتفق الأشخاص المنطقيون بشأن ذلك.
لكن دعوني أبسط الافتراضات
ونستخدم فقط الأرقام الأمريكية، 10 أرقام،
وثقوا بأنني سأستخدم التعليمة البرمجية
في Python أو أي لغة أخرى
للتخلص من الصيغة،
وعلامات الترقيم وأي شيء

English: 
Like, there's no way to solve
this problem it would seem.
So what's best?
We have to make a
compromise and just accept
that we have to solve this with code.
AUDIENCE: Varchar.
DAVID J. MALAN: Varchar?
All right.
So varchars or char.
All right.
So maybe let's simplify the problem.
No one from outside the US can
take freshman intramural sports.
That simplifies the world.
Because if we only support US phone
numbers, now we can say 10 digits.
And if we say, you know what?
I don't care about the
hyphens or the parentheses.
I can use code, JavaScript or
Python, to throw away the syntax.
And I can just store 10 digits.
Maybe char 10 is sufficient--
3 for the area code, then the rest
of the number, the all seven digits
thereof.
But you could find fault with this too.
And we're really alienating that
international population on campus.
But again, these are just
non-obvious design decisions.
And so here we are, at
the end of the semester.
We don't always have good answers.
And reasonable people will disagree.
But let me simplify our assumptions
and just do US numbers, 10 digits,
and trust that I will use code
in Python or some other language
to throw away the syntax,
the punctuation and whatnot

Arabic: 
كالأقواس والشُرط.
وسأتأكد من أن الشخص لم يكتب
أي حرف من الأحرف الأبجدية.
يمكنني القيام بذلك في التعليمة البرمجية.
وأنتم تعلمون أنه يمكننا فعل ذلك حتى في
JavaScript عندما يقدم الشخص شكلاً.
دعونا ننتقل إلى النهاية،
الرياضة، ماذا كانت الرياضة--
الجمهور: الرياضة التي يريدون القيام بها.
ديفيد ج. مالان: الرياضة التي
قد يريدون القيام بها.
إذن هذا مثال جيد، لا يجب
أن تكون لديكم مسافات
في اسم الحقل، لذا التقليد
سيكون الرياضة_هم_ حقًا أو ربما
أو دعونا نطلق عليها فقط
الرياضة في هذه الحالة.
سنعود إلى ذلك.
أعتقد أن لدينا
فكرتان أخرتان.
رقم الهاتف.
الجمهور: البريد الإلكتروني.
ديفيد ج. مالان: البريد الإلكتروني.
جسنًا.
البريد الإلكتروني فكرة جيدة.
ما الذي يجب أن يكون عليه ذلك؟
لا يوجد نوع بريد إلكتروني،
لسوء الحظ، على الرغم من وجود
hTML، نوع مدخل للبريد الإلكتروني.
الجمهور: Varchar.
ديفيد ج. مالان: ما هذا؟
الجمهور: Varchar.
ديفيد ج. مالان: حسنًا، أشعر أننا ربما
بحاجة إلى varchar هنا.
ولكنه هنا، غير واضح قليلاً،
ما هو أطول عنوان بريد إلكتروني في العالم؟
ربما عنوان بريد نيك الإلكتروني؟
إذن لا أعرف.
ولكن دعونا نختار حدًا أعلى
معقولاً يمكننا ربما أن نعتاد
عليه كمجموعة.

English: 
of parentheses and hyphens.
And I'll make sure the human hasn't
typed in any letters of the alphabet.
I can do that in code.
And you know we can do that even in
JavaScript when a human submits a form.
We'll leave for the end,
sports, what was it sports--
AUDIENCE: Sports they want to do.
DAVID J. MALAN: Sports
they might want to do.
So this is a good example of,
you shouldn't really have spaces
in your field name, so the convention
would be sports_they_ really or might
or let's just call it
sports in this case.
We'll come back to that.
I think there were two
other ideas we had.
Phone number.
AUDIENCE: Email.
DAVID J. MALAN: Email.
OK.
Email is a good one.
What should that one be?
There's no email type,
unfortunately, even though there
is an HTML, an input type for email.
AUDIENCE: Varchar.
DAVID J. MALAN: What's that?
AUDIENCE: Varchar.
DAVID J. MALAN: Yeah, I feel like
we probably need a varchar here.
But here, a little non-obvious, what is
the longest email address in the world?
Maybe it's Nick's?
So I don't know.
But let's pick a reasonable
upper bound that we can maybe
be comfortable with as a group.

English: 
And let's see-- anything else here?
No?
OK.
And was there one more field?
AUDIENCE: Graduation year.
DAVID J. MALAN: Oh, grad-- oh, age.
Let's go with age.
So age-- finally, something simple.
What you want this to be?
AUDIENCE: Small int.
DAVID J. MALAN: Small int, right.
We will not support people
older than 65,535 years old.
Someone want to find fault
with this idea though?
I would argue, there's no one
right answer to any of these.
AUDIENCE: You need month.
DAVID J. MALAN: Month--
oh, it depends.
Do we want month?
AUDIENCE: Yeah.
We might need [INAUDIBLE].
AUDIENCE: --then you
need the date, the year.
DAVID J. MALAN: So you're
assuming we want birth date.
I think I've called it age.
So maybe that's the problem.
Like, if it's age, small int's fine.
Like, you can be 0 years
old or 65,000 years old.
We have a good range.
AUDIENCE: All about
the age, date of birth.
DAVID J. MALAN: If it's
age, I think we're OK.
But I think you allude to a good point,
which is, why would we maybe want

Arabic: 
ولنرى-- أي شيء آخر هنا؟
لا؟
حسنًا.
هل كان هناك حقلاً إضافيًا آخر؟
الجمهور: عام التخرج.
ديفيد ج. مالان: أوه، التخرج-- أوه، العمر.
لنأخذ العمر.
إذن العمر-- أخيرًا، شيء بسيط.
ما الذي تريدون أن يكون عليه هذا؟
الجمهور: int صغير.
ديفيد ج. مالان: int صغير، حسنًا.
لن ندعم الأشخاص الذين
تزيد أعمارهم عن 65535 عامًا.
على الرغم من ذلك هل يرغب شخص ما
في إيجاد خطأ في هذه الفكرة؟
يمكنني القول، لا توجد إجابة
واحدة صحيحة لأي من هذه الأسئلة.
الجمهور: تحتاج إلى شهر.
ديفيد ج. مالان: شهر--
أوه، على حسب.
هل نريد شهرًا؟
الجمهور: أجل.
قد نحتاج إلى [INAUDIBLE].
الجمهور: --ثم تحتاج
إلى التاريخ، السنة.
ديفيد ج. مالان: إذن أنتم تفترضون
أننا نريد تاريخ الميلاد.
أعتقد أنني أطلقتُ عليه العمر.
إذن ربما هذه هي المشكلة.
على سبيل المثال، إذا كان العمر، فسيكون int الصغير جيد.
على سبيل المثال، يمكن أن يكون عمرك 0
سنة أو 65000 سنة.
لدينا نطاق جيد.
الجمهور: يدور كل شيء حول
العمر، تاريخ الميلاد.
ديفيد ج. مالان: إذا كان العمر،
فأعتقد أننا على ما يرام.
لكنني أعتقد أنك تشير إلى نقطة جيدة،
وهي ربما لماذا نريد

English: 
to store birth date and not age?
AUDIENCE: [INAUDIBLE]
DAVID J. MALAN: Yeah.
The damn thing's always
changing, otherwise, right?
Like, I'm going to have to update
my database tomorrow and then
the next day, let alone every
hour or every minute just
because my users' ages are changing.
Like, that seems silly.
Let me, instead, fix a value--
so do something like birth date.
Birth date-- maybe specify not an int.
But let's actually use the date field.
We could store time if we
really care what time they
were born on a certain day.
But here, I can say date is going
to be a little better because, now I
know in Python, JavaScript, even
C, I can do a little bit of math.
And if I know they were born on such
and such a day and month and year,
well, I'll just subtract that from
the current day, month, and year
and figure out how many days or years
old they are-- so a better design
decision there perhaps.
But we do have to
standardize the format.
We can't just allow people
from the US and Europe and Asia
to all kind of choose their own formats.
SQL standardizes this--
year, year, year, year dash
month, month dash day, day.

Arabic: 
تخزين تاريخ الميلاد وليس العمر؟
الجمهور: [INAUDIBLE]
ديفيد ج. مالان: أجل.
يتغير هذا الشيء دائمًا،
بخلاف ذلك، أليس كذلك؟
على سبيل المثال، سأضطر إلى تحديث
قاعدة بياناتي غدًا ومن ثم
في اليوم التالي، ناهيك
عن كل ساعة أو كل دقيقة فقط
لأن أعمار المستخدمين تتغير.
يبدو هذا سخيفًا.
دعوني، بدلاً من ذلك، أحدّد قيمة--
لتقوم بشيء مثل تاريخ الميلاد.
تاريخ الميلاد-- ربما يحدد شيئًا غير int.
لكن دعونا بالفعل نستخدم حقل التاريخ.
يمكننا تخزين الوقت إذا كنا
مهتمين حقًا بالوقت الذي
ولدوا فيه في يوم معين.
ولكن هنا، يمكنني أن أقول أن التاريخ
سيكون أفضل قليلاً، لأنني أعرف الآن
في Python وJavaScript وحتى C،
يمكنني أن أقوم بالقليل من العمليات الحسابية.
وإذا كنتُ أعرف أنهم ولدوا في
هذا اليوم والشهر والسنة،
حسنًا، سأطرح ذلك فقط من
اليوم والشهر والسنة الحاليين
وأكتشف كم هو عمرهم بالأيام
أو السنوات-- لذا من المحتمل أنه أفضل قرار
تصميم هناك.
لكن يجب أن
نوحد الشكل.
لا يمكننا السماح فقط لأشخاص
من الولايات المتحدة وأوروبا وآسيا
اختيار أشكالهم الخاصة جميعًا.
تقوم SQL بتوحيد هذا--
سنة، سنة، سنة، سنة شرطة
شهر، شهر شرطة يوم، يوم.

English: 
And that's the value of
having these data types again.
All right.
So how about sports-- the last one?
AUDIENCE: Varchar.
DAVID J. MALAN: Varchar, all right.
What's the longest number
of words in the sport?
AUDIENCE: I didn't say might want
to do, so I could get up there,
but 255 probably makes the most sense.
DAVID J. MALAN: Maybe unless
they're very athletic.
Yeah.
Here too I don't know.
But just for the sake of
opening up possibilities,
when you think the human
might be a little expository
and actually write a paragraph
of all the sports they're
involved in or whatnot or even bigger
than a paragraph, text is even bigger.
Sports, this probably isn't compelling.
And I'll change it back to varchar.
But if someone is typing
in their college essay
into the Common
Application, or if you're
asking people to paste their resumes,
or the like, you might want to use text.
Because I have no idea how many
words someone's going to have.
Text allows you to store even more data.
But it stores it a little differently.
It tends to store it not in
the column, but using pointers.
If you recall from a few weeks
back, it uses the equivalent
of that to store it over there, which
takes a little more time to get to.

Arabic: 
وهذه هي قيمة وجود هذه
الأنواع من البيانات مجددًا.
حسنًا.
إذن ماذا عن الرياضة-- آخر حقل؟
الجمهور: Varchar.
ديفيد ج. مالان: Varchar، حسنًا.
ما هو أطول عدد من
الكلمات في الرياضة؟
الجمهور: لم أقل قد تريد القيام بها،
لذا يمكن الوقوف هناك،
لكن ربما يجعل 255 الأمر منطقيًا أكثر.
ديفيد ج. مالان: ربما ما لم
يكونوا رياضيين جدًا.
أجل.
هنا أيضًا لا أعلم.
ولكن فقط من أجل
تقديم الاحتمالات،
عندما تعتقدون أن الشخص قد
يكون إيضاحيًا قليلاً
ويكتب في الواقع فقرة عن
جميع الألعاب الرياضية التي ينضم إليها
أو أي شيء أو حتى أكبر
من فقرة، يكون النص أكبر.
الرياضة، ربما هذه ليست كلمة مقنعة.
وسأغيرها مجددًا إلى varchar.
ولكن إذا كتب شخص
ما مقالاً في كليته
عن التطبيق المشترك،
أو إذا كنتم
تطلبون من أشخاص لصق سيرهم الذاتية،
أو ما شابه ذلك، فقد ترغبون في استخدام النص.
لأنه ليس لدي أي فكرة عن عدد
الكلمات التي سيحصل عليها شخص ما.
يتيح لكم النص تخزين المزيد من البيانات.
لكنه يخزنها بشكل مختلف قليلاً.
إنه يميل إلى تخزينها ليس
في العمود، ولكن باستخدام المؤشرات.
إذا كنتم تتذكرون منذ بضعة أسابيع،
فإنه يستخدم المعادل
لذلك لتخزينها هناك، ويستغرق الوصول إليها
وقتًا أطول قليلاً.

English: 
So again, there's just a trade-off here.
So we could do varchar 255--
makes me a little nervous.
So I'm going to go with
another common value.
1024, it's a power of 2, but
there's no one right answer here.
But these are the non-obvious
design decisions we have to make.
If I didn't make any
mistakes here, I'm going
to go ahead and click Create, and whoo--
table has been created.
You can even see now all of the
data that's been created there.
And voila, if I go back to froshims,
and I go back to the registrants table,
not only can I browse it--
there's nothing in there yet.
I can look at the structure and
actually see all of those same values
and edit some of them like renaming.
But you can't completely mutilate it.
You might have to start over
if you make too many changes.
All right.
Any questions then about this?
Yeah?
AUDIENCE: Why do you use
1024 instead of 1023?
DAVID J. MALAN: Oh, why do
I use 1024 instead of 1023.
Typically, when you choose
a ma-- oh, convention.
I can't justify this.
255 was the max because I think one of
the bites was reserved for some value,
historically.

Arabic: 
لذا مجددًا، هناك فقط مقايضة هنا.
إذن يمكننا القيام بإنشاء varchar 255--
يجعلني متوترًا قليلاً.
لذلك سأنتقل إلى
قيمة مشتركة أخرى.
1024، إنها قوة 2، ولكن لا
توجد إجابة واحدة صحيحة هنا.
لكن قرارات التصميم غير
الواضحة هذه التي يجب أن نتخذها.
إذا لم ارتكب أي أخطاء
هنا، فسأمضي
قدمًا وأنقر فوق Create، وأوه--
تم إنشاء جدول.
يمكنكم الآن رؤية جميع البيانات
التي تم إنشاؤها هناك.
وها هي ذا، إذا عدتُ إلى froshims،
وعدتُ إلى جدول المسجَّلين،
لا يمكنني تصفح ذلك فقط--
حيث لا يوجد أي شيء هناك حتى الآن.
يمكنني النظر في البنية
ورؤية جميع تلك القيم نفسها
وتحرير بعضها مثل إعادة التسمية.
لكن لا يمكنكم تشويهها بالكامل.
ربما يجب أن تبدأوا من جديد
إذا قمتم بإجراء تغييرات كثيرة جدًا.
حسنًا.
هل توجد أي أسئلة حول هذا؟
أجل؟
الجمهور: لماذا تستخدم 1024
بدلاً من 1023؟
ديفيد ج. مالان: أو، لماذا أستخدم
1024 بدلاً من 1023.
عادة، عند اختيار--
أوه، التقليد.
لا يمكنني تبرير هذا.
255 كان الحد الأقصى لأنني أعتقد أن
إحدى وحدات البايت كانت محفوظة لقيمة ما،
من الناحية التاريخية.

Arabic: 
لكن هذا ليس صحيحًا بالفعل.
تم رفع هذا الحد،
وليس هناك سبب وجيه.
الجمهور: كان يمكنك استخدام 255.
ديفيد ج. مالان: هذه الأيام، أجل.
منذ سنوات، 255 كان حد فعلي.
وهكذا تم تبنيه.
الآن، لا أعلم.
لقد اخترتُ فقط قوة 2 في كثير من الأحيان.
وبعد ذلك، سيكون الانتقال إلى
2048، و4096، وما إلى ذلك، ليس فقط.
أجل؟
الحمهور: ما الفرق بين
varchar وchar؟
ديفيد ج. مالان: Varchar--
ما الفرق بين
varchar وchar؟
تستخدم Char عددًا ثابتًا من وحدات البايت
بغض النظر عن عددها الذي تستخدمونه،
وميزتها هي الأعمدة الخاصة بكم،
من الناحية النظرية،
وهي مستقيمة تمامًا على الحافة
اليسرى، والحافة اليمنى، مما يعني
أنه يمكنكم الوصول بشكل عشوائي لأن
كل خلية هي عدد ثابت
من وحدات البايت من الباقي.
تستخدم Varchar مصفوفة
رثة، كما يطلق عليها،
حيث يكون جانب واحد، الجانب الأيمن
أقصر أو أطول في خلايا مختلفة.
لذا لا يوجد سوى الحد الأقصى
للطول على كل من هذه الخلايا.
ولكن البحث عنه قد
يكون أبطأ كنتيجة لذلك
لأنه لا يمكنكم الانتقال
من خلية إلى خلية.
يجب أن تتبعوا أطوال
تلك الأشياء.
هذه مقايضة.
أجل؟

English: 
But that's not really the case.
That bound has been
lifted, and no good reason.
AUDIENCE: You could have used 255.
DAVID J. MALAN: Nowadays, yes.
Years ago, 255 was an actual limit.
And so it got adopted.
Now, I don't know.
I just pick powers of 2 often.
And then at my next go-to would be
2048, 4096, and so forth, just because.
Yeah?
AUDIENCE: What's the difference
between varchar and char?
DAVID J. MALAN: Varchar--
What's the difference
between varchar and char?
Char uses a fixed number of bytes no
matter how many of them you are using,
the advantage of which is
your columns, conceptually,
are perfectly straight on both the
left edge and the right edge, which
means you have random access
because every cell is some fixed
number of bytes from the rest.
Varchar user a ragged
array, as it's called,
where one side, the right-hand side is
shorter or longer in different cells.
So there's only a maximum
length on each of those cells.
But searching it can
be slower as a result
because you can't just
jump to cell to cell.
You have to follow the
lengths of those things.
That's the trade-off.
Yeah?

English: 
AUDIENCE: If you [INAUDIBLE]
education, how do you add it?
DAVID J. MALAN: Oh, if I wanted to
add an education field now and modify
the table--
if you realize too late, oh, darn,
like, I need to actually add something
to this, in the GUI tool, we can add
1 fields to the end of the table,
literally.
So let's do that.
Let me go ahead and click Go.
I'll be prompted with a
similar form, but smaller.
I can go ahead and type in
something like education.
Let me propose this
is varchar, maybe 255,
though we could have that debate too.
I'm going to go ahead
and say add fields.
And now notice that the table
has been altered successfully.
It actually, for whatever
reason, it's not showing me
the code for that particular command.
But there is literally
an ALTER command in SQL
that would allow you to change it.
And if I go back to the
structure now, you'll
see that I have another column
called education shown ironically
here as a row.
Yeah?
AUDIENCE: Does the order
of the columns matter?
DAVID J. MALAN: Good question.
Does the order of the columns matter?
Fundamentally, no.
By convention, you would
typically put the ID first.

Arabic: 
الجمهور: إذا كنتَ [INAUDIBLE]
التعليم، فكيف يمكنك إضافته؟
ديفيد ج. مالان: أوه، إذا أردتُ إضافة
حقل تعليم الآن وتعديل
الجدول--
إذا أدركتم بعد فوات الأوان، أوه، على سبيل
المثال، أنا بحاجة إلى إضافة شيء إلى هذا،
في أداة واجهة المستخدم الرسومية،
يمكننا إضافة حقل واحد في نهاية الجدول،
حرفيًا.
لذا لنقم بذلك.
دعوني أمضي قدمًا وأضغط على Go.
سأطالب بشكل متشابه،
ولكن أصغر.
يمكنني المضي قدمًا وكتابة
شيء مثل التعليم.
دعوني أقترح هذا
varchar، ربما 255،
على الرغم من أنه يمكننا أن نخوض هذا النقاش أيضًا.
سأمضي قدمًا
وأقول أضف حقولاً.
والآن لاحظوا أنه تم
تغيير الجدول بنجاح.
في الواقع، لأي سبب
من الأسباب، إنه لا يعرض لي
التعليمة البرمجية لهذا الأمر المعين.
ولكن هناك حرفيًا
أمر ALTER في SQL
الذي يتيح لكم تغييره.
وإذا عدتُ إلى البنية
الآن، سترى أن هناك
عمودًا آخر يُسمى التعليم
يظهر بشكل ساخر
هنا كصف.
أجل؟
الجمهور: هل يُعد ترتيب
الأعمدة أمرًا مهمًا؟
ديفيد ج. مالان: سؤال جيد.
هل يُعد ترتيب الأعمدة أمرًا مهمًا؟
بشكل أساسي، لا يهم.
حسب التقليد، عادة ما
تضعون المعرّف أولاً.

Arabic: 
وبعد ذلك، سأقوم، بشكل شخصي، حسب
التصميم، بوضع أهم الحقول التالية
مثل الاسم الذي
يبدو أنه هو الاختيار الصحيح،
وربما يبدو أن البريد الإلكتروني هو
الاختيار الصحيح، لقد فكرتُ في الأمر
في وقت متأخر قليلاً هذه المرة.
ليس من السهل إعادة ترتيب الأشياء في SQLite،
ولكن يمكنكم ذلك في قواعد البيانات الأخرى.
لذا هناك، إنه
تقليد بشري بشكل أكبر.
أجل؟
الجمهور: هل هو تقليد أن تكون
لديك كلمة رئيسية واحدة،
أو هل يمكن أن تكون لديك عدة كلمات رئيسية؟
ديفيد ج. مالان: سؤال جيد.
هل هو تقليد أن تكون لديك كلمة رئيسية واحدة،
أو هل يمكن أن تكون لديك عدة كلمات رئيسية؟
حسب التعريف، يمكنكم فقط الحصول على كلمة واحدة.
ولكن يمكن أن تغطي هذه الكلمة
الرئيسية عدة أعمدة.
لذلك لم نرَ حالة استخدام
لهذا حتى الآن.
لكن هناك سيناريوهات
حيث ستريدون قول،
أريد أن أضمن أن هذين
العمودين معًا فريدان من نوعهما،
ولكن ليس كل واحد بمفرده فريدًا.
لكننا لن نصادف ذلك حتى الآن.
أي أسئلة أخرى، أجل؟
الجمهور: ماذا لو
أضفتَ التعليم
بعد أن بدأتَ بقاعدة البيانات،
وكان ذلك حقلاً ليس فارغًا؟
ديفيد ج. مالان: سؤال جيد حقًا.
ماذا لو أضفتَ التعليم بعد
أن يكون لديك بالفعل بيانات حقيقية هناك،
ولكنك حددتَ أنها ليست فارغة،
وهذا أمر مثير للمشاكل.
لأنه ما هي الخلفيات
التعليمية للأشخاص السابقين؟

English: 
And then I, personally, by design,
put the most important fields
next like name feels
like the right choice,
maybe email feels like the right
choice, though, I clearly thought
of it a little too late this time.
It's not easy in SQLite to reorder
things, but in other databases you can.
So there, it's more
of a human convention.
Yeah?
AUDIENCE: Is it convention to
have one single primary key,
or can you have multiple?
DAVID J. MALAN: Good question.
Is it a convention to have one single
primary key, or can you have multiple?
By definition, you can only have one.
But that primary key can
span multiple columns.
So we haven't seen a
use case for this yet.
But there are scenarios in
which you would want to say,
I want to guarantee that these
two columns together are unique,
but not each individual one unique.
But we won't encounter that just yet.
Other questions, yeah?
AUDIENCE: What if you
had added education
after you had started the database,
and that was a not null field?
DAVID J. MALAN: Really good question.
What if you had added education after
you already had real data in there,
but you specified not
null, which is problematic.
Because what is the educational
backgrounds of the previous people?

English: 
Typically, what the database
would do is either reject it,
or it would just put the
"empty string," quote unquote.
So it's not technically null, but
there's nothing actually there.
It's just a string of length 0.
Really good question.
All right.
So what can we now do that's a
little more powerful about this?
Well, let me go ahead and
quickly insert some data here.
I'm going to keep most of it blank.
But you know what?
I'm not even going to bother with ID.
Brian you're back on the team.
Let's go ahead and insert Brian.
Let's go ahead now
into registrants again.
Let's go ahead and add Veronica again.
So I'm just inserting
a few rows manually.
And again, notice it's
executing all of this for me
without me having to
bother typing it out.
But I absolutely could.
In fact, just for good
measure, let's do one manually.
If I click the SQL tab, notice that
I get a default suggestion here.
That is the syntax with which
you can select everything.
Or I can just type
INSERT into registrants.
But now, if I only
want to insert a name,
I don't have to do all of the columns.
I can just say go ahead and
insert here, Erin, for instance,
semicolon, zoom out and click Go.
That seemed to work.

Arabic: 
عادة، ما يمكن أن تفعله قاعدة
البيانات هو إما رفضه،
أو أنها ستضع فقط "سلسلة فارغة"،
علامة اقتباس وعلامة إنهاء الاقتباس.
لذلك لا يعد ذلك من الناحية الفنية فارغًا،
ولكن لا يوجد أي شيء في الواقع هناك.
إنها مجرد سلسلة من طول 0.
سؤال جيد حقًا.
حسنًا.
إذن، ما الذي يمكننا فعله
الآن إنه قوي قليلاً؟
حسنًا، دعوني أمضي قدمًا
وأقوم بإدراج بعض البيانات بسرعة هنا.
سأحتفظ بمعظمها فارغًا.
لكن أتعرفون ماذا؟
أنا لن أزعج نفسي باستخدام المعرّف.
براين لقد عدتَ إلى الفريق.
لنمضي قدمًا وندرج براين.
دعونا نمضي قدمًا الآن
إلى المسجَّلين مجددًا.
لنمضي قدمًا ونضيف
فيرونيكا مجددًا.
لذا أنا أقوم بإدراج
بضعة صفوف يدويًا.
ومجددًا، لاحظوا أنه يُنفِّذ
كل هذا من أجلي
دون أن أزعج نفسي
بكتابته.
لكن يمكنني ذلك بالفعل.
في الواقع، فقط للقياس الجيد،
دعونا نقوم بشيء آخر يدويًا.
إذا قمتُ بالنقر فوق علامة تبويب SQL،
فلاحظوا أنه يمكنني الحصول على اقتراح افتراضي هنا.
هذه هي الصيغة التي يمكنكم
من خلالها تحديد كل شيء.
أو يمكنني فقط كتابة
إدراج في المسجَّلين.
ولكن الآن، إذا أردتُ
فقط إدراج اسم،
لا يجب أن أقوم بكل هذه الأعمدة.
يمكنني فقط قول امضي قدمًا وأدرج هنا،
إيرين، على سبيل المثال،
فاصلة منقوطة، وقم بالتصغير وانقر فوق Go.
يبدو أن هذا ينجح.

Arabic: 
إذا عدتُ للمتصفح الآن،
فإن إيرين موجود هناك أيضًا.
لكنكم سترون الاختلاف.
كان الاستعلام الذي يتم إنشاؤه تلقائيًا
بواسطة واجهة المستخدم الرسومية
يدرج بالكاد علامة اقتباس وعلامة إنهاء الاقتباس،
وهو ما يُطلق عليه سلسلة فارغة من الطول 0.
قمتُ، عن طريق تجاهل
ذكر تلك الأعمدة،
بإدراج فارغ عن عمد.
لذا بصراحة، أصبحت قاعدة بياناتي
فوضوية قليلاً هنا.
لذلك لا تستخدموا phpLiteAdminا بشكل عام
أو واجهة المستخدم الرسومية لإدراج البيانات.
قد تستخدمونه لإنشاء الجداول
الخاصة بكم بطريقة مناسبة
والحصول على التطبيق بالفعل.
ولكن ستكتبون التعليمة
البرمجية في النهاية.
وهذا هو الاتجاه الذي سنتبعه.
وسأمضي قدمًا وأقوم
بإدراج شخص إضافي واحد.
أوه، لقد نسيتُ أنني لستُ في الفريق
على الإطلاق لأننا بدأنا من جديد.
لذا دعوني أضع نفسي في
الفريق، ديفيد.
ودعوني أمضي قدمًا وأنقر فوق
INSERT، وأعود إلى المسجَّلين،
والآن سترون أنه يوجد أربعة منا.
تغير المعرّف الخاص بي لأنهم قاموا
بالإدراج في ترتيبات مختلفة.
ولكن لاحظوا أن كل الزيادة التلقائية قد
حدثت بطريقة سحرية من أجلي.
وهذا أمر مفيد لأنه لا يجب
أن أفكر في ذلك.
ومَن يهتم بما هو المعرّف الخاص بي.
أنا فقط أحتاج إلى، في كثير من الحالات،
في قاعدة بيانات، معرّف فريد.
لذا الآن دعونا في الواقع نكتب بعض
من التعليمة البرمجية، أليس كذلك؟

English: 
If I go back to browse now,
Erin is in there as well.
But you'll see the difference.
The query that's being generated
automatically by the GUI
was lazily just inserting quote unquote,
the so-called empty string of length 0.
I, by omitting even
mention of those columns,
was deliberately inserting null.
So frankly, my database is
getting a little messy here.
So you generally don't use
phpLiteAdmin or a GUI to insert data.
You might use it to
conveniently create your tables
and get your application ready.
But then you're going to
write code ultimately.
And that's the direction we're going.
And I'm going to go ahead
and insert one more person.
Oh, I forgot I'm not on the team
at all because we started over.
So let me put myself
back on the team, David.
And let me go ahead and click
INSERT, go back to registrants,
and now you'll see there are four of us.
My ID changed because they've
been inserted in different orders.
But notice all of the auto incrementing
has been happening magically for me.
And that's useful because I don't
have to even think about it.
And who cares what my ID is.
I just need to have, in many
cases, in a database, a unique ID.
So now let's actually write
a little bit of code, right?

Arabic: 
حتى الآن لم نفعل
أي شيء مفيد.
لقد عرضنا لكم هذه النافذة
بالأبيض والأسود حيث يمكنكم
التحديد في بعض بيانات التحديث.
لكن هذا لا يحل أي مشاكل
نعرفها حتى الآن.
لدينا هذه الواجهة الرسومية
القائمة على الويب
والتي يمكنكم من خلالها إنشاء الجداول
وإضافة البيانات، ولكن مَن يهتم؟
نحن نحاول حل المشاكل الفعلية.
وكانت المشاكل في
وقت متأخر لإنشاء
البرامج التي ستحل
أي عدد من المشاكل البشرية
مثل خدمة المستخدمين
وعرض النتائج
أو العثور على أوجه التشابه في الوثائق.
لذا لنفترض أن المشكلة المطروحة الآن
هي في الواقع لبناء شيء مثل
موقع froshims على الويب والسماح
للطلاب بالتسجيل ومن ثم معرفة
مَن تم تسجيله.
حسنًا، في الماضي، كنتُ كسولاً إلى حد ما،
لنقص المعرفة الفنية،
فقط إرسال بريد إلكتروني بالمسجَّلين
إلى المراقب أو RA الذي كان
يدير برنامج الرياضة الداخلي.
ولكن-- بدأتُ في وقت لاحق
وضعه في ملفات CSV.
لنفترض الآن، الإصدار 3، بعد 20 عامًا،
أريد التخزين في قاعدة بيانات فعلية.
كيف يمكنني فعل ذلك
ومن ثم رؤية النتائج؟
حسنًا، دعوني أنتقل إلى
IDE مجددًا وأفتح،

English: 
Thus far we haven't
done anything useful.
We've shown you this black
and white window in which you
can select in certain update data.
But that doesn't really solve
any problems we know about yet.
We have this graphical
web-based interface
via which you can create tables
and add data, but who cares?
We're trying to solve actual problems.
And the problems of
late have been to build
software that would solve
any number of human problems
like serving users and
showing the results
or finding similarities in documents.
So suppose the problem at
hand now is to actually build
something like the froshims website
and let students register and then see
who is registered.
Well, back in my day, I fairly lazily,
for lack of technical know-how,
just emailed the registrations
to the proctor or the RA who was
managing the intramural sports program.
But I-- they later started
putting it in CSV files.
Suppose now, version 3, 20 years later,
I want to store in an actual database.
How can I actually do that
and then see the results?
Well, let me go into the
IDE again and open up,

English: 
for instance, a New File that
I'll go ahead and call lecture.py.
And suppose I just want to write
a simple Python program via which
to select data from a database.
So it turns out I can
do a few things here.
First of all, let me go ahead
and do, let's say, from CS50,
I previously have done things
like import get_string and get_int
and so forth.
It turns out that the CS50 library
for Python also supports SQL.
And it's going to give
us a function called
EXECUTE that will let you execute
any SQL command, but in Python code.
So instead of pulling up
SQLite3 via my own hands
or going to a graphical
user interface phpLiteAdmin,
I can write code that talks
directly to froshims.db,
and eliminate all of those tools
altogether, and just now write code.
So how do I do this?
I'm going to declare a variable
called db for Database.
So I could call it anything I want.
And I'm going to go ahead
and call this SQL function.
And I'm going to pass in a somewhat
funky looking string as an argument,
but it's a standard
convention, to say what
database technology do you want to use?

Arabic: 
على سبيل المثال، ملف جديد
وسأمضي قدمًا وأطلق عليه lecture.py.
ولنفترض أنني أريد فقط أن أكتب
برنامج Python بسيط يمكنكم من خلاله
تحديد البيانات من قاعدة البيانات.
إذن يتضح أنه يمكنني
القيام ببضعة أشياء هنا.
أولاً وقبل كل شيء، دعوني أمضي قدمًا
وأقوم، لنقل، من CS50،
لقد قمتُ سابقًا بأشياء
مثل استيراد get_string وget_int
وما إلى ذلك.
يتضح أن مكتبة CS50
الخاصة بلغة Python تدعم أيضًا SQL.
وستعطينا دالة
تُسمى
EXECUTE تتيح لكم تنفيذ أي
أمر SQL، ولكن في تعليمة Python البرمجية.
لذا بدلاً من سحب
SQLite3 بنفسي
أو الانتقال إلى واجهة
المستخدم الرسومية phpLiteAdmin،
يمكنني كتابة التعليمة البرمجية
التي تتحدث مباشرة إلى froshims.db،
وإزالة جميع تلك الأدوات
تمامًا، وكتابة التعليمة البرمجية الآن فقط.
إذن كيف يُمكنني فعل هذا؟
سأعلن عن متغير يُسمى
db لقاعدة البيانات.
إذن يمكنني تسميته بأي اسم أريده.
وسأمضي قدمًا وأطلب
دالة SQL هذه.
وسأقوم بالتمرير في سلسلة تبدو
غير تقليدية إلى حد ما كوسيطة،
ولكنه تقليد قياسي،
لنقول ما هي
تقنية قواعد البيانات التي تريدون استخدامها؟

Arabic: 
بعد ذلك، تقومون بكتابة نقطتين، خط مائل، خط مائل،
خط مائل-- إذن إنها ثلاثة خطوط مائلة،
وليس الاثنان المعتادان في عنوان URL.
وسأقوم بتحديد froshims.db.
سيعطيني هذا الآن
متغير Python الذي يُسمى
قاعدة البيانات التي تشبه مدخل،
إذا صح التعبير، في ملف قاعدة البيانات هذا
الذي يمكنني إرسال SELECTs وINSERTs
وDELETEs وUPDATEs إليه.
كيف يمكنني فعل هذ؟
حسنًا، إذا كنتُ في النهاية،
أريد تنفيذ
المعادل من تحديد نجمة من
المسجَّلين، كيف يمكنني فعل ذلك؟
حسنًا، أنا فقط محرر نص، أليس كذلك؟
هذه هي CS50 IDE.
أنا فقط أكتب نصًا.
وعلاوة على ذلك، أنا أكتب نصًا في
ملف Python، وهذه ليست Python.
وبالفعل، فإن IDE تحتوي على x الأحمر الصغير هذا
الذي يقول، امم-امم، لا يمكنني القيام بذلك.
ولكن يمكنني تمرير تعليمة SQL البرمجية
كمدخل لدالة Python
والسماح لهذه الدالة
بالتحدث إلى قاعدة البيانات.
وبالفعل، هذا ما سنحصل عليه
هنا من مكتبة CS50.
سأمضي قدمًا وأفعل هذا.
أتعلمون ماذا؟

English: 
Then you do colon, slash, slash,
slash-- so it's three slashes, not
the usual two in a URL.
And I'm going to specify froshims.db.
This now will give me a
Python variable called
database that is kind of like a
portal, if you will, into that database
file that I can send SELECTs, and
INSERTs, and DELETEs, and UPDATEs to.
How do I do this?
Well, if at the end of
the day, I want to execute
the equivalent of SELECT star from
registrants, how do I do that?
Well, I'm just in a text editor, right?
This is CS50 IDE.
I'm just typing text.
Moreover, I'm typing text in a
Python file, and this is not Python.
And indeed, the IDE has this little
red x saying, mm-mm, can't do this.
But I could pass SQL code as
an input to a Python function
and let that function
talk to the database.
And indeed, that's what we're going
to get here from CS50's library.
I'm going to go ahead and do this.
You know what?

Arabic: 
الوصول إلى قاعدة البيانات
وتعليمة SQL البرمجية التالية EXECUTE،
علامة اقتباس وعلامة إنهاء الاقتباس، "التي" تغلق الأقواس.
الآن، ما هو خيار الإرجاع
حسب التقليد؟
ما الذي يجب أن أعيده؟
حسنًا، في SQLite3، رأينا
فقط جدولاً قائم على النص بشكل جيد
بسطور وخطوط مائلة تبدو
كجدول، ولكنه كان مجرد نص.
phpLiteAdmin، رأينا بالفعل جداول
HTML عندما كنتُ أتصفح قاعدة البيانات.
واقترحتُ ذلك شفهيًا قبل
قليل، أتعرفون ماذا؟
إذا كنتُ سأقوم بإرجاع كل هذه
البيانات في التعليمة البرمجية، فما هو نوع البيانات
الذي أريده لنفسي كـ؟
الصفوف.
أُريد صفوفًا من جدول.
اعرض لي جميع الطلاب
الذين قاموا بالتسجيل.
ما هي بنية البيانات التي تبدو ملائمة في Python؟
الجمهور: القائمة.
ديفيد ج. مالان: أجل،
مجرد قائمة، أليس كذلك؟
قائمة مُرتَبة من الصف
الأول إلى الصف الأخير.
لذلك سنطلق على ذلك قائمة أو مصفوفة،
كما كان في لغة C. لذا أتعرفون ماذا؟
سأفترض أن هذا صحيح.
وإذا قرأتُ الوثائق،
فسأجد أنها صحيحة.
دالة EXCUTE في CS50، إذا قمتم
بتحديدها، فستقوم بإرجاع قائمة صفوف من أجلكم.
قد تحتوي على 0 من الصفوف
إذا لم تكن هناك تطابقات.
ولكن قد تحتوي على 1000 صف
إذا كانت هناك تطابقات كثيرة.

English: 
Access the database and
EXECUTE the following SQL code,
quote unquote, "that" close parentheses.
Now, what is select
return by convention?
What should it return?
Well, in SQLite3, we just
saw a pretty text-based table
with lines and slashes that looked
like a table, but was just text.
phpLiteAdmin, we actually saw HTML
tables when I browsed the database.
And I proposed verbally, a
bit ago that, you know what?
If I were to get back all of
this data in code, what data type
would I like it to me as?
Rows.
I want rows from a table.
Show me all the students
who've registered.
What data structure in Python seems apt?
AUDIENCE: List.
DAVID J. MALAN: Yeah,
just a list, right?
A list that's ordered from
first row to last row.
So we'll call that a list or an array,
back in the day of C. So you know what?
I'm going to assume that's correct.
And if I read the documentation,
I would see that it's correct.
CS50's EXECUTE function, if you
select, returns to you a list of rows.
It might have 0 rows if
there are no matches.
But it might have 1,000 rows
if there are lots of matches.

English: 
I'm going to store those results,
wherever they are, in my rows array.
Now, suppose I want to print out
who has registered in my database
from whatever froshims website exists.
I'm assuming students have
registered on the web.
Now I'm just the proctor or
the RA who's actually now
trying to manipulate the data
and do something with it.
So what can I do?
Well, for row in rows,
what do I want to do?
Let me go ahead and just print
out that so-and-so registered.
So so-and-so registered.
Well, how do I plug in so-and-so?
Well, there are a few ways to do this.
And let's see.
First of all, I could use my
placeholder syntax for print.
And then, I want to print out the row.
But what do I want from that row?
What columns are in any
row in this database?
AUDIENCE: [INAUDIBLE]
DAVID J. MALAN: ID and name
and dorm and phone and sports.
Well, it turns out, those are going to
be handed to you as Python dictionaries
or dict structures.
So I can just say row
quote unquote, 'name' here.
And I'll use single quotes just to
make more clear what's going on here.
And then I need to make one fix.

Arabic: 
سأقوم بتخزين تلك النتائج،
أينما كانت، في مصفوفة الصفوف الخاصة بي.
الآن، لنفترض أنني أريد طباعة
مَن قام بالتسجيل في قاعدة بياناتي
من أي موقع froshims موجود.
أفترض أن الطلاب قاموا
بالتسجيل على الويب.
الآن أنا فقط مراقب أو RA
أحاول في الواقع
التلاعب بالبيانات
والقيام بشيء ما بها.
إذن ما الذي يمكنني فعله؟
حسنًا، بالنسبة إلى صف من
الصفوف، ما الذي أريد فعله؟
دعوني فقط أمضي قدمًا وأطبع
مَن تم تسجيله.
إذن مَن تم تسجيله.
حسنًا، كيف يمكنني إدخال هذا؟
حسنًا، هناك عدة طرق للقيام بذلك.
دعونا نرى.
أولاً، يمكنني استخدام
صيغة العنصر النائب للطباعة.
ومن ثم أريد طباعة الصف.
ولكن ما الذي أريده من هذا الصف؟
ما هي الأعمدة في أي
صف في قاعدة البيانات هذه؟
الجمهور: [INAUDIBLE]
ديفيد ج. مالان: معرّف واسم
وسكن ورقم هاتف ورياضة.
حسنًا، يتضح أنه، سيتم تسليمها
إليك كقواميس Python
أو بنيات dict.
لذا يمكنني فقط أن أقول صف
علامة اقتباس وعلامة إنهاء الاقتباس، "اسم" هنا.
وسأستخدم علامة اقتباس واحدة
فقط لجعل ما يحدث هنا واضحًا أكثر.
ثم أنا أحتاج إلى إجراء إصلاح واحد.

Arabic: 
كيف يمكنني--
الجمهور: F.
ديفيد ج. مالان: --F لسلسلة التنسيق.
لذلك تبدو مشفرة قليلاً.
لكن هذه فقط أشياء Python الآن.
الشيء الوحيد الجديد هو SQL.
ولكن إذا حدّدنا أن SQL،
عند استخدام دالة التنفيذ هذه،
ستقدم لكم قائمة من
الصفوف، كل منها
عبارة عن قاموس بحيث يمكنكم الحصول
عليه في هذا العمود أو هذا العمود--
المعرّف، أو الاسم، أو السكن--
يبدو هذا الآن تقاربًا
جميلاً في هذا الأسبوع--
الآن، مع الأسبوعين الماضيين.
إذن دعوني أمضي قدمًا وأحفظ ذلك.
دعوني أمضي قدمًا وأعرض وحدة التحكم الخاصة بي،
لذا أنا لدي نافذة طرفية.
ودعوني أمضي قدمًا
وأقوم بتشغيل Python من lecture.py.
وفي غضون لحظات،
إذا عقدتُ أصابعي،
آمل أن أرى
مَن قام بالتسجيل.
مدهش.
لقد رأيت مَن تم تسجيله.
الآن يوجد سطر مخرج واحد
لم أتوقعه، وهو هذا السطر فقط.
تُصبح هذه المكتبة
مفيدة فقط من الناحية الموضوعية.
إنها تعرض لي كل أمر
أرسلتُه إلى قاعدة البيانات.
ولكن سترون أن
ذاك وذاك مُسجل.
إذن هذا مثير للاهتمام إلى حد ما.
إنه برنامج غبي إلى حد ما، أليس كذلك؟
لأن معظم المراقبين
لن يقوموا باختراق
froshims باستخدام نافذة
طرفية وتشغيل نصوص Python.

English: 
How do I--
AUDIENCE: F.
DAVID J. MALAN: --F for Format string.
So it looks a little cryptic.
But this is just Python stuff now.
The only thing that's new is SQL.
But if we stipulate that SQL,
when using this execute function
is just going to hand you all
a list of rows, each of which
is a dictionary so that you can
get at this column or this column--
ID, or name, or dorm--
this would seem to be now a
nice convergence of this week--
now, with the past couple of weeks.
So let me go ahead and save this.
Let me go ahead and View my Console,
so I have a Terminal window.
And let me go ahead and
run Python of lecture.py.
And in just a moment,
if I cross my fingers,
I should hopefully see
who has registered.
Amazing.
I've seen who's registered.
Now there's one line of output that I
didn't expect, which is just this one.
This is the library just
being pedagogically helpful.
It's showing me every command
that I sent to the database.
But you'll see that
so-and-so has registered.
So this is kind of interesting.
It's kind of a stupid program, right?
Because most proctors
aren't going to be hacking
froshims by using a terminal
window and running Python scripts.

English: 
They're probably going to
want to do this by a web page
and actually see who is registered.
But if we have the ability in
Python code to do this, like,
iteration, what could I do instead
of just printing to the screen?
What could I print out per last
week and per the past problems set?
I could print out HTML, right?
Like, each of the students
who register, kind of
feels like an opportunity
for an unordered list
or an ordered list or
a table or whatever.
You can now generate HTML.
So let me do this.
Let me actually go into an
example I've made in advance.
What if I went ahead and
opened up layout.html.
Here is a simple layout for a
web application using Flask.
For those unfamiliar,
this is mostly HTML
plus a technology called Jinja, which
is a web-based technology for generating
websites dynamically.
The body of this page is
clearly what's of interest.
And you know what?
I bet I could do some
logic right in there.
So let me go ahead and do this.
Let me go ahead and Create,
let's say, a New File.
Let's call this application.py.
I'm going to go ahead
and, just for time's sake,

Arabic: 
من المحتمل أنهم سيرغبون في
القيام بذلك عبر صفحة ويب
ليروا بالفعل مَن هو مُسجل.
ولكن إذا كانت لدينا القدرة في
تعليمة Python البرمجية للقيام بذلك، على سبيل المثال،
التكرار، ما الذي يمكنني فعله بدلاً من
من مجرد الطباعة على الشاشة؟
ما الذي يمكنني طباعته للأسبوع الماضي
ولمجموعة المشاكل السابقة؟
يمكنني طباعة HTML، أليس كذلك؟
على سبيل المثال، جميع الطلاب
الذين سجلوا، يشعرون إلى حد ما
بأنها فرصة
لقائمة غير مرتبة
أو قائمة مرتبة أو
جدول أو أيًا كان.
يمكنكم الآن إنشاء HTML.
إذن دعوني أقوم بهذا.
دعوني أنتقل بالفعل إلى
مثال قمتُ به مسبقًا.
ماذا لو مضيتُ قدمًا
وفتحتُ layout.html.
ها هو تخطيط بسيط
لتطبيق ويب باستخدام Flask.
بالنسبة لهؤلاء الذين ليسوا على دراية به،
هذه HTML تقريبًا
بالإضافة إلى تقنية تُسمى Jinja، والتي
تُعد تقنية قائمة على الويب لإنشاء
مواقع الويب بشكل ديناميكي.
من الواضح أن بنية
هذه الصفحة هي ما تهمنا.
أتعلمون ما الأمر؟
أراهن أنه يمكنني القيام ببعض
المنطق هناك بالضبط.
إذن دعوني أمضي قدمًا وأفعل هذا.
دعوني أمضي قدمًا وأقوم بإنشاء،
لنقل، ملف جديد.
دعونا نُسمي هذا application.py.
سأمضي قدمًا،
توفيرًا للوقت فقط،

English: 
do a little bit of copy-paste
to save myself some keystrokes.
So here's a very simple web app.
And this is going to be my to-do.
So if I go in here to templates,
let me open up index.html--
and let me go head into here.
So long story short--
here's where we're going with this.
What if I instead generate an unordered
list using code from last week,
but I use my for loop
here inside of my web app
instead of actually just with
a simple lecture.py file.
Well, recall that I could
do something like this.
I can have a Jinja loop.
So I could say something
like for row in rows.
And then, down here, I can
preemptively say something
like andfor, which is our
weird syntax from last week.
And then, in here, I
can just do a list item.
And then, if I want to show who
registered, what do I type here?
Something in between these curly braces
if each row represents a registrant?
AUDIENCE: Row.
DAVID J. MALAN: Row name registered.
I can just do something like this.

Arabic: 
وأقوم بالقليل من النسخ واللصق
لأوفر القيام ببعض ضغطات المفاتيح.
إذن، ها هو تطبيق ويب بسيط للغاية.
وسيكون هذا ما أفعله.
لذا إذا انتقلتُ هنا إلى القوالب،
دعوني أفتح index.html--
ودعوني أنتقل إلى هنا.
إذن خلاصة القول--
ها هو ما يقودنا إليه هذا.
ماذا لو قمتُ بدلاً من ذلك بإنشاء قائمة
غير مرتبة باستخدام تعليمة برمجية من الأسبوع الماضي،
لكنني أستخدم التكرار الحلقي من النوع for
هنا داخل تطبيق الويب الخاص بي
في الواقع بدلاً من استخدام
ملف lecture.py بسيط فقط.
حسنًا، تذكرون أنه يمكنني أن
أفعل شيء كهذا.
يمكنني أن أحصل على تكرار Jinja حلقي.
إذن يمكنني قول شيء
كهذا for row في rows.
ومن ثم، هنا بالأسفل، يمكنني
القول بشكل استباقي شيء
مثل andfor، وهذه كانت الصيغة 
الغريبة الخاصة بنا من الأسبوع الماضي.
ومن ثم، هنا،
يمكنني فقط إنشاء عنصر قائمة.
ومن ثم، إذا أردتُ عرض مَن قام
بالتسجيل، فما الذي أكتبه هنا؟
شيء بين هذه الأقواس المتعرجة
إذا كان كل صف يُمثل مُسجَّل؟
الجمهور: صف.
دايفيد مالان: اسم الصف مُسجل.
يمكنني القيام بشيء من هذا القبيل.

Arabic: 
إذن الفكرة نفسها، أقوم بتغليفه فقط
بالقليل من HTML.
الآن دعوني أنتقل إلى
ملف application.py لأنني
سأضطر إلى ملء بعض الفراغات.
ودعوني أرى، كيف يمكنني القيام بذلك؟
حسنًا، في النهاية، أريد
إرجاع نتيجة تقديم
قالب يُسمى index.html.
للذين ليسوا على دراية بهذا،
هذا فقط سطر من التعليمة البرمجية
يقول اعرض هذا الملف للمستخدم.
لكنني لا أريد فقط أن
أعرض له الملف كما هو.
لكن دعونا على الأقل نحصل على هذا الإعداد.
أنا قلق من أنه قد لا يعمل بعد
لأنني أحتاج إلى الحصول على البيانات الفعلية.
إذن كيف يمكنني الحصول على
جميع الصفوف للمُسجَّلين لديّ؟
حسنًا، يمكنني أن أفعل هذا صفوف يساوي db.execute.
ويمكنني أن أمضي قدمًا وأكتب تحديد نجمة من
المُسجَّلين وأقوم بتخزين ذلك هناك.
يُطلق على هذا الملف froshims.db
والذي قمتُ بإنشائه مُسبقًا.
وكل الأشياء الأخرى هي أشياء 
Flask فقط من الأسبوع الماضي.
لا شيء آخر جديد.
الشيء الوحيد
الجديد هو هذا السطر هنا،
وهذا السطر هنا، والآن
هذا السطر هنا حيث
أستخدم SQL داخل
استدعاء Python عبر تمريره
كوسيطة إلى دالة
تُسمى EXECUTE.
كيف يمكنني تمرير الصفوف إلى index.html؟
الجمهور: [INAUDIBLE]

English: 
So same idea, I'm just wrapping
it with a little bit of HTML.
Now let me go to my
application.py file because I'm
going to have to fill in some blanks.
And let me see, how can I do this?
Well, ultimately, I want to
return the result of rendering
a template called index.html.
For families unfamiliar,
this is just a line of code
that says go show that file to the user.
But I don't want to just
show them the file as-is.
But let's at least get this set up.
I'm worried that it might not work yet
because I need to get the actual data.
So how can I get all of the
rows for my registrants?
Well, I can do rows gets db.execute.
And I can go ahead and select star from
registrants and store that in there.
This file is called froshims.db
that I created earlier.
And everything else is just
Flask stuff from last week.
Nothing else is new.
The only thing that's
new is this line here,
this line here, and now
this line here where
I'm using SQL inside of
a Python call by passing
it is an argument to a
function called EXECUTE.
How do I pass the rows to index.html?
AUDIENCE: [INAUDIBLE]

Arabic: 
دايفيد ج. مالان: نعم، على سبيل المثال صفوف تساوي
صفوف وهو التقليد الذي تبنّيناه.
يمكنكم تسميه أي شيء
تريدونه، x يساوي y،
ولكن هذا مباشر
أكثر قليلاً.
إذن هذا ما سنقوله، مرحبًا، قاعدة البيانات، قومي
بإحضار جميع الصفوف من المُسجَّلين لديّ،
ثم تقديم قالب
index.html، والتمرير في هذه الصفوف.
والآن، إذا حبستُ أنفاسى وقمتُ
بتشغيل flask، لا توجد أخطاء في الصيغة.
إذا مضيتُ قدمًا وقمتُ بزيارة
هذا هنا وفتحتُ--
اللعنة-- علامة التبويب، أرى
خطأ داخلي في الخادم.
إذن لحظة نتعلم منها، يا قوم.
دعونا نعود إلى نافذة
المتصفح تلك هنا ونرى ما حدث.
حسنًا.
خطأ في صيغة القالب--
إذن خطأ غبي جدًا.
يبدو أنني توقعتُ قوسًا مربعًا
بدلاً من قوس متعرج.
هذا قابل للإصلاح.
دعوني أنتقل إلى index.html.
وأوه، لم أُنهي فكرتي.
إذن هذا بعض من إحباطات
البرمجة لهؤلاء
الذين يرون هذا لأول مرة.
دعوني أقوم بحفظ ذلك.
دعوني أعود إلى المتصفح
هنا، وسنقوم فقط بإعادة التحميل.
يا إلهي، ها هي ذا،
الآن لديّ صفحة ويب
التي يمكنكم عبرها رؤية
مَن قام بالتسجيل.
لكن أتعرفون ماذا؟

English: 
DAVID J. MALAN: Yeah, like rows equals
rows is the convention we've adopted.
You call it anything
you want, x equals y,
but this is a little
more straightforward.
So this is saying, hey, database, get
me all of the rows from my registrants,
and then render the template
index.html, and pass in these rows.
And now, if I hold my breath and
run flask run, no syntax errors.
If I go ahead and visit
this here and open--
dammit-- the tab, I see
an internal server error.
So teachable moment, families.
Let's go back into that browser
window here and see what happened.
OK.
Template syntax error--
so pretty stupid mistake.
It looks like I expected a square
bracket instead of a curly brace.
That's fixable.
Let me go into index.html.
And oh, I didn't finish my thought.
So that's some of the frustrations
of programming for those
who are seeing this for the first time.
Let me save that.
Let me go back to the browser
here, and we'll just reload.
And oh my god, voila,
now I have a web page
via which you can see
who has registered.
But you know what?

Arabic: 
يمكننا جعل هذا قوي أكثر.
تذكرون أننا كنا نعبث
باستخدام HTTP لبعض الوقت.
وإذا كان هذا هو عنوان URL
الذي أصل إليه، فتذكّروا
أننا عبثنا
بإعادة تنفيذ دالة البحث.
حسنًا، ماذا لو كنتُ أريد دعم بحث كهذا
حتى يمكنني فقط زيارة q
يساوي ومن ثم البحث عن
أسماء أشخاص، لنقل، براين
ورؤية عدد المُسجَّلين باسم براين.
هل يمكننا إضافة دعم
لشيء مثل هذا؟
حسنًا، ربما.
دعوني أعود إلى
IDE، إلى application.py.
ودعوني أمضي قدمًا
وأقول شيئًا من هذا القبيل.
q يساوي request.args احصل على q
لرؤية ما إذا كان أي شيء موجود هناك بالفعل.
ثم دعوني أمضي قدمًا وأفعل هذا.
تحديد نجمة من المُسجَّلين حيث--
دعوني أرى-- q حيث ماذا؟
الاسم يساوي q.
لكنني أحتاج إلى عنصر نائب.
إذن ربما يجب أن أفعل هذا.
وبمجرد أن أفعل هذا، أحتاج إلى ماذا؟
F لسلسلة تنسيق.
إذن يمكنني فقط إنشاء،
وبشكل سريع، أمر SQL
الذي يمكنه إدخال قيمة
q بين تلك الأقواس
المتعرجة للتعبير عن
منطق تحديد جميع

English: 
We can make this more powerful.
Recall that we've been playing
with HTTP for some time.
And if this is the URL
I'm accessing, recall
that we played around with
reimplementing search functionality.
Well, what if I want to support
search such that I can just visit q
equals and then search for
people named, say, Brian
and see how many Brians are registered.
Could we add support
for something like this?
Well, maybe.
Let me go back into the
IDE, into application.py.
And let me go ahead and
say something like this.
q equals request.args get q to
see if anything is actually there.
And then let me go ahead and do this.
SELECT star FROM registrants WHERE--
let me see-- q where what?
NAME equals q.
But I need a placeholder.
So maybe I should do this.
And as soon as I do this, I need a what?
F for a format string.
So I could just create,
on the fly, a SQL command
that plugs in the value
of q between those curly
braces to express the
logic of select all

Arabic: 
المُسجَّلين حيث
أسماؤهم تساوي براين أو فيرونيكا
أو اسم أي شخص كتبتُه.
دعوني أعود إلى المتصفح هنا.
دعوني أنتقل وأفعل
شيء من هذا القبيل الآن.
علامة استفهام q يساوي براين--
سأعقد أصابعي كما فعلتُ من قبل.
اللعنة.
حسنًا.
وما هو الخطأ الذي قمتُ به هنا؟
ما هو الخطأ الذي قمتُ به هنا؟
هذا دقيق.
ونحن نرى هذا لأول مرة.
يعتقد أنه يوجد عمود يُسمى براين.
لكن لماذا يعتقد ذلك؟
حسنًا، ما قمتُ به
بفعالية تم إرساله في هذا.
لا تُعد براين كلمة رئيسية في SQL.
ولأنها سلسلة فعلية
التي أقوم بمقارنتها معها،
ما أحتاج فعله في الواقع هو هذا.
وإلا ستعتقد SQLite أنه
كاسم العمود أو شيء ما
قمتُ بإنشائه مُسبقًا إذن يجب أن نصلح ذلك.
لكن لا مشكلة.
يمكنني وضع علامات الاقتباس هناك.
ولكن على الأرجح يجب أن أضع
q هناك في علامات الاقتباس.

English: 
of the registrants whose
names equal Brian or Veronica
or whoever's name I typed in.
Let me go back to the browser here.
Let me go over and do
something like this now.
Question mark q equals Brian--
cross my fingers as before.
Dammit.
OK.
And what did I do wrong here?
What did I do wrong here?
This is subtle.
And we're seeing it for the first time.
It thinks there's a column called Brian.
But why would it think that?
Well, what I've effectively
done is sent in this.
Brian is not a keyword in SQL.
And because it's an actual string
that I'm comparing against,
what I really need to be doing is this.
Otherwise, SQLite is going to think it's
like the name of a column or something
I pre-created so we have to fix this.
But that's OK.
I can put the quotes there.
But I should probably put
the q there in quotes.

English: 
Let's save this, go back
to the browser, reload.
And there we go.
Now we have functionality for Brian.
And so with this basic building
block, what have we done?
Well, in SQL, we have several
commands at our disposal--
creating a table, which frankly
gets tedious by typing it out.
I myself tend to use and recommend
phpLiteAdmin just to create your table
and get it going.
But then you can certainly manually,
with SQLite3 or phpLiteAdmin INSERT,
or UPDATE, or DELETE,
or SELECT information
once it's actually in the database.
And that's pretty powerful.
But once you do that, you can now use
that same new syntax, that new language
SQL, passing it in as an input with
a "string" to our EXECUTE function,
and now start pulling any data
you want from your database.
Last week, with CSV files,
if you wanted to do this,
you'd have to open the CSV file,
use a for loop to iterate over it,
look over every column and row
for your data, then pass it in.
And that's fine.
That's correct.
That's not bad.
But it's tedious.
And you're reinventing
the wheel again and again.
And there's no filtration built
in as there is to SQL itself.
So you now have a more
sophisticated tool

Arabic: 
دعوني أحفظ هذا، وأعود
إلى المتصفح، وأُعيد تحميله.
وها نحن ذا.
الآن لدينا وظيفة لبراين.
إذن باستخدام هذه الكتلة البنائية
الأساسية، ما الذي قمنا به؟
حسنًا، في SQL، لدينا العديد من
الأوامر تحت تصرفنا--
إنشاء جدول، والذي يصبح
بصراحة أمرًا مملاً عند كتابته.
أنا أميل إلى استخدام
phpLiteAdmin وتوصيتها فقط لإنشاء الجدول الخاص بكم
وجعله يعمل.
ولكن يمكنكم بالتأكيد يدويًا،
باستخدام SQLite3 أو phpLiteAdmin، إدراج معلومات،
أو تحديثها، أو حذفها،
أو تحديدها
بمجرد أن تكون بالفعل في قاعدة البيانات.
وذلك قوي جدًا.
ولكن بمجرد القيام بذلك، يمكنكم الآن استخدام
الصيغة الجديدة نفسها، تلك اللغة الجديدة
SQL، وتمريرها كمدخل باستخدام
"سلسلة" إلى دالة EXECUTE لدينا،
والآن ابدأوا بسحب أي بيانات
تريدونها من قاعدة بياناتكم.
الأسبوع الماضي، باستخدام ملفات CSV،
إذا أردتم القيام بذلك،
كان يجب أن تفتحوا ملف CSV،
واستخدام تكرار حلقي من النوع for للتكراره،
والبحث في كل عمود وصف
عن بياناتكم، ثم تمريرها.
وهذا جيد.
هذا صحيح.
هذا ليس سيئًا.
لكنه مُمل.
وتعيدون اختراع
العجلة مرارًا وتكرارًا.
ولا يوجد تصفية مُدمجة فيه
كما توجد في SQL نفسها.
إذن لديكم الآن أداة
أكثر تطورًا

English: 
in your toolkit so to speak with which
to solve that same kind of problem.
Any questions then on this technique?
All right.
Well, let's look at a bigger database
and see where we can go with this?
So if you go on the
course's website, you'll
see a larger database that's actually
available in multiple formats, SQLite,
which we'll see in a moment,
but also Google Spreadsheets.
Because frankly, it's a
lot more pleasant to look
at your rows and columns in a
GUI than it is, necessarily,
with the file itself.
So this happens to be a free
and open source sample database.
Like, some guy, years ago, took
his actual iTunes database--
all the music he'd ever
bought, he wrote a program
to like analyze Apple's
file format in iTunes
and extract all of the data that
seemed to be stored about him,
I think was the story, and just made
it publicly available as a sample
database for students and teachers
to just use to manipulate data.
But what's interesting
is that this database
demonstrates some other principles
that we really haven't touched on.

Arabic: 
في مجموعة الأدوات الخاصة بكم، إذا جاز التعبير يمكنكم
عبرها حل ذلك النوع نفسه من المشاكل.
إذن أي أسئلة على هذه التقنية؟
حسنًا.
حسنًا، دعونا ننظر إلى قاعدة بيانات أكبر
ونرى إلى أين قد يؤدي بنا هذا الأمر؟
إذن إذا انتقلتم إلى
موقع الدورة على الويب، فسترون
قاعدة بيانات أكبر وهي في الواقع
متاحة في تنسيقات متعددة، SQLite،
والتي سنراها في غضون لحظات،
ولكن أيضًا جداول بيانات Google.
لأنها بصراحة،
جيدة أكثر عند النظر
في الصفوف والأعمدة في GUI
مما هو عليه، بالضرورة،
بالملف نفسه.
إذن يُصادف أن هذا نموذج
قاعدة بيانات مجانية ومفتوحة المصدر.
على سبيل المثال، أخذ شخص ما، منذ سنوات،
قاعدة بيانات iTunes الفعلية الخاصة به--
كل الموسيقى التي اشتراها،
كتب برنامجًا
لتحليل تنسيق
ملف Apple في iTunes
واستخرج جميع البيانات التي
يبدو أنه تم تخزينها عنه،
أعتقد كانت القصة، وجعلها فقط
متاحة للعامة كنموذج
قاعدة بيانات للطلاب والمدرسين
لاستخدامها فقط لمعالجة البيانات.
لكن الأمر المثير للاهتمام
هو أن قاعدة البيانات هذه
تُثبت بعض المبادئ الأخرى
التي لم نتطرق إليها حقًا.

Arabic: 
على سبيل المثال، إذا كنتُ
سأخزِّن، مرارًا وتكرارًا،
جميع هؤلاء الطلاب الذين
يسجّلون في froshims،
ما الذي ترونه في حقول معينة؟
حسنًا، كنتُ كسولاً قليلاً، ولم
أحمّل نفسي عناء كتابة سكن الجميع.
لكن لنفترض أن المئات من الطلاب
قد سجّلوا في froshims.
سيكون الكثير منهم من
ماثيوز، بعضهم من بيني بايكر،
بعضهم من Candaday، وبعضهم من ويلد،
ومجموعات المباني الأخرى في الحرم الجامعي.
يصبح الأمر
سخيفًا قليلاً عندما
ترون ماثيوز، ماثيوز،
ماثيوز،
متكررة كثيرًا-- مثل، 100 مرة أو أكثر.
إذا كان هناك 1600 طالب جديد، يوجد
الكثير من الأطفال في ماثيوز.
ذلك عدد كبير من وحدات البايت
ليتم تخزينه م-ا-ث-ي-و--
لا أعرف.
هذا ليس مهمًا.
لا يهم كيف تتم تهجئتها.
ذلك عدد كبير من وحدات البايت ليتم تخزينه
بالفعل في قاعدة بياناتكم مرارًا
وتكرارًا.
يبدو الأمر كما لو يجب
أن تكون هناك فرصة
لفصل القواسم المشتركة.
وما يفعله الأشخاص عبر قواعد البيانات
هو، بمجرد التعرف على نمط
متكرر للبيانات، والسلاسل نفسها
مرارًا وتكرارًا، أتعلمون ماذا؟
بدلاً من استخدام-- الآن التهجئة تهم--
م-ا-ث-ي-و-ز-- وهي ست وحدات بايت.

English: 
For instance, if I were
to store, again and again,
all of these students who
are registering for froshims,
what do you start to
see in certain fields?
Well, I was a little lazy, and I didn't
bother typing in everyone's dorm.
But suppose that hundreds of students
have registered for froshims.
A lot of them are going to be from
Matthews, some from Pennypacker,
some from Candaday, some from Weld, and
bunches of other buildings on campus.
It starts to get a
little ridiculous when
you see Matthews, Matthews,
Matthews, Matthews,
Matthews-- like, 100 or more times.
If there are 1,600 freshmen, there
are a lot of kids in Matthews.
That's a lot of bytes
to store M-A-T-T-H-E-W--
I don't know.
It's not important.
Doesn't matter how it's spelled.
That's a lot of bytes to actually
store in your database again and again
and again.
It feels like there
should be an opportunity
to factor out the commonalities.
And what humans do with databases
is, once they recognize a recurring
pattern of data, same darn strings again
and again and again, you know what?
Rather than use-- now it matters--
M-A-T-T-H-E-W-S-- which is 8 bytes.

English: 
Or P-E-N-N-Y-P-A-C-K-E-R, which is 11,
then we have a lot of bytes being used
again and again and again
to store all of these dorms.
You know what?
What's better than 11 bytes or 8 bytes?
Let's just use an int, or
let's even use a small int--
2 bytes or 4 bytes to represent dorms.
So instead of storing Matthews,
let's just store the number 10.
And instead of Penny Packer, lets
just store the number 11, thereby,
using some bytes, but
fewer and, therefore,
saving bytes in the long run.
And so with this database demonstrates
is exactly that principle.
Certainly, when it comes to music,
where artists have multiple albums
and artists have multiple
songs, it's probably
a little silly in a musical database
to store the name of the album
again and again and again
and again for all 10 or 12
or 20 tracks or songs on
that particular album.
So what this person did was this.
Notice here, we have a
whole bunch of sheets.
Or in database-speak,
these would be tables.
And notice that these
tables have columns.
And notice that these
columns are album ID,

Arabic: 
أو ب-ي-ن-ي-ب-ا-ي-ك-ر، وهي تسع وحدات،
لدينا الكثير من وحدات البايت المستخدمة
مرارًا وتكرارًا
لتخزين جميع هذه المساكن.
أتعلمون ماذا؟
ما هو أفضل من 9 أو 6 وحدات بايت؟
دعونا فقط نستخدم int، أو
دعونا نستخدم int صغير--
وحدتين أو 4 وحدات بايت لتمثيل المساكن.
إذن بدلاً من تخزين ماثيوز،
دعونا فقط نُخزِّن الرقم 8.
وبدلاً من بيني بايكر، دعونا نُخزِّن
الرقم 9 فقط، وبالتالي،
باستخدام بعض وحدات البايت، ولكن
عدد أقل، وبالتالي،
حفظ وحدات بايت على المدى الطويل.
إذن ما تُثبته قاعدة البيانات هذه
هو بالضبط ذلك المبدأ.
بالتأكيد، عندما يتعلق الأمر بالموسيقى،
حيث يمتلك الفنانون ألبومات عديدة
ولديهم أغاني
كثيرة، من المحتمل أن
تخزين اسم الألبوم في قاعدة بيانات موسيقية
أمرًا سخيفًا قليلاً
مرارًا وتكرارًا
لـ 10 أو 12
أو 20 أغنية أو مقطع موسيقي في
هذا الألبوم الخاص.
إذن ما فعله هذا الشخص هو هذا.
لاحظوا هنا، لدينا
مجموعة كاملة من الأوراق.
أو فيما يتعلق بقاعدة البيانات،
ستكون هذه جداول.
ولاحظوا أن هذه
الجداول تحتوي على أعمدة.
ولاحظوا أن هذه الأعمدة
هي معرّف الألبوم،

Arabic: 
في جدول الألبوم، ومعرّف الألبوم وعنوانه.
ولكن لاحظوا ما فعله بذكاء
شديد باستخدام هذا الحقل، معرّف الفنان.
يمتلك الفنانون أو المطربون الكثير من
الأغاني بأسمائهم، في نهاية المطاف.
ولذا قام بتعيين قيمة فريدة
لكل أغانيهم،
أو قامت Apple بذلك، في iTunes
بشكل غير ظاهر.
إذن، كيف أعرف ما
هو اسم هذا الفنان؟
كيف يمكنكم اكتشاف ذلك؟
هذا ليس مثيرًا للاهتمام بالنسبة لنا كبشر
لنعرف، أوه، الرقم الثاني من معرّف الفنان.
هذا فقط-- ما هذا؟
الجمهور: أنت بحاجة إلى جدول
آخر للفنانين.
ديفيد ج. مالان: أجل.
نحتاج إلى جدول آخر
للفنانين، وهذا صحيح هنا.
إذن دعوني أمضي قدمًا وأنظر هناك.
إذن إذا أردتُ أن أرى-- دعونا نرى،
"Let there be rock،" الفنان رقم 1.
دعونا ننتقل إلى جدول الفنانين.
ويتضح أن، فرقة AC/DC،
هي مَن قامت بغناء تلك الأغنية.
الآن أضفنا خطوة هنا، والتي ربما
تستغرق بعض الوقت.
لكنها ستوفر مساحة على
المدى الطويل إذا لم أُخزِّن أسماء
طويلة للفنانين-- على الرغم من أن
AC/DC ليس اسمًا طويلاً جدًا--
مرارًا وتكرارًا.
الآن، أيهما أفضل؟
حسنًا، إنها مقايضة.
هل اعتدتم بشكل كبير علي إهدار المساحة
وتخزين كل شيء معًا؟
أو أنكم تفضلون توفير مساحة
وفقط قضاء وقت أكثر قليلاً

English: 
in the album table, album ID and title.
But notice what he did very
cleverly with this field, artist ID.
Artists or singers have lots of
songs to their name, eventually.
And so he's assigned each
of them unique value,
or Apple did, in iTunes
underneath the hood.
So how do I know what
this artist's name is?
How would you figure this out?
It's not that interesting to us humans
do know, ooh, artist ID number 2.
This is just-- what's that?
AUDIENCE: You need another
table with artists.
DAVID J. MALAN: Yeah.
We need another table with
artists, which is right over here.
So let me go ahead and look there.
So if I want to see-- let's see,
"Let there be rock," artist number 1.
Let's go to the artists table.
And turns out, AC/DC, the
band is who created that.
Now we've added a step here, which maybe
is costing us a little bit of time.
But it's going to save a space in
the long run if I'm not storing long
artist's names-- although,
AC/DC isn't terribly long--
again and again and again.
Now, which is better?
Well, it's a trade-off.
Are you more comfortable wasting
space and storing everything together?
Or do you prefer to save space
and just spend a little more time

Arabic: 
في جمع البيانات مرة أخرى معًا؟
ولكن سيصبح الأمر
بالفعل مُزعجًا إذا، الآن،
إذا أردتُ إنشاء موقع ويب
يعرض لي أسماء الأغاني
التي لديّ في قاعدة بيانات
ومطربي تلك الأغاني،
ناهيك عن الألبومات، والأكثر من ذلك،
عناوين المقاطع الموسيقية، وهكذا.
يبدو أن هناك
ثلاثة استعلامات، أليس كذلك؟
على سبيل المثال تحديد الألبوم، تحديد
الفنان، تحديد العناوين--
لكن لا.
باستخدام SQL، يمكنكم
طي ذلك تمامًا.
لأنه لاحظوا، في هذا
الجدول هنا، الفنان،
يوجد عمود يُسمى
معرّف الفنان وهو عبارة عن أرقام.
ولاحظوا، إذا كنتم
تتخيلون هذا، فإن
هذا يشبه أطراف الأصابع هنا-- دعونا
نقترح بشكل مجازي--
تمثيل معرّف الفنان.
إذا انتقلتُ إلى الألبوم الآن، لاحظوا
أن لدينا معرّف الألبوم وعنوانه،
لكن لدينا أيضًا معرّف الفنان.
إذن إذا تخيلتم هذين الجدولين
يتقاسمان هذا العمود المشترك، ماذا لو
قمنا بتجميعهما معًا
هكذا، ليتطابق أحدهما
على اليسار، والآخر على
اليمين، وبالتالي نعيد بناء
كل المعلومات
وتكرارها حسب
الحاجة لكي أجد الألبوم
والعنوان والفنان فقط.

English: 
joining the data back together?
But it's going to be
really annoying if, now,
if I want to make a website that
shows me the names of the songs
that I have in a database
and the artists for them,
let alone the albums, and more of that,
the titles of the tracks, and so forth.
It feels like that's
three queries, right?
Like SELECT the album, SELECT
the artist, SELECT the titles--
but no.
With SQL, you can
collapse that altogether.
Because notice, in this
table here, artist,
there is a column called
Artist ID that's numbers.
And notice, if you kind
of picture this, it's
like finger tips here-- let's
propose metaphorically--
represent the artist ID.
If I go into album now, notice
that we have album ID and title,
but we also have artist ID.
And so if you imagine these two tables
sharing this common column, what if we
kind of stitch them together
like this, lining up one
on the left, the other on the
right, thereby reconstructing
all of the information
and duplicating it as
needed so that I get back just the
album and the title and the artist.

Arabic: 
حسنًا، كيف يمكنني التعبير عن ذلك؟
حسنًا، دعوني أمضي قدمًا في CS50 IDE
حيث لديّ نسخة من هذا الملف.
دعوني أغلق كل علامات التبويب من وقت
سابق وأنتقل إلى هذا الملف الذي يُسمى lecture.db.
وفي lecture.db، في phpLiteAdmin،
سنرى جميع هذه الجداول نفسها.
وقمتُ حرفيًا فقط
باستيرادها إلى SQLite.
سترون جميع هذه الجداول نفسها.
يمكننا تصفح الألبوم تمامًا كما فعلنا من قبل.
ونرى فقط تنسيقًا
مختلفًا للبيانات نفسها.
إنها البيانات نفسها من
جدول بيانات Google،
وهو سهل الاستخدام بشكل كبير فقط.
ودعوني أمضي قدمًا وأفعل هذا.
يمكنني، بالطبع،
تحدي نجمة من الألبوم
حيث معرّف الفنان لدينا يساوي 1 للحصول
على جميع ألبومات AC/DC.
وبالفعل، هنا، لديّ اثنتان.
لدى هؤلاء أغنية For those about to rock،
We salute you، وLet there be rock.
لديهم اثنتان.
ولكن لاحظوا، تحتوي الصفوف التي حصلت
عليها فقط على أي معلومات؟
عنوان معرّف الألبوم، ومعرّف الفنان.
أعرف فقط، كشخص، أن
أوه، هذه هي ألبومات AC/DC.

English: 
Well, how can express that?
Well, let me go ahead into CS50 IDE
where I have a copy of this file.
Let me close all of my tabs from earlier
go into this file called lecture.db.
And in lecture.db, in phpLiteAdmin,
we'll see all of those same tables.
And I literally just
imported it into a SQLite.
You'll see all of these same tables.
We can browse album just as before.
And we just see a different
format for the same data.
It's the same data from
the Google Spreadsheet,
which is just more user-friendly.
And let me go ahead and do this.
I could, of course,
SELECT star from album
Where our artist ID equals 1 to
get back all of AC/DC's albums.
And indeed, here, I have two.
They have For those about to rock,
We salute you, and Let there be rock.
They have two.
But notice, the rows I got back
contain only what information?
Album ID title, and artist ID.
I just know, as a human, that
oh, these are AC/DC's albums.

English: 
But what if I want to know, well,
OK, I see that artist ID is 1.
So all right, well, let
me open another tab here.
And now let me SELECT star from
artist WHERE artist ID equals 1.
And so if I want to learn something
about that artist-- let me go ahead
and Zoom Out, click Go,
and OK-- now I get AC/DC.
Well, this is great.
Now I have to results, two sets of rows.
This is stupid.
Now I'm just creating work for
myself by having two return values.
I could call db EXECUTE twice.
But there's a better way.
It turns out, SQL allows you to
join tables just using SQL itself.
So I'm going to go ahead and do this.
I'm going to go ahead and
SELECT star FROM album,
but also FROM artist
WHERE Album.Artistid--
let me scroll to the right--
equals Artist.Artistid.
So notice I'm saying select
everything from two tables,

Arabic: 
ولكن ماذا لو أردتُ أن أعرف،
حسنًا، أرى أن معرّف الفنان هو 1.
إذن حسنًا، جيد، دعوني
أفتح علامة تبويب أخرى هنا.
والآن دعوني أقوم بتحديد نجمة من الفنان
حيث معرّف الفنان يساوي 1.
ولذا إذا أردتُ أن أعرف شيئًا
عن ذلك الفنان-- دعوني أمضي قدمًا
وأقوم بالتصغير، وأنقر فوق Go،
وحسنًا-- الآن لقد حصلتُ على AC/DC.
حسنًا، هذا رائع.
الآن لديّ نتيجتان، مجموعتان من الصفوف.
هذا غبي.
الآن، سأقوم بإنشاء ذلك لنفسي فقط
عن طريق الحصول على قيمتي إرجاع.
يمكنني استدعاء db EXECUTE مرتين.
لكن هناك طريقة أفضل.
يتضح أن، SQL تتيح لكم
جمع الجداول فقط باستخدام SQL نفسها.
إذن سأمضي قدمًا وأفعل هذا.
سأمضي قدمًا وأقوم بتحديد
نجمة من الألبوم،
ولكن أيضًا من الفنان
حيث Album.Artistid--
دعوني أنتقل إلى اليمين--
يساوي Artist.Artistid.
إذن لاحظوا أنني أقول حدّد
كل شيء من جدولين،

Arabic: 
ولكن فقط قم بذلك حيث
تحتوي جداول الألبوم، عمود معرّف
الفنان على نفس القيمة
كجداول الفنان أي عمود معرّف الفنان.
هذا يشبه تجميع
أصابعي معًا، بشكل مجازي،
للبحث عن
هذا العمود المشترك.
إذا مضيتُ قدمًا، ونقرتُ فوق Go، رائع،
انظروا ما الذي قمتُ بإنشائه للتو.
إنها معلومات كثيرة،
ولكن لديّ معرّف الألبوم وعنوانه،
لديّ معرّف الفنانين، ولكن أيضًا لديّ
اسم ذلك الفنان.
إذن إذا كنتم الآن
تتذكرون تعليمة Python البرمجية،
أوه، يمكنني الآن الحصول على
مجموعة كاملة من الصفوف التي تحتوي
كل شيء يهمني مرة واحدة.
لا أحتاج إلى إجراء عمليتي تحديد استعلامات.
يمكنني تجميع هذه الجداول بهذه الطريقة.
وأنا أستخدم كلمة تجميع بشكل متعمد.
يتضح أنه توجد طريقة
أخرى للتعبير عن هذا الشيء نفسه.
بدلاً من استخدام صيغة الفاصلة تلك،
قد ترون هذا أيضًا،
تحديد نجمة من الفنان تجميع الألبوم
على Artist.Artistid يساوي--
دعوني أقوم بالتمرير--
Album.Artistid.

English: 
but only do so where the
album tables, artist ID
column has the same value as the
artist tables artist ID column.
That's kind of the stitching,
metaphorically, of my fingers
together, looking for
that common column.
If I go ahead and click Go, wow,
look at what I've just constructed.
It's a lot of information,
but I have album ID and title,
I have artists ID still, but I have
the name of that artist altogether.
So if you now let your mind
wander back to the Python code,
oh, I could now get a whole
bunch of rows containing
everything I care about all at once.
I don't need two select queries.
I can join these tables in this way.
And I use join very deliberately.
It turns out that there's another
way to express this same thing.
Instead of using that comma syntax
I did, you might see as well this,
Select star From Artist JOIN
Album ON Artist.Artistid equals--
let me scroll over--
Album.Artistid.

Arabic: 
سيكون لهذا
التأثير نفسه بالضبط،
ولكن قد تجدون فقط أنه يبدو
بديهيًا أكثر لكم.
حدّد كل شيء من نتيجة
تجميع هذين الجدولين.
كيف تريدون تجميعهما؟
حسنًا، قم بتجميعهما على هذا يساوي ذلك--
مجرد طريقة أخرى
للتعبير عن الفكرة نفسها.
وإذا قمتُ بالنقر فوق Go، فسأحصل
على المعلومات نفسها.
إذن في نهاية المطاف، باستخدام التجميعات هل
لدينا القدرة على إعادة تجميع البيانات.
إذن من ناحية، هذا فقط تدريب جيد
على تطبيع قاعدة البيانات لديكم.
تحديد الأعمدة التي تحتوي على الكثير
جدًا من التكرارات، وفقط
تخزين تلك المعلومات مرة واحدة.
على سبيل المثال، CS50 Finance،
إذا كنتم تدعمون
العديد من المستخدمين المختلفين، في كل مرة يشتري
فيها مالان أو براين أو فيرونيكا سهمًا،
يبدو الأمر سخيفًا
قليلاً لتخزين مالان
أو براين أو فيرونيكا بجانب Netflix،
الرمز، وعدد الأسهم
التي اشتراها أحدنا.
لأن مالان، مالان،
مالان، مالان
ستظهر جميعها في قاعدة البيانات.
وماذا لو قمتُ بتغيير اسم المستخدم لديّ
أو اسمي أو أصبح أي شخص متزوج
وبالتالي، يتغير؟
مثلاًَ، لماذا تخلقون
تلك الفوضى لأنفسكم؟
بدلاً من ذلك، أعطوني أنا وبراين
وفيرونيكا وكل شخص آخر معرّفًا فريدًا.

English: 
This is going to have
the exact same effect,
but you might just find that it reads
a little more intuitively to you.
Select everything from the result
of joining these two tables.
How do you want to join them?
Well, join them on this equaling that--
just another way of
expressing the same idea.
And if I click Go, I get
back the same information.
So ultimately, with JOINs do we
have the ability to reassemble data.
So on the one hand, it's just good
practice to normalize your database.
Identify columns that have lots and
lots and lots of redundancy, and only
store that information once.
For instance, CS50 Finance,
if you're supporting
many different users, every time Malan
or Brian or Veronica buys a stock,
feels like it would be a
little silly to store Malan
or Brian or Veronica along with Netflix,
the symbol, and the number of shares
one of us bought.
Because Malan, Malan,
Malan, Malan is going
to appear all throughout the database.
And what if I change my username
or my name or someone gets married
and, therefore, it changes?
Like, why do you create
that messiness for yourself?
Instead, give Brian and Veronica and
me and everyone else a unique ID.

English: 
And when they buy something, just
store their user ID or customer ID
or however you want to think about it,
just like with album ID and artist ID.
And so normalizing a database is all
about finding those commonalities
and moving the data into its own table.
And if you care about
rejoining it, just use
SQL to reconstruct that view
of the data, so to speak.
So what else can we do here as well?
It turns out that there is in
SQL, not just primary keys,
but there are unique constraints in
some databases where you can specify,
this isn't my primary key,
but I want it to be unique.
You can specify that
something should be indexed.
So it turns out that, if you just
know there's a field in your database
that you want to be able to
search on very efficiently,
you can index it in advance.
And you'll see or be able to do this
if you'd like for final projects
or even for the next
problem set if you'd like.
But what this enables
are queries like this.
If I want to go ahead and
search for, for instance--
what would be a good example?
Rock.
I'm interested in rock.

Arabic: 
وعندما يقومون بشراء شيء ما، فقط
قوموا بتخزين معرّف المستخدم أو العميل الخاص بهم
أو أيًا كانت الطريقة التي تريدون أن تفكروا بها في ذلك،
تمامًا مثل معرّف الألبوم ومعرّف الفنان.
ولذا تطبيع قاعدة البيانات يدور
حول إيجاد تلك القواسم المشتركة
ونقل البيانات إلى الجدول الخاص بها.
وإذا كنتم تهتمون
بإعادة تجميعها، فقط استخدموا
SQL لإعادة إنشاء عرض
البيانات ذلك، إذا جاز التعبير.
إذن ما الذي يمكننا فعله هنا أيضًا؟
يتضح أن في SQL
يوجد، ليس فقط مفاتيح أساسية،
ولكن توجد أيضًا قيود فريدة في
بعض قواعد البيانات حيث يمكنكم تحديد،
هذا ليس المفتاح الأساسي الخاص بي،
ولكنني أريده أن يكون فريدًا.
يمكنكم أن تحددوا أنه
يجب فهرسة شيء ما.
إذن يتّضح أنه، إذا كنتم فقط
تعرفون أنه يوجد حقل في قاعدة بياناتكم
التي تريدون أن تتمكّنوا من
البحث فيه بفعالية كبيرة،
يُمكنكم فهرستها مُسبقًا.
وسترون أو ستتمكّنوا من فعل ذلك
إذا أردتم ذلك في المشاريع النهائية
أو حتى لمجموعة
المشاكل القادمة إذا كنتم تريدون ذلك.
لكن ما يُمكّنه هذا هو
استعلامات مثل هذه.
إذا أردتُ أن أمضي قدمًا
وأبحث عن، على سبيل المثال--
ما الذي سيكون مثالاً جيدًا؟
الروك.
أنا مهتم بموسيقى الروك.

English: 
So if I want to go into My SQL tab here.
I could say something like this.
SELECT star FROM Album
WHERE Name not equals,
but where name is LIKE and
then I'm going to say 'Rock.'
But if I want any number of
characters to come before that word,
I can use a percent sign.
And if any number of characters
after, I can use a percent sign.
These are like wildcards.
In most languages, you would use star.
In SQL, you use percent signs.
But it means the same thing.
And if I go ahead and
say go, now I get back--
oh, I get the got wrong lecture, album,
oh, title I think is what I wanted.
Let me try that again, sorry--
WHERE Title LIKE 'Rock'--
let me go ahead and click Go.
And voila, here are all of the
albums in the database that
have the word rock in them.
Now, as an aside, this table
has a lot of more albums in it.
And frankly, it's small enough though.
It has hundreds of rows,
maybe a few thousand rows.
None of us humans are really going
to notice how slow linear search is.
But if you start having thousands
of rows, tens of thousands

Arabic: 
لذا إذا أردتُ أن أنتقل إلى علامة تبويب SQL هنا.
يمكنني قول شيء من هذا القبيل.
تحديد نجمة من الألبوم
حيث الاسم لا يساوي،
ولكن حيث الاسم مثل
ومن ثم سأقول "موسيقى الروك."
ولكن إذا أردتُ أن يأتي أي عدد
من الأحرف قبل هذه الكلمة،
يمكنني استخدام علامة النسبة المئوية.
وإذا جاء أي عدد من الأحرف
بعدها، يمكنني استخدام علامة النسبة المئوية.
هذه مثل أحرف البدل.
في معظم اللغات، ستستخدمون نجمة.
في SQL، تستخدمون علامات النسبة المئوية.
لكنها تعني الأمر نفسه.
وإذا مضيتُ قدمًا وقلتُ
go، الآن أعود--
أوه، أحصل على، حصلتُ على المحاضرة الخاطئة، الألبوم،
أوه، أعتقد أن ما أردتُه هو عنوان.
دعوني أحاول ذلك مجددًا، عذرًا--
حيث العنوان مثل "الروك"--
دعوني أمضي قدمًا وأنقر فوق Go.
وها هي ذا، الألبومات جميعها
في قاعدة البيانات التي
تحتوي على كلمة روك.
الآن، كملاحظة جانبية، يحتوي هذا الجدول
على الكثير من الألبومات.
وبصراحة، إنه صغير بما يكفي.
إنه يحتوي على مئات الصفوف،
ربما بضعة آلاف من الصفوف.
لن يلاحظ أي واحد منا نحن البشر
مدى بُطء البحث الخطي حقًا.
لكن إذا بدأتم بالحصول على آلاف
الصفوف، أو عشرات الآلاف

English: 
of rows, millions of
rows, not having an index
means that searching for something
like rock is going to start at the top
and search every darn field all
the way to the bottom, big O of n.
If you instead tell the
database, I know I'm
going to be searching on this column
a lot, please index it for me,
here comes the secret sauce.
SQLite, Oracle, Microsoft
Access, and so forth, they
will, using their own
intellectual property,
build up some fancy data
structures-- trees, or hash tables,
or whatever in memory, store the
data for you invisibly in that format
so that, when you do ask for a question
like, show me all the albums like rock,
they can answer you in much
faster time than linear.
And that too is what you get with
SQL that you don't get with CSVs.
CSVs are, by nature, only linear.
So we can do better.
But you, the programmer,
have to help the database
and actually give it those
hints, not just the types,
but also hints like this.
And as an aside, there's also
the notion of foreign keys
where, if you really want to lock
things down, you can specify that,
if you ever see in album
ID in another table,

Arabic: 
من الصفوف، أو ملايين
الصفوف، بدون فهرس
هذا يعني أن البحث عن شيء
مثل روك سيبدأ في الأعلى
والبحث في كل حقل على
طول الطريق إلى الأسفل، حرف O كبير من n.
بدلاً من ذلك إذا أخبرتم
قاعدة البيانات، أعلم أنني
سأبحث في هذا العمود
كثيرًا، من فضلك قم بفهرسته من أجلي،
ها هي الخلطة السرية.
SQLite، وOracle، وMicrosoft
Access، وما إلى ذلك، فهم
سيقومون، باستخدام الملكية
الفكرية الخاصة بهم،
بإنشاء بعض بنيات البيانات
الرائعة-- أشجار، أو جداول علامة تجزئة،
أو أي شيء في الذاكرة، وتخزين
البيانات لكم بطريقة غير مرئية في هذا التنسيق
إذن، عندما تطرحون سؤالاً
على سبيل المثال، اعرض لي جميع الألبومات مثل روك،
يمكنها أن تجيب بشكل
أسرع بكثير من الإجابة الخطية.
وهذا أيضًا هو ما تحصلون عليه باستخدام
SQL وليس باستخدام ملفات CSV.
تُعد ملفات CSV، حسب طبيعتها، خطية فقط.
إذن يمكننا فعل ما هو أفضل.
لكنكم، كمبرمجين،
يجب أن تساعدوا قاعدة البيانات
وتعطوها بالفعل تلك
التلميحات، ليست فقط الأنواع،
ولكن تلميحات أيضًا كهذه.
وكملاحظة جانبية، هناك أيضًا
فكرة المفاتيح الخارجية
حيث، إذا أردتم حقًا قفل
أشياء، فيمكنكم تحديد ذلك،
إذا رأيتم ذلك من قبل في معرّف
الألبوم في جدول آخر،

Arabic: 
إذا كانت الكلمة الرئيسية
في جدول الألبومات،
حسب التعريف، في الجدول الآخر،
ستتم تسميتها كلمة رئيسية خارجية.
لأنه بالفعل لا تنتمي
إلى هناك، لكنها
تشير إلى عمود في مكان آخر.
إذن توجد
تقنيات ومفردات كثيرة.
ونرحب بكم لتتعمقوا في الأمر أكثر.
والاحتمالات هي، أن الكثير منكم
سيفعل ذلك في المشاريع النهائية،
حسب طبيعة الرغبة في ميزات
معينة، من بينها، حتى
تلك التي رأيناها مثل الزيادة
التلقائية وليس فارغ.
كملاحظة جانبية أيضًا، حتى SQL تحتوي على دالات.
وبالنسبة إلى علماء البيانات
والإحصائيين
إنها مفيدة للغاية لتتمكّنوا فقط من
القيام بعملية حسابية وتلخيص البيانات مباشرة
داخل SQL دون كتابة
تعليمة Python البرمجية أو R أو أي شيء آخر.
يتم الإنشاء في SQLite
وقواعد البيانات الأخرى هي
دالات مثل هذه للمتوسط،
وحساب أشياء، والحصول على
الحد الأدنى، والأقصى، والمجموع، وهكذا--
تحصلون على كل هذا مجانًا
باستخدام قواعد البيانات متعددة.
كل ما يتطلبه الأمر في سياق
Python هو سطر كهذا.
لكن، لكن، لكن
توجد بعض المشاكل.
ودعونا ننهي الأمر من خلال إلقاء نظرة على مشكلتين من
المشاكل والتهديدات الأساسية التي
لا يتم تقديرها بالفعل في كثير من الأحيان.
في الواقع، علينا إصلاح
ثغرة خطيرة جدًا قمتُ بتقديمها
في تعليمتي البرمجية في وقت سابق.

English: 
if it's a primary key
in the album table,
by definition, in the other table,
it's going to be called a foreign key.
Because it doesn't really
belong there, but it's
referencing a column elsewhere.
So there's a lot more
technology and vocabulary.
And you're welcome to dive in deeper.
And odds are, many of you
will for final projects,
by nature of wanting certain
features, among them, even
the ones we've seen like auto
incrementing and not null.
As an aside too, SQL even has functions.
And for data scientists
and statisticians
it's super useful to be able to just
do math and summaries of data right
within SQL without ever writing
Python code or R or anything else.
Built into a SQLite
and other databases are
functions like this for average,
counting things, getting
the min, max, sum, and so forth--
all of that you get for free
with a lot of databases.
All it takes in the context
of Python is a line like this.
But, but, but, but, but
there are some problems.
And let's end by taking a look at two
fundamental problems and threats that
are too often underappreciated.
And in fact, we have to fix a very
serious vulnerability that I introduced
into my very own code earlier.

Arabic: 
ولكن أولاً، ما يُسمى بشرط التعارُض.
في الاستقصاء-- أو بالأحرى، دعونا نرى--
لنفترض أننا رجعنا بالذاكرة إلى
بداية الفصل الدراسي، حيث قام معظمكم
بالتسجيل على حساب GitHub
للمرة الأولى.
وانتقلتم إلى github.com/signup.
بالنسبة لمَن ليسوا على دراية به،
GitHub هو موقع ويب
حيث يمكنكم حفظ وتخزين برمجة التعليمة البرمجية
التي قمتم بكتابتها
وتريدون التعاون مع الآخرين عليها.
واخترتم اسم مستخدم.
ودعوني أمضي قدمًا وأحاول اختيار
اسم مستخدم، على سبيل المثال، jharvard
لجون هارفارد.
لاحظوا أن الموقع على الفور
قال أن اسم المستخدم موجود.
حسنًا، هذا مفيد.
ومن المحتمل أنه يمكنكم تخمين كيف يتم
هذا الأمر-- ربما بعض JavaScript،
باستخدام AJAX، والتحدث إلى
الخادم، والحصول على الاستجابة،
وتغيير HTML أو
CSS أو أيًا كانت.
قد يستغرق ربط كل ذلك
معًا بعض الوقت.
لكن هذا ما يحدث على الأرجح.
إذن دعوني أُجرب اسم مستخدم
طويل وعشوائي جدًا غير موجود.
مهلاً، إنه متوفر.
ولكن من المحتمل أنه ليس أمرًا جيدًا لكي
أقوم ببث هذا على الإنترنت.
لأنه إذا انتظرتُ طويلاً بما فيه الكفاية، أراهن
أن شخص ما يمكنه، للتسلية،
فقط التسجيل بهذا، ناهيك
عن أي شخص في هذه الغرفة.

English: 
But first, the so-called race condition.
In survey-- or rather, let's see--
suppose that we think back at the very
start of the semester, most of you
signed up for a GitHub account
for the very first time.
And you went to github.com/signup.
For those unfamiliar,
GitHub is a website
where you can save and store
programming code that you've written
and want to collaborate with others on.
And you chose a username.
And let me go ahead and try choosing
a username like, say, jharvard
for John Harvard.
Notice that the website immediately
said the user name is taken.
All right, that's useful.
And you can probably guess how this
is done-- maybe a little JavaScript,
using AJAX, talking to the
server, getting the response,
changing the HTML or
the CSS or whatever.
Might take some time to
wire all that together.
But that's probably what's going on.
So let me try a really long
random username that is not taken.
Hey, it's available.
But probably is not a good thing that
I'm streaming this on the internet.
Because if I wait long enough, I bet
someone could, for playful reasons,
just sign up for this, let
alone anyone in this room.

English: 
But you've just told me it's available.
So good.
I'm really excited.
I've got my username.
Let me go ahead and type
in my email address,
malan@harvard.edu, my password,
12345-- take a few moments there.
Verify my account and so forth.
And I click Submit.
Suppose that I'm told, momentarily,
sorry, that username has been taken.
Could that happen?
Yeah, if any of you were trying
to mess with me right now,
you would have signed up for that
username and beaten me to the punch
so that when I hit Join, I get an error.
That's the definition of a race
condition where two people or two users
or two computers or two threads--
if we really roll back to our
discussion of threads in Scratch--
are trying to do the same
thing at roughly the same time.
And if those two things,
threads or humans,
check the state of a variable,
which is a fancy way of saying
is the username available,
they both get back answers.
But then some number
of split seconds later,
then they make a decision based on that
information, there is a window of time,
either split seconds or
even seconds or minutes,

Arabic: 
ولكنك أخبرتني للتو أنه متوفر.
جيد جدًا.
أنا متحمس جدًا.
لقد حصلتُ على اسم المستخدم الخاص بي.
دعوني أمضي قدمًا وأكتب
عنوان بريدي الإلكتروني،
malan@harvard.edu، كلمة المرور الخاصة بي،
12345-- يستغرق الأمر بضع لحظات هناك.
التحقّق من حسابي وهكذا.
ثم أنقر فوق Submit.
لنفترض أنه تم إخباري، بشكل مؤقت،
معذرةً، اسم المستخدم هذا موجود بالفعل.
هل يمكن أن يحدث ذلك؟
نعم، إذا حاول أحدكم
أن يعبث معي الآن،
فقد تقومون بالتسجيل باسم 
المستخدم ذلك وتسبقوني
لذا عندما أضغط على الانضمام، أحصل على خطأ.
هذا هو تعريف شرط التعارض
حيث يوجد شخصان أو مستخدمان
أو جهازا كمبيوتر أو مُؤشرا ترابط--
إذا أردنا بالفعل تذكّر مناقشتنا
عن مؤشرات الترابط في سكراتش--
إنهما يحاولان القيام بالشيء
نفسه في الوقت نفسه تقريبًا.
وإذا كان هذان الشيئان،
مؤشرات ترابط أو أشخاص،
يتحققان من حالة المتغير،
وهي طريقة رائعة لقول
هل اسم المستخدم متوفر،
ويحصل كلاهما على إجابات.
لكن بعد ذلك،
بعد بضعة أجزاء من الثانية لاحقًا،
يتخذون قرارًا بناءً على تلك
المعلومات، توجد نافذة للوقت،
إما أجزاء من الثانية أو
حتى ثواني أو دقائق،

English: 
where the state of that variable
could, of course, change.
So if you two, literally,
right now on your laptop,
typed that very long username, all of
us would probably be told, green light,
it's available.
But only one of us is
actually going to get it.
And that's because of a race condition.
Literally, all of us might be
racing to sign up for that value.
And it's when state can change
in between things happening.
This is a bad thing
because it makes your data
vulnerable to changes by someone
you don't necessarily intend.
Or if the database
isn't smart, you might
be able to do especially bad things.
ATMs are a canonical example of this.
If you had a malicious adversary trying
to log into two bank accounts at once
or two physical machines at once, either
with two cards or two accounts and two
laptops, you could imagine both
of them trying to deduct, like,
$100 from the same account instantly.
Because imagine a
poorly-implemented bank website.
It checks the account balance
of the user logged in.
Do you have $100?
If the answer is yes, maybe both
websites are going to say yes,
you may deduct $100.

Arabic: 
حيث يمكن أن تتغير، بالطبع،
حالة ذلك المتغير.
إذن إذا قمتم أنتم أيضًا، حرفيًا،
الآن على جهاز الكمبيوتر المحمول،
بكتابة اسم المستخدم الطويل جدًا ذلك، من
المحتمل أنه سيتم إخبارنا جميعًا، ضوء أخضر،
أنه متوفر.
لكن سيحصل عليه واحد منا فقط
بالفعل.
وذلك بسبب شرط التعارض.
حرفيًا، قد يتعارض جميعنا
في التسجيل لتلك القيمة.
و عندما يمكن للحالة أن تتغير
تحدث أشياء بين ذلك.
هذا أمر سيء
لأنه يجعل البيانات لديكم
مُعرضة للتغيرات عبر شخص
لا تقصدونه بالضرورة.
أو إذا لم تكن قاعدة البيانات
ذكية، فربما
سيكون بإمكانكم القيام بأشياء سيئة بشكل خاص.
تُعد أجهزة الصراف الآلي مثال متعارف عليه لهذا.
إذا كان لديكم خصم ضار يحاول
تسجيل الدخول إلى حسابين مصرفيين في وقت واحد
أو جهازين ماديين في وقت واحد، إما
عبر بطاقتين أو حسابين وجهازي
كمبيوتر محمول، يمكنكم تخيُل أنهما
سيحاولان اسقتطاع، على سبيل المثال،
مئة دولار من الحساب نفسه على الفور.
لأن تخيلوا
موقع الويب الخاص بالبنك تم تنفيذه بشكل سيئ.
يتحقق من رصيد حساب
المستخدم الذي سجّل الدخول.
هل لديك مئة دولار؟
إذا كانت الإجابة نعم، ربما
سيقول كلا موقعي الويب نعم،
يمكنك استقطاع مئة دولار.

Arabic: 
تضغط على Enter
وها هي ذا، تستقطع مئة دولار.
يحصل المستخدم عليها بطريقة ما لأنه
تم نقلها إلى حساب آخر.
لكن يعتقد البنك أنه فعل
ذلك مرة واحدة فقط، يستقطع 100 $،
ولكنك قد رحلت للتو ومعك 200 $
لأنك اتخذت قرار بناءً
على الإجابة نفسها في
مؤشري ترابط مختلفين
أو برنامجين مختلفين
أو جهازي كمبيوتر مختلفين.
إذن خلاصة القول، يمكن لهذا أن يحدث
في العالم الحقيقي حتى.
كان هذا مثال قد تعلمته من المُرشد
الخاص بي منذ سنوات.
لنفترض أنكم ورفقاء سكنكم
لديكم ثلاجة صغيرة في السكن.
وأنكم معتادون، بالطبع،
على شرب الكثير من الحليب.
وإذن نفد الحليب من الثلاجة.
وتعود إلى المسكن، أول
رفيق سكن بعد المحاضرات.
وتُدرك، أوه،
أنا حقًا بحاجة مشروب حليب.
وإذن تتفقد الثلاجة.
لا يوجد شيء هناك.
إذن تغلق الثلاجة،
وتدخل مباشرةً، وتنتقل إلى CVS،
وتقف في الصف لشراء بعض الحليب.
في الوقت نفسه، يأتي رفيقك إلى السكن.
أيضًا، هو حقًا بحاجة مشروب من الحليب.
إذن يتحقق من
حالة المتغير.
تبًا، لا يوجد حليب.
يغلق الثلاجة، ثم يذهب على سبيل المثال
إلى Tommy's Convenience أو أي مكان آخر
قريب ويقف في الصف لبعض الحليب.
بالطبع، بعد ذلك يصل كلاكما
للمسكن في نهاية المطاف.

English: 
You hit enter and
voila, you deduct $100.
The user gets it somehow because it's
transferred to some other account.
But the bank thinks it only
did that once, deducts $100,
but you've just walked away with $200
because you made a decision based
on the same answer in
two different threads
or two different programs
or two different computers.
So long story short, this can
happen even in the real world.
An example I was taught by my
advisor years ago was this.
Suppose you and your roommates
have a little dorm fridge.
And you're in the habit, of
course, of drinking a lot of milk.
And so the fridge has run out of milk.
And you come home, the first
roommate after classes.
And you realize, oh, I
really need a drink of milk.
And so you check the fridge.
There's nothing there.
So you close the fridge, and you
walk into the square, go to CVS,
and get in line to buy some milk.
Meanwhile, your roommate comes home.
Also, they really need a drink of milk.
And so they check the
state of the variable.
Argh, no milk.
Close the fridge, and then walk to like
Tommy's Convenience or some other place
nearby and get in line for some milk.
You of course, then both
get home eventually.

English: 
And what happens now?
Dammit, now you have twice as much milk.
And milk goes bad quickly.
So now this is a problem,
a very bad problem.
You have twice as much milk
as you could possibly drink.
But what's the origin of
that problem fundamentally?
AUDIENCE: You're out of something.
DAVID J. MALAN: You're
out of something, but--
AUDIENCE: You need it.
DAVID J. MALAN: --you need it.
But why did I end up with two?
AUDIENCE: There's no flag.
DAVID J. MALAN: There's no flag, right?
There's no indication.
There's no sharing of state.
You both inspected the
value of the variable,
made a decision independently on it.
But the state of that variable
changed on one of you.
Because when one of you came home,
the later person, damn, like,
the milk has already been refilled.
So how do you solve this?
In the real world, how could
you avoid this problem?
You just, one, never do
errands for your roommate.
AUDIENCE: The magnet you put on
the refrigerator says get this.
DAVID J. MALAN: Mag-- yes.
A shopping list, right-- gone for milk--
Arrested Development.
Always leave a note, right?
You could convey that information.
You could more dramatically
lock the refrigerator, right?
Padlock the thing, and
so your roommate can't
inspect the state of the refrigerator
while you are gone, therefore,

Arabic: 
والآن ما الذي يحدث؟
اللعنة، الآن لديكم ضعف كمية الحليب.
ويفسد الحليب بسرعة.
إذن الآن هذه مشكلة،
مشكلة سيئة للغاية.
لديكم ضعف كمية الحليب
عن التي بإمكانكم شربها.
ولكن ما هو أصل
تلك المشكلة بشكل أساسي؟
الجمهور: شيء ما نفد عندك.
ديفيد ج. مالان: شيء ما
نفد عندك، لكن--
الجمهور: أنت بحاجة إليه.
ديفيد ج. مالان: --أنت بحاجة إليه.
لكن لماذا انتهى بي الأمر باثنين؟
الجمهور: لا يوجد علم.
ديفيد ج. مالان: لا يوجد علم، أليس كذلك؟
لا توجد إشارة.
لا يوجد مشاركة الحالة.
كلاكما قمتما بفحص
قيمة المتغير،
اتخذتما قرار بشكل مستقل بناءً عليه.
لكن تغيرت حالة ذلك
المتغير لأحدكم.
لأنه عندما أتى أحدكم إلى المسكن،
الشخص الذي أتى لاحقًا، اللعنة، مثلاً،
قد تم بالفعل إعادة تعبئة الحليب.
إذن كيف يمكنكم حل هذا؟
في العالم الحقيقي، كيف يمكنكم
تجنب هذه المشكلة؟
أنت فقط، الشخص، الذي لا يقضي أبدًا
طلبات رفيقه في السكن.
الجمهور: يقول المغنطيس الذي وضعته
على الثلاجة اشتري هذا.
ديفيد ج. مالان: مغنطيس-- نعم.
قائمة تسوق، صحيح-- ذهبتُ لشراء الحليب--
أوقفتوه عن الشراء.
دائمًا اتركوا ملاحظة، أليس كذلك؟
يمكنكم تبليغ تلك المعلومة.
يمكنكم وبشكل أكبر
قفل الثلاجة، أليس كذلك؟
قفل الشيء، وإذن
لا يمكن لرفيقكم في السكن
أن يفحص حالة الثلاجة
في غيابكم، وبالتالي،

English: 
not making us vulnerable to this.
And I use the word lock
deliberately because,
in databases, that's
how they solve this.
There is a feature in
databases called locks.
Or fancier versions of this
are called transactions,
whereby, you can guarantee
something called atomicity,
where atomicity means you can do
multiple things back to back to back
without getting interrupted.
So in the case of a bank, it is
possible, with SQL, using slightly
fancier syntax that we won't dive into
today to solve this problem by saying,
you know what?
Begin the following transaction.
Check the state of the bank account,
deduct this amount of money,
and now commit the results.
And while I'm doing that,
lock everyone else out.
Don't let any other
customer or any other user
do exactly that information that
touches the same data until I am done.
Long story short-- you
pay a price, perhaps.
You're literally preventing your
roommate from accessing the fridge,
and that's annoying.
Or you're preventing other
customers from doing transactions.
So hopefully the computer is fast
at this, and your fast at shopping.
But you've at least ensured
that you have atomicity.

Arabic: 
لا يجعلنا عُرضة لهذا.
وأستخدم كلمة قفل
بشكل متعمد لأن،
في قواعد البيانات، ذلك هو
كيف يتم حل هذا.
هناك ميزة في
قواعد البيانات تُسمى أقفال.
أو تُسمى الإصدارات الأكثر روعة
من هذا المُعاملات،
حيث يمكنكم ضمان
شيء يُسمى آلية الرجوع،
حيث تعني آلية الرجوع أنه يمكنكم
القيام بأشياء متعددة على التوالي
دون أن تتم مقاطعتكم.
إذن في حالة البنك، من
الممكن، عبر SQL، باستخدام القليل من
الصيغ الأكثر روعة والتي لن نتعمق فيها
اليوم لحل هذه المشكلة بقول،
أتعلمون ماذا؟
ابدأ في المعاملة التالية.
تحقق من حالة الحساب المصرفي،
استقطع هذا المبلغ من المال،
والآن التزم بالنتائج.
وبينما أفعل ذلك،
امنع أي شخص من الدخول.
لا تدع أي عميل
آخر أو أي مستخدم آخر
أن يفعل بالضبط تلك المعلومات التي تمس
البيانات نفسها حتى انتهي.
باختصار--
تدفعون ثمن، ربما.
حرفيًا تمنعون رفيقكم في السكن
من الوصول إلى الثلاجة،
وهذا مزعج.
أو تمنعون العملاء
الآخرين من القيام بمعاملات.
إذن آمل أن يكون الكمبيوتر سريعًا
في هذا، وأنكم تقومون بالتسوق بسرعة.
ولكن قد ضمنتم على الأقل
أن لديكم آلية الرجوع.

English: 
No operation can get inserted
into your sequence of operations
as by your roommate or some
other computer or thread.
So that's a problem with databases
that we're only going to skirt over.
And GitHub might solve this, how?
Well, by just not caring, potentially.
I don't know what's going to
happen if multiple of us try.
I'm guessing they will just give n minus
1 of us an error message saying, sorry,
that username is no longer available.
Think about this.
If you've ever bought
airline tickets, this
is a solved problem in that industry.
That would be really annoying.
If you just spent an hour
of stressful price-hunting
for a good airplane ticket,
you start checking out
after adding it to your shopping cart.
And five minutes later, after your
name and email address and credit card
number, the ticket is gone.
So what do airlines do?
They often give you
a five-minute window.
And some of the fancier websites
show you the clock saying,
we guarantee this for
the next five minutes.
Hotels might do this too where they
locked the refrigerator for you
by somehow altering the
database to say, mm-mm.
No one else can buy this ticket or
this room for the next five minutes,
much like the note or the padlock.
So those kinds of things
are all around us.

Arabic: 
لا يمكن إدراج أي عملية
في تسلسل العمليات الخاص بكم
عبر رفيقكم في السكن أو
كمبيوتر آخر أو مؤشر ترابط.
إذن فهذه مشكلة مع قواعد البيانات
سنقوم باختصارها فقط.
ويُمكن لـ GitHub أن يحل هذا، كيف؟
حسنًا، بعدم الاهتمام، من المحتمل.
لا أعرف ما الذي سيحدث
إذا حاول العديد منّا.
أخمّن أنها ستعطي فقط n ناقص 1
منا رسالة خطأ تقول، معذرةً،
لم يعد اسم المستخدم هذا متوفرًا.
فكّروا في هذا.
إذا اشتريتم مُسبقًا
تذاكر طيران، فهذه
مشكلة محلولة في تلك الصناعة.
سيكون هذا مزعج جدًا.
إذا فقط قضيتم ساعة
من البحث المُرهِق عن سعر
جيد لتذكرة طائرة،
تبدأون في البحث
بعد إضافتها إلى عربة التسوق الخاصة بكم.
وبعد خمس دقائق، بعد إدخال
الاسم وعنوان البريد الإلكتروني ورقم بطاقة الائتمان
الخاصين بكم، لم تعد التذكرة موجودة.
إذن ما الذي تفعله الخطوط الجوية؟
في كثير من الأحيان يمنحونكم
نافذة لمدة خمس دقائق.
وتعرض لكم بعض مواقع
الويب الأروع الساعة قائلة،
نضمن هذا للخمس
دقائق القادمة.
قد تفعل الفنادق هذا أيضًا حيث
يقومون بقفل الثلاجة لكم
عبر تغيير قاعدة
البيانات بطريقة ما ليقولوا، امم-امم.
لا يمكن لأي شخص آخر شراء هذه التذكرة أو
هذه الحجرة للخمس دقائق القادمة،
وهذا ما يُشبه إلى حد كبير الملاحظة أو القفل.
إذن هذه النوع من الأشياء
موجود في كل مكان حولنا.

Arabic: 
لكن دعونا ننظر إلى مثال أخير
الذي يُعد أسوأ تهديد على الإطلاق وهو هذا.
في السابق، سمحتُ
لنفسي بالبحث بالاسم.
إذن q يساوي Brian أو q يساوي
David أو Veronica أو ما شابه.
وماذا فعلتُ بتلك المعلومة؟
حسنًا، إذا عدنا إلى
IDE ونظرنا في الواقع
إلى ذلك الملف في application.py، قمتُ
بتنسيقه ببساطة باستخدام سلسلة F
داخل سلسلة SQL هذه.
ولكن ماذا إذا كان المستخدمين لديّ
ضارّين قليلاً؟
ولنفترض أن شخصًا ما لا
يريد فقط البحث عن Brian.
لكن أتعلمون ماذا؟
لنفترض أنه يفعل شيئًا على سبيل المثال، إن
الاستعلام لديّ هو حذف من المُسجلين حيث--
عذرًا براين-- اسم يساوي Brian--
شيئًا من هذا القبيل.
الآن، هذا غير صالح في هذه
اللحظة، لأن هذه السلسلة،
بينما يُسمَح لي
بالتأكيد كتابتها،
سيتم إدخالها في التعليمة البرمجية لديّ،
لكن منطقيًا في المكان الخطأ.
على سبيل المثال، سأبحث عن اسم
شخص ما يُسمى "حذف من المُسجلين
حيث اسم يساوي Brian،"
وهذا فقط سخيف.

English: 
But let's look at one final example
that's the worst threat of all is this.
Previously, I allowed
myself to search by name.
So q equals Brian or q equals
David or Veronica or the like.
And what did I do with that information?
Well, if we go back into
the IDE and actually look
at that file in application.py, I
simply formatted it using an F string
inside of this SQL string.
But what if my users were
a little bit malicious?
And suppose that someone doesn't
want to just search for Brian.
But you know what?
Suppose they do something like, my
query is DELETE FROM registrants WHERE--
sorry Brian-- NAME equals Brian--
something like this.
Now, this is not valid at the
moment, because this string,
while I'm certainly
allowed to type it in,
is going to get plugged into my code,
but in the wrong place logically.
Like, I'm going to look for someone's
name called "DELETE FROM registrants
WHERE name equals Brian,"
which is just nonsensical.

English: 
It will return 0 results.
But what if I do something
like this where I say,
Brian or DELETE from
registrants where I finish
the thought that the programmer had
and then start my own new thought.
Or another way of doing this is to use
special syntax semicolon, something
like this.
Long story short, I could contrive
a human malicious input that
finishes the programmer's thought and
returns zero rows, but by the way,
also sneaks one additional
rogue query into the database.
This is what's known as
a SQL injection attack.
And if you naively and very, very, very
badly and incorrectly write code like I
did-- don't ever do this--
you will be vulnerable
to exactly this attack
because you are blindly plugging
in the user's input to a string
that you are then passing to a database.
This is a fundamental flaw in lots
of applications, lots of languages
where you have to distrust your users.
It doesn't matter if it's
for just students on campus
or it's just for you and your friends.

Arabic: 
سيقوم بإرجاع 0 من النتائج.
لكن ماذا إذا قمتُ بشيء
من هذا القبيل حيث أقول
Brian أو حذف من
المُسجلين عندما أُنهي
فكرة المبرمج
ثم أبدأ بفكرة جديدة خاصة بي.
أو طريقة أخرى للقيام بهذا هي استخدام
فاصلة منقوطة وهي صيغة خاصة، شيء من
هذا القبيل.
باختصار، يمكنني استنباط
مدخل بشري ضار والذي
يُنهي فكرة المبرمج ويقوم
بإرجاع صفر من الصفوف، لكن بالمناسبة،
أيضًا يقوم بتسلل استعلام مخادع
إضافي في قاعدة البيانات.
هذا ما يُعرف
بحقنة هجوم SQL.
وإذا كتبتم بشكل ساذج وسيئ جدًا،
وغير صحيح تعليمة برمجية مثلما
فعلت-- لاتفعلوا ذلك أبدًا--
ستكونون مُعرضين
لهذا الهجوم بالضبط
لأنكم تقوموا بإدخال مدخل المستخدم
بشكل أعمى في سلسلة
ثم تقومون بتمريره إلى قاعدة بيانات.
هذا هو الخطأ الأساسي في الكثير
من التطبيقات، واللغات
حين يجب عليكم عدم الثقة بالمستخدمين لديكم.
لا يهم إذا كان هذا
فقط للطلاب في الحرم الجامعي
أو فقط لكم ولأصدقائكم.

English: 
Never ever, ever trust users'
input because either someone's
going to mistype something and
something is going to go awry,
or you're going to
have a bad apple trying
to hack into your website
or your application
by trying these kinds of commands.
And you have to always
write code defensively.
So how to do this?
There are a bunch of ways.
But it turns out that, what's
dangerous about something
like I just typed in is that
it's the semicolon, for instance,
and that's the quote
marks over "elsewhere."
So the safest thing to do is, no matter
what the user types in, escape things.
You can use special syntax.
We saw this in C-- generally, putting a
backslash in front of something means,
don't let it have its default behavior.
Instead, treat it specially.
So you could use special
code in Python that
just says remove any bad
characters, or replace things.
Frankly, you've probably been to
a website where you've been told,
sorry, you can't use that
character in your password.
Or sorry, you can't use
that in your username.
That's just dumb.
Like, that is the lazy approach to this.
There is no reason to
prevent users from typing
any characters into their keyboard
for their password and maybe even
their username.

Arabic: 
لا تثقوا أبدًا، أبدًا في مدخل المستخدمين
لأنه إما سيُخطئ
أحدهم في كتابة شيء ما
ثم سينحرف شيئًا ما،
أو أن لديكم شخص
سيء يحاول
اختراق موقع الويب
أو التطبيق الخاص بكم
عبر تجربة هذه الأنواع من الأوامر.
وعليكم دائمًا
كتابة تعليمة برمجية بشكل دفاعي.
إذن كيف يُمكنكم فعل هذا؟
يوجد بضعة طرق.
ولكن يتّضح أن، الأمر الخطير
حول شيء
مثل الذي كتبته
هي الفاصلة المنقوطة، على سبيل المثال،
وهي علامات الاقتباس
فوق "elsewhere."
إذن الشيء الأكثر أمانًا لنفعله هو، بغض النظر
عما يكتبه المستخدم، إلغاء الأشياء.
يمكنكم استخدام صيغة خاصة.
رأينا هذا في C-- بشكل عام، وضع
خط مائل عكسي أمام شيء مما يعني،
لا تدعونه يحتفظ بسلوكه الافتراضي.
بدلاً من ذلك، عاملوه بشكل خاص.
إذن يمكنكم استخدام تعليمة
برمجية خاصة في Python
التي تقول فقط قوموا بإزالة أي حروف
غير صالحة، أو استبدال أشياء.
بصراحة، قد كنتم على الأرجح في
موقع ويب حيث قد قيل لكم،
معذرةً، لا يمكنك استخدام هذا الحرف
في كلمة المرور الخاصة بك.
أو معذرةً، لا يمكنك استخدام ذلك
في اسم المستخدم الخاص بك.
هذا فقط غبي.
مثل، ذلك نهج كسول لهذا.
لا يوجد سبب لمنع
المستخدمين من كتابة
أي حروف بلوحة المفاتيح
لكلمة المرور الخاصة بهم وربما حتى
اسم المستخدم الخاص بهم.

Arabic: 
هذه نوعًا ما طريقة كسولة
للتصدي لهذا بقول،
امم-امم، لا أثق بأي علامة
نسبة مئوية، أو أي فواصل منقوطة،
أو أي شرطات، أو أي فواصل عليا.
بدلاً من ذلك، فقط قوموا بإلغاء أشياء.
ولكن هذا سخيف لنا
جميعًا في هذه الغرفة
كتابة التعليمة البرمجية الخاصة بنا من أجل إلغاء
مدخل المستخدمين أو تنقيته، كما تُسمى،
أو تعقيمه، كما
تُسمى-- الأشياء نفسها.
لمَ لا نستخدم فقط مكتبة؟
الآن، يوجد العديد من المكتبات هناك.
المكتبة التي نستخدمها
في الوقت الحالي هي CS50.
وتقوم دالة EXECUTE
بهذا لأجلنا.
بدلاً من استخدام سلاسل F، التي
لا يجب استخدامها هكذا.
بدلاً من ذلك يجب عليكم القيام بهذا.
إذا أردتم إدخال قيمة عنصر نائب
إلى استعلام SQL،
تستخدمون حرفياً تقليد
قياسي، والذي تبنيناه أيضًا،
حيث يمكنكم فقط وضع اسم
متغير، لكن مع وجود نقطتين أمامه.
ويمكن أن يكون أي شيء.
يمكن أن يكون q.
يمكن أن يكون x.
لا يهم.
لكنكم تريدون فقط
إدخال قيمة ما هناك.
إذن سأُطلق عليها
اسم، حسب التقليد.
ثم تقومون بإنهاء الاقتباس لديكم
وإنهاء الفكرة.
ثم امضوا قدمًا وقوموا بتمرير
القيمة الفعلية، اسم يساوي q.
والآن قمتم
بإنشاء، بشكل ديناميكي،

English: 
That's kind of a lazy way of
defending against this by saying,
mm-mm, I don't trust any
percent sign, any semicolons,
any dashes, any apostrophes.
Rather, just escape things.
But it's silly for
all of us in this room
to write our own code for scaping users'
input or scrubbing it, as it's called,
or sanitizing it, as it's
called-- same things.
Why don't we just use a library?
Now, there are many libraries out there.
The one that we're using
at the moment is CS50's.
And the EXECUTE function
does this for us.
Instead of using F strings, which
you should not use like this.
You should instead do this.
If you want to plug in a
placeholder value to a SQL query,
you literally use a standard
convention, that we have adopted too,
where you just put in a variable's
name, but with a colon in front of it.
And it can be anything.
It can be q.
It can be x.
It doesn't matter.
But you want to just
plug in some value there.
So I'm going to call
it name, by convention.
Then you close your quote
and finish your thought.
And then you go ahead and pass in
the actual value, name equals q.
And now you have
constructed, dynamically,

English: 
a SQL string with a
place holder that is not
Python's own curly brace placeholder.
This is a special SQL convention
where you say plug in value here.
What value?
We'll plug in this names value, q,
whatever the human has typed in.
And what are execute
function will do for you
is all of the fancy backslashing
and all of the escaping
and will protect you
from the user's data.
And this is how truly simple it is.
It doesn't have to be CS50's library.
This is ever so common in all languages,
but too few people know about it
and use it.
And so half the time you read
about some database getting hacked
or your data getting
stolen, it is because
of a stupid oversight like that.
So just use libraries
and escape users' input.
We can see this now more concretely.
All of the undergrads
in the room have surely
logged into, either Yale's
website or Harvard's website,
which looks a little
something like this here.
You're prompted for your
login name and your password,
or your Harvard key or the like.
Well, how does this take
effect in real terms?
If I were to type in my email address--
but then weird syntax like
this-- let's look at an example.

Arabic: 
سلسلة SQL عبر
عنصر نائب وهو ليس
قوس متعرج عنصر نائب الخاص بـ Python.
هذا تقليد خاص في SQL
حيث تقولون قم بإدخال قيمة هنا.
أي قيمة؟
سنقوم بإدخال قيمة الأسماء، q،
أيًّا كان ما كتبه الإنسان.
وما ستفعله
دالة execute لأجلكم
هو الخط المائل العكسي
والإلغاء الرائعين
وستحميكم
من بيانات المستخدم.
وهذه هي مدى بساطة الأمر حقًا.
لا يجب أن تكون مكتبة CS50.
هذا أمر شائع جدًا في جميع اللغات،
ولكن عدد قليل جدًا من الأشخاص يعرفون ذلك
ويستخدمونه.
إذن معظم الوقت تقرأون
عن اختراق بعض قواعد البيانات
أو عن سرقة
بياناتكم، فذلك بسبب
سهو غبي من ذلك القبيل.
إذن، استخدموا فقط مكتبات
وقوموا بإلغاء مدخل المستخدمين.
يمكننا أن نرى هذا الآن بشكل ملموس أكثر.
قد قام الطلاب الجامعيين جميعهم
في الغرفة بالتأكيد
بتسجيل الدخول، إما على موقع الويب
الخاص بييل أو بهارفارد،
الذي يبدو إلى
حد ما شيئًا كهذا هنا.
تتم مطالبتكم باسم تسجيل الدخول
وكلمة المرور الخاصة بكم،
أو Harvard key الخاص بكم أو ما شابه.
حسنًا، كيف يصبح هذا
مؤثر بقيم فعلية؟
إذا كنت سأكتب عنوان البريد الإلكتروني لديّ--
ولكن صيغة غريبة مثل
هذه-- دعونا ننظر إلى مثال.

Arabic: 
علامة اقتباس Or علامة اقتباس 1
وعلامة إنهاء الاقتباس يساوي علامة اقتباس 1.
لاحظوا أنها ليست موزونة.
ينقصها علامة اقتباس هنا،
وأخرى هنا.
لأن الافتراض هو أنه
ربما تكون هارفارد مُعرضة لهذا.
لا أعتقد أنها كذلك.
لكن لنفترض أن التعليمة
البرمجية التي تقوم بتشغيل Harvard key
وصفحة تسجيل الدخول إلى هارفارد تبدو
نوعًا ما كهذه.
هذا سيء.
هذا أمر خطير لأنهم
فقط يستخدمون سلاسل f أو سلاسل
تنسيق، والتي ستقوم فقط
بإدخال أي شيء هناك بشكل أعمى.
إذن إذا سمحت للإنسان أن يكتب
شيء مُشفر مثل ذلك،
لاحظوا ما حدث منطقيًا.
حيث اسم المستخدم يساوي me at example
email provider.com وكلمة المرور
يساوي علامة اقتباس وعلامة إنهاء الاقتباس، إذن
فارغة، أو 1 يساوي 1.
ولماذا 1 يساوي 1؟
إذا رجعتُ، لاحظوا أنه يوجد
هنا علامة اقتباس وهنا.
والسبب في أنني لم أُنهي
علامة الاقتباس الثانية هنا أو الأخرى
هنا هو لأنني
أفترض، كشخص سيء،
أعتقد أن هارفارد ستقوم فقط
بإدخال المدخل الخاص بي بشكل أعمى
في علامة اقتباس واحدة خاصة بها.
بالتالي، يمكنني إنهاء
فكرتهم بشكل سخيف.

English: 
Quote "or" quote unquote
"1" equals quote "1."
Notice it's not balanced.
It's missing a quote over here,
missing a quote over here.
Because the presumption is that
maybe Harvard is vulnerable to this.
I don't think they are.
But suppose that the
code running Harvard key
and Harvard's login page looks
a little something like this.
This is bad.
This is dangerous because they're
just using f strings or format
strings, which are just going to
blindly plug anything in there.
And so if you let the human type
in something cryptic like that,
notice what has happened logically.
Where username equals me at example
your email provider.com and password
equals quote unquote, so
nothing, or 1 equals 1.
And why 1 equals 1?
If I go back, notice that there's
a quote here and a quote here.
And the reason that I didn't finish my
second quote here or my second quote
here is because I'm
assuming, as a bad guy,
I think Harvard is just going
to blindly plug my input
into a single quotes of their own.
Therefore, I can finish
their thought nonsensically.

English: 
But notice, logically, what happens.
Select all users from the database where
the user name is me at example email
provider and the password is nothing.
Or 1 equals 1.
Well, when does 1 equal 1?
Like, always.
So this will always return
users from the database,
and presumably, therefore, let
me log in as one of those users--
so incredibly simple
to defend against this.
Just use placeholder syntax and
distrust and sanitize users' input.
The syntax in SQL and the CS50 library
is quite simply with that colon.
But in other libraries, it
might be quite the same.
So now you are all,
families and students alike,
inaugurated into the
small class of folks
in the world who understand
particularly geeky humor.
You might notice this meme that's gone
around the internet for many years
now where someone either
maliciously or humorously
decided to paint this over
their license platelets.
Let's enhance.
Why would someone do this?

Arabic: 
لكن لاحظوا، منطقيًا، ما الذي يحدث.
حدد المستخدمين جميعهم من قاعدة البيانات حيث
اسم المستخدم هو me at example email
provider وكلمة المرور فارغة.
أو 1 يساوي 1.
حسنًا، متى 1 يساوي 1؟
دائمًا.
إذن فإن هذا سيقوم بإرجاع المستخدمين
دائمًا من قاعدة البيانات،
ومن المفترض، بالتالي، يسمح
لي بتسجيل الدخول كواحدًا من هؤلاء المستخدمين--
إذن الأمر بسيط بشكل لا يصدق
للتصدي لهذا.
فقط استخدموا صيغة العنصر النائب
ولا تثقوا بمدخل المستخدمين وقوموا بتعقيمه.
إن الصيغة في SQL ومكتبة CS50
بسيطة تمامًا مع تلك النقطتين.
ولكن في مكتبات أخرى، قد تكون
نفسها تمامًا.
إذن أنتم الآن جميعًا،
الحضور والطلاب على حدٍ سواء،
بدأتم في
فئة صغيرة من الناس
في العالم الذي يفهم
فكاهة العباقرة بشكل خاص.
قد تلاحظون هذا الميم الذي انتقل
عبر الإنترنت منذ سنوات عديدة
وحتى الآن حيث قرر شخص ما إما
بشكل ضار أو فكاهي
أن يرسم هذا على
لوحة الرخصة الخاصة به.
دعونا نقوم بالتكبير.
لما قد يفعل شخص ما هذا؟

Arabic: 
الجمهور: ماسحات ضوئية.
ديفيد ج. مالان: ماسحات ضوئية، نعم.
تتلاشي مقرّات محصلي
الضرائب، على الأقل في الولايات المتحدة.
وبدلاً من ذلك لديهم كاميرات أو قارئات
تقوم بمسح مقدمة سيارتكم
وتحاول إجراء OCR بشكل ضوئي،
التعرف الضوئي على الحروف،
على لوحة الرخصة الخاصة بكم.
والافتراض هنا هو، ربما
في بعض البلديات،
هناك بعض التعليمات البرمجية المكتوبة بشكل سيء
حيث يتم بشكل أعمى إدخال
لوحة الرخصة الخاصة بكم في التعليمات البرمجية لديهم.
آملين أن تنهوا
الفكرة حيث ZU 0666--
أيًّا كان ذلك، فإنه
جزء من لوحة الرخصة--
لكن فاصلة منقوطة جدول
إسقاط قاعدة البيانات نقطة نقطة نقطة.
ولم ننظر حتى إلى ذلك
لأن كلمة إسقاط مبالغ فيها جدًا.
تقوم حرفيًا بحذف قاعدة البيانات نفسها.
ولكن هذه طريقة لطيفة
للإعفاء من الضرائب.
وأكثر شيء متعارف عليه على الأرجح، XKCD
وهو كارتون شائع جدًا يصدر بشكل متسلسل.
يستهدف العباقرة بشكل خاص.
وربما ستفهمون هذه الدعابة
الآن كذلك بين دوائر CS.
[LAUGHING]

English: 
AUDIENCE: Scanners.
DAVID J. MALAN: Scanners, yeah.
Tollbooths are going
away, at least in the US.
And they instead have cameras or readers
that are scanning the front of your car
and trying to optically do OCR,
Optical Character Recognition,
on your license plate.
And the presumption here is,
maybe in some municipality,
there's some badly written code
where they just blindly plug
your license plate into their code.
And hopefully you finish
the thought where ZU 0666--
whatever that is, it's
part of the license plate--
but "semicolon drop
database table dot dot dot."
And we didn't even look at that
because DROP is pretty extreme.
It literally deletes a database itself.
But this is a nice way of getting
off the hook from a total price.
And most canonical perhaps, XKCD
is a very popular cartoon strip.
It's particularly geek-oriented.
And you'll perhaps understand this
joke now as well among CS circles.
[LAUGHING]

English: 
I can hear the laughter
making its way through.
So from here on out, if
you take nothing else away,
remember little Bobby Tables with pset.
Our final, will you actually
implement CS50 Finance
and coalesce all these ideas.
Thank you so much to all of
our families for joining.
And we will see you next time.
[APPLAUSE]

Arabic: 
يمكنني سماع الضحك
في كل مكان.
إذن من الآن فصاعدًا، إذا
لم تأخذوا شيء آخر،
تذكروا جداول بوبي الصغيرة مع pset.
في النهاية، هل ستقومون في الواقع
بتنفيذ CS50 Finance
وجمع هذه الأفكار جميعها.
شكرًا جزيلاً لانضمام
الحضور جميعهم.
وسنراكم في المرة القادمة.
[APPLAUSE]
