외래키 쓸래말래?

류희수·2024년 11월 18일
0

외래키를 사용하는 것이 좋은가 안 좋은가.. 에 대한 토론이 일어났다.

외래키란?

부모 - 자식에서 관계를 맺어주고 스카마를 통하여 각 테이블의 연관관계를 직관적으로 알 수 있게 해준다.

외래키의 장점

일단 뭐니뭐니 해도 데이터 무결성 이라는 장점이 제일 큰 것 같다.

외래키가 없이 데이터 정합성을 지키기 위해선 어플리케이션단에서 코드를 통해 이것을 지켜야 하는데 여러 사람이 협업하는 과정에서는 상당히 어려운 과정이다.

또한 스키마를 통해 테이블 간 관계를 명확히 알 수 있다.
(특히 ERD 툴을 사용했을 때 더 직관적으로 알 수 있다.)


외래키의 단점

외래키 추가로 인한 성능 저하 (CPU cost)

외래키 관련 CRUD 발생시 데이터 정합성을 위해 DBMS 에선 추가적인 쿼리를 실행시킨다.

외래키로 지정된 다른 테이블의 row가 존재하는지 확인 하거나 해당 row 가 삭제 되었을시,연관된 다른 테이블의 row들도 삭제 (CASCADE ON DELETE) 하는 등의 오버헤드가 발생하여 성능 부하 문제가 일어난다.

레거시 코드를 수정해야 하는데 기존 데이터들을 냅둬야 한다면
CASCADE로 전부 변경 할 수가 없을 것이다.

하지만 실제론 성능적인 문제는 많이 크지않고 저 작업들을 해야하는 비용이 더 크다고 생각한다.

예를 들어 참조되는 릴레이션은 참조하는 릴레이션보다 먼저 만들어져 있어야 하기 때문에 생성, 수정할 때마다 순서를 신경 써줘야 하는 번거로움 같은..

추가로 외래키가 있으면 정말 insert가 느려질까? 라고 테스트를 해본 사례가 있는데

대충 요약하면

테이블 구성
parent 테이블: PRIMARY KEY를 가진 테이블.
child 테이블: FOREIGN KEY로 parent의 PRIMARY KEY를 참조.

삽입 과정

child 테이블에 데이터를 삽입할 때, 외래키 제약 조건이 활성화된 상태에서 DBMS는 다음 작업을 수행한다

삽입하는 child 테이블의 외래키 값이 parent 테이블의 기본 키(primary key)와 매칭되는지 확인(참조 무결성 검증).

이는 SELECT를 통해 parent 테이블을 조회하는 작업을 포함한다.

정답은 no 였다.


결론

물론 상황마다 다르겠지만 나의 프로젝트 수준에서는
성능적인 오버헤드로 외래키를 못 쓸 정도는 아닌 것 같다.

하지만 정말 대규모의 프로젝트라고 생각한다면
개발의 규모가 커져 참조 무결성을 검증하여 대량 트래픽 시스템에서는 병목이 되거나,
트랜잭션이 복잡해지고 락 경합(Contention)이 발생할 가능성
도 있다고 생각한다.

지금 레벨에서는(작은 프로젝트) 오히려 성능적인 부분보단 테스트의 확장성, 개발 편의성을 위해 안 쓰는 느낌이 들었다.

또한 분리되어 있는 MSA 구조에서도 사용하기 상당히 번거롭고 껄끄러울 것 같다.

즉 이렇게 외래키를 사용하지 않게 된다면 반드시 애플리케이션에서 철저한 검증이 이루어져야 한다.

즉 무결성, 정합성을 희생시켜 개발자의 편의성과 확장성을 도모하는 것 같다.

항상 왜?를 붙여보자!

profile
자바를자바

0개의 댓글