엔티티-관계 모델링
고친 사람 github-actions[bot]
엔티티-관계 모델링은 테이블을 짜기 전에 시스템이 다룰 대상과 그 사이의 이어짐부터 그림으로 정리합니다. 고객과 주문과 상품은 상자로 그립니다. 고객이 주문을 한다는 이어짐은 선으로 긋습니다. 이 그림을 정해진 규칙으로 옮기면 서비스용 데이터베이스의 테이블이 나옵니다.
쉽고 빠른 이해
무슨 일을 하나 — 테이블을 만들기 전에 다룰 대상과 그 이어짐을 그림 한 장으로 정리합니다. 쇼핑몰이라면 고객·주문·상품을 상자로, 「고객이 주문을 한다」를 선으로 그립니다.
왜 이렇게 하나 — 테이블부터 만들면 빠뜨린 대상이나 잘못 센 개수가 데이터가 쌓인 뒤에야 드러납니다. 그때 고치려면 테이블과 데이터를 함께 옮겨야 합니다. 그림 단계에서는 지우고 다시 그리면 끝납니다.
어떻게 도나
- 요구사항에서 따로 기록할 대상을 뽑습니다
- 대상끼리 어떻게 이어지는지, 몇 대 몇인지 적습니다
- 대상은 테이블로, 이어짐은 다른 테이블을 가리키는 열이나 짝을 적는 테이블로 옮깁니다
대가 — 같은 값을 한 곳에만 두려고 테이블이 잘게 나뉩니다. 여러 테이블을 엮어 집계하는 분석 질문은 테이블을 많이 이어 붙여야 합니다. 그래서 한 건씩 넣고 고치는 서비스용 데이터베이스에 씁니다. 집계 위주인 분석용 테이블은 다른 방법으로 짭니다.
상세
이 절은 작은 쇼핑몰의 요구사항 세 줄을 테이블까지 들고 갑니다. 먼저 요구사항에서 구성 요소를 뽑습니다. 그것으로 그림을 그립니다. 그 그림을 테이블로 옮깁니다.
고객은 이메일과 이름을 가진다. 고객은 주문을 여러 번 할 수 있다. 주문 하나에는 상품이 여러 개 담기고, 상품 하나도 여러 주문에 담긴다.
ER(Entity-Relationship, 엔티티-관계) 모델링은 이런 문장에서 엔티티, 속성, 관계 세 가지를 뽑아냅니다. 이름은 그 가운데 엔티티와 관계에서 왔습니다.
그림부터 그리는 이유
요구사항을 읽자마자 테이블을 만들 수도 있습니다. 그러면 빠뜨린 대상이나 잘못 센 개수가 데이터가 쌓인 뒤에야 드러납니다. 주문 하나에 상품이 하나뿐이라고 잘못 읽었다면, 주문 테이블에 상품번호 열 하나를 두고 시작하게 됩니다.
그 잘못을 나중에 고치려면 테이블을 새로 만들고 쌓인 데이터까지 옮겨야 합니다. 그림 단계에서는 선 하나를 다시 그리면 끝납니다. 그림은 업무 담당자도 읽을 수 있어서 틀린 곳을 만들기 전에 함께 짚을 수 있습니다.
엔티티
문장에 나오는 명사 가운데 따로 기록하고 따로 찾아야 하는 것이 엔티티입니다. 위 요구사항에서는 고객, 주문, 상품이 엔티티입니다. 고객은 천 명이 쌓일 수 있습니다. 그중 한 명을 골라 볼 일도 생깁니다.
엔티티라는 말은 종류와 그 종류의 하나를 둘 다 가리킬 때가 있습니다. 「고객」이라는 종류와 「김철수라는 고객 한 명」입니다. 이 문서에서는 종류를 엔티티라 부릅니다. 그 종류의 하나는 「고객 한 명」처럼 풀어 씁니다.
속성
엔티티에 붙어 다니는 값 하나하나가 속성입니다. 고객의 이메일과 이름이 속성입니다. 속성은 혼자서는 뜻이 없습니다. 어느 고객의 이메일인지가 붙어야 뜻이 생깁니다.
명사 하나가 엔티티인지 속성인지 헷갈릴 때가 있습니다. 가르는 질문은 「이것에도 따로 적을 값이 붙나」입니다. 주소가 문자열 한 줄이면 고객의 속성입니다. 고객 한 명이 배송지를 여럿 둘 수 있다고 합시다. 배송지마다 받는 사람도 적는다면 배송지는 엔티티로 올라갑니다.
식별자
고객 한 명 한 명을 서로 가려내는 속성이 식별자입니다. 이름은 겹칠 수 있어서 식별자가 못 됩니다. 그래서 고객번호처럼 겹치지 않는 값을 둡니다.
식별자는 테이블로 옮기면 기본 키가 됩니다. 상품 바코드처럼 업무에 원래 있는 값을 쓸 수도 있습니다. 일련번호를 새로 매길 수도 있습니다.
관계
엔티티 사이의 이어짐이 관계입니다. 「고객이 주문을 한다」와 「주문에 상품이 담긴다」가 관계입니다. 관계에는 동사로 이름을 붙여 둡니다. 그러면 그림을 문장처럼 읽을 수 있습니다.
카디널리티와 참여 제약
관계마다 몇 대 몇으로 이어지는지 적습니다. 이것을 관계의 카디널리티라고 부릅니다. 테이블로 옮길 때 무엇을 어디에 둘지가 이 값으로 정해집니다. 카디널리티는 세 가지입니다.
| 카디널리티 | 뜻 | 쇼핑몰의 예 |
|---|---|---|
| 일대일 | 양쪽 모두 상대 하나와만 이어진다 | 고객과 회원 설정 |
| 일대다 | 한쪽 하나가 다른 쪽 여럿과 이어진다 | 고객과 주문 |
| 다대다 | 양쪽 모두 상대 여럿과 이어질 수 있다 | 주문과 상품 |
몇 대 몇과 함께 「상대가 반드시 있어야 하나」도 적습니다. 주문은 고객 없이 생기지 않습니다. 고객은 주문이 하나도 없어도 됩니다.
이 구분이 참여 제약입니다. 테이블로 옮길 때 빈 값을 허용할지가 이것으로 정해집니다.
ER 다이어그램
엔티티와 속성과 관계를 모아 그린 그림이 ER 다이어그램입니다. 지금 가장 흔히 보는 꼴은 까마귀발 표기법입니다. 엔티티는 상자로, 관계는 선으로 그립니다. 카디널리티와 참여 제약은 선 끝 모양으로 적습니다.
erDiagram
direction TB
고객 ||--o{ 주문 : "한다"
주문 }o--|{ 상품 : "담는다"
선 끝의 기호는 세 가지입니다. 세 갈래는 「여럿」, 세로 막대는 「하나」, 동그라미는 「없을 수도 있음」입니다.
선 끝마다 기호가 둘씩 붙습니다. 두 기호의 뜻을 합쳐 읽습니다. 막대가 둘이면 「반드시 하나」, 막대와 세 갈래는 「하나 이상」, 동그라미와 세 갈래는 「없거나 여럿」입니다.
고객과 주문 사이 선부터 읽습니다. 고객 쪽 끝의 막대 둘은 주문 하나에 고객이 반드시 한 명 있다는 뜻입니다. 주문 쪽 끝은 고객 한 명의 주문이 없을 수도 여럿일 수도 있다는 뜻입니다.
주문과 상품 사이 선도 같은 방법으로 읽습니다. 주문 하나에는 상품이 하나 이상 담깁니다. 상품 하나는 아무 주문에도 안 담겼을 수도, 여러 주문에 담겼을 수도 있습니다.
첸 표기법
ER 모델은 Peter Chen 이 처음 내놓았습니다. 그때 쓴 그림은 생김새가 다릅니다. 엔티티는 상자, 관계는 마름모, 속성은 타원으로 그립니다. 이 꼴이 첸 표기법입니다.
첸 표기법으로 「고객이 주문을 한다」를 그리면 고객과 주문 사이에 마름모가 끼어듭니다. 선 위의 1 과 N 이 일대다를 뜻합니다.
flowchart TD
A1(["이메일"]) --- E1["고객"]
E1 ---|"1"| R1{"한다"}
R1 ---|"N"| E2["주문"]
E2 --- A2(["주문일"])
마름모가 따로 있으니 관계에도 속성을 달 수 있습니다. 위 그림에는 없는 예로, 주문과 상품 사이의 「수량」이 그런 속성입니다. 수량은 주문 하나에만 속하지도, 상품 하나에만 속하지도 않습니다. 어느 주문에 어느 상품을 몇 개 담았나로 정해집니다.
두 표기법은 같은 구성 요소를 다른 모양으로 그립니다. 엔티티만은 둘 다 상자입니다.
| 구성 요소 | 첸 표기법 | 까마귀발 표기법 |
|---|---|---|
| 엔티티 | 상자 | 상자 |
| 관계 | 마름모 | 선 |
| 속성 | 엔티티에 매단 타원 | 상자 안에 적는 줄 |
| 카디널리티 | 선 위의 1 · N · M | 선 끝의 막대 · 세 갈래 |
첸 표기법은 개념을 설명할 때 자주 씁니다. 실무의 설계 도구는 대개 까마귀발 표기법으로 그립니다. 상자 안에 속성을 적어 넣으니 그림이 덜 퍼집니다.
테이블로 옮기는 규칙
그림이 끝나면 테이블로 옮깁니다. 옮기는 규칙은 거의 기계적이라 표 하나로 모입니다.
| 그림의 요소 | 테이블에서 |
|---|---|
| 엔티티 | 테이블 하나 |
| 속성 | 열 하나 |
| 식별자 | 기본 키 |
| 일대다 관계 | 「다」 쪽 테이블에 「일」 쪽 기본 키를 담는 열 |
| 다대다 관계 | 두 쪽 기본 키를 함께 담는 테이블을 새로 둔다 |
| 일대일 관계 | 한쪽에 상대 기본 키를 담는 열을 두고 같은 값이 두 번 못 들어가게 막는다 |
다른 테이블의 기본 키 값을 담아 그 행을 가리키는 열이 외래 키입니다. 주문 테이블의 고객번호 열이 외래 키입니다. 주문 하나를 보고 누가 주문했는지 찾아갈 수 있습니다.
일대다에서 외래 키는 언제나 「다」 쪽에 둡니다. 「일」 쪽인 고객 테이블에 두면 고객 한 명의 행에 주문번호를 여럿 담아야 합니다. 열 하나에는 값 하나만 들어가니 그렇게 담을 수 없습니다.
참여 제약은 여기서 쓰입니다. 주문은 반드시 고객이 있어야 하니 주문 테이블의 고객번호 열은 빈 값을 막습니다.
연결 테이블
주문과 상품은 다대다입니다. 주문 테이블에 상품번호 열 하나를 두면 상품을 하나밖에 못 담습니다. 상품 테이블에 주문번호 열을 두어도 같은 문제가 생깁니다.
그래서 둘 사이에 주문항목 테이블을 새로 둡니다. 한 행이 주문 하나와 상품 하나의 짝입니다. 이렇게 다대다를 담으려고 새로 두는 테이블이 연결 테이블입니다.
| 주문번호 | 상품번호 | 수량 |
|---|---|---|
| 1 | 10 | 2 |
| 1 | 20 | 1 |
| 2 | 10 | 3 |
주문 1 에는 상품이 두 개 담겼습니다. 상품 10 은 주문 1 과 주문 2 에 다 들어갔습니다. 관계의 속성이던 수량도 이 테이블의 열이 됩니다.
테이블을 만드는 문장에서는 주문번호와 상품번호가 각각 주문 테이블과 상품 테이블을 가리키게 합니다.
CREATE TABLE 주문항목 (
주문번호 BIGINT NOT NULL REFERENCES 주문,
상품번호 BIGINT NOT NULL REFERENCES 상품,
수량 INT NOT NULL,
PRIMARY KEY (주문번호, 상품번호)
);
방금 본 테이블은 외래 키 두 개를 묶어 기본 키로 씁니다. 그래서 한 주문에 같은 상품 행이 두 번 생기지 않습니다. 여러 열을 묶은 이런 기본 키를 복합 키라고 합니다.
연결 테이블을 그림에 넣으면 다대다 선 하나가 일대다 선 둘로 바뀝니다. 이번에는 상자 안에 열과 키도 적었습니다. PK(primary key) 는 기본 키, FK(foreign key) 는 외래 키 표시입니다.
erDiagram
direction TB
고객 ||--o{ 주문 : "한다"
주문 ||--|{ 주문항목 : "담는다"
상품 ||--o{ 주문항목 : "들어간다"
고객 {
BIGINT 고객번호 PK
TEXT 이메일
TEXT 이름
}
주문 {
BIGINT 주문번호 PK
BIGINT 고객번호 FK
DATE 주문일
}
주문항목 {
BIGINT 주문번호 PK,FK
BIGINT 상품번호 PK,FK
INT 수량
}
상품 {
BIGINT 상품번호 PK
TEXT 이름
}
상자 안의 한 줄은 자료형, 열 이름, 키 표시 차례입니다. 외래 키인 고객번호가 「다」 쪽인 주문 상자에 들어 있습니다.
약한 엔티티
주문항목은 주문 없이는 뜻이 없습니다. 상품번호만으로는 어느 주문의 항목인지 구별할 수 없어서 주문번호를 빌려 와야 합니다. 이렇게 다른 엔티티의 식별자를 빌려야 한 행씩 구별되는 엔티티를 약한 엔티티라고 합니다.
약한 엔티티는 기대는 쪽이 지워지면 함께 지워지는 것이 자연스럽습니다. 주문을 지우면 그 주문항목도 남겨 둘 필요가 없습니다. 첸 표기법에서는 약한 엔티티를 테두리가 두 겹인 상자로 그려 구분합니다.
정규화로 이어지는 길
ER 모델링으로 짠 테이블은 대체로 같은 값을 한 곳에만 둡니다. 상품 이름은 상품 테이블에만 있습니다. 고객 이메일은 고객 테이블에만 있습니다. 엔티티마다 테이블을 나눴기 때문입니다.
같은 값이 두 곳에 저장되지 않게 테이블을 나누는 일을 정규화라고 합니다. 상품 이름이 한 곳에만 있으면 이름을 고칠 때 한 행만 고치면 됩니다. 두 곳에 있으면 한쪽만 고쳐져 값이 서로 어긋날 수 있습니다.
ER 모델링이 정규화의 큰 몫을 미리 해 줍니다. 그래도 속성을 엔티티에 잘못 붙이면 중복이 남습니다. 그래서 테이블로 옮긴 뒤에 한 번 더 점검합니다.
이때 잣대로 쓰는 것이 정규형입니다. 정규형은 테이블이 중복을 얼마나 걷어 냈는지 단계별로 재는 기준입니다. 제1정규형, 제2정규형처럼 번호가 붙고 번호가 클수록 조건이 엄격합니다.
개념 모델에서 물리 모델까지
데이터 모델링은 흔히 세 단계로 나눕니다. 같은 내용을 업무의 말에서 저장 장치 쪽으로 차츰 옮겨 갑니다. ER 모델링의 그림은 앞의 두 단계에 걸쳐 쓰입니다.
| 단계 | 정하는 것 | 쇼핑몰의 예 |
|---|---|---|
| 개념 모델 | 다룰 엔티티와 관계 | 고객이 주문을 한다 |
| 논리 모델 | 테이블 · 열 · 키 | 주문 테이블에 고객번호 외래 키를 둔다 |
| 물리 모델 | 쓸 데이터베이스에서의 저장 방식 | 고객번호 열에 인덱스를 건다 |
「ER 다이어그램」 소절의 그림처럼 엔티티와 관계만 그린 것이 개념 모델입니다. 「연결 테이블」 소절의 그림처럼 열과 키까지 적어 넣으면 논리 모델에 가깝습니다.
조인이 늘어나는 대가
ER 모델링으로 짠 테이블은 읽는 쪽에서 값을 치릅니다. 테이블이 잘게 나뉘어 있습니다. 그래서 여러 엔티티를 엮어 보는 질문은 테이블을 여럿 이어 붙여야 합니다. 두 테이블을 같은 값끼리 이어 붙이는 연산이 조인입니다.
「지난 분기 카테고리별 매출」을 물으면 주문, 주문항목, 상품, 카테고리를 차례로 조인해야 합니다. 행이 많아질수록 이런 질문은 무거워집니다. 쓰기를 쉽게 하려고 나눈 모양이 집계에서는 짐이 되는 것입니다.
차원 모델링과 견준 모습
서비스용 테이블을 짜는 ER 모델링과 분석용 테이블을 짜는 차원 모델링은 자주 나란히 놓입니다. 두 방법은 맞춘 일부터 다릅니다.
| ER 모델링 | 차원 모델링 | |
|---|---|---|
| 맞춘 일 | 한 건씩 넣고 고치기 | 많은 행을 훑어 집계하기 |
| 출발점 | 업무에 나오는 대상과 관계 | 답할 분석 질문과 그 숫자 |
| 같은 값 | 한 곳에만 둔다 | 여러 곳에 되풀이한다 |
| 테이블 모양 | 잘게 나뉜 테이블이 그물처럼 이어진다 | 숫자를 담는 테이블 하나를 기준 테이블들이 둘러싼다 |
한 회사에는 한 건씩 넣고 고치는 일과 많은 행을 모아 집계하는 일이 다 있습니다. 그래서 두 방법을 함께 씁니다.
서비스는 ER 모델로 짠 데이터베이스에 씁니다. 그 데이터를 주기적으로 옮겨 차원 모델로 다시 담습니다.
쓰는 곳과 안 쓰는 곳
ER 모델링은 주문, 회원, 결제처럼 한 건씩 넣고 고치는 서비스용 관계형 데이터베이스에서 씁니다. 다룰 대상이 분명하고 같은 값이 어긋나면 안 되는 곳입니다. 백엔드 코드의 테이블 대부분이 이 방법으로 설계됩니다.
코드 쪽에서도 같은 말을 씁니다. ORM(Object-Relational Mapping, 객체-관계 매핑) 도구는 테이블 하나에 클래스 하나를 맞춰 다루게 해 줍니다. 그 클래스를 흔히 엔티티 클래스라고 부릅니다. ER 모델의 엔티티가 코드로 옮겨진 것입니다.
분석용 집계 테이블에는 쓰지 않습니다. 조인이 많아 집계가 무겁기 때문입니다. 이런 테이블은 앞 소절의 차원 모델링으로 짭니다.
문서 데이터베이스나 키-값 저장소처럼 조인이 없거나 약한 저장소에도 테이블로 옮기는 규칙은 맞지 않습니다. 엔티티마다 나눠 두면 다시 모으는 일을 애플리케이션이 떠맡습니다. 그래서 이런 저장소는 읽을 모양부터 정합니다. 함께 읽는 값은 한 덩어리로 묶어 저장합니다. 대상과 관계를 그림으로 정리하는 앞 단계는 이때도 쓸모가 있습니다.
관련 항목
엔티티-관계 모델을 이루는 구성 요소
엔티티 · 속성 · 관계 · 식별자 · 카디널리티 · 참여 제약 · 약한 엔티티
엔티티-관계 모델을 그리는 표기법
ER 다이어그램 · 첸 표기법 · 까마귀발 표기법 · IDEF1X · UML 클래스 다이어그램
테이블로 옮기며 생기는 키와 구조
테이블 · 기본 키 · 외래 키 · 복합 키 · 연결 테이블 · 자연 키 · 대리 키 · 참조 무결성
엔티티-관계 모델링이 속하는 설계 단계
데이터 모델링 · 개념 모델 · 논리 모델 · 물리 모델
엔티티-관계 모델로 짠 테이블을 다듬는 규칙
정규화 · 제1정규형 · 제2정규형 · 제3정규형 · 반정규화
엔티티-관계 모델이 바탕으로 삼는 데이터 모델과 데이터베이스
관계형 모델 · 관계형 데이터베이스 · 스키마 · 조인 · SQL
엔티티-관계 모델링과 맞세워지는 설계 방법
차원 모델링 · 데이터 볼트 · 원 빅 테이블 · 스타 스키마
엔티티를 코드의 객체로 옮기는 도구와 설계
ORM · 도메인 모델 · 도메인 주도 설계 · 액티브 레코드
엔티티-관계 모델링이 잘 맞지 않는 저장소
문서 데이터베이스 · 키-값 저장소 · 와이드 컬럼 저장소 · 데이터 웨어하우스
다른 이름: entity-relationship modeling · entity-relationship modelling · ER modeling · ER 모델링 · E-R 모델링 · ER 모델 · 엔티티-관계 모델 · 개체-관계 모델링