관계형 DB

류연찬·2023년 5월 19일
0

GraphQL

목록 보기
11/17

데이터 정규화?

백엔드 개발자는 데이터를 다루는 일이 굉장히 중요합니다.

쇼핑몰을 만들어야 한다고 생각해보겠습니다.

여기에 들어갈 데이터는 양도 많고, 종류도 많습니다.

그렇기 때문에 처음부터 설계를 잘해서 데이터를 정의해야합니다.

데이터 정규화 는 쉽게 말해, 중복 데이터를 분리하는 것입니다.

정규형 Normal Form

정규화가 된 결과를 정규형이라고 합니다.

정규형의 종류에는 여러가지가 있지만, 실무에서는 일부(노란색 상자)만 사용하게 됩니다.

따라서 우리는 모든 정규형을 살펴보지 않고 실무에서 주로 사용되는 제 3 정규형까지 만들어보겠습니다.

💡 정규화는 단계적으로 진행되야한다는 점에 유의하세요!


비정규화

처음에는 모든 데이터가 하나의 테이블에 다 담겨있습니다.

정규화되지 않은 상태입니다.

[주문] 테이블

주문번호날짜이름나이주문 상품
P00110/23철수13A001 레고 1개, A002 미니카 2개
P00208/13영희15A003 인형 1개, A001 레고 2개
P00309/07훈이12A003 인형 2개, A002 미니카 1개

위와 같은 상태에서는 데이터를 수정하고 삭제할 때 문제가 생길 수 있습니다.

예를 들어 P001 주문에서 주문 상품을 레고 2개로 변경하려면 주문 상품의 데이터 값에서 '레고'를 찾아서 그 뒤의 숫자 부분을 찾아서 1을 2로 바뀐다? 너무 이상합니다.

나이를 바꾼다면 age = 20 이런식으로 한번에 바꿀 수 있습니다.

제 1 정규화

위의 테이블처럼 한 줄에 여러 데이터가 있는 것을 다가 속성(Multivalued Attributed)이라고 합니다.

첫번째로 할 일은, 엑셀 하나의 칸에는 하나의 값 만 들어가도록 만들어줍니다.

이것이 제 1 정규화 입니다.

주문 상품 컬럼의 값을 한개씩 갖도록 나누면 아래와 같습니다.

주문번호날짜이름나이주문 상품
P00110/23철수13A001 레고 1개
P00110/23철수13A002 미니카 2개
P00208/13영희15A003 인형 1개
P00208/13영희15A001 레고 2개
P00309/07훈이12A003 인형 2개
P00309/07훈이12A002 미니카 1개

그런데 이번에는 주문 상품 컬럼에 속성이 여러개(상품 번호, 상품 수량) 들어있습니다.

이를 복합 속성이라고 합니다.

하나의 칸에는 하나의 값만 들어가도록 만드는 것이 제 1 정규화라고 했습니다.

따라서 주문 상품 컬럼을 또 분리해주겠습니다.

주문번호날짜이름나이상품 번호상품명상품 수량
P00110/23철수13A001레고1개
P00110/23철수13A002미니카2개
P00208/13영희15A003인형1개
P00208/13영희15A001레고2개
P00309/07훈이12A003인형2개
P00309/07훈이12A002미니카1개

그런데 주문번호부터 나이까지 같은 데이터가 2줄씩 들어가있습니다.

분리하다보니, 중복 데이터가 발생한 것입니다.

이런 상황에서는 철수의 이름을 바꾸려면 2줄을 바꿔야합니다.

아래와 같이 테이블을 2개로 분리함으로써 이를 개선할 수 있습니다.

[주문] 테이블

주문번호날짜이름나이
P00110/23철수13
P00208/13영희15
P00309/07훈이12

[주문_상품] 테이블

주문번호상품 번호상품명상품 수량
P001A001레고1개
P001A002미니카2개
P002A003인형1개
P002A001레고2개
P003A003인형2개
P003A002미니카1개

제 2 정규화

제 2 정규화에 대해서 알아보기전에 PK(기본키)에 대해서 설명하겠습니다.

PK(Primary Key)는 한 줄의 데이터를 구분할 수 있는 유일한 키를 말합니다.

