مفهوم المفتاح الرئيسي ( Primary Key )
المفتاح الرئيسي هو العامود الذي نضعه في الجدول بهدف جعلنا قادرين على الوصول إلى كل سطر فيه بسهولة سواء بهدف الحصول على قيمه, تعديلها أو لحذف السطر كما هو من الجدول. بالإضافة إلى ذلك, فأننا نستخدمه لربط قيم الجداول ببعضها البعض و هذه الأمور سبق و شرحناها بتفصيل ممل.
كمثال بسيط, في الجدول التالي يمكننا الوصول لأي سطر من خلال رقم id السطر.
| id | first_name | last_name |
|---|---|---|
| 1 | Ahmad | Eid |
| 2 | Ramez | Morad |
| 3 | Hassan | Mortada |
| 4 | Saad | Alkassem |
| 5 | Zaher | Fahmi |
معلومة تقنية
العامود الذي يتم تعيينه كمفتاح رئيسي لا يسمح بأن يتم تخزين قيم مكررة فيه.
بمعنى آخر, جميع قيم المفتاح الرئيسي تعتبر موحدة ( UNIQUE ) حتى و إن لم نعرفها كذلك.
تعيين المفتاح الرئيسي
في أغلب الأوقات, تحتاج وضع عامود واحد في الجدول ليكون بمثابة المفتاح الرئيسي للوصول لكل سطر فيه و هذا الأمر تطرقنا له كثيراً في الدروس السابقة حيث كنا نضع عامود واحد إسمه id كمفتاح رئيسي في أي جدول ننشئه, و لكن في بعض الحالات قد تجد أنك بحاجة إلى تكوين مفتاح رئيسي في الجدول من عامودين أو أكثر و ليس من عامود واحد فقط.
تعيين العامود كمفتاح رئيسي عند إنشاء الجدول
إذا كنت تنوي تعيين عامود كمفتاح رئيسي في الجدول, يمكنك إضافة الخاصية PRIMARY KEY إلى تعريف العامود فقط.
عندها سيصبح العامود لا يقبل أن تخزن فيه قيم موحدة و سيجبرك على إدخال قيم بنفسك له.
المثال الأول
في المثال التالي, عند إنشاء جدول جديد قمنا بإنشاء عامود نوعه INT و تعيينه كمفتاح رئيسي في الجدول.
الإستعلام
CREATE TABLE users (
id INT PRIMARY KEY, -- users كمفتاح رئيسي للجدول id هنا قمنا بتعريف العامود
first_name VARCHAR(50),
last_name VARCHAR(50)
);
المثال الثاني
في المثال التالي, عند إنشاء جدول جديد قمنا بإنشاء عامود نوعه VARCHAR و تعيينه كمفتاح رئيسي في الجدول.
الإستعلام
CREATE TABLE users (
username VARCHAR(50) PRIMARY KEY, -- users كمفتاح رئيسي للجدول username هنا قمنا بتعريف العامود
first_name VARCHAR(50),
last_name VARCHAR(50)
);
تعيين أكثر من عامود كمفتاح رئيسي عند إنشاء الجدول
لتعيين أكثر من عامود كمفتاح رئيسي في الجدول, يجب إضافة قيد ( CONSTRAINT ) على الجدول نحدد فيه كل الأعمدة التي نريدها أن تكون بمثابة مفتاح رئيسي.
إنتبه لنقطة مهمة جداً, و هي أنه عند تعيين عامودين كمفتاح رئيسيي, فإن كل عامود منهم يعتبر عامود عادي جداً و لكنهما مع بعض يشكلان مفتاح واحد.
الشكل العام لإضافة قيد خاص بتعيين المفتاح الرئيسي
لإضافة CONSTRAINT خاص بتحديد الأعمدة التي نريد تعيينها بمثابة PRIMARY KEY واحد يجب كتابتة الإستعلام كالتالي.
CREATE TABLE table_name (
column1 datatype NOT NULL,
column2 datatype NOT NULL,
...,
CONSTRAINT PK_table_name PRIMARY KEY (column1, column2)
);
مثال
في المثال التالي, عند إنشاء جدول جديد قمنا بإنشاء عامود نوعه INT و عامود نوعه VARCHAR و تعيينهما كمفتاح رئيسي في الجدول.
لتعيين هذين العامودين كمفتاح واحد فعلنا التالي:
العامود
idقمنا بتعريفهINT NOT NULLلأننا نريد إدخال قيمة رقمية و أن لا يسمح بترك الحقل فارغاً.العامود
usernameقمنا بتعريفهVARCHAR(50) NOT NULLلأننا نريد إدخال قيم نصية لا يتعدى طولها 50 حرف و أن لا يسمح بترك الحقل فارغاً.قمنا بإضافة
CONSTRAINTنوعهPRIMARY KEYبإسمpk_usersليكون مشابهاً لإسم الجدول فقط.ذكرنا فيه إسم العامودين اللذين نريد وضعهما كمفتاح رئيسي في الجدول بين أقواس القيد
PRIMARY KEY.
الإستعلام
CREATE TABLE users (
id INT NOT NULL,
username VARCHAR(50) NOT NULL,
first_name VARCHAR(50),
last_name VARCHAR(50),
CONSTRAINT pk_users PRIMARY KEY (id, username)
);
الآن, لاحظ أن العامود username يمكنه أن يحتوي على قيم مكررة و العامود id كذلك أيضاً.
السببب الذي يجعل ذلك لا يشكل مشكلة هو أن كل عامود منهما لا يشكل مفتاح رئيسي لوحده, بل قيمتهما مع بعضهما هي ما تشكل المفتاح الرئيسي في كل سطر.
| id | username | first_name | last_name |
|---|---|---|---|
| 1 | ahmad | Ahmad | Eid |
| 2 | ahmad | Ahmad | Rashad |
| 2 | hassan | Hassan | Mortada |
| 3 | saad | Saad | Alkassem |
1ahmadهو مفتاح السطر الأول.2ahmadهو مفتاح السطر الثاني.2hassanهو مفتاح السطر الثالث.3saadهو مفتاح السطر الرابع.
إذاً في حال كان المفتاح الرئيسي يتألف من أكثر من عامود, يمكننا جعل الأعمدة تقبل أن يكون فيها قيم مكررة و لكن لا يمكننا تكرار نفس قيم الأعمدة الموجودة على نفس السطر في سطر آخر.
في الجدول السابق ممنوع تكرار نفس الـ id و الـ username في أكثر من سطر. أي ممنوع إدخال قيم مكررة كالتالي.
| id | username | first_name | last_name |
|---|---|---|---|
| 1 | ahmad | Ahmad | Eid |
| 1 | ahmad | Ahmad | Rashad |
تعيين المفتاح الرئيسي بعد إنشاء الجدول
إذا كنت تنوي تعيين المفتاح الرئيسي بعد إنشاء الجدول, يجب أن تتأكد أولاً أن العامود أو الأعمدة التي تنوي وضعها كمفتاح رئيسي لا تحتوي على حقول فارغة.
في حال كنت تنوي تعيين عامود واحد كمفتاح رئيسي, يمكنك استخدام الأمر ALTER لتعيينه كالتالي.
ALTER TABLE table_name
ADD PRIMARY KEY (column_name);
في حال كنت تنوي تعيين أكثر من عامود واحد كمفتاح رئيسي, يجب إضافة CONSTRAINT لتعيينه كالتالي.
ALTER TABLE table_name
ADD CONSTRAINT pk_constraint_name PRIMARY KEY (column1, column2, ..);
المثال الأول
الإستعلام التالي يقوم بتعيين العامود id الموجود في الجدول users كمفتاح رئيسي.
الإستعلام
ALTER TABLE users
ADD PRIMARY KEY (id);
المثال الثاني
الإستعلام التالي يقوم بتعيين العامودين id و username الموجودين في الجدول users كمفتاح رئيسي.
الإستعلام
ALTER TABLE users
ADD CONSTRAINT pk_users PRIMARY KEY (id, username);
حذف المفتاح الرئيسي
في حال أردت إلغاء المفتاح الرئيسي الذي قمت بتعيينه سابقاً. يمكنك تعديل العامود بواسطة الأمر ALTER
مع الإشارة إلى أن طريقة فعل ذلك تختلف من قاعدة بيانات لأخرى.
في قواعد بيانات MySQL
ALTER TABLE table_name
DROP PRIMARY KEY;
الإستعلام التالي يقوم بإلغاء تعيين المفتاح الرئيسي الموضوع في الجدول users.
هنا لا داعي لذكر إسم المفتاح الرئيسي الذي تنوي إلغاؤه.
مثال
ALTER TABLE users
DROP PRIMARY KEY;
في قواعد بيانات SQL Server / Oracle / Access
ALTER TABLE table_name
DROP CONSTRAINT pk_constraint_name;
الإستعلام التالي يقوم بحذف القيد pk_users الذي تم وضعه سابقاً لتعيين المفتاح الرئيسي في الجدول users.
هنا يجب ذكر إسم القيد الذي يمثل المفتاح الرئيسي الذي تنوي إلغاؤه.
مثال
ALTER TABLE users
DROP CONSTRAINT pk_users;
المفتاح الأجنبي ( Foreign Key )
المفتاح الأجنبي هو العامود الذي نضع فيه قيم مفتاح رئيسي موجود في جدول آخر بهدف ربطهما مع بعض.
فمثلاً في الجدول users, العامود country_id يعتبر مفتاح أجنبي لأن قيمه تشير لقيم العامود id في الجدول countries.
نلاحظ أن قيم العامود country_id يجب أن تشير لقيم العامود id في الجدول countries لتخزين قيم صحيحة.
لضمان أن لا يتم تخزين أرقام خاطئة في العامود country_id يجب تعيين هذا العامود كمفتاح أجنبي بالنسبة للعامود id الموجود في الجدول countries.
عندها في حال تمرير قيمة للحقل country_id غير موجودة في الجدول countries, لن يتم قبولها و سيظهر لك خطأ يخبرك أنه لا يمكنك ذلك.
تعيين المفتاح الرئيسي و المفتاح الأجنبي عند إنشاء الجدول
في الدرس السابق شاهدنا أنه يوجد طريقتين لتحديد المفتاح الرئيسي, الأولى يمكن استخدامها في حال كان المفتاح الرئيسي عبارة عن عامود واحد, و الثانية إستخدامها إجباري في حال كان المفتاح الرئيسي يتكون من أكثر من عامود.
المفتاح الأجنبي كذلك الأمر, حيث يمكن تعيين واحد أو أكثر كمفتاح أجنبي في الجدول.
لتعيين عامود واحد أو أكثر كمفتاح أجنبي في الجدول, يمكننا وضع قيد ( CONSTRAINT ) لتحديده.
هذه الطريقة متاحة في جميع قواعد البيانات و استخدامها سهل لأننا نقوم بتعريف الأعمدة و في النهاية نحدد مفاتيح الجدول.
المميز في هذه الطريقة, أنك في حال قررت إلغاء المفتاح الأجنبي لاحقاً, يمكنك فعل ذلك بكل سهولة لأنك ستعتمد على إسم القيد الذي وضعته بنفسك من أجل إلغائه.
مثال
CREATE TABLE users (
id INT NOT NULL,
first_name VARCHAR(50),
last_name VARCHAR(50),
country_id INT NOT NULL,
-- users كمفتاح رئيسي في الجدول id هنا قمنا بتعيين العامود
PRIMARY KEY (id),
-- countries الموجود في الجدول id هو مفتاح ثانوي بالنسبة للعامود country_id يحدد أن العامود fk_country_user هنا قمنا بوضع قيد بإسم
CONSTRAINT fk_country_user FOREIGN KEY (country_id) REFERENCES countries(id)
);
تعيين المفاتيح في قواعد بيانات MySQL
يمكنك اتباع الطريقة التالية لتعريف المفاتيح مع الإشارة إلى أنه يفضل وضع قيد بشكل يدوي لأن التعامل معه مستقبلاً سيكون أسهل عليك إن أردت ذلك.
مثال
CREATE TABLE users (
id INT NOT NULL,
first_name VARCHAR(50),
last_name VARCHAR(50),
country_id INT NOT NULL,
-- users كمفتاح رئيسي في الجدول id هنا قمنا بتعيين العامود
PRIMARY KEY (id),
-- countries الموجود في الجدول id هو مفتاح ثانوي بالنسبة للعامود country_id هنا قمنا بوضع قيد يحدد أن العامود
FOREIGN KEY (country_id) REFERENCES countries(id)
);
تعيين المفاتيح في قواعد بيانات SQL Server / Oracle / Access
يمكنك اتباع الطريقة التالية لتعريف المفاتيح مع الإشارة إلى أنه يفضل وضع قيد بشكل يدوي لأن التعامل معه مستقبلاً سيكون أسهل عليك إن أردت ذلك.
مثال
CREATE TABLE users (
id INT NOT NULL PRIMARY KEY, -- users كمفتاح رئيسي في الجدول id هنا قمنا بتعيين العامود
first_name VARCHAR(50),
last_name VARCHAR(50),
country_id INT FOREIGN KEY REFERENCES countries(id) -- countries الموجود في الجدول id هو مفتاح ثانوي بالنسبة للعامود country_id يحدد أن العامود fk_country_user هنا قمنا بوضع قيد بإسم
);
تعيين المفتاح الأجنبي بعد إنشاء الجدول
في حال كنت تنوي تعيين عامود واحد كمفتاح أجنبي, يمكنك استخدام الأمر ALTER لتعيينه.
في حال كنت تنوي تعيين أكثر من عامود كمفتاح أجنبي, يجب إضافة CONSTRAINT لتعيينه.
ملاحظة: إضافة CONSTRAINT أمر يحتاج كتابة إستعلام أطول قليلاً و لكن التعامل معه مستقبلاً سيكون أسهل عليك إن أردت ذلك.
المثال الأول
الإستعلام التالي يقوم بتعيين العامود country_id الموجود في الجدول users كمفتاح أجنبي بالنسبة للعامود id الموجود في الجدول countries.
الإستعلام
ALTER TABLE users -- users هنا قمنا بتحديد أننا نريد إجراء تعديل على بنية الجدول
ADD FOREIGN KEY (contry_id) REFERENCES countries(id); -- countries الموجود في الجدول id هو عامود أجنبي بالنسبة للعامود country_id هنا قمنا بتحديد أن العامود
المثال الثاني
الإستعلام التالي يقوم بتعيين العامود country_id الموجود في الجدول users كمفتاح أجنبي بالنسبة للعامود id الموجود في الجدول countries.
الإستعلام
ALTER TABLE users -- users هنا قمنا بتحديد أننا نريد إجراء تعديل على بنية الجدول
ADD CONSTRAINT fk_country_user -- users و countries للإشارة إلى أنه مفتاح أجنبي بين الجدولين fk_country_user هنا قمنا بوضع قيد إسمه
FOREIGN KEY (country_id) REFERENCES countries(id); -- countries الموجود في الجدول id يستخدم قيم العامود country_id هنا قمنا بتحديد أن العامود
حذف قيد المفتاح الأجنبي
طريقة إلغاء قيد ( CONSTRAINT ) المفتاح الأجنبي الذي قمت بتعيينه سابقاً, تختلف من قاعدة بيانات لأخرى.
في قواعد بيانات MySQL
ALTER TABLE table_name
DROP FOREIGN KEY fk_constraint_name;
الإستعلام التالي يقوم بإلغاء قيد مفتاح أجنبي إسمه fk_country_user إفترضنا أنه موضوع في الجدول users.
مثال
ALTER TABLE users
DROP FOREIGN KEY fk_country_user;
في قواعد بيانات SQL Server / Oracle / Access
ALTER TABLE table_name
DROP CONSTRAINT fk_constraint_name;
الإستعلام التالي يقوم بإلغاء قيد مفتاح أجنبي إسمه fk_country_user إفترضنا أنه موضوع في الجدول users.
مثال
ALTER TABLE users
DROP CONSTRAINT fk_country_user;