MySQL / Constraint (PRIMARY KEY, NOT NULL)

Constraint (PRIMARY KEY, NOT NULL)

Constraint бол хүснэгтэд оруулах өгөгдөлд тавих дүрэм юм. MySQL-ийн constraint-үүд буруу өгөгдлийг аппликейшн кодын оронд өгөгдлийн сангийн түвшинд блоклоно — энэ нь өгөгдлийн бүрэн бүтэн байдлыг хамгийн найдвартай хангах арга.

NOT NULL

Багана заавал утгатай байх ёстой — NULL хадгалагдахгүй.

sql
CREATE TABLE users (
  id    INT          NOT NULL,
  name  VARCHAR(100) NOT NULL,
  phone VARCHAR(20)           -- NULL байж болно (анхдагч)
);

NOT NULL баганад NULL оруулахыг оролдвол:

sql
INSERT INTO users (id, name, phone) VALUES (1, NULL, '99001234');
-- ERROR 1048: Column 'name' cannot be null

UNIQUE

Баганын утга хүснэгт дотор давтагдахгүй байхыг хангана.

sql
CREATE TABLE users (
  id       INT          NOT NULL,
  email    VARCHAR(255) NOT NULL UNIQUE,
  username VARCHAR(50)  UNIQUE          -- NULL байж болно, давтагдахгүй
);

Давтагдсан утга оруулахыг оролдвол:

sql
INSERT INTO users (id, email) VALUES (2, 'bold@example.com');
-- ERROR 1062: Duplicate entry 'bold@example.com' for key 'email'

UNIQUE ба NULL: MySQL-д NULL утгууд давтагдах боломжтой — NULL нь "мэдэгдэхгүй" утгыг илэрхийлэх тул хоёр NULL тэнцүү биш гэж үзнэ.

Олон баганын UNIQUE

Хоёр баганын хослол давтагдахгүй байхыг хангах:

sql
CREATE TABLE lesson_progress (
  user_id    INT NOT NULL,
  lesson_slug VARCHAR(100) NOT NULL,
  UNIQUE (user_id, lesson_slug)   -- нэг хэрэглэгч нэг хичээлийг давтахгүй
);

PRIMARY KEY

Мөр бүрийг өвөрмөцөөр таньдаг үндсэн түлхүүр. NOT NULL + UNIQUE-ийн хослол — нэмж хурдан хайлт хийх index автоматаар үүснэ.

sql
-- Нэг багана
CREATE TABLE users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(100) NOT NULL
);

-- Олон баганын Primary Key (composite)
CREATE TABLE order_items (
  order_id   INT NOT NULL,
  product_id INT NOT NULL,
  quantity   INT NOT NULL DEFAULT 1,
  PRIMARY KEY (order_id, product_id)
);

Хүснэгт бүр нэг л PRIMARY KEY агуулж болно.


DEFAULT

Утга оруулаагүй үед хэрэглэгдэх анхдагч утга:

