All Articles

Primary Key - Surrogate Key VS Natural Key

DB 테이블의 primary key를 surroage key를 사용할것이냐 아니면 natural key(bussiness key라고도 함) 를사용할것이냐는 질문은 개발자나 DB 관리자들 사이에서는 고전적인 주제다. 고전적인 주제 임에도 불구하고, 주관적인 선호도가 작용할수 있는 여지가 많은 주제이기 때문에 계속해서 이야기되는 주제이기도 하다.

Surrogate key는 business 적인 의미가 전혀 없이 단순히 해당 row를 나타내기 위한 생성한 key 이다. 글로 설명하기에는 명확하지 않을수 있지만 예제를 보면 아주 단순하다. 예를 들어 아래의 create table 구문에서

CREATE TABLE stock (
    id INT NOT NULL AUTO_INCREMENT,
    ticker VARCHAR(20) NOT NULL,
    price DECIMAL(35, 4),
    PRIMARY KEY (ID)
);

id가 바로 surrogate key의 전형적인 예 이다. 여기서 id는 단순한 정수 값으로서 주식과는 아무 관련이 없는 정보지만 stock 테이블의 각 row를 대표하기 위한 id로 쓰인다.

Surrogate key와는 다르게 natural key는 실제 domain에 관련한 정보를 key로 쓰는 개념이다. 위의 stock 테이블 schema를 natural key를 사용하면 아래 처럼 변경할수 있다:

CREATE TABLE stock (
    ticker VARCHAR(20) NOT NULL,
    price DECIMAL(35, 4),
    PRIMARY KEY (ticker)
);

id 필드를 없애고 대신에 ticker 필드를 primary key로 지정하였다. Surrogate key가 아니라 natural key를 primary key로 사용한 것이다.

Natural Key의 단점

위의 단순한 예제만 본다면 natural key를 쓰는게 surrogate key를 쓰는거 보다 더 합리적으로 보인다. 어차피 각 주식의 ticker는 고유한 값을 가지고 있기 때문에 굳이 추가적으로 정수 id 필드를 추가해서 primary key로 사용하는거 보다는 그냥 ticker를 사용하는것이 합리적이라고 결론을 내릴수도 있다 (물론 ticker 필드는 타입이 VARCHAR 이기 때문에 foreign key가 걸리게 되면 INT 타입의 key 보다 비효율적인 점이 있을수 있지만 사실 요즘 DB 환경에서는 대부분의 경우 큰 영향을 끼치진 않는다.).

하지만 natural key의 가장 큰 문제점은 아무리 고정 값의 필드를 natural key로 사용한다고 하더라도 대부분의 natural key들이 언젠가는 값이 변할수 있다는 것이다. 주식 ticker도 값이 변할 수 있다. 회사가 다른 회사와 병합 된다든가 하는 등의 흔치는 않지만 충분히 일어날수 있는 이벤트에 의해 주식 ticker값이 변할 수 있다. 만일 ticker 값이 변하게 되면 그에 따른 관리를 해주는것이 굉장히 복잡하고 어려워질수 있다. 예를 들어, stock_infoportfolio 라는 table들이 stock table의 ticker 필드에 foreign key가 걸려 있다고 가정해보자. ticker 필드 값이 변하지 않으면 아무 문제 없지만 만일 ticker 값이 변해버리면 해당 ticker에 foreign key가 걸려있는 다른 table들의 row들도 전부 동시에 변경 해주어야 한다. 큰 규모의 실제 시스템에서는 DB 구조가 이보다 훨씬 복잡한 경우가 많으므로 모든 foreign key를 업데이트 시키는 일은 굉장히 어려워질수 있다.

이와 반면에 surrogate key는 변경되지 않는다. 처음부터 busienss 적인 의미가 없기 때문에 예상치 못하게 변경될 이유가 없는것이다.

Surrogate Key의 단점

Surrogate key의 가장 큰 단점은 DB query가 복잡해진다는 점을 들수 있다. Business적으로 의미가 없는 key를 사용하기 때문에 간단한 query라도 join이 들어가게 되어서 복잡해지게 된다.

Surrogate key 아니면 Natural key?

Surroage key가 query를 복잡하게 만드는 단점이 있지만 대부분의 경우 값이 변할 가능성이 있는 natural key보다는 surrogate key를 쓰는게 낮다고 생각한다. 누군가는 주식 ticker만 그런것이지 다른 필드는 값이 변경되지 않을수도 있지 않냐고 주장할수도 있다. 물론 그럴수도 있지만, 값이 절대 안바뀌는 natural key는 굉장히 드물다고 할수 있다. 주식 ticker 뿐만이 아니라 책의 ISBN 그리고 심지어 주민번호도 바뀔수 있는 가능성이 있다. 그러므로 대부분의 경우 surrogate key를 사용하는것이 합리적이다.