본문 바로가기
computer science/데이터베이스

[데이터베이스] 키의 개념과 종류

by 박연호의 개발 블로그 2020. 2. 27.



이번 시간에는 데이터베이스의 슈퍼키, 후보키, 기본키, 대체키, 외래키에 대해 공부해 보겠습니다.

 

릴레이션에서는 수많은 튜플들이 있습니다. 고객 릴레이션에 많은 고객들에 대한 튜플이 존재하며 각 튜플들에서는 중복되는 값이 발생할 수 있습니다.

 

예를 들어 이름, 나이, 사는곳 등이 중복될 수 있는데, 이때 각각의 고객(튜플)을 구분하기 위한 기준이 되는 속성이 필요합니다. 이것을 우리는 "키"라고 하며 속성 또는 속성들의 집합으로 표현할 수 있습니다. 키의 종류에는 슈퍼키, 후보키, 기본키, 대체키, 외래키가 있습니다.


최소성, 유일성

먼저 키에 대해 알아보기 전에 최소성과 유일성에 대해 공부해 봅시다.

 

유일성 : 하나의 키값으로 튜플을 유일하게 식별할 수 있는 성질

여러개의 튜플이 존재할 때 각각의 튜플을 서로 구분할 수 있어야 합니다. 한마디로 각각의 튜플을 유일해야 한다는 의미입니다. 예를 들어 (주민번호, 나이, 사는곳, 혈액형)이라는 속성이 있을 때 나이, 사는곳, 혈액형을 충분히 중복될 수 있는 속성입니다. 하지만 주민번호는 모두 다르기 때문에 각각의 튜플을 중복되는 속성 값이 존재할 수는 있지만 주민번호는 절대 중복할 수 없습니다. 이렇게 각각의 튜플을 구분할 수 있는 성질을 유일성이라고 합니다.

 

최소성 : 키를 구성하는 속성들 중 꼭 필요한 최소한의 속성들로만 키를 구성하는 성질

쉽게 설명하면 키를 구성하는 속성들이 진짜 각 튜플을 구분하는데 꼭 필요한 속성들로만 구성되어 있냐?를 의미합니다. 굳이 없어도 될 속성들을 넣지 말자는 말입니다. 예를 들어 다음과 같은 키(주민번호, 이름, 나이)가 있다면, 물론 현재의 키는 각 튜플을 구분할 수 있습니다. 주민번호, 이름, 나이가 모두 같은 사람을 없을 테니깐요. 근데 생각해보면 이름, 나이가를 빼고도 주민번호만으로 각 튜플을 유일하게 식별할 수 있습니다. 이때 이름, 나이를 빼면 해당 키는 최소성을 만족합니다.


키의 종류와 개념

1. 슈퍼키 : 유일성 O, 최소성 X

슈퍼키는 유일성의 특성을 만족하는 속성 또는 속성들의 집합입니다. 키 값이 같은 튜플을 존재할 수 없습니다. 예를 들어 (고객 아이디)의 경우 각 아이디가 같은 고객은 없기 때문에 슈퍼키가 될 수 있습니다. 하지만 (나이, 직업, 등급)의 경우 나이, 직업, 등급이 같은 고객은 충분히 존재할 수 있기 때문에 슈퍼키로 사용할 수 없습니다. 하지만 (고객 아이디, 나이, 직업, 등급)의 경우는 고객 아이디가 각 튜플을 구분할 수 있기 때문에 슈퍼키가 될 수 있습니다. 이처럼 슈퍼키는 유일성은 만족하지만 최소성은 만족하지 않습니다.

 

2. 후보키 : 유일성 O, 최소성 O

후보키는 슈퍼키 중에서 최소성을 만족하는, 즉 유일성과 최소성을 모두 만족하는 속성 또는 속성들의 집합입니다. 슈퍼키에서 (고객 아이디, 나이, 직업, 등급)의 경우 각각의 튜플을 유일하게 식별할 수 있으므로 유일성은 만족합니다. 근데 여기서 나이, 직업, 등급이 굳이 필요할까요 ? 이 속성들을 충분히 중복되는 속성을 가지고 있고 없어도 전혀 문제가 되지 않습니다. 고객 아이디로만 각 튜플을 유일하게 구별할 수 있으니깐요. 여기서 나이, 직업, 등급을 제거한 (고객 아이디)는 최소성을 만족하며 후보키가 될 수 있습니다.

 

3. 기본키 : 후보키 중 선택받은  키

