ترجمة آلية تحت المراجعة
الأسبوع 7: SQL
المصدر الأصلي على CS50المحاضرة السابعة (Lecture 7)
- مرحبًا!
- قاعدة بيانات الملفات المسطحة
- قواعد البيانات العلائقية
- حدد
- أدخل
- حذف
- تحديث
- شجونه
JOINs- الفهارس
- استخدام SQL في بايثون
- ظروف السباق
- هجمات حقن SQL
- التلخيص
مرحبًا! (Welcome!)
- في الأسابيع الماضية، قدمنا لك لغة Python، وهي لغة برمجة عالية المستوى تستخدم نفس العناصر الأساسية التي تعلمناها في لغة C. ومع ذلك، فقد قدمنا هذه اللغة الجديدة ليس بغرض تعلم "مجرد لغة أخرى". وبدلاً من ذلك، فإننا نفعل ذلك لأن بعض الأدوات أفضل لبعض الوظائف وليست رائعة بالنسبة لوظائف أخرى!
- سنواصل هذا الأسبوع المزيد من بناء الجملة المتعلق ببايثون.
- علاوة على ذلك، سنقوم بدمج هذه المعرفة مع البيانات.
- أخيرًا، سنناقش SQL أو لغة الاستعلام المنظمة، طريقة خاصة بالمجال يمكننا من خلالها التفاعل مع البيانات وتعديلها.
- بشكل عام، أحد أهداف هذه الدورة هو تعلم البرمجة بشكل عام - وليس مجرد كيفية البرمجة باللغات الموضحة في هذه الدورة.
قاعدة بيانات الملفات المسطحة (Flat-File Database)
- كما رأيت من قبل، يمكن غالبًا وصف البيانات في أنماط الأعمدة والصفوف.
- يمكن إخراج جداول البيانات مثل تلك التي تم إنشاؤها في Microsoft Excel وGoogle Sheets إلى
csvأو قيم مفصولة بفواصل ملف. - إذا نظرت إلى
csv، ستلاحظ أن الملف مسطح حيث يتم تخزين جميع بياناتنا في جدول واحد يمثله ملف نصي. نحن نسمي هذا النوع من البيانات أ قاعدة بيانات ذات ملف ثابت. - يتم تخزين جميع البيانات صفًا تلو الآخر. يتم فصل كل عمود بفاصلة أو قيمة أخرى.
- تأتي لغة Python مع دعم أصلي لـ
csvالملفات. - أولاً، قم بالتنزيل favorites.csv وقم بتحميله إلى مستكشف الملفات الخاص بك بالداخل cs50.dev. ثانيًا، عند فحص هذه البيانات، لاحظ أن الصف الأول خاص لأنه يحدد كل عمود. ثم يتم تخزين كل سجل صفًا تلو الآخر. تم استيراد مكتبة
-
في نافذتك الطرفية، اكتب
code favorites.pyواكتب الشيفرة كما يلي:# Prints all favorites in CSV using csv.reader import csv # Open CSV file with open("favorites.csv", "r") as file: # Create reader reader = csv.reader(file) # Skip header row next(reader) # Iterate over CSV file, printing each favorite for row in reader: print(row[1])لاحظ أن يتم استخدام كتلة
csv. وعلاوة على ذلك، أنشأناreaderالذي سيحمل نتيجة تقرأ وظيفةcsv.reader(file). ال يُستخدم الرمزcsv.readerكل صف من الملف، وفي الشيفرة الخاص بنا، نقوم بتخزين النتائج فيreader.print(row[1])، لذلك، سوف يطبع اللغة من ملفfavorites.csvالملف. يمكنك تنزيل هذا الرمز هنا. -
يمكنك تحسين الشيفرة الخاص بك كما يلي: يتم تخزين
# Stores favorite in a variable import csv # Open CSV file with open("favorites.csv", "r") as file: # Create reader reader = csv.reader(file) # Skip header row next(reader) # Iterate over CSV file, printing each favorite for row in reader: favorite = row[1] print(favorite)لاحظ ذلك تم الآن إنشاء
favoriteثم طباعته. لاحظ أيضًا أننا نستخدم وظيفةnextللانتقال إلى السطر التالي من القارئ. يمكنك تنزيل هذا الرمز هنا. - أحد عيوب النهج المذكور أعلاه هو أننا نثق في ذلك
row[1]هو المفضل دائمًا. ومع ذلك، ماذا سيحدث لو تم نقل الأعمدة؟ -
يمكننا حل هذه المشكلة المحتملة. تتيح لك Python أيضًا الفهرسة باستخدام مفاتيح القائمة. قم بتعديل الشيفرة الخاص بك كما يلي:
# Prints all favorites in CSV using csv.DictReader import csv # Open CSV file with open("favorites.csv", "r") as file: # Create DictReader reader = csv.DictReader(file) # Iterate over CSV file, printing each favorite for row in reader: favorite = row["language"] print(favorite)لاحظ أن هذا المثال يستخدم مباشرة مفتاح
languageفي عبارة الطباعة. تم تعيين قيمةfavoriteلـrow["language"]. يمكنك تنزيل هذا الرمز هنا. -
يمكن تبسيط ذلك بشكل أكبر من أجل:
# Prints all favorites in CSV using csv.DictReader import csv # Open CSV file with open("favorites.csv", "r") as file: # Create DictReader reader = csv.DictReader(file) # Iterate over CSV file, printing each favorite for row in reader: print(row["language"])يمكنك تنزيل هذا الرمز هنا.
-
لحساب عدد اللغات المفضلة المعبر عنها في
csv، يمكننا القيام بما يلي:# Counts favorites using variables import csv # Open CSV file with open("favorites.csv", "r") as file: # Create DictReader reader = csv.DictReader(file) # Counts scratch, c, python = 0, 0, 0 # Iterate over CSV file, counting favorites for row in reader: favorite = row["language"] if favorite == "Scratch": scratch += 1 elif favorite == "C": c += 1 elif favorite == "Python": python += 1 # Print counts print(f"Scratch: {scratch}") print(f"C: {c}") print(f"Python: {python}")لاحظ أنه يتم حساب كل لغة باستخدام
ifتصريحات. وعلاوة على ذلك، لاحظ المساواة المزدوجة==علامات في تلكifتصريحات. يمكنك تنزيل هذا الرمز هنا. -
تسمح لنا لغة Python باستخدام قاموس لحساب عدد
countsمن كل لغة. ضع في اعتبارك التحسين التالي على الشيفرة الخاص بنا:# Counts favorites using dictionary import csv # Open CSV file with open("favorites.csv", "r") as file: # Create DictReader reader = csv.DictReader(file) # Counts counts = {} # Iterate over CSV file, counting favorites for row in reader: favorite = row["language"] if favorite in counts: counts[favorite] += 1 else: counts[favorite] = 1 # Print counts for favorite in counts: print(f"{favorite}: {counts[favorite]}")لاحظ أن القيمة الموجودة في
countsبالمفتاح تتم زيادةfavoriteعندما يكون موجودًا بالفعل. إذا لم يكن موجودا، فإننا نحددcounts[favorite]وقم بتعيينه على 1. علاوة على ذلك، تم تحسين السلسلة المنسقة لتقديمcounts[favorite]. يمكنك تنزيل هذا الرمز هنا. -
يمكننا أيضًا الاستفادة
tryوexceptلحساب الاستثناءات المحتملة: تم استبدال# Uses try/except instead import csv # Open CSV file with open("favorites.csv", "r") as file: # Create DictReader reader = csv.DictReader(file) # Counts counts = {} # Iterate over CSV file, counting favorites for row in reader: favorite = row["language"] try: counts[favorite] += 1 except KeyError: counts[favorite] = 1 # Print counts for favorite in counts: print(f"{favorite}: {counts[favorite]}")لاحظ كيف يتم استدعاء الدالة
ifوelseبـtryوexcept. يمكنك تنزيل هذا الرمز هنا. -
تسمح لغة Python أيضًا بالفرز
counts. تحسين الشيفرة الخاصة بك على النحو التالي:# Sorts favorites by key import csv # Open CSV file with open("favorites.csv", "r") as file: # Create DictReader reader = csv.DictReader(file) # Counts counts = {} # Iterate over CSV file, counting favorites for row in reader: favorite = row["language"] if favorite in counts: counts[favorite] += 1 else: counts[favorite] = 1 # Print counts for favorite in sorted(counts): print(f"{favorite}: {counts[favorite]}")لاحظ
sorted(counts)في أسفل الشيفرة. يمكنك تنزيل هذا الرمز هنا. -
إذا نظرت إلى المعلمات الخاصة بـ
sortedفي وثائق Python، ستجد أنها تحتوي على العديد من المعلمات المضمنة. يمكنك الاستفادة من بعض هذه المعلمات المضمنة على النحو التالي:# Sorts favorites by value using .get import csv # Open CSV file with open("favorites.csv", "r") as file: # Create DictReader reader = csv.DictReader(file) # Counts counts = {} # Iterate over CSV file, counting favorites for row in reader: favorite = row["language"] if favorite in counts: counts[favorite] += 1 else: counts[favorite] = 1 # Print counts for favorite in sorted(counts, key=counts.get, reverse=True): print(f"{favorite}: {counts[favorite]}")لاحظ الوسائط التي تم تمريرها إلى تسمح لك الوسيطة
sorted. ال يُستخدم الرمزkeyبإخبار بايثون بالطريقة التي ترغب في استخدامها لفرز العناصر. في هذه الحالة، يتم استخدامcounts.getللفرز حسب القيم.reverse=Trueيقولsortedللفرز من الأكبر إلى الأصغر. يمكنك تنزيل هذا الرمز هنا. - يمكنك معرفة المزيد عنه تم الترتيب في دليل وثائق بايثون.
قواعد البيانات العلائقية (Relational Databases)
- يستخدم كل من Google وX وMeta قواعد بيانات علائقية لتخزين معلوماتهم على نطاق واسع.
- تقوم قواعد البيانات العلائقية بتخزين البيانات في صفوف وأعمدة في هياكل تسمى الجداول.
-
يسمح SQL بأربعة أنواع من الأوامر:
Create Read Update Delete - يتم استدعاء هذه العمليات الأربع بمودة خام.
- يمكننا إنشاء قاعدة بيانات باستخدام بناء جملة SQL
CREATE TABLE table (column type, ...);. ولكن أين يمكنك تشغيل هذا الأمر؟ -
sqlite3هو نوع من قواعد بيانات SQL يحتوي على الميزات الأساسية المطلوبة لهذه الدورة. - يمكننا إنشاء قاعدة بيانات SQL في الجهاز عن طريق الكتابة
sqlite3 favorites.db. عند المطالبة، سوف نتفق على أننا نريد إنشاءfavorites.dbبالضغطy. - ستلاحظ مطالبة مختلفة لأننا نستخدم الآن برنامجًا يسمى
sqlite. - يمكننا أن نضع
وضع
sqliteإلىcsvعن طريق الكتابة.mode csv. وبعد ذلك، يمكننا استيراد بياناتنا منcsvالملف عن طريق الكتابة.import favorites.csv favorites. ويبدو أن شيئا لم يحدث! - يمكننا الكتابة
.schemaلرؤية بنية قاعدة البيانات. - يمكنك قراءة العناصر من جدول باستخدام بناء الجملة
SELECT columns FROM table. - على سبيل المثال، يمكنك الكتابة
SELECT * FROM favorites;والذي سيطبع كل صف فيهfavorites. - يمكنك الحصول على مجموعة فرعية من البيانات باستخدام الأمر
SELECT language FROM favorites;. -
يدعم SQL العديد من الأوامر للوصول إلى البيانات، بما في ذلك:
AVG COUNT DISTINCT LOWER MAX MIN UPPER - على سبيل المثال، يمكنك الكتابة
SELECT COUNT(*) FROM favorites;. وعلاوة على ذلك، يمكنك الكتابةSELECT DISTINCT language FROM favorites;للحصول على قائمة باللغات الفردية داخل قاعدة البيانات. يمكنك حتى الكتابةSELECT COUNT(DISTINCT language) FROM favorites;للحصول على عدد من هؤلاء. -
توفر لغة SQL أوامر إضافية يمكننا استخدامها في استعلاماتنا:
WHERE -- adding a Boolean expression to filter our data LIKE -- filtering responses more loosely ORDER BY -- ordering responses LIMIT -- limiting the number of responses GROUP BY -- grouping responses togetherلاحظ أننا نستخدم
--لكتابة تعليق في SQL.
حدد (SELECT)
- على سبيل المثال، يمكننا التنفيذ
SELECT COUNT(*) FROM favorites WHERE language = 'C';. يتم تقديم العد. - علاوة على ذلك، يمكننا الكتابة
يتم استخدام
SELECT COUNT(*) FROM favorites WHERE language = 'C' AND problem = 'Hello, World';. لاحظ كيفANDلتضييق نطاق النتائج. - بالمثل، يمكننا التنفيذ
SELECT language, COUNT(*) FROM favorites GROUP BY language;. سيوفر هذا جدولًا مؤقتًا يُظهر اللغة والعدد. - يمكننا تحسين ذلك عن طريق الكتابة
SELECT language, COUNT(*) FROM favorites GROUP BY language ORDER BY COUNT(*);. سيؤدي هذا إلى ترتيب الجدول الناتج حسبcount. - وبالمثل، يمكننا التنفيذ
SELECT COUNT(*) FROM favorites WHERE language = 'C' AND (problem = 'Hello, World' OR problem = 'Hello, It''s Me');. لاحظ أن هناك اثنين''علامات للسماح باستخدام علامات الاقتباس المفردة بطريقة لا تربك SQL. - علاوة على ذلك، يمكننا التنفيذ
SELECT COUNT(*) FROM favorites WHERE language = 'C' AND problem LIKE 'Hello, %';للعثور على أي مشاكل تبدأ بـHello,(بما في ذلك مسافة). - يمكننا ترتيب الإخراج على النحو التالي:
SELECT language, COUNT(*) FROM favorites GROUP BY language ORDER BY COUNT(*) DESC;. - يمكننا أيضًا إنشاء أسماء مستعارة، مثل المتغيرات في استعلاماتنا:
SELECT language, COUNT(*) AS n FROM favorites GROUP BY language ORDER BY n DESC;. - أخيرًا، يمكننا قصر مخرجاتنا على قيمة واحدة أو أكثر:
SELECT language, COUNT(*) AS n FROM favorites GROUP BY language ORDER BY n DESC LIMIT 1;. - لاحظ، وفقًا للاتفاقية، غالبًا ما تتم كتابة الكلمات الأساسية لـ SQL بالأحرف الكبيرة.
أدخل (INSERT)
- يمكننا أيضًا
INSERTفي قاعدة بيانات SQL باستخدام النموذجINSERT INTO table (column...) VALUES(value, ...);. - يمكننا التنفيذ
INSERT INTO favorites (language, problem) VALUES ('SQL', 'Fiftyville');. - يمكنك التحقق من إضافة هذه المفضلة عن طريق التنفيذ
SELECT * FROM favorites;.
حذف (DELETE)
-
DELETEيسمح لك بحذف أجزاء من بياناتك. على سبيل المثال، يمكنكDELETE FROM favorites WHERE Timestamp IS NULL;. يؤدي هذا إلى حذف أي سجل حيثTimestampهوNULL.
تحديث (UPDATE)
- يمكننا أيضًا الاستفادة من
أمر
UPDATEلتحديث بياناتك. - على سبيل المثال، يمكنك التنفيذ
UPDATE favorites SET language = 'SQL', problem = 'Fiftyville';. سيؤدي هذا إلى تحديث كافة الصفوف. - لاحظ أن هذه الاستعلامات تتمتع بقوة هائلة. وفقًا لذلك، في بيئة العالم الحقيقي، يجب عليك التفكير في من لديه الأذونات لتنفيذ أوامر معينة وما إذا كان لديك نسخ احتياطية متاحة!
شجونه (IMDb)
- يمكننا أن نتخيل قاعدة بيانات قد نرغب في إنشائها لفهرسة البرامج التلفزيونية المختلفة. يمكننا إنشاء جدول بيانات يحتوي على أعمدة مثل
title,star,star,star,starوالمزيد من النجوم. مشكلة هذا الأسلوب هي أنه يحتوي على مساحة كبيرة مهدرة. قد تحتوي بعض العروض على نجمة واحدة. والبعض الآخر قد يكون لديه العشرات. - يمكننا تقسيم قاعدة البيانات الخاصة بنا إلى أوراق متعددة. يمكن أن يكون لدينا
showsورقة، أstarsورقة، وpeopleورقة. علىpeople، يمكن أن يكون لكل شخص ميزة فريدةid. علىshows، يمكن أن يكون لكل عرض ميزة فريدةidأيضًا. على ورقة ثالثة تسمىstarsيمكننا ربط الأشخاص بالعروض من خلال وجودshow_idوperson_id. على الرغم من أن هذا يعد تحسينًا، إلا أنه ليس قاعدة بيانات مثالية. -
يقدم IMDb قاعدة بيانات للأشخاص والعروض والكتاب والنجوم والأنواع والتقييمات. ويرتبط كل من هذه الجداول ببعضها البعض على النحو التالي:

- بعد التنزيل
shows.db، يمكنك التنفيذsqlite3 shows.dbفي نافذتك الطرفية. -
دعونا نركز على العلاقة بين جدولين داخل قاعدة البيانات المسماة
showsوratings. ويمكن توضيح العلاقة بين هذين الجدولين على النحو التالي:
- لتوضيح العلاقة بين هذه الجداول يمكننا تنفيذ الأمر التالي:
SELECT * FROM ratings LIMIT 10;. فحص الإخراج، يمكننا التنفيذSELECT * FROM shows LIMIT 10;. - الفحص
showsوratings، يمكننا أن نرى أن هناك علاقة فردية: عرض واحد له تقييم واحد. - لفهم قاعدة البيانات عند تنفيذها
.schemaلن تجد كل جدول من الجداول فحسب، بل ستجد الحقول الفردية داخل كل جدول من هذه الجداول. - وبشكل أكثر تحديدًا، يمكنك التنفيذ
.schema showsلفهم الحقول الموجودة بداخلهshows. يمكنك أيضًا التنفيذ.schema ratingsلرؤية الحقول الموجودة بالداخلratings. - يوجد مرجع لمعرف العرض في كافة الجداول. في
جدول
shows، يُطلق عليه ببساطةid. يسمى هذا الحقل المشترك بين جميع الجداول أ . تُستخدم المفاتيح الأساسية لتحديد سجل فريد في الجدول. المفاتيح الخارجية يتم استخدام لبناء العلاقات بين الجداول من خلال الإشارة إلى المفتاح الأساسي في جدول آخر. يمكنك أن ترى في مخططratingsذلكshow_idهو مفتاح خارجي يشيرidفيshows. - من خلال تخزين البيانات في قاعدة بيانات علائقية، كما هو مذكور أعلاه، يمكن تخزين البيانات بشكل أكثر كفاءة.
-
في سكليتي، لدينا خمسة أنواع من البيانات، بما في ذلك:
BLOB -- binary large objects that are groups of ones and zeros INTEGER -- an integer NUMERIC -- for numbers that are formatted specially like dates REAL -- like a float TEXT -- for strings and the like -
بالإضافة إلى ذلك، يمكن تعيين الأعمدة لإضافة قيود خاصة:
NOT NULL UNIQUE - يمكننا أيضًا اللعب بهذه البيانات لفهم هذه العلاقات. ينفذ
SELECT * FROM ratings;. هناك الكثير من التقييمات! - يمكننا تقييد هذه البيانات بشكل أكبر من خلال التنفيذ
SELECT show_id FROM ratings WHERE rating >= 6.0 LIMIT 10;. من هذا الاستعلام، يمكنك أن ترى أن هناك 10 عروض مقدمة. ومع ذلك، لا نعرف ما الذي يظهره كل منهماshow_idيمثل. - يمكنك اكتشاف ما يظهر من خلال التنفيذ
SELECT * FROM shows WHERE id = 626124; -
يمكننا تحسين استعلامنا ليكون أكثر كفاءة من خلال تنفيذ:
SELECT title FROM shows WHERE id IN ( SELECT show_id FROM ratings WHERE rating >= 6.0 LIMIT 10 );لاحظ أن هذا الاستعلام يجمع استعلامين معًا. يتم استخدام الاستعلام الداخلي بواسطة استعلام خارجي.
JOINs
- نحن نقوم بسحب البيانات من
showsوratings. لاحظ كيف على حد سواءshowsوratingsلديكidمشتركة. - كيف يمكننا دمج الجداول مؤقتًا؟ يمكن ربط الجداول ببعضها باستخدام
أمر
JOIN. -
قم بتنفيذ الأمر التالي:
SELECT * FROM shows JOIN ratings ON shows.id = ratings.show_id WHERE rating >= 6.0 LIMIT 10;لاحظ أن هذا يؤدي إلى جدول أوسع مما رأيناه سابقًا.
-
حيث أوضحت الاستعلامات السابقة واحد لواحد العلاقة بين هذه المفاتيح، دعونا نتفحص بعضها واحد لكثير العلاقات. التركيز على جدول
genres، قم بتنفيذ ما يلي:SELECT * FROM genres LIMIT 10;لاحظ كيف يوفر لنا هذا فكرة عن البيانات الأولية. قد تلاحظ أن العرض الواحد له ثلاث قيم. هذه علاقة رأس بأطراف.
- يمكننا معرفة المزيد عن
genresالجدول عن طريق الكتابة.schema genres. -
قم بتنفيذ الأمر التالي لمعرفة المزيد حول الأفلام الكوميدية المتنوعة في قاعدة البيانات:
SELECT title FROM shows WHERE id IN ( SELECT show_id FROM genres WHERE genre = 'Comedy' LIMIT 10 );لاحظ كيف ينتج عن ذلك قائمة من الأفلام الكوميدية، بما في ذلك كاتويزل.
-
يمكننا معرفة المزيد عن Catweazle من خلال الانضمام إلى الجداول المختلفة:
SELECT * FROM shows JOIN genres ON shows.id = genres.show_id WHERE id = 63881;لاحظ أن هذا يؤدي إلى جدول مؤقت. من الجيد أن يكون لديك جدول مكرر. علاوة على ذلك، لاحظ أنه تم تعيين Catweazle (عنوان واحد). كثيرة الأنواع، بما في ذلك المغامرة والكوميديا والعائلة.
- على النقيض من علاقات رأس برأس وعلاقة رأس بأطراف، هناك متعدد إلى متعدد العلاقات. على سبيل المثال، يمكن أن يظهر العديد من الأشخاص في العديد من العروض!
-
يمكننا معرفة المزيد عن العرض المكتب والممثلين في هذا العرض عن طريق تنفيذ الأمر التالي:
SELECT name FROM people WHERE id IN (SELECT person_id FROM stars WHERE show_id = (SELECT id FROM shows WHERE title = 'The Office' AND year = 2005));لاحظ أن هذا يؤدي إلى جدول يتضمن أسماء النجوم المختلفة من خلال الاستعلامات المتداخلة.
-
يمكننا العثور على جميع العروض التي قام ببطولتها ستيف كاريل:
SELECT title FROM shows WHERE id IN (SELECT show_id FROM stars WHERE person_id = (SELECT id FROM people WHERE name = 'Steve Carell'));ينتج عن هذا قائمة بعناوين العروض التي قام ستيف كاريل ببطولتها.
-
يمكن التعبير عن هذا كـ a
JOINكـ:SELECT title FROM shows JOIN stars ON shows.id = stars.show_id JOIN people ON stars.person_id = people.id WHERE name = 'Steve Carell'; -
يمكن أيضًا التعبير عن ذلك بهذه الطريقة:
SELECT title FROM shows, stars, people WHERE shows.id = stars.show_id AND people.id = stars.person_id AND name = 'Steve Carell'; - حرف البدل
يمكن استخدام عامل التشغيل
%للعثور على جميع الأشخاص الذين تبدأ أسماؤهم بـSteve Cعن طريق استخدام الصيغة التالية:SELECT * FROM people WHERE name LIKE 'Steve C%';.
الفهارس (Indexes)
- في حين أن قواعد البيانات العلائقية لديها القدرة على أن تكون أسرع وأكثر قوة من استخدام
CSV، يمكن تحسين البيانات داخل الجدول باستخدام الفهارس. - يمكن استخدام الفهارس لتسريع استعلاماتنا.
- يمكننا تتبع سرعة استعلاماتنا من خلال التنفيذ
.timer onفيsqlite3. - لفهم كيف يمكن للفهارس تسريع استعلاماتنا، قم بتشغيل ما يلي:
SELECT * FROM shows WHERE title = 'The Office';لاحظ الوقت الذي يتم عرضه بعد تنفيذ الاستعلام. - بعد ذلك، يمكننا إنشاء فهرس بالصيغة
CREATE INDEX title_index ON shows (title);. هذا يحكيsqlite3لإنشاء فهرس وإجراء بعض التحسينات الخاصة المتعلقة بهذا العمودtitle. -
سيؤدي هذا إلى إنشاء بنية بيانات تسمى أ شجرة ب، بنية بيانات تشبه الشجرة الثنائية. ومع ذلك، على عكس الشجرة الثنائية، يمكن أن يكون هناك أكثر من عقدتين تابعتين.

