اذهب إلى المحتوى

تتميز قواعد البيانات العلاقية Relational Databases بميزة تشكيل البيانات ضمن بنية معرَّفة جيدًا تستخدم جداول ذات أعمدة ثابتة واتباع أنواع بيانات مُعرَّفة بدقة وتضمن بأن جميع الصفوف لها الشكل نفسه. من المهم أن نكون قادرين على العثور على الصفوف في الجداول والإشارة إليها دون التباس عند تخزين هذه البيانات ضمن صفوف الجداول، إذ يمكن تحقيق ذلك في لغة الاستعلام البنيوية Structured Query Language -أو SQL اختصارًا- باستخدام المفاتيح الرئيسية Primary Keys، والتي تعمل كمعرّفات للصفوف الفردية في جداول قاعدة البيانات العلاقية.

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

مستلزمات العمل

يجب أن يكون لدينا حاسوب يشغّل نظام إدارة قواعد البيانات العلاقية Relational Database Management System -أو RDBMS اختصارًا- مستند إلى لغة SQL. وقد اختبرنا التعليمات والأمثلة الواردة في هذا المقال باستخدام البيئة التالية:

ملاحظة: تجدر الإشارة إلى أنّ الكثير من أنظمة إدارة قواعد البيانات العلاقية RDBMS لها تقديماتها الفريدة من لغة SQL، إذ ستعمل الأوامر في هذا المقال بنجاح مع معظم هذه الأنظمة، إذ تُعَد المفاتيح الرئيسية جزءًا من معيار SQL، ولكن هناك بعض الميزات خاصة بقاعدة البيانات، لذا قد نجد بعض الاختلافات في الصيغة أو الناتج عند اختبارها على أنظمة مختلفة عن MySQL.

سنحتاج أيضًا إلى قاعدة بيانات فارغة يمكن من خلالها إنشاء جداول توضّح استخدام المفاتيح الرئيسية كما سنشرح في الفقرات التالية.

الاتصال بخادم MySQL وإعداد قاعدة بيانات تجريبية نموذجية

سنتصل في هذا القسم بخادم MySQL وننشئ قاعدة بيانات تجريبية. إذا كان نظام قاعدة بيانات SQL الخاص بنا يعمل على خادم بعيد، نتصل بالخادم باستخدام بروتوكول SSH من جهازنا المحلي كما يلي:

$ ssh user@your_server_ip

ثم نفتح واجهة سطر أوامر خادم MySQL مع وضع اسم حساب مستخدم MySQL الخاص بك مكان user:

$ mysql -u user -p

ننشئ قاعدة بيانات بالاسم primary_keys:

mysql> CREATE DATABASE primary_keys;

إذا أُنشئِت قاعدة البيانات بنجاح، فسيظهر الخرج التالي:

الخرج
Query OK, 1 row affected (0.01 sec)

يمكن اختيار قاعدة البيانات primary_keys من خلال تنفيذ تعليمة USE التالية:

$ USE primary_keys;

وسيظهر الخرج التالي:

الخرج
Database changed

اخترنا قاعدة البيانات، ويمكن الآن إنشاء جداول تجريبية ضمنها، وبذلك أصبحنا جاهزًا لمتابعة هذا المقال والبدء في العمل مع المفاتيح الرئيسية.

مقدمة إلى المفاتيح الرئيسية Primary Keys

تُخزَّن البيانات في قاعدة البيانات العلاقية في جداول ذات بنية موحَّدة ومحدَّدة من الصفوف الفردية، ويوضّح تعريف الجدول الأعمدة الموجودة فيه وأنواع البيانات التي يمكن حفظها في الأعمدة الفردية، وهذا كافي لتخزين المعلومات في قاعدة البيانات والعثور عليها لاحقًا باستخدام معايير ترشيح مختلفة باستخدام تعليمة WHERE، ولكن لا تضمن هذه البنية إمكانية العثور على أي صف بعينه دون التباس مع صفوف أخرى.

لنفترض أن لدينا قاعدة بيانات لجميع السيارات المسجَّلة المسموح لها بالقيادة على الطرق العامة، حيث ستحتوي قاعدة البيانات على معلومات مثل نوع السيارة وطرازها وسنة تصنيعها ولون طلائها، ولكن إذا بحثنا عن سيارة شيفروليه كامارو Chevrolet Camaro حمراء اللون ومصنوعة في عام 2007، فيمكن العثور على أكثر من سيارة، إذ سيبيع المصنعون سيارات متماثلة لعملاء متعددين، لذا تحتوي السيارات المُسجَّلة على أرقام لوحات ترخيص تحدّد كل سيارة فريدة. إذا بحثنا عن سيارة تحمل لوحة الترخيص OFP857، فيمكن التأكد من أن هذا المعيار سيجد سيارة واحدة فقط، لأن أرقام اللوحات تحدد السيارات المسجلة بطريقة فريدة قانونيًا، ويسمى هذا الجزء من البيانات في قاعدة البيانات العلاقية بالمفتاح الرئيسي Primary Key.

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

  • يجب أن يستخدم المفتاح الرئيسي قيمًا فريدة، وإذا تكوّن المفتاح الرئيسي من أكثر من عمود واحد، فيجب أن تكون مجموعة القيم في هذه الأعمدة فريدة في الجدول بأكمله، إذ لا يمكن أن يظهر المفتاح الرئيسي أكثر من مرة لأنه مخصّص لتحديد كل صف بطريقة فريدة
  • يجب ألا يحتوي المفتاح الرئيسي على قيم NULL
  • يمكن لكل جدول في قاعدة البيانات استخدام مفتاح رئيسي واحد فقط

يفرض محرّك قاعدة البيانات هذه القواعد، لذا يمكنك الوثوق بصحة هذه الخاصيات عند تعريف المفتاح الرئيسي لجدول ما، ويجب أن تضع في بالنا محتوى البيانات وما الذي يمكن اختياره منها لتمثيل المفتاح الرئيسي بشكل مناسب. المفاتيح الطبيعية Natural keys هي معرّفات موجودة مسبقًا في مجموعة البيانات، والمفاتيح البديلة Surrogate Keys هي معرّفات اصطناعية، ويمكن مطالعة مقال فهم قيود SQL لمزيد من التفاصيل.

تحتوي بعض هياكل البيانات على مفاتيح رئيسية تظهر في مجموعة البيانات طبيعيًا مثل أرقام لوحات الترخيص في قاعدة بيانات السيارات أو أرقام الضمان الاجتماعي في دليل المواطنين، ولا تكون هذه المعرّفات مؤلَّفة من قيمة واحدة بل مؤلفة من زوج أو مجموعة من عدة قيم في بعض الأحيان، فمثلًا لا يمكن تحديد منزل فريد باستخدام اسم الشارع أو رقم الشارع فقط في دليل مدينة محلية للمنازل، إذ يمكن أن يكون هناك عدة منازل في شارع واحد، ويمكن أن يظهر الرقم نفسه في شوارع متعددة، ولكن يمكن افتراض أن كلًا من اسم الشارع ورقمه هو معرّف منزل فريد. تسمّى هذه المعرّفات بالمفاتيح الطبيعية.

لكن لا يمكن في بعض الأحيان تمييز البيانات تمييزًا فريدًا باستخدام قيم عمود واحد أو مجموعة فرعية صغيرة من الأعمدة، وبالتالي يجب إنشاء مفاتيح رئيسية اصطناعية باستخدام تسلسل من الأرقام مثلًا أو معرّفات مُولَّدة عشوائيًا مثل معرّفات UUID، وتسمّى هذه المفاتيح بالمفاتيح البديلة.

سننشئ في الأقسام التالية مفاتيح طبيعية بناءً على عمود واحد أو أعمدة متعددة، كما سنولّد مفاتيح بديلة للجداول التي لا يكون المفتاح الطبيعي خيارًا فيها.

إنشاء مفتاح رئيسي من عمود واحد

