PostgreSQL: قيود PostgreSQL وسلامة البيانات

آخر تحديث: 2026-08-26

1. ما ستتعلمه


2. القصة

Charlie هو مهندس قاعدة بيانات في منصة SaaS. يحتاج إلى فرض قواعد العمل التالية على مستوى قاعدة البيانات:

  1. يجب أن يكون مبلغ كل طلب > 0 (CHECK)
  2. يجب ألا تتداخل النطاقات الزمنية لحجوزات غرف الاجتماعات (EXCLUSION)
  3. يجب أن يؤدي حذف عميل إلى تنظيف طلباته تلقائيًا، لكن يجب حماية الطلبات الحرجة (استراتيجية تعاقب FOREIGN KEY)
  4. عند استيراد البيانات بكميات كبيرة، قد تنتهك الإشارات بين الصفوف القيود مؤقتًا، ويجب التحقق منها فقط بعد اكتمال الاستيراد (DEFERRABLE)

يستخدم Charlie القيود بدلاً من التحقق على مستوى التطبيق، مما يجعل قاعدة البيانات خط الدفاع الأخير لسلامة البيانات.


3. المفهوم: PRIMARY KEY

(1) دور المفتاح الأساسي

يحدد المفتاح الأساسي كل صف بشكل فريد في الجدول، ويجمع بين UNIQUE + NOT NULL. يمكن أن يكون للجدول مفتاح أساسي واحد فقط.

الخاصية الوصف
التفرد لا يُسمح بالقيم المكررة
غير فارغ لا يُسمح بـ NULL
فهرس تلقائ�� يقوم PostgreSQL تلقائيًا بإنشاء فهرس B-Tree فريد للمفتاح الأساسي
واحد لكل جدول يمكن تعريف PRIMARY KEY واحد فقط

(1) ▶ مثال

SQL
CREATE TABLE customers (
  customer_id BIGSERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  email VARCHAR(255) UNIQUE
);

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

(2) ▶ مثال

SQL
CREATE TABLE order_items (
  order_id   BIGINT NOT NULL,
  product_id BIGINT NOT NULL,
  quantity   INT NOT NULL CHECK (quantity > 0),
  PRIMARY KEY (order_id, product_id)
);

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

(2) مقارنة أنواع أعمدة المفتاح الأساسي

النوع التخزين النطاق حالة الاستخدام
SERIAL / BIGSERIAL 4/8 بايت 2 مليار / 9.2×10¹⁸ معظم جداول الأعمال
UUID 16 بايت فريد عالميًا الأنظمة الموزعة
مفتاح طبيع�� (مثلاً: البريد الإلكتروني) متغير نادر الاستخدام؛ خطر تغيير الأعمال
مفتاح أساسي مركب عدة أعمدة جداول الوصل، جداول جسر كثير إلى كثير

(3) ▶ مثال

