وقتی شما یک جدول در PostgreSQL میسازید، در واقع فقط “ظرفی برای دادهها” نمیسازید؛ بلکه باید مطمئن شوید دادهای که داخل آن میریزد، درست، سازگار و معتبر است.
اینجاست که Constraints وارد عمل میشوند — قوانینی که PostgreSQL بهطور خودکار اجرا میکند تا از خراب شدن دادهها جلوگیری کند.
در یک جمله:
«Constraints تضمین میکنند که فقط دادههای معتبر وارد جدول شوند.»
یعنی بهجای اعتماد به برنامهنویس یا اپلیکیشن، خود دیتابیس نگهبان دادههاست.
مثلاً:
| نوع Constraint | هدف | مثال ساده |
|---|---|---|
NOT NULL | جلوگیری از مقدار خالی | نام مشتری نباید خالی باشد |
CHECK | اعتبارسنجی شرطی | سن باید بیشتر از صفر باشد |
UNIQUE | یکتا بودن مقدار | ایمیل نباید تکراری باشد |
PRIMARY KEY | شناسهی یکتا و اجباری | شمارهی کاربر منحصر بهفرد باشد |
FOREIGN KEY | ارتباط بین جدولها | هر سفارش باید مشتری معتبر داشته باشد |
EXCLUSION | جلوگیری از همپوشانی دادهها | (در نوع خاصی از داده مثل زمانها) |
اگر ستونی را NOT NULL تعریف کنید، PostgreSQL اجازه نمیدهد مقدار خالی در آن قرار گیرد.
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
email TEXT
);
🔸 تلاش برای درج رکورد ناقص:
INSERT INTO users (email) VALUES ('test@example.com');
-- ERROR: null value in column "name" violates not-null constraint
گاهی میخواهید قانون خاصی روی مقدارها اعمال شود.
مثلاً سن باید بین ۰ و ۱۲۰ باشد.
CREATE TABLE people (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
age INT CHECK (age >= 0 AND age <= 120)
);
🔸 درج مقدار نامعتبر:
INSERT INTO people (name, age) VALUES ('Ali', -5);
-- ERROR: new row for relation "people" violates check constraint "people_age_check"
📘 نکته: میتوانید چند CHECK constraint روی یک جدول داشته باشید.
گاهی دو رکورد نباید مقدار تکراری در یک ستون داشته باشند (مثلاً ایمیل یا شماره ملی).
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
email TEXT UNIQUE
);
اگر دوباره همان ایمیل را درج کنید:
INSERT INTO employees (email) VALUES ('john@company.com');
INSERT INTO employees (email) VALUES ('john@company.com');
-- ERROR: duplicate key value violates unique constraint "employees_email_key"
🧠 PostgreSQL در پسزمینه برای UNIQUE، یک ایندکس خودکار میسازد.
PRIMARY KEY در واقع ترکیبی از دو Constraint است:
یعنی بهترین گزینه برای “شناسهی یکتا” در هر جدول.
CREATE TABLE products (
product_id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
📦 PostgreSQL خودش برای آن یک ایندکس B-tree میسازد.
اگر جدولها به هم وابسته باشند (مثل سفارش و مشتری)،
باید مطمئن شوید سفارش به مشتری واقعی اشاره دارد.
این کار را FOREIGN KEY انجام میدهد.
CREATE TABLE customers (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
customer_id INT REFERENCES customers(id)
);
🔸 اگر سعی کنید سفارشی برای مشتری ناموجود ثبت کنید:
INSERT INTO orders (customer_id) VALUES (999);
-- ERROR: insert or update on table "orders" violates foreign key constraint
✅ PostgreSQL از این طریق یکپارچگی ارجاعی (Referential Integrity) را حفظ میکند.
این نوع کمتر شناختهشده است ولی بسیار قدرتمند.
میگوید “این دو سطر نباید همزمان شرایط خاصی را داشته باشند.”
مثلاً اتاق رزرو شده نباید در بازهی زمانی تداخل داشته باشد:
CREATE TABLE reservations (
room INT,
during TSRANGE,
EXCLUDE USING GIST (room WITH =, during WITH &&)
);
⏰ یعنی دو رزرو نمیتوانند برای یک اتاق در بازهی زمانی همپوشان باشند.
PostgreSQL همهی Constraintها را در کاتالوگهای سیستمی ذخیره میکند:
SELECT conname, contype, conrelid::regclass
FROM pg_constraint
WHERE conrelid = 'orders'::regclass;
| ستون | توضیح |
|---|---|
conname | نام Constraint |
contype | نوع (p=primary, f=foreign, u=unique, c=check) |
conrelid | جدول مربوطه |
گاهی میخواهید Constraint فقط در پایان تراکنش بررسی شود، نه بلافاصله.
CREATE TABLE accounts (
id SERIAL PRIMARY KEY,
balance NUMERIC CHECK (balance >= 0) DEFERRABLE INITIALLY DEFERRED
);
در این حالت میتوانید در طول تراکنش موقتاً شرایط را نقض کنید و در انتها همه چیز بررسی شود.
| نوع Constraint | کارکرد اصلی | سطح کاربرد |
|---|---|---|
NOT NULL | مقدار نباید تهی باشد | پایه |
CHECK | شرط منطقی روی مقدار | اعتبارسنجی |
UNIQUE | جلوگیری از تکرار | یکپارچگی داده |
PRIMARY KEY | شناسهی یکتا | مدیریت رکورد |
FOREIGN KEY | ارتباط بین جدولها | یکپارچگی ارجاعی |
EXCLUSION | جلوگیری از تداخل | دادههای پیشرفته |
Constraints ستون فقرات یک طراحی درست در PostgreSQL هستند.
به شما کمک میکنند:
به بیان سادهتر:
Constraints همان نگهبانان وفادار PostgreSQL هستند که شبانهروز از یکپارچگی دادههای شما مراقبت میکنند. 🛡️