تحتوي مجموعة البيانات على عمود واحد طبيعيًا في العديد من الحالات، ويمكن استخدام هذا العمود لتحديد الصفوف في الجدول تحديدًا فريدًا، وبالتالي يمكن إنشاء مفتاح طبيعي لوصف هذه البيانات. لنفترض أن لدينا الجدول التالي باتباع المثال السابق لقاعدة بيانات السيارات المُسجَّلة:

جدول بسيط
+---------------+-----------+------------+-------+------+
| license_plate | brand     | model      | color | year |
+---------------+-----------+------------+-------+------+
| ABC123        | Ford      | Mustang    | Red   | 2018 |
| CES214        | Ford      | Mustang    | Red   | 2018 |
| DEF456        | Chevrolet | Camaro     | Blue  | 2016 |
| GHI789        | Dodge     | Challenger | Black | 2014 |
+---------------+-----------+------------+-------+------+

يمثّل الصف الأول والثاني سيارة فورد موستانج Ford Mustang حمراء مصنوعة في عام 2018، ولن تتمكّن من تحديد السيارة بطريقة فريدة باستخدام نوع السيارة وطرازها فقط، لذا تختلف لوحة الترخيص لكل سيارة في كلتا الحالتين، ممّا يوفّر معرّفًا فريدًا جيدًا لكل صف في الجدول. يُعَد رقم لوحة الترخيص جزءًا من البيانات، لذا يؤدي استخدامه بوصفه مفتاحًا رئيسيًا إلى إنشاء مفتاح طبيعي. إذا أنشأنا الجدول دون استخدام مفتاح رئيسي في العمود license_plate، فستخاطر بظهور لوحة مكررة أو فارغة في مجموعة البيانات لاحقًا.

لننشئ الآن جدولًا يشبه الجدول السابق مع استخدام العمود license_plate بوصفه مفتاحًا رئيسيًا مع الأعمدة التالية:

  • license_plate: رقم لوحة الترخيص، ونمثله باستخدام نوع البيانات varchar
  • brand: نوع السيارة، ونمثّله باستخدام نوع البيانات varchar بحد أقصى 50 محرفًا
  • model: طراز السيارة، ونمثّله باستخدام نوع البيانات varchar بحد أقصى 50 محرفًا
  • color: لون السيارة، ونمثّله باستخدام نوع البيانات varchar بحد أقصى 20 محرفًا
  • year: سنة تصنيع السيارة، ونمثّله باستخدام نوع البيانات int لتخزين البيانات العددي.

ولننشئ الآن الجدول cars من خلال تنفيذ تعليمة SQL التالية:

mysql> CREATE TABLE cars (
mysql>     license_plate varchar(8) PRIMARY KEY,
mysql>     brand varchar(50),
mysql>     model varchar(50),
mysql>     color varchar(20),
mysql>     year int
mysql> );

تكون تعليمة PRIMARY KEY بعد تعريف نوع بيانات license_plate، حيث يمكنك استخدام الصيغة المبسَّطة لإنشاء المفتاح وكتابة PRIMARY KEY في تعريف العمود عند التعامل مع المفاتيح الرئيسية المستندة إلى أعمدة مفردة.

إذا كان الخرج كما يلي، فهذا يعني إنشاء الجدول بنجاح:

الخرج
Query OK, 0 rows affected (0.00 sec)

نحمّل بعد ذلك الجدول ببعض الصفوف التجريبية المعروضة في المثال السابق من خلال تشغيل عملية INSERT INTO التالية:

mysql> INSERT INTO cars VALUES
mysql>     ('ABC123', 'Ford', 'Mustang', 'Red', 2018),
mysql>     ('CES214', 'Ford', 'Mustang', 'Red', 2018),
mysql>     ('DEF456', 'Chevrolet', 'Camaro', 'Blue', 2016),
mysql>     ('GHI789', 'Dodge', 'Challenger', 'Black', 2014);

وستستجيب قاعدة البيانات برسالة النجاح التالية:

الخرج
Query OK, 4 rows affected (0.010 sec)
Records: 4  Duplicates: 0  Warnings: 0

