관계형 모델의 표는 줄의 모음이라, 줄을 어떤 순서로 적어도 같은 표다. 칸도 이름과 값의 짝만 맞으면 순서를 바꿔도 된다. 한 칸에는 더 쪼갤 수 없는 값 하나만 들어가므로, 여러 값을 넣고 싶으면 표를 하나 더 만들어야 한다. 값을 모르거나 그 줄에는 맞지 않는 칸에는 ‘값 없음’ 표시를 해 둔다.
예시로 보기
엑셀 표에서는 “세 번째 줄”이라는 말이 통한다. 릴레이션에서는 통하지 않는다. 같은 학생 다섯 명을 두 가지 순서로 적은 표가 있다.
| 순서 1 | 순서 2 |
|---|---|
| Bayer, Kim, Davidson, Panchal, Benson | Davidson, Benson, Panchal, Kim, Bayer |
두 표는 같은 릴레이션이다. 어느 순서가 더 맞는 것도 아니다. 릴레이션은 튜플의 집합이고, 집합의 원소에는 순서가 없기 때문이다. 디스크에는 어떤 순서로든 저장되고 화면에도 위에서 아래로 그려지지만, 그 순서는 릴레이션의 정의에 들어 있지 않다.
칸의 순서는 어떨까? Davidson의 튜플을 “속성 이름과 값의 짝”으로 두 번 적는다.
- ⟨(Name, Dick Davidson), (Ssn, 422-11-2320), (Home_phone, NULL), (Address, 3452 Elgin Road), (Office_phone, (817)749-1253), (Age, 25), (Gpa, 3.53)⟩
- ⟨(Address, 3452 Elgin Road), (Name, Dick Davidson), (Ssn, 422-11-2320), (Age, 25), (Office_phone, (817)749-1253), (Gpa, 3.53), (Home_phone, NULL)⟩
짝의 순서만 다르고 짝은 같다. 그래서 같은 튜플이다. 반대로 값만 자리를 바꿔 Age 칸에 3.53을, Gpa 칸에 25를 넣으면 짝이 달라져 다른 튜플이 된다.
= NULL 0행·IS NULL 3행, 키가 없는 SQL 표에 같은 행 두 번 — 33_relation-characteristics_verify.py네 가지 특성
1. 튜플에는 순서가 없다. 릴레이션은 튜플의 집합으로 정의한다. 그래서 튜플을 늘어놓는 순서는 릴레이션의 일부가 아니다.
2. 속성의 순서는 짝만 맞으면 중요하지 않다. 튜플은 정의로는 값 \(n\)개를 순서대로 늘어놓은 목록이다. 그래도 어느 값이 어느 속성의 것인지만 지켜지면 속성을 적는 순서는 그리 중요하지 않다.
3. 값은 더 쪼갤 수 없는 값 하나다. 이런 값을 원자값이라 부른다. 그래서 여러 부분으로 된 속성(복합 속성)과 값이 여럿인 속성(다치 속성)은 그대로는 들어가지 못한다.
- 복합 속성은 가장 작은 성분만 속성으로 둔다. 이름 Name(Fname, Minit, Lname)은 Fname, Minit, Lname 세 속성이 된다.
- 다치 속성은 릴레이션을 따로 만든다. 5번 부서의 위치는 Bellaire, Sugarland, Houston 세 곳이다. 이 셋을 한 칸에 넣지 않고, DEPT_LOCATIONS(Dnumber, Dlocation)에 (5, Bellaire), (5, Sugarland), (5, Houston) 세 줄로 적는다: 다치 속성의 사상
칸마다 값이 하나뿐인 납작한 표만 쓴다는 뜻에서 이 모델을 평면 관계형 모델(flat relational model)이라 부른다.
4. 값이 없으면 NULL을 쓴다. NULL은 그 튜플에서 값을 모르거나 그 속성이 그 튜플에 맞지 않을 때 쓴다. 뜻이 여럿이다: 모른다(unknown), 있지만 얻을 수 없다(unavailable), 정해지지 않았다(undefined). STUDENT 표에는 NULL이 네 칸 있다. Davidson의 Home_phone 한 칸과 Bayer, Kim, Benson의 Office_phone 세 칸이다. 학생에게는 사무실이 없을 수 있으니 Office_phone의 NULL은 “맞지 않는다”로, Home_phone의 NULL은 “모른다”로 읽을 수 있다. 표만 보고는 어느 뜻인지 가를 수 없다1.
활용
- NULL은 값이 아니다. SQL에서
Office_phone = NULL로 찾으면 한 줄도 안 나온다. NULL끼리 견주어도 참이 되지 않기 때문이다.Office_phone IS NULL로 찾아야 세 줄이 나온다: NULL 값과 IS NULL2 - SQL의 표는 릴레이션과 조금 다르다. 키를 정하지 않은 SQL 표는 똑같은 줄을 두 번 받는다. 집합이 아니라 같은 원소를 여러 번 담는 모음이다: 다중집합인 표와 DISTINCT2
- 흔한 실수. “취미” 칸에
독서, 등산처럼 쉼표로 이어 적는 것. 원자값이 아니라서 “등산이 취미인 사람”을 찾으려면 글자를 쪼개야 한다. 표를 따로 만든다.
연결
- 선수: 릴레이션과 도메인·속성·튜플, 속성의 종류(복합 속성, 다치 속성)
- 순서가 없는 까닭: 집합
- 복합·다치 속성을 릴레이션으로 옮기기: 개체 타입의 사상, 다치 속성의 사상
- NULL이 올 수 없는 자리: 개체 무결성 제약
확인 문제
C1 STUDENT 표를 세 가지로 바꿨다. 원래와 같은 릴레이션인 것은? (가) 줄의 순서를 거꾸로 뒤집었다. (나) Age 칸과 Gpa 칸을 이름과 값을 함께 맞바꿔 적었다. (다) 칸의 이름은 그대로 두고 Davidson의 줄에서 값 25와 3.53만 자리를 바꿨다.
답: (가)와 (나)는 같다. (다)는 다르다.
이유: (가) 튜플에는 순서가 없다. (나) 속성과 값의 짝이 그대로다. (다) (Age, 3.53), (Gpa, 25)라는 다른 짝이 되어 다른 튜플이다. Gpa의 도메인(0과 4 사이)에도 맞지 않는다.
C2 5번 부서의 위치 세 곳을 DEPARTMENT의 한 칸에 적지 않는 까닭은 무엇인가? 그러면 어떻게 적는가? COMPANY 상태에서 그 릴레이션은 몇 줄인가?
답: 릴레이션의 값은 더 쪼갤 수 없는 값 하나여야 한다. 세 곳을 한 칸에 넣으면 원자값이 아니다. DEPT_LOCATIONS(Dnumber, Dlocation)를 따로 만들어 위치마다 한 줄씩 적는다. 1번 부서 1곳, 4번 부서 1곳, 5번 부서 3곳이라 모두 5줄이다.
C3 STUDENT 표에서 Office_phone = NULL인 줄과 Office_phone IS NULL인 줄은 각각 몇 줄 나오는가? 왜 다른가?
답: 0줄과 3줄. NULL은 값이 아니라 “값 없음” 표시라서 무엇과 견주어도, NULL끼리 견주어도 참이 되지 않는다. NULL인지 묻는 말은 IS NULL로 따로 있다.