관계 데이터 연산

관계 데이터 연산

관계 데이터 연산 (Relational Data Operation)

관계 데이터 연산은 원하는 데이터를 얻기 위해 릴레이션에 필요한 처리 요구를 수행하는 것이다.


1. 관계 대수 vs 관계 해석

구분관계 대수 (Relational Algebra)관계 해석 (Relational Calculus)
언어 유형절차적 언어 (Procedural)비절차적 언어 (Non-procedural)
기술 방식처리 과정을 순서대로 기술원하는 데이터가 무엇인지만 기술
특징HOW (어떻게)WHAT (무엇을)
표현력동등동등

관계적으로 완전(Relationally Complete): 관계 대수나 관계 해석으로 기술할 수 있는 모든 질의를 표현할 수 있는 언어

폐쇄 특성 (Closure Property)

관계 대수에서 피연산자도 릴레이션이고, 연산 결과도 릴레이션이다.

릴레이션 ──→ [연산자] ──→ 릴레이션 ──→ [연산자] ──→ 릴레이션
              ↑                          ↑
         연산 가능                   연산 가능 (연쇄 적용)

2. 예제 릴레이션

다음 예제들에서 사용할 릴레이션:

학생 릴레이션 (R)                      수강 릴레이션 (S)
┌────────┬────────┬────────┐          ┌────────┬────────┐
│ 학번    │ 이름    │ 학과    │          │ 학번    │ 과목    │
├────────┼────────┼────────┤          ├────────┼────────┤
│ 001    │ 홍길동  │ CS     │          │ 001    │ DB     │
│ 002    │ 김영희  │ BA     │          │ 001    │ OS     │
│ 003    │ 이철수  │ CS     │          │ 002    │ DB     │
│ 004    │ 박민수  │ EE     │          │ 003    │ NET    │
└────────┴────────┴────────┘          └────────┴────────┘

교수 릴레이션 (T)
┌────────┬────────┬────────┐
│ 교수번호 │ 이름    │ 학과    │
├────────┼────────┼────────┤
│ P01    │ 김교수  │ CS     │
│ P02    │ 이교수  │ BA     │
│ P03    │ 박교수  │ CS     │
└────────┴────────┴────────┘

3. 일반 집합 연산자

합병 가능 조건

합집합, 교집합, 차집합 연산은 합병 가능해야 한다:

  1. 두 릴레이션의 차수(속성 개수)가 같아야
  2. 대응되는 속성의 도메인이 같아야 함 (이름은 달라도 됨)

3.1 합집합 (Union) - R ∪ S

두 릴레이션에 속하는 모든 투플 (중복 제거)

CS학과 학생                           BA학과 학생
┌────────┬────────┐                  ┌────────┬────────┐
│ 학번    │ 이름    │                  │ 학번    │ 이름    │
├────────┼────────┤                  ├────────┼────────┤
│ 001    │ 홍길동  │                  │ 002    │ 김영희  │
│ 003    │ 이철수  │                  └────────┴────────┘
└────────┴────────┘

CS학과 ∪ BA학과 (합집합)
┌────────┬────────┐
│ 학번    │ 이름    │
├────────┼────────┤
│ 001    │ 홍길동  │
│ 002    │ 김영희  │  ← 중복 없이 모두 포함
│ 003    │ 이철수  │
└────────┴────────┘

차수: 2 (동일)
카디널리티: ≤ (R의 카디널리티 + S의 카디널리티)

SQL 대응:

SELECT 학번, 이름 FROM CS학과학생
UNION
SELECT 학번, 이름 FROM BA학과학생;

3.2 교집합 (Intersection) - R ∩ S

두 릴레이션에 공통으로 속하는 투플

DB수강생                              OS수강생
┌────────┬────────┐                  ┌────────┬────────┐
│ 학번    │ 이름    │                  │ 학번    │ 이름    │
├────────┼────────┤                  ├────────┼────────┤
│ 001    │ 홍길동  │                  │ 001    │ 홍길동  │
│ 002    │ 김영희  │                  │ 003    │ 이철수  │
└────────┴────────┘                  └────────┴────────┘

