본문 바로가기

CS ﹒ Algorithm/Database

데이터베이스 (7) 설계 3 - N : M 관계, 1:1 관계

 

1. N : M 관계?

 

 

한명의 학생이 여러 과목을 가질 수도 있고, 한 과목이 여러 학생에 의해 공유될 수도 있다.

이것이 N : M 관계(다대다 관계)이다.

아마 1 : N의 관계와 헷갈릴 수도 있지만, 쓸데 없이 어렵게 꼬아서 생각하지 않으면 헷갈릴 것도 없다는 것을 알게 될 것이다.

 

1 : N의 관계는 N에 해당하는 개체가 1에 종속되어 있어야 한다고 했다.

그러면 생각해보자

 

학생은 과목이 있어야만 존재하는가? 아니다.

과목은 학생이 있어야만 존재하는가? 아니다.

학생이 여러 명 있어야 과목도 여러 개 존재하는가? 아니다.

과목이 여러 개 있어야 학생도 여러 명 존재하는가? 아니다.

 

이렇듯 학생과 과목은 직접적인 관계가 없다.

이 둘은 명사로써 존재하는 테이블, 즉 "마스터 테이블"이다.

다만 수업, 수강 등의 비즈니스 로직(관계형 테이블)이 끼어들어야 둘 사이에 관계가 형성되는 것이다.

 

아직 헷갈릴 수 있으니 버스와 좌석, 버스와 승객이라는 두가지 예시를 더 보고 넘어가자.

 

버스가 있어야만 좌석도 존재하는가? 맞다.

버스가 여러 대 있어야 좌석도 여러 개 존재할 수 있는가? 맞다.

하나의 버스가 소유한 좌석은 그 버스에 종속되는가? 맞다.

( => 1 : N 관계 )

 

버스가 있어야 승객이 존재하는가? 아니다.

하나의 승객은 한 대의 버스만 이용할 거나, 한 대의 버스는 한 명의 승객만을 태울 수 있는가? 아니다.

( => N : M 관계 )

 

설명 없는 추가 예시 :

1 : N )

버스와 좌석

책과 목차

학교와 학생

회사와 부서

 

M : N )

학교와 과목

소비자와 상품

 

 

 

 

2. 관계 테이블의 Key 설계

 

 

(1) 상속형 PK 모델

 

가장 흔히 보게될 M : N의 예시이다. ( PK, FK를 다 가지고 있는 상태인데 버그로 인해 FK인 것처럼 보이고 있다. )

score는 과목 테이블과 성적 테이블 사이를 성적이라는 관계로 이어주고 있는데, score_table만의 독립적인 id가 존재하지 않고 참조하고있는 값들을 PK로 사용하고 있다.

이 경우 같은 학생이 같은 과목의 점수가 중복으로 나온다던가하는 문제가 엄격하게 통제된다.

 

 

 

(2) 독립형 PK 모델

 

* 이번에도 버그로 인해 잘못 표시되고 있는데, book_id, client_ic, loan_seq가 모두 PK인 상태이다.

 

위의 예시와 달리 이번 예시는 도서 대출 테이블은 고객과 책의 id를 참조만 하고 있고 PK는 본인만의 값을 가지고 있다.

이 경우 어떤 이점을 얻을 수 있을까?

가령, 비즈니스 로직이 점점 추가되어 loan_table이 참조할 테이블이 4개로 늘었다고 생각해보자. 그리고 참조할 키는 6개로 늘어났다.

그리고 여기서 JOIN으로 필요한 데이터를 추출하려면? 엄청나게 복잡해질 것이다.

이럴 때 보조키(마찬가지로 PK)가 있다면 해당 키 하나로 간단하게 데이터를 추출할 수 있다.

확장성을 고려한다면 보조키를 따로 부여하는 편이 좋다.

 

다만 여기서 seq에도 PK를 주는지, 아니면 고유키나 일반키로 두는지는 정답이 없다.

인덱스 / 클러스터 인덱스 개념에 대해 공부하고 여러 사례를 찾아가며 스스로 생각해보자.

 

 

 

 

 

3. 1:1 관계?

 

 

 

부부관계는 대표적인 1:1관계의 예시이다.

이전에 N:M의 관계를 정의하기 위해 사용했던 방법들을 떠올려보자.

 

신랑은 신부가 있어야만 존재하는가? YES

신부는 신랑이 있어야만 존자해는가? YES

 

참고로 여기서 말하는 존재의 여부는 말 그대로 데이터로써의 의미이다.

자꾸 현실 세계랑 대입해서 생각하면 1:1 관계는 이해가 어려워질 수 있다.

신랑 테이블과 신부 테이블은 따로 나뉘어 있지만 사실 '부부'라는 테이블로 묶어놔도 아무 상관이 없다. 

 

그런데 왜 이렇게 떨어트려놓은 것일까?

첫 번째로는 확장성을 위해서이다.

각각 다른 속성을 가지고 필요한 데이터만 가지고 다른 테이블로 확장시켜 나갈 수 있다.

두 번째는 데이터베이스를 보는 우리를 위해서이다.

지금은 그냥 부부(신랑+신부)라는 간단한 예시이지만 조금 더 복잡한 것을 보자.

 

 

 

여기 있는 모든 테이블에 있는 Column들은 다 book_table안에 들어갔어도 됐을 내용들이다.

그렇지 않은가? 책의 제목과 작가 출판사 책의 구분 ISBN넘버..

만약 실무에서 이것의 몇 배, 몇십 배는 되는 데이터 Column들이 한 테이블 안에 들어있다고 생각해봐라.

어떻게든 데이터베이스 설계 전문가를 초빙해야 한다고 대표님의 바짓가랑이를 붙잡고 빌게 될 것이다.

 

그러나 이것들을 모두 1:1 관계로 풀어놓음으로써 모두 같은 id를 공유하고 있기 때문에 테이블명을 참고하여 필요한 데이터에 해당하는 항목을 찾은 뒤 해당 아이디로 모든 데이터를 조회할 수 있다.

 

데이터베이스 설계 과정에서 1:1 관계가 필요한 곳을 파악하는 능력은 굉장히 중요하며, 1:1 관계가 필요한 곳을 1:다 관계나 다:다 관계로 풀어놓을 경우 몹시 슬퍼질 수 있다.