يمكن الآن التحقق من أن الجدول الذي أنشأناه يحتوي على البيانات والتنسيق المتوقع باستخدام تعليمة SELECT التالية:

mysql> SELECT * FROM cars;

وسيظهر الخرج جدولًا مشابهًا للجدول الموجود في بداية هذا القسم:

الخرج
+---------------+-----------+------------+-------+------+
| license_plate | brand     | model      | color | year |
+---------------+-----------+------------+-------+------+
| ABC123        | Ford      | Mustang    | Red   | 2018 |
| CES214        | Ford      | Mustang    | Red   | 2018 |
| DEF456        | Chevrolet | Camaro     | Blue  | 2016 |
| GHI789        | Dodge     | Challenger | Black | 2014 |
+---------------+-----------+------------+-------+------+

يمكن بعد ذلك التحقق من ضمان قواعد المفتاح الرئيسي باستخدام محرّك قاعدة البيانات، لذا نجرّب إدخال سيارة لها رقم لوحة مكرّر من خلال تنفيذ الأمر التالي:

mysql> INSERT INTO cars VALUES ('DEF456', 'Jeep', 'Wrangler', 'Yellow', 2019);

وسيستجيب MySQL برسالة الخطأ التالية التي تفيد بأن لوحة الترخيص DEF456 تمثّل إدخالًا مكررًا للمفتاح الرئيسي:

الخرج
ERROR 1062 (23000): Duplicate entry 'DEF456' for key 'cars.PRIMARY'

ملاحظة: تُطبَّق المفاتيح الرئيسية باستخدام الفهارس الفريدة Unique Indexes وتشترك في العديد من الخاصيات مع الفهارس التي قد ننشئها يدويًا لأعمدة أخرى في الجدول، وتعمل فهارس المفاتيح الرئيسية أيضًا على تحسين أداء الاستعلام في الجدول للعمود الذي عرّفنا الفهرس له. اطّلع على مقال كيفية استخدام الفهارس في SQL لمزيد من المعلومات.

يمكن الآن التأكد من عدم السماح باستخدام لوحات ترخيص مكرّرة، ولنتحقق الآن من إمكانية إدخال سيارة لها لوحة ترخيص فارغة كما يلي:

mysql> INSERT INTO cars VALUES (NULL, 'Jeep', 'Wrangler', 'Yellow', 2019);

وستستجيب قاعدة البيانات برسالة الخطأ التالية:

الخرج
ERROR 1048 (23000): Column 'license_plate' cannot be null

يمكن التأكّد من أن المفتاح الرئيسي license_plate يحدّد كلّ صف في الجدول تحديدًا فريدًا بفضل القاعدتين السابقتين اللتين تفرضهما قاعدة البيانات، وبالتالي إذا استعلمنا في الجدول عن أي لوحة ترخيص، فسنتوقع إعادة صف واحد في كل مرة.

نشرح في القسم التالي كيفية استخدام المفاتيح الرئيسية مع أعمدة متعددة.

إنشاء مفتاح رئيسي من أعمدة متعددة

إن لم يكن عمود واحد كافيًا لتحديد صف فريد في الجدول، فيمكن إنشاء مفاتيح رئيسية تستخدم أكثر من عمودٍ واحد. لنفترض مثلًا وجود سجلٍ للمنازل بحيث لا يكفي اسم الشارع أو رقمه فقط لتحديد أيّ منزل فردي كما يلي:

جدول بسيط
+-------------------+---------------+-------------------+------+
| street_name       | street_number | house_owner       | year |
+-------------------+---------------+-------------------+------+
| 5th Avenue        | 100           | Bob Johnson       | 2018 |
| Broadway          | 1500          | Jane Smith        | 2016 |
| Central Park West | 100           | John Doe          | 2014 |
| Central Park West | 200           | Tom Thompson      | 2015 |
| Lexington Avenue  | 5001          | Samantha Davis    | 2010 |
| Park Avenue       | 7000          | Michael Rodriguez | 2012 |
+-------------------+---------------+-------------------+------+

