logo
작성일

CH5. 관계대수 한 장

Authors
  • avatar
    Name
    seren-wib
    Twitter
Contents

관계대수 한 장 (6장 전부)

SQL은 "뭘 원하는지", 관계대수는 "어떤 순서로 꺼낼지". 답 쓸 땐 ← 로 한 줄씩 끊어 쓰는 게 안 틀림

1. 기호 한눈에

기호이름하는 일SQL
σ조건(R)SELECT조건 맞는 행WHERE
π열(R)PROJECT적은 열만, 중복 지움SELECT DISTINCT
ρS(열…)(R)RENAME테이블·열 이름 바꾸기AS
R ∪ S, R ∩ S, R − S집합 연산합·교·차UNION, INTERSECT, EXCEPT
R × SCARTESIAN PRODUCT모든 행 조합FROM R, S (조건 없이)
R ⋈조건 SJOIN조건 맞는 행끼리 붙임JOIN ON
R * SNATURAL JOIN같은 이름 열로 붙이고 그 열 하나만NATURAL JOIN
R ⟕ S, R ⟖ S, R ⟗ SOUTER JOIN짝 없어도 남김LEFT / RIGHT / FULL OUTER JOIN
그룹열ℱ함수 열(R)집계묶어서 COUNT·SUM…GROUP BY + 집계
R ÷ SDIVISIONS 전부 가진 R 행NOT EXISTS … EXCEPT
T ← 식대입중간 결과에 이름임시 테이블

2. 행 고르기 σ

σ조건(R): 조건 맞는 행만. 열은 그대로

  • 조건은 열 비교 값 / 열 비교 열, AND·OR·NOT. 비교는 =, <, ≤, >, ≥, ≠

σDno=4(EMPLOYEE) → 4번 부서 직원
σ(Dno=4 AND Salary>25000) OR (Dno=5 AND Salary>30000)(EMPLOYEE)

  • σc1(σc2(R)) = σc1 AND c2(R). 순서 상관없음
  • 이름이 SELECT인데 SQL의 WHERE임. SQL SELECT 자리는 π

3. 열 고르기 π

π열 목록(R): 적은 열만. 결과는 집합이라 겹치는 행 지움

πLname, Fname, Salary(EMPLOYEE) → 세 열
πSex, Salary(EMPLOYEE) → (M, 25000) 둘이면 하나로

4. 이어 쓰기와 이름 바꾸기 ρ

둘 중 하나: 괄호로 겹치기 / ← 로 끊기. 안쪽(아래 줄)부터 실행

πFname, Lname, Salary(σDno=5(EMPLOYEE))

DEP5_EMPS ← σDno=5(EMPLOYEE)
RESULT ← πFname, Lname, Salary(DEP5_EMPS)

ρ 쓰는 법바꾸는 것
ρS(B1, B2, …)(R)테이블 이름 S, 열 이름 B1, B2…
ρS(R)테이블 이름만
ρ(B1, B2, …)(R)열 이름만
R(B1, B2, …) ← 식← 왼쪽에 열 이름 붙여도 됨

R(First_name, Last_name, Salary) ← πFname, Lname, Salary(DEP5_EMPS)

5. 집합 연산 ∪ ∩ −

조건: 열 개수 같고 열마다 타입 같아야 (type compatible)

식결과예
R ∪ S둘 중 하나에라도 있는 행, 중복 지움학생이거나 강사
R ∩ S둘 다에 있는 행학생이면서 강사
R − SR엔 있고 S엔 없는 행. S − R과 다름강사 아닌 학생

RESULT1 ← πSsn(DEP5_EMPS)
RESULT2(Ssn) ← πSuper_ssn(DEP5_EMPS)
RESULT ← RESULT1 ∪ RESULT2

  • 5번 부서 직원이거나 그 직속 상사인 Ssn. 열 이름 달라서 RESULT2에 (Ssn) 붙임

6. 모든 조합 ×

