키(key)는 릴레이션에서 튜플을 하나씩 구별하거나, 다른 릴레이션의 튜플을 가리킬 때 쓰는 속성의 묶음입니다. 유일성과 최소성 두 성질로 슈퍼키·후보키·기본키·대체키를 가르고, 다른 릴레이션의 기본키를 가리키는 키는 외래키라고 합니다.
학생 일곱 명 가운데 한 명을 정확히 가리켜야 할 때가 많습니다. 성적을 고칠 학생을 찾을 때도, 수강 표의 101이 어느 학생인지 알아낼 때도 그렇습니다. 이름으로 가리키면 동명이인이 들어오는 순간 두 명이 나옵니다. 그래서 값이 겹치지 않는 속성을 정해 두고, 그 속성으로 튜플을 가리킵니다. 아래 그림은 학생 표에 열 묶음을 하나씩 대 보며 두 성질을 따집니다.
1유일성과 최소성
키가 될 수 있는지는 두 성질로 봅니다. 그림은 학생 표의 학년, 학번, 학번 + 이름을 차례로 대 보며 이 둘을 따집니다.
- 유일성(uniqueness): 그 속성 값으로 모든 튜플을 하나씩 구별할 수 있습니다.
- 최소성(minimality): 묶음에서 속성을 하나라도 빼면 유일성이 깨집니다. 꼭 필요한 속성만 묶었다는 뜻입니다.
키는 튜플을 하나씩 구별하는 데 쓰는 속성의 묶음입니다. 속성 하나일 수도 있고, 둘 이상을 묶을 수도 있습니다.
학년은 3이 세 번 나옵니다. 학년이 3인 튜플을 찾으면 101·105·106 세 명이 나오므로 유일성이 없습니다.
학번은 일곱 값이 모두 다릅니다. 속성이 하나뿐이라 더 뺄 것이 없으니 최소성도 갖춥니다. 유일성과 최소성을 모두 갖춘 묶음을 후보키(candidate key)라고 합니다. 기본키가 될 수 있는 후보라는 뜻입니다.
학번 + 이름도 모든 튜플을 구별합니다. 그런데 이름을 빼도 학번만으로 구별되니 최소성이 없습니다. 이렇게 유일성은 갖추었지만 최소성은 갖추지 못한 묶음을 슈퍼키(super key)라고 합니다. 슈퍼키는 최소성을 따지지 않으므로, 학번처럼 두 성질을 다 갖춘 묶음도 슈퍼키에 듭니다. 다만 시험에서 '어떤 키인가'를 물으면 두 성질을 다 갖춘 묶음은 후보키라고 답합니다.
2키는 지금 값이 아니라 들어올 값으로 정한다
이름은 지금 학생 표에서는 일곱 값이 모두 다릅니다. 하지만 동명이인 김민수가 들어오면 겹칩니다. 키는 지금 들어 있는 값이 아니라, 앞으로 들어올 수 있는 값까지 보고 정합니다. 그래서 이름은 후보키가 아닙니다.
3후보키에서 고르는 기본키와 대체키
과목 표에서 과목명은 겹치지 않게 정한다고 합시다. 그러면 과목코드와 과목명이 둘 다 후보키입니다. 후보키 가운데 하나를 골라 기본키(PK, Primary Key)로 삼습니다. 보통 짧고 바뀌지 않는 과목코드를 고릅니다. 기본키로 고르지 않고 남은 후보키 과목명은 대체키(alternate key)입니다. 자료에 따라 보조키라고도 부릅니다.
4속성 둘을 묶은 키와 외래키
수강 표에는 학번도 과목코드도 여러 번 나옵니다. 학번 101은 세 번, 과목코드 DS는 네 번입니다. 둘을 묶은 학번 + 과목코드는 겹치지 않아 유일성을 갖춥니다. 어느 하나를 빼면 다시 겹치니 최소성도 갖춥니다. 속성 둘로 된 묶음도 후보키가 될 수 있습니다. 수강의 기본키가 이 묶음입니다.
수강의 학번은 학생의 기본키 학번을, 수강의 과목코드는 과목의 기본키 과목코드를 가리킵니다. 다른 릴레이션의 기본키를 가리키는 속성을 외래키(FK, Foreign Key)라고 합니다. 외래키를 따라가면 수강 행 101 · DS에서 김민수와 자료구조를 찾을 수 있습니다.
그림 밖에서 알아 둘 것이 셋 있습니다.
- 기본키는 튜플을 가리키는 데 쓰므로 비어 있으면(NULL) 안 되고 겹쳐도 안 됩니다. 이 규칙은 다음 레슨 무결성 제약 조건에서 봅니다.
- 외래키는 비어 있어도 됩니다. 학생의 학과코드는 학과를 가리키는 외래키인데, 107 강도현은 아직 학과가 없어 NULL입니다.
- 외래키는 자기 릴레이션의 기본키를 가리킬 수도 있습니다. 과목의 선수과목은 같은 과목 표의 과목코드를 가리킵니다.
예제
SQL 문장은 13단원부터 배웁니다. 여기서는 INSERT는 행을 넣고, SELECT와 WHERE는 조건에 맞는 행을 보여 준다는 것만 알면 됩니다.
동명이인이 들어오면
그림이 이름을 대 보던 장면을 실제로 해 봅니다. 동명이인 김민수(108)를 넣고 이름이 김민수인 학생을 찾으면 둘이 나옵니다.
SQL로 확인하기
INSERT INTO 학생
VALUES (108, '김민수',
1, 'EE');
SELECT 학번,
이름,
학년
FROM 학생
WHERE 이름 = '김민수'
ORDER BY 학번;| 학번 | 이름 | 학년 |
|---|---|---|
| 101 | 김민수 | 3 |
| 108 | 김민수 | 1 |
이름으로 찾으면 두 학생이 나옵니다. 학번으로 찾으면 언제나 한 명입니다.
대체키도 겹치지 않게 막는다
그림이 과목 표에 둔 가정 '과목명은 겹치지 않는다'를 실제로 겁니다. 대체키는 SQL에서 UNIQUE로 적습니다. 그 뒤 이미 있는 과목명 자료구조로 새 과목을 넣으면, 과목명이 겹친다는 오류(ORA-00001)를 내고 들어가지 않습니다.
SQL로 확인하기
제약 조건을 거는 ALTER TABLE은 13단원 DDL: CREATE·ALTER·DROP에서 배웁니다. 오류 속 SQLD는 이 예제를 돌린 데이터베이스 계정 이름입니다.
ALTER TABLE 과목
ADD CONSTRAINT
과목_과목명_UK
UNIQUE (과목명);
INSERT INTO 과목
VALUES ('AL', '자료구조',
3, NULL);ORA-00001: unique
constraint
(SQLD.과목_과목명_UK)
violated
on table SQLD.과목
columns (과목명)
ORA-03301: (ORA-00001
details) row with column
values (과목명:'자료구조')
already exists
표에 적는 키
슈퍼키와 후보키는 설계할 때 따져 보는 묶음입니다. 표를 만들 때 SQL로 적는 것은 기본키·대체키·외래키 셋입니다.
| 키 | SQL에 적는 꼴 | 이 데이터에서 |
|---|---|---|
| 기본키 | PRIMARY KEY | 학생의 학번, 수강의 학번 + 과목코드 |
| 대체키 | UNIQUE | 과목의 과목명(예제에서 더함) |
| 외래키 | REFERENCES | 수강의 학번 → 학생의 학번 |
시험 포인트
- 필기: 키 이름은 두 성질로 가립니다 — 후보키는 유일성과 최소성을 모두 갖추고, 슈퍼키는 유일성만 갖춥니다(최소성은 따지지 않음). 기본키는 후보키 가운데 고른 하나, 대체키는 고르고 남은 후보키, 외래키는 다른 릴레이션의 기본키를 가리키는 속성입니다. 키는 지금 값이 아니라 들어올 수 있는 모든 값을 두고 정합니다. 정의를 주고 키 이름을 고르게 하거나, 표를 주고 후보키·슈퍼키를 찾게 합니다.
- 실기: 키 이름을 씁니다 — 슈퍼키(Super Key)·후보키(Candidate Key)·기본키(PK, Primary Key)·대체키(Alternate Key)·외래키(FK, Foreign Key).
확인 문제
1. 수강 표(학번, 과목코드, 점수)에서 한 학생은 같은 과목을 한 번만 듣습니다. 후보키로 알맞은 것을 고르세요.
- ① (학번)
- ② (학번, 과목코드)
- ③ (학번, 과목코드, 점수)
- ④ (과목코드, 점수)
정답
②입니다. 한 학생이 한 과목을 한 번만 들으니 (학번, 과목코드)는 행마다 다릅니다(유일성). 둘 가운데 하나라도 빼면 겹칩니다(최소성).
- ① 학번만으로는 겹칩니다. 101은 세 과목을 들어 세 행에 나옵니다.
- ③ 행은 모두 구별하지만, 점수를 빼도 여전히 구별되어 최소성이 없습니다.
- ④ 같은 과목에서 같은 점수가 나올 수 있습니다. OS에 75점이 두 행(101·104) 있습니다.
2. 1번 보기 ③ (학번, 과목코드, 점수)는 모든 행을 구별하지만, 점수를 빼도 여전히 구별됩니다. 이런 키의 이름을 한글 이름과 영문으로 함께 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.
정답
받는 답: 슈퍼키(Super Key)
모든 행을 구별하면(유일성) 키가 될 수 있고, 없어도 되는 속성이 섞여 최소성이 없으면 후보키가 아니라 슈퍼키입니다.
- 틀리는 꼴 후보키: 유일성과 최소성을 모두 갖춘 키입니다. 점수를 빼도 구별되니 후보키가 아닙니다.
- 틀리는 꼴 대체키: 후보키 가운데 기본키로 고르지 않은 나머지입니다. 이 조합은 후보키부터 아닙니다.
3. 다른 업무의 사원 릴레이션(사번, 주민등록번호, 이름, 부서코드)을 설계한 기록입니다. 사번과 주민등록번호는 사원마다 다르고 비는 일이 없습니다. (가)~(라)에 들어갈 키 이름을 한글 이름과 영문으로 함께 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.
- (가) 사번과 주민등록번호는 각각 혼자서 사원을 하나씩 집어내고, 더 뺄 속성도 없습니다. 둘 다 (가)입니다.
- (나) 둘 가운데 짧고 바뀌지 않는 사번을 골라, 사원을 가리킬 때 늘 이것을 쓰기로 했습니다. 사번이 (나)입니다.
- (다) 고르지 않고 남은 주민등록번호는 (다)입니다.
- (라) 부서코드에는 부서 릴레이션에 실제로 있는 부서의 코드만 넣을 수 있습니다. 부서코드는 (라)입니다.
정답
받는 답: (가) 후보키(Candidate Key) · (나) 기본키(PK, Primary Key) · (다) 대체키(Alternate Key, 자료에 따라 보조키) · (라) 외래키(FK, Foreign Key)
(가)의 실마리는 '혼자서 집어내고 더 뺄 속성이 없다', (나)는 '그 가운데 하나를 골라 늘 이것으로 가리킨다', (다)는 '고르지 않고 남았다', (라)는 '다른 릴레이션에 있는 값만 넣을 수 있다'입니다.
- 같은 이름의 다른 꼴: Candidate Key·Primary Key처럼 영문만 쓴 꼴 — 문제가 한글 이름과 영문을 함께 쓰라고 했습니다.
- 틀리는 꼴 슈퍼키 — (가)에: 뺄 속성이 남아 있어도 되는 키입니다. 사번과 주민등록번호는 더 뺄 것이 없습니다.
- 틀리는 꼴 외래키 — (다)에: 다른 릴레이션의 값을 가리키는 속성입니다. 주민등록번호는 사원 안에서 사원을 집어낼 뿐입니다.
더 자세히: SQLD의 식별자