يظهر اسم الشارع Central Park West أكثر من مرة في الجدول، ويظهر رقم الشارع 100 أكثر من مرة أيضًا، ولكن لا تظهَر أي أزواج مكررة من أسماء الشوارع وأرقامها، وبالتالي يمكن استخدام زوج من هاتين القيمتين لتحديد كل صف في الجدول تحديدًا فريدًا في الحالة التي لا يمكن فيها لأي عمود بمفرده أن يكون مفتاحًا رئيسيًا.

لننشئ الآن جدولًا يشبه الجدول السابق ويحتوي على الأعمدة التالية:

  • street_name: اسم الشارع الذي يقع فيه المنزل، ونمثّله باستخدام نوع البيانات varchar بحد أقصى 50 محرفًا.
  • street_number: رقم شارع المنزل، ونمثّله باستخدام نوع البيانات varchar، ويمكن لهذا العمود تخزين ما يصل إلى 5 محارف، ولا يستخدم نوع البيانات العددي int لأن بعض أرقام الشوارع قد تحتوي على محارف مثل 200B.
  • house_owner: اسم مالك المنزل، ونمثّله باستخدام نوع البيانات varchar بحد أقصى 50 محرفًا.
  • year: العام الذي بُني فيه المنزل، ونمثّله باستخدام نوع البيانات int لتخزين القيم العددية.

سيستخدم المفتاح الرئيسي هذه المرة العمودين street_name و street_number بدلًا من استخدام عمود واحد من خلال تنفيذ تعليمة SQL التالية:

mysql> CREATE TABLE houses (
mysql>     street_name varchar(50),
mysql>     street_number varchar(5),
mysql>     house_owner varchar(50),
mysql>     year int,
mysql>     PRIMARY KEY(street_name, street_number)
mysql> );

تظهر تعليمة PRIMARY KEY بعد تعريفات الأعمدة على عكس المثال السابق، وتليها أقواس تحتوي على اسمي عمودين هما: street_name و street_number. تنشئ هذه الصيغة المفتاح الرئيسي في الجدول houses الذي يمتد إلى عمودين.

إذا ظهر الخرج التالي، فهذا يعني إنشاء الجدول بنجاح:

الخرج
Query OK, 0 rows affected (0.00 sec)

نحمّل بعد ذلك الجدول بالصفوف التجريبية المعروضة في المثال السابق من خلال تشغيل عملية INSERT INTO التالية:

mysql> INSERT INTO houses VALUES
mysql>     ('Central Park West', '100', 'John Doe', 2014),
mysql>     ('Broadway', '1500', 'Jane Smith', 2016),
mysql>     ('5th Avenue', '100', 'Bob Johnson', 2018),
mysql>     ('Lexington Avenue', '5001', 'Samantha Davis', 2010),
mysql>     ('Park Avenue', '7000', 'Michael Rodriguez', 2012),
mysql>     ('Central Park West', '200', 'Tom Thompson', 2015);

وستستجيب قاعدة البيانات برسالة النجاح التالية:

الخرج
Query OK, 6 rows affected (0.000 sec)
Records: 6  Duplicates: 0  Warnings: 0

يمكن الآن التحقق من أن الجدول الذي أنشأناه يحتوي على البيانات والتنسيق المتوقع باستخدام تعليمة SELECT التالية:

mysql> SELECT * FROM houses;

وسيُظهِر الخرج جدولًا مشابهًا للجدول الموجود في بداية هذا القسم:

الخرج
+-------------------+---------------+-------------------+------+
| street_name       | street_number | house_owner       | year |
+-------------------+---------------+-------------------+------+
| 5th Avenue        | 100           | Bob Johnson       | 2018 |
| Broadway          | 1500          | Jane Smith        | 2016 |
| Central Park West | 100           | John Doe          | 2014 |
| Central Park West | 200           | Tom Thompson      | 2015 |
| Lexington Avenue  | 5001          | Samantha Davis    | 2010 |
| Park Avenue       | 7000          | Michael Rodriguez | 2012 |
+-------------------+---------------+-------------------+------+
6 rows in set (0.000 sec)

لنتحقق الآن من سماح قاعدة البيانات بإدراج صفوف تحتوي على أسماء وأرقام شوارع مكرَّرة، مع تقييد ظهور عناوين كاملة مكررة في الجدول. لنبدأ أولًا بإضافة منزل آخر في شارع Park Avenue كما يلي:

mysql> INSERT INTO houses VALUES ('Park Avenue', '8000', 'Emily Brown', 2011);

سيستجيب MySQL برسالة النجاح التالية لأن العنوان ‎8000 Park Avenue‎ لم يظهر في الجدول سابقًا:

الخرج
Query OK, 1 row affected (0.010 sec)

وستظهر نتيجة مماثلة عند إضافة منزل في العنوان ‎8000 Main Street‎ مع تكرار رقم الشارع كما يلي:

mysql> INSERT INTO houses VALUES ('Main Street', '8000', 'David Jones', 2009);

مما سيؤدي إلى إدراج صف جديد بنجاح بسبب عدم تكرار العنوان الكامل:

الخرج
Query OK, 1 row affected (0.010 sec)

نحاول الآن إضافة منزل آخر في العنوان ‎100 5th Avenue‎ باستخدام تعليمة INSERT التالية:

mysql> INSERT INTO houses VALUES ('5th Avenue', '100', 'Josh Gordon', 2008);

وستستجيب قاعدة البيانات برسالة الخطأ التالية لإعلامك بوجود إدخال مكرر للمفتاح الرئيسي لزوج القيم 5th Avenue و 100:

الخرج
ERROR 1062 (23000): Duplicate entry '5th Avenue-100' for key 'houses.PRIMARY'

تطبّق قاعدة البيانات قواعد المفتاح الرئيسي بطريقة صحيحة، مع تعريف المفتاح لزوج من الأعمدة، وبالتالي يمكن التأكّد من عدم تكرار العنوان الكامل المكون من اسم الشارع ورقمه في الجدول.

أنشأنا في هذا القسم مفتاحًا طبيعيًا مع زوج من الأعمدة لتحديد كل صف في الجدول house بوصفه صفًا فريدًا، ولكن لا يمكن دائمًا استخلاص المفاتيح الرئيسية من مجموعة البيانات، لذا سنستخدم في القسم التالي المفاتيح الرئيسية الاصطناعية التي لا تأتي من البيانات مباشرةً.

إنشاء مفتاح رئيسي تسلسلي Sequential Primary Key

أنشأنا مفاتيح رئيسية فريدة باستخدام أعمدة موجودة في مجموعات البيانات التجريبية النموذجية، ولكن البيانات ستتكرّر في بعض الحالات، مما يمنع الأعمدة من أن تكون معرّفات فريدة جيدة، لذا يمكن إنشاء مفاتيح رئيسية تسلسلية باستخدام معرّفات مُولَّدة. تسمَّى المفاتيح الرئيسية التي أنشأناها من المعرّفات الاصطناعية بالمفاتيح البديلة Surrogate Keys عندما تتطلب البيانات المتاحة ابتكار معرّفات جديدة لتحديد الصفوف بطريقة فريدة.

لنفترض أن لدينا قائمة بأعضاء نادي الكتاب، وهو تجمع غير رسمي يمكن لأي شخص الانضمام إليه دون بطاقة هوية حكومية، وبالتالي هناك احتمال أن ينضم إلى النادي في وقتٍ ما أشخاص يحملون أسماء متطابقة:

جدول بسيط
+------------+-----------+
| first_name | last_name |
+------------+-----------+
| John       | Doe       |
| Jane       | Smith     |
| Bob        | Johnson   |
| Samantha   | Davis     |
| Michael    | Rodriguez |
| Tom        | Thompson  |
| Sara       | Johnson   |
| David      | Jones     |
| Jane       | Smith     |
| Bob        | Johnson   |
+------------+-----------+

