외래 키 제약 조건 완벽 가이드: 참조 무결성 보장하기

데이터베이스 외래 키(Foreign Key)와 제약 조건을 실전 예제로 배웁니다. CASCADE, SET NULL 등 다양한 옵션을 이해합니다.

럿지 AI 팀
4분 읽기

외래 키 완벽 가이드



외래 키란?



다른 테이블의 기본 키를 참조하는 컬럼

**목적:** 참조 무결성 보장

기본 예제



테이블 구조



``sql
-- 회원 테이블
CREATE TABLE members (
member_id INT PRIMARY KEY,
name VARCHAR(50)
);

-- 주문 테이블
CREATE TABLE orders (
order_id INT PRIMARY KEY,
member_id INT,
total_amount DECIMAL(10,2),
FOREIGN KEY (member_id) REFERENCES members(member_id)
);
`

외래 키 효과



`sql
-- ✓ 성공: member_id=1 존재
INSERT INTO orders (order_id, member_id, total_amount)
VALUES (1, 1, 50000);

-- ✗ 실패: member_id=999 없음
INSERT INTO orders (order_id, member_id, total_amount)
VALUES (2, 999, 30000);
-- ERROR: Cannot add or update a child row
`

CASCADE 옵션



ON DELETE CASCADE



`sql
CREATE TABLE orders (
order_id INT PRIMARY KEY,
member_id INT,
FOREIGN KEY (member_id) REFERENCES members(member_id)
ON DELETE CASCADE -- 회원 삭제 시 주문도 삭제
);

-- 회원 삭제
DELETE FROM members WHERE member_id = 1;
-- → orders의 관련 데이터도 자동 삭제!
`

ON UPDATE CASCADE



`sql
CREATE TABLE orders (
order_id INT PRIMARY KEY,
member_id INT,
FOREIGN KEY (member_id) REFERENCES members(member_id)
ON UPDATE CASCADE -- 회원 ID 변경 시 주문도 변경
);

-- 회원 ID 변경
UPDATE members SET member_id = 100 WHERE member_id = 1;
-- → orders의 member_id도 100으로 자동 변경!
`

SET NULL 옵션



`sql
CREATE TABLE orders (
order_id INT PRIMARY KEY,
member_id INT NULL, -- NULL 허용
FOREIGN KEY (member_id) REFERENCES members(member_id)
ON DELETE SET NULL
);

-- 회원 삭제
DELETE FROM members WHERE member_id = 1;
-- → orders의 member_id가 NULL로 변경
-- 주문 데이터는 유지!
`

RESTRICT / NO ACTION



`sql
CREATE TABLE orders (
order_id INT PRIMARY KEY,
member_id INT,
FOREIGN KEY (member_id) REFERENCES members(member_id)
ON DELETE RESTRICT -- 삭제 차단
);

-- 회원 삭제 시도
DELETE FROM members WHERE member_id = 1;
-- ERROR: Cannot delete - 참조 중!

-- 먼저 주문 삭제해야 함
DELETE FROM orders WHERE member_id = 1;
DELETE FROM members WHERE member_id = 1;
-- ✓ 성공
`

옵션 비교



| 옵션 | 부모 삭제 시 | 사용 사례 |
|------|------------|---------|
| CASCADE | 자식도 삭제 | 게시글-댓글 |
| SET NULL | NULL로 변경 | 회원-주문 (회원 탈퇴 후 주문 보존) |
| RESTRICT | 삭제 차단 | 카테고리-상품 |
| NO ACTION | 삭제 차단 | RESTRICT와 동일 |

실전 예제



Case 1: 게시판 (CASCADE)



`sql
-- 게시글 삭제 시 댓글도 삭제
CREATE TABLE posts (
post_id INT PRIMARY KEY,
title VARCHAR(200)
);

CREATE TABLE comments (
comment_id INT PRIMARY KEY,
post_id INT,
content TEXT,
FOREIGN KEY (post_id) REFERENCES posts(post_id)
ON DELETE CASCADE
);
`

Case 2: 회원-주문 (SET NULL)



`sql
-- 회원 탈퇴해도 주문 이력 보존
CREATE TABLE members (
member_id INT PRIMARY KEY,
email VARCHAR(100)
);

CREATE TABLE orders (
order_id INT PRIMARY KEY,
member_id INT NULL,
FOREIGN KEY (member_id) REFERENCES members(member_id)
ON DELETE SET NULL
);
`

Case 3: 카테고리-상품 (RESTRICT)



`sql
-- 카테고리에 상품 있으면 삭제 불가
CREATE TABLE categories (
category_id INT PRIMARY KEY,
name VARCHAR(50)
);

CREATE TABLE products (
product_id INT PRIMARY KEY,
category_id INT,
FOREIGN KEY (category_id) REFERENCES categories(category_id)
ON DELETE RESTRICT
);
`

복합 외래 키



`sql
CREATE TABLE order_items (
order_id INT,
product_id INT,
quantity INT,
PRIMARY KEY (order_id, product_id),
FOREIGN KEY (order_id) REFERENCES orders(order_id),
FOREIGN KEY (product_id) REFERENCES products(product_id)
);
`

외래 키 추가/삭제



기존 테이블에 추가



`sql
ALTER TABLE orders
ADD FOREIGN KEY (member_id) REFERENCES members(member_id)
ON DELETE CASCADE;
`

외래 키 삭제



`sql
-- 외래 키 이름 확인
SHOW CREATE TABLE orders;

-- 삭제
ALTER TABLE orders
DROP FOREIGN KEY orders_ibfk_1;
`

외래 키 이름 지정



`sql
ALTER TABLE orders
ADD CONSTRAINT fk_orders_member
FOREIGN KEY (member_id) REFERENCES members(member_id)
ON DELETE CASCADE;
`

CHECK 제약 조건



`sql
CREATE TABLE products (
product_id INT PRIMARY KEY,
price DECIMAL(10,2) CHECK (price >= 0), -- 가격 0 이상
stock INT CHECK (stock >= 0) -- 재고 0 이상
);

-- ✗ 실패
INSERT INTO products (product_id, price, stock)
VALUES (1, -1000, 10);
-- ERROR: Check constraint violated
`

UNIQUE 제약 조건



`sql
CREATE TABLE members (
member_id INT PRIMARY KEY,
email VARCHAR(100) UNIQUE -- 중복 불가
);

-- ✗ 실패: 중복 이메일
INSERT INTO members VALUES (1, 'test@example.com');
INSERT INTO members VALUES (2, 'test@example.com');
-- ERROR: Duplicate entry
`

성능 고려



인덱스 자동 생성



`sql
-- 외래 키는 자동으로 인덱스 생성
FOREIGN KEY (member_id) REFERENCES members(member_id)
-- → member_id에 인덱스 자동 생성
`

대량 데이터 입력 시



`sql
-- 임시로 외래 키 체크 비활성화
SET FOREIGN_KEY_CHECKS=0;

-- 대량 INSERT
INSERT INTO orders ...;

-- 다시 활성화
SET FOREIGN_KEY_CHECKS=1;
``

더 배우기



김영한의 실전 데이터베이스
- 제약 조건 심화
- 실전 설계 패턴
- 성능 최적화

---

**태그**: #외래키 #ForeignKey #제약조건 #참조무결성 #CASCADE

L

럿지 AI 팀

AI 기술과 비즈니스 혁신을 선도하는 럿지 AI의 콘텐츠 팀입니다.