관계 타입과 관계 집합 문서의 검증 코드다. if __name__ == "__main__": 아래가 자체 테스트다.
"""관계 타입과 관계 집합 검증.
문서: 22.관계 타입과 관계 집합 (예시로 보기, 정의, 카드 C2·C3)
출처: Elmasri & Navathe, Fundamentals of Database Systems 3장의 WORKS_FOR 예
주장:
1. 문서의 WORKS_FOR 표의 관계 인스턴스는 7개이고, 하나하나가 (직원, 부서) 짝이다.
r4 = (e4, d2)다(문서에서 예로 든 인스턴스).
2. 관계 집합은 개체 집합들의 곱집합의 부분집합이다: WORKS_FOR ⊆ EMPLOYEE × DEPARTMENT.
문서의 표에 보이는 범위에서 가능한 짝은 7 × 3 = 21개, 그 가운데 7개가 들어 있다.
3. 차수는 인스턴스 하나가 잇는 개체의 수다. WORKS_FOR는 2(이항), SUPPLY는 3(삼항).
4. 집합이므로 같은 짝은 한 번만 들어간다.
"""
from itertools import product
EMPLOYEE = [f"e{i}" for i in range(1, 8)]
DEPARTMENT = ["d1", "d2", "d3"]
# 문서의 WORKS_FOR 표: r1..r7
WORKS_FOR = {
"r1": ("e1", "d1"), "r2": ("e2", "d2"), "r3": ("e3", "d1"), "r4": ("e4", "d2"),
"r5": ("e5", "d3"), "r6": ("e6", "d1"), "r7": ("e7", "d3"),
}
# 삼항 관계 SUPPLY의 작은 예(문서의 예, 보충): (공급자, 부품, 프로젝트)
SUPPLIER, PART, PROJECT = ["s1", "s2"], ["p1", "p2", "p3"], ["j1", "j2", "j3"]
SUPPLY = {("s1", "p1", "j1"), ("s1", "p2", "j1"), ("s2", "p1", "j2")}
def main():
assert len(WORKS_FOR) == 7 and WORKS_FOR["r4"] == ("e4", "d2")
print("[OK] WORKS_FOR: 관계 인스턴스 7개, r4 = (e4, d2)")
pairs = set(WORKS_FOR.values())
space = set(product(EMPLOYEE, DEPARTMENT))
assert pairs <= space and len(space) == 21 and len(pairs) == 7
print("[OK] WORKS_FOR ⊆ EMPLOYEE × DEPARTMENT, 가능한 짝 21개 중 7개")
assert {len(t) for t in pairs} == {2} and {len(t) for t in SUPPLY} == {3}
assert SUPPLY <= set(product(SUPPLIER, PART, PROJECT))
print("[OK] 차수: WORKS_FOR 2, SUPPLY 3")
# d1에서 일하는 직원
assert sorted(e for e, d in pairs if d == "d1") == ["e1", "e3", "e6"]
print("[OK] d1에서 일하는 직원: e1, e3, e6")
# 집합이라 같은 짝을 또 넣어도 늘지 않는다
again = set(pairs)
again.add(("e1", "d1"))
assert len(again) == 7
print("[OK] 같은 짝을 다시 넣어도 7개 그대로다")
print("ALL CHECKS PASSED")
if __name__ == "__main__":
main()