이 글은 가장 쉬운 데이터베이스 설계 책을 읽고 정리한 내용 중 키에 관한 내용이다.
DB에 있어서 Key의 중요성
우리가 데이터를 모아서 특정 주제에 따라 테이블을 나누고 특성에 따라 필드를 설정했다고 해보자. 일단 데이터 저장은 다 했는데, 테이블에서 우리가 원하는 레코드는 어떻게 찾는 것이 좋을까? 일일히 우리가 원하는 조건에 맞는 레코드를 검색해볼 수도 있겠지만 가장 좋은 것은 몇 개의 필드값만을 검색해서 해당 레코드를 찾는 것일 것이다. 여기서 사용되는 몇개의 필드가 바로 이 글에서 다룰 키가 된다.
키의 장점은 다음과 같이 생각해 볼 수 있다.
- 테이블 내의 각 레코드가 정확하게 식별되도록 보장한다.
- 다양한 종류의 무결성을 설정하고 강화하는 것을 도와준다.
- 테이블간의 관계를 설정하도록 해준다.
뭔가 거창해 보일 수도 있지만 간단히 보면 키는 테이블 내의 레코드들이 서로 구별될 수 있도록 해주며 테이블 간의 관계를 설정할 수 있도록 도와준다. 있다가 다시 다루겠지만 이를 통해서 데이터가 중복되지 않는 데이터 무결성과 특정 관계를 갖는 테이블 간의 값이 연결될 수 있도록 해준다.
각 테이블에 Key 설정하기
위의 설명을 보니 키는 테이블에 있어서 정말 도움이 될 것 같은데, 어떤 필드를 키로 설정해야 할까? 어느 필드든지 키로 사용해볼 수는 있지만 효율적인 DB를 구성하기 위해서는 특정 조건들을 만족하는 필드를 사용해야 한다. 먼저, 키의 종류는 다음과 같다.
- 키의 종류
- 후보 키 (Candidate Key)
- 기본 / 주 키 (Primary Key)
- 외래키 (Foreign Key)
- 비 키 (Non-Key)
후보 키
테이블의 키를 설정하는 작업은 먼저 후보 키들을 선정하는 작업으로 시작된다. 후보 키는 테이블 주제의 단일 인스턴스를 유일하게 식별해주는 하나의 필드 또는 필드 집합으로 각 테이블은 적어도 하나의 후보 키를 가져야 한다. 후보 키가 되기 위한 조건은 다음과 같다.
- 후보 키 조건
- 다중 부분 필드일 수 없다.
- 유일한 값을 포함해야 한다. → 서로 중복되는 경우를 막아 고유한 성질을 갖게 해준다.
- Null 값을 포함할 수 없다. → Null 값을 포함한다면 서로 다른 레코드를 식별할 수 없다.
- 조직의 보안 또는 비밀 규칙을 준수해야 한다. → 후보 키는 레코드를 식별하기 위해 사용되는데 사회적으로 민감한 정보나 보안 관련 요소들이 사용되면 노출될 수 있으므로
- 유일성을 만족하는 조건 하에서 최소 개수의 필드들을 포함해야 한다.
- 테이블 내의 각 레코드들을 유일하고 베타적으로 식별해야 한다.
- 아주 극단적인 경우에만 수정될 수 있다.
다음의 Clinet 테이블 예제를 통해서 각각의 필드들이 키로서 적합한지 한 번 살펴보자
사용자 ID | 주민등록번호 | 성 | 이름 | 사는 곳 | 전화 번호 |
---|---|---|---|---|---|
1 | 940421-123456 | 홍 | 길수 | 인천 | 010-1234-5678 |
2 | 970811-154321 | 선 | 유도 | 사당 | 010-4561-7894 |
3 | 911225-201421 | 독 | 바위 | 인천 | 010-4214-1548 |
- 사용자 ID : 각각의 사용자마다 고유하게 배정되는 번호로서 위의 모든 조건들을 만족시킨다 (합격)
- 주민등록번호 : 사용자 ID처럼 역시 고유하지만 개인정보에 해당하므로 사용할 수 없다. (불합격)
- 성, 이름 : 따로 사용하면 고유한 값으로 볼 수는 없지만 성, 이름 필드 집합으로 함께 보면 가능하다 (합격)
- 사는 곳, 전화번호 : 고유해보일 수도 있지만 여러 사용자가 같은 지역에 살 수도 있으며 같은 번호를 공유할 수도 있으므로 사용할 수 없다 (불합격)
이 예제처럼 테이블을 구성하는 각각의 필드에 대해서 후보 키 가능성을 검토하고 후보 키로 가능한 필드들에 표시를 해준다. 하나의 필드인 경우 CK, 집합의 경우 CCK를 사용
필드 이름 | 키 |
---|---|
사용자 ID | CK |
주민등록번호 | |
성 | CCK1 |
이름 | CCK2 |
사는 곳 | |
전화번호 |
만약, 특정 테이블에서 마땅한 후보 키들이 하나도 없는 경우에는 사용자 ID처럼 고유하게 식별할 수 있는 새로운 필드를 추가함으로써 후보키를 설정할 수 있다. 모든 테이블에 대해서 후보 키들을 찾아 Pool을 만든 후, 기본 / 주 키 선정 단계로 넘어간다.
기본 / 주 키
주 키 필드는 데이터 베이스 구조 전체에 걸쳐 테이블, 레코드를 베타적으로 식별하고 테이블 간의 관계를 설정하는 것을 도와준다. 테이블 내에서는 주 키는 이전 단계에서 얻어진 후보 키들 중에서 적절한 키를 선택하는 것이기 때문에 자연스럽게 후보 키의 조건들을 만족하게 된다.
- 선별 기준
- 보다 단순한 (필드의 숫자가 적은) 후보 키를 선택한다.
- 테이블 이름의 일부를 필드의 이름에 포함하는 후보 키를 선택한다.
- 규칙
- 각 테이블은 오직 하나의 주 키를 가져야 한다.
- 각각의 주 키는 반드시 유일해야 한다.
이 기준을 위의 예제에 적용시켜 보면 우리에게는 (사용자 ID), (성, 이름)의 후보 키 Pool이 있는데, 이 중에서는 당연히 사용자 ID가 보다 단순하기 때문에 이를 주요키로 선정한다. 주요 키를 선정하면 단일 필드라면 PK, 집합이라면 CPK (Composite Primary Key)로 설정해준다.
다음 단계로 넘어가기 전에 베타적으로 식별에 대해 살펴보자. 우리가 선정한 주 키가 각각의 필드에 대해 베타적으로 식별하는 지를 살펴보는 것은 생각보다 간단하다. 주 키를 통해 각각의 필드가 구별가능한 것으로 주 키를 제외한 다른 필드와 연관성이 있어서는 안된다.
예를 들면, 제품 판매 테이블이 있다고 해보자. 여기의 필드는 거래 번호 / 제품 번호 / 구매자 이름 / 판매자 이름 / 판매자 번호가 있다고 해보자. 거래 번호가 주 키라고 했을 때 판매자 번호는 베타적으로 식별이 가능할까? 답은 아니오다. 판매자 번호는 다른 필드들과는 다르게 판매자 이름과 연관이 있어 거래번호와 판매자 이름이 함께 적용되어야 베타적으로 식별이 가능하다. 이런 경우에는 판매자 번호를 같은 테이블에 놓는 것이 아니라 다른 테이블로 빼는 것이 좋다. 테이블에 주 키를 제외한 필드끼리 연관이 있다면 이 경우에는 다시 살펴보는 것이 좋을 것이다.
대체 키
후보 키들의 Pool 중 주 키를 골랐다면 나머지 키들은 대체 키가 된다. 말 그대로 이 키들은 특정 레코드를 유일하게 식별할 수 잇는 대체 수단을 제공한다. 표시는 AK, CAK (Composite Alternative Key)를 사용한다.
비 키
비 키(Non-Key)는 후보 키에 포함되지 못한 필드의 집합으로써 유일한 목적은 테이블 주제의 특성을 나타내는 것이다. 값은 주 키에 의해 결정된다.
테이블 수준의 무결성
테이블 수준의 무결성은 전반적인 데이터 무결성의 주요 구성요소로서 다음의 사항들을 보장한다.
- 테이블 내 이중 레코드들이 없다.
- 주 키는 각 레코드들을 베타적으로 식별한다.
- 모든 주 키 값을 유일하다.
- 주 키값은 Null값이 아니다. 위의 과정을 통해서 위의 무결성을 얻을 수 있으며 추가적인 무결성은 후에 필드 명세를 설정하며 개선될 것이다.
초기 테이블 구조 검토하기
여기까지 했다면 기본적인 테이블 구조가 완성된다. 이후에는 지금까지 한 작업을 검토하기 위해 사용자 및 관리자들과 인터뷰를 수행해야 한다. 인터뷰 과정에서는 다음과 같은 내용들을 점검, 실시해야 한다.
- 적절한 주제들이 데이터베이스에 표현되는 것을 확인
- 테이블 이름과 설명이 모든 사람에게 의미가 있도록
- 필드 이름들이 모든 사람에게 적합하고 의미가 있도록
- 모든 필드들이 각 테이블에 적절하게 할당되었는지 검증 이 과정을 통해서 혹시라도 누락되었을 만한 사항들을 재검토할 수 있으며 앞으로 DB를 사용할 사람들과의 합의를 통해서 조직에 어울리는 보다 적합한 이름, 구조를 설정할 수 있다.