주문 테이블을 보면, 주문번호를 알면 날짜, 이름, 나이를 구분할 수 있습니다.

날짜를 안닥 주문 번호를 알거나 이름을 알 수는 없습니다.

같은 날짜에 여러번 주문을 할 수도 있기 때문이죠.

주문_상품 테이블은 주문번호나 상품번호 한가지만 알아서는 어떤 상품을 주문했는지 알 수 없습니다.

주문번호상품번호 둘 다 알아야 합니다.

이를 복합키라고 합니다.

주문_상품 테이블의 경우처럼 복합키로 구성되어 있을 때, 나머지 컬럼은 이 두가지 모두에 종속되어야합니다.

즉, 상품 수량을 알기 위해서는 주문 번호와 상품 번호를 모두 알아야합니다.

하지만, 상품명은 상품번호만 알면 알 수 있습니다.

따라서 상품명은 복합키 중 일부에만 종속적입니다.

이런 컬럼을 분리시키는 것이 제 2 정규화입니다.

따라서 [주문_상품] 테이블에서 상품 번호와 상품명을 아래와 같이 분리하겠습니다.

[주문] 테이블

주문번호날짜이름나이
P00110/23철수13
P00208/13영희15
P00309/07훈이12

[주문_상품] 테이블

주문번호상품 번호상품 수량
P001A0011개
P001A0022개
P002A0031개
P002A0012개
P003A0032개
P003A0021개

[상품] 테이블

상품 번호상품명
A001레고
A002미니카
A003인형

제 3 정규화

A -> B -> C의 관계를 가지고 있을때, A와 B, B와 C를 묶어 다른 테이블로 분리하는 것이 제 3 정규화입니다.

주문 테이블을 보면 주문번호와 나이는 상관이 없어 보입니다.

주문 번호를 알면 누군인지 알 수 있고, 누구인지 알면 그 사람의 나이를 알 수 있습니다.

따라서 주문 테이블에서 고객 정보를 고객 테이블로 분리합니다.

[주문] 테이블

주문번호날짜고객번호
P00110/23U001
P00208/13U002
P00309/07U003

[고객] 테이블

고객번호이름나이
U001철수13
U002영희15
U003훈이12

정리된 표

제 3 정규화까지 거쳐서 정리된 표는 아래와 같습니다.

[주문] 테이블

주문번호날짜고객번호
P00110/23U001
P00208/13U002
P00309/07U003

[고객] 테이블

고객번호이름나이
U001철수13
U002영희15
U003훈이12

[주문_상품] 테이블

주문번호상품 번호상품 수량
P001A0011개
P001A0022개
P002A0031개
P002A0012개
P003A0032개
P003A0021개

[상품] 테이블

상품 번호상품명
A001레고
A002미니카
A003인형

상품 ERD

우리가 만드는 쇼핑몰에 필요한 데이터베이스를 설계해보겠습니다.

상품 정보는 엑셀에 저장하겠습니다.

상품 정보에는 아래의 내용이 들어갑니다.



비정규화

처음에는 모든 데이터가 하나의 테이블에 다 담겨있습니다.

처음에 표에셔 상품태그 열을 보면 한 칸에 여러값이 들어가 있습니다.

이 부분을 분리해 하나의 값 만 가지도록 해줍니다.



상품 태그 테이블 분리

아래와 같이 상품 테이블 에서 태그를 분리해 따로 표를 만들었습니다.

그래거 상품 테이블 에서 상품ID의 중복이 사라졌습니다.

[상품_상품태그] 테이블

[상품] 테이블



상품과 상품 태그를 연결하는 중간 테이블

그런데 여기도 보면 전자제품 이라는 값이 중복됩니다.

[상품_상품태그] 테이블

상품 태그를 위한 표만 따로 만들고, 여기서 만든 ID를 [상품_상품태그] 테이블 에 연결해줍니다.

이렇게 했을 때, [상품 태그] 테이블 을 보면 태그 값('전자제품')의 중복은 사라졌습니다.

[상품 태그] 테이블

[상품_상품태그] 테이블



카테고리 테이블 분리

다시 상품 테이블을 보면 카테고리의 값들이 중복되어 보입니다.

