앞으로 그날그날 공부한 것들을 정리할 겸 기록해두려고 한다.
오늘은 Primary Key에 대해서 정리를 해보려고 한다.
■ 개요
보통 PK라고도 하고, 기본키라고도 하고, Primary Key 라고 부르기도 한다.
Primary Key는 데이터베이스의 테이블의 각 row를 유일성과 최소성을 만족시키면서 식별할 수 있는 후보키 중에 선택한 Main Key이다.
유일성 : 테이블에 있는 모든 튜플(row)에 대해 유일하게 식별되어야 함.
여러개의 튜플이 존재할 때 각각의 튜플을 구분할 수 있어야 한다. 쉽게 말하면 각각의 튜플은 유일해야 한다는 것이다.
예를들어 주민번호, 나이, 이름, 사는 곳, 혈액형, 전화번호라는 속성이 있을 때, 나이, 이름, 사는 곳, 혈액형은 중복될 수 있는 속성이다. 하지만 주민번호나 전화번호는 모두 다르기 때문에 유일성에 만족하는 것이다.
최소성 : 키를 구성하는 속성들 중 꼭 필요한 최소한의 속성들로만 구성되어야 함
키를 구성하는 속성들이 진짜 각 튜플을 구분하는데 정말로 필요한 속성들로만 구성되어 있는가?를 의미한다.
다시 말하면 굳이 없어도 되는 속성들을 넣지 말라는 것이다.
예를 들어 주민번호, 이름, 나이라는 키들이 있는데, 굳이 생각해보면 이름, 나이를 빼고도 주민번호만으로 각 튜플을 유일하게 식별할 수 있다. 이 때 이름, 나이를 빼면 해당 키는 최소성을 만족하는 것이다.
튜플 = 레코드 : 데이터베이스 테이블의 row에 해당
■ 기준
여러 후보키 중에 Main Key로 선택된게 기본키인데, 아무키나 기본키로 선택할 수 있는 것은 아니고 기준에 맞게 선택을 해야 한다.
1. 유일한 값을 가져야 한다.(다른 튜플들과 구분하기 위해서)
2. NULL이 아닌 값을 가져야 한다.(null값을 가지면 안된다)
3. 변경되지 않아야 한다.
■ 기본키 사용 이유
그렇다면 왜 기본키를 써야할까?
만약에 테이블에 기본키가 없다면, 서로 구분도 되지 않고, 일관성 없는 데이터가 반복적으로 쌓일 수 있기 때문에 쿼리 속도도 느리게 되고, 개발자가 예상하고 원하는 결과가 나오지 않을 가능성도 있다.
실무에서 많이 사용하는 Mysql, Oracle 등등을 관계형 데이터베이스라고 하는데, 관계형 데이터베이스는 반드시 각 행이 고유하게 식별되어야 한다. 만약 각 행이 고유하게 식별되지 않는다면, 더 이상 관계형이라고 볼 수 없고, A테이블에서 B테이블을 참조하거나 A테이블과 B테이블을 조인하는 쿼리 등을 수행하는데에 문제를 일으킬 수 있다.
그래서 보통 기본키를 Auto_increment로 지정해서 사용을 많이한다.

위 쿼리를 보면 user라는 테이블을 생성하는데, 각 튜플을 유일하게 구분할 수 있는 속성(기본키)으로 id로 지정을 했고
이 id는 정수형 타입으로써 튜플이 생성될 때마다 1씩 증가한다. 또한 PRIMARY KEY(id)라고 명시해줌으로써 id라는 속성이 각 튜플을 구분할 수 있는 기본키가 되는 것이다.
Mysql의 InnoDB는 기본적으로 데이터를 저장하고 인덱싱하기 위해서 PK를 지정하도록 되있다.
명시적으로 NONCLUSTERED 제약조건을 설정하지 않는 이상 PK는 Cluster Index이다.
■ 클러스터 인덱스
클러스터링 인덱스는 테이블의 PK에 대해서 적용되는 내용이다. 즉, PK값이 비슷한 레코드끼리 묶어서 저장하는 것을 클러스터링 인덱스라고 표현을 한다. 꼭 짚고 넘어가야 할 것은 PK값에 의해서 레코드의 저장위치가 결정된다는 것이다. 그리고 PK값이 변경된다면 그 레코드의 물리적인 저장위치가 바뀌게 된다는 것을 의미하기도 한다. PK로 클러스터링된 테이블은 PK 자체에 대한 의존도가 상당히 크기 때문에 PK를 신중히 결정해야 한다.
일반적으로 InnoDB와 같이 항상 클러스터링 인덱스로 저장되는 테이블은 PK기반의 검색이 매우 빠르며, 대신 레코드의 저장이나 프라이머리 키의 변경이 상대적으로 느릴 수 밖에 없다.
위의 InnoDB나 클러스터 인덱스에 대해서는 추후 포스팅에서 좀 더 자세히 다뤄보려고 한다.
'데이터베이스' 카테고리의 다른 글
SQL의 분류 (DML, DDL, DCL) (0) | 2022.07.11 |
---|---|
[MYSQL] ANY, ALL, 서브쿼리 (0) | 2022.07.10 |
[MYSQL] Unique Key에 대해서 (0) | 2022.06.19 |