الانتقال إلى المحتوى الرئيسي
الوحدة 9 · الدرس 2 من 434/57 في الدورة~12 min
دروس الوحدة (2/4)

قيود متعددة وعلى مستوى الجدول

يعد التأكد من صحة البيانات الموجودة في قاعدة البيانات في الطبقة الأساسية ("تكامل البيانات") أمرًا أساسيًا. إذا قمت فقط بكتابة الأمان في تطبيق Node.js، فقد تتسبب الأخطاء في بيانات غير متناسقة في قاعدة البيانات. القيود على مستوى DDL هي خط الدفاع الأخير الذي لا يمكن اختراقه.

القيود الرئيسية

بالإضافة إلى PRIMARY KEY (مما يجعل العمود فريدًا وليس فارغًا) والكلاسيكيين NOT NULL وUNIQUE، هناك فئتان أساسيتان للاتساق المنطقي للبيانات:

1. المفتاح الخارجي (التكامل المرجعي)

يضمن القيد REFERENCES وجود معرف الارتباط بالفعل في الجدول "الأصل" الذي يشير إليه. على سبيل المثال، يجب ربط الطلب بعميل موجود.

SQL
CREATE TABLE orders (
  id SERIAL PRIMARY KEY,
  customer_id INTEGER REFERENCES customers(id)
);

** ماذا يفعل المفتاح الخارجي؟ **

  • يمنعك من إدراج customer_id غير موجود في customers.
  • يمنعك من DELETE (حذف) عميل من customers إذا كانت هناك أوامر تشير إليه (يحمي من السجلات "اليتيمة").

يمكننا أيضًا أن نقرر ما يجب أن يحدث عند حذف "الأصل":

SQL
customer_id INTEGER REFERENCES customers(id) ON DELETE CASCADE

باستخدام ON DELETE CASCADE، إذا قمنا بحذف العميل، فسوف يقوم Postgres ** تلقائيًا ** بإزالة جميع الروابط orders! (استخدمه بحذر شديد؛ عادةً ما يكون الإعداد الافتراضي الذي يمنع العملية هو الأفضل.)

2. تحقق من القيود

يقوم القيد CHECK بالتحقق من صحة الصف عن طريق اختبار تعبير منطقي قبل متابعة الحفظ.

SQL
CREATE TABLE contratti (
  id SERIAL PRIMARY KEY,
  stipendio NUMERIC(10,2) CHECK (stipendio > 0),
  data_inizio DATE,
  data_fine DATE,
  CHECK (data_fine > data_inizio)
);

الأول CHECK هو قيد العمود (يشير فقط إلى stipendio). أما CHECK الثاني في الأسفل فهو قيد الجدول (يمكنه عبور القيم من أعمدة متعددة، ويجب الإعلان عنه في الأسفل).

إذا حاول INSERT أو UPDATE حفظ النهاية قبل البداية، فسوف يرفضها Postgres مع وجود خطأ!

قيود التسمية

غالبًا ما يكون من الممارسات الجيدة إعطاء القيود اسمًا صريحًا (باستخدام الكلمة الأساسية CONSTRAINT). بهذه الطريقة، عندما يقوم Postgres بحظر سجل ما، سيخبرك الخطأ على سبيل المثال "تم انتهاك القيد 'stipendio_positivo'"، وهو أمر أكثر وضوحًا لتصحيح الأخطاء!

SQL
CREATE TABLE prodotti (
  id SERIAL PRIMARY KEY,
  nome VARCHAR(50),
  CONSTRAINT nome_univoco UNIQUE(nome)
);

جربه

تمرين#sql.m9.l2.e1
المحاولات: 0جارٍ التحميل…

قم بإنشاء جدول "prenotazioni" بالمعرف (SERIAL PRIMARY KEY) و"customer_id" (INTEGER). استخدم CONSTRAINT fk_cliente FOREIGN KEY (customer_id) مراجع العملاء (id) لإعطاء اسم صريح لقيد المفتاح الخارجي. افعل ذلك في الأسفل، كقيد للجدول.

جارٍ تحميل المحرر…
إظهار التلميح

اكتب القيد fk_cliente FOREIGN KEY (local_column) المراجع External_table(external_col)

الحل متاح بعد 3 من المحاولات

القيود مع المنطق المخصص

تمرين#sql.m9.l2.e2
المحاولات: 0جارٍ التحميل…

أنشئ جدول "eventi" بالمعرف (SERIAL PRIMARY KEY) وposti_totali (INTEGER) وbiglietti_venduti (INTEGER). قم بإضافة قيد جدول باسم "check_capienza" حيث يجب ألا يكون biglietti_venduti أكبر من posti_totali.

جارٍ تحميل المحرر…
إظهار التلميح

أضف القيد في الأسفل باستخدام CONSTRAINT check_capienza CHECK ( التعبير )

الحل متاح بعد 3 من المحاولات