icon

안동민 개발노트

7장 : 데이터 모델링과 ERD

개체-관계 모델 (ER Model)


ER 모델(Entity-Relationship Model)은 데이터를 개체(Entity), 속성(Attribute), 관계(Relationship)의 세 가지 요소로 표현하는 데이터 모델링 방법입니다. 1976년 피터 첸(Peter Chen)이 제안한 이 모델은 현실 세계의 복잡한 데이터 구조를 직관적으로 표현할 수 있어, 데이터베이스 설계의 사실상 표준으로 자리 잡았습니다. ER 모델의 결과물인 ERD(Entity-Relationship Diagram)는 설계자, 개발자, 기획자 모두가 소통하는 공용 언어 역할을 합니다.


개체 (Entity)

개체(Entity)는 현실 세계에서 독립적으로 존재하며, 다른 것과 구별할 수 있는 대상입니다. 사람, 장소, 사건, 개념 등 데이터베이스에서 관리해야 할 모든 것이 개체가 될 수 있습니다.

개체를 정확히 이해하려면 개체 타입(Entity Type)개체 인스턴스(Entity Instance)를 구분해야 합니다. 개체 타입은 같은 종류의 개체들을 묶어 정의한 것으로, 관계형 모델에서 릴레이션 스키마에 대응됩니다. 개체 인스턴스는 개체 타입에 속하는 구체적인 하나하나의 데이터로, 튜플에 대응됩니다.

개체 타입과 개체 인스턴스
개체 타입: 학생(학번, 이름, 학과)

개체 인스턴스
  (2024001, 김철수, 컴퓨터공학과)
  (2024002, 이영희, 전자공학과)
  (2024003, 박민수, 수학과)

관계형 모델 대응
  개체 타입   → 릴레이션 스키마 (테이블 구조)
  개체 인스턴스 → 튜플 (행)
  개체 집합   → 릴레이션 인스턴스 (테이블 데이터)

개체의 종류

개체는 그 성격에 따라 여러 유형으로 분류됩니다.

강한 개체(Strong Entity)는 다른 개체에 의존하지 않고 자체적인 식별자로 독립적으로 존재하는 개체입니다. ERD에서 단일 직사각형으로 표현합니다. 학생, 직원, 상품, 부서 등이 강한 개체입니다.

약한 개체(Weak Entity)는 자신만의 식별자로는 유일하게 식별될 수 없고, 다른 개체(소유 개체, Owner Entity)에 의존하는 개체입니다. ERD에서 이중 직사각형으로 표현합니다. 약한 개체는 소유 개체의 기본키와 자신의 부분키(Partial Key, Discriminator)를 결합해야 유일하게 식별됩니다.

강한 개체와 약한 개체
  강한 개체              약한 개체
┌──────────┐           ╔══════════╗
│  건  물  │           ║  강의실  ║  (이중 직사각형으로 표기)
│ #건물코드│───소속───▶║ #호실번호║
│  건물명  │           ║  수용인원║
└──────────┘           ╚══════════╝

강의실의 PK = 건물코드(FK) + 호실번호(부분키)

"101호"만으로는 유일하지 않지만,
"공학관 101호"라면 유일하게 식별 가능

약한 개체의 대표적인 예시를 더 살펴보겠습니다.

약한 개체 추가 예시
주문(Order) ──소유──→ 주문상세(OrderItem)
  #주문번호               #순번(1,2,3...)
                          상품명, 수량, 가격

직원(Employee) ──소유──→ 부양가족(Dependent)
  #사원번호                 #이름
                           관계(배우자, 자녀)

서적(Book) ──소유──→ 챕터(Chapter)
  #ISBN                   #장번호
                          제목

약한 개체의 핵심 특성은 소유 개체가 삭제되면 함께 삭제된다는 것입니다. 주문이 삭제되면 주문상세도 의미가 없어집니다. 이것은 SQL에서 ON DELETE CASCADE로 구현됩니다.


속성 (Attribute)

속성(Attribute)은 개체의 특성이나 성질을 나타내는 것입니다. 학생의 이름, 나이, 이메일 등이 속성입니다. ER 모델에서 속성은 타원으로 표현하며, 속성의 유형에 따라 표기 방식이 달라집니다.