DB수강생 ∩ OS수강생 (교집합)
┌────────┬────────┐
│ 학번    │ 이름    │
├────────┼────────┤
│ 001    │ 홍길동  │  ← 둘 다 수강하는 학생
└────────┴────────┘

차수: 2 (동일)
카디널리티: ≤ min(R, S)

SQL 대응:

SELECT 학번, 이름 FROM DB수강생
INTERSECT
SELECT 학번, 이름 FROM OS수강생;

3.3 차집합 (Difference) - R - S

R에는 있지만 S에는 없는 투플

전체학생                              장학생
┌────────┬────────┐                  ┌────────┬────────┐
│ 학번    │ 이름    │                  │ 학번    │ 이름    │
├────────┼────────┤                  ├────────┼────────┤
│ 001    │ 홍길동  │                  │ 001    │ 홍길동  │
│ 002    │ 김영희  │                  │ 003    │ 이철수  │
│ 003    │ 이철수  │                  └────────┴────────┘
│ 004    │ 박민수  │
└────────┴────────┘

전체학생 - 장학생 (차집합)
┌────────┬────────┐
│ 학번    │ 이름    │
├────────┼────────┤
│ 002    │ 김영희  │  ← 장학생이 아닌 학생
│ 004    │ 박민수  │
└────────┴────────┘

주의: R - S ≠ S - R (교환적 특성 없음!)

SQL 대응:

SELECT 학번, 이름 FROM 전체학생
EXCEPT  -- 또는 MINUS (Oracle)
SELECT 학번, 이름 FROM 장학생;

3.4 카티션 프로덕트 (Cartesian Product) - R × S

R의 각 투플과 S의 각 투플을 모두 연결

학생 (R)                              과목 (S)
┌────────┬────────┐                  ┌────────┐
│ 학번    │ 이름    │                  │ 과목    │
├────────┼────────┤                  ├────────┤
│ 001    │ 홍길동  │                  │ DB     │
│ 002    │ 김영희  │                  │ OS     │
└────────┴────────┘                  └────────┘

R × S (카티션 프로덕트)
┌────────┬────────┬────────┐
│ 학번    │ 이름    │ 과목    │
├────────┼────────┼────────┤
│ 001    │ 홍길동  │ DB     │  ← 모든 조합
│ 001    │ 홍길동  │ OS     │
│ 002    │ 김영희  │ DB     │
│ 002    │ 김영희  │ OS     │
└────────┴────────┴────────┘

차수: R차수 + S차수 = 2 + 1 = 3
카디널리티: R카디널리티 × S카디널리티 = 2 × 2 = 4

SQL 대응:

SELECT * FROM 학생, 과목;
-- 또는
SELECT * FROM 학생 CROSS JOIN 과목;

일반 집합 연산자 요약

연산자기호합병 가능교환적결합적결과 차수결과 카디널리티
합집합필요OO동일≤ R + S
교집합필요OO동일≤ min(R, S)
차집합-필요XX동일≤ R
카티션 프로덕트×불필요OOR + SR × S

4. 순수 관계 연산자

4.1 셀렉트 (Select) - σ

조건을 만족하는 투플(행) 선택 → 수평적 부분집합

σ(조건식)(릴레이션)  또는  릴레이션 WHERE 조건식
학생 릴레이션
┌────────┬────────┬────────┬────────┐
│ 학번    │ 이름    │ 학과    │ 학년    │
├────────┼────────┼────────┼────────┤
│ 001    │ 홍길동  │ CS     │ 3      │
│ 002    │ 김영희  │ BA     │ 2      │
│ 003    │ 이철수  │ CS     │ 1      │
│ 004    │ 박민수  │ EE     │ 3      │
└────────┴────────┴────────┴────────┘

σ(학과='CS')(학생)
┌────────┬────────┬────────┬────────┐
│ 학번    │ 이름    │ 학과    │ 학년    │
├────────┼────────┼────────┼────────┤
│ 001    │ 홍길동  │ CS     │ 3      │  ← 수평적 절단
│ 003    │ 이철수  │ CS     │ 1      │
└────────┴────────┴────────┴────────┘

σ(학과='CS' ∧ 학년≥2)(학생)
┌────────┬────────┬────────┬────────┐
│ 학번    │ 이름    │ 학과    │ 학년    │
├────────┼────────┼────────┼────────┤
│ 001    │ 홍길동  │ CS     │ 3      │  ← 복합 조건
└────────┴────────┴────────┴────────┘

