Backend · Infra

[MySQL InnoDB] 외래키(Foreign Key) 설정 시 주의사항

devhyen 2025. 6. 16. 13:32

외래키 (Foreign Key) 란

하나의 테이블이 다른 테이블의 기본키(Primary Key)를 참조하도록 설정하는 제약조건이다. 

이를 통해 데이터 무결성 보장하고 논리적 관계 (부모- 자식 관계)명확히 할 수 있다.

더보기
더보기

예) 댓글 테이블이 게시글 테이블의 ID를 참조하는 구조 → 댓글은 반드시 유효한 게시글에만 달림

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가 수정되면, 자식이 그것을 참조 중일 경우 에러 발생
  • 참조되는 값을 바꿀 수 없다!
  • 데이터 정합성을 위해 수정 자체를 막는다

실무에서 삭제 처리 로직 

  1. 사용자 삭제 요청 
  2. 소프트 삭제 처리
    • is_delete = true, deleted_at = now() 등으로 논리적으로만 삭제 
  3. 비즈니스 조건 검토 
    • 일정 기간 동안 복구가 가능하도록 유지 (ex. 30일 유예)
  4. 배치로 물리적 삭제 
    • 주기적으로 배치 작업으로 deleted_at + 일정 기간 기준이 지난 데이터 실제로 DELETE
이렇게 했을 때 사용자 복구 요청 시 즉시 복원 가능하고 실수를 방지할 수 있고 감사 로그/이력 관리가 쉽다는 이점이 있다.
🎁 일부 민감 정보는 deleted_at 과 관계없이 바로 마스킹 처리를 하기도 한다. (개인정보 같은 경우) 

 

외래키 에러 예시

Cannot delete or update a parent row: a foreign key constraint fails

위 에러는 ON DELETE RESTRICT 또는 자식 레코드가 존재하는 상태에서 부모를 삭제하는 경우 발생합니다.

자식을 먼저 삭제하거나 ON DELETE CASCADE 옵션을 확인할 필요가 있습니다.