관계형 데이터베이스에서의 키(Key)
지난 시간에 이어 데이터베이스 개념들을 정리해보겠습니다. 테이블을 설계할 때 키들을 정해야 할 때가 옵니다. 그때 과거의 저의 경험에 빗대어 저술해보겠습니다.
기본 키 정하기
기본 키를 정하기 위해서는 기본 키의 개념에 대해 알아야 합니다.
제 과거 이야기를 해볼까요? 저는 국비 지원 학원을 다녔었는데요. 그때 한 동료 분이 최종 프로젝트를 준비하면서, 테이블 설계에 대해 고민을 하셨습니다. (개인 프로젝트여서 설계도 다 혼자 했어야 했습니다.)
그분은 테이블을 설계할 때 기본 키를 2개로 설정할지, 3개로 설정할지를 고민했었습니다. 저는 기본키를 한 개 이상 설정한다는 점에서 무언가 아닌거 같았는데, 그때 당시에는 왜 아닌 거 같은지 설명할 수 없었습니다. 그리고 3개의 속성은 중복되면 안 되서 이렇게 설정했다는 그분의 의견도 일리가 있는 거 같아 넘어갔는데요. 요즘 데이터 베이스 키에 대해 공부하면서 그분 생각이 많이 납니다.
결과적으로 기본 키는 하나만 설정할 수 있습니다.
어라? 기본 키는 하나 이상 설정할 수 있는데? 라고 물으실 수 있습니다. 이번 글은 그런 분들에게 도움이 되었으면 좋겠습니다.
슈퍼 키
기본 키를 이해하기 위해서는 후보 키를 이해해야 합니다. 그리고 후보 키를 이해하기 위해서는 슈퍼 키를 이해해야 합니다.
슈퍼 키는 릴레이션에서 튜플들을 고유하게 식별할 수 있는 속성들의 집합 입니다.
이미지의 학급 릴레이션은 CLASS(student_id, student_name, age, class_number, class_name)
를 담고 있습니다. 여기서 슈퍼 키는 튜플들을 고유하게 식별할 수 있는 속성의 조합이면 슈퍼 키가 됩니다.
예를 들어 학생 아이디, 이름과, 나이, 학급 번호, 반 번호는 중복 될 수 있어서 슈퍼 키가 될 수 없습니다. 오직 학생의 고유 아이디만 슈퍼 키가 될 수 있습니다.
이때 슈퍼 키가 될 수 없었던 속성들을 학생 아이디와 조합하면 그 자체로 고유해지기 때문에 슈퍼 키가 될 수 있습니다.
또 이런 조합이 가능합니다. 학급 번호와, 반 이름은 각각 중복될 수 있기 때문에 슈퍼 키가 되지 못합니다. 하지만 서로 조합하면 슈퍼 키가 될 수 있습니다. 예를 들어 1반 13번과 4반 13번은 고유하기 때문입니다.
그리고 모든 속성들을 조합하면 역시 고유해지기에 슈퍼 키가 될 수 있습니다. 이 모든 경우를 조합해보면 다음과 같습니다.
{student_id, student_name, age, class_number, class_name}, {student_id}, {student_id, student_name}, {student_id, age}, {student_id, class_number}, {student_id, class_name}, {class_number, class_name}, ... etc
위 경우의 수를 보시면 아시겠지만, 튜플을 고유하게 식별할 수 있는 속성의 조합이면 모두 다 슈퍼 키가 될 수 있습니다.
후보 키
슈퍼 키는 튜플들을 고유하게 식별할 수 있는 속성들의 집합이었는데요? 이때 후보 키는 이 속성 중에서 하나라도 빠지게 되면 슈퍼 키가 되지 않는 키를 후보 키라 합니다.
따라서 후보 키는 {student_id}, {class_number, class_name}
입니다. 이때 드는 의문이 있을 수 있습니다. student_id
는 이해할 수 있는데, class_number
와 class_name
은 두 개의 속성인데 후보 키가 되는 이유인데요. class_number
와 class_name
의 조합이 가능하면 student_id, student_name
, ... 등의 2개 조합도 가능해야 할 거 같습니다.
하지만 잘 생각해보면 student_id
를 포함한 조합은 후보 키로 적절하지 않습니다.
문제의 class_number
와 class_name
의 조합을 볼까요? 이는 제가 위에서 언급드렸던 후보 키의 속성 설명, 「_후보 키는 어느 하나라도 빠지게 되면 슈퍼 키가 되지 않는 키입니다._」를 충족합니다. 서로가 빠진 각각의 class_number
와 class_name
은 하나로만 본다면 슈퍼 키가 아니기 때문입니다.
하지만, student_id
를 포함한 조합들은 이야기가 다릅니다. 예로 student_id
, student_name
조합은 student_id
가 빠지면 student_name
은 중복 될 수 있기 때문에 슈퍼 키가 되지 않습니다. 그러나 반대의 경우 student_name
이 빠져도 student_id
는 중복되지 않기 때문에 슈퍼 키입니다.「_후보 키는 어느 하나라도 빠지게 되면 슈퍼 키가 되지 않는 키입니다._」라는 설명에서 student_name
이 빠져도 student_id
는 슈퍼 키이기 때문에 후보 키가 되지 않습니다.
기본 키
기본 키는 데이터베이스 설계자에 의해 선택된 후보 키입니다. 기본 키는 다음과 같은 특징을 갖습니다.
- 기본 키는 후보 키의 속성을 같습니다. 따라서 고유해야 합니다.
- 기본 키는 하나만 존재합니다.
- 기본 키는 null이 올 수 없습니다.
위 테이블에서 정할 수 있는 기본 키는 {student_id}
와 {class_number, class_name}
입니다.
이제 기본 키를 둘 중 하나로 정해야 하는데요. 이때 기본 키는 한 번 정하면 절대 변하면 안 됩니다. 따라서 우리가 제어할 수 없는 현실 세계의 속성에 의존하지 않는 것이 중요합니다. 가령 핸드폰 번호나, 주민등록번호는 후보 키에 어울리지만, 기본 키로는 지양해야 합니다. 왜냐하면 이것들은 개발자가 제어할 수 없기 때문입니다.
또한 속성의 개수가 가장 적은 것을 골라야 관리하기 편합니다. 따라서 저였다면 기본 키를 현실 세계의 속성에 의존하지 않고, 관리하기도 편한 student_id
로 정하겠습니다.
예전 이야기로 돌아가서, 만약 제가 과거로 돌아가면 동료분에게 이렇게 조언해줄 거 같습니다.
- 테이블에서 후보 키를 먼저 뽑아 보세요.
- null이 올 수 있는 것을 제거하세요.
- 현실 세계의 속성을 제거하세요.
- 그렇게 해서 남는 최소한의 속성 집합을 후보 키로 삼으세요.
유니크 키
유니크 키는 후보 키에서 기본 키로 선택되지 않은 남은 모든 키들을 유니크 키라 할 수 있습니다. 위의 경우 {class_number, class_name}
가 유니크 키입니다.
마치며
이 글을 읽으셨다면 기본 키는 두 개 이상 올 수 없다는 것을 알게 되셨을 겁니다.
create table class
(student_id int(20),
student_name varchar(20),
age int,
class_number int,
class_name int,
primary key(class_number, class_name)
);
만약 class_number
와 class_name
의 조합을 기본 키로 정했다면 기본 키는 {class_number, class_name}
인 것이지 {class_number}
, {class_name}
로 두 개가 아니라는 점 아셨으면 좋겠습니다.
또한 기본 키를 정할 때 속성의 조합이 하나 이상 나오게 되었다면, 위에서 말씀 드린 조건들을 충족하는지 따져봐야 합니다. (not null, 제어 가능한 속성인지 등등)
또 글에서 많이 벗어나는 거 같아 자세히 언급하지 않았지만, 기본 키는 기본적으로 데이터베이스에서 인덱스처리합니다. 워크밴치에서 확인해볼까요?
제가 테이블을 만들 때 인덱스처리하지 않았어도, 테이블에는 자동으로 기본 키가 인덱스처리 되었습니다. 이처럼 기본 키를 설계할 때는 이런 것들을 다 따져가며 설계해야 합니다.
긴 글 읽어주셔서 감사합니다!
'Database' 카테고리의 다른 글
관계형 데이터베이스 개념 정리(릴레이션, 튜플, 도메인) (0) | 2023.09.18 |
---|---|
관계형 데이터베이스 정리 (0) | 2023.09.14 |
데이터베이스 트랜잭션(transaction)의 중요성 (0) | 2023.04.02 |