يتكرر الاسمان Bob Johnson و Jane Smith في الجدول، لذا نحتاج إلى استخدام معرّف إضافي للتأكد من هوية كل منهما، ولا يمكن تحديد الصفوف تحديدًا فريدًا في هذا الجدول بأيّ طريقة، ولكن إذا احتفظنا بقائمة أعضاء نادي الكتاب على الورق، فيمكن الاحتفاظ بمعرّفات مساعدة للتمييز بين الأشخاص الذين يحملون الأسماء نفسها في المجموعة.

يمكن إجراء شيء مماثل في قاعدة بيانات علاقية باستخدام عمود إضافي يحتوي على معرّفات مُولَّدة بدون معنى لغرض وحيد هو الفصل بين جميع الصفوف في الجدول بطريقة فريدة، ولنسمي هذا العمود بالاسم member_id، ولكن سيكون من الصعب التوصّل إلى مثل هذا المعرّف كلما أردنا إضافة عضو آخر في نادي الكتاب إلى قاعدة البيانات. يمكن حل هذه المشكلة باستخدام الميزة التي يوفرها MySQL، والتي هي ميزة خاصة بالأعمدة الرقمية المتزايدة تلقائيًا، حيث توفّر قاعدة البيانات قيمة العمود بتسلسل متزايد من الأعداد الصحيحة تلقائيًا.

لننشئ الآن جدولًا يشبه الجدول السابق، ولكن سنضيف عمودًا إضافيًا متزايدًا تلقائيًا member_id ليكون محتويًا على العدد المُسنَد لكل عضو في النادي تلقائيًا، وسيمثّل هذا العدد المُسنَد تلقائيًا مفتاحًا رئيسيًا للجدول الذي سيحتوي على الأعمدة التالية:

  • member_id: معرّف رقمي متزايد تلقائيًا، ونمثّله باستخدام نوع البيانات int.
  • first_name: الاسم الأول لأعضاء النادي، والذي نمثله باستخدام نوع البيانات varchar بحد أقصى 50 محرفًا.
  • last_name: يالاسم الأخير لأعضاء النادي، والذي نمثله باستخدام نوع البيانات varchar بحد أقصى 50 محرفًا.

لننشئ هذا الجدول من خلال تنفيذ تعليمة SQL التالية:

mysql> CREATE TABLE club_members (
mysql>     member_id int AUTO_INCREMENT PRIMARY KEY,
mysql>     first_name varchar(50),
mysql>     last_name varchar(50)
mysql> );

تظهَر تعليمة PRIMARY KEY بعد تعريف نوع العمود مثل المفتاح الرئيسي لعمود واحد، ولكن تظهَر سمة Attribute إضافية قبلها هي AUTO_INCREMENT التي تخبر MySQL بتوليد قيم تلقائيًا لهذا العمود باستخدام تسلسلٍ متزايد من الأرقام إن لم تكن متوفّرة صراحةً.

ملاحظة: تُعَد الخاصية AUTO_INCREMENT لتعريف عمود خاصةً بقاعدة بيانات MySQL، ولكن توفّر قواعد البيانات الأخرى طرقًا مماثلة لتوليد مفاتيح تسلسلية مع اختلاف صيغتها بين المحرّكات، لذا نشجّعك على الرجوع إلى التوثيق الرسمي لنظام إدارة قواعد البيانات العلاقية الخاص بك لمزيد من التفاصيل.

إذا ظهر الخرج التالي، فهذا يعني إنشاء الجدول بنجاح:

الخرج
Query OK, 0 rows affected (0.00 sec)

نحمّل بعد ذلك الجدول بالصفوف التجريبية النموذجية المعروضة في المثال السابق من خلال تشغيل عملية INSERT INTO التالية:

mysql> INSERT INTO club_members (first_name, last_name) VALUES
mysql>     ('John', 'Doe'),
mysql>     ('Jane', 'Smith'),
mysql>     ('Bob', 'Johnson'),
mysql>     ('Samantha', 'Davis'),
mysql>     ('Michael', 'Rodriguez'),
mysql>     ('Tom', 'Thompson'),
mysql>     ('Sara', 'Johnson'),
mysql>     ('David', 'Jones'),
mysql>     ('Jane', 'Smith'),
mysql>     ('Bob', 'Johnson');