조건식 연산자:

  • 비교: >, >=, <, <=, =,
  • 논리: (AND), (OR), ¬ (NOT)

SQL 대응:

SELECT * FROM 학생 WHERE 학과 = 'CS';
SELECT * FROM 학생 WHERE 학과 = 'CS' AND 학년 >= 2;

4.2 프로젝트 (Project) - π

선택한 **속성(열)**만 추출 → 수직적 부분집합

π(속성리스트)(릴레이션)
학생 릴레이션
┌────────┬────────┬────────┬────────┐
│ 학번    │ 이름    │ 학과    │ 학년    │
├────────┼────────┼────────┼────────┤
│ 001    │ 홍길동  │ CS     │ 3      │
│ 002    │ 김영희  │ BA     │ 2      │
│ 003    │ 이철수  │ CS     │ 1      │
│ 004    │ 박민수  │ EE     │ 3      │
└────────┴────────┴────────┴────────┘

π(이름, 학과)(학생)
┌────────┬────────┐
│ 이름    │ 학과    │   ← 수직적 절단
├────────┼────────┤
│ 홍길동  │ CS     │
│ 김영희  │ BA     │
│ 이철수  │ CS     │
│ 박민수  │ EE     │
└────────┴────────┘

π(학과)(학생)
┌────────┐
│ 학과    │
├────────┤
│ CS     │   ← 중복 제거됨!
│ BA     │
│ EE     │
└────────┘

SQL 대응:

SELECT 이름, 학과 FROM 학생;
SELECT DISTINCT 학과 FROM 학생;  -- 중복 제거

4.3 셀렉트 + 프로젝트 조합

π(이름)(σ(학과='CS')(학생))

1단계: σ(학과='CS')(학생)  → CS학과 학생만 선택
2단계: π(이름)(결과)       → 이름만 추출

결과:
┌────────┐
│ 이름    │
├────────┤
│ 홍길동  │
│ 이철수  │
└────────┘

SQL 대응:

SELECT 이름 FROM 학생 WHERE 학과 = 'CS';

4.4 조인 (Join) - ⋈

공통 속성을 기준으로 두 릴레이션의 투플을 연결

학생                                   수강
┌────────┬────────┬────────┐          ┌────────┬────────┐
│ 학번    │ 이름    │ 학과    │          │ 학번    │ 과목    │
├────────┼────────┼────────┤          ├────────┼────────┤
│ 001    │ 홍길동  │ CS     │          │ 001    │ DB     │
│ 002    │ 김영희  │ BA     │          │ 001    │ OS     │
│ 003    │ 이철수  │ CS     │          │ 002    │ DB     │
│ 004    │ 박민수  │ EE     │          │ 003    │ NET    │
└────────┴────────┴────────┘          └────────┴────────┘
                    ↑                         ↑
                    └────── 조인 속성: 학번 ──────┘

세타 조인 (Theta Join)

조건을 만족하는 투플을 연결 (비교 연산자 사용)

R ⋈(A θ B) S    (θ: >, >=, <, <=, =, ≠)

동등 조인 (Equi Join)

세타 조인에서 = 연산자 사용 (가장 일반적)

학생 ⋈(학생.학번 = 수강.학번) 수강

┌────────┬────────┬────────┬────────┬────────┐
│ 학번    │ 이름    │ 학과    │ 학번    │ 과목    │
├────────┼────────┼────────┼────────┼────────┤
│ 001    │ 홍길동  │ CS     │ 001    │ DB     │
│ 001    │ 홍길동  │ CS     │ 001    │ OS     │
│ 002    │ 김영희  │ BA     │ 002    │ DB     │
│ 003    │ 이철수  │ CS     │ 003    │ NET    │
└────────┴────────┴────────┴────────┴────────┘
          ↑                  ↑
          └── 학번 중복됨 ────┘

자연 조인 (Natural Join) - ⋈ₙ

동등 조인 + 중복 속성 제거

학생 ⋈ₙ 수강