이렇게 각 튜플을 구별할 수 있으며 유일성과 최소성을 만족하는 후보키가 구해졌습니다. 후보키는 여러개가 존재할 수 있는데 여기서 우리는 여러 후보키 중에서 하나를 선택해서 사용해야 하며 여기서 선택된 키가 기본키입니다. 하지만 문제점은 여러 후보키들 중에서 기본키를 선택하는데 있어 다음과 같은 기준이 있습니다.

 

  1. 널 값을 가질 수 있는 속성이 포함된 후보키는 기본키로 부적절 합니다.
  2. 값이 자주 변경될 수 있는 속성이 포함된 후보키는 기본키로 부적절 합니다.
  3. 단순한 후보키를 기본키로 선택합니다.

4. 대체키 : 후보키 중 선택받지 못한 키

대체키는 기본키로 선택되지 못한 후보키들 입니다. 이름에서 알 수 있듯이 대체키는 기본키를 대신할 수 있는 자격이 있지만 3.1 ~ 3.3 등의 이유 때문에 기본키로 선택되지 못한 나머지 키들을 말합니다.

 

5. 외래키 : 다른 릴레이션의 기본키를 참조

외래키는 어떤 릴레이션에 소속된 속성 또는 속성 집합이 다른 릴레이션의 기본키가 되는 키 입니다. 다시 말해 다른 릴레이션의 기본키를 그대로 참조하는 속성의 집합이 외래키 입니다. 외래키는 릴레이션들 사이의 관계를 올바르게 표현하기 위해 필요합니다.

 

예를 들어 다음과 같이 두개의 고객, 주문 릴레이션이 있다고 생각해 봅시다.

 

고객 (고객 아이디, 고객 이름, 나이, 등급, 직업, 적립금)

주문 (주문번호, 주문고객, 주문제품, 수량, 단가, 주문일자)

 

위의 릴레이션에 잠시 생각해보면 고객 릴레이션은 사이트에 가입한 고객에 대한 데이터를 가지며, 주문 릴레이션은 어떤 제품을 어떤 고객이 주문했는지에 대한 데이터를 다룹니다. 주문 릴레이션에는 어떤 고객이 어떤 제품을 언제, 몇개를 주문했고 금액에 대한 정보가 있겠죠. 그리고 각각의 튜플을 구분할 수 있는 기본키(주문번호, 고객아이디)가 있겠구요.

 

여기서 주문 릴레이션은 고객의 정보를 모두 저장할 필요가 없습니다. 단지 고객 릴레이션의 기본키가 되는 속성만을 가지고 있으면 되며 이를 고객 릴레이션의 기본키(고객 아이디)를 참조하는 주문 릴레이션의 외래키(주문고객)이라고 합니다. 외래키는 기본키를 참조하고 있으며 중요한 점은 두 기본키와 외래키의 도메인 반드시 같아야 합니다. 도메인이 같아야 비교연산이 가능하기 때문입니다.


왜 외래키가 있어야 할까 ?

예전에 개발을 할 때 왜 굳이 외래키가 있어야 할까? 라는 생각을 했었습니다. 위의 예시에서 주문고객을 통하여 해당 고객의 정보를 알아낼 수 있습니다. 주문고객 = 고객아이디 이기 때문에 쿼리문으로 조회할 수 있죠. 여기서 든 생각은, 이것때문에 외래키가 있어야 하는걸까 ? 굳이 외래키 설정을 해주지 않아도 조회하는게 가능한데 말이죠...

 

사실 외래키의 존재이유는 데이터 무결성 때문입니다. 여기서 무결성이란 데이터가 항상 정확한 값을 유지하는 성질을 의미합니다.

예를 들어 고객 릴레이션의 고객 아이디가 변경되었는데 주문 릴레이션의 주문 고객의 값은 변경되지 않았다면 두 값은 서로 같은 값이어야 하는데 다른값이 되어 버립니다. 이는 무결성이 깨지는 것을 의미하며 치명적인 결함이죠. 이것을 예방하기 위해 외래키가 존재합니다.

 

실제로 외래키를 설정할 때 여러 옵션을 통해, 기본값이 변경되었을 때 무결성을 지키기 위해 여러 옵션을 제공하고 있습니다. 예를 들어 기본값에 대한 조작이 있을 경우 이를 참조하는 외래키는 어떻게 할 것이냐 라는 것에 대한 여러 기능을 제공하고 있으며 개발자는 이를 각 상황에 맞게 적절히 사용할 수 있습니다.