콘텐츠로 이동

데이터베이스 설계 — 개념과 관계형 모델

데이터를 어떻게 구조화할 것인가

현실 세계에는 수많은 정보가 있습니다.
학생, 수업, 수강 기록, 성적 — 이것들을 컴퓨터에 저장하려면 먼저 구조를 정해야 합니다.

데이터베이스 설계는 세 단계로 진행됩니다.

현실 세계
    ↓ 추상화
개념적 모델 (Conceptual Model)  — "무엇이 있는가?"
    ↓ 정형화
논리적 모델 (Logical Model)     — "어떤 관계인가?"
    ↓ 구현
물리적 모델 (Physical Model)    — "어떤 DB에 어떻게 저장하는가?"

이 장에서는 개념적 모델논리적 모델을 집중적으로 다룹니다.
코드보다 개념이 먼저입니다.

개념적 모델 — ER 모델

개념적 모델(Conceptual Model)은 현실 세계를 추상화한 첫 번째 단계입니다.
특정 데이터베이스 제품(MySQL, PostgreSQL 등)에 독립적입니다.

가장 널리 쓰이는 개념적 모델링 방법이 ER 모델(Entity-Relationship Model)입니다.

ER 모델은 세 가지 요소로 현실을 표현합니다.

엔터티 (Entity)        — 존재하는 것
속성 (Attribute)       — 엔터티가 가진 특성
관계 (Relationship)    — 엔터티 사이의 연결

엔터티 (Entity)

엔터티 = 독립적으로 존재하며 저장할 가치가 있는 사물이나 개념

현실 세계 예시:
  학생, 수업, 교수, 도서, 주문, 상품

엔터티의 개별 사례를 인스턴스(Instance)라고 합니다.

엔터티: 학생
인스턴스: 김지민(17세), 이하나(18세), 박준서(17세) ...

엔터티 vs 속성 판단

무언가를 엔터티로 모델링해야 할지, 속성으로 두어야 할지 헷갈릴 때:

독립적으로 존재하는가?           → 엔터티
다른 엔터티에 종속된 특성인가?   → 속성

예)
주소 — 사람 없이 주소만 존재하는가? → 보통은 속성
       하지만 배송지를 여러 개 관리한다면? → 엔터티

속성 (Attribute)

속성 = 엔터티의 특성을 설명하는 정보

학생 엔터티의 속성:
  학번, 이름, 생년월일, 전공, 이메일

속성의 종류

종류 설명 예시
단순 속성 더 분해할 수 없음 나이, 학번
복합 속성 더 작은 단위로 분해 가능 주소 → 시/구/동
단일값 속성 값이 하나 생년월일
다중값 속성 값이 여러 개 가능 전화번호 (집, 휴대폰)
파생 속성 다른 속성으로부터 계산 나이 ← 생년월일
키 속성 인스턴스를 유일하게 식별 학번, 주민등록번호

키 속성 (Key Attribute)

엔터티의 인스턴스를 유일하게 식별하는 속성입니다.

학생 엔터티:
  학번 — 유일함 → 키 속성 가능
  이름 — 중복 가능 → 키 속성 불가

주문 엔터티:
  주문번호 — 유일함 → 키 속성 가능

키가 될 수 있는 후보를 후보 키(Candidate Key)라 하고,
그 중 실제로 선택된 것을 기본 키(Primary Key)라 합니다.

관계 (Relationship)

관계 = 두 엔터티 사이의 의미 있는 연결

학생 ── 수강 ── 수업
사람 ── 소유 ── 자동차
직원 ── 근무 ── 부서

관계의 카디널리티 (Cardinality)

카디널리티는 두 엔터티가 얼마나 연결될 수 있는지를 나타냅니다.

1:1 (일 대 일)

사람  ── 여권
(한 사람은 여권 하나, 여권 하나는 한 사람 것)

나라 ── 수도

1:N (일 대 다)

부서 ──< 직원
(한 부서에 여러 직원, 직원 하나는 한 부서)

작가 ──< 책
고객 ──< 주문

가장 자주 등장하는 관계입니다.

N:M (다 대 다)

학생 >──< 수업
(학생 한 명이 여러 수업 수강, 수업 하나에 여러 학생)

상품 >──< 주문
배우 >──< 영화

N:M 관계는 직접 표현할 수 없습니다.
반드시 중간 엔터티(교차 엔터티)로 분해해야 합니다.

학생 >──< 수업
        ↓ 분해
학생 ──< 수강 >── 수업
         (중간 엔터티: 수강)

수강 엔터티의 속성:
  학생번호 (FK), 수업번호 (FK), 수강일, 성적

참여 제약 (Participation Constraint)

관계에서 엔터티의 참여가 필수인지 선택인지 나타냅니다.

전체 참여 (Total Participation): 모든 인스턴스가 반드시 관계에 참여
부분 참여 (Partial Participation): 참여하지 않는 인스턴스도 존재 가능

