طَبِّقْهاتعلّم المبدأ، وطبّقه بيدكمقرر 121 · مبادئ قواعد البيانات
الدرس 5 · الوحدة 3: أمان وتكامل قواعد البيانات

تكامل البيانات: القيود

قواعد داخل الجدول ترفض البيانات الخاطئة قبل أن تُحفظ. ⏱ نحو 25 دقيقة.

بعد هذا الدرس ستستطيع أن:
  • تشرح أنواع تكامل البيانات الثلاثة.
  • تستخدم القيود PRIMARY KEY و NOT NULL و DEFAULT و UNIQUE و CHECK.
  • تفسّر رسالة الخطأ حين يرفض النظام بيانات تخالف قيدًا.
  • تبيّن دور المفتاح الأجنبي في التكامل المرجعي.

١ما تكامل البيانات؟

تكامل البيانات Data Integrity: أن تبقى البيانات صحيحة ودقيقة ومتسقة طوال حياتها، مهما أضاف المستخدمون أو عدّلوا. والطريقة: نضع قيودًا Constraints في تعريف الجدول، فيرفض النظام أي بيانات تخالفها قبل أن تُحفظ.

نوع التكاملمعناهالقيد الذي يحققه
تكامل الكيانكل صف يمكن تمييزه عن غيره، فلا يتكرر ولا يُجهل.PRIMARY KEY
تكامل المجالكل قيمة في عمود من النوع والمدى المسموح.NOT NULL CHECK DEFAULT UNIQUE
التكامل المرجعيكل إشارة إلى جدول آخر تشير إلى صف موجود فعلًا.FOREIGN KEY

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

٢المفتاح الأساسي PRIMARY KEY

عمود (أو أكثر) قيمته فريدة لكل صف ولا تكون فارغة أبدًا. مثل رقم الهوية أو الرقم التدريبي: لا يتكرر، ولا يوجد طالب بلا رقم.

query.sql
CREATE TABLE students (  id   INTEGER PRIMARY KEY,  name TEXT);INSERT INTO students VALUES (441001, 'أحمد');INSERT INTO students VALUES (441002, 'محمد');INSERT INTO students VALUES (441001, 'يوسف');  -- رقم مكرر!
✓ أُنشئ الجدول
✓ أُضيف صف واحد
✓ أُضيف صف واحد
✗ خطأ (السطر 7): مخالفة قيد UNIQUE: القيمة مكررة في students.id

رفض النظام الصف الثالث لأن الرقم 441001 موجود. ولاحظ أن الصفين الأولين أُضيفا قبل الخطأ.

٣NOT NULL و DEFAULT: لا فراغ

NULL في قواعد البيانات تعني «لا قيمة» أو «غير معروف»، وليست صفرًا ولا نصًّا فارغًا. والقيد NOT NULL يمنعها. أما DEFAULT فيضع قيمة افتراضية حين لا يذكر المستخدم قيمة:

query.sql
CREATE TABLE tickets (  id       INTEGER PRIMARY KEY,  title    TEXT NOT NULL,  status   TEXT NOT NULL DEFAULT 'مفتوح',  priority INTEGER DEFAULT 3);-- لم نذكر status ولا priorityINSERT INTO tickets (id, title) VALUES (1, 'الطابعة لا تعمل');SELECT * FROM tickets; -- نسينا العنوانINSERT INTO tickets (id) VALUES (2);
✓ أُنشئ الجدول
✓ أُضيف صف واحد
النتيجة · صف واحد
idtitlestatuspriority
1الطابعة لا تعملمفتوح3
✗ خطأ (السطر 11): مخالفة قيد NOT NULL: العمود tickets.title لا يقبل قيمة فارغة

٤UNIQUE: لا تكرار

UNIQUE يمنع تكرار القيمة في عمود ليس هو المفتاح الأساسي، مثل البريد الإلكتروني أو رقم الجوال. وفي «متجر الواحة» رقم الجوال UNIQUE:

query.sql
INSERT INTO customers (id, name, phone)VALUES (11, 'عميل جديد', '0551000002');
✗ خطأ (السطر 1): مخالفة قيد UNIQUE: القيمة مكررة في customers.phone

الرقم 0551000002 مسجّل لنورة، فرفض النظام تسجيله لعميل آخر. الفرق عن المفتاح الأساسي: الجدول له مفتاح أساسي واحد، ويمكن أن يكون فيه أكثر من عمود UNIQUE، و UNIQUE يقبل NULL.

٥CHECK: شرط على القيمة

CHECK يضع شرطًا يجب أن تحققه كل قيمة. في «متجر الواحة» السعر يجب أن يكون موجبًا، وفي «الكلية التقنية» المعدل بين 0 و 5:

query.sql
INSERT INTO products (id, name, category, price)VALUES (13, 'قهوة مجانية', 'مشروبات', -5);
✗ خطأ (السطر 1): مخالفة قيد CHECK: price > 0
query.sql
UPDATE students SET gpa = 5.5 WHERE id = 1001;
✗ خطأ (السطر 1): مخالفة قيد CHECK: gpa BETWEEN 0 AND 5

القيود لا تعمل عند الإدخال فقط، بل عند التعديل أيضًا: لا يمكن أن «تتسلل» قيمة خاطئة بأي طريق.

٦التكامل المرجعي: إشارة إلى شيء موجود

الطلب في جدول orders يشير إلى عميل برقمه customer_id. فماذا لو أدخلنا طلبًا لعميل رقمه 99، وهو غير موجود؟

query.sql
INSERT INTO orders (id, customer_id, order_date)VALUES (13, 99, '2025-06-01');
✗ خطأ (السطر 1): مخالفة المفتاح الأجنبي: القيمة غير موجودة في الجدول الأصل، أو أن صفوفًا أخرى تعتمد على هذا الصف

هذا عمل FOREIGN KEY، المفتاح الأجنبي. يمنع «الطلبات اليتيمة» التي لا صاحب لها. وستتعلم إنشاءه بنفسك في الدرس 10.

توقّع وتحقّق

أي قيد يضمن ألا يتكرر رقم الطالب ولا يكون فارغًا؟

فريد وغير فارغ.

القيد الذي يمنع سعرًا سالبًا:

شرط على القيمة.

معنى NULL:

غير معروف.

القيد الذي يمنع طلبًا لعميل غير موجود:

تكامل مرجعي.

الخلاصة

تحدٍّ برمجي: جدول موظفين محمي

متوسط

أنشئ جدول موظفين يرفض البيانات الخاطئة من تلقاء نفسه.

المطلوب:
  • اسم الجدول employees وأعمدته بالترتيب: id و name و email و salary و dept.
  • id مفتاح أساسي، و name لا يقبل الفراغ.
  • email لا يتكرر.
  • salary لا يقل عن 4000.
  • dept قيمته الافتراضية «عام».
👀 اعرض النتيجة المطلوبة
بعد التنفيذ: SELECT dept FROM employees WHERE id = 1
dept
عام
✓ التحقق الآلي من حلّك:
  • الكود يعمل بلا أخطاء
  • يقبل موظفًا صحيحًا
  • القسم الافتراضي «عام»
  • يرفض رقمًا مكررًا
  • يرفض موظفًا بلا اسم
  • يرفض بريدًا مكررًا
  • يرفض راتبًا أقل من 4000

💡 تلميح 1
اكتب القيد بعد نوع العمود مباشرة، مثل: name TEXT NOT NULL
💡 تلميح 2
salary REAL CHECK (salary >= 4000) و dept TEXT DEFAULT 'عام'

حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.

solution.sql
CREATE TABLE employees (  id     INTEGER PRIMARY KEY,  name   TEXT NOT NULL,  email  TEXT UNIQUE,  salary REAL CHECK (salary >= 4000),  dept   TEXT DEFAULT 'عام');
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←

📝 معلم؟ أرسل ملاحظة للمؤلف عن هذا الدرس