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. نمذجة قاعدة بيانات للعناوين

لنستخدم دراسة حالة بسيطة لنرى كيف تُبنى قاعدة البيانات. نريد إنشاء قاعدة بيانات للعناوين.

★☆☆ جرّب بنفسك:

اكتب الخصائص التي يتكون منها عنوان بسيط والتي نريد تخزينها في قاعدة بياناتنا.

بنية العنوان

الخصائص التي تصف العنوان هي الأعمدة. ونوع المعلومات المخزنة في كل عمود هو نوع بياناته. سنحلل في القسم التالي جدول العناوين المفاهيمي لنرى كيف يمكننا تحسينه!

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 أعلاه لتقليل التكرار وتطبيع بنية البيانات.

يمكنك قراءة المزيد عن تطبيع قواعد البيانات هنا

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.

إذا رسمنا مخطط كيانات وعلاقات لهذين الجدولين، فسيبدو تقريبًا هكذا:

../../../_images/er-people-streets.png

يساعدنا مخطط الكيانات والعلاقات على التعبير عن علاقات 'واحد إلى متعدد'. في هذه الحالة يبيّن رمز السهم أن الشارع الواحد قد يسكنه أشخاص كثيرون.

★★☆ جرّب بنفسك:

لا يزال في نموذج people بعض مشكلات التطبيع - حاول أن ترى إن كان بإمكانك تطبيعه أكثر، واعرض أفكارك بواسطة مخطط كيانات وعلاقات.

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. ما التالي؟

بعد أن اطّلعنا على طريقة عمل قواعد البيانات نظريًا، لننشئ قاعدة بيانات جديدة لتطبيق النظرية التي تناولناها.