앞선 게시글에서 제 1 정규화를 진행하는 방법을 알아봤다.
https://velog.io/@iiingkeep/DB-설계-데이터베이스-모델링Database-Modeling-제-1-정규형1NF-First-Normal-Form
하지만 Foreign key를 어디에 두어야 하는지 명확하지 않아 일일이 시도해봐야 했다.
이제 Forein key로 어느 테이블에 컬럼을 생성해야 하는지 빠르게 알 수 있는 방법을 알아 볼 것인데, 핵심은 "관계 파악"이다.
테이블간 관계를 파악하는 방법은 다음과 같다.
이 때 헷갈리지 않기 위해 한 개의 개체와 다른 개체가 어떤 관계인지 꼭 기재
관계를 파악했다면 다음의 규칙에 따라 제 1 정규화를 진행한다.
중간 테이블을 생성한 뒤 그 테이블에 두 테이블의 Foreign key를 넣는다.
예시)
아래의 학생 테이블을 정규화 하여 학생 테이블과 과목 테이블로 분리할 때 관계는 학생 : 과목 = N : M 이다.
이 때 중간 테이블인 수강 테이블을 생성한 후 학생 테이블의 id와 과목 테이블의 id를 모두 Foreign key로 넣는다.
이후에는 관계를 새롭게 설정한다 → 학생 : 등록 = 1 : N / 과목 : 등록 = 1 : N
정규화 이전)
students Table
| id | 이름 | 수강 과목 |
|---|---|---|
| 1 | 김지민 | 국어, 수학 |
| 2 | 이은서 | 수학, 과학 |
| 3 | 전서진 | 국어, 과학 |
정규화 이후)
students Table
| id | 이름 |
|---|---|
| 1 | 김지민 |
| 2 | 이은서 |
| 3 | 전서진 |
subjects Table
| id | 과목명 |
|---|---|
| 1 | 국어 |
| 2 | 수학 |
| 3 | 과학 |
course_registrations Table
| id | 학생 id(FK) | 과목 id(FK) |
|---|---|---|
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 2 |
| 4 | 2 | 3 |
| 5 | 3 | 1 |
| 6 | 3 | 3 |
N쪽의 테이블에 Foreign key를 넣는다.
예시)
아래의 가게 테이블을 정규화 하여 가게 테이블과 상품 테이블로 분리할 때
관계는 가게 : 상품 = 1 : N 이다.
이 때 N쪽인 상품 테이블에 가게 id를 Foreign key로 넣는다.
정규화 이전)
stores Table
| id | 가게명 | 판매 상품 |
|---|---|---|
| 1 | DB 카페 | 아메리카노, 카페라떼 |
| 2 | 데이터 국밥 | 수육국밥, 순대국밥, 선지국밥 |
정규화 이후)
stores Table
| id | 가게명 |
|---|---|
| 1 | DB 카페 |
| 2 | 데이터 국밥 |
products Table
| id | 판매 상품 | 가게 id(FK) |
|---|---|---|
| 1 | 아메리카노 | 1 |
| 2 | 카페라떼 | 1 |
| 3 | 수육국밥 | 2 |
| 4 | 순대국밥 | 2 |
| 5 | 선지국밥 | 2 |
3. 1 : 1 관계
둘 중 아무 테이블에 Foreign key를 넣어도 된다.
예시)
아래의 사용자 테이블을 정규화 하여 사용자 테이블과 프로필 테이블로 분리할 때
관계는 사용자 : 프로필 = 1 : 1 이다.
이 때 사용자 테이블에 프로필 id를 Foreign key로 넣거나 프로필 테이블에 사용자 id를 Foreign key로 넣는다. 원하는 곳에 넣으면 된다.
정규화 이전)
users Table
| id | 이메일 | 비밀번호 | 프로필사진 | 닉네임 | 자기소개 |
|---|---|---|---|---|---|
| 1 | k@k.com | 123 | https ://k.com/1 | 짱구 | 안녕하세요. |
| 2 | n@n.com | 132 | https ://n.com/2 | 흰둥 | 멍멍 |
| 3 | j@j.com | 213 | https ://j.com/3 | 맹구 | .... |
정규화 이후)
경우1)
사용자 테이블에 프로필 id를 Foreign key로 넣은 경우
users Table
| id | 이메일 | 비밀번호 | 프로필 id(FK) |
|---|---|---|---|
| 1 | k@k.com | 123 | 1 |
| 2 | n@n.com | 132 | 2 |
| 3 | j@j.com | 213 | 3 |
profiles Table
| id | 프로필사진 | 닉네임 | 자기소개 |
|---|---|---|---|
| 1 | https ://k.com/1 | 짱구 | 안녕하세요. |
| 2 | https ://n.com/2 | 흰둥 | 멍멍 |
| 3 | https ://j.com/3 | 맹구 | .... |
경우2)
프로필 테이블에 사용자 id를 Foreign key로 넣은 경우
users Table
| id | 이메일 | 비밀번호 |
|---|---|---|
| 1 | k@k.com | 123 |
| 2 | n@n.com | 132 |
| 3 | j@j.com | 213 |
profiles Table
| id | 프로필사진 | 닉네임 | 자기소개 | 사용자 id(FK) |
|---|---|---|---|---|
| 1 | https ://k.com/1 | 짱구 | 안녕하세요. | 1 |
| 2 | https ://n.com/2 | 흰둥 | 멍멍 | 2 |
| 3 | https ://j.com/3 | 맹구 | .... | 3 |
하지만 정규화 과정에서 분리한 테이블의 관계가 1:1이고, 큰 이점이 없다면 이후에 join 등으로 인한 성능 저하가 발생하지 않도록 이 테이블은 분리하지 않고 그대로 사용하는 것이 오히려 좋을 수 있다.
왠만하면 1:1 관계로 분리하지 않는 것을 추천!
이 게시글은 박재성님의 비전공자도 이해할 수 있는 DB 설계 입문/실전 강의를 토대로 작성되었습니다.
https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-db-%EC%84%A4%EA%B3%84-%EC%9E%85%EB%AC%B8/dashboard