تتضمن تعليمة INSERT الآن قائمة بأسماء الأعمدة first_name و first_name، مما يضمن معرفة قاعدة البيانات بأن العمود member_id غير مُدرَج في مجموعة البيانات، لذا يجب أخذ القيمة الافتراضية له بدلًا من ذلك.

وستستجيب قاعدة البيانات برسالة النجاح التالية:

الخرج
Query OK, 10 rows affected (0.002 sec)
Records: 10  Duplicates: 0  Warnings: 0

نستخدم تعليمة SELECT التالية للتحقق من البيانات الموجودة في الجدول الذي أنشأناه:

mysql> SELECT * FROM club_members;

وسيعرض الخرج التالي جدولًا مشابهًا للجدول الموجود في بداية هذا القسم:

الخرج
+-----------+------------+-----------+
| member_id | first_name | last_name |
+-----------+------------+-----------+
|         1 | John       | Doe       |
|         2 | Jane       | Smith     |
|         3 | Bob        | Johnson   |
|         4 | Samantha   | Davis     |
|         5 | Michael    | Rodriguez |
|         6 | Tom        | Thompson  |
|         7 | Sara       | Johnson   |
|         8 | David      | Jones     |
|         9 | Jane       | Smith     |
|        10 | Bob        | Johnson   |
+-----------+------------+-----------+
10 rows in set (0.000 sec)

ولكن سيظهر العمود member_id في النتيجة، والذي يحتوي على تسلسل من الأرقام من 1 إلى 10، وبالتالي أصبح من الممكن التمييز بين الصفوف Jane Smith و Bob Johnson المكرّرة، إذ سيرتبط كل اسم بمعرّف فريد member_id.

لنتحقّق الآن مما إذا كانت قاعدة البيانات ستسمح بإضافة بعضو آخر اسمه Tom Thompson إلى قائمة أعضاء النادي كما يلي:

mysql> INSERT INTO club_members (first_name, last_name) VALUES ('Tom', 'Thompson');

وسيستجيب MySQL برسالة النجاح التالية:

الخرج
Query OK, 1 row affected (0.009 sec)

ولنتحقق الآن من المعرّف الرقمي الذي أسندَته قاعدة البيانات للإدخال الجديد من خلال تنفيذ استعلام SELECT التالي:

mysql> SELECT * FROM club_members;

وسيظهر الخرج التالي الذي سيحتوي على صفٍ جديد:

الخرج
+-----------+------------+-----------+
| member_id | first_name | last_name |
+-----------+------------+-----------+
|         1 | John       | Doe       |
|         2 | Jane       | Smith     |
|         3 | Bob        | Johnson   |
|         4 | Samantha   | Davis     |
|         5 | Michael    | Rodriguez |
|         6 | Tom        | Thompson  |
|         7 | Sara       | Johnson   |
|         8 | David      | Jones     |
|         9 | Jane       | Smith     |
|        10 | Bob        | Johnson   |
|        11 | Tom        | Thompson  |
+-----------+------------+-----------+
11 rows in set (0.000 sec)

أُسنِد الرقم 11 إلى الصف الجديد تلقائيًا في عمود member_id باستخدام ميزة AUTO_INCREMENT في قاعدة البيانات.

إذا لم يكن للبيانات التي نعمل عليها مرشَّحين طبيعيين ليكونوا مفاتيح رئيسية، ولا نريد توفير معرّفات اصطناعية في كل مرة نضيف فيها بيانات جديدة إلى قاعدة البيانات، فيمكن الاعتماد على المعرّفات المولَّدة تسلسليًا لتكون مفاتيح رئيسية.

الخلاصة

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

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

ترجمة -وبتصرف- للمقال How To Use Primary Keys in SQL لصاحبَيه Mateusz Papiernik و Rachel Lee.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...