3차 프로젝트 진행 중에 DB 모델링에 관해 흥미로운 사실을 알게 되었다.
바로 외래키를 사용하지 않는다
는 것이었다...!
지금까지 DB모델링을 해오면서 서로 관계되어있는 테이블은 외래키로 엮어주는 것이 필수처럼 여겨졌었는데 그걸 하지 않는다니.. 정말 신선한 충격이었다.
PM님의 말씀으로는 제약조건이 있으면 데이터 수정이 까다롭기 때문에 현업에서는 잘쓰지 않는다고 하셨는데, 보다 더 정확히 이해하기 위해 이에 대해 조사를 해보았다.
외래키를 사용하게 되면 데이터 생성 및 수정시 항상 무결성 검사를 하게 된다. 예를 들어 자식 테이블에 데이터를 추가할 때 부모 테이블에 pk가 존재하는지를 확인하는 것이다. 이러한 무결성 검사의 선행은 insert/update에 대한 성능 저하를 일으킨다.
외래키를 사용하면 몇가지 번거로움이 생긴다.
자식 테이블에 데이터 생성시 부모 데이터에 row가 미리 생성되어 있어야 한다던지, 데이터 수정 및 삭제 시 데이터의 정합성 유지를 위해 데이터 수정에 순서가 필요한다던지 하는 것들이다.
추가로 프로그램의 로직이 바뀌거나 서비스가 확장되었을 때 이 외래키의 제약조건때문에 에러가 일어날 수 있다.
이러한 번거로움때문에 확장성 및 개발 편의성을 위해서라도 외래키를 사용하지 않고 애플리케이션 단에서 데이터의 무결성을 보장하도록 하는 것이다.
사실 테스트 데이터를 포함한 데이터 생성 및 수정에 관한 불편함은 개발 단계에서 제약조건을 비활성화해놓음으로써 해결이 되고, 프로그램 단에서 무결성을 검사하는 것 또한 db 무결성 검사를 하는 것과 비교하면 유의미할 정도의 속도차이는 안난다고 한다. 이걸 보면 결국에는 조금 더 쉽게 개발하자고 외래키를 쓰지 않는 경우가 대부분인것 같다.
하지만 RDBMS라는건 테이블 간 관계를 표현함은 물론 연관된 데이터에 대한 무결성 검사를 해주기 때문에 사용하는 건데, 단순히 편의를 위해 외래키를 사용하지 않는다는 것이 조금 의아하긴 하다.
우리 프로젝트에서는 데이터 수정 시 발생할 수 있는 정합성 문제를 최소화하고 미래에 개발팀 및 서비스가 확장되었을 때의 구조 변경 편의성을 고려하여 외래키를 쓰지 않는다고 하니 외래키 없이 테이블의 관계를 표현하고 무결성을 검사하는 로직을 추가하는 식의 개발을 해볼 수 있을 것 같다.
이에 대한 업데이트가 생긴다면 추후에 글을 또 작성해보도록 하겠다.
Foreign Key 없이 구축하는 관계형 데이터베이스 시스템에 대한 생각
대용량 디비에서는 외래키를 안쓰나요?
[SW기술] Foreign Key(외래키)에 대한 생각
[데이터베이스] FK의 사용