pk란 Entity 개념에서 고유한 식별자다
Entity 는 자신의 생명주기동안 형태와 내용이 급격하게 바뀔 수도 있지만 연속성은 유지해야 한다 (도메인 주도 설계 93p 참고)
이렇게 변화하는 Entity 를 추적하려면 식별성이 부여되어야 하고, 식별자는 해당 시스템 내에서 유일하고 변경되어서는 안 된다
보통 DBMS 로 영속성을 관리하는 시스템에서의 Entity 식별자는 Table 의 PK 와 매핑되는 경우가 대부분이다
MySQL 의 경우 주로 AUTO_INCREMENT bigint 속성을 활용한다
원래 대리키라는 용어 (Surrogate Key)는 자연키(Netural Key)라는 용어와 대칭되는 개념인데, Entity 의 식별자와 동급의 의미를 가지는 추가 식별자 정도로 용어를 정의된다.
Entity 의 식별자는 외부에 오픈하거나 오용되지 않도록 주의하고, 식별자가 아닌 대리키를 오픈하는 것이 여러모로 좋다
Entity 식별자를 외부에 직접 오픈했을 때의 이슈 상황을 예시로 설명하면,
예시 1 - URL PATH 노출
BigInt(Long) 형태의 유저 아이디를 URL PATH 로 사용하여 유저의 거래내역을 노출하는 GET API 가 있다고 하자.
이런 경우, (인증 과정이 없다는 전제하에) URL 의 숫자만 조작하면 다른 이의 거래내역을 손쉽게 볼 수 있게 된다
이슈 발생 후 랜덤 스트링 형태의 대체키로 변환하여 API를 수정해야 했다.
예시 2 - 외부 연동 서비스
외부 협력사와 자사 서비스 간에 상품 데이터 연동 과정에서 키 값을 시스템 내부의 PK 로 사용했다고 가정하자
그렇게 되면 양사간의 데이터는 자사 시스템 내부의 PK 로 강하게 묶이게 된다
이 후 자사 시스템에서 데이터베이스를 MySQL 에서 MongoDB 등으로 변경하게 된다면, 달라진 PK 체계로 인해 많은 공수가 발생할 수 있다. 외부 협력사와 추가적인 식별자 논의도 진행해야 한다
unique index
로 설정하여 사용한다.성능
에 대한 고민이 많을 것인데 MySQL 기준으로 1천만건 이상으로 넘어가기 전까지는 random string 으로 사용해도 조회 성능에 크게 이슈가 없고, 성능을 고려한다면 UUID를 rearranged 하여 사용하는 것을 검토할 수 있다.
https://www.percona.com/blog/2014/12/19/store-uuid-optimized-way/ 참고