-
[Tnote] "참조관계"의 고민T-note 2024. 6. 29. 01:04728x90
팀원과 회의중 "현재 외래키를 통한 참조관계로 개발을 진행했는데, 대다수의 기업에서 진행하는 방식에 따라 외래키 없는 참조관계로 리팩토링을 진행하자" 라는 의견이 나왔고 "어떤 방식의 참조관계 형성이 우리의 프로젝트에 더 효율적인지?" 에 대한 고민을 하며 나온 결론과 프로젝트에 적용한 방식에 대해서 소개하고자 합니다.
제가 고민한 "참조관계"에 대해서 말씀드리기 전에 간단하게 외래키에 대해서 짚고 넘어가겠습니다.
외래키는 데이터의 정합성을 돕는 역할로써 일종의 테이블을 연결하여 가상의 다리역할을 합니다.
이런 외래키는 아래와 같은 특징들을 가지고 있습니다
1. 관계 데이터 모델의 릴레이션 간의 관계를 표현한다
2. 다른 릴레이션의 기본키를 참조하는 속성이다.
3. 참조하고(외래키) 참조되는(기본키) 양쪽 릴레이션의 도메인은 서로 같아야 한다
4. null 값과 중복 값 등이 허용된다그렇다면, 왜 "외래키를 사용할지 말지?"에 대한 고민이 생기는 것일까?
그 이유는 아래와 같이 4가지의 이유를 볼 수 있다.
1. cascade 등 외래키 사용시 지켜야 하는 부분을 지키며 개발하기 불편하다
2. 1번과 같은 조검 검사와, on delete, on update 옵션 기능을 위해 필수적인 무결성 검사를 해야하므로 성능 저하가 발생한다
3. 테스트 데이터를 만드는게 불편하다.
4. 테이블 구조 변경시 고려사항이 많아진다이러한 이유들에 의해서 많은 기업들이 외래키 없이 참조관계를 만들며 개발하고 있습니다.
하지만, 고민하고 자료를 찾아 볼수록 외래키 사용하는 것이 낫다고 생각이 들게 되었습니다. 위의 4가지 이유에 대한 답변들을 아래에 적어보았습니다
1번과 2번에 대한 답변
-> 성능저하의 초점에서 바라보면, 자식 테이블의 DML시에 오버헤드는 분명하지만, "트랜젝션 처리" 즉 OLTP에 영향을 끼칠만한 오버헤드는 아니며, FK를 사용하지 않았을때 부모 테이블이 존재하는지 SELECT문을 날려야 하는데 이는 오버헤드가 더 커지며, 참조 무결성이 안지켜집니다. [ 프로젝트를 진행하면서 참조 무결성의 보장이 지켜지지 않는 것을 상상해보기가,,,, ]
-> 외래키 때문에 DB 병목현상이 발생한다는 의견도 있는데, 이 문제의 원인은 대체로 외래키가 아닌 DB 설계 자체 문제나 부적절한 인덱스의 문제입니다.
-> 외래키의 성능 문제는 부모 테이블의 PK가 변하지 않도록 인조키로 설정하며, 외래키 컬럼에 인덱스를 달아주면 된다. ( 인덱스는 DB마다 다른데 저희가 사용하는 MySQL은 기본적으로 생성되며, 오라클 9i 버전부터 이 문제가 해결되어 FK에 굳이 인덱스를 만들어 주지 않아도 됩니다. )
3번과 4번에 대한 답변
[ 아래 참조 문서중 Foreign Key 없이 구축하는 데이터베이스 시스템에 대한 생각 ] 참고해보면,
-> 저도 프로젝트 API들의 테스트 코드를 작성하면서 부모 Row 작성하고 자식 Row를 생성하는 등 불편함을 겪었습니다. 하지만 이는 개발기간 중엔 FK를 Disable 시켜 놓으면 해결 됩니다.
-> 구조 변경에 어려움은 테이블 관계에 따른 DML 작성 순서가 필요해지는데. 이는 FK를 만들때 Deferred 옵션을 주며, 매 문장단위로 정합성 검사를 하는 것이 아닌 Commit시에 정합성 검사를 하여 문장들의 순서를 상관없게 할 수 있습니다.
=> FK를 Deferred로 만들어 Disable 시켜놓고 테스트 하기전에 Enable 시키면 개발 단계의 불편함을 줄일 수 있습니다. 다만, 데드락을 예방할 수 있기에 FK를 Not Deferred로 만드는 것이 좋긴합니다.
결국 저희는 소통을 해보니 결국 다른 서비스들이 FK를 적용하지 않는 이유는 DBA관점이 아닌 개발자의 관점에서 성능 저하와 불편성이라는 생각을 하게 되었고 이를 기준으로 저희는 아래와 같은 이유로 프로젝트에 FK를 적용하기로 결정하게 되었습니다.
- 저희 프로젝트의 규모는 실제 우리가 자주 사용하는 서비스들에 비해 작아 테스트 코드 작성과 구조 변경에 따른 불편성이 작음
- 테이블간의 연관성이 적으며, 자식 테이블에서 DML문 작성시 생기는 오버헤드로 인한 미미한 성능 저하보다 참조 무결성이 중요하다고 판단
- FK사용에 의한 성능 저하를 막기 위해 FK에 인덱스를 설정해야 하는데 저희가 사용하는 MySQL은 자동으로 인덱스를 설정해주기에 괜찮다고 판단보고 계신 분들의 다양한 피드백 환영하오니 부탁드립니다! 감사합니다!
참조
Foreign Key 없이 구축하는 관계형 데이터베이스 시스템에 대한 생각
Foreign Key (Referential Integrity) 없이 구축하는 관계형 데이터베이스 시스템에 대한 생각
engineering-skcc.github.io
https://velog.io/@subutai/%EB%A7%A4%EC%9D%BC-2day
[DB] 외래키의 장점과 단점 및 논의
데이터베이스 개론을 들으면, 외래키는 테이블과 테이블간의 연관관계를 맺어주는역할을 한다고 한다. 생각해보면 외래키의 여러가지 장점만 배우고,예를들어 제약조건 생성, 테이블관의 명시
velog.io
https://okky.kr/questions/586565
OKKY - 대용량 디비에서는 외래키를 안쓰나요?
안녕하세요몇개월 안된 신입 개발자입니다주변 유명 아이티기업 백엔드로 일하고 계시는 분들 말씀을 들어보면, 데이터가 많으면 속도때문에 외래키를 아예 안쓰고 조인을 많이 쓴다는데 원래
okky.kr
https://velog.io/@hiy7030/DB-Primary-key%EC%99%80-foreign-key
[DB] Primary key와 foreign key
데이터베이스 테이블 내의 모든 레코드에서 고유한 아이디를 제공한다. 1\. 모든 레코드가 서로 다른 값을 가지고 있어 각 레코드를 식별할 수 있다.2\. NULL값이 존재할 수 없다. 3\. 레코드의 값은
velog.io
'T-note' 카테고리의 다른 글
[에러] schema-validation 에러 (0) 2024.04.08 [티노트] 로깅 (0) 2024.03.28 [Error] 502 Bad Gateway (0) 2024.03.14 [error] bind for 0.0.0.0:80 failed: port is already allocate (0) 2024.03.11 [Tnote] npm를 통해서 https로 변경하기 (0) 2024.03.11