서론
"FK란 무엇인지, 왜 사용하는지, 언제 사용하는지 설명해주세요." 모의 면접에서 질문이 나왔다.
이부분을 조금 더 깊게 공부해보려고 한다.
FK란 무엇이고 왜 사용하는가?
Foreign Key는 외래키라고 부른다. RDBMS에서 관계를 지정할 때 사용합니다.
하지만, FK 말고 일반 컬럼으로도 관계를 표현할 수 있지만, 그럼에도 FK를 사용하는 이유는 *참조 무결성 제약조건을 설정할 수 있기 때문입니다.
(참조 무결성은 RDBMS에서 FK와 PK간의 일관성을 유지하는 것입니다.)
관계의 종류는 어떻게 되나요?
기본적으로 RDBMS에서는 아래 네가지 종류의 관계를 지원해줍니다.
- One-to-One
- One-to-Many / Many-to-One
- Many-to-Many
각 관계 매핑에 따라 장단점과 적절한 예시를 두고 설명해보겠습니다.
One-to-One
설명:
각 레코드가 1 대 1로 관계가 맺어질 때 사용합니다.
사용 예시:
- 유저와 유저 프로필
- 주문과 결제 정보
- 학생과 보호자
장점:
- 참조 무결성
- 쿼리 성능 향상
- 확장성과 유지보수성
고민해야하는 포인트:
One-to-One 관계는 굳이 한 테이블로 묶을 수 있는데 왜 테이블을 나누어야 하는지 고민해보아야 합니다.
위에서 설명한 예시의 One-to-One으로 선택한 포인트를 설명해보겠습니다.
- 유저와 유저 프로필(개인 정보와 공개 정보)
- 유저: 유저의 개인정보(고유 pk id, 비밀번호, email 등)같이 비공개 정보를 저장할 수 있습니다.
- 유저 프로필: 유저 고유의 공개 정보를 가져올 수 있습니다.
- 이렇게 설계한 이유는 유저와 유저 프로필 테이블에 저장되는 데이터의 성격이 다르기 때문입니다. 확장성의 관점으로 확인해볼 수 있습니다. 데이터가 다른데 같은 테이블에 저장할 필요가 없죠!
- 주문과 결제 정보
- 주문: 구매 물건 정보와 같은 공개 정보만 저장되기 때문입니다.
- 결제 정보: 유저의 개인정보(계좌번호, 주문번호, 유저 이름 등)가 포함되기 때문입니다.
- 위와 같은 이유입니다. 유저의 개인정보같이 민감한 정보를 주문 미리보기 DTO에서 보여줄 필요가 없기 때문이에요.
- 학생과 보호자
- 학생: 학생의 정보가 포함됩니다.
- 보호자: 보호자의 정보가 포함됩니다.
- 이건 서비스에 따라 다릅니다. 학교라고 가정한다면, 가정통신문이나 부모님의 동의가 필요한 경우가 아니라면 보호자는 가끔씩 사용되는 정보이기 때문에 분리하였습니다.
One-to-Many / Many-to-One
설명:
각 레코드가 1 대 다로 관계가 맺어질 때 사용합니다.
사용 예시:
- 게시글과 댓글
- 회사와 직원
장점:
- 참조 무결성
- 쿼리 성능 향상
- 데이터 중복 최소화
고민해야하는 포인트:
One-to-Many 관계 또한 데이터의 성격을 고려해야하지만, 다른 관계보다 꽤나 직관적입니다.
주로 Many가 One에 종속될 때 이렇게 설계합니다. 그렇지 않은 경우도 존재합니다. (예를 들면 게시글-해시태그, 대학생과 수강과목)
이는 Many-to-Many 부분에서 설명하겠습니다.
Many-to-Many
설명:
각 레코드가 다 대 다로 매핑될 때 사용합니다.
사용 예시:
- 게시글과 해시태그
- 대학생과 수강과목
장점:
- 참조 무결성
- 쿼리 성능 향상
- 데이터 중복 최소화
고민해야하는 포인트:
Many-to-Many는 크게 두가지로 설계 방식이 나뉩니다.
- 그냥 Many-to-Many로 설계하는 방식
- Many-to-One을 두번 사용하고 중간에 *매핑 테이블을 사용하는 방식
매핑 테이블이란?
다 대 다 관계에서 Many-to-Many를 사용하지 않고, 두 테이블 사이에 두 테이블의 Many-to-One으로 JOIN 하여 값을 저장하는 방식입니다.
대부분의 Many-to-Many가 매핑 테이블 방식으로 상호 변경 가능합니다.
매핑 테이블을 Many-to-Many을 대신하여 사용할 때?
장점:
- 데이터의 정규화: 중복 데이터를 최소화하여 효율적인 데이터 관리를 가능하게 합니다.
- 확장성: 매핑 테이블을 통해 새로운 엔티티를 쉽게 추가하거나 삭제할 수 있습니다.
- 성능: Many-to-Many 관계에서 JOIN을 사용해 연결된 엔티티를 쿼리하면, 중복 데이터를 제거하면서 정확한 결과를 얻을 수 있습니다.
단점:
- 설계 복잡도: Many-to-Many 관계를 구현하려면 중간에 매핑 테이블을 추가하여 복잡한 데이터 모델을 만들어야 합니다.
- 성능: 매핑 테이블을 사용하면 두 테이블 간의 JOIN이 필요하기 때문에 데이터베이스의 성능에 영향을 줄 수 있습니다.
- 데이터 무결성: 매핑 테이블을 사용할 때, 중복 데이터를 제거하지 않으면 데이터 무결성에 위배될 수 있습니다. 또한, 삭제된 데이터에 대한 처리도 신경써야 합니다.
요약하자면 매핑테이블은 중복 데이터가 필요없을 때 편합니다. 두 FK를 COMPOSITE KEY로 설정하면 되니까요.
어떨 때 composite key를 사용해야 할까?
다만, 성능면에서 조금 떨어질 수 있습니다.
이 관점으로 보면 위에서 설명한 Many-to-Many의 사용 예시를 어떻게 설계할 지 정할 수 있습니다.
- 게시글과 해시태그: 새로운 해시태그가 생성되면 안되니 중복 체크를 위하여 매핑 테이블 방식
- 대학생과 수강과목: 재수강을 통해 반복하여 수강할 수 있으니, 굳이 중복체크를 하지 않아도 됩니다. 성능을 위하여 매핑 테이블을 사용하지 않습니다.
'CS' 카테고리의 다른 글
크롬의 탭은 프로세스일까? 스레드일까? (0) | 2023.06.06 |
---|---|
데이터베이스 Lock이란 (0) | 2023.03.15 |
트랜잭션 격리 수준 (0) | 2023.03.07 |
[PostgreSQL] 데이터베이스 트랜잭션이란? (0) | 2023.03.06 |
우리는 왜 JWT를 사용하는가? / JWT 사용 이유 (0) | 2023.02.20 |
글 내용 중 잘못되거나 이해되지 않는 부분은 댓글을 달아주세요! 감사합니다! 문의: puleugo@gmail.com