Entity id 생성 방식 정리
빠른 ID 생성
- 특징
- 엔티티가 생성되기 전 ID 정책에 따라서 직접 생성된다.
- key를 시스템에서 만들어낸다는 것은 기본적으로 충돌 내성이 필요하다
- 예시
- 도메인 모델에서 직접 generateId() 를 호출하여 ID를 발급
- 엔티티 생성하기 전에 먼저 DB에게 getNextId() 호출해서 ID를 발급
- 식별자 생성을 위한 BoundedContext를 만들고, 분산 환경에서도 유일한 ID 생성
- 장점
- 엔티티가 DB 저장 전이라도 도메인 이벤트 발행 시, id값이 포함될 수 있다
- 단점
- 직접 관리해줘야하고, 충돌의 위험이 존재한다.
느린 ID 생성
- 특징
- 엔티티가 생성된 후 ID가 생성된다.
- 예시
- AutoIncrement로 설정한 JPA-Entity ID
- 장점
- 엔티티 저장 시 동시성 이슈로부터 자유롭다.
- 단점
- ID가 명백히 DB 의존적이다.
예시(AccountNumber)
(빠른 Id 생성) id, accountNumber를 AccountId로 통합 시
- 빠른 Id 생성
- AccountId (String, 예: “240523-0123456789”) = PK = 계좌번호
1 |
|
장점
1. 단순함하나의 값으로 PK와 비즈니스 식별자를 동시에 처리
조인이나 조회 시 추가 컬럼 불필요
코드가 간결해짐
- 자연키의 이점
계좌번호만 알면 바로 조회 가능 (외부 시스템 연동 시 편리)
개발/디버깅 시 데이터 파악이 직관적
단점 (시스템 확장 시 문제점)
1. 인덱스 성능 저하String(17자) PK는 Long(8byte) 대비 2배 이상의 저장 공간 필요
B-Tree 인덱스에서 문자열 비교는 숫자 비교보다 느림
클러스터드 인덱스 크기 증가 → 모든 세컨더리 인덱스도 영향
- FK 참조하는 모든 테이블에 전파
Transaction 테이블에서 from_account_id, to_account_id 모두 String 17자
테이블 수가 늘어날수록 저장 공간 낭비 가중
- 계좌번호 변경 불가
PK를 변경하면 모든 FK 참조도 변경해야 함
실무에서 계좌번호 체계 변경 시 대규모 마이그레이션 필요
- 분산 시스템에서의 문제
현재 Random으로 생성 → 충돌 가능성 존재
여러 인스턴스에서 동시에 같은 ID 생성 가능
UUID나 Snowflake 같은 분산 ID 전략으로 변경 시 계좌번호 형식과 충돌
- 샤딩 시 불리
문자열 기반 샤딩은 숫자 기반보다 범위 분할이 어려움
날짜 prefix가 있어 시간 기반 핫스팟 발생 가능 (같은 날 생성 계좌가 한 샤드에 몰림)
(느린 Id 생성) id, accountNumber를 AccountId로 분리 시
1 |
|
분리의 이점:
- PK: Long → 인덱스 성능 최적화
- 계좌번호: 비즈니스 로직용 유니크 키
- 계좌번호 체계 변경 시 PK 영향 없음
- FK는 Long으로 참조 → 저장 공간 절약
결론
현재 소규모 시스템에서는 문제없지만, 데이터가 수백만 건 이상이거나 분산 환경으로 확장 시이슈가 발생할 수 있습니다. 초기 단계라면 지금 분리하는 것이 마이그레이션 비용이 적습니다.