티스토리 뷰
1. 자연키(Natural Key)
회원 테이블을 만든다고 가정해보자.
약간 속성의 차이는 있겠지만 대부분 이런형태의 테이블구조가 나올것이다. 이제 회원이 늘어날때마다 각각의 속성들에 대응하는 값들을 갖고있는 로우가 하나씩 추가될것이다. 그럼 이제 해당 로우들을 각각 고유하게 구별할 수 있는 기본키(primary key)를 지정해야한다. 어떤 컬럼을 기본키로 지정해주면 좋을까?
성별은 회원이 몇명이든 2개의 값밖에 들어갈 수 없다. 필연코 각 로우별 중복적인 값이 들어올수밖에 없는 속성이므로 기본키로 적합하지않다(불가능하다.).
이름도 동명이인이 충분히 있는만큼 적합하지않다. 주소는 가능할까? 주소를 가지고 기본키로 설정하면 내가 가입한곳을 동생이 가입하기 힘든사태가 벌어질수도 있을것 같다.
그럼 남은것 중 전화번호는 어떨까? 확실히 전화번호는 중복될수가 없는 값이다. 하지만 우리가 살면서 전화번호가 바뀌는일은 생각보다 잦다. 변경이 있는 값을 기본키로 하는건 좋지않다. 기본키는 각 로우를 확실히 구분하면서 최대한 변하지않는(가능하다면 영구한) 데이터가 되는것이 좋다.
그럼 남는건 회원ID뿐이다. 확실히 회원ID는 중복되지않으며, 변경될 여지도 거의없다. 기본키만을 위한 불필요한 컬럼 없이 회원이라는 비즈니스에 필요한 속성을 가지고 기본키를 구해냈으니 작업을 시작하면 될것이다.
이 내용에서는 회원 테이블을 만들고, 회원 테이블의 속성들을 추출해냈다. 그리고 그 추출한 속성들중 가장 기본키로서 효율적인 속성을 골라내어 기본키로 설정했다. 기본키만을 위한 데이터가 아니라 비즈니스 모델에서 자연스레 나오는 속성으로 기본키를 정한다고해서 자연키(Natural Key)라고 표현한다.
2. 인조키(Artificial Key)
앞선 내용에서는 회원 이라는 내용을 가지고 테이블을 설계했다. 보통 회원이라는건 가입자한테 그 사실을 알려주고 (DB차원에서 기본키랑은 상관없이)그회원의 고유한 값을 전달해주게된다. 거기서 자연스레 고유한 값은 ID가 추출됐고, 그걸 기본키로 설정한것이다. 그럼 비슷한 데이터지만 회원과는 조금 다른 테이블을 설계해보자. 이벤트 참여 개인정보를 제공받는 테이블이다.
회원 테이블과 거의 동일하다. 하지만 이벤트 참여를 받을땐 참여자로부터 고유한 값을 입력받지 않는다. 때문에 앞선 회원 테이블의 ID와같은 고유한 값이 없다. 이럴땐 기본키로 어떤걸 설정해야할까? 변할가능성은 어느정도있지만 그래도 고유함은 보장할 수 있는 전화번호는 어떨까? 일리있는 생각이긴하지만 1~2달 쓰고 종료할 시스템이 아니라면 좋은생각은 아니다.
생각을 조금 바꿔보자 고유한 값을 꼭 회원이나 참여자로부터 입력받아야할까? 입력받는게 없으면 우리가 부여하면 되는거 아닐까? 카페에서 커피를 시킬때를 생각해보자. 우리는 그냥 돈내고 결제만 하면 끝나지만 종업원으로부터 대기자들 중 우리를 식별할 수 있는 번호표를 받는다(호출기도 잘 살펴보면 고유번호가 있다.). 마찬가지로 우리가 부여하면된다.
우리가 부여한 참여자번호로 인해 우리는 참여자가 몇명이든 그들을 구분할 수 있는 속성을 갖게됐다. DBMS적인 측면에서 본다면 Oracle의 Sequence, MySQL의 Auto Increment라고 보면된다. 비즈니스 모델과는 달리 키를 위한 데이터라는 측면에서 인조키(Artificial Key)라고 부른다.
3. 자연키와 인조키
비즈니스 모델에서 자연히 얻게되는 자연키와 기본키만을 위한 인조키 중 어떤걸 사용하는게 더 좋을까? 앞선 내용에서 알아본것처럼 자연키가 있으면 자연키를 사용하고, 없으면 인조키를 사용하는 선자연키 후인조키 전략이 좋은걸까?
각각의 비즈니스에 따라 갈리는게 당연한일이므로 명확한 정답이 있는건 아니지만 보통의 경우 자연키보다는 인조키를 사용하는게 좋고, 그렇게 권장한다.
기본키는 최대한 변하지않는 값이어야하는데(실제 값이 변하지않는 측면에서도 그렇지만 그 값이 의미하는 바도 변하지않는게 좋다.) 비즈니스 모델에서 추출한 자연키는 비즈니스 규칙에 의해 값 혹은 그 의미가 변할 여지가 다분하다.
간단한 예로 대한민국 국민은 기본키를 부여받고 살아가게된다. 바로 주민번호다. 지금이야 상상할수도 없지만 이전에는 별 시덥잖은 사이트에 가입할때도 필수적으로 주민번호를 입력해야했다. 만약 그때 주민번호를 기본키로 잡아놨다면 그 사이트는 정부의 대대적인 보안정책으로 인해 피똥싸는 수정을 했어야할것이다. 주민번호가 갖는 그 고유한 특성 자체는 변하지않았지만 그 값이 갖는 의미가 변했기때문에 더이상 데이터베이스에 영구히 보관할수가 없어진 탓이다.
단순히 회원 테이블의 기본키로만 쓰인게 아니라 여기저기 외래키로도 사용됐다면 그 사이트는 시스템 전체를 들었다놔야하는 상황을 맞이할수도 있었을것이다(아마... 꽤나 많은 사이트들이 이런 사태를 맞지않았을까 예상해본다.).
'DataBase' 카테고리의 다른 글
외래키의 사용 - 식별관계, 비식별관계 (8) | 2017.06.25 |
---|---|
MySQL ROLLUP (0) | 2017.01.24 |
쿼리 캐싱 방지 (0) | 2017.01.12 |
mysql 실행계획 2 (0) | 2017.01.10 |
서브 쿼리의 종류 (0) | 2017.01.01 |
- Total
- Today
- Yesterday
- MySQL
- backend개발환경
- mariadb
- JavaScript Core
- go-core
- http
- db
- Git
- toby
- code
- java8
- Design Pattern
- TEST
- clean code
- spring cloud
- frontcode
- programming
- servlet
- 정규표현식
- DesignPattern
- JPA
- Spring
- javascript
- java
- EffectiveJava
- Jackson
- frontend개발환경
- Kotlin
- OOP
- generics
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |