DB

[MySQL] DML과 FOREIGN KEY 제약조건 관리 완전 정복 🔗

인생아 2025. 7. 3. 17:19
반응형

MySQL에서 데이터 무결성을 유지하기 위해 가장 핵심적인 제약조건 중 하나는 FOREIGN KEY(외래 키)이다.
이 제약조건은 INSERT, UPDATE, DELETE 같은 DML(데이터 조작어) 명령어 실행 시 매우 중요한 역할을 한다.
하지만 잘못된 설정이나 이해 부족으로 인해 외래 키 에러를 자주 만나게 된다.

🧱 FOREIGN KEY란?

외래 키(Foreign Key)는 한 테이블의 컬럼이 다른 테이블의 기본 키(Primary Key) 또는 유니크 키를 참조하도록 강제하는 제약조건이다.
이 제약조건은 데이터 간의 관계(Relationship)를 표현하고, 데이터의 정합성(무결성)을 보장한다.

CREATE TABLE orders (
  id INT PRIMARY KEY,
  user_id INT,
  FOREIGN KEY (user_id) REFERENCES users(id)
);

위 예제에서 orders.user_id는 users.id를 참조하고 있다.
즉, users 테이블에 존재하지 않는 사용자의 주문을 추가할 수 없도록 막는다.

반응형

💥 DML 명령어에서 발생할 수 있는 외래 키 오류

1️⃣ INSERT 오류

INSERT INTO orders (id, user_id) VALUES (1, 999);

→ users 테이블에 id = 999가 없으면 foreign key constraint fails 에러가 발생한다.

2️⃣ UPDATE 오류

UPDATE orders SET user_id = 1234 WHERE id = 1;

→ user_id를 users에 존재하지 않는 값으로 바꾸면 외래 키 위반으로 실패한다.

3️⃣ DELETE 오류

DELETE FROM users WHERE id = 2;

→ 만약 orders 테이블에서 user_id = 2가 사용 중이면 삭제할 수 없으며 에러 발생

🔧 해결 방법: 외래 키 행동 옵션

외래 키 제약조건을 정의할 때 ON DELETE, ON UPDATE 옵션을 통해 연쇄 행동을 지정할 수 있다.

옵션 설명
CASCADE 참조된 키가 삭제/수정되면, 종속된 테이블의 데이터도 함께 삭제/수정됨
SET NULL 참조된 키가 삭제/수정되면, 외래 키를 NULL로 설정
RESTRICT 참조된 키가 사용 중이면, 삭제/수정 불가능 (기본값)
NO ACTION RESTRICT와 같지만 트랜잭션 상황에 따라 동작 다름
CREATE TABLE orders (
  id INT PRIMARY KEY,
  user_id INT,
  FOREIGN KEY (user_id) REFERENCES users(id)
  ON DELETE CASCADE
  ON UPDATE CASCADE
);

→ 부모 테이블의 사용자가 삭제되면 관련 주문도 자동으로 삭제된다.

반응형

⚠️ 실무 주의사항

  • ON DELETE CASCADE는 매우 강력하므로, 설계 시 주의가 필요하다. 실수로 전체 데이터가 삭제될 수 있다.
  • SET NULL을 사용하려면 외래 키 컬럼이 NULL을 허용해야 한다.
  • 외래 키가 여러 개 연결된 경우, 트랜잭션 충돌이 날 수 있으므로 트랜잭션 사용 시 순서에 주의해야 한다.

✍️ 실습 예제: 외래 키와 함께 사용하는 INSERT / DELETE

사용자 테이블

CREATE TABLE users (
  id INT PRIMARY KEY,
  name VARCHAR(50)
);

주문 테이블

CREATE TABLE orders (
  id INT PRIMARY KEY,
  user_id INT,
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

예제 실행

INSERT INTO users (id, name) VALUES (1, 'Alice');
INSERT INTO orders (id, user_id) VALUES (100, 1);
DELETE FROM users WHERE id = 1;

→ Alice가 삭제되면서 orders 테이블의 주문도 함께 삭제된다. (CASCADE 효과)

🧠 FOREIGN_KEY_CHECKS로 제약 일시 해제

개발 환경에서 제약을 일시적으로 끄고 싶을 때 사용

SET foreign_key_checks = 0;
DELETE FROM users WHERE id = 1;
SET foreign_key_checks = 1;

주의: 실제 운영 환경에서는 사용 지양. 데이터 무결성이 깨질 수 있다.

📚 참고 자료

공식 문서: MySQL FOREIGN KEY Constraints

반응형