예)
직원 ── 근무 ── 부서
  직원은 반드시 부서에 속해야 함 → 전체 참여
  부서는 직원이 없을 수도 있음  → 부분 참여 (새 부서 생성 직후)

ERD (Entity-Relationship Diagram)

ER 모델을 시각화한 다이어그램입니다.
코딩 전에 이 그림을 그려야 전체 데이터 구조가 보입니다.

Todo 서비스 ERD

┌─────────────────┐         ┌──────────────────────┐
│      User       │         │         Todo         │
├─────────────────┤         ├──────────────────────┤
│ *id             │ 1     N │ *id                  │
│  email          │─────────│  user_id (FK)        │
│  password       │  작성   │  title               │
│  created_at     │         │  is_done             │
└─────────────────┘         │  created_at          │
                            └──────────────────────┘

* = 기본 키 (Primary Key)

블로그 서비스 ERD

┌──────────┐      ┌──────────┐      ┌──────────┐
│   User   │      │   Post   │      │  Comment │
├──────────┤      ├──────────┤      ├──────────┤
│ *id      │1   N │ *id      │1   N │ *id      │
│  email   │──────│ user_id  │──────│ post_id  │
│  name    │ 작성 │ title    │ 달림 │ user_id  │──┐
└──────────┘      │ content  │      │ content  │  │
     ▲            └──────────┘      └──────────┘  │
     └──────────────────────────────── 작성 ───────┘

논리적 모델 — 관계형 모델

개념적 모델(ER 모델)을 관계형 모델(Relational Model)로 변환하는 단계입니다.

관계형 모델은 현대 데이터베이스의 이론적 기반입니다.

핵심 용어

관계형 모델 용어 일상적 표현 설명
릴레이션(Relation) 테이블 데이터를 저장하는 2차원 표
튜플(Tuple) 행(Row) 데이터 하나
속성(Attribute) 열(Column) 데이터의 특성
도메인(Domain) 타입 속성이 가질 수 있는 값의 범위
차수(Degree) 열의 수 속성의 개수
카디널리티(Cardinality) 행의 수 튜플의 개수
[students 릴레이션]
학번  | 이름 | 나이 | 전공         ← 속성 (Attribute)
------|------|------|------
2001  | 지민 | 17   | 컴퓨터공학   ← 튜플 (Tuple)
2002  | 하나 | 18   | 경영학
2003  | 준서 | 17   | 컴퓨터공학

차수(Degree) = 4 (열이 4개)
카디널리티 = 3 (행이 3개)

릴레이션의 특성

  1. 튜플의 유일성 — 완전히 동일한 튜플은 없음
  2. 튜플의 순서 없음 — 행의 순서는 의미 없음
  3. 속성의 원자성 — 각 셀은 하나의 값만 가짐 (리스트 불가)
  4. 속성 이름의 유일성 — 같은 이름의 열은 없음

키의 종류

키 종류 설명 예시
후보 키 튜플을 유일하게 식별할 수 있는 속성(들) 학번, 이메일
기본 키 (PK) 후보 키 중 선택된 하나 학번
대리 키 의미 없는 임의 숫자 ID id (AUTO_INCREMENT)
외래 키 (FK) 다른 릴레이션의 기본 키를 참조 todos.user_id → users.id
복합 키 두 속성을 합쳐 기본 키로 사용 (학번, 수업번호)

외래 키와 참조 무결성

외래 키는 릴레이션 간 관계를 표현하는 핵심 수단입니다.

users 릴레이션:
id | email
---|------
 1 | jimin@ex.com
 2 | hana@ex.com

todos 릴레이션:
id | user_id | title
---|---------|------
 1 |       1 | 운동하기   ← user_id=1 → users에서 id=1 (지민)
 2 |       1 | 책 읽기
 3 |       2 | 영어 공부  ← user_id=2 → users에서 id=2 (하나)

참조 무결성(Referential Integrity) = FK가 가리키는 PK가 반드시 존재해야 하는 규칙

user_id = 99인 todo를 추가하려 할 때:
  users에 id=99가 없음 → 오류 (참조 무결성 위반)

정규화 (Normalization)

정규화 = 데이터 중복을 제거하고 이상(Anomaly)을 방지하는 설계 기법

이상(Anomaly)이란?

중복된 데이터 때문에 발생하는 문제입니다.

[나쁜 설계 — 정규화 전]
주문ID | 고객명 | 고객이메일    | 상품명 | 가격
-------|--------|-------------|--------|-----
  101  | 지민   | j@ex.com    | 텀블러 | 25000
  102  | 지민   | j@ex.com    | 노트   |  3000
  103  | 하나   | h@ex.com    | 텀블러 | 25000
이상 종류 발생 상황
삽입 이상 상품을 등록하려면 주문도 있어야 함
삭제 이상 주문을 삭제하면 고객 정보도 사라짐
수정 이상 지민의 이메일 변경 시 여러 행을 수정해야 하고, 하나라도 빠뜨리면 불일치

1NF — 원자성 확보

