0001-01-01
Table of Contents
  1. auto incremental ID 란? -> 데이터베이스가 자동으로 생성해주는 number id -> mysql 에서는 bigint 타입을 사용함 (사내 권장)

    • mysql 의 int 는 -2147483648 ~ 2147483647 ( 4 바이트 ) 21억 4천만…
    • 해보니 넘는 경우가 생김
    • bigint 로 -9223372036854775808 ~ 9223372036854775807 (8바이트) -> 비교 vs Char, Varchar 1개의 문자열 저장 Char 1바이트, varchar 2바이트
  2. auto increment id 를 쓰면 좋은점 -> 순차적인 증가가 가능 -> 고유값. -> 주로 Entity ID로 사용함 -> primary key 로 사용

  3. 외부 노출의 문제 ex) 서비스의 중요 지표인 user, message 의 카운트를 id값으로 추정할 수 있음. 새로운 user, message가 등록될 때마다 id값도 1씩 오르기 때문임 -> 불필요한 내부 정보 추정이 가능해짐 -> 지표의 노출/ 공격 대상의 지정이 쉬워지는 문제 발생

  4. JPA에서는 실제 Identification Key 가 Insert 쿼리가 실행된 이후에 결정되버린다. -> 영속성관리 타이밍상 mysql 의 autoincremtid 를 사용하면 IDENTITY 식별자 생성 전략(mysql의 auto-increment 등)은 어쩔 수 없이, 쓰기 지연이 동작하지 않고 영속화 할 때 insert 쿼리가 먼저 데이터베이스로 나간다

  5. String ID를 사용하자.

  6. UUID (Universally Unique ID) - RFC4122 - tools.ietf.org/html/rfc4122 UUID4 많이 사용함 ex) 83fda883-86d9-4913-9729-91f20973fa52 UUID는 128bit(16바이트), 즉 int id 값보다 보다 4배나 큼 따라서 디스크/메모리 사용이 커지고, 성능에 영향이 있다.

(평균 2.5배, 최악의 경우, UUID가 Auto Increment에 비해 28배 느림 클러스터드 인덱스 테이블에서는 기본키를 포인터로 해서 보조 인덱스가 저장되므로 5개의 보조 인덱스의 UUID기반 스키마의 경우 , 총 6번 저장. 총 1억 개의 테이블에서 216G, 즉 스토리지의 70%를 차지할 수도 있음 https://percona.com/blog/2019/11/2)

  1. 분산 데이터베이스에서의 키 관리 부하집중을 방지해야함 => UUID4 권장 https://cloud.google.com/spanner/docs/schema-design#primary-key-prevent-hotspots

  2. 키가 완전한 랜덤이 되면서 오는 문제

  • 키를 기반으로한 sorting 이 불가능해짐.
  • autoincremt primary key 를 기반으로 max 값을 스냅샷 해서 지표로 저장하는 기능 불가능
  1. 적당한 타협점을 찾을 수 없는가?
  • uuid 처럼 랜덤한 문자열 형태이면서
  • 오름차순, 내림차순 정렬이 가능한 형태이면서
  • 128bit 보다 적은 사이즈
  1. ULID https://github.com/ulid/spec#monotonicity

  2. 멀티 리전

미국 <—–> 영국 auto auto entity 1 entity 1

=> <=

    통합 DB

Skip to end of metadata james.star(안정수)/kakao님이 작성, 2022/08/25에 최종 변경Go to start of metadata 데이터베이스의 엔티티를 설계할 때 primary ID를 어떻게 해야하는가에 대한 고민 과정입니다.

Auto incremnt ID

  1. 흔히 사용하는 auto incremental ID 란? -> 데이터베이스가 자동으로 생성해주는 number id -> mysql 에서는 bigint 타입을 사용함 (사내 권장)

    • mysql 의 int 는 -2147483648 ~ 2147483647 ( 4 바이트 ) 21억 4천만…
    • 해보니 넘는 경우가 생김
    • bigint 로 -9223372036854775808 ~ 9223372036854775807 (8바이트) -> 비교 vs Char, Varchar 1개의 문자열 저장 Char 1바이트, varchar 2바이트
  2. auto increment id 를 쓰면 좋은점 -> 순차적인 증가가 가능 -> 고유값. -> 주로 Entity ID로 사용함 -> primary key 로 사용

Auto incremnt ID 를 사용할 때의 단점 3. 외부 노출의 문제 ex) 서비스의 중요 지표인 user, message 의 카운트를 id값으로 추정할 수 있음. 새로운 user, message가 등록될 때마다 id값도 1씩 오르기 때문임 -> 불필요한 내부 정보 추정이 가능해짐 -> 지표의 노출/ 공격 대상의 지정이 쉬워지는 문제 발생

  1. JPA에서는 실제 Identification Key 가 Insert 쿼리가 실행된 이후에 결정되버린다. -> 영속성관리 타이밍상 mysql 의 autoincremtid 를 사용하면 IDENTITY 식별자 생성 전략(mysql의 auto-increment 등)은 어쩔 수 없이, 쓰기 지연이 동작하지 않고 영속화 할 때 insert 쿼리가 먼저 데이터베이스로 나간다

  2. 만약 멀티 리전을 운영하면서 독립 DB를 사용하고, 통합 DB를 운영하는 식으로 DB를 구성하려고 할 때