R × S: R 행 하나마다 S 행 전부 붙임. 열 n + m, 행 |R| × |S|. 타입 안 맞아도 됨

  • 혼자선 쓰레기. 뒤에 σ로 짝 맞는 조합만 남김 → 그걸 합친 게 JOIN

FEMALE_EMPS ← σSex='F'(EMPLOYEE)
EMPNAMES ← πFname, Lname, Ssn(FEMALE_EMPS)
EMP_DEPENDENTS ← EMPNAMES × DEPENDENT
ACTUAL_DEPENDENTS ← σSsn=Essn(EMP_DEPENDENTS)
RESULT ← πFname, Lname, Dependent_name(ACTUAL_DEPENDENTS)

  • 여직원과 부양가족 이름. 3행 × 7행 = 21행 만들고 σ로 짝 맞는 것만

7. 붙이기 ⋈

R ⋈조건 S = σ조건(R × S). 조건 맞는 R행·S행을 한 줄로

DEPT_MGR ← DEPARTMENT ⋈Mgr_ssn=Ssn EMPLOYEE
RESULT ← πDname, Lname, Fname(DEPT_MGR)

  • 부서별 관리자 이름
종류조건결과 열
THETA JOIN ⋈A θ Bθ는 =, <, ≤, >, ≥, ≠ 아무거나R 열 + S 열 전부
EQUIJOIN ⋈A=B= 만R 열 + S 열 전부. 값 같은 열 둘 다 남음 (Mgr_ssn, Ssn)
NATURAL JOIN R * S이름 같은 열끼리 =같은 이름 열은 하나만
  • NATURAL JOIN은 열 이름이 같아야. 다르면 ρ로 먼저 맞춤

DEPT ← ρ(Dname, Dnum, Mgr_ssn, Mgr_start_date)(DEPARTMENT)
PROJ_DEPT ← PROJECT * DEPT

  • PROJECT.Dnum과 맞추려고 Dnumber → Dnum

  • 결과 행 수: 0 (하나도 안 맞음) ~ |R| × |S| (전부 맞음)

OUTER JOIN: 짝 없는 행도 남기고 빈 칸 NULL. ⟕ 왼쪽 전부, ⟖ 오른쪽 전부, ⟗ 양쪽

TEMP ← EMPLOYEE ⟕Ssn=Mgr_ssn DEPARTMENT
RESULT ← πFname, Minit, Lname, Dname(TEMP)

  • 전 직원 + 관리하는 부서 이름. 관리자 아니면 Dname NULL

8. 세기 ℱ

그룹 열 ℱ 함수 열, …(R): 그룹 열 같은 행끼리 묶어 함수. 함수는 COUNT, SUM, AVERAGE, MAXIMUM, MINIMUM

Dno ℱ COUNT Ssn, AVERAGE Salary(EMPLOYEE) - 부서별 직원 수·평균 급여. 결과 열 Dno, Count_ssn, Average_salary

ℱ COUNT Ssn, AVERAGE Salary(EMPLOYEE)

  • 그룹 열 없으면 전체 한 묶음 → 한 행

ρR(Dno, No_of_employees, Average_sal)(Dno ℱ COUNT Ssn, AVERAGE Salary(EMPLOYEE))

  • 열 이름 바꾸려면 ρ로 감쌈

  • 중복 안 지우고 셈 / NULL은 빼고 / 결과는 한 칸이라도 테이블

9. 전부 가진 것 찾기 ÷

R ÷ S: S에 있는 값을 전부 가진 R의 행. S 열은 R 열의 일부여야 하고, 결과 열 = R 열 − S 열

R(A, B) ÷ S(A): S의 a1, a2, a3을 전부 가진 B 값만 남음

