15.1. الدرس: مقدمة إلى قواعد البيانات¶
قبل استخدام PostgreSQL، لنتأكد من أرضية صلبة بتغطية النظرية العامة لقواعد البيانات. لن تحتاج إلى إدخال أي من الشيفرات النموذجية؛ فهي موجودة لأغراض التوضيح فقط.
هدف هذا الدرس: فهم المفاهيم الأساسية لقواعد البيانات.
15.1.1. ما قاعدة البيانات؟¶
تتكون قاعدة البيانات من مجموعة منظمة من البيانات لاستخدام واحد أو أكثر، وعادةً ما تكون في صيغة رقمية. - Wikipedia
يتكون نظام إدارة قواعد البيانات (DBMS) من برمجيات تشغّل قواعد البيانات، وتوفّر التخزين والوصول والأمان والنسخ الاحتياطي وغيرها من المرافق. - Wikipedia
15.1.2. الجداول¶
في قواعد البيانات العلائقية وقواعد بيانات الملفات المسطحة، الجدول مجموعة من عناصر البيانات (القيم) منظمة وفق نموذج من الأعمدة الرأسية (التي تُعرَّف بأسمائها) والصفوف الأفقية. للجدول عدد محدد من الأعمدة، لكن يمكن أن يحتوي أي عدد من الصفوف. ويُعرَّف كل صف بالقيم الظاهرة في مجموعة فرعية معينة من الأعمدة حُدِّدت مفتاحًا مرشحًا (candidate key). - Wikipedia
id | name | age
----+-------+-----
1 | Tim | 20
2 | Horst | 88
(2 rows)
في قواعد بيانات SQL، يُعرف الجدول أيضًا باسم العلاقة (relation).
15.1.3. الأعمدة / الحقول¶
العمود مجموعة من قيم البيانات من نوع بسيط معين، قيمة واحدة لكل صف من صفوف الجدول. توفر الأعمدة البنية التي تتشكل الصفوف وفقًا لها. وكثيرًا ما يُستخدم مصطلح الحقل بالتبادل مع العمود، مع أن كثيرين يرون أن الأصح استخدام الحقل (أو قيمة الحقل) للإشارة تحديدًا إلى العنصر المفرد الموجود عند تقاطع صف واحد مع عمود واحد. - Wikipedia
عمود:
| name |
+-------+
| Tim |
| Horst |
حقل:
| Horst |
15.1.4. السجلات¶
السجل هو المعلومات المخزنة في صف من صفوف الجدول. سيحتوي كل سجل على حقل لكل عمود من أعمدة الجدول.
2 | Horst | 88 <-- one record
15.1.5. أنواع البيانات¶
تقيّد أنواع البيانات نوع المعلومات التي يمكن تخزينها في عمود. - Tim and Horst
هناك أنواع كثيرة من البيانات. لنركّز على الأكثر شيوعًا:
String- لتخزين البيانات النصية الحرةInteger- لتخزين الأعداد الصحيحةReal- لتخزين الأعداد العشريةDate- لتخزين تاريخ ميلاد Horst حتى لا ينساه أحدBoolean- لتخزين قيم بسيطة من نوع صح/خطأ
يمكنك أن تطلب من قاعدة البيانات السماح لك أيضًا بعدم تخزين شيء في حقل ما. وإذا لم يكن في الحقل شيء، يُشار إلى محتواه بأنه قيمة 'null':
insert into person (age) values (40);
select * from person;
النتيجة:
id | name | age
---+-------+-----
1 | Tim | 20
2 | Horst | 88
4 | | 40 <-- null for name
(3 rows)
هناك أنواع بيانات أخرى كثيرة يمكنك استخدامها - راجع دليل PostgreSQL!
15.1.6. نمذجة قاعدة بيانات للعناوين¶
لنستخدم دراسة حالة بسيطة لنرى كيف تُبنى قاعدة البيانات. نريد إنشاء قاعدة بيانات للعناوين.
★☆☆ جرّب بنفسك:¶
اكتب الخصائص التي يتكون منها عنوان بسيط والتي نريد تخزينها في قاعدة بياناتنا.
الإجابة
في جدول العناوين النظري، قد نرغب في تخزين الخصائص التالية:
House Number
Street Name
Suburb Name
City Name
Postcode
Country
عند إنشاء الجدول الذي يمثل كائن العنوان، سننشئ أعمدة تمثل كل خاصية من هذه الخصائص، وسنسمّيها بأسماء متوافقة مع SQL وربما مختصرة:
house_number
street_name
suburb
city
postcode
country
بنية العنوان¶
الخصائص التي تصف العنوان هي الأعمدة. ونوع المعلومات المخزنة في كل عمود هو نوع بياناته. سنحلل في القسم التالي جدول العناوين المفاهيمي لنرى كيف يمكننا تحسينه!
15.1.7. نظرية قواعد البيانات¶
تتضمن عملية إنشاء قاعدة بيانات بناء نموذج للعالم الحقيقي؛ أي أخذ مفاهيم من العالم الحقيقي وتمثيلها في قاعدة البيانات على هيئة كيانات.
15.1.8. التطبيع¶
من الأفكار الرئيسية في قواعد البيانات تجنّب تكرار البيانات وزيادتها. وتُسمى عملية إزالة التكرار من قاعدة البيانات التطبيع (Normalisation).
التطبيع طريقة منهجية لضمان أن تكون بنية قاعدة البيانات مناسبة للاستعلامات العامة وخالية من بعض الخصائص غير المرغوب فيها - شذوذات الإدراج والتحديث والحذف - التي قد تؤدي إلى فقدان سلامة البيانات. - Wikipedia
هناك أنواع مختلفة من 'صيغ' التطبيع.
لنلقِ نظرة على مثال بسيط:
Table "public.people"
Column | Type | Modifiers
----------+------------------------+------------------------------------
id | integer | not null default
| | nextval('people_id_seq'::regclass)
| |
name | character varying(50) |
address | character varying(200) | not null
phone_no | character varying |
Indexes:
"people_pkey" PRIMARY KEY, btree (id)
select * from people;
id | name | address | phone_no
---+---------------+-----------------------------+-------------
1 | Tim Sutton | 3 Buirski Plein, Swellendam | 071 123 123
2 | Horst Duester | 4 Avenue du Roix, Geneva | 072 121 122
(2 rows)
تخيّل أن لديك أصدقاء كثيرين يشتركون في اسم الشارع أو المدينة. في كل مرة تتكرر فيها هذه البيانات، فإنها تستهلك مساحة. والأسوأ من ذلك أنه إذا تغيّر اسم مدينة، فعليك بذل جهد كبير لتحديث قاعدة بياناتك.
15.1.9. ★☆☆ جرّب بنفسك:¶
أعد تصميم الجدول النظري people أعلاه لتقليل التكرار وتطبيع بنية البيانات.
يمكنك قراءة المزيد عن تطبيع قواعد البيانات هنا
الإجابة
المشكلة الرئيسية في الجدول people أن فيه حقل عنوان واحدًا يحتوي عنوان الشخص كاملًا. وبالعودة إلى الجدول النظري address الذي تناولناه في بداية هذا الدرس، نعلم أن العنوان يتكون من خصائص مختلفة كثيرة. وبتخزين كل هذه الخصائص في حقل واحد، نجعل تحديث بياناتنا والاستعلام عنها أصعب بكثير. لذلك نحتاج إلى تقسيم حقل العنوان إلى خصائصه المختلفة. وسيعطينا ذلك جدولًا بالبنية التالية:
id | name | house_no | street_name | city | phone_no
--+---------------+----------+----------------+------------+-----------------
1 | Tim Sutton | 3 | Buirski Plein | Swellendam | 071 123 123
2 | Horst Duester | 4 | Avenue du Roix | Geneva | 072 121 122
ستتعرف في القسم التالي على علاقات المفتاح الأجنبي التي يمكن استخدامها في هذا المثال لتحسين بنية قاعدة بياناتنا أكثر.
15.1.10. الفهارس¶
فهرس قاعدة البيانات بنية بيانات تحسّن سرعة عمليات استرجاع البيانات من جدول في قاعدة البيانات. - Wikipedia
تخيّل أنك تقرأ كتابًا دراسيًا وتبحث عن شرح مفهوم ما - والكتاب بلا فهرس! سيكون عليك أن تبدأ القراءة من الغلاف وتمضي في الكتاب كله حتى تجد المعلومة التي تحتاجها. أما الفهرس في نهاية الكتاب فيساعدك على الانتقال بسرعة إلى الصفحة التي تحوي المعلومة المطلوبة:
create index person_name_idx on people (name);
الآن ستصبح عمليات البحث في الاسم أسرع:
Table "public.people"
Column | Type | Modifiers
----------+------------------------+-------------------------------------
id | integer | not null default
| | nextval('people_id_seq'::regclass)
| |
name | character varying(50) |
address | character varying(200) | not null
phone_no | character varying |
Indexes:
"people_pkey" PRIMARY KEY, btree (id)
"person_name_idx" btree (name)
15.1.11. التسلسلات¶
التسلسل مولّد أرقام فريدة. ويُستخدم عادةً لإنشاء معرّف فريد لعمود في جدول.
في هذا المثال، id تسلسل - يزداد الرقم في كل مرة يُضاف فيها سجل إلى الجدول:
id | name | address | phone_no
---+--------------+-----------------------------+-------------
1 | Tim Sutton | 3 Buirski Plein, Swellendam | 071 123 123
2 | Horst Duster | 4 Avenue du Roix, Geneva | 072 121 122
15.1.12. رسم مخططات الكيانات والعلاقات¶
في قاعدة البيانات المطبَّعة، تكون لديك عادةً علاقات (جداول) كثيرة. ويُستخدم مخطط الكيانات والعلاقات (ER Diagram) لتصميم الاعتماديات المنطقية بين العلاقات. لنتأمل الجدول people غير المطبَّع الذي رأيناه في بداية الدرس:
select * from people;
id | name | address | phone_no
----+--------------+-----------------------------+-------------
1 | Tim Sutton | 3 Buirski Plein, Swellendam | 071 123 123
2 | Horst Duster | 4 Avenue du Roix, Geneva | 072 121 122
(2 rows)
ببعض الجهد يمكننا تقسيمه إلى جدولين، فنستغني عن تكرار اسم الشارع للأفراد الذين يسكنون الشارع نفسه:
select * from streets;
id | name
----+--------------
1 | Plein Street
(1 row)
و:
select * from people;
id | name | house_no | street_id | phone_no
----+--------------+----------+-----------+-------------
1 | Horst Duster | 4 | 1 | 072 121 122
(1 row)
يمكننا بعد ذلك ربط الجدولين باستخدام 'المفتاحين' streets.id و people.streets_id.
إذا رسمنا مخطط كيانات وعلاقات لهذين الجدولين، فسيبدو تقريبًا هكذا:
يساعدنا مخطط الكيانات والعلاقات على التعبير عن علاقات 'واحد إلى متعدد'. في هذه الحالة يبيّن رمز السهم أن الشارع الواحد قد يسكنه أشخاص كثيرون.
★★☆ جرّب بنفسك:¶
لا يزال في نموذج people بعض مشكلات التطبيع - حاول أن ترى إن كان بإمكانك تطبيعه أكثر، واعرض أفكارك بواسطة مخطط كيانات وعلاقات.
الإجابة
يبدو الجدول people حاليًا هكذا:
id | name | house_no | street_id | phone_no
---+--------------+----------+-----------+-------------
1 | Horst Duster | 4 | 1 | 072 121 122
يمثل العمود street_id علاقة 'واحد إلى متعدد' بين كائن الشخص وكائن الشارع المرتبط به، الموجود في الجدول streets.
إحدى طرق تطبيع الجدول أكثر هي تقسيم حقل الاسم إلى first_name و last_name:
id | first_name | last_name | house_no | street_id | phone_no
---+------------+------------+----------+-----------+------------
1 | Horst | Duster | 4 | 1 | 072 121 122
يمكننا أيضًا إنشاء جداول منفصلة لاسم البلدة أو المدينة والدولة، وربطها بالجدول people عبر علاقات 'واحد إلى متعدد':
id | first_name | last_name | house_no | street_id | town_id | country_id
---+------------+-----------+----------+-----------+---------+------------
1 | Horst | Duster | 4 | 1 | 2 | 1
سيبدو مخطط الكيانات والعلاقات الذي يمثل ذلك هكذا:
15.1.13. القيود والمفاتيح الأساسية والمفاتيح الأجنبية¶
يُستخدم قيد قاعدة البيانات لضمان أن البيانات في العلاقة تطابق تصوّر مصمّم النموذج لطريقة تخزين تلك البيانات. فمثلًا، يمكن لقيد على الرمز البريدي أن يضمن وقوع الرقم بين 1000 و 9999.
المفتاح الأساسي قيمة حقل واحد أو أكثر تجعل السجل فريدًا. وعادةً ما يُسمى المفتاح الأساسي id ويكون تسلسلًا.
يُستخدم المفتاح الأجنبي للإشارة إلى سجل فريد في جدول آخر (باستخدام المفتاح الأساسي لذلك الجدول).
في مخططات الكيانات والعلاقات، يعتمد الربط بين الجداول عادةً على مفاتيح أجنبية ترتبط بمفاتيح أساسية.
إذا نظرنا إلى مثال الأشخاص، يبيّن تعريف الجدول أن عمود الشارع مفتاح أجنبي يشير إلى المفتاح الأساسي في جدول الشوارع:
Table "public.people"
Column | Type | Modifiers
-----------+-----------------------+--------------------------------------
id | integer | not null default
| | nextval('people_id_seq'::regclass)
name | character varying(50) |
house_no | integer | not null
street_id | integer | not null
phone_no | character varying |
Indexes:
"people_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"people_street_id_fkey" FOREIGN KEY (street_id) REFERENCES streets(id)
15.1.14. المعاملات¶
عند إضافة البيانات أو تغييرها أو حذفها في قاعدة بيانات، من المهم دائمًا أن تبقى قاعدة البيانات في حالة سليمة إذا حدث خطأ ما. توفر معظم قواعد البيانات ميزة تُسمى دعم المعاملات (transactions). تتيح لك المعاملات إنشاء نقطة تراجع يمكنك العودة إليها إذا لم تجرِ تعديلاتك على قاعدة البيانات كما خُطط لها.
لنأخذ سيناريو لديك فيه نظام محاسبة. تحتاج إلى سحب أموال من حساب وإضافتها إلى حساب آخر. ستكون سلسلة الخطوات كالتالي:
اسحب R20 من Joe
أضف R20 إلى Anne
إذا حدث خطأ ما أثناء العملية (مثل انقطاع الكهرباء)، فسيُتراجَع عن المعاملة.
15.1.15. الخلاصة¶
تتيح لك قواعد البيانات إدارة البيانات بطريقة منظمة باستخدام بنى شيفرة بسيطة.
15.1.16. ما التالي؟¶
بعد أن اطّلعنا على طريقة عمل قواعد البيانات نظريًا، لننشئ قاعدة بيانات جديدة لتطبيق النظرية التي تناولناها.