sql
CREATE TABLE products (
  id         INT            AUTO_INCREMENT PRIMARY KEY,
  name       VARCHAR(200)   NOT NULL,
  stock      INT            DEFAULT 0,
  is_active  BOOLEAN        DEFAULT TRUE,
  rating     DECIMAL(3,1)   DEFAULT 0.0,
  created_at TIMESTAMP      DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP      DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

ON UPDATE CURRENT_TIMESTAMP — мөр өөрчлөгдөх бүрд updated_at автоматаар шинэчлэгдэнэ.


CHECK

Баганын утга тодорхой нөхцөлийг хангах ёстой гэдгийг заана. MySQL 8.0.16-аас хойш бүрэн дэмжигдсэн.

sql
CREATE TABLE products (
  id       INT            AUTO_INCREMENT PRIMARY KEY,
  name     VARCHAR(200)   NOT NULL,
  price    DECIMAL(10,2)  NOT NULL,
  stock    INT            DEFAULT 0,
  rating   DECIMAL(3,1)   DEFAULT 0.0,

  CONSTRAINT chk_price  CHECK (price > 0),
  CONSTRAINT chk_stock  CHECK (stock >= 0),
  CONSTRAINT chk_rating CHECK (rating BETWEEN 0.0 AND 5.0)
);

CHECK зөрчвөл:

sql
INSERT INTO products (name, price) VALUES ('Бараа', -100);
-- ERROR 3819: Check constraint 'chk_price' is violated.

CONSTRAINT нэр өгөх

Constraint-д нэр өгвөл алдааны мессеж илүү тодорхой болж, дараа нь устгах, өөрчлөхөд хялбар болно:

sql
CREATE TABLE users (
  id       INT          AUTO_INCREMENT,
  email    VARCHAR(255) NOT NULL,
  username VARCHAR(50),

  CONSTRAINT pk_users        PRIMARY KEY (id),
  CONSTRAINT uq_users_email  UNIQUE (email),
  CONSTRAINT uq_users_uname  UNIQUE (username)
);

Нэрлэлтийн заншил: pk_ (primary key), uq_ (unique), chk_ (check), fk_ (foreign key) угтвар ашиглах.


ALTER TABLE-д constraint нэмэх

Хүснэгт аль хэдийн үүссэн байхад constraint нэмж болно:

sql
-- NOT NULL нэмэх (MODIFY ашигладаг)
ALTER TABLE users
  MODIFY COLUMN phone VARCHAR(20) NOT NULL;

-- UNIQUE нэмэх
ALTER TABLE users
  ADD CONSTRAINT uq_users_phone UNIQUE (phone);

-- CHECK нэмэх
ALTER TABLE products
  ADD CONSTRAINT chk_price CHECK (price > 0);

-- PRIMARY KEY нэмэх
ALTER TABLE old_table
  ADD CONSTRAINT pk_old PRIMARY KEY (id);

Constraint устгах

sql
-- UNIQUE устгах
ALTER TABLE users
  DROP INDEX uq_users_phone;

-- CHECK устгах
ALTER TABLE products
  DROP CHECK chk_price;

-- PRIMARY KEY устгах
ALTER TABLE users
  DROP PRIMARY KEY;

Байгаа constraint-үүдийг харах

sql
-- Хүснэгтийн бүтэц + constraint-үүд
SHOW CREATE TABLE products;

-- information_schema-аас харах
SELECT
  CONSTRAINT_NAME,
  CONSTRAINT_TYPE
FROM information_schema.TABLE_CONSTRAINTS
WHERE TABLE_NAME = 'products'
  AND TABLE_SCHEMA = DATABASE();

Жишээ: бүрэн тодорхойлолттой хүснэгт

sql
CREATE TABLE profiles (
  id          INT              AUTO_INCREMENT,
  user_id     INT              NOT NULL,
  username    VARCHAR(30)      NOT NULL,
  xp          INT              NOT NULL DEFAULT 0,
  streak      INT              NOT NULL DEFAULT 0,
  level       TINYINT UNSIGNED NOT NULL DEFAULT 1,
  bio         VARCHAR(300),
  created_at  TIMESTAMP        NOT NULL DEFAULT CURRENT_TIMESTAMP,

  CONSTRAINT pk_profiles      PRIMARY KEY (id),
  CONSTRAINT uq_profiles_uid  UNIQUE (user_id),
  CONSTRAINT uq_profiles_name UNIQUE (username),
  CONSTRAINT chk_xp           CHECK (xp >= 0),
  CONSTRAINT chk_streak       CHECK (streak >= 0),
  CONSTRAINT chk_level        CHECK (level BETWEEN 1 AND 100)
);

Дараагийн хичээлд:

Foreign key — хүснэгтүүдийн хоорондын холбоо тогтоох, ON DELETE CASCADE/SET NULL/RESTRICT тохируулах аргуудыг үзнэ.