모든 속성 값은 원자적(더 분해할 수 없는 단일 값)이어야 한다.

위반:
주문ID | 상품목록
-------|----------
  101  | 텀블러, 노트, 펜    ← 하나의 셀에 여러 값

준수:
주문ID | 상품명
-------|-------
  101  | 텀블러
  101  | 노트
  101  | 펜

2NF — 부분 함수 종속 제거

기본 키의 일부에만 종속된 속성을 분리한다.
(복합 기본 키일 때만 해당)

위반 — 기본 키: (학번, 수업번호)
학번 | 수업번호 | 학생이름 | 수강성적
-----|---------|---------|--------
2001 |    CS01 | 지민    | A

'학생이름'은 학번만으로 결정됨 (수업번호와 무관) → 부분 종속

분리:
[학생] 학번 | 학생이름
[수강] 학번 | 수업번호 | 수강성적

3NF — 이행 함수 종속 제거

기본 키가 아닌 속성이 다른 비키 속성을 결정하면 분리한다.

위반:
직원ID | 부서ID | 부서명
-------|--------|-------
   101 |     10 | 개발팀

직원ID → 부서ID → 부서명
(부서명이 부서ID를 통해 간접적으로 결정됨)

분리:
[직원] 직원ID | 부서ID
[부서] 부서ID | 부서명

정규화 원칙 한 문장

같은 사실은 한 곳에만 저장한다.
데이터를 복사하지 말고, 참조(FK)로 연결한다.

ER 모델 → 관계형 모델 변환 규칙

개념적 설계(ERD)를 논리적 설계(테이블)로 변환하는 규칙입니다.

ER 모델 관계형 모델
엔터티 테이블
속성 컬럼
키 속성 기본 키 (PRIMARY KEY)
1:N 관계 N쪽 테이블에 FK 추가
N:M 관계 중간 테이블 생성, 양쪽 FK
1:1 관계 한쪽 테이블에 FK 추가

변환 예시 — 수강 시스템

[ERD]
학생 >──< 수업  (N:M)

[관계형 모델]
학생(학번 PK, 이름, 전공)
수업(수업번호 PK, 수업명, 담당교수)
수강(학번 FK, 수업번호 FK, 성적)  ← 중간 테이블
     └─────────────── 복합 기본 키

실습 미션

미션 1: 엔터티와 속성 구분

아래에서 엔터티와 속성을 구분하고, 각 엔터티의 키 속성을 정하세요.

도서관 시스템에 있는 것들:
책, 제목, 저자, ISBN, 회원, 회원번호, 이름, 대출일, 반납일, 대출기록

미션 2: 카디널리티 파악

아래 관계의 카디널리티(1:1, 1:N, N:M)를 판단하고 이유를 설명하세요.

1. 학생 — 학생증
2. 팀 — 팀원
3. 태그 — 게시글
4. 환자 — 담당의사 (병원에서)
5. 배우 — 영화

미션 3: ERD 그리기

아래 요구사항을 ERD로 표현하세요.
엔터티, 속성, 관계, 카디널리티를 모두 표시하세요.

- 사용자는 여러 게시글을 작성할 수 있다
- 게시글에는 여러 태그를 붙일 수 있다 (태그도 여러 게시글에 사용 가능)
- 사용자는 게시글에 댓글을 달 수 있다
- 사용자는 게시글에 좋아요를 누를 수 있다 (한 번만)

미션 4: 정규화

아래 테이블에서 발생할 수 있는 이상(Anomaly)을 찾고, 정규화하세요.

[주문 테이블]
주문ID | 고객ID | 고객명 | 고객이메일  | 상품ID | 상품명 | 단가  | 수량
-------|--------|--------|-----------|--------|--------|-------|----
  1001 |    201 | 지민   | j@ex.com  |    501 | 텀블러 | 25000 |  2
  1002 |    201 | 지민   | j@ex.com  |    502 | 노트   |  3000 |  5
  1003 |    202 | 하나   | h@ex.com  |    501 | 텀블러 | 25000 |  1

미션 5 (심화): 내 서비스 ERD → 관계형 모델

3장(SRS)에서 정의한 서비스의 ERD를 그리고,
변환 규칙에 따라 테이블 목록(이름, 컬럼, PK, FK)을 작성하세요.

핵심 요약

개념 설명
개념적 모델 현실을 추상화, DB 제품에 독립적
ER 모델 엔터티, 속성, 관계로 현실을 표현
엔터티 독립적으로 존재하는 사물/개념
속성 엔터티의 특성
관계 엔터티 사이의 연결
카디널리티 1:1, 1:N, N:M
논리적 모델 관계형 모델 — 릴레이션, 튜플, 속성
기본 키 (PK) 튜플을 유일하게 식별
외래 키 (FK) 다른 릴레이션의 PK 참조
정규화 중복 제거 — 같은 사실은 한 곳에만
1NF / 2NF / 3NF 원자성 / 부분 종속 제거 / 이행 종속 제거