su-tudy 님의 블로그
제약조건 (Constraints) 본문
𖤐 제약조건과 무결성
제약조건은 테이블에 잘못된 데이터가 들어오지 못하도록 규칙을 거는 것이다. 데이터 무결성을 지키기 위한 장치라고 보면 된다. 테이블 생성할 때 걸 수도 있고, 나중에 ALTER로 추가할 수도 있다.
𖤐 정리 노트
✧ 제약조건 지정 방법
-- 테이블 생성할 때
CREATE TABLE table_name (
column1 datatype constraint,
column2 datatype constraint
);
-- 테이블 수정할 때
ALTER TABLE table_name
MODIFY COLUMN column_name datatype constraint;
✧ NOT NULL
NULL 값을 허용하지 않는다. 값이 반드시 입력돼야 하는 컬럼에 건다.
-- 생성할 때
CREATE TABLE users (
id INT NOT NULL,
name VARCHAR(50) NOT NULL
);
-- 수정할 때
ALTER TABLE users
MODIFY COLUMN name VARCHAR(50) NOT NULL;
✧ UNIQUE
컬럼의 모든 값이 중복 없이 고유해야 한다. NULL은 허용한다.
-- 생성할 때 (단일 컬럼)
CREATE TABLE users (
email VARCHAR(100) UNIQUE
);
-- 생성할 때 (여러 컬럼 조합에 UNIQUE, 제약조건 이름 지정)
CREATE TABLE users (
id INT,
email VARCHAR(100),
CONSTRAINT uq_user_email UNIQUE (id, email)
);
-- 수정할 때
ALTER TABLE users
ADD CONSTRAINT uq_user_email UNIQUE (email);
-- 삭제
ALTER TABLE users
DROP INDEX uq_user_email;
✧ PRIMARY KEY
테이블의 각 행을 고유하게 식별하는 기본 키다. PK = UNIQUE + NOT NULL이라고 이해하면 된다. 중복 불가, NULL 불가, 테이블당 딱 하나만 존재할 수 있다.
-- 생성할 때 (단일 컬럼)
CREATE TABLE users (
id INT NOT NULL,
name VARCHAR(50),
PRIMARY KEY (id)
);
-- 생성할 때 (복합 PK: 두 컬럼 조합이 PK)
CREATE TABLE orders (
order_id INT NOT NULL,
item_id INT NOT NULL,
quantity INT,
CONSTRAINT pk_orders PRIMARY KEY (order_id, item_id)
);
-- 수정할 때
ALTER TABLE users
ADD PRIMARY KEY (id);
-- 삭제
ALTER TABLE users
DROP PRIMARY KEY;
✧ FOREIGN KEY
다른 테이블의 PRIMARY KEY를 참조하는 키다. 테이블 간의 관계를 연결하고, 존재하지 않는 값이 들어오는 걸 막아준다.
- FK가 있는 테이블 → 자식 테이블
- PK가 있는 테이블 → 부모 테이블
-- 부모 테이블
CREATE TABLE users (
id INT NOT NULL,
name VARCHAR(50),
PRIMARY KEY (id)
);
-- 자식 테이블 (users의 id를 참조)
CREATE TABLE orders (
order_id INT NOT NULL,
user_id INT,
item VARCHAR(100),
PRIMARY KEY (order_id),
CONSTRAINT fk_orders_user
FOREIGN KEY (user_id) REFERENCES users(id)
);
-- 수정할 때 추가
ALTER TABLE orders
ADD CONSTRAINT fk_orders_user
FOREIGN KEY (user_id) REFERENCES users(id);
-- 삭제
ALTER TABLE orders
DROP FOREIGN KEY fk_orders_user;
▸ CASCADE 옵션
부모 테이블의 데이터가 변경되거나 삭제될 때 자식 테이블에도 자동으로 반영하는 옵션이다.
CONSTRAINT fk_orders_user
FOREIGN KEY (user_id) REFERENCES users(id)
ON DELETE CASCADE -- 부모 행 삭제 시 자식 행도 함께 삭제
ON UPDATE CASCADE -- 부모 PK 변경 시 자식 FK도 함께 변경
| 옵션 | 동작 |
CASCADE |
부모 변경/삭제 시 자식도 함께 변경/삭제 |
SET NULL |
부모 삭제 시 자식의 FK를 NULL로 변경 |
RESTRICT |
자식이 참조 중이면 부모 삭제/변경 불가 (기본값) |
NO ACTION |
RESTRICT와 동일 |
✧ CHECK
컬럼에 들어올 수 있는 값의 조건을 제한한다.
-- 생성할 때
CREATE TABLE users (
id INT NOT NULL,
age INT,
CONSTRAINT chk_age CHECK (age >= 0 AND age <= 150)
);
-- 수정할 때
ALTER TABLE users
ADD CONSTRAINT chk_age CHECK (age >= 0 AND age <= 150);
-- 삭제
ALTER TABLE users
DROP CHECK chk_age;
✧ DEFAULT
값이 입력되지 않았을 때 자동으로 채울 기본값을 지정한다.
-- 생성할 때
CREATE TABLE users (
id INT NOT NULL,
status VARCHAR(10) DEFAULT 'active',
created_at DATE DEFAULT CURRENT_DATE()
);
-- 수정할 때
ALTER TABLE users
ALTER status SET DEFAULT 'active';
-- 삭제
ALTER TABLE users
ALTER status DROP DEFAULT;
✧ 제약조건 이름 지정하는 이유
CONSTRAINT 이름 으로 제약조건에 이름을 붙이면 나중에 삭제하거나 수정할 때 이름으로 특정할 수 있다. 이름을 안 붙이면 DB가 자동으로 이름을 만드는데, 그 이름을 찾기가 번거롭다.
-- 이름 없이 → 나중에 삭제하려면 자동 생성된 이름을 찾아야 함
FOREIGN KEY (user_id) REFERENCES users(id)
-- 이름 지정 → 나중에 바로 삭제 가능
CONSTRAINT fk_orders_user FOREIGN KEY (user_id) REFERENCES users(id)
-- 삭제할 때
DROP FOREIGN KEY fk_orders_user;
✧ 제약조건 한눈에 비교
| 제약조건 | NULL 허용 | 중복 허용 | 테이블당 개수 |
| NOT NULL | ❌ | ✅ | 여러 개 |
| UNIQUE | ✅ | ❌ | 여러 개 |
| PRIMARY KEY | ❌ | ❌ | 1개만 |
| FOREIGN KEY | ✅ | ✅ | 여러 개 |
| CHECK | - | - | 여러 개 |
| DEFAULT | - | - | 여러 개 |
𖤐 체크포인트
🚨 PK 조건
PK는 UNIQUE + NOT NULL이지만 그냥 UNIQUE + NOT NULL을 걸어도 PK가 되는 건 아니다.
🚨 주의 — FK는 부모 테이블 먼저 만들어야 한다
자식 테이블이 참조할 부모 테이블이 먼저 존재해야 FK를 설정할 수 있다. 순서가 틀리면 에러가 난다.
🚨 주의 — CASCADE 옵션 신중하게 사용
ON DELETE CASCADE를 걸면 부모 행 하나 지울 때 연결된 자식 행이 전부 삭제된다. 편하지만 의도치 않게 대량 삭제가 일어날 수 있어서 신중하게 설정해야 한다.
𖤐 오늘의 한 줄 요약
제약조건은 잘못된 데이터가 테이블에 들어오는 걸 막는 규칙. PK는 UNIQUE + NOT NULL이고 테이블당 하나, FK는 테이블 간 관계를 연결. 제약조건엔 이름을 붙여두는 습관을 들이자.
'DBMS > Part 3. DDL' 카테고리의 다른 글
| CREATE, ALTER, DROP, RENAME, TRUNCATE (0) | 2024.10.12 |
|---|