상품에 카테고리가 종속되는 것이 아니라, 카테고리에 상품이 종속되기 때문에 분리해주겠습니다.

[상품] 테이블

먼저 카테고리 테이블을 만들어줍니다.

[카테고리] 테이블

상품 테이블에 카테고리 값을 직접 넣지 말고, 카테고리 테이블의 ID를 연결해줍니다.

[상품] 테이블



판매자 분리

[상품] 테이블

[상품] 테이블을 보면 상품을 알면 판매자를 알 수 있고, 판매자를 알면 이메일을 알 수 있ㅅ브니다.

그래서 상품과 판매자 정보는 A -> B -> C의 관계를 가지고 있을때, A와 B, B와 C를 묶어 다른 테이블로 분리하는 것이 제 3 정규화입니다.

먼저 판매자 관련 정보를 상품 테이블에서 분리합니다.

[상품 판매자] 테이블

이렇게 만든 [상품 판매자] 의 판매자 ID를 [상품] 테이블에 연결시킵니다.

[상품] 테이블



마찬가지로, 거래 위치 부분도 [상품] 테이블에서 분리하겠습니다.

[상품] 테이블

[상품 거래 위치] 테이블



정리된 표

제 3 정규화까지 거쳐서 정리된 표는 아래와 같습니다.

[상품] 테이블

[상품 거래 위치] 테이블

[카테고리] 테이블

[상품 판매자] 테이블

[상품 태그] 테이블

[상품_상품태그] 테이블



ERD(Entity-Relationship Diagram) 도구

제 3 정규화까지 해보면서 엑셀로 표를 나눴지만, 여러개의 표들 사이의 관계는 보이지 않습니다.

테이블 간의 관계를 보여주는 그림을 *ERD**라고 합니다.

여기서는 무료인 ERDCloud를 사용합니다.



위에서 엑셀로 설계했던 데이터 구조와 관계를 ERD로 그려보면 아래와 같습니다.

위에서 완성했던 엑셀 표랑 비교해보면, 컬럼 하나하나를 ERD Cloud에서 작성해주면 됩니다.

테이블 관계를 보기 위한 다이어그램이기 때문에, 실제 데이터 값은 적지 않습니다.



PK & FK

PK는 기본키로 그 테이블에서 데이터들을 구분할 수 있는 유니크한 값이라고 했습니다.

따라서 여기는 상품IDid 라는 이름으로 정했습니다.

FK는 외래키로 다른 테이블에서 값을 참조할 때 참조해오는 테이블의 PK(기본키)를 말합니다.

따라서 상품의 테이블에서 상품 카테고리, 유저, 상품거래위치 테이블을 참조해오기 때문에 FK를 작성해주었습니다.

1:1, 1:N, N:M

이렇게 다른 테이블과 연결시킨다고 할 때, 두 테이블이 1:1 관계, 1:N 관계, N:M 관계인지 설정해줘야합니다.

상품상품거래위치 테이블의 관계를 먼저 생각해봅시다.

중고 상품이기 때문에 상품 데이터 하나가 가질 수 있는 상품거래위치는 하나밖에 없습니다.

따라서 이 두 테이블의 관계는 1:1 입니다.



이번엔 판매자(유저)상품 테이블의 관계를 생각해볼까요?

유저 한명은 여러개의 상품을 올리 수 있습니다.

상품 하나는 하나의 유저밖에 가질 수 없습니다.

따라서 이 두 테이블의 관계는 1:N 입니다.



마찬가지로, 상품 카테고리 하나에는 여러 상품이 들어있을 수 있습니다.

하지만 상품은 하나의 카테고리밖에 가지지 못합니다.

따라서 이 둘의 관계도 1:N 입니다.



마지막으로 상품과 상품태그 테이블은 N:N 관계입니다.

상품 하나는 여러개의 태그를 가질 수 있고, 태그도 하나의 태그가 여러 상품에 사용될 수 있습니다.

이렇게 N:M일 경우에는 상품_상품태그 테이블처럼 중간 테이블을 만들어 사이에 두고 각각 1:N의 관계를 갖도록 그려줍니다.

0개의 댓글