최근에 프로그래머스 데브코스에서 팀 프로젝트를 진행하던 중 외래키를 사용하지 말자는 팀원분의 의견이 있었다. 나로서는 처음 듣는 내용이었다. 외래키가 없다면 연관관계 매핑을 어떻게 해야 하는 거지..?라는 생각이 들었고 실제로 찾아본 후 많은 기업에서 외래키를 지양하는 것을 확인하였고, 이에 대해 더 자세히 알아보게 되었다.
외래키를 사용하는 이유
1. 외래키의 가장 큰 장점으로는 데이터가 일련되고 정합성이 지켜지는 것이다.
외래키 없어 데이터 정합성을 지키기 위해서는 애플리케이션단에서 코드를 통해 이것을 지켜야 한다. 하지만 이러한 방법은 시간이 지남에 따라 한계를 보일 수밖에 없고 결국 외래키가 없는 상태에선 시간이 지날수록 데이터 정합성이 조금씩 깨지기 시작한다.
2. 스키마를 통해 각 테이블간의 관계를 명확히 알 수 있다.
DB 스키마를 분석하여 ERD를 자동으로 그려주는 툴을 통해 확인해 보면 가시적으로 이를 확인할 수 있다.
따로 외래키가 지정되어 있지 않은 경우 애플리케이션단 코드를 보며 파악하거나 문서(시간이 지남에 따라 현 상태와 맞지 않을 수도 있다)를 통해 파악해야 할 것이다.
결국 이는 인수자가 구조를 파악하기 어렵고 시간이 걸린다.
외래키를 사용하지 않는 이유
1. 성능 저하
외래키를 사용하게 되면 데이터 생성 및 수정시 항상 무결설 검사를 하게 된다. 예를 들어 자식 테이블에 데이터를 추가할 때 부모 테이블에 PK가 존재하는지를 확인하는 것이다. 이러한 무결성 검사의 선행은 insert/update에 대한 성능 저하를 일으킨다.
2. 개발 단계에서의 용이함을 위해
외래키를 사용하면 몇 가지 번거로움이 생긴다.
자식 테이블에 데이터 생성시 부모 데이터에 row가 미리 생성되어 있어야 한다던지, 데이터 수정 및 삭제 시 데이터의 정합성 유지를 위해 데이터 수정에 순서가 필요하다는 등 번거로움이 있다.
추가로 프로그램의 로직이 바뀌거나 서비스가 확장되었을 때 이 외래키의 제약조건 때문에 에러가 일어날 수 있다.
이러한 번거로움때문에 확장성 및 개발 편의성을 위해서라도 외래키를 사용하지 않고 애플리케이션 단에서 데이터의 무결성을 보장하도록 하는 것이다.
한마디로 요약해서 외래키를 사용하지 않는 것은 무결성, 정합성을 희생시켜 개발 편의와 안정성, 확장성을 도모하기 위함이라고 할 수 있다.
외래키 없이 Join 할 수 있는가?
Join 연산은 데이터 중복 방지를 위해 나누어진 두 테이블을 연결해 원하는 데이터를 찾기 위해 필요하다.
Join 연산에는 보통 기본키와 외래키를 사용하도록 언급해서 Join으로 두 테이블을 연결해서 데이터를 뽑아내기 위해 기본키, 외래키를 사용하는 줄 많이들 알고 있지만, Join 연산에 키는 필수가 아니다. 일반 컬럼으로도 Join 할 수 있다.
다만 무결성 원칙을 지키기 위해서는 외래키를 거는 것이 권장된다.
나의 생각
외래키를 사용하여 테스트를 진행할 때의 불편함은 개발 단계에서 제약조건을 비활성화해놓음으로써 해결을 할 수 있고, 애플리케이션 단에서 무결성을 검사하는 것 또한 DB 무결성 검사를 하는 것과 비교하면 유의미한 속도차이는 나지 않는다고 한다.
결국에는 개발 편의와 확정성의 증대가 무결성, 정합성의 중요성보다 높다라고 판단을 해서 외래키를 사용하지 않는 걸까?
하지만 RDBMS라는 것은 테이블 간 관계를 표현함은 물론 연관된 데이터에 대한 무결성 검사를 해주기 때문에 사용하는 것인데, 단순히 편의를 위해 외래키를 사용하지 않는다는 것이 조금 의아하긴 하다.
나는 속도에 민감한 서비스가 아니라면 데이터 품질을 보장받기 위해 외래키를 사용하는 것이 좋다라는 결론을 내렸다.
물론 내가 아직 대규모 트래픽이 발생하는 서비스를 만들어 보지 않았기에 나의 안일한 생각일 수 도 있지만 현재 나의 경험으로는 이 정도의 결론이 나에게 있어서 설득이 되었다.
다만 데이터 무결성을 지키려면 개발 과정이 꽤나 귀찮아지는데 제일 나아 보이는 해결 방법은 외래키를 deferred로 만든 후 disable 시킨 후 개발하는 것이다.
출처 : 참고
https://co1nam.tistory.com/44#google_vignette
외래키를 사용하지 않는 이유 feat. 인덱스
외래 키(foreign key) 란 관계형 데이터베이스에서 다른 릴레이션(테이블)을 참조할 때 사용하는 키입니다. 아래 학생 릴레이션을 봅시다. id 학생명 강의명 강의코드 1 개똥이 병충해 방지기법 1231 2
co1nam.tistory.com
https://gdsc-university-of-seoul.github.io/foreign-key/
외래키? 그거 없어도 되지 않나요? | GDSC UOS
외래키? 그거 없어도 되지 않나요? 1. 외래키는 왜 쓰는가? 외래키를 생각해보기 전에, 키는 무엇인가? 키는 테이블에서 데이터를 구분할 수 있도록 하는 속성으로 슈퍼 키, 복합 키, 기본 키 등이
gdsc-university-of-seoul.github.io