미국 <—–> 영국 auto auto entity 1 entity 1

=> <=

    통합 DB

통합 DB에서 Key 충돌이 있을 수 있음

(충돌 회피를 위해서는 별도의 auto increment step 을 2, 3씩 증가하도록 설정할 수도 있음..)

=> 멀티 리전, 멀티 디비를 쓸지 말지도 모르는 상태에서 고민하지는 말자.

Auto incremnt ID 단점 극복 전략 5. String ID를 사용하자.

  1. UUID (Universally Unique ID) - RFC4122 - tools.ietf.org/html/rfc4122 UUID4 많이 사용함 ex) 83fda883-86d9-4913-9729-91f20973fa52

String UUID4 의 단점

UUID는 128bit(16바이트), 즉 int id 값보다 보다 4배나 큼 따라서 디스크/메모리 사용이 커지고, 성능에 영향이 있다.

(평균 2.5배, 최악의 경우, UUID가 Auto Increment에 비해 28배 느림 클러스터드 인덱스 테이블에서는 기본키를 포인터로 해서 보조 인덱스가 저장되므로 5개의 보조 인덱스의 UUID기반 스키마의 경우 , 총 6번 저장. 총 1억 개의 테이블에서 216G, 즉 스토리지의 70%를 차지할 수도 있음 https://percona.com/blog/2019/11/2)

  1. 분산 데이터베이스에서의 키 관리 부하집중을 방지해야함 => UUID4 권장 https://cloud.google.com/spanner/docs/schema-design#primary-key-prevent-hotspots

  2. 키가 완전한 랜덤이 되면서 오는 문제

  • 키를 기반으로한 sorting 이 불가능해짐.
  • autoincremt primary key 를 기반으로 max 값을 스냅샷 해서 지표로 저장하는 기능 불가능

최근의 Key generation 전략중 새로운 ULID

  1. 적당한 타협점을 찾을 수 없는가?
  • uuid 처럼 랜덤한 문자열 형태이면서
  • 오름차순, 내림차순 정렬이 가능한 형태이면서
  • 128bit 보다 적은 사이즈
  1. ULID https://github.com/ulid/spec#monotonicity

https://velog.io/@injoon2019/UUID-vs-ULID

요약 :

Entity Primary ID Key 를 생성할 때도 이런 고민을 할 수도 있음 여기까지 생각하는 것은 오버엔지니어링일 수 있음

참고자료 :

PK-를-auto-increment자동-증가-할-경우-생기는-문제점 (https://ssunw.tistory.com/entry/14-PK-%EB%A5%BC-auto-increment%EC%9E%90%EB%8F%99-%EC%A6%9D%EA%B0%80-%ED%95%A0-%EA%B2%BD%EC%9A%B0-%EC%83%9D%EA%B8%B0%EB%8A%94-%EB%AC%B8%EC%A0%9C%EC%A0%90) UUID vs Auto Increment (https://velog.io/@qnfmtm666/DevTip-UUID-vs-Auto-Increment) UUID 퍼포먼스 이슈 - percona (mysql 8.0 미만) - (링크) ycombinator.com ULID 토론 (2018.12 시작) - https://news.ycombinator.com/item?id=18768909 sequential-uuid-generators (https://www.2ndquadrant.com/en/blog/sequential-uuid-generators/) ulid-creator (https://github.com/f4b6a3/ulid-creator) google colud spanner 스키마 설계 권장사항 (https://cloud.google.com/spanner/docs/schema-design#primary-key-prevent-hotspots) 가상의 상황 트위터 (https://twitter.com/dylayed/status/1496020581610778625 ) JPA Auto incremet 가 포함된 Insert 쿼리는 언제 나갈까? (https://velog.io/@sangwoo0727/JPA-Auto-Increment%EA%B0%80-%ED%8F%AC%ED%95%A8%EB%90%9C-Insert%EC%BF%BC%EB%A6%AC%EB%8A%94-%EC%96%B8%EC%A0%9C-%EB%82%98%EA%B0%88%EA%B9%8C)


comments powered by Disqus