속성 유형설명예시ERD 표기
단순 속성더 이상 분해 불가이름, 나이실선 타원
복합 속성하위 속성으로 분해 가능주소 → 시, 구, 동타원 + 하위 타원
유도 속성다른 속성에서 계산나이 (생년월일에서 유도)점선 타원
다중 값 속성여러 값을 가질 수 있음전화번호 (여러 개)이중 타원
키 속성개체를 유일하게 식별학번, 사원번호밑줄 표시

단순 속성과 복합 속성

단순 속성(Simple Attribute)은 더 이상 의미 있는 하위 단위로 분해할 수 없는 속성입니다. 나이, 성별, 학번 등이 단순 속성입니다.

복합 속성(Composite Attribute)은 여러 하위 속성으로 분해 가능한 속성입니다. 주소가 대표적인 복합 속성입니다. "서울시 강남구 삼성동 123번지"라는 주소를 시(서울시), 구(강남구), 동(삼성동), 상세(123번지)로 분해할 수 있습니다.

복합 속성
  주소 (복합 속성)
  ├── 시      "서울시"
  ├── 구      "강남구"
  ├── 동      "삼성동"
  └── 상세주소 "123번지"

이름 (복합 속성 - 국제 서비스)
  ├── 성      "Kim"
  └── 이름    "Cheolsu"

복합 속성을 분해하여 저장할지, 하나의 문자열로 저장할지는 검색과 정렬 요구사항에 따라 결정합니다. 강남구에 사는 회원을 검색해야 한다면 주소를 분해하여 저장하는 것이 유리합니다. 단순히 표시만 한다면 합쳐서 저장해도 괜찮습니다.

유도 속성

유도 속성(Derived Attribute)은 다른 속성의 값에서 계산되어 얻어지는 속성입니다. 생년월일에서 나이를 계산할 수 있으므로 나이는 유도 속성입니다. 주문 상세의 수량과 단가에서 주문 총액을 계산할 수 있으므로 총액도 유도 속성입니다.

유도 속성의 저장 여부
 저장하지 않는 경우 (원칙)
  생년월일: 1995-03-15
  나이 = YEAR(CURRENT_DATE) - YEAR(생년월일) → 매번 계산

 저장하는 경우 (성능 최적화)
  주문 테이블의 total_amount = SUM(수량 × 단가)
  → 수십 개 품목의 합계를 매번 계산하면 느림
  → 미리 계산하여 저장하고, 주문 변경 시 동기화

유도 속성을 저장하면 조회 성능이 향상되지만, 원본 데이터와의 동기화 책임이 생깁니다. 트리거나 애플리케이션 로직에서 원본 데이터가 변경될 때 유도 속성도 함께 갱신해야 합니다.

다중 값 속성

다중 값 속성(Multi-valued Attribute)은 하나의 개체 인스턴스에 대해 여러 개의 값을 가질 수 있는 속성입니다. 한 사람이 여러 전화번호를 가질 수 있고, 한 직원이 여러 자격증을 보유할 수 있습니다.

관계형 모델에서는 1NF(제1정규형)에 의해 하나의 셀에 여러 값을 넣을 수 없습니다. 따라서 다중 값 속성은 별도의 테이블로 분리해야 합니다.

다중 값 속성의 테이블 분리
-- 잘못된 설계: 쉼표로 구분 (1NF 위반)
CREATE TABLE employees (
    emp_id  INT PRIMARY KEY,
    name    VARCHAR(50),
    phones  VARCHAR(200)  -- "010-1234-5678, 02-555-1234" ← 나쁜 설계!
);

-- 올바른 설계: 별도 테이블로 분리
CREATE TABLE employees (
    emp_id  INT PRIMARY KEY,
    name    VARCHAR(50)
);

CREATE TABLE employee_phones (
    emp_id     INT,
    phone      VARCHAR(20),
    phone_type VARCHAR(10),  -- '휴대폰', '사무실', '자택'
    PRIMARY KEY (emp_id, phone),
    FOREIGN KEY (emp_id) REFERENCES employees(emp_id)
);

키 속성

키 속성(Key Attribute)은 개체 인스턴스를 유일하게 식별하는 속성입니다. ER 다이어그램에서 속성 이름에 밑줄을 그어 표시합니다. 학생 개체의 학번, 직원 개체의 사원번호 등이 키 속성입니다.

하나의 개체가 여러 키 속성을 가질 수 있습니다. 학생의 학번과 이메일이 모두 유일하다면 둘 다 키 속성이 됩니다.


관계 (Relationship)