SMITH ← σFname='John' AND Lname='Smith'(EMPLOYEE)
SMITH_PNOS ← πPno(WORKS_ON ⋈Essn=Ssn SMITH)
SSN_PNOS ← πEssn, Pno(WORKS_ON)
SSNS(Ssn) ← SSN_PNOS ÷ SMITH_PNOS
RESULT ← πFname, Lname(SSNS * EMPLOYEE)

  • Smith가 하는 프로젝트 전부에 참여하는 직원. SMITH_PNOS = {1, 2}면 1도 2도 하는 Essn만 남음

÷ 쓰는 틀: ① "전부"의 목록 S 만들기(π 한 열) → ② 누가 뭘 하는지 R 만들기(π 두 열, S 열 포함) → ③ R ÷ S → ④ 이름 붙이려고 * 로 원본과 붙이기

10. 완전 집합과 질의 트리

완전 집합 {σ, π, ∪, ρ, −, ×}: 이 여섯으로 나머지 다 만듦

  • R ∩ S = (R ∪ S) − ((R − S) ∪ (S − R))
  • R ⋈c S = σc(R × S)

질의 트리: 식을 나무로. 잎 = 테이블, 안쪽 = 연산, 잎부터 위로 실행

Stafford 프로젝트 질의를 σ → ⋈ → ⋈ → π 순서로 그린 질의 트리

11. 같은 질문, SQL 옆에 관계대수

질문SQL관계대수
5번 부서 직원 이름·급여SELECT Fname, Lname, Salary FROM EMPLOYEE WHERE Dno = 5πFname, Lname, Salary(σDno=5(EMPLOYEE))
Research 부서 직원 이름·주소SELECT Fname, Lname, Address FROM EMPLOYEE, DEPARTMENT WHERE Dname = 'Research' AND Dnumber = DnoRESEARCH ← σDname='Research'(DEPARTMENT) / RD ← RESEARCH ⋈Dnumber=Dno EMPLOYEE / πFname, Lname, Address(RD)
직원과 상사 이름… FROM EMPLOYEE AS E, EMPLOYEE AS S WHERE E.Super_ssn = S.SsnS ← ρS(Sssn, Sfn, Sln, …)(EMPLOYEE) / EMPLOYEE ⋈Super_ssn=Sssn S
부서별 직원 수SELECT Dno, COUNT(*) FROM EMPLOYEE GROUP BY DnoDno ℱ COUNT Ssn(EMPLOYEE)
부양가족 없는 직원WHERE NOT EXISTS (SELECT * FROM DEPENDENT WHERE Ssn = Essn)ALL ← πSsn(EMPLOYEE) / HAS ← πEssn(DEPENDENT) / πFname, Lname((ALL − HAS) * EMPLOYEE)
5번 부서 프로젝트 전부에 참여WHERE NOT EXISTS ((SELECT Pnumber FROM PROJECT WHERE Dnum = 5) EXCEPT (SELECT Pno FROM WORKS_ON WHERE Essn = Ssn))P5 ← πPnumber(σDnum=5(PROJECT)) / SP ← πEssn, Pno(WORKS_ON) / SP ÷ P5
상사 없는 직원도 포함해서 직원 + 상사LEFT OUTER JOINEMPLOYEE ⟕Super_ssn=Sssn S

12. 문제 문장 → 기호

문제에 이 말 나오면쓰는 것
~인 (조건)σ
~의 이름, 번호 (열 고르기)π. 맨 마지막에
테이블 둘의 열⋈FK=PK. 열 이름 같으면 *
직원과 그 상사ρ로 EMPLOYEE 복사본 열 이름 바꾸고 ⋈
~이거나∪ (열 맞춰서)
~이면서 (두 결과 다에)∩
~가 아닌, ~가 없는− (전체 − 있는 것)
몇 명, 합, 평균ℱ
~별, ~마다ℱ 앞에 그룹 열
전부에 참여하는, 모든 ~를÷
짝 없는 것도 보여야⟕ ⟖ ⟗
열 이름 안 맞아서 * 못 씀 / 결과 열 이름 바꾸기ρ