Хязгаарлалт (PRIMARY KEY, UNIQUE, NOT NULL)
Өгөгдлийн санд буруу, давтагдсан, хоосон мэдээлэл орохоос сэргийлэхийн тулд constraint буюу хязгаарлалт ашиглана. Constraint нь хүснэгтийн "дүрэм" юм — энэ дүрмийг зөрчсөн ямар ч бичлэг орохыг PostgreSQL автоматаар татгалздаг. Мэдээллийн чанарыг хамгаалах хамгийн найдвартай арга бол code дотор биш, өгөгдлийн санд хязгаарлалт тавих явдал.
NOT NULL — хоосон байж болохгүй
NOT NULL нь тухайн баганад NULL утга орохыг хориглодог хамгийн энгийн хязгаарлалт:
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
нэр TEXT NOT NULL, -- заавал байх ёстой
имэйл TEXT NOT NULL, -- заавал байх ёстой
утас TEXT -- NULL байж болно (заасаагүй)
);
NOT NULL зөрчвөл:
INSERT INTO users (нэр) VALUES ('Болд');
-- ERROR: null value in column "имэйл" of relation "users"
-- violates not-null constraint
Одоо байгаа баганад NOT NULL нэмэх:
ALTER TABLE users ALTER COLUMN утас SET NOT NULL;
-- Хасах
ALTER TABLE users ALTER COLUMN утас DROP NOT NULL;
PRIMARY KEY — давтагдашгүй танигч
PRIMARY KEY нь хүснэгтийн хамгийн чухал хязгаарлалт юм. Хоёр шаардлагыг нэгэн зэрэг биелүүлнэ: NOT NULL ба UNIQUE. Хүснэгт бүрт яг нэг PRIMARY KEY байна.
-- SERIAL + PRIMARY KEY хамтдаа
CREATE TABLE products (
id BIGSERIAL PRIMARY KEY,
нэр TEXT NOT NULL
);
-- Эсвэл доор тусдаа зарлах хэлбэр
CREATE TABLE products (
id BIGINT GENERATED ALWAYS AS IDENTITY,
нэр TEXT NOT NULL,
CONSTRAINT products_pkey PRIMARY KEY (id)
);
Нийлмэл primary key — хоёр баганын хослол давтагдашгүй байх:
CREATE TABLE lesson_progress (
user_id INTEGER NOT NULL,
lesson_id INTEGER NOT NULL,
дууссан BOOLEAN DEFAULT FALSE,
PRIMARY KEY (user_id, lesson_id) -- хоёулаа хамтдаа давтагдахгүй
);
UNIQUE — давтагдашгүй утга
UNIQUE нь тухайн баганын утга хүснэгтэд давтагдахгүй байхыг баталгаажуулна. PRIMARY KEY-с ялгаатай нь NULL утга зөвшөөрдөг (NULL ≠ NULL тул хэд хэдэн NULL байж болно):
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
имэйл TEXT UNIQUE NOT NULL,
утас TEXT UNIQUE -- NULL байж болно, гэхдээ утга байвал давтагдахгүй
);
UNIQUE зөрчвөл:
INSERT INTO users (имэйл) VALUES ('bold@example.com');
INSERT INTO users (имэйл) VALUES ('bold@example.com');
-- ERROR: duplicate key value violates unique constraint "users_имэйл_key"
-- DETAIL: Key (имэйл)=(bold@example.com) already exists.
Нийлмэл unique — хоёр баганын хослол давтагдахгүй:
CREATE TABLE enrollments (
user_id INTEGER NOT NULL,
course_id INTEGER NOT NULL,
UNIQUE (user_id, course_id) -- нэг хэрэглэгч нэг курст нэг удаа л бүртгэгдэнэ
);
CHECK — нөхцөлт хязгаарлалт
CHECK нь баганын утга тодорхой нөхцөлийг хангаж байхыг шаарддаг:
CREATE TABLE products (
id BIGSERIAL PRIMARY KEY,
нэр TEXT NOT NULL,
үнэ NUMERIC(10,2) CHECK (үнэ >= 0),
нөөц INTEGER CHECK (нөөц >= 0),
үнэлгээ SMALLINT CHECK (үнэлгээ BETWEEN 1 AND 5)
);
Нэрлэсэн CHECK constraint:
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
нас INTEGER,
CONSTRAINT нас_хүчин_төгөлдөр CHECK (нас >= 0 AND нас <= 150)
);
CHECK зөрчвөл:
INSERT INTO products (нэр, үнэ) VALUES ('Бараа', -500);
-- ERROR: new row for relation "products" violates check constraint "products_үнэ_check"
DEFAULT — өгөгдмөл утга
DEFAULT нь хязгаарлалт биш боловч constraint-уудтай хамт байнга ашиглагддаг. Утга оруулаагүй үед автоматаар тавигдах утга тодорхойлно:
CREATE TABLE posts (
id BIGSERIAL PRIMARY KEY,
гарчиг TEXT NOT NULL,
нийтлэгдсэн BOOLEAN DEFAULT FALSE,
харагдсан INTEGER DEFAULT 0,
үүсгэсэн TIMESTAMPTZ DEFAULT NOW(),
статус TEXT DEFAULT 'draft' CHECK (статус IN ('draft', 'published', 'archived'))
);
Одоо байгаа хүснэгтэд constraint нэмэх
-- UNIQUE нэмэх
ALTER TABLE users
ADD CONSTRAINT users_утас_unique UNIQUE (утас);
-- CHECK нэмэх
ALTER TABLE products
ADD CONSTRAINT үнэ_эерэг CHECK (үнэ > 0);
-- Constraint хасах
ALTER TABLE products
DROP CONSTRAINT үнэ_эерэг;
Бүх constraint-уудыг нэгтгэсэн жишээ
CREATE TABLE orders (
id BIGSERIAL PRIMARY KEY,
user_id INTEGER NOT NULL,
нийт_үнэ NUMERIC(12,2) NOT NULL CHECK (нийт_үнэ > 0),
статус TEXT NOT NULL DEFAULT 'pending'
CHECK (статус IN ('pending','processing','shipped','delivered','cancelled')),
хаяг TEXT NOT NULL,
үүсгэсэн TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE (id, user_id)
);
Constraint нь хөгжүүлэгчийн алдааг хамгаалдаг хамгийн зардал багатай хамгаалалт — код бичихдээ заавал ашиглах дадал болго.
Дараагийн хичээлд:
Хүснэгтүүдийг хоорондоо холбох FOREIGN KEY хязгаарлалтыг сурч — харилцаат өгөгдлийн санг зөв бүтцэлэх үндэс суурийг тавина.