상세 컨텐츠

본문 제목

[DB기초] 관계형 데이터 베이스 주 키와 후보키, 키 제약이란?

IT/Database

by J KIMS 2020. 11. 16. 11:46

본문

반응형

 

 

 

주 키(primary key)와 후보키(candidate key)

 

- 후보키(candidate key) : 릴레이션의 튜플을 유일식별가능하게 해주는 가장 작은 집합

- 주 키(primary key) : 데이터 베이스 설계자는 후보키 중 하나를 주 키로 설정한다.

 

 

앞에서 릴레이션은 도메인의 유한부분집합으로 정의되고, 집합의 각 요소가 튜플이라고 했다. 그 말은 즉슨, 집합의 정의에 의해서 각 요소들은 반드시 서로 다른 '원소'들이어야 하고, 튜플도 마찬가지로 서로 달라야 한단 뜻이다. 그러면 이 튜플들이 서로 다른 개체라는 걸 뭘 보고 알 수 있는가? 그걸 식별가능하게 해주는 게 후보 키이다.

 

후보키는 하나의 속성이 될 수도 있고 두 개의 속성으로 구성될 수도 있다. 그래서 가장 작은 집합이라고 한 것이다. 두 개 이상의 속성이 하나의 후보키가 된다면, 그 경우 속성 하나를 빼면 더 이상 유일 식별능력을 갖지 않게 된다. 모든 속성의 집합이 후보키가 되는 경우도 있다.

 

예를 들어, 다음과 같은 릴레이션 사원이 있다고 한다.

 

사원

사원번호 사원명 급여 소속 보험번호
1315 김가인 500 K55 7890
1618 방예린 400 K41 7901

 

이때 후보키는 사원번호, 보험번호이다. (다른 사원이 같은 사원번호/보험 번호를 가질 일이 없다는 가정 하에)

사원명은 동명이인의 가능성 때문에 후보키가 될 수 없다.

 

이 경우 후보키는 2개이지만 사원번호가 사원과 같은 의미로 볼 수 있기 때문에 주키로 설정한다. 

 

다른 예시로, 다음과 같이 릴레이션 납품이 있다고 하자.

 

납품

상품번호 고객번호 납품수량
A1 B1 5
A1 B2 10
A2 B2 20
A2 B3 10

 

이때는 속성의 집합 {상품번호, 고객번호}가 후보키가 된다. 같은 상품이어도 다른 고객이 주문할 수 있고, 같은 고객이 다른 상품을 납품하는 경우도 고려할 수 있기 때문. 더 쉽게 생각하면 상품번호나 고객번호 어느 하나만으론 튜플을 유일하게 식별하는 게 불가능하기 때문.

 

후보키가 하나인 경우는 후보키가 곧 주키이다.

 

키 제약 (key constraint)

 

주키로 설정된 키는 다른 후보키와는 다른 특별한 의미적 제약(semantic constraint)을 부여받는다.

 

  1. 주키는 튜플을 유일하게 식별할 수 있는 능력을 갖는다 (一意識別能力)
  2. 주키를 구성하는 속성은 null 값을 갖지 않는다

주키는 위 조건을 만족해야 한다.

 

2번에 대해 보충 설명을 하자면, 후보키는 null 값을 가져도 된다. 하지만 주키는 그럴 수 없으므로 대신 "ㅡ" 같이 null값을 의미하는 기호를 써넣는다. 주키가 null 값이면 안 되는 이유는, 그 경우 단순한 질의에도 답할 수 없게 되기 때문이다.

 

만약 위 예시에서 사원번호에 null값이 있다고 생각해보자. 이 경우 사원은 총 몇 명 있습니까? 같은 질문에 데이터베이스는 답할 수 없게 된다. 이런 문제를 막기 위해 관계형 데이터 베이스의 주 키에는 null값이 허용되지 않는 것이다.

 

외부 키 (foreign key)

 

관계형 데이터 베이스에는 보통 복수의 릴레이션이 존재한다.

 

예를 들어, 기업의 어떤 데이터 베이스에 다음과 같이 두 개의 릴레이션이 존재한다 하자.

 

 

주 키에는 밑줄, 외부키에는 점선을 긋고 화살표로 관계를 표시함. 계속 예시로 등장할 예정.

 

주의할 점은

  • 릴레이션 사원의 속성 소속에는 릴레이션 부문의 부문번호에 등록된 값이나 NULL값만 들어갈 수 있음
  • 릴레이션 부문의 속성 부장에는 릴레이션 사원의 사원번호에 등록된 값이나 NULL값만 들어갈 수 있음 

