외래키 (Foreign Key) 란
하나의 테이블이 다른 테이블의 기본키(Primary Key)를 참조하도록 설정하는 제약조건이다.
이를 통해 데이터 무결성 보장하고 논리적 관계 (부모- 자식 관계) 를 명확히 할 수 있다.
InnoDB 스토리지 엔진
MySQL에서 여러 스트로지 엔진을 지원하지만, 외래키 기능은 InnoDB엔진에서만 동작한다.
다른 엔진에서는 외래키 제약조건이 무시되고 작동하지 않는다.
외래키를 사용하려면 반드시 ENGINE=InnoDB 를 명시해야 한다.
CREATE TABLE post (
id INT PRIMARY KEY AUTO_INCREMENT
) ENGINE=InnoDB;
다른 DB 중에는?
InnoDB는 MySQL에서 사용되는 기본 스토리지 엔진이고, 아래 DB 들은 이를 기반으로 하거나 호환된다.
- MariaDB(10.2 이상은 InnoDB를 기본사용)
- Percona Server for MySQL
- Amazon RDS (MySQL 호환모드)
- Google Cloud SQL (MySQL 호환모드)
기본구조
-- 부모 테이블 (참조 대상)
CREATE TABLE parent (
id INT PRIMARY KEY
);
-- 자식 테이블 (외래 키 보유)
CREATE TABLE child (
id INT PRIMARY KEY,
parent_id INT,
FOREIGN KEY (parent_id) REFERENCES parent(id)
ON DELETE CASCADE
ON UPDATE RESTRICT
);
관계용어
용어 | 설명 |
참조 개체 (Referenced Table) | 외래 키가 참조하는 테이블 → 보통 부모 역할 |
외래키 (Foreign Key) | 참조 대상의 PRIMARY KEY 를 참조 |
제약조건 (Constraint) | 부모 - 자식 관계에서의 동기화 또는 제어 규칙 |
ON DELETE CASCADE
- 부모가 삭제 될 때, 자식도 자동 삭제
- 개발 시 실수로 부모 삭제하면 모든 자식이 사라지기 때문에 위험!
- 삭제전 반드시 트랜잭션 또는 확인 로직 필요
ON UPDATE RESTRICT
- 부모 id가 수정되면, 자식이 그것을 참조 중일 경우 에러 발생
- 참조되는 값을 바꿀 수 없다!
- 데이터 정합성을 위해 수정 자체를 막는다
실무에서 삭제 처리 로직
- 사용자 삭제 요청
- 소프트 삭제 처리
- is_delete = true, deleted_at = now() 등으로 논리적으로만 삭제
- 비즈니스 조건 검토
- 일정 기간 동안 복구가 가능하도록 유지 (ex. 30일 유예)
- 배치로 물리적 삭제
- 주기적으로 배치 작업으로 deleted_at + 일정 기간 기준이 지난 데이터 실제로 DELETE
이렇게 했을 때 사용자 복구 요청 시 즉시 복원 가능하고 실수를 방지할 수 있고 감사 로그/이력 관리가 쉽다는 이점이 있다.
🎁 일부 민감 정보는 deleted_at 과 관계없이 바로 마스킹 처리를 하기도 한다. (개인정보 같은 경우)
외래키 에러 예시
Cannot delete or update a parent row: a foreign key constraint fails
위 에러는 ON DELETE RESTRICT 또는 자식 레코드가 존재하는 상태에서 부모를 삭제하는 경우 발생합니다.
자식을 먼저 삭제하거나 ON DELETE CASCADE 옵션을 확인할 필요가 있습니다.
'Backend · Infra' 카테고리의 다른 글
Figma 살 돈이없다면? Penpot self-hosting으로 대체하자 (3) | 2025.07.21 |
---|---|
MySQL부터 Qdrant 까지 DB 종류 한눈에 보기 (1) | 2025.07.09 |
docker 를 티기고 티기는 WSL(Ubuntu) + docker cli + git에 이미지 올리기 (0) | 2025.05.12 |
OIDC란? Ory를 활용한 인증 알아보기 (0) | 2025.02.11 |
Docker 인증서 오류(x509) 해결기: SSL 인증서와의 전쟁 (0) | 2025.02.07 |