외래키를 사용하지 않는 이유 - ttasjwi/board-system GitHub Wiki
외래키
- 데이터베이스에서 두 테이블 간의 관계를 정의하고 무결성을 데이터베이스 수준에서 보장하기 위해서 '외래키' 를 사용한다.
- 데이터의 일관성과 무결성이 보장되지만, 몇 가지 단점 또는 고려사항이 생긴다.
문제점
데이터 추가/수정 시 성능 저하
- 외래키를 사용하게 되면 데이터 생성 및 수정시 항상 무결성 검사를 하게 된다.
- 예를 들면, 자식 테이블에 데이터를 추가할 때 부모 테이블에 pk가 존재하는지를 확인한다.
- 이러한 무결성 검사의 선행은 insert/update 에 대한 성능 저하를 일으킨다.
데이터 삭제 관점
- 외래키로 참조되는 테이블의 데이터를 삭제하려고 할 때, 그 데이터를 참조하는 다른 테이블의 데이터가 존재하면 삭제가 불가능하다.
- 예를 들어, 게시글을 삭제하려는데 그 게시글에 대한 '게시글 좋아요' 데이터가 있으면 삭제가 불가능하다.
- 이를 '캐스캐이드 삭제' 옵션으로 해결할 수 있지만, 잘못된 설정으로 데이터 손실의 위험이 있다.
데이터 이관 문제
- 외래키 관계가 설정된 테이블의 데이터를 다른 데이터베이스나 시스템으로 이관할 때 순서와 방법을 신중히 고려해야한다.
- 테이블 생성과정에서 자식 테이블 생성은 부모 테이블 생성을 선행으로 수행해야한다.
- 단순히 한 두 테이블의 관계면 간단할 수 있지만, 테이블 선행 관계가 2-3단계 이상 엮이거나 부모-자식 관계가 여럿이라면 더 복잡해진다.
맥락의 경계 관점
- 게시글을 삭제하려는데, 그 게시글을 의존하는 게시글의 좋아요가 삭제되어야한다면 게시글 삭제 기능 구현 과정에서 게시글 좋아요를 삭제하는 로직을 작성해야한다.
- 게시글 맥락 관점에서 게시글 좋아요 개념과 강하게 결합된다.
- 게시글 기능과 게시글 좋아요 기능이 어느 정도는 독립적으로 성장해야하는데, 이들이 강하게 결합되어 있다면 이들은 독립적으로 성장하기 힘든 구조가 된다.
해결안
- 외래키를 사용하지 않는다.
- 대신, 무결성을 애플리케이션 레벨에서 제어하도록 한다.