مرحباً بكم في سلسلة قواعد البيانات وبالتحديد PostgreSQL. في الدرس الماضي تحدثنا عن كيفية إدارة الجداول والقيود على الأعمدة والجداول، وتوقفنا عند موضوع References و Foreign Key.
اليوم سوف نتحدث بشكل مفصل عن Foreign Key وأيضاً عن مفهوم يسمى Referential Actions.
بالتأكيد أنتم تعرفون ما معنى Foreign Key. في الدرس الماضي تحدثنا عن Primary Key.
Primary Key هو العمود أو في معظم الأوقات هو ID. إنه المعرف الفريد للبيانات. إذا كان لدينا 100 صف مثلاً، فكل بيانات سيكون لها ID معين، وهذا ID يجب أن يكون فريداً ولا يتكرر.
لنفترض أن لدينا جدولين:
User (المستخدمين)Profile (الملفات الشخصية)الطريقة لربط هذين الجدولين ببعضهما البعض هي استخدام Foreign Key.
جدول User يحتوي على Primary Key وهو ID. أما جدول Profile فيحتوي على عمود اسمه User ID. هذا العمود User ID ليس أي بيانات عشوائية - بل يحتوي على البيانات المحددة لـ Primary Key من جدول User.
هذا هو ما نسميه Foreign Key - إنها ببساطة الطريقة لربط جداول ببعضها البعض.
هناك طريقتان لإنشاء Foreign Key:
| الطريقة | الوصف |
|---|---|
| Column Constraints | قيود تُوضع على العمود نفسه |
| Table Constraints | قيود تُوضع على الجدول ككل |
كلا الطريقتين لها مميزاتها الخاصة. دعونا نرى كيفية عمل ذلك عملياً.
سوف نبني مثالاً عملياً. لنفترض أن لدينا:
workspace (مساحات العمل)project (المشاريع)كل project ينتمي إلى workspace معين. قد يكون هناك أكثر من project واحد لنفس workspace.
Workspace:
- ID: 1, Name: "My Workspace"
Projects:
- ID: 1, Name: "Project One", Workspace ID: 1
- ID: 2, Name: "Project Two", Workspace ID: 1
اشترك في النشرة البريدية
دروس جديدة، مقالات، وأدوات مباشرة لبريدك.
لتخزين هذه البيانات بشكل صحيح وتوضيح أن project معين ينتمي إلى workspace معين، نستخدم Foreign Key.
أولاً، سوف نفتح psql ونبدأ بإنشاء جدول workspace:
CREATE TABLE workspace (
id SERIAL PRIMARY KEY,
name VARCHAR(100) UNIQUE NOT NULL
);هنا نحن ننشئ جدول workspace يحتوي على:
id من نوع SERIAL وهو PRIMARY KEY (معرف فريد يزداد تلقائياً)name من نوع VARCHAR(100) - يمكن أن يكون طوله حتى 100 حرفUNIQUE - لا يمكن أن يكون هناك workspace بنفس الاسمNOT NULL - يجب أن يكون الاسم موجوداًالآن سننشئ جدول project. الشيء المهم هنا هو كيفية ربطه بـ workspace:
CREATE TABLE project (
id SERIAL PRIMARY KEY,
name VARCHAR(100) UNIQUE NOT NULL,
workspace_id INTEGER REFERENCES workspace(id)
);لاحظوا العمود الأخير: workspace_id INTEGER REFERENCES workspace(id)
هذا يخبر قاعدة البيانات أن:
workspace_id يجب أن يحتوي على قيمة INTEGERid من جدول workspaceإذا حاولنا إدراج قيمة في workspace_id وهذه القيمة غير موجودة في جدول workspace، فستحصل على خطأ. قاعدة البيانات لن تسمح لك بإنشاء مرجع "مكسور" (orphaned record).
الطريقة الثانية لإنشاء نفس الجدول هي باستخدام Table Constraint. أولاً، دعنا نحذف الجدول القديم:
DROP TABLE project;الآن ننشئ الجدول مرة أخرى باستخدام Table Constraint:
CREATE TABLE project (
id SERIAL PRIMARY KEY,
name VARCHAR(100) UNIQUE NOT NULL,
workspace_id INTEGER,
FOREIGN KEY (workspace_id) REFERENCES workspace(id)
);في هذه الطريقة:
workspace_id ببساطة كـ INTEGERFOREIGN KEY constraint على مستوى الجدول| النقطة | Column Constraint | Table Constraint |
|---|---|---|
| عدد الأعمدة | عمود واحد فقط | يمكن أن يكون أكثر من عمود |
| الوضوح | مدمج مع تعريف العمود | منفصل وأكثر وضوحاً |
| الاستخدام | للحالات البسيطة | للحالات المعقدة |
يمكنك التحقق من أن Foreign Key تم إنشاؤه بنجاح باستخدام:
\d projectستشاهد في النتيجة:
Foreign-key constraints:
"project_workspace_id_fkey" FOREIGN KEY (workspace_id) REFERENCES workspace(id)
يمكنك أيضاً التحقق من الجدول workspace لترى الارتباطات الخارجية:
\d workspaceستجد:
Referenced by:
TABLE "project" CONSTRAINT "project_workspace_id_fkey" FOREIGN KEY (workspace_id) REFERENCES id
هذا يخبرك أن هناك جدول project يرتبط بهذا الجدول.
الآن نأتي إلى الجزء المهم: Referential Actions
Referential Actions هي الإجراءات التي تحدث عندما نقوم بتحديث أو حذف البيانات في الجدول الأب (في حالتنا workspace).
إذا كان لدينا workspace مع اثنين من projects مرتبطين به:
ماذا يحدث إذا حذفنا workspace؟
ماذا يحدث إذا عدّلنا ID في workspace؟
هنا تأتي Referential Actions لتحديد السلوك.
FOREIGN KEY (workspace_id) REFERENCES workspace(id) ON DELETE RESTRICTهذا يمنع حذف الـ workspace إذا كان لديه projects مرتبطة به.
الخطوات المطلوبة:
projects المرتبطةworkspaceهذا هو السلوك الافتراضي إذا لم تحدد شيئاً.
FOREIGN KEY (workspace_id) REFERENCES workspace(id) ON DELETE CASCADEإذا حذفت workspace، سيتم حذف جميع projects المرتبطة به تلقائياً.
FOREIGN KEY (workspace_id) REFERENCES workspace(id) ON DELETE SET NULLإذا حذفت workspace، سيتم تعيين قيمة workspace_id إلى NULL في جميع projects المرتبطة.
ملاحظة: للاستخدام SET NULL، يجب أن يكون العمود workspace_id قابلاً لقيمة NULL.
نفس الأنواع تنطبق على ON UPDATE:
| الإجراء | الوصف |
|---|---|
| ON UPDATE RESTRICT | منع تعديل ID إذا كان هناك مراجع |
| ON UPDATE CASCADE | تحديث workspace_id تلقائياً عند تعديل ID |
| ON UPDATE SET NULL | تعيين NULL عند تعديل ID |
إذا أردت إنشاء جدول مع تحديد Referential Actions:
CREATE TABLE project (
id SERIAL PRIMARY KEY,
name VARCHAR(100) UNIQUE NOT NULL,
workspace_id INTEGER,
FOREIGN KEY (workspace_id)
REFERENCES workspace(id)
ON DELETE CASCADE
ON UPDATE CASCADE
);عندما تقوم بـ \d project، ستشاهد:
Foreign-key constraints:
"project_workspace_id_fkey" FOREIGN KEY (workspace_id) REFERENCES workspace(id) ON UPDATE CASCADE ON DELETE CASCADE
لقد تعلمنا:
استخدم هذه المفاهيم عند تصميم قواعد البيانات للتأكد من سلامة البيانات والعلاقات بينها.
شكراً لمتابعتكم! اشتركوا في القناة!