관계(Relationship)는 두 개 이상의 개체 사이의 연관(Association)입니다. ER 모델에서 관계는 마름모로 표현합니다. "회원이 상품을 주문한다"에서 "주문한다"가 관계입니다.

관계도 개체처럼 관계 타입(Relationship Type)관계 인스턴스(Relationship Instance)로 구분됩니다. 수강한다는 관계 타입이고, 김철수가 데이터베이스학을 수강한다는 관계 인스턴스입니다.

관계의 차수 (Degree)

관계에 참여하는 개체 타입의 수를 차수(Degree)라 합니다.

관계의 차수
단항 관계 (Unary, Degree = 1)
  직원 ──관리──▶ 직원  (자기 자신과의 관계)
  "직원이 다른 직원을 관리한다"

이항 관계 (Binary, Degree = 2)
  학생 ──수강──▶ 과목  (두 개체 간 관계)
  "학생이 과목을 수강한다"

삼항 관계 (Ternary, Degree = 3)
  공급자 ──공급──▶ 부품

           프로젝트
  "공급자가 프로젝트에 부품을 공급한다"

대부분의 관계는 이항 관계입니다. 삼항 이상의 관계는 가능하면 여러 이항 관계로 분해하는 것이 설계가 명확해집니다.

카디널리티 (Cardinality)

카디널리티(Cardinality)는 관계에 참여하는 개체 인스턴스의 수를 나타냅니다. 관계의 종류를 결정하는 가장 중요한 개념입니다.

카디널리티 유형
1:1 관계 (one-to-one)
  회원 ──────── 프로필  (1명의 회원 = 1개의 프로필)

  회원 A ←──→ 프로필 A
  회원 B ←──→ 프로필 B
  회원 C ←──→ 프로필 C

1:N 관계 (one-to-many)
  부서 ──┬───── 직원A
         ├───── 직원B  (1부서 : N명의 직원)
         └───── 직원C

  영업부 ←──→ 김과장
  영업부 ←──→ 이대리
  개발부 ←──→ 박팀장

M:N 관계 (many-to-many)
  학생A ──┬───── 과목1
  학생B ──┼───── 과목2  (여러 학생 : 여러 과목)
  학생C ──┘

  김철수 ──→ 데이터베이스, 알고리즘
  이영희 ──→ 데이터베이스, 운영체제
  박민수 ──→ 알고리즘, 운영체제

1:1 관계의 구현

1:1 관계는 두 개체를 하나의 테이블로 합치거나, 한쪽 테이블에 다른 쪽의 기본키를 외래키로 넣어 구현합니다.

1:1 관계 구현
-- 방법 1: 한쪽에 외래키 추가
CREATE TABLE members (
    member_id   INT PRIMARY KEY,
    name        VARCHAR(50)
);

CREATE TABLE profiles (
    profile_id  INT PRIMARY KEY,
    member_id   INT UNIQUE,           -- UNIQUE로 1:1 보장
    bio         TEXT,
    avatar_url  VARCHAR(200),
    FOREIGN KEY (member_id) REFERENCES members(member_id)
);

-- 방법 2: 하나의 테이블로 합치기
CREATE TABLE members (
    member_id   INT PRIMARY KEY,
    name        VARCHAR(50),
    bio         TEXT,              -- 프로필 정보를 같이 저장
    avatar_url  VARCHAR(200)
);

어떤 방법을 선택할지는 상황에 따라 다릅니다. 프로필 정보가 선택적이고(모든 회원이 프로필을 가지지 않음), 프로필 데이터가 크다면 별도 테이블이 적합합니다. 프로필이 필수이고 자주 함께 조회된다면 하나의 테이블이 적합합니다.

1:N 관계의 구현

1:N 관계는 가장 흔한 관계 유형입니다. N쪽 테이블에 1쪽의 기본키를 외래키로 추가하여 구현합니다.

1:N 관계 구현
CREATE TABLE departments (
    dept_id    INT PRIMARY KEY,
    dept_name  VARCHAR(50)
);

CREATE TABLE employees (
    emp_id     INT PRIMARY KEY,
    name       VARCHAR(50),
    dept_id    INT,                 -- 부서의 PK를 FK로 참조
    FOREIGN KEY (dept_id) REFERENCES departments(dept_id)
);

외래키는 항상 N쪽에 위치합니다. 1쪽(부서)에 외래키를 넣으면 여러 직원을 참조할 수 없기 때문입니다.

