[JPA][데이터베이스] 테이블 설계시 식별자 선택 (자연키 vs 대리키)

Woolly·2023년 5월 24일
0

현재 개인프로젝트 초기 세팅 후 테이블 설계 단계에서 막혀 테이블 설계시 PK를 어떻게 가져가야 하는가에 대한 해답을 찾아다니고 있다.

그러다가 김영한님의 책 <자바 ORM 표준 JPA 프로그래밍>에 관련 내용이 있어 정리하고자 한다.

내가 고민하던 지점
이전에 실무에서 어떻게 했었는지 조금 헷갈리기 시작했다.
그때 당시에는 아이디를 PK로 했었는지,
Auto Increment 같은 자동증가 값을 PK로 가져갔었는지 잘 기억이 나지 않아

처음엔 JPA 활용 강의대로 Id 타입을 Long으로 지정했었다가,
다시 String 타입으로 바꿔 회원가입 시점에 사용자가 직접 아이디를 입력하도록 설계를 했었다.

그러다가 순간 아차싶어 다시 찾아보기 시작하였고,
왜 회원 아이디를 PK로 지정하면 안되는지에 대해 다시금 깨달을 수 있었다.


권장하는 식별자 선택 전략

데이터베이스 기본 키는 다음 3가지 조건을 모두 만족해야 한다.

  1. null값은 허용하지 않는다.
  2. 유일해야 한다.
  3. 변해선 안된다.

테이블의 기본 키를 선택하는 전략은 크게 2가지가 있다.

자연 키(natural key)

  • 비즈니스에 의미가 있는 키
  • 예: 주민등록번호, 이메일, 전화번호

대리 키(surrogate key)

  • 비즈니스와 관련 없는 임의로 만들어진 키, 대체 키로도 불린다.
  • 예: 오라클 시퀀스, auto_increment, 키생성 테이블 사용

자연 키보다는 대리 키를 권장한다

자연 키와 대리 키는 일장 일단이 있지만 될 수 있으면 대리 키의 사용을 권장한다. 예를 들어 자연 키인 전화번호를 기본 키로 선택한다면 그 번호가 유일할 수는 있지만, 전화번호가 없을 수도 있고 전화번호가 변경될 수도 있다. 따라서 기본 키로 적당하지 않다. 문제는 주민등록번호처럼 그럴듯 하게 보이는 값이다. 이 값은 null이 아니고 유일하며 변하지 않는다는 3가지 조건을 모두 만족하는 것 같다. 하지만 현실과 비즈니스 규칙은 생각보다 쉽게 변한다. 주민등록번호조차도 여러 가지 이유로 변경될 수 있다.

비즈니스 환경은 언젠가 변한다

나의 경험을 하나 이야기하겠다. 레거시 시스템을 유지보수할 일이 있었는데, 분석해보니 회원 테 이블에 주민등록번호가 기본 키로 잡혀 있었다. 회원과 관련된 수많은 테이블에서 조인을 위해 주 민등록번호를 외래 키로 가지고 있었고 심지어 자식 테이블의 자식 테이블까지 주민등록번호가 내려가 있었다. 문제는 정부 정책이 변경되면서 법적으로 주민등록번호를 저장할 수 없게 되면서 발생했다. 결국 데이터베이스 테이블은 물론이고 수많은 애플리케이션 로직을 수정했다. 만약 데 이터베이스를 처음 설계할 때부터 자연 키인 주민등록번호 대신에 비즈니스와 관련 없는 대리 키 를 사용했다면 수정할 부분이 많지는 않았을 것이다.

기본 키의 조건을 현재는 물론이고 미래까지 충족하는 자연 키를 찾기는 쉽지 않다. 대리 키는 비 즈니스와 무관한 임의의 값이므로 요구사항이 변경되어도 기본 키가 변경되는 일은 드물다. 대리 키를 기본 키로 사용하되 주민등록번호나 이메일처럼 자연 키의 후보가 되는 컬럼들은 필요에 따 라 유니크 인덱스를 설정해서 사용하는 것을 권장한다.

JPA는 모든 엔티티에 일관된 방식으로 대리 키 사용을 권장한다

비즈니스 요구사항은 계속해서 변하는데 테이블은 한 번 정의하면 변경하기 어렵다. 그런 면에서 외부 풍파에 쉽게 흔들리지 않는 대리 키가 일반적으로 좋은 선택이라 생각한다.


출처 : https://www.inflearn.com/questions/124691/%EB%A9%A4%EB%B2%84-%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%84%A4%EA%B3%84%ED%95%A0-%EB%95%8C-db-%EC%B9%BC%EB%9F%BC-%EA%B5%AC%EC%84%B1%EC%97%90-%EB%8C%80%ED%95%B4-%EA%B6%81%EA%B8%88%EC%A6%9D%EC%9D%B4-%EC%83%9D%EA%B2%BC%EC%8A%B5%EB%8B%88%EB%8B%A4


DB 설계를 다시 정리해야겠다.

profile
Ad Astra

0개의 댓글