즉, 사원의 소식이 아직 결정되지 않았거나 부장이 아직 정해지지 않은 상황을 허용한다는 것. 하지만 존재하지 않는 사원번호나 부문 번호가 값으로 입력될 수는 없다.

 

또 하나의 주의점은, 사원번호와 부문번호는 각 릴레이션의 주키로써 NULL값을 갖는 일은 없다는 것이다. 이는 곧 존재하는 사원과 부문은 릴레이션에 전부 등록되어 있다고 보증할 수 있는 것이다. 위에서 말한 키제약의 의미가 이런 거라고 짚고 넘어간다.

 

이때, 릴레이션 사원의 속성 소속릴레이션 부문에 대한 외부키라고 한다.

마찬가지로 릴레이션 부문의 속성 부장릴레이션 사원에 대한 외부키이다.

 

외부키에 대해서도 다음과 같은 제약이 주어진다.

 

외부키 제약

  • 릴레이션 R(… , Ai , …)의 속성 Ai 가 릴레이션 S(Bi, …)에 대한 외부키라면, R의 임의의 튜플 t에 대해서, t[Ai]는 NULL값이거나, S의 임의의 튜플 u가 존재할 때 t[Ai] = u[B1] 가 성립해야 한다. 여기서 t[Ai]와 u[B1]는 각각 t와 u의 Ai값과 B1값을 나타낸다.

 

일관성 제약 (integrity constraint)

 

: 실세계와 데이터베이스가 모순되지 않도록 키 제약, 외부키 제약 외에도 필요한 여러 가지 제약들

 

- 검사제약 (check constraint)

예를 들어 사원의 소속 값은 'K55' , 'K41', '그 외' 셋 중 하나여야만 하거나, 사원의 평균 급여는 200 이상이어야 한다는 등의 제약. 이 제약은 릴레이션을 정의할 때 명시적으로 지정 가능하며, 릴레이션이 갱신될 때마다 체크된다. 검사 제약에 걸리는 갱신은 허용되지 않는다.

 

소속 NCHAR(3), CHECK(소속 IN ('K55' , 'K41', '그 외' )),

급여 INTEGER, CHECK(200 <= SELECT AVG(급여) FROM 사원)), ... 

 

이런 식으로 CHECK() 안에 조건을 써넣음.

 

 

- 표명 (assertion)

표명을 쓰면 검사 제약보다 더 복잡한 제약을 지정할 수 있다.

 

"상사보다 급여가 높은 사원이 있으면 안 된다"라는 제약은 다음과 같이 쓸 수 있다.

 

CREATE ASSERTION 급여 제약

CHECK (NOT EXISTS (SELECT X.* FROM 사원 X, 사원 Y, 부문 Z

WHERE X. 소속 = Z.부문번호 AND Z.부장 = Y.사원번호 AND X.급여 > Y.급여))

 

 

- 트리거 (trigger)

위의 검사제약과 표명이 데이터베이스 설계자의 시점에서의 제약이라고 하면 트리거는 유저 어플리케이션 시점을 반영한 제약이다. 이런 유저 정의 (user defined)의 의미적 제약을 기술하는 장치를 트리거라고 한다.

 

트리거의 기본적인 역할은, 한 릴레이션의 갱신이 다른 릴레이션에 어떻게 반영될지 설정하는 것이다.  (트리거에는 방아쇠라는 뜻이 담겨있다, 순차적으로 갱신되는 이미지를 떠올리자)

 

예시로, 사원이 퇴사하여 릴레이션 사원의 데이터를 삭제하는 경우를 생각해보자. 이 경우 릴레이션 부문의 사원 수에는 증감 변화가 일어나야 한다. 이러한 제약은 트리거로만 작성 가능하다.

 

CREATE TRIGGER 부원수조절

 AFTER INSERT ON 사원

  UPDATE 부문

  SET 부원수 = 부원수 + 1

  WHERE 부문.부문번호 = 사원.소속 

 

관계형 데이터 베이스 스키마

 

- 데이터 베이스 스키마 (database schema) : 실세계를 기술하는 데 필요한 릴레이션 스키마와 일관성 제약을 스키마 레벨에서 기술한 것. 데이터 베이스 설계자는 이를 기술하여 처음으로 데이터베이스를 설계한 것이 된다. 도메인이나 릴레이션 스키마의 정의 , AUTHORIZATION을 이용한 권한 부여 등이 지정되어 있음.

 

 

- 참고서적 : サイエンス社 データベース入門

반응형

관련글 더보기

댓글 영역