관계형 데이터베이스에서 기본 키는 Primary Key(PK)라고 하며, Key로 레코드의 유일성을 식별할 수 있다.
Auto Increment Key
기본 키를 자동으로 1씩 증가해주며 생성해주는 PK 매핑 전략이다.
Integer는 unsigned 라고 해도 4바이트이므로 2,147,483,647 * 2 = 약 42억 정도로 충분히 초과할 수 있는 수치다.
따라서, Long 타입을 주로 사용하게 된다.
Entity 객체를 생성할 때 id를 null로 하면 자동으로 DB에서 PK를 생성해준다.
DB에 PK 생성을 위임하므로, DB 자체의 Auto Increment 로직을 타서 성능 면에서 좋다고 한다.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", updatable = false)
private Long id;
단점
1부터 시작해서 증가하며 생성되는 방식이므로, 전체 테이블에서 유일한 PK임을 보장하지는 않는다.
또한 PK를 통해 예측 가능하므로 테이블의 레코드 수를 파악할 수 있고, 이는 악의적인 공격에 취약할 수 밖에 없다.
UUID(Universally Unique Identifier)
UUID는 16진수로 구성된 128비트의 값으로, 랜덤으로 생성된다.
UUID 예시: 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d
이는 Auto Increment 방식의 단점들을 해결한다.
값 자체로만 보면 의미가 없어서 어떤 특징을 유추하기가 불가능하다. → 보안성 향상
(3번 째 필드의 숫자 4를 통해 버전이 4인 것은 알 수 있다.)
또한, 전체 테이블에서 유일한 PK임을 보장받을 수 있을 것이다. → 데이터 충돌 방지
여러 데이터베이스 시스템에서 데이터를 병합할 때 충돌을 일으킬 확률은 희박하다고 한다.
@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(
name = "UUID",
strategy = "org.hibernate.id.UUIDGenerator"
)
@Column(name = "id", updatable = false, nullable = false)
private UUID id;
UUID 버전에 따라 생성 방식이 다르다.
- UUIDv1: 시간 기반으로 생성. (MAC 주소와 타임스탬프를 기반으로 함)
- UUIDv2: DCE 보안 버전(드물게 사용됨).
- UUIDv3: 네임스페이스와 해시(MD5)를 사용하여 생성.
- UUIDv4: 랜덤 값 기반으로 생성.
- UUIDv5: 네임스페이스와 해시(SHA-1)를 사용하여 생성.
가장 제너럴하게 사용되는 버전은 UUIDv4이고, (완전히 고유하고 랜덤한 값)
현재 코드에서 사용하고 있는 org.hibernate.id.UUIDGenerator는 기본적으로 UUIDv4 (랜덤 값 기반 UUID)를 생성한다.
이를 변경하고 싶다면 UUIDGenerator의 다른 설정을 사용해야 하며, Hibernate에서 @GenericGenerator와 함께 특정한 UUID 버전을 생성하도록 전략을 설정할 수 있다.
단점
Auto Increment Key의 장점을 단점으로 가진다.
DB의 성능 저하 이슈가 있을 수 있다.
데이터베이스 엔진은 PK를 기준으로 테이블의 레코드를 정렬하는데, 이 과정에서 UUID는 일반적인 정수와는 달리 복잡한 값을 가진다.
또한, 저장 공간 측면에서도 더 많은 공간을 차지한다. (UUID: 128 bit = 16byte / Long: 8byte)
결론
Auto Increment Key와 UUID 매핑 전략을 적재적소에 사용하자.
성능과 저장공간 측면에서는 Auto Increment Key 매핑 전략이 우수하고,
보안과 데이터 안정성 측면에서는 UUID 매핑 전략이 우수하다.
각각의 방식을 채용했을 때 얻게 되는 장점과 단점이 명확하고, Trade off 지점이 존재한다는 것을 깨달았다.
지금까지는 무지성 Auto Increment Key를 적용해왔지만, Entity의 특징을 고려해서 적절한 매핑 전략을 사용해야 한다는 것을 알게 되었다.
- UUID는 분산 시스템, 보안이 중요한 엔티티, 데이터 복제가 필요한 상황에서 사용
- Auto Increment Key는 단순하고, 성능이 중요한 경우, 또는 순차적인 데이터를 다룰 때 사용
하자.
조금 더 구체적으로,
MSA에서 분산 데이터베이스를 사용하거나, User 와 같이 보안이 필요한 엔티티는 UUID
단순하게 사용하며 읽기/쓰기 속도가 빨라야 하는, 블로그 플랫폼에서 Article 같은 엔티티는 Auto Increment Key를 선택하면 될 것 같다.
Ref
https://docs.tosspayments.com/resources/glossary/uuid
UUID(Universally Unique Identifier) | 토스페이먼츠 개발자센터
UUID는 128-bit의 고유 식별자에요. UUID는 중앙 시스템에 등록하고 발급하는 과정이 없어서 상대적으로 빠르고 간단하게 만들 수 있어요.
docs.tosspayments.com