CODING/강의노트-JSCODE 박재성

[DB 설계] 섹션 4 - ⭐️복잡한 개념을 몰라도 누구나 따라할 수 있는, 마법의 DB 설계 규칙 5가지⭐️

codingTrip 2025. 5. 28. 15:58

https://inf.run/pxDWY
[본 게시물은 파트너스 활동의 일환으로 소정의 수수료를 받을 수 있습니다.]


[규칙 1] 한 칸에는 한 가지 정보만 들어가도록 만들어라 - 1

✅ 한 칸에는 한 가지 정보만 들어가도록 만들어라.

데이터베이스 테이블을 설계할 때 한 칸에는 한 가지 정보만 들어가야 한다.라는 규칙을 지켜야 한다.

 

위의 규칙을 안 지킨 사례

[사례 1]

users (사용자)

id(PK) 이름 이메일
1 박재성 js123@naver.com, js00@naver.com
2 김시안 king123@naver.com, queen123@naver.com

 

=> 한 칸에는 한 가지 정보만 들어가야 하는데 2가지 정보가 들어가 있다.

 

[사례 2]

stores (가게)

id (PK) 가게명 판매 상품
1 JSCODE 카페 JS아메리카노, JS카페라떼
2 재성이네 국밥 재성이네 돼지국밥, 재성이네 육개장, 재성이네 수육

위 사례를 살펴보면 한 칸에 2가지 이상의 정보가 들어가있는 걸 확인할 수 있다.

 

“왜 한 칸에 2가지 이상 정보가 들어가면 안 되는걸까?”

 

 

 

판매 상품 조회해서 사용할 때마다 -> 중간에 있는 콤마(,)를 제거하고 배열에 집어넣는 로직을 넣어야 함

판매 상품 삽입, 삭제 시 -> 항상 콤마(,)를 신경써서 작업해야 함

한 칸에 데이터를 여러 개 집어넣다보면 -> 실수로 데이터를 중복해서 삽입 가능성 발생

따라서 한 칸에는 한 가지의 정보만 넣으려고 하는 것

 

✅ 한 칸에 2개 이상의 정보가 들어가있을 땐?

한 칸에 2가지 이상의 정보가 들어가있을 때는 테이블을 분리하면 된다.

테이블을 분리함으로써 한 칸에 한 가지 정보만 들어가도록 해야 한다.

 

[사례 1 - 테이블 분리]

users (사용자)

id (PK)  이름
1 박재성
2 김시안

 

emails (이메일)

id (PK) 이메일
1 js123@naver.com
2 js00@naver.com
3 king123@naver.com
4 queen123@naver.com

테이블을 분리하는 것까진 좋은데 위와 같이 테이블을 분리하면, 특정 사용자의 이메일 주소를 알 수 있는 방법이 없다.

특정 사용자의 이메일 주소가 어떤 건지 알 수 있게 테이블을 보완해보자.

 

[사례 1 - 잘못된 분리]

users (사용자)

id (PK) 이름 사용자 id (FK)
1 박재성 1, 2
2 김시안 3, 4

 

emails (이메일)

id (PK) 이메일
1 js123@naver.com
2 js00@naver.com
3 king123@naver.com
4 queen123@naver.com

위와 같이 데이터를 저장하니 특정 사용자의 이메일 주소를 알 수는 있게 됐다.

하지만 한 칸에 2가지 이상의 정보가 다시 들어가게 됐다.

이럴 때는 FK를 다른 테이블로 옮겨보자.

즉, FK의 위치를 users 테이블에서 emails 테이블로 옮겨보자.

 

[사례 1 - 최종]

users (사용자)

id (PK)  이름
1 박재성
2 김시안

 

emails (이메일)

id (PK)  이메일 사용자 id (FK)
1 js123@naver.com 1
2 js00@naver.com 1
3 king123@naver.com 2
4 queen123@naver.com 2

위와 같이 데이터를 저장하니 특정 사용자의 이메일 주소도 알 수 있고, 한 칸에 한 가지의 정보만 들어가게 만들었다.

위와 같이 테이블을 분리해야 한다.

 

다시 한 번 정리해보자.

 

한 칸에 두 가지 이상의 정보가 들어가있을 땐, 테이블을 분리해서 FK를 활용해 한 칸에 한 가지의 정보만 들어가게 만들어야 한다.

 


두 번째 사례

 

[사례 2]

stores (가게)

id (PK)  가게명 판매 상품
1 JSCODE 카페 JS아메리카노, JS카페라떼
2 재성이네 국밥 재성이네 돼지국밥, 재성이네 육개장, 재성이네 수육

 

[사례 2 - 잘못된 분리]

stores (가게)

id (PK)  가게명 판매 상품 id (FK)
1 JSCODE 카페 1, 2
2 재성이네 국밥 3, 4, 5

 

products (판매 상품)

id (PK)  상품명
1 JS아메리카노
2 JS카페라떼
3 재성이네 돼지국밥
4 재성이네 육개장
5 재성이네 수육

 

[사례 2 - 최종]

stores (가게)

id (PK) 가게명
1 JSCODE 카페
2 재성이네 국밥

 

products (판매 상품)

id (PK) 상품명 가게 id (FK)
1 JS아메리카노 1
2 JS카페라떼 1
3 재성이네 돼지국밥 2
4 재성이네 육개장 2
5 재성이네 수육 2

 

🧑🏻 이 과정을 보고 데이터베이스 이론에서는 제1정규형이라고 부른다.
이런 학구적인 용어는 DB 설계를 할 수 있게 됐을 때 배워도 늦지 않다.
중요한 건 DB 설계를 하는 능력이다. 정확한 용어를 외우고 익히는 건 나중에 해라.