-
علاوة على ذلك، يمكننا إنشاء فهارس على النحو التالي:
CREATE INDEX name_index ON people (name); CREATE INDEX person_index ON stars (person_id); -
قم بتشغيل الاستعلام وستلاحظ أن الاستعلام يعمل بسرعة أكبر!
SELECT title FROM shows WHERE id IN (SELECT show_id FROM stars WHERE person_id = (SELECT id FROM people WHERE name = 'Steve Carell')); - لسوء الحظ، قد تؤدي فهرسة جميع الأعمدة إلى استخدام مساحة تخزين أكبر. لذلك، هناك مقايضة لتحسين السرعة.
استخدام SQL في بايثون (Using SQL in Python)
-
للمساعدة في العمل مع SQL في هذه الدورة، يمكن استخدام مكتبة CS50 على النحو التالي في الشيفرة الخاصة بك:
from cs50 import SQL - على غرار الاستخدامات السابقة لمكتبة CS50، ستساعدك هذه المكتبة في الخطوات المعقدة لاستخدام SQL داخل كود Python الخاص بك.
- يمكنك قراءة المزيد حول وظيفة SQL لمكتبة CS50 في الوثائق.
- باستخدام معرفتنا الجديدة، يمكننا الآن الاستفادة من Python إلى جانب SQL.
-
قم بتعديل الشيفرة الخاص بك لـ
favorites.pyعلى النحو التالي:# Searches database for popularity of a problem from cs50 import SQL # Open database db = SQL("sqlite:///favorites.db") # Prompt user for favorite favorite = input("Favorite: ") # Search for title rows = db.execute("SELECT COUNT(*) AS n FROM favorites WHERE problem = ?", favorite) # Get first (and only) row row = rows[0] # Print popularity print(row["n"])لاحظ ذلك تم الآن إنشاء
db = SQL("sqlite:///favorites.db")يوفر لبيثون موقع ملف قاعدة البيانات. ثم السطر الذي يبدأ بـrowsينفذ أوامر SQL باستخدامdb.execute. في الواقع، يقوم هذا الأمر بتمرير بناء الجملة ضمن علامات الاقتباس إلى وظيفةdb.execute. يمكننا إصدار أي أمر SQL باستخدام بناء الجملة هذا. علاوة على ذلك، لاحظ ذلك يتم إرجاعrowsكقائمة من القواميس. في هذه الحالة، هناك نتيجة واحدة فقط، صف واحد، يتم إرجاعها إلى قائمة الصفوف كقاموس. يمكنك تنزيل هذا الرمز هنا.
ظروف السباق (Race Conditions)
- يمكن أن يؤدي استخدام SQL في بعض الأحيان إلى حدوث بعض المشكلات.
- يمكنك تخيل حالة حيث يمكن لعدة مستخدمين الوصول إلى نفس قاعدة البيانات وتنفيذ الأوامر في نفس الوقت.
- قد يؤدي هذا إلى حدوث خلل حيث تتم مقاطعة الشيفرة بسبب تصرفات الأشخاص الآخرين. قد يؤدي هذا إلى فقدان البيانات.
- ميزات SQL المضمنة مثل
BEGIN TRANSACTION,COMMITوROLLBACKيساعد في تجنب بعض مشكلات حالة السباق هذه.
هجمات حقن SQL (SQL Injection Attacks)
- الآن، ومازلت تفكر في الشيفرة أعلاه، ربما تتساءل ما هو
?علامات الاستفهام تفعل أعلاه. إحدى المشاكل التي يمكن أن تنشأ في تطبيقات SQL في العالم الحقيقي هي ما يسمى هجوم الحقن. هجوم الحقن هو المكان الذي يمكن فيه لممثل خبيث إدخال كود SQL ضار. -
على سبيل المثال، خذ بعين الاعتبار شاشة تسجيل الدخول كما يلي:

-
بدون الحماية المناسبة في الشيفرة الخاصة بنا، يمكن لممثل سيء تشغيل تعليمات برمجية ضارة. خذ بعين الاعتبار ما يلي:
rows = db.execute("SELECT COUNT(*) FROM users WHERE username = ? AND password = ?", username, password)لاحظ ذلك لأن
?في مكانه، ويمكن تشغيل التحقق من الصحةusernameوpasswordقبل أن يتم قبولها بشكل أعمى بواسطة الاستعلام. - لا تثق أبدًا بشكل أعمى في مدخلات المستخدم.
- باستخدام مكتبة CS50، ستقوم المكتبة تعقيم وقم بإزالة أي أحرف قد تكون ضارة.
التلخيص (Summing Up)
في هذا الدرس، تعلمت المزيد من بناء الجملة المتعلق ببايثون. علاوة على ذلك، تعلمت كيفية دمج هذه المعرفة مع البيانات في شكل ملفات ثابتة وقواعد بيانات علائقية. وأخيرا، تعلمت عن SQL. على وجه التحديد، ناقشنا…
- قواعد بيانات الملفات الثابتة
- قواعد البيانات العلائقية
- أوامر SQL مثل
SELECT,CREATE,INSERT,DELETEوUPDATE. - المفاتيح الأساسية والأجنبية
-
JOINs - الفهارس
- استخدام SQL في بايثون
- ظروف السباق
- هجمات حقن SQL
نراكم في المرة القادمة!