Chapter 2. Relational Model
핵심 요약: 관계형 모델은 데이터를 테이블(릴레이션)로 표현하며, 각 릴레이션은 속성(attribute)과 튜플(tuple)로 구성된다. 키(슈퍼키, 후보키, 기본키, 외래키)를 통해 튜플을 식별하고 릴레이션 간 관계를 표현한다. 관계 대수는 6개의 기본 연산자(σ, Π, ∪, −, ×, ρ)와 추가 연산(⋈, ∩, ←)을 통해 릴레이션을 질의·변환하는 절차적 언어다.
1. 관계형 모델의 구조
관계형 모델에서 데이터는 릴레이션(relation), 즉 테이블의 집합으로 표현된다.
기본 용어
- 릴레이션(Relation): 테이블. 행(row)과 열(column)로 구성된다.
- 튜플(Tuple): 릴레이션의 한 행. 하나의 레코드에 해당한다.
- 속성(Attribute): 릴레이션의 한 열. 각 속성은 이름을 가진다.
- 릴레이션 스키마(Relation Schema): 릴레이션의 논리적 설계.
R(A₁, A₂, ..., Aₙ)형태로 표기한다.- 예:
instructor(ID, name, dept_name, salary)
- 예:
- 릴레이션 인스턴스(Relation Instance): 특정 시점에서의 릴레이션의 실제 데이터(튜플의 집합).
- 튜플의 순서는 무의미하다 (Relations are Unordered): 릴레이션은 튜플의 집합이므로 튜플이 저장되는 순서는 임의적이며, 어떤 순서로 나열하든 같은 릴레이션이다.
스키마 vs 인스턴스 (Schema vs Instance)
- 스키마(Schema) = 릴레이션의 논리적 구조. 프로그래밍에서 변수의 타입에 해당한다.
- 예:
instructor(ID, name, dept_name, salary)
- 예:
- 인스턴스(Instance) = 특정 시점에서의 릴레이션의 실제 데이터 스냅샷. 프로그래밍에서 변수의 값에 해당한다.
- 시간이 지나면서 데이터가 추가/삭제/수정되면 인스턴스가 변한다.
속성의 특성
- 각 속성의 허용 가능한 값의 집합을 도메인(domain)이라 한다.
- 속성 값은 원자적(atomic)이어야 한다. 즉, 더 이상 분할할 수 없는 단일 값이어야 한다.
- 예: 전화번호를 단일 속성으로 저장하면 원자적. 그러나 country code / area code / local number로 분할해서 하나의 속성에 합성 값으로 넣으면 원자성 위반.
- null 값은 “값을 모르거나 존재하지 않음”을 나타내는 특수 값이다.
- null은 모든 도메인의 멤버로 간주된다.
- null은 많은 연산의 정의를 복잡하게 만든다 (예: null + 5 = null, null 비교 → unknown). 가능한 한 사용을 피해야 한다.
2. 키 (Keys)
키는 릴레이션에서 튜플을 고유하게 식별하거나 릴레이션 간 관계를 표현하는 데 사용된다.
| 키 유형 | 정의 |
|---|---|
| 슈퍼키 (Superkey) | 릴레이션 내에서 튜플을 유일하게 식별할 수 있는 속성의 집합. {ID}도, {ID, name}도 슈퍼키다. |
| 후보키 (Candidate Key) | 최소 슈퍼키. 어떤 진부분집합도 슈퍼키가 되지 않는 슈퍼키다. |
| 기본키 (Primary Key) | DBA가 후보키 중에서 선택한 대표 키. 밑줄로 표시한다. |
| 외래키 (Foreign Key) | 다른 릴레이션의 기본키를 참조하는 속성. 릴레이션 간 관계를 표현한다. |
참조 무결성 제약조건: 참조하는 릴레이션의 외래키 값은 참조되는 릴레이션의 기본키 값으로 반드시 존재해야 한다.
예시 (대학 스키마):
instructor(ID, name, dept_name, salary)— dept_name은 department를 참조하는 외래키department(dept_name, building, budget)— dept_name이 기본키
3. 스키마 다이어그램
스키마 다이어그램은 데이터베이스의 논리적 구조를 시각적으로 보여준다:
- 각 릴레이션은 직사각형으로 표시
- 기본키 속성은 밑줄로 표시
- 외래키 관계는 화살표로 표시 (참조하는 쪽 → 참조되는 쪽)
대학 스키마의 주요 릴레이션:
department(dept_name, building, budget)
course(course_id, title, dept_name, credits)
instructor(ID, name, dept_name, salary)
section(course_id, sec_id, semester, year, building, room_number, time_slot_id)
teaches(ID, course_id, sec_id, semester, year)
student(ID, name, dept_name, tot_cred)
takes(ID, course_id, sec_id, semester, year, grade)
advisor(s_ID, i_ID)
prereq(course_id, prereq_id)
classroom(building, room_number, capacity)
time_slot(time_slot_id, day, start_hr, start_min, end_hr, end_min)
샘플 데이터
course 릴레이션:
| course_id | title | dept_name | credits |
|---|---|---|---|
| BIO-101 | Intro. to Biology | Biology | 4 |
| BIO-301 | Genetics | Biology | 4 |
| CS-101 | Intro. to Computer Science | Comp. Sci. | 4 |
| CS-190 | Game Design | Comp. Sci. | 4 |
| CS-315 | Robotics | Comp. Sci. | 3 |
| CS-319 | Image Processing | Comp. Sci. | 3 |
| CS-347 | Database System Concepts | Comp. Sci. | 3 |
| EE-181 | Intro. to Digital Systems | Elec. Eng. | 3 |
| FIN-201 | Investment Banking | Finance | 3 |
| HIS-351 | World History | History | 3 |
| MU-199 | Music Video Production | Music | 3 |
| PHY-101 | Physical Principles | Physics | 4 |
prereq 릴레이션:
| course_id | prereq_id |
|---|---|
| BIO-301 | BIO-101 |
| BIO-399 | BIO-101 |
| CS-190 | CS-101 |
| CS-315 | CS-101 |
| CS-319 | CS-101 |
| CS-347 | CS-101 |
| EE-181 | PHY-101 |
4. 관계 대수 (Relational Algebra)
관계 대수는 하나 또는 두 개의 릴레이션을 입력으로 받아 새로운 릴레이션을 결과로 산출하는 절차적 쿼리 언어다. 6개의 기본 연산자가 있다.
핵심 성질 — 연산의 합성(Composition): 관계 대수 연산의 결과는 항상 릴레이션이므로, 연산을 중첩(합성)할 수 있다.
예:Π_name(σ_{dept_name="Physics"}(instructor))— 선택 결과(릴레이션)에 투영을 바로 적용
4.1 Select (선택) — σ
조건을 만족하는 튜플만 선택한다.
σ_조건(릴레이션)
예: 물리학과 교수 중 급여가 90,000 초과인 교수
σ_{dept_name="Physics" ∧ salary>90000}(instructor)
- 조건에는
=, ≠, >, ≥, <, ≤비교 연산자와∧(and), ∨(or), ¬(not)논리 연산자를 사용할 수 있다.
4.2 Project (투영) — Π
지정한 속성만 추출한다 (열 선택). 결과에서 중복 튜플은 자동 제거된다.
Π_{속성목록}(릴레이션)
예: 교수의 ID, 이름, 급여만 추출
Π_{ID, name, salary}(instructor)
4.3 Union (합집합) — ∪
두 릴레이션의 모든 튜플을 합친다. 중복은 제거된다.
r ∪ s
- 호환 조건: r과 s는 같은 수의 속성을 가져야 하고, 대응 속성의 도메인이 호환되어야 한다.
예: 2017 Fall 또는 2018 Spring에 개설된 과목
Π_{course_id}(σ_{semester="Fall" ∧ year=2017}(section)) ∪ Π_{course_id}(σ_{semester="Spring" ∧ year=2018}(section))
4.4 Set Difference (차집합) — −
r에는 있지만 s에는 없는 튜플을 구한다.
r − s
예: 2017 Fall에는 개설되었지만 2018 Spring에는 개설되지 않은 과목
Π_{course_id}(σ_{semester="Fall" ∧ year=2017}(section)) − Π_{course_id}(σ_{semester="Spring" ∧ year=2018}(section))
4.5 Cartesian Product (카티션 곱) — ×
두 릴레이션의 모든 튜플 쌍을 조합한다.
r × s
- 결과의 속성은 r과 s의 속성을 모두 포함한다.
- 공통 속성이 있으면 릴레이션 이름으로 구분한다 (예:
instructor.name,student.name).
예: 교수와 그가 가르치는 과목 정보 결합
σ_{instructor.ID = teaches.ID}(instructor × teaches)
왜 대부분의 카티션 곱 결과가 무의미한가: instructor에 5개, teaches에 13개의 튜플이 있다면, 카티션 곱은 5×13 = 65개의 튜플을 생성한다. 이 중 instructor.ID = teaches.ID를 만족하는 유의미한 조합은 13개뿐이고, 나머지 52개는 서로 관련 없는 교수-강의 조합이다. 따라서 카티션 곱은 거의 항상 선택(σ) 조건과 함께 사용된다.
4.6 Rename (재명명) — ρ
릴레이션이나 속성의 이름을 변경한다.
ρ_x(E) — 결과 릴레이션 이름을 x로 변경
ρ_{x(A₁,A₂,...,Aₙ)}(E) — 릴레이션 이름과 속성 이름을 모두 변경
5. 추가 관계 대수 연산
기본 연산자만으로 모든 쿼리를 표현할 수 있지만, 편의를 위해 추가 연산이 정의된다.
5.1 Set Intersection (교집합) — ∩
r과 s 모두에 존재하는 튜플을 구한다.
r ∩ s = r − (r − s)
예: 2017 Fall과 2018 Spring 모두에 개설된 과목
Π_{course_id}(σ_{semester="Fall" ∧ year=2017}(section)) ∩ Π_{course_id}(σ_{semester="Spring" ∧ year=2018}(section))
5.2 Natural Join (자연 조인) — ⋈
두 릴레이션에서 공통 속성 값이 같은 튜플을 결합한다. 공통 속성은 결과에서 한 번만 나타난다.
r ⋈ s
예: 교수와 그가 가르치는 과목 (ID가 공통 속성)
instructor ⋈ teaches
- 자연 조인은 카티션 곱 + 선택 + 투영으로 정의할 수 있다.
- Theta Join: 조건을 직접 명시하는 조인.
r ⋈_θ s = σ_θ(r × s)
5.3 Assignment (배정) — ←
중간 결과에 이름을 부여하여 복잡한 쿼리를 단계적으로 작성할 수 있게 한다.
temp ← σ_{dept_name="Physics"}(instructor)
result ← Π_{name}(temp)
6. 동치 쿼리 (Equivalent Queries)
동일한 결과를 산출하는 서로 다른 관계 대수 표현이 존재할 수 있다. 쿼리 최적화기는 이 중 가장 효율적인 것을 선택한다.
예: “물리학과에서 급여 90,000 초과인 교수의 이름”을 구하는 두 가지 방법:
-- 방법 1: 선택 후 투영
Π_{name}(σ_{dept_name="Physics" ∧ salary>90000}(instructor))
-- 방법 2: 조인 후 선택·투영
Π_{name}(σ_{salary>90000}(σ_{dept_name="Physics"}(instructor)))
두 표현은 같은 결과를 내지만, 실행 비용이 다를 수 있다.
7. 관계 대수 연산자 요약
| 연산자 | 기호 | 유형 | 설명 |
|---|---|---|---|
| Select | σ | 단항 | 조건을 만족하는 행 선택 |
| Project | Π | 단항 | 특정 열만 추출 (중복 제거) |
| Union | ∪ | 이항 | 두 릴레이션 합집합 |
| Set Difference | − | 이항 | 차집합 |
| Cartesian Product | × | 이항 | 모든 튜플 쌍 조합 |
| Rename | ρ | 단항 | 이름 변경 |
| Natural Join | ⋈ | 이항 | 공통 속성 기준 결합 |
| Set Intersection | ∩ | 이항 | 교집합 |
| Assignment | ← | — | 중간 결과에 이름 부여 |
출처: Database System Concepts, 7th Edition (Silberschatz, Korth, Sudarshan)