[규칙 1] 한 칸에는 한 가지 정보만 들어가도록 만들어라 - 2

✅ 심화) ‘한 가지 정보’라는 게 관점에 따라 달라질 수 있다.

users (사용자)

id 이름
1 박재성
2 김시온

 

users (사용자)

id 이름
1 재성
2 시온

 

박재성이라는 전체 이름이 하나의 정보?
박, 재성 각각 하나의 정보?
둘 다 올바른 관점

말 그대로 ‘한 가지 정보’라는 건 절대적 X

자신의 서비스에 맞게 판단해야 함

 

그럼 어떻게 판단해야 할까?
서비스에서 데이터의 사용 방식에 따라 결정해야 한다!

 

 

예를 들어, 서비스에서 성과 이름을 따로따로 조회해야 하는 경우가 많다면 2번째 테이블의 형태로 구성하는 게 좋다.

반대로 서비스에서 성과 이름을 따로따로 조회할 일이 없고 통째로 쓰는 경우만 있다면 1번째 테이블의 형태로 구성하는 게 좋다.


이와 비슷한 예시를 하나 더 알아보자.

stores (가게)

id  전화번호
1 0321112345
2 0521234567

stores (가게)

id  전화번호1 전화번호2 전화번호3
1 032 111 2345
2 052 123 4567

 

전화번호가 하나의 정보? 3가지의 정보?

둘 다 맞는 말이다.

어떻게 테이블을 설계해야 하는 지는 서비스에 맞게 판단하면 됨

만약 전화번호의 3가지 정보를 분리해서 따로따로 사용해야 하는 경우가 있다면 두 번째처럼 설계를 해야 함

 

✅ 요약

  • 한 칸에는 한 가지 정보만 들어가야 한다.
  • 한 칸에 두 가지 이상의 정보가 들어가있을 땐, 테이블을 분리해서 FK를 활용하면 된다.
  • 특정 테이블에 FK를 도입했을 때 규칙 1이 안 지켜진다면, 다른 테이블로 FK를 옮겨보자.
  • ‘한 가지 정보’의 기준은 절대적이지 않다. 따라서 서비스에 맞게 판단해야 한다.

[규칙 2] 어떤 테이블에 FK를 넣어도 ‘규칙 1’을 못 지킬 때는 중간 테이블을 하나 더 만들어라

✅ 어떤 테이블에 FK를 넣어도 ‘규칙 1’을 못 지킬 때는 중간 테이블을 하나 더 만들어라.

 

1.

students (학생)

id 이름 수강 과목
1 박재성 수학, 과학
2 김재은 국어, 수학
3 김지훈 국어, 과학

위 테이블을 보면 규칙 1(한 칸에는 한 가지 정보만 들어가도록 만들어라)을 안 지키고 있다.

규칙 1을 지키게 만들기 위해 테이블을 분리해보자.

 

2.

students (학생)

id 이름 수강 과목 id(FK)
1 박재성 2, 3
2 김재은 1, 2
3 김지훈 1, 3

 

courses (수강 과목)

id 과목명
1 국어
2 수학
3 과학

 

여전히 규칙 1을 안 지키고 있다.

그러면 FK를 students 테이블이 아닌 courses 테이블로 옮겨보자.

 

3.

students (학생)

id 이름
1 박재성
2 김재은
3 김지훈

 

 

courses (수강 과목)

id 과목명 학생 id
1 국어 2, 3
2 수학 1, 2
3 과학 1, 3

 

FK의 위치를 다른 테이블로 바꿔봤음도 불구하고 여전히 규칙 1이 안 지켜진다. 이럴 땐 어떻게 해야 할까?

 

어떤 테이블에 FK를 넣어도 ‘규칙 1’을 못 지킬 때는 중간 테이블을 하나 더 만들어야 한다.

 

 

4.

students (학생)

id 이름
1 박재성
2 김재은
3 김지훈

 

course_registrations (수강 과목 등록)

=> student_courses보다는 동사로 하면 좋다. 직관적으로 의미있게 지으면 가독성이 좋아진다.

id 학생 id (FK) 수강 과목 id (FK)
1 1 2
2 1 3
3 2 1
4 2 2
5 3 1
6 3 3

 

courses (수강 과목)

id 과목명
1 국어
2 수학
3 과학

 

위와 같이 테이블을 설계하면 어떤 학생이 어떤 과목들을 수강하는 지까지 다 파악할 수 있으며, 규칙 1을 지킬 수 있게된다.

 

✅ 또 다른 연습 예제

아래 테이블을 규칙 1을 지키도록 재구성해보자.

movies (영화)

id 이름 출연 배우
1 베테랑 황정민, 오달수
2 신세계 황정민, 이정재
3 관상 이정재, 송강호

 

 

1. 테이블 분리

movies (영화)

id 이름 출연 배우 id (FK)
1 베테랑 1, 2
2 신세계 1, 3
3 관상 1, 4

 

actors (배우)

id 이름
1 황정민
2 오달수
3 이정재
4 송강호

 

 

2. FK 위치 변경

movies (영화)

id 이름
1 베테랑
2 신세계
3 관상

 

 

actors (배우)

id 이름 영화 id (FK)
1 황정민 1, 2
2 오달수 1
3 이정재 2, 3
4 송강호 3

 

3. 중간 테이블 추가

movies (영화)

id 이름
1 베테랑
2 신세계
3 관상

 

 

castings (캐스팅)

=> movies_actors보다 더 직관적이다.

id 영화 id (FK) 배우 id (FK)
1 1 1
2 1 2
3 2 1
4 2 3
5 3 3
6 3 4

 

actors (배우)

id 이름
1 황정민
2 오달수
3 이정재
4 송강호