프로그래밍 언어/데이터베이스

자연키(Natural Key) 대 대체키(Surrogate Key)

소혼 2010. 1. 21. 00:44
반응형

<B Tree Index - www.filibeto.org/sun/lib/nonsun/...t169.gif 발췌>

오랜만에 DB를 만지게 되었다.
sqlite3의 내부 구조를 모르지만, File DB라고 들었는데 성능을 위한 옵션 같은것이 분명 존재할 것 같다.

어쨌거나 모바일에서 테이블 한두개 만드는데 문제가 되겠냐만, 옛날 DB 공부할 때 생각에 Primary Key를 Natural Key로 할 지, Surrogate Key로 할지에 대해 고민해봤다.

생각보다 입맛에 딱 맞는 자료를 못찾아 그냥 내 맘데로 생각을 풀어본다.

먼저 자연키가 무엇이고 대체키가 무엇인지부터 정리해보기로 한다.
기본키 ( Primary Key ) : 테이블에서 레코드를 유일하게 식별하는 데 가장 적합한 후보키(Candidate Key)
자연키 ( Natural Key ) : 테이블을 이루는 컬럼들 가운데 의미를 담고 있는 후보키
대체키 ( Surrogate Key ) : 테이블을 이루는 컬럼들 가운데 유일하게 식별하기에 적합한 단일 후보키가 존재하지 않을 때, 임의의 식별번호로 이루어진 후보키를 추가할 수 있는데 이를 대체키라고 한다.

Primary Key는 두가지 특성을 가지고 있다고 생각한다.
< 제약과 인덱스 >

제약은 원래 관심사항이 아니었고, 인덱스가 중요하다고 생각한다.
Primary Key는 일반적으로 인덱스를 구축한다. 심지어 SQL Server의 경우는 Cluster Index가 되기도 한다.
인덱스가 검색을 위한 것이기 때문에 검색에서 핵심이 되는 값이 Primary Key가 될수록 성능에 지대한 공헌을 하게 된다.

일반적으로 대체키의 도입을 고민하는 경우는, 자연키가 숫자로 이루어지지 않는 경우이다.
만약 자연키가 숫자로 있다면 당연히 대체키를 도입할 필요가 없다.

만약 자연키가 문자열이거나 하나 이상의 컬럼을 결합키로 만드어야 한다면 우리는 대체키를 도입할 것인가 고민해보아야 한다.
이것은 단순히 어느쪽이 좋다라고 할 수 있는 문제는 아닌 것 같다.

integer index와 문자열 인덱스의 성능은 당연히 integer index가 빠르다.
따라서 일반적인 경우 대체키를 사용하는 것이 낫다. 검색의 성능도 빠르고 크기도 작기 때문에 Block IO도 적게 발생할 가능성이 높다.

자연키는 그 자체가 의미를 갖는 검색이 될 수 있지만, 대체키는 레코드의 기본키를 이용한 수정, 삭제, 외래키 참조에만 효율적이다.
자연키는 자신이 정보를 가지고 있으므로, 테이블에서 자연키로 검색하는 경우가 대부분이고 수정, 삭제, 외래키 참조가 없다면 자연키를 인덱스로 사용하는 것이 낫다.
만약 둘 다 빈번하면 자연키를 사용하는 인덱스를 하나 더 만드는 것도 고려할 수 있을 것 같다.
그러나 범위검색의 가능성이 큰 자연키에게 클러스터나 클러스터드 인덱스는 양보하는 편이 좋을 것 같다.

대체키는 대체키를 생성하기 위한 트릭이 필요하다.
Oracle 의 Sequence나 auto increment가 전혀 비용을 수반하지 않는다고 생각하지 않는다. 하지만 입력할때 인덱스를 구축하는 비용은 문자열 인덱스가 클 것 같다. 어쨌거나 위에 언급한 것 같은 시스템이 지원하는 방법이 없어서 SELECT를 한번 더 사용해야 하는 DB의 경우라면 대체키 도입은 좋은 방법이 아닐 수 있다. 물론 검색이 더 중요한 경우가 대부분이므로 입력의 비용은 무시하고 생각할 수도 있을듯 하다.

정리하고자 적어봤는데
결국 뭘 어떻게 하라는 건지
어쨌든 대부분의 경우는 대체키가 좋지 않을까 조심스레 생각해본다.



반응형