외래키(FK)는 좋은 것일까?

허진혁·2023년 5월 5일
0

궁금점

데이터 Read를 할 때, Join을 통해 테이블을 하나의 쿼리로 가져올 수 있어요. 그렇다면 매핑을 위한 칼럼이 추가되는 것이에요.
이렇게 단순히 Join을 통해 가져올 수 있는데 왜 왜래키를 설정해야 할까?

'외래키 활용이 차후에 테이블의 확장에 방해가 되지 않을까?' 라는 생각이 문득 들어 글쓰기를 시작했어요.

관계형 DB의 장점

우선 관계형 데이터베이스의 장점을 정리해보아요.

  • 각 테이블끼리 관계를 갖을 수 있으며, 이와 같은 특징으로 저장 공간의 효율성과 확장성이 향상되요.
  • 서로 관계 있는 데이터가 여러 테이블로 나뉘어 저장되므로, 각 테이블에 저장된 데이터를 효과적으로 검색이 가능해요.
  • 인덱스를 잘 활용하고, 쿼리문을 잘 작성하면 비용을 극적으로 낮출 수 있어요.
  • 각 테이블은 논리적인 관계를 가지며 테이블 간에 join을 하여 데이터를 가져올 수 있으며 데이터의 무결성을 보장할 수 있어요.

정리해보면 관계형 DB는 모든 정보들을 여러 테이블에 정규화되어 분산해요. 그래서 테이블끼리 서로 특정한 규칙(관계)을 만들어 설계를 하게 되는 것이지요.

관계 있는 테이블을 활용하는 방식이 Join을 활용하는 것이에요. 그렇다면 Join의 역할과 장점들이 무엇일까요?

Join의 역할

  • 두 개 이상의 테이블을 연결(결합)하여 데이터를 출력해요.
  • 서로 다른 테이블을 공통 칼럼을 기준으로 결합 하는 연산이에요.

정리헤보면, Join은 여러 테이블에 흩어져 있는 정보 중에 필요한 정보를 가져와 가상의 테이블처럼 결과를 보여줘요.

위의 정리를 다르게 생각해보면, 각 테이블에 필요한 데이털르 저장하고, 테이블끼리 중복되는 데이터를 저장하지 않음으로써 저장 공간의 효율성이 증가하는 것이에요. 즉, Join 덕분에 관계형 DB의 장점들이 살아나는 것으로 볼 수 있어요.

외래키란?

  • 부모 - 자식 테이블 관계를 맺어주고 스키마를 통해 각 테이블간의 연관 관계를 명시적으로 알수있어요.

  • 제약조건인 참조 무결성(referential integritiy)을 통해 데이터 정합성을 지킬수 있다.

외래키를 사용하는 이유

  1. 외래키의 가장 큰 장점으로는 데이터가 일관되고 정합성이 지켜주어요.

    외래키 없이 데이터 정합성을 지키기 위해선 어플리케이션단에서 코드를 통해 이것을 지켜야 해요.
    보통 협업을 하며 많은 사람들이 사용하게 되는데 시간이 지남에 따라 한계를 보일수밖에 없고, DB 클라이언트를 통해 직접 접근하여 수동으로 데이터를 바꾸는 경우도 있어요. 결국 이 데이터 정합성은 조금씩 깨지기 시작할 거에요.

  2. 스키마를 통해 테이블 간 관계를 명확히 알 수 있어요.

    DB 스키마를 분석하여 ERD를 자동으로 그려주는 툴을 통해 확인해보면 가시적으로 이를 확인 할 수 있어요.
    따로 외래키가 지정되어 있지 않은 경우 코드나 칼럼이름을 보며 파악하거나 문서(시간이 지남에 따라 현상태와 맞지 않을수도 있다)를 통해 파악해야 해요.

외래키의 단점

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

    외래키 관련 CRUD 발생시 데이터 정합성을 위해 DBMS 에선 추가적인 쿼리를 실행시켜요. 외래키로 지정된 다른 테이블의 row가 존재하는지 확인 하거나 해당 row 가 삭제 되었을시,연관된 다른 테이블의 row들도 삭 (CASCADE ON DELETE)하는 등의 오버헤드가 발생하여 성능 부하 문제가 일어날수도 있다는 우려가 있어요. ~~(알아보니 추가적인 오버헤드 비용이 그렇게 커보이지는 않는것 같아요.) ~~

  2. 기존 데이터들이 Referential Integrity 정합성에 맞지 않아서 Foreign Key 를 적용할 수 없을 수 있어요.

    이 경우 Foreign Key 를 달 때(또는 Alter 명령으로 Enable 시킬 때) Enable Novalidate 옵션으로 생성해 주면 해결이 가능해요. 디폴트는 Enable Validate 인데 의미는 기존 데이터들에 대해 Validation 검사수행 후 성공하면 Enable 시킨다는 뜻이에요. 반면에 Enable Novalidate 는 기존 데이터들에 대한 Validation 검사를 수행하지 않고 Foreign Key 를 Enable 시키므로 이 문제를 회피할 수 있어요.

  3. 개발시 외래키가 있음으로 인해 불편해요.

    외래키의 참조 무결성 제약사항으로 인해 부모 - 자식 관계에서 자식 테이블의 row를 추가 할시 자식이 외래키로 참조 하고있는 부모 테이블의 row 가 있어야 DML 작업이 가능해요. (참조할 데이터를 항상 넣어주어야 하는 것이죠)

정리

관계형 DB의 장점은 이미 많이 증명이 되어 있고, DB사용 순위를 보면 1~4위까지 모두 관계형 DB인 것을 알 수 있어요.
[사진]
사실 외래키로 인한 장점이 더 많다고 생각했어요. 단점들이 많이 보완되고, 장점을 부술만한 단점들은 아니기 때문이에요.

그러나 보수적으로 데이터를 관리하는 것은 유지 보수 입장에서는 장점이지만, 변화에 입장에서는 단점이 되는 것이에요.
데이터 타입을 바꾸는 것도 엄청난 비용, 다른 테이블의 관계를 추가 및 삭제 하는 것도 엄청난 비용이에요.

나중에 변화가 있을 경우 외래키 때문에 변화하는 작업에 드는 비용이 크다는 것도 고려해 보아야 할 것 같아요.

참고자료

외래키가 Insert 속도에 영향을 끼치나요?
https://lackofwillpower.tistory.com/m/76
Foreign Key 없이 구축하는 관계형 데이터베이스 시스템에 대한 생각

profile
Don't ever say it's over if I'm breathing

0개의 댓글