┌────────┬────────┬────────┬────────┐
│ 학번    │ 이름    │ 학과    │ 과목    │
├────────┼────────┼────────┼────────┤
│ 001    │ 홍길동  │ CS     │ DB     │
│ 001    │ 홍길동  │ CS     │ OS     │
│ 002    │ 김영희  │ BA     │ DB     │
│ 003    │ 이철수  │ CS     │ NET    │
└────────┴────────┴────────┴────────┘
          ↑
          └── 학번 한 번만 나타남

주의: 004 박민수는 수강 기록이 없어 결과에 미포함!

SQL 대응:

-- 동등 조인
SELECT * FROM 학생, 수강 WHERE 학생.학번 = 수강.학번;

-- INNER JOIN
SELECT * FROM 학생 INNER JOIN 수강 ON 학생.학번 = 수강.학번;

-- NATURAL JOIN
SELECT * FROM 학생 NATURAL JOIN 수강;

조인 종류 비교

┌─────────────────────────────────────────────────────────────┐
│                     조인 (Join) 종류                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  세타 조인 (θ-Join)                                          │
│    └── 동등 조인 (Equi Join)  [θ = '=']                      │
│          └── 자연 조인 (Natural Join)  [중복 속성 제거]        │
│                                                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  외부 조인 (Outer Join)                                      │
│    ├── 왼쪽 외부 조인 (Left Outer Join)                      │
│    ├── 오른쪽 외부 조인 (Right Outer Join)                   │
│    └── 완전 외부 조인 (Full Outer Join)                      │
│                                                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  세미 조인 (Semi Join)                                       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

4.5 디비전 (Division) - ÷

S의 모든 투플과 관련 있는 R의 투플을 반환

수강 (R)                              필수과목 (S)
┌────────┬────────┐                  ┌────────┐
│ 학번    │ 과목    │                  │ 과목    │
├────────┼────────┤                  ├────────┤
│ 001    │ DB     │                  │ DB     │
│ 001    │ OS     │                  │ OS     │
│ 001    │ NET    │                  └────────┘
│ 002    │ DB     │
│ 002    │ OS     │
│ 003    │ DB     │
└────────┴────────┘

수강 ÷ 필수과목

"DB와 OS를 모두 수강한 학생은?"

┌────────┐
│ 학번    │
├────────┤
│ 001    │  ← DB, OS 모두 수강
│ 002    │  ← DB, OS 모두 수강
└────────┘

003은 DB만 수강했으므로 제외

SQL 대응 (직접 지원 없음):

-- "모든 필수과목을 수강한 학생"
SELECT 학번 FROM 수강
WHERE 과목 IN (SELECT 과목 FROM 필수과목)
GROUP BY 학번
HAVING COUNT(DISTINCT 과목) = (SELECT COUNT(*) FROM 필수과목);

5. 확장된 관계 대수 연산자

5.1 세미 조인 (Semi Join) - ⋉

조인 속성으로 프로젝트한 후 조인

R ⋉ S = R ⋈ (π(조인속성)(S))
학생                                   수강
┌────────┬────────┬────────┐          ┌────────┬────────┐
│ 학번    │ 이름    │ 학과    │          │ 학번    │ 과목    │
├────────┼────────┼────────┤          ├────────┼────────┤
│ 001    │ 홍길동  │ CS     │          │ 001    │ DB     │
│ 002    │ 김영희  │ BA     │          │ 002    │ OS     │
│ 003    │ 이철수  │ CS     │          └────────┴────────┘
│ 004    │ 박민수  │ EE     │
└────────┴────────┴────────┘

학생 ⋉ 수강 = 학생 ⋈ (π(학번)(수강))

결과: 수강 기록이 있는 학생만
┌────────┬────────┬────────┐
│ 학번    │ 이름    │ 학과    │
├────────┼────────┼────────┤
│ 001    │ 홍길동  │ CS     │
│ 002    │ 김영희  │ BA     │
└────────┴────────┴────────┘

주의: R ⋉ S ≠ S ⋉ R (교환적 특성 없음!)

SQL 대응:

SELECT * FROM 학생 WHERE 학번 IN (SELECT 학번 FROM 수강);
-- 또는
SELECT * FROM 학생 WHERE EXISTS (SELECT 1 FROM 수강 WHERE 수강.학번 = 학생.학번);

