본문 바로가기
Database

데이터베이스에서 기본 키 정하기(슈퍼 키, 후보 키, 기본 키, 유니크 키 개념 알아보기)

by 코더 제이콥 2023. 9. 22.

관계형 데이터베이스에서의 키(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_numberclass_name은 두 개의 속성인데 후보 키가 되는 이유인데요. class_numberclass_name의 조합이 가능하면 student_id, student_name, ... 등의 2개 조합도 가능해야 할 거 같습니다.

하지만 잘 생각해보면 student_id를 포함한 조합은 후보 키로 적절하지 않습니다.

문제의 class_numberclass_name의 조합을 볼까요? 이는 제가 위에서 언급드렸던 후보 키의 속성 설명, 「_후보 키는 어느 하나라도 빠지게 되면 슈퍼 키가 되지 않는 키입니다._」를 충족합니다. 서로가 빠진 각각의 class_numberclass_name은 하나로만 본다면 슈퍼 키가 아니기 때문입니다.

하지만, student_id를 포함한 조합들은 이야기가 다릅니다. 예로 student_id, student_name 조합은 student_id가 빠지면 student_name은 중복 될 수 있기 때문에 슈퍼 키가 되지 않습니다. 그러나 반대의 경우 student_name이 빠져도 student_id는 중복되지 않기 때문에 슈퍼 키입니다.「_후보 키는 어느 하나라도 빠지게 되면 슈퍼 키가 되지 않는 키입니다._」라는 설명에서 student_name이 빠져도 student_id는 슈퍼 키이기 때문에 후보 키가 되지 않습니다.

기본 키

기본 키는 데이터베이스 설계자에 의해 선택된 후보 키입니다. 기본 키는 다음과 같은 특징을 갖습니다.

  1. 기본 키는 후보 키의 속성을 같습니다. 따라서 고유해야 합니다.
  2. 기본 키는 하나만 존재합니다.
  3. 기본 키는 null이 올 수 없습니다.

위 테이블에서 정할 수 있는 기본 키는 {student_id}{class_number, class_name}입니다.

이제 기본 키를 둘 중 하나로 정해야 하는데요. 이때 기본 키는 한 번 정하면 절대 변하면 안 됩니다. 따라서 우리가 제어할 수 없는 현실 세계의 속성에 의존하지 않는 것이 중요합니다. 가령 핸드폰 번호나, 주민등록번호는 후보 키에 어울리지만, 기본 키로는 지양해야 합니다. 왜냐하면 이것들은 개발자가 제어할 수 없기 때문입니다.

또한 속성의 개수가 가장 적은 것을 골라야 관리하기 편합니다. 따라서 저였다면 기본 키를 현실 세계의 속성에 의존하지 않고, 관리하기도 편한 student_id로 정하겠습니다.

예전 이야기로 돌아가서, 만약 제가 과거로 돌아가면 동료분에게 이렇게 조언해줄 거 같습니다.

  1. 테이블에서 후보 키를 먼저 뽑아 보세요.
  2. null이 올 수 있는 것을 제거하세요.
  3. 현실 세계의 속성을 제거하세요.
  4. 그렇게 해서 남는 최소한의 속성 집합을 후보 키로 삼으세요.

유니크 키

유니크 키는 후보 키에서 기본 키로 선택되지 않은 남은 모든 키들을 유니크 키라 할 수 있습니다. 위의 경우 {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_numberclass_name의 조합을 기본 키로 정했다면 기본 키는 {class_number, class_name}인 것이지 {class_number}, {class_name}로 두 개가 아니라는 점 아셨으면 좋겠습니다.

또한 기본 키를 정할 때 속성의 조합이 하나 이상 나오게 되었다면, 위에서 말씀 드린 조건들을 충족하는지 따져봐야 합니다. (not null, 제어 가능한 속성인지 등등)

또 글에서 많이 벗어나는 거 같아 자세히 언급하지 않았지만, 기본 키는 기본적으로 데이터베이스에서 인덱스처리합니다. 워크밴치에서 확인해볼까요?

제가 테이블을 만들 때 인덱스처리하지 않았어도, 테이블에는 자동으로 기본 키가 인덱스처리 되었습니다. 이처럼 기본 키를 설계할 때는 이런 것들을 다 따져가며 설계해야 합니다.

긴 글 읽어주셔서 감사합니다!