M:N 관계의 구현

M:N 관계는 관계형 데이터베이스에서 직접 표현할 수 없습니다. 중간 테이블(연결 테이블, 교차 테이블, Junction Table)을 만들어 두 개의 1:N 관계로 분해해야 합니다.

M:N 관계 해소
-- M:N: 학생 ←→ 과목
-- 해소: 학생 ←1:N→ 수강 ←N:1→ 과목

CREATE TABLE students (
    student_id  INT PRIMARY KEY,
    name        VARCHAR(50)
);

CREATE TABLE courses (
    course_id   INT PRIMARY KEY,
    title       VARCHAR(100)
);

-- 중간 테이블 (연결 테이블)
CREATE TABLE enrollments (
    student_id  INT,
    course_id   INT,
    enrolled_at DATE DEFAULT (CURRENT_DATE),
    grade       CHAR(2),
    PRIMARY KEY (student_id, course_id),
    FOREIGN KEY (student_id) REFERENCES students(student_id),
    FOREIGN KEY (course_id) REFERENCES courses(course_id)
);

중간 테이블에는 관계 자체에 속하는 속성(수강일, 성적 등)을 포함할 수 있습니다. 이러한 속성은 학생에도, 과목에도 속하지 않고, 학생과 과목의 관계에 속하는 것입니다.


참여 제약 (Participation Constraint)

관계에 개체가 참여하는 방식에 따라 전체 참여부분 참여로 구분합니다.

전체 참여(Total Participation)는 개체 타입의 모든 인스턴스가 관계에 반드시 참여해야 하는 것입니다. ERD에서 이중 실선으로 표현합니다. "모든 직원은 반드시 하나의 부서에 소속되어야 한다"는 직원 개체의 전체 참여입니다.

부분 참여(Partial Participation)는 개체 타입의 일부 인스턴스만 관계에 참여해도 되는 것입니다. ERD에서 단일 실선으로 표현합니다. "모든 회원이 반드시 주문을 할 필요는 없다"는 회원 개체의 부분 참여입니다.

참여 제약
전체 참여 (이중선)
  직원 ════소속════ 부서
  (모든 직원은 반드시 부서에 소속)
  → SQL: dept_id INT NOT NULL

부분 참여 (단일선)
  회원 ────주문──── 상품
  (주문하지 않은 회원도 존재 가능)
  → SQL: 해당 외래키에 NULL 허용

참여 제약은 SQL에서 NOT NULL 제약으로 구현됩니다. 전체 참여이면 외래키 컬럼에 NOT NULL을, 부분 참여이면 NULL을 허용합니다.


관계의 속성

관계 자체가 속성을 가질 수 있습니다. 이러한 속성은 관계에 참여하는 어느 한 개체에만 속하지 않고, 두 개체의 관계에 속하는 것입니다.

관계의 속성
학생 ──수강── 과목

수강 관계의 속성
  - 수강일: 학생의 속성도, 과목의 속성도 아님
  - 성적: 특정 학생이 특정 과목을 수강한 결과

학생(학번: 2024001) × 과목(코드: CS101) → 성적: A+
이 "A+"는 학생에게만 속하는 것이 아니고 (여러 과목 수강)
과목에게만 속하는 것도 아닙니다 (여러 학생 수강)

ERD 표기법

ER 다이어그램의 표기법은 여러 가지가 있습니다. 각 표기법은 같은 개념을 다른 방식으로 시각화합니다.

Peter Chen 표기법

피터 첸의 원래 표기법입니다. 학술적 환경에서 주로 사용됩니다.

Peter Chen 표기법
기호
  ┌────────┐  직사각형 = 개체
  │ 개 체  │
  └────────┘
  (  속 성  )  타원 = 속성
  ◇ 관 계 ◇   마름모 = 관계
  ── 선 ──    연결선

예시
  ┌─────┐                    ┌─────┐
  │학 생│═══════◇수강◇═══════│과 목│
  └──┬──┘                    └──┬──┘
     │                          │
  (학번) (이름)              (과목코드) (과목명)
   ̲학̲번̲ = 키 속성 (밑줄)

IE (Information Engineering) 표기법