5.2 외부 조인 (Outer Join)

조인에서 제외된 투플도 포함 (NULL로 채움)

학생                                   수강
┌────────┬────────┐                  ┌────────┬────────┐
│ 학번    │ 이름    │                  │ 학번    │ 과목    │
├────────┼────────┤                  ├────────┼────────┤
│ 001    │ 홍길동  │                  │ 001    │ DB     │
│ 002    │ 김영희  │                  │ 002    │ OS     │
│ 003    │ 이철수  │                  │ 005    │ NET    │  ← 학생에 없음
└────────┴────────┘                  └────────┴────────┘

왼쪽 외부 조인 (Left Outer Join)

학생 ⟕ 수강

┌────────┬────────┬────────┬────────┐
│ 학번    │ 이름    │ 학번    │ 과목    │
├────────┼────────┼────────┼────────┤
│ 001    │ 홍길동  │ 001    │ DB     │
│ 002    │ 김영희  │ 002    │ OS     │
│ 003    │ 이철수  │ NULL   │ NULL   │  ← 왼쪽 릴레이션 모두 포함
└────────┴────────┴────────┴────────┘

오른쪽 외부 조인 (Right Outer Join)

학생 ⟖ 수강

┌────────┬────────┬────────┬────────┐
│ 학번    │ 이름    │ 학번    │ 과목    │
├────────┼────────┼────────┼────────┤
│ 001    │ 홍길동  │ 001    │ DB     │
│ 002    │ 김영희  │ 002    │ OS     │
│ NULL   │ NULL   │ 005    │ NET    │  ← 오른쪽 릴레이션 모두 포함
└────────┴────────┴────────┴────────┘

완전 외부 조인 (Full Outer Join)

학생 ⟗ 수강

┌────────┬────────┬────────┬────────┐
│ 학번    │ 이름    │ 학번    │ 과목    │
├────────┼────────┼────────┼────────┤
│ 001    │ 홍길동  │ 001    │ DB     │
│ 002    │ 김영희  │ 002    │ OS     │
│ 003    │ 이철수  │ NULL   │ NULL   │  ← 양쪽 모두 포함
│ NULL   │ NULL   │ 005    │ NET    │
└────────┴────────┴────────┴────────┘

SQL 대응:

-- 왼쪽 외부 조인
SELECT * FROM 학생 LEFT OUTER JOIN 수강 ON 학생.학번 = 수강.학번;

-- 오른쪽 외부 조인
SELECT * FROM 학생 RIGHT OUTER JOIN 수강 ON 학생.학번 = 수강.학번;

-- 완전 외부 조인
SELECT * FROM 학생 FULL OUTER JOIN 수강 ON 학생.학번 = 수강.학번;

6. 연산자와 SQL 대응표

관계 대수기호SQL
셀렉트σWHERE
프로젝트πSELECT (컬럼 지정)
합집합UNION
교집합INTERSECT
차집합-EXCEPT / MINUS
카티션 프로덕트×CROSS JOIN 또는 ,
자연 조인⋈ₙNATURAL JOIN
동등 조인INNER JOIN ... ON
왼쪽 외부 조인LEFT OUTER JOIN
오른쪽 외부 조인RIGHT OUTER JOIN
완전 외부 조인FULL OUTER JOIN

7. 정리

일반 집합 연산자

연산자기호의미
합집합R 또는 S에 속하는 투플
교집합R과 S에 공통으로 속하는 투플
차집합-R에만 속하는 투플
카티션 프로덕트×R과 S의 모든 투플 조합

순수 관계 연산자

연산자기호의미
셀렉트σ조건을 만족하는 투플 (수평)
프로젝트π선택한 속성으로 구성된 투플 (수직)
조인공통 속성으로 연결된 투플
디비전÷S의 모든 투플과 관련 있는 R의 투플

핵심 특성

  1. 폐쇄 특성: 연산 결과도 릴레이션 → 연쇄 연산 가능
  2. 셀렉트: 수평적 부분집합 (행 선택)
  3. 프로젝트: 수직적 부분집합 (열 선택)
  4. 자연 조인: 동등 조인 + 중복 속성 제거
  5. 외부 조인: 조인 실패한 투플도 NULL로 포함