외래 키 제약 조건 완벽 가이드: 참조 무결성 보장하기
데이터베이스 외래 키(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의 콘텐츠 팀입니다.
관련 포스트
비즈니스
탄탄한 DB 아키텍처로 시리즈 B 200억 투자 유치 성공
VC들이 가장 주목한 기술 경쟁력, 확장 가능한 DB 설계로 기업 가치 3배 인정받은 스타트업 사례입니다.
•3분 읽기
비즈니스
DB 설계로 스타트업 스케일링 성공: 유저 10배 증가 무장애 운영
처음부터 제대로 된 DB 설계로 유저 100만 돌파까지 리팩토링 없이 성공한 스타트업 사례입니다.
•4분 읽기
비즈니스
DB 최적화로 연간 서버 비용 12억 절감: 클라우드 비용 80% 감소
올바른 DB 설계와 최적화로 AWS 비용을 80% 절감하고 연간 12억을 아낀 중견 기업 사례입니다.
•4분 읽기