SQL
CREATE TABLE global_events (
  event_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  event_name VARCHAR(200) NOT NULL,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

4. المفهوم: FOREIGN KEY

(1) المفتاح الخارجي واستراتيجيات التعاقب الخمس

يضمن المفتاح الخارجي سلامة المرجعية: يجب أن تكون قيمة العمود المرجع في الجدول الابن موجودة في المفتاح الأساسي/الفريد للجدول الأب.

الاستراتيجية سلوك ON DELETE سلوك ON UPDATE السيناريو النموذجي
CASCADE حذف تعاقبي للصفوف الابنة تحديث تعاقبي للصفوف الابنة حذف عناصر الطلب مع الطلب
SET NULL تعيين الصف الابن إلى NULL تعيين الصف الابن إلى NULL ارتباط اختياري؛ الحذف ليس له تأثير
SET DEFAULT تعيين الصف الابن إلى القيمة الافتراضية تعيين الصف الابن إلى القيمة الافتراضية نادر الاستخدام
RESTRICT رفض الحذف (فوري) رفض التحديث (فوري) حماية البيانات الحرجة
NO ACTION رفض الحذف (قابل للتأجيل) رفض التحديث (قابل للتأجيل) السلوك الافتراضي

(4) ▶ مثال

SQL
CREATE TABLE orders (
  order_id    BIGSERIAL PRIMARY KEY,
  customer_id BIGINT NOT NULL
    REFERENCES customers(customer_id) ON DELETE CASCADE,
  total_amount DECIMAL(12,2) NOT NULL
);

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

عند حذف عميل، يتم حذف جميع طلباته تلقائيًا.

(5) ▶ مثال

SQL
CREATE TABLE invoices (
  invoice_id  BIGSERIAL PRIMARY KEY,
  order_id    BIGINT NOT NULL
    REFERENCES orders(order_id) ON DELETE RESTRICT,
  invoice_date DATE NOT NULL
);

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

إذا كان الطلب لديه فاتورة بالفعل، يتم رفض حذف الطلب.

(2) مقارنة CASCADE مقابل RESTRICT

البعد CASCADE RESTRICT
حذف الصف الأب حذف الصفوف الابنة أيضًا رفض الحذف
أمان البيانا�� مريح لكنه محفوف بالمخاطر آمن لكنه يحتاج تنظيفًا يدويًا
حالة الاستخدام البيانات المساعدة البيانات الحرجة / المالية

(6) ▶ مثال

SQL
CREATE TABLE customers (
  customer_id BIGSERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL
);

CREATE TABLE orders (
  order_id    BIGSERIAL PRIMARY KEY,
  customer_id BIGINT REFERENCES customers(customer_id) ON DELETE CASCADE
);

CREATE TABLE order_items (
  item_id     BIGSERIAL PRIMARY KEY,
  order_id    BIGINT REFERENCES orders(order_id) ON DELETE CASCADE,
  product_id  BIGINT NOT NULL
);

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

حذف عميل → حذف تلقائي للطلبات → حذف تلقائي لعناصر الطلب، تعاقب ثلاثي المستويات.

(7) ▶ مثال

SQL
CREATE TABLE reviews (
  review_id   BIGSERIAL PRIMARY KEY,
  product_id  BIGINT REFERENCES products(product_id) ON DELETE SET NULL,
  content     TEXT NOT NULL
);

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

بعد حذف منتج، يتم تعيين product_id في المراجعة إلى NULL، لكن يتم الاحتفاظ بالمراجعة.


5. المفهوم: UNIQUE و NOT NULL

(1) قيد UNIQUE

يضمن UNIQUE عدم تكرار قيم العمود (أو تركيبات الأعمدة)، ويسمح بـ NULL (عدة قيم NULL لا تعتبر تكرارًا).

البعد PRIMARY KEY UNIQUE
العدد لكل جدول واحد فقط مسموح بعدة
NULL مسموح غير مسموح مسموح (عدة NULL لا تتعارض)
فهرس تلقائي نعم نعم
الدلالة يحدد الصف يضمن التفرد

(8) ▶ مثال

SQL
CREATE TABLE user_accounts (
  user_id BIGSERIAL PRIMARY KEY,
  email   VARCHAR(255) UNIQUE,
  phone   VARCHAR(20),
  UNIQUE (email, phone)
);

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

البريد الإلكتروني فريد بمفرده + (البريد الإلكتروني، الهاتف) فريد كتركيبة.

(2) قيد NOT NULL

يمنع NOT NULL تخزين قيم NULL في عمود؛ إنه أبسط قيد س��امة.

الكتابة الوصف
col TYPE NOT NULL قيد على مستوى العمود
CONSTRAINT nn_col CHECK (col IS NOT NULL) شكل مكافئ

(9) ▶ مثال

SQL
CREATE TABLE products (
  product_id   BIGSERIAL PRIMARY KEY,
  name         VARCHAR(200) NOT NULL,
  unit_price   DECIMAL(10,2) NOT NULL,
  description  TEXT
);

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

description يسمح بـ NULL؛ الأعمدة الرئيسية الأخرى لا تسمح.


6. المفهوم: قيد CHECK

(1) أساسيات قيد CHECK

يتطلب قيد CHECK أن تحقق قيمة العمود تعبيرًا منطقيًا معينًا. يمكن لـ CHECK في PostgreSQL الإشارة إلى أعمدة أخرى في نفس الصف (يدعم معيار SQL هذا أيضًا، لكن العديد من قواعد البيانات لا تدعمه).

الخاصية الوصف
فحص على مستوى الصف يمكنه الإشارة فقط إلى أعمدة الصف الحالي
ميزة PostgreSQL يمكنه الإشارة إلى صفوف أخرى (عبر استعلام فرعي، مع قيود)
CHECK على مستوى الجدول يمكنه تقييد عدة أعمدة مرة واحدة
NO INHERIT لا ينتشر إلى الجداول الابنة (ميزة PG)

(10) ▶ مثال

SQL
CREATE TABLE orders (
  order_id    BIGSERIAL PRIMARY KEY,
  total_amount DECIMAL(12,2) NOT NULL CHECK (total_amount > 0),
  discount    DECIMAL(12,2) DEFAULT 0 CHECK (discount >= 0)
);

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

(11) ▶ مثال

SQL
CREATE TABLE campaigns (
  campaign_id BIGSERIAL PRIMARY KEY,
  start_date  DATE NOT NULL,
  end_date    DATE NOT NULL,
  budget      DECIMAL(12,2) NOT NULL CHECK (budget > 0),
  CONSTRAINT chk_date_range CHECK (end_date >= start_date),
  CONSTRAINT chk_budget_limit CHECK (budget <= 1000000)
);

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

(2) أنماط CHECK الشائعة

قاعدة العمل تعبير CHECK
المبلغ موجب CHECK (amount > 0)
نطاق الخصم CHECK (discount BETWEEN 0 AND 1)
ترتيب التواريخ CHECK (end_date >= start_date)
قيم تعداد CHECK (status IN ('active', 'inactive', 'pending'))
طول السلسلة CHECK (LENGTH(phone) >= 10)
نسبة مئوية CHECK (rate >= 0 AND rate <= 100)

(12) ▶ مثال

SQL
CREATE TABLE subscriptions (
  sub_id    BIGSERIAL PRIMARY KEY,
  plan      VARCHAR(50) NOT NULL,
  price     DECIMAL(10,2) NOT NULL,
  CONSTRAINT chk_price_positive CHECK (price > 0),
  CONSTRAINT chk_plan_valid CHECK (plan IN ('free', 'basic', 'pro', 'enterprise'))
);

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

(13) ▶ مثال

SQL
ALTER TABLE orders
ADD CONSTRAINT chk_amount_positive CHECK (total_amount > 0);

Output:

TEXT 📖 للعرض فقط
-- تم تنفيذ عبارة SQL بنجاح

7. المفهوم: قيد EXCLUSION

(1) كيفية عمل EXCLUSION

يضمن قيد EXCLUSION: إذا كان صفان "متساويين" في أعمدة محددة (مقارنة بعامل =)، فإنهما لا "ي��داخلان" في البعد المحدد (مقارنة بعامل تداخل). هذه ميزة خاصة بـ PostgreSQL.

السيناريو القيد العامل
نطاقات زمنية غير متداخلة أوقات نفس المورد لا يمكن أن تتقاطع =, &&
عدم تكرار المقاعد أرقام مقاعد نفس الجلسة لا تتكرر =, = (مكافئ لـ UNIQUE)

(14) ▶ مثال

SQL
CREATE TABLE room_bookings (
  booking_id BIGSERIAL PRIMARY KEY,
  room_id    INT NOT NULL,
  time_range TSTZRANGE NOT NULL,
  booked_by  VARCHAR(100) NOT NULL,
  CONSTRAINT excl_room_no_overlap
    EXCLUDE USING GiST (room_id WITH =, time_range WITH &&)
);

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

(15) ▶ مثال

SQL
INSERT INTO room_bookings (room_id, time_range, booked_by)
VALUES (1, '[2025-07-13 09:00, 2025-07-13 11:00)', 'Alice');

INSERT INTO room_bookings (room_id, time_range, booked_by)
VALUES (1, '[2025-07-13 10:00, 2025-07-13 12:00)', 'Bob');
TEXT 📖 للعرض فقط
ERROR: conflicting key value violates exclusion constraint "excl_room_no_overlap"
DETAIL: Key (room_id, time_range)=(1, [2025-07-13 10:00,2025-07-13 12:00))
conflicts with existing key (room_id, time_range)=(1, [2025-07-13 09:00,2025-07-13 11:00)).

(2) مقارنة EXCLUSION مقابل UNIQUE

البعد UNIQUE EXCLUSION
عامل المقارنة = فقط مخصص (=، &&، <->، إلخ)
تداخل النطاق غير مدعوم مدعوم
نوع الفهرس B-Tree GiST / SP-GiST
المرونة منخفضة عالية
حالة الاستخدام تفرد القيم المنفصلة نطاقات غير متداخلة، قيود المسافة

(16) ▶ مثال

SQL
CREATE TABLE discount_tiers (
  tier_id    BIGSERIAL PRIMARY KEY,
  product_id INT NOT NULL,
  price_range NUMRANGE NOT NULL,
  discount   DECIMAL(5,4) NOT NULL,
  CONSTRAINT excl_price_no_overlap
    EXCLUDE USING GiST (product_id WITH =, price_range WITH &&)
);

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

8. المفهوم: قيد DEFERRABLE المؤجل

(1) آلية القيد المؤجل

افتراضيًا، يتم التحقق من القيود فورًا بعد كل عبارة. يسمح قيد DEFERRABLE بتأجيل التحقق حتى إيداع المعاملة، مما يحل مشكلة المرجع الدائري في العمليات الجماعية.

الوضع توقيت التحقق الصيغة
IMMEDIATE بعد كل عبارة السلوك الافتراضي
DEFERRABLE INITIALLY IMMEDIATE بعد كل عبارة (قابل للتبديل) DEFERRABLE INITIALLY IMMEDIATE
DEFERRABLE INITIALLY DEFERRED عند إيداع المعاملة DEFERRABLE INITIALLY DEFERRED

(17) ▶ مثال

SQL
CREATE TABLE departments (
  dept_id   INT PRIMARY KEY,
  name      VARCHAR(100) NOT NULL,
  manager_id INT
);

ALTER TABLE departments
ADD CONSTRAINT fk_dept_manager
  FOREIGN KEY (manager_id) REFERENCES departments(dept_id)
  DEFERRABLE INITIALLY DEFERRED;

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

(18) ▶ مثال

SQL
BEGIN;

INSERT INTO departments (dept_id, name, manager_id)
VALUES (1, 'Engineering', 2);

INSERT INTO departments (dept_id, name, manager_id)
VALUES (2, 'QA', 1);

COMMIT;

Output:

TEXT 📖 للعرض فقط
INSERT 0 1

تنفيذ INSERT الأول بمفرده سيفشل (manager_id=2 غير موجود بعد)، لكن DEFERRABLE يؤجل التحقق حتى COMMIT، لذا بمجرد اكتمال كلا INSERT ينجح التحقق.

(2) تبديل توقيت التحقق ديناميكيًا

(19) ▶ مثال

SQL
BEGIN;
SET CONSTRAINTS fk_dept_manager DEFERRED;

INSERT INTO departments (dept_id, name, manager_id) VALUES (3, 'Sales', 4);
INSERT INTO departments (dept_id, name, manager_id) VALUES (4, 'Marketing', 3);

SET CONSTRAINTS fk_dept_manager IMMEDIATE;
COMMIT;

Output:

TEXT 📖 للعرض فقط
INSERT 0 1

(3) مقارنة IMMEDIATE مقابل DEFERRED

البعد IMMEDIATE DEFERRED
توقيت التحقق بعد كل عبارة عند إيداع المعاملة
الأداء أسرع (تغذية راجعة فورية) أبطأ قليلاً (تحقق دفعة)
المرجع الدائري لا يمكن حله قابل للحل
المخاط�� منخفضة اكتشاف الانتهاك فقط في نهاية المعاملة
حالة الاستخدام معظم القيود المراجع الدائرية، الاستيراد الجماعي

9. المفهوم: تسمية القيود وإدارتها

(1) اصطلاح تسمية القيود

التسمية الجيدة تسهل تحديد المشاكل وتنفيذ العمليات.

نوع القيد البادئة الموصى بها مثال
PRIMARY KEY pk_ pk_orders
FOREIGN KEY fk_ fk_orders_customer
UNIQUE uq_ uq_users_email
CHECK chk_ chk_amount_positive
EXCLUSION excl_ excl_room_no_overlap

(20) ▶ مثال

SQL
CREATE TABLE orders (
  order_id     BIGSERIAL      CONSTRAINT pk_orders PRIMARY KEY,
  customer_id  BIGINT NOT NULL CONSTRAINT fk_orders_customer
    REFERENCES customers(customer_id) ON DELETE CASCADE,
  total_amount DECIMAL(12,2)  CONSTRAINT chk_amount_positive CHECK (total_amount > 0),
  status       VARCHAR(20)    CONSTRAINT chk_status_valid
    CHECK (status IN ('pending', 'shipped', 'delivered', 'cancelled')),
  order_date   TIMESTAMPTZ    NOT NULL DEFAULT NOW()
);

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

(2) عمليات إدارة القيود

العملية الصيغة
إضافة قيد ALTER TABLE t ADD CONSTRAINT name CHECK (...)
حذف قيد ALTER TABLE t DROP CONSTRAINT name
عرض القيود SELECT * FROM pg_constraint WHERE conrelid = 't'::regclass
تعطيل المشغلات (تعطيل القيود بشكل غير مباشر) ALTER TABLE t DISABLE TRIGGER ALL

(21) ▶ مثال

SQL
SELECT
  conname AS constraint_name,
  contype AS type,
  pg_get_constraintdef(oid) AS definition
FROM pg_constraint
WHERE conrelid = 'orders'::regclass;
TEXT 📖 للعرض فقط
 constraint_name       | type | definition
-----------------------+------+--------------------------------------------
 pk_orders             | p    | PRIMARY KEY (order_id)
 fk_orders_customer    | f    | FOREIGN KEY (customer_id) REFERENCES ...
 chk_amount_positive   | c    | CHECK ((total_amount > 0))
 chk_status_valid      | c    | CHECK ((status = ANY (ARRAY['pending'::...

10. مثال شامل

مخطط قيود منصة SaaS لـ Charlie — يغطي المفتاح الأساسي، تعاقب المفتاح الخارجي، CHECK، EXCLUSION، DEFERRABLE:

SQL
CREATE TABLE customers (
  customer_id BIGSERIAL    CONSTRAINT pk_customers PRIMARY KEY,
  name        VARCHAR(100) NOT NULL,
  email       VARCHAR(255) CONSTRAINT uq_customers_email UNIQUE,
  credit_limit DECIMAL(12,2) DEFAULT 0
    CONSTRAINT chk_credit_non_negative CHECK (credit_limit >= 0)
);

CREATE TABLE orders (
  order_id     BIGSERIAL      CONSTRAINT pk_orders PRIMARY KEY,
  customer_id  BIGINT NOT NULL CONSTRAINT fk_orders_customer
    REFERENCES customers(customer_id) ON DELETE RESTRICT,
  total_amount DECIMAL(12,2) NOT NULL
    CONSTRAINT chk_amount_positive CHECK (total_amount > 0),
  status       VARCHAR(20) DEFAULT 'pending'
    CONSTRAINT chk_status CHECK (status IN ('pending','shipped','delivered','cancelled')),
  created_at   TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE room_bookings (
  booking_id BIGSERIAL   CONSTRAINT pk_bookings PRIMARY KEY,
  room_id    INT NOT NULL,
  time_range TSTZRANGE NOT NULL,
  booked_by  VARCHAR(100) NOT NULL,
  CONSTRAINT excl_room_no_overlap
    EXCLUDE USING GiST (room_id WITH =, time_range WITH &&)
);

ALTER TABLE orders
ADD CONSTRAINT fk_orders_customer_deferred
  FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
  ON DELETE RESTRICT
  DEFERRABLE INITIALLY IMMEDIATE;

11. تدفق التنفيذ

أين يحدث التحقق من القيود في تنفيذ عبارة DML:

100%
flowchart TD
    A[INSERT/UPDATE/DELETE] --> B{فحص NOT NULL}
    B -->|نجاح| C{فحص CHECK}
    B -->|فشل| Z[خطأ، تراجع]
    C -->|نجاح| D{فحص UNIQUE}
    C -->|فشل| Z
    D -->|نجاح| E{فحص PRIMARY KEY}
    D -->|فشل| Z
    E -->|نجاح| F{فحص EXCLUSION}
    E -->|فشل| Z
    F -->|نجاح| G{توقيت القيد؟}
    F -->|فشل| Z
    G -->|IMMEDIATE| H[فحص FK فورًا]
    G -->|DEFERRED| I[تأجيل فحص FK حتى COMMIT]
    H -->|نجاح| J[اكتمال العبارة]
    I --> K[COMMIT]
    K --> L[فحص جميع FK المؤجلة]
    L -->|نجاح| M[إيداع المعاملة]
    L -->|فشل| Z

    style Z fill:#ffccbc
    style J fill:#c8e6c9
    style M fill:#c8e6c9

❓ أسئلة شائعة

س ما الفرق بين RESTRICT و NO ACTION؟
ج وظيفيًا متطابقان تقريبًا — كلاهما يرفض الحذف/التحديث. الفرق هو أن NO ACTION يمكن دمجه مع DEFERRABLE لتأجيل التحقق، بينما RESTRICT يتحقق دائمًا فورًا.
س هل يسمح قيد UNIQUE بعدة قيم NULL؟
ج في PostgreSQL، يسمح عمود UNIQUE بعدة قي�� NULL، لأن NULL != NULL. إذا كنت بحاجة إلى أن يكون NULL فريدًا أيضًا، أضف قيد NOT NULL.
س هل يمكن لقيد CHECK الإشارة إلى صفوف في جداول أخرى؟
ج يمكنك كتابة استعلام فرعي، لكن CHECK في PostgreSQL ي��من القيد للصف الحالي فقط — لا يضمن التناسق عبر الصفوف (قد تعدل جلسة أخرى البيانات المرجعية). للتناسق عبر الجداول، استخدم مفتاحًا خارجيًا.
س ما الفهرس الذي يحتاجه قيد EXCLUSION؟
ج يحتاج إلى فهرس GiST أو SP-GiST للدعم. يقوم PostgreSQL تلقائيًا بإنشاء الفهرس المقابل لقيد EXCLUSION.
س هل يمكن استخدام DEFERRABLE لقيود CHECK؟
ج لا. ينطبق DEFERRABLE فقط على قيود FOREIGN KEY و UNIQUE. يتم التحقق من CHECK و NOT NULL دائمًا فورًا.
س هل يؤثر حذف CASCADE الكبير على الأداء؟
ج نعم. تنفذ عمليات الحذف التعاقبي صفًا بصف وقد تولد قفلاً ثقيلاً وإدخال/إخراج. لعمليات الحذف الجماعية الكبيرة، يوصى بحذف بيانات الجدول الابن يدويًا أولاً، ثم حذف الصف الأب، لتجنب المعاملات الطويلة.

📖 ملخص


📝 تمارين

  1. ⭐ أنشئ جدولي customers و orders، عرف المفاتيح الأساسية والخارجية (ON DELETE CASCADE)، وأضف قيد CHECK يضمن أن مبلغ الطلب > 0.

  2. ⭐ أنشئ جدول products مع عمود SKU فريد وقيد CHECK يضمن السعر > 0 والخصم <= السعر.

  3. ⭐⭐ استخدم قيد EXCLUSION لإنشاء جدول room_bookings، مع ضمان عدم تداخل النطاقات الزمنية لنفس غرفة الاجتماعات، واختبر إدراجًا متعارضًا.

  4. ⭐⭐ أنشئ جدولين بمرجع متبادل (employees يشير إلى departments، و manager_id في departments يشير إلى employees)، واستخدم DEFERRABLE لحل المرجع الدائري.

  5. ⭐⭐⭐ صمم نموذج بيانات SaaS كامل للمستأجرين مع: جدول tenants، جدول users (تعاقب مفتاح خارجي)، جدول subscriptions (CHECK يتحقق من التواريخ والمبالغ)، جدول resource_booking (EXCLUSION يمنع تداخل الوقت)، وقم بتسمية جميع القيود.

Web-Tutorial.com

فريق Web-Tutorial التقني

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

100%