실무에서 가장 널리 사용되는 표기법입니다. 까마귀 발(Crow's Foot) 표기법이라고도 합니다.

IE 표기법 - 카디널리티 기호
──||──  정확히 하나 (mandatory one)
──|○──  0 또는 하나 (optional one)
──|<──  하나 이상 (mandatory many)  ← 까마귀 발
──○<──  0 이상 (optional many)    ← 까마귀 발 + 동그라미

예시: 부서 1:N 직원
  ┌─────────┐              ┌─────────┐
  │  부서   │──||────|<────│  직원   │
  │ dept_id │              │ emp_id  │
  │ name    │              │ name    │
  └─────────┘              │ dept_id │
                           └─────────┘
  읽는 법: "부서는 하나 이상의 직원을 가진다"
           "직원은 정확히 하나의 부서에 소속된다"

Barker 표기법

Oracle의 CASE Method에서 사용하는 표기법으로, ERWin 같은 도구에서 지원합니다.

Barker 표기법
  ┌────────────┐              ┌────────────┐
  │ # dept_id  │              │ # emp_id   │
  │ * name     │←─────────────│ * name     │
  │ o location │              │ * dept_id  │
  └────────────┘              │ o salary   │
                              └────────────┘
기호
  # = 기본키 (UID)
  * = 필수 (NOT NULL)
  o = 선택 (NULL 허용)

실선 = 필수 참여 (NOT NULL FK)
점선 = 선택 참여 (NULL 허용 FK)

표기법 비교

표기법사용 환경장점단점
Peter Chen학교, 학술 논문직관적, 학습 용이복잡한 스키마에서 번잡
IE (Crow's Foot)실무, SI 프로젝트간결, 도구 지원 풍부속성 표현이 직관적이지 않음
BarkerOracle 환경NOT NULL 표현 명확Oracle 편향적
UML객체지향 설계 통합코드와 통합 용이DB 전문가에게 생소

실무에서는 IE(Crow's Foot) 표기법이 가장 널리 사용됩니다. ERWin, DA#, dbdiagram.io 등 대부분의 모델링 도구가 이 표기법을 기본으로 지원합니다.


ER 모델에서 릴레이션으로 변환

ER 모델(개념적 모델)을 관계형 모델(논리적 모델)로 변환하는 규칙을 정리합니다. 이 변환 과정은 논리적 모델링의 핵심 활동입니다.

변환 규칙

ER → 릴레이션 변환 규칙
규칙 1: 강한 개체 → 릴레이션
  키 속성 → 기본키
  일반 속성 → 일반 컬럼

규칙 2: 약한 개체 → 릴레이션
  소유 개체의 PK + 부분키 → 복합 기본키
  소유 개체에 대한 FK 포함

규칙 3: 1:1 관계 → 한쪽에 FK 추가
  전체 참여 쪽에 FK를 넣는 것이 유리

규칙 4: 1:N 관계 → N쪽에 FK 추가
  1쪽의 PK를 N쪽에 FK로 추가

규칙 5: M:N 관계 → 새 릴레이션 생성
  양쪽의 PK를 FK로 가지며, 복합 PK 구성
  관계 속성은 이 릴레이션의 일반 컬럼

규칙 6: 다중 값 속성 → 별도 릴레이션
  개체의 PK를 FK로 참조

규칙 7: 복합 속성 → 하위 속성을 각각 컬럼으로
  또는 하나의 문자열 컬럼으로 합침

변환 예시

ER 모델
  학생(#학번, 이름, ‥주소(시, 구, 동)‥, ⊙전화번호)
     │                                     ↑다중값
     └── 수강 ── 과목(#과목코드, 과목명)
         (성적, 수강일) ← 관계 속성
변환 결과 (SQL)
-- 규칙 1: 강한 개체 → 릴레이션
CREATE TABLE students (
    student_id  INT PRIMARY KEY,       -- 키 속성 → PK
    name        VARCHAR(50),           -- 단순 속성 → 컬럼
    city        VARCHAR(50),           -- 복합 속성 (규칙 7)
    district    VARCHAR(50),
    dong        VARCHAR(50)
);

CREATE TABLE courses (
    course_id   INT PRIMARY KEY,
    title       VARCHAR(100)
);

-- 규칙 5: M:N 관계 → 새 릴레이션
CREATE TABLE enrollments (
    student_id  INT,
    course_id   INT,
    grade       CHAR(2),               -- 관계 속성 → 컬럼
    enrolled_at DATE,                   -- 관계 속성 → 컬럼
    PRIMARY KEY (student_id, course_id),
    FOREIGN KEY (student_id) REFERENCES students(student_id),
    FOREIGN KEY (course_id) REFERENCES courses(course_id)
);

-- 규칙 6: 다중 값 속성 → 별도 릴레이션
CREATE TABLE student_phones (
    student_id  INT,
    phone       VARCHAR(20),
    PRIMARY KEY (student_id, phone),
    FOREIGN KEY (student_id) REFERENCES students(student_id)
);

일반화와 특수화

개체 간에 상위-하위 관계(IS-A 관계)가 있을 수 있습니다.

일반화(Generalization)는 여러 하위 개체의 공통 속성을 추출하여 상위 개체를 만드는 것입니다. 정규직, 계약직, 인턴을 "직원"이라는 상위 개체로 일반화할 수 있습니다.

특수화(Specialization)는 상위 개체를 세분화하여 하위 개체를 만드는 것입니다. "직원"을 정규직, 계약직, 인턴으로 특수화할 수 있습니다.

일반화/특수화
              ┌──────────┐
              │  직  원  │  (상위 개체)
              │ #사원번호│
              │  이름    │
              │  부서    │
              └────┬─────┘
                   │ IS-A
          ┌────────┼──────────┐
     ┌────┴───┐ ┌──┴─────┐ ┌──┴───┐
     │ 정규직 │ │계약직  │ │ 인턴 │  (하위 개체)
     │ 연봉   │ │계약기간│ │멘토  │
     │ 퇴직금 │ │시급    │ │학교  │
     └────────┘ └────────┘ └──────┘

릴레이션으로 변환하는 방법은 세 가지가 있습니다.

방법 1: 각각 별도 테이블
CREATE TABLE employees (
    emp_id INT PRIMARY KEY, name VARCHAR(50), dept VARCHAR(50)
);
CREATE TABLE full_time (
    emp_id INT PRIMARY KEY, salary INT, severance INT,
    FOREIGN KEY (emp_id) REFERENCES employees(emp_id)
);
CREATE TABLE contract (
    emp_id INT PRIMARY KEY, duration INT, hourly_rate INT,
    FOREIGN KEY (emp_id) REFERENCES employees(emp_id)
);
-- 장점: 정규화됨, 제약 표현 명확
-- 단점: JOIN 필요
방법 2: 하나의 테이블로 합침
CREATE TABLE employees (
    emp_id INT PRIMARY KEY, name VARCHAR(50), dept VARCHAR(50),
    emp_type VARCHAR(10),  -- 'FULL', 'CONTRACT', 'INTERN'
    salary INT, severance INT,        -- 정규직 전용
    duration INT, hourly_rate INT,    -- 계약직 전용
    mentor VARCHAR(50), school VARCHAR(50)  -- 인턴 전용
);
-- 장점: JOIN 불필요, 단순
-- 단점: NULL 많음, 제약 표현 어려움

실전 ER 모델링 예시

종합적인 ER 모델링 예시로 온라인 쇼핑몰을 설계해봅니다.

온라인 쇼핑몰 ERD (IE 표기법)
┌───────────┐          ┌─────────────┐          ┌───────────┐
│ 회원      │          │ 주문        │          │ 상품      │
│ #회원번호 │──||──|<──│ #주문번호   │──>|──||──│ #상품번호 │
│ 이름      │          │ 회원번호(FK)│          │ 상품명    │
│ 이메일    │          │ 주문일      │      ┌───│ 가격      │
│ 연락처    │          │ 총금액      │      │   │ 재고수량  │
│ 가입일    │          │ 상태        │      │   │ 카테고리  │
└───────────┘          └─────────────┘      │   └───────────┘
                                  │         │
                               ||─┤        ─┤
                             ┌────┴─────┐   │
                             │ 주문상세 │───┘
                             │ 주문번호 │
                             │ 상품번호 │
                             │ 수량     │
                             │ 단가     │
                             └──────────┘

추가 관계
  회원 ──1:N──→ 리뷰
  상품 ──1:N──→ 리뷰
  상품 ──N:1──→ 카테고리
  회원 ──1:N──→ 배송지 (다중 값 속성 분리)

ER 모델은 데이터베이스 설계의 청사진입니다. 잘 그려진 ERD는 수십 페이지의 문서보다 효과적으로 데이터 구조를 전달합니다. 다음 절에서는 ER 모델을 시각적으로 표현하는 ERD 표기법의 상세와 실습을 다루겠습니다.

목차