Database Key Design - aragorn/home GitHub Wiki

2021-03-13 JK

λ“€μ–΄κ°€λ©΄μ„œ

Database design μ—μ„œ Auto increment ID 와 UUID κ°€μš΄λ°, μ–΄λŠ 것을 Primary key 둜 μ‚¬μš©ν•˜λŠ” 것이 μ’‹μ€κ°€λΌλŠ” 질문이 μžˆλ‹€. FAQ 라고 ν• λ§Œν•œ, 자주 μ ‘ν•˜λ©° κ³ λ―Όν•˜κ²Œ 되고, μ—¬λŸ¬ μ‚¬λžŒμ΄ κ²ͺλŠ” 문제인데, 닀루기 μ–΄λ €μš΄ λ¬Έμ œμ΄λ‹€. μ†Œν”„νŠΈμ›¨μ–΄ λ””μžμΈ λ¬Έμ œκ°€ 보톡 κ·ΈλŸ¬ν•œλ°, λͺ…μΎŒν•˜κ²Œ 무엇이 더 μš°μ›”ν•œμ§€ κ΅¬λΆ„ν•˜κΈ° μ–΄λ ΅κ³ , Pros, Cons 의 각 ν•­λͺ©λ„ ν‰κ°€ν•˜κΈ° μ–΄λ ΅λ‹€.

κ·Έλž˜λ„, μ‚΄νŽ΄λ³΄κ³  κ³ λ―Όν•΄ 보면 쒋은 λ¬Έμ œμ΄λ‹ˆ, λͺ‡κΈ€μž μ μ–΄μ„œ μ£Όμž₯ν•΄ λ³Έλ‹€.

Natural Key vs Surrogate Key

이 두 κ°€μ§€ Key κ°€ 각각 무엇인지에 λŒ€ν•΄μ„œλΆ€ν„° μ΄ν•΄ν•˜κ³  κ°€λ©΄ μ’‹κ² λ‹€. κ΅¬κΈ€μ—μ„œ κ²€μƒ‰ν•˜κ³  레퍼런슀 찾아보면, λ°˜λ³΅ν•΄μ„œ μ‚¬λžŒλ“€μ΄ μ§ˆλ¬Έν•˜κ³  있고, 닡을 μ •λ¦¬ν•˜κ³  μžˆλŠ”λ°, 이 뢀뢄은 보톡 μ‚¬λžŒλ“€μ΄ λ‹΅ν•˜λŠ” λ‚΄μš©μ΄ 썩 μ™€λ‹Ώμ§€λŠ” μ•ŠλŠ”λ‹€.

http://www.agiledata.org/essays/keys.html

  • Natural key. A key that is formed of attributes that already exist in the real world. For example, U.S. citizens are issued a Social Security Number (SSN) that is unique to them (this isn't guaranteed to be true, but it's pretty darn close in practice). SSN could be used as a natural key, assuming privacy laws allow it, for a Person entity (assuming the scope of your organization is limited to the U.S.).
  • Surrogate key. A key with no business meaning.

μœ„μ™€ 같은 μ„€λͺ…이 λ§Žλ‹€.

이 μ§ˆλ¬Έμ— λ‹€λ₯΄κ²Œ 닡을 ν•˜κ³  μ‹Άλ‹€. λˆ„κ°€ λ§Œλ“€μ–΄μ„œ λ‚˜ν•œν…Œ μ•Œλ €μ€€ 것이라면 natural key, λ‚΄κ°€ μƒˆλ‘œ λ§Œλ“€μ—ˆμœΌλ©΄ surrogate key. 핡심적 ꡬ뢄은 λ‚˜μ™€ λ„ˆ λ˜λŠ” 내뢀와 μ™ΈλΆ€μ˜ ꡬ뢄이닀.

https://en.wikipedia.org/wiki/Surrogate_key

  • Surrogate (1) – Hall, Owlett and Todd (1976)
    A surrogate represents an entity in the outside world. The surrogate is internally generated by the system but is nevertheless visible to the user or application.[2]
  • Surrogate (2) – Wieringa and De Jonge (1991)
    A surrogate represents an object in the database itself. The surrogate is internally generated by the system and is invisible to the user or application.

λΉ„μ¦ˆλ‹ˆμŠ€ μ˜λ―Έκ°€ μžˆλƒ 없냐, 이런 것이 μ€‘μš”ν•˜μ§€ μ•Šμ•„ 보인닀. λΉ„μ¦ˆλ‹ˆμŠ€ μ˜λ―Έκ°€ μžˆλ‹€λŠ” 것은 남듀이 이미 μ“°κ³  μžˆλ‹€λŠ” κ²ƒμ˜ λ‹€λ₯Έ ν‘œν˜„μΌ 뿐이닀.

μ‹œμŠ€ν…œμ˜ 내뢀와 μ™ΈλΆ€λ₯Ό κ΅¬λΆ„ν•˜λŠ” 것은 κ°„λ‹¨ν•˜μ§€ μ•Šλ‹€. 보톡 μ†Œν”„νŠΈμ›¨μ–΄ μ‹œμŠ€ν…œμ€ 결함이 μžˆκΈ°λ„ ν•˜κ³ , 경계가 뢈λͺ…ν™•ν•˜κ±°λ‚˜ ν˜Όλ™μ΄ μžˆκΈ°λ„ ν•˜λ‹€. λͺ‡κ°€μ§€ 기쀀이 있긴 ν•˜μ§€λ§Œ,

  • μ†Œν”„νŠΈμ›¨μ–΄ 생λͺ… μ£ΌκΈ°λ₯Ό 같이 ν•˜λŠ” 덩어리
  • ν•˜λ‚˜μ˜ κ°œλ°œνŒ€μ˜ λ²”μœ„μ™€ κ·Έ κ°œλ°œνŒ€μ΄ λ‹΄λ‹Ήν•˜λŠ” μ‹œμŠ€ν…œμ˜ λ²”μœ„
  • Git repository 의 λ‹¨μœ„

등을 생각할 수 μžˆλŠ”λ°, μ λ‹Ήν•œ κ²ƒμœΌλ‘œ Software Development Life Cycle 을 꼽을 수 μžˆλ‹€. Development, Test, QA, Deployment, Rollback 의 μ£ΌκΈ°λ₯Ό 같이 λ”°λΌκ°€λŠλƒμ΄λ‹€. μ†Œν”„νŠΈμ›¨μ–΄ μ—”μ§€λ‹ˆμ–΄λ§νŒ€μ˜ 쑰직, κ°œλ°œνŒ€μ˜ λ²”μœ„λ„ μ€‘μš”ν•˜λ‹€.

κ°œλ°œμ–Έμ–΄, ν”„λ ˆμž„μ›Œν¬ ꡬ뢄이 κ²°μ •ν•˜μ§€ μ•Šμ„ 것이닀. 예λ₯Ό λ“€μ–΄ Java Spring μ• ν”Œλ¦¬μΌ€μ΄μ…˜κ³Ό React application 이 ν•œλ²ˆμ— νŒ¨ν‚€μ§•λ˜μ–΄ λ°°ν¬λœλ‹€λ©΄ λ˜λŠ” νŒ¨ν‚€μ§•μ€ 별도이더라도, λΉŒλ“œ/QA/배포/λ‘€λ°± μ£ΌκΈ°κ°€ λ™κΈ°ν™”λ˜μ–΄ μžˆλ‹€λ©΄, ν•˜λ‚˜μ˜ μ‹œμŠ€ν…œμΈ κ²ƒμœΌλ‘œ κ°„μ£Όν•˜λ©΄ λœλ‹€.

μ΄λ ‡κ²Œ natural key, surrogate key 의 κ°œλ…μ„ μ‚΄νŽ΄λ³΄λŠ” 것은, natural key κ°€ 처음 μ–΄λ–»κ²Œ λ§Œλ“€μ–΄μ‘Œμ„κΉŒ 따져보면, κ²°κ΅­ surrogate key 생성 문제둜 ν™˜μ›λœλ‹€λŠ” 것을 보여주기 μœ„ν•΄μ„œμ΄λ‹€. μ–΄λŠ μ‹œμŠ€ν…œμ€ Keyλ₯Ό μƒˆλ‘œ λ§Œλ“€κΈ° 마련이고, 그것을 λ‹€λ₯Έ μ‹œμŠ€ν…œμ— μ „νŒŒν•˜κ²Œ λœλ‹€. λ„˜κ²¨ 받은 μͺ½μ—μ„œλŠ” 그것을 natural key 둜 κ°„μ£Όν•˜λ©΄ 되고, 처음 λ§Œλ“œλŠ” μͺ½μ—μ„œλŠ” surrogate key λ₯Ό μ–΄λ–»κ²Œ 잘 λ§Œλ“€ 것인지λ₯Ό κ³ λ―Όν•˜λŠ” 것과 λ™μΌν•œ λ¬Έμ œκ°€ λœλ‹€.

Key 내뢀에 code system 을 embed ν•˜μ˜€λƒ μ—¬λΆ€λŠ” natural vs surrogate key ꡬ뢄과 λ¬΄κ΄€ν•œ λ‹€λ₯Έ μ£Όμ œμ΄λ‹€. 예λ₯Ό λ“€μ–΄ ν•œκ΅­μ˜ μ£Όλ―Όλ“±λ‘λ²ˆν˜ΈλŠ” μ•žλΆ€λΆ„ 6κΈ€μžκ°€ 생년월일이고, λ’·λΆ€λΆ„ μ²«κΈ€μžκ°€ 성별/내ꡭ인/외ꡭ인 ꡬ뢄 λ“± 의미λ₯Ό κ°–λŠ”λ‹€. κ·ΈλŸ¬λ‚˜, 이런 code system 을 κ°–κ³  μžˆλŠ”μ§€ μ—¬λΆ€λŠ”, natural vs surrogate key ꡬ뢄과 λ¬΄κ΄€ν•˜λ‹€. surrogate key λ₯Ό 생성할 λ•Œ, 편의λ₯Ό μœ„ν•΄ code system 을 μ μš©ν•˜λŠ” 것이 μž₯점이 있으면, λ„μž…ν•  수 μžˆλ‹€. μ΄λŸ¬ν•œ μ˜ˆμ‹œλ₯Ό 이후에 μ œμ‹œν•΄ 보겠닀.

Auto increment id vs UUID

ꡬ글 κ²€μƒ‰ν•˜λ©΄, λ§Žμ€ 글이 λ‚˜μ˜¨λ‹€. μ²«νŽ˜μ΄μ§€μ˜ κΈ€ κ°€μš΄λ° λͺ‡κ°œ λ§ν¬ν•œλ‹€.

κ·Έλž˜μ„œ UUID κ°€ 더 λ‚«λ‹€.

https://mareks-082.medium.com/auto-increment-keys-vs-uuid-a74d81f7476a

이 κΈ€ μ €μžμ˜ μ˜κ²¬μ€ 각 key 의 Pros, Cons μ—μ„œ λ‚΄ 의견과 κ°™κ±°λ‚˜ λΉ„μŠ·ν•˜λ‹€. 그런데, λ§ˆμ§€λ§‰ 결둠은 UUID κ°€ 더 λ‚«λ‹€λŠ” κ²ƒμœΌλ‘œ 달라진닀.

Auto increment id κ°€ 더 λ‚«λ‹€.

https://stackoverflow.com/questions/4642695/how-to-choose-between-uuids-autoincrement-sequence-keys-and-sequence-tables-for

https://tomharrisonjr.com/uuid-or-guid-as-primary-keys-be-careful-7b2aa3dcb439

이 κΈ€ μ €μžμ˜ 의견이 λ‚˜μ™€ λΉ„μŠ·ν•˜λ‹€.

κ·Έ μ™Έ

https://www.reddit.com/r/django/comments/fxfehw/uuid_vs_incremental_ids_pros_cons/g4xh3v9?utm_source=share&utm_medium=web2x&context=3

이 λŒ“κΈ€λ„ Pros, Cons λ₯Ό 잘 μš”μ•½ν•˜κ³  μžˆλ‹€.

κ·Έλž˜μ„œ λ‚΄ μ˜κ²¬μ€,

결둠만 κ°„λ‹¨νžˆ μ΄μ•ΌκΈ°ν•œλ‹€λ©΄, λ‚˜λŠ” λŒ€μ²΄λ‘œ auto increment id μͺ½μ΄λ‹€.

UUID의 μž₯점과 단점이 무엇인가?

일단 UUIDκ°€ 무엇인지뢀터 μ•Œμ•„μ•Ό ν•˜κ² λ‹€. μ•„μ£Ό κ°„λ‹¨νžˆ 말해, 128 bit λ§‰μˆ˜μ΄λ‹€. https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)

https://en.wikipedia.org/wiki/Birthday_problem 을 풀어보면, 128 bit UUID κ°€ λ™μΌν•œ 값이 λ‚˜μ˜¬ ν™•λ₯ μ€ μ—†κ³ , 보톡 κ²½μš°μ—λŠ” μΆ©λŒν•˜μ§€ μ•ŠλŠ”λ‹€κ³  보면 λœλ‹€. μΌλΆ€λŸ¬ random seed λ₯Ό λ™μΌν•˜κ²Œ λ§žμΆ”μ§€ μ•ŠλŠ”λ‹€λ©΄. λ§‰μˆ˜λΌλŠ” 것은 μ€‘μš”ν•œ νŠΉμ§•μ΄κ³ , μž₯점이 λ˜κΈ°λ„ ν•˜μ§€λ§Œ, 단점이 λ˜κΈ°λ„ ν•œλ‹€.

μΆ”μΈ‘ν•  수 μ—†λ‹€λŠ” 것, κ·Έλž˜μ„œ 내뢀에 μ‘΄μž¬ν•˜λŠ” id μ•„λ¬΄κ±°λ‚˜ ν•˜λ‚˜λΌλ„, μ™ΈλΆ€μ—μ„œλŠ” 찍어 맞힐 μˆ˜κ°€ μ—†λ‹€λŠ” 것을 μž₯점으둜 손에 κΌ½λŠ” μ‚¬λžŒλ“€μ΄ μžˆλ‹€. 이런 νŠΉμ„±μ€ μ—„μ²­ 큰 λ§‰μˆ˜λΌλŠ” κ²ƒμ—μ„œ λΉ„λ‘―λœ λ‹Ήμ—°ν•œ νŠΉμ„±μΈλ°, 그것이 security κ΄€μ μ—μ„œ μž₯점이 λœλ‹€λŠ” 것은, "λ³„λ‘œ..?"라고 λ³Έλ‹€. Security λ₯Ό 여기에 μ˜μ‘΄ν•˜λ©΄ μ•ˆ λœλ‹€. User ID μΆ”μΈ‘ν•˜λŠ” 것은 μ–΄μ°¨ν”Ό λ‹€λ₯Έ μ‹μœΌλ‘œ μˆ˜μ§‘ν•΄μ„œ 찍어 맞힐 μˆ˜λ„ μžˆλ‹€.

λ‚˜μ˜ κ΄€μ μ—μ„œ UUID의 μž₯점은, λΆ„μ‚° μ‹œμŠ€ν…œμ— μ ν•©ν•˜λ‹€λŠ” 것이닀. 쀑앙 μ§‘μ€‘λœ Online Key Generator κ°€ μ•„λ‹ˆλΌλŠ” 것이닀. UUIDλŠ” Globally unique key λ₯Ό λ§Œλ“€μ–΄λ‚΄κΈ° λ•Œλ¬Έμ—,

  • μ—¬λŸ¬ λ§ˆμ΄ν¬λ‘œμ„œλΉ„μŠ€ λ˜λŠ” λ”°λ‘œ λ–¨μ–΄μ Έμ„œ μž‘λ™ν•˜λŠ” instance κ°€ 각각 key λ₯Ό 생성할 수 μžˆλ‹€. Single Point of Failure κ°€ 사라진닀. μ„±λŠ₯/λŒ€μ—­ν­μ˜ 병λͺ©μ„ μ—†μ• κΈ° μ’‹λ‹€.
  • 각각 λ§Œλ“€μ–΄μ§€κ³  μ €μž₯된 데이터λ₯Ό ν•˜λ‚˜λ‘œ λ³‘ν•©ν•˜λ”λΌλ„, key 좩돌이 μ—†λ‹€. λ―Έκ΅­ μ„œλΆ€μ˜ μ‹œμŠ€ν…œμ΄ μƒμ„±ν•œ key, λ―Έκ΅­ 동뢀 μ‹œμŠ€ν…œμ΄ μƒμ„±ν•œ key, μ„œμšΈμ—μ„œ μƒμ„±ν•œ key, μΌλ³Έμ—μ„œ μƒμ„±ν•œ key, 각각을 λͺ¨λ‘ λ³‘ν•©ν•΄μ„œ BigQuery 에 데이터λ₯Ό λͺ¨μœΌλ”라도, 좩돌이 μ—†λ‹€.

단점은 λ„ˆλ¬΄ κΈΈλ‹€λŠ” 것이닀. μ†Œκ·œλͺ¨ μ‹œμŠ€ν…œμ—μ„œλŠ” 이 단점이 λ‹€λ₯Έ μž₯점을 λͺ¨λ‘ κ°€λ¦°λ‹€κ³  λ³Έλ‹€. λ‚΄κ°€ 보기엔 거의 μœ μΌν•œ λΆ„λͺ…ν•œ μ΄μœ μ΄λ‹€.

  • μ‚¬λžŒμ΄ μΈμ§€ν•˜κ³ , λΆ€λ₯΄κ³ , λ³΅λΆ™ν•˜κ³ , 닀루기 μ–΄λ ΅λ‹€. λ‘œκ·Έμ— 찍으면 읽을 수 μ—†λ‹€. Hexdigit 6κΈ€μžλ„ 읽기 μ–΄λ €μ›Œν•˜λŠ”λ°, 32κΈ€μž λͺ» 읽고 λͺ» μ™Έμš΄λ‹€. 화면에 좜λ ₯ν•  땐 보톡 - ν¬ν•¨ν•˜μ—¬ 36κΈ€μžμ΄λ‹€.
  • λ‘œλ΄‡μ˜ ν„°μΉ˜μŠ€ν¬λ¦°μ— 좜λ ₯ν•˜λ©΄ μ–΄μ©Œλ €κ³ ? ν™”λ©΄ 폭 내에 좜λ ₯이 κ°€λŠ₯ν•œκ°€? 보여쀀닀고 ν•΄μ„œ, μ „ν™”ν†΅ν™”ν•˜λ©΄μ„œ 읽어쀄 수 μžˆλ‚˜?

예) μΉ΄μΉ΄μ˜€ν†‘μ˜ 카카였 계정 ID κ°€ μžˆλŠ”λ°, 64bit integer λ₯Ό μ‚¬μš©ν•˜κ³ , hexadigit 도 μ•„λ‹Œ decimal 10μ§„μˆ˜λ‘œ 화면에 좜λ ₯ν•΄ μ€€λ‹€. 고객지원 λ°›μœΌλ €κ³  ν•˜λ©΄, 이 카카였 계정 ID λ₯Ό μ½μ–΄μ€˜μ•Ό ν•  수 μžˆλ‹€. λ˜λŠ” λ‚΄λΆ€ κ°œλ°œμžκ°€ 디버깅할 λ•Œ, 이 8 byte integer λ₯Ό API의 μ£Όμš” νŒŒλΌλ―Έν„°λ‘œ μ“°κΈ° λ•Œλ¬Έμ—, 이걸 읽고 전달해야 ν•œλ‹€. 맀우 κ³€λž€ν•˜λ‹€.

JavaScript μ—μ„œ 별 생각없이 이 ID λ₯Ό number 둜 닀루면, precision 문제 λ•Œλ¬Έμ—, λ’·λΆ€λΆ„ 자리수 λŒ€μ—¬μ„―κ°œκ°€ 쑰용히 λ‚ μ•„κ°„λ‹€. 버그 μžˆλŠ” 쀄 λͺ¨λ₯΄κ³ , ν•œμ°Έ μ§„ν–‰ν•˜λ‹€ λ’€λŠ¦κ²Œ μ‹€μˆ˜ λ°œκ²¬ν•˜κ³  μ‚½μ§ˆμ„ ν•˜κ²Œ λœλ‹€.

λ˜λ‹€λ₯Έ λ‹¨μ μœΌλ‘œ μ„±λŠ₯에 λΆˆλ¦¬ν•˜λ‹€. 길이가 λ„ˆλ¬΄ κΈΈλ‹€λŠ” 것, random value λΌλŠ” 것, 두 κ°€μ§€ 이유 λ•Œλ¬Έμ—, μ €μž₯μ†Œκ°€ 효율적으둜 μž‘λ™ν•˜λŠ”λ° λΆˆλ¦¬ν•˜λ‹€. μ†Œκ·œλͺ¨μ—μ„œλŠ” μ„±λŠ₯에 별 μ΄μŠˆκ°€ μ—†μ§€λ§Œ, large system μ—μ„œ UUID λ₯Ό key index 둜 μ‚¬μš©ν•˜λŠ” 건, νŽ˜λ„ν‹°κ°€ 크닀. κ·Έλž˜μ„œ νš¨μœ¨μ„ μœ„ν•΄ λ‹€μ‹œ incremental number 의 surrogate key λ₯Ό 내뢀에 λ§Œλ“€μ–΄ μ‚¬μš©ν•˜κ²Œ λœλ‹€.

λ‚΄κ°€ UUIDλ₯Ό μ“΄λ‹€λ©΄, μ–Έμ œ μ“°κ²Œ 될까?

  • multi-region μ—μ„œ λ…λ¦½μ μœΌλ‘œ μž‘λ™ν•˜λŠ” μ„œλΉ„μŠ€λ₯Ό 빨리 λ§Œλ“€μ–΄μ•Ό ν•  λ•Œ.
  • key system design μ΄μŠˆμ— λŒ€ν•΄ λ…Όμ˜ν•˜κ³  μ€€λΉ„ν•  μ—¬λ ₯이 μ•ˆ 될 λ•Œ.

Auto increment id의 μž₯점과 단점이 무엇인가?

UUIDλ₯Ό μ‚΄νŽ΄λ³΄κ³  λ‚˜λ‹ˆ, auto increment id 의 μž₯단점을 κΌ½κΈ° μ‰¬μ›Œμ‘Œλ‹€.

첫번째 μž₯점. μ§§λ‹€. 짧은 key κ°€μš΄λ° κ΅¬ν˜„μ΄ 제일 μ‰¬μš΄ 방법이닀. 더 짧은 key λ₯Ό λ§Œλ“€κΈ° μ–΄λ ΅λ‹€. 꽉 μ±„μ›Œ μ‚¬μš©ν•œ auto increment id 보닀 더 짧은 key λ₯Ό λ§Œλ“œλŠ” 것은 λΆˆκ°€λŠ₯ν•˜λ‹€.

λ‘λ²ˆμ§Έ μž₯점. Sequential ν•˜κΈ° λ•Œλ¬Έμ—, range 둜 set 을 ν‘œν˜„ν•˜λŠ”λ° μœ λ¦¬ν•˜λ‹€. 보톡 λ‹€λ£¨κ²Œ λ˜λŠ” resource의 subset 이 μ–΄λŠ id λΆ€ν„° μ–΄λŠ id 사이, 이런 range 둜 ν‘œν˜„ κ°€λŠ₯ν•΄μ§„λ‹€.

예) 곡μž₯μ—μ„œ λΆˆλŸ‰μ΄ 생기면, λŒ€λΆ€λΆ„ sequential number range λ₯Ό μ§€μ •ν•΄μ„œ recall ν•˜λ©΄ λœλ‹€.

μ„Έλ²ˆμ§Έ μž₯점. time locality κ°€ μžˆμ–΄μ„œ, 보톡 μ‹œκ°„μˆœ μ •λ ¬ λͺ©λ‘μ„ λ§Œλ“€ λ•Œ, μ €μ ˆλ‘œ cache hit ratio κ°€ μ˜¬λΌκ°„λ‹€.

λͺ‡κ°€μ§€ 단점이 μžˆλ‹€.

첫번째. Key generator κ°€ online 으둜 μž‘λ™ν•΄μ•Ό ν•œλ‹€. λ„€νŠΈμ›Œν¬ μž₯μ• κ°€ λ‚˜λ©΄ λͺ¨λ‘ λ©ˆμΆ˜λ‹€λŠ” μ˜λ―Έμ΄λ‹€. Single Point of Failure κ°€ λœλ‹€. 이것은 치λͺ…적 단점 쀑 ν•˜λ‚˜μ΄λ‹€. μ†Œκ·œλͺ¨ 온라인 μ‹œμŠ€ν…œμ—μ„  보톡 상관이 μ—†μ§€λ§Œ. 그런데, multi-region μ΄κ±°λ‚˜, offline system κ³Ό λ­”κ°€λ₯Ό ν•˜λ €κ³  ν•˜λ©΄ 치λͺ…μ μ΄κ²Œ λœλ‹€.

λ‘λ²ˆμ§Έ. RDBMS 의 incremental id λ₯Ό μ“°λ©΄, 데이터λ₯Ό 넣어보아야 key λ₯Ό μ•Œ 수 있게 λœλ‹€.

DB table 에 데이터λ₯Ό 넣어보아야 key λ₯Ό μ•Œ 수 μžˆλ‹€λŠ” 것은, μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ auto increment id λ₯Ό 직접 μƒμ„±ν•˜λŠ” κ²ƒμœΌλ‘œ ν•΄κ²°ν•  μˆ˜λ„ μžˆλ‹€. κ³ μ„±λŠ₯의 Key generator κ°€ ν•„μš”ν•œ 경우, mysql λ“± DBMSκ°€ μ œκ³΅ν•˜λŠ” auto increment id κ°€ μ•„λ‹Œ, application μ—μ„œ 직접 μƒμ„±ν•œ key λ₯Ό μ‚¬μš©ν•˜λ©΄μ„œ, bulk/batch processing ν•˜λŠ” κΈ°μˆ μ„ μ μš©ν•  수 μžˆλ‹€. λ˜λŠ” redis 같은 cache storage μ—μ„œ id λ₯Ό μƒμ„±ν•˜λŠ” 방법도 μ’‹λ‹€.

μ„Έλ²ˆμ§Έ. λŒ€μš©λŸ‰ λΆ„μ‚° μ‹œμŠ€ν…œμ„ λ§Œλ“œλŠ”λ° 병λͺ©μ΄ λ˜μ–΄ 버린닀. μˆ˜μ‹­λŒ€ λ…Έλ“œ μˆ˜μ€€μ—μ„œ, κ³ μ†μœΌλ‘œ μž‘λ™ν•˜κ³  싢은데, Key generator λ₯Ό auto increment number 둜 μ μš©ν•œ 경우, 병λͺ©μ΄ λ˜μ–΄ 버린닀. μˆ˜λ°±λŒ€ 이상 λ…Έλ“œλ‘œ λŠ˜μ΄μ§€λ„ λͺ»ν•œλ‹€. 보톡 이런 κ²½μš°λŠ”, ν‰μƒμ‹œμ— λŒ€λŸ‰μ˜ 데이터가 μœ μž…λ˜κ³  μžˆκΈ°μ—, μ•½κ°„μ˜ μ„±λŠ₯ degradation 이 λ°œμƒν•΄λ„, Key generator μ‹œμŠ€ν…œμ˜ throughput 이 κ°μ†Œν•˜κ³ , 이곳에 λΆ€ν•˜κ°€ μ§‘μ€‘λ˜κ³ , 전체 μ‹œμŠ€ν…œμ΄ 먹톡이 되곀 ν•œλ‹€. Spinlock 기반의 κ³ μ„±λŠ₯ key generator λ₯Ό κ΅¬ν˜„ν•˜λŠλƒ λ§ˆλŠλƒ, redis key 생성기가 μΆ©λΆ„νžˆ λΉ λ₯΄λƒ μ•„λ‹ˆλƒ, μ„±λŠ₯ ν…ŒμŠ€νŠΈλŠ” μ–΄λ–»κ²Œ ν•  것이며, μ–΄λŠ μ •λ„μ˜ High availability λ₯Ό 보μž₯ν•  것이냐, κ·Έ νŒ€μ—μ„œ μž₯μ• λ₯Ό λ‚΄λ©΄ λˆ„κ°€ μ–΄λ–»κ²Œ μ±…μž„μ§ˆ 것이냐 λ“± μ΄μŠˆκ°€ λΆˆκ±°μ§„λ‹€.

UUID 와 Increment id κ°€ 각각의 μž₯단점이 μžˆλŠ”λ°, λŒ€μ•ˆμ΄ μžˆλŠ”μ§€? 해결책이 μžˆλŠ”μ§€?

자, 이제 μ§„μ§œ λ³Έ 주제둜 λ“€μ–΄κ°€μž. μ–΄λ €μš΄ μ‹œμŠ€ν…œ λ””μžμΈ λ¬Έμ œμ΄λ‹€.

첫번째 ν•΄κ²°μ±…. Natural key λ₯Ό μ“°λŠ” 것이닀.

Surrogate key λŠ” μ—¬λŸ¬κ°€μ§€ μž₯점이 μžˆμ§€λ§Œ, 단점도 λ§Žλ‹€. μ‹œμŠ€ν…œ λ””μžμΈμ„ ν•  λ•Œ, 일단 별 생각없이 incremental id λ₯Ό 내뢀에 λ§Œλ“€μ–΄λ‚΄λŠ” 것은 기본으둜 ν•˜κ³  λ³Έλ‹€. κ·Έλž˜μ•Ό 보톡 μ‹œμŠ€ν…œμ΄ 효율적으둜 μž‘λ™ν•˜κ²Œ λ””μžμΈ, κ΅¬ν˜„ν•  수 μžˆλ‹€. 그런데 이 id λ₯Ό 외뢀와 데이터 κ΅ν™˜ν•  λ•Œ μ‚¬μš©ν•˜λŠ” κ²ƒμ—λŠ” 맀우 신쀑해야 ν•˜κ³ , 보톡 잘 λͺ¨λ₯΄κ² μœΌλ©΄, μ•ˆ ν•΄μ•Ό ν•œλ‹€. UUID 이든, Increment ID 이든, Surrogate key λ₯Ό 외뢀에 μœ ν†΅μ‹œν‚€λŠ” 것에 맀우 신쀑해야 ν•œλ‹€.

Surrogate key λ‘œμ„œ, UUID λ₯Ό μ“°μ§€ 말아야 ν•˜λŠ” 이유 쀑 ν•˜λ‚˜μ™€ μ—°κ²°λœλ‹€. 외뢀에 μœ ν†΅μ‹œν‚€μ§€ μ•Šμ„ν…λ°, Global unique id λΌλŠ” μž₯점이 무어에 ν•„μš”ν•˜λ‹€λŠ” 것인가? λ‚΄λΆ€μ—μ„œλ§Œ μ“°κ² λ‹€λ©΄, Compact ν•œ Sequential number κ°€ 훨씬 μ’‹λ‹€.

Natural Key λ₯Ό κ·Έλƒ₯ μ“°λŠ” 것이 맀우 쒋은 λŒ€μ•ˆμ΄λ‹€.

만일 아직 Natural Key κ°€ μ—†λ‹€λ©΄, 이것은 λ‚¨μ—κ²Œ κ·Έ 일을 λ– λ„˜κΈ°λŠ” 것을 μ „μ œλ‘œ ν•œλ‹€. ν•˜ν•˜ν•˜.

λ‘λ²ˆμ§Έ 방법. Natural key 의 hash value λ₯Ό μ‚¬μš©ν•œλ‹€.

Natural Key κ°€ λ„ˆλ¬΄ κΈΈκ±°λ‚˜, κ°€λ³€κΈΈμ΄μ—¬μ„œ 닀루기 νž˜λ“  κ²½μš°κ°€ μžˆλ‹€. λŒ€ν‘œμ μœΌλ‘œ url 의 경우, natural key κ°€ κΈΈκ³  가변길이이닀. 이것에 λŒ€ν•΄, SHA1, MD5, murmur λ“± hash function 을 μ μš©ν•˜κ³ , κ·Έ hash value λ₯Ό natural key 인 것인양, λ˜λŠ” candidate key 인 것인양 μ‚¬μš©ν•˜λ©΄ λœλ‹€. human readable representation μœΌλ‘œλŠ” url safe base64 λ₯Ό μ‚¬μš©ν•œλ‹€.

κΈΈμ΄λŠ” Birthday problem 을 풀어보면 닡이 λ‚˜μ˜¨λ‹€. μ €μž₯곡간을 μ•„κ»΄μ“°κ³  μ‹Άλ‹€λ©΄, hash value 의 일뢀λ₯Ό 8 bytes ~ 12 bytes μ •λ„λ‘œ λŠμ–΄μ„œ μ‚¬μš©ν•  수 μžˆλ‹€. 8 bytes μ‚¬μš©ν•˜λŠ” 경우, 2의 64승의 제곱근인 2의 32승 근처, 4G, 40μ–΅ μ •λ„μ˜ 데이터λ₯Ό λ‹€λ£¨λŠ”λ° λ¬Έμ œκ°€ μ—†λ‹€. 12 bytes μ‚¬μš©ν•œλ‹€λ©΄, 2의 48승 = 2의 32승 x 2의 16승 = 40μ–΅ x 6만 = 240μ‘° μ •λ„μ˜ 데이터λ₯Ό λ‹€λ£° 수 μžˆλ‹€. 이 정도 μ„ μ—μ„œ 좩돌이 없을 κ²ƒμœΌλ‘œ μΆ”μ •ν•  수 μžˆλ‹€. 8 bytes 의 hash value λŠ” base64 둜 ν‘œν˜„ν•˜λ©΄ 12κΈ€μž, 12 bytes 의 hash value λŠ” base64 둜 ν‘œν˜„ν•˜λ©΄ 16κΈ€μžκ°€ λœλ‹€.

μ²«κΈ€μžμ— κ΅¬λΆ„μžλ₯Ό 적절히 μ •μ˜ν•΄ 쀄 수 μžˆλ‹€. File μœ ν˜• κ΅¬λΆ„ν•˜λŠ” magic number 4~8 bytes 처럼, ID의 μ•žλΆ€λΆ„ λͺ‡λΉ„νŠΈμ— 따라, user_id, message_id, device_id λ“± μ£Όμš” resource μœ ν˜•μ„ κ΅¬λΆ„ν•˜λŠ” 체계λ₯Ό embed ν•  수 μžˆλ‹€. λ¦¬μ†ŒμŠ€ μœ ν˜• κ΅¬λΆ„μžλ₯Ό λ„μž…ν•˜λŠ” 것은, hash value 의 key 이든 auto increment key 이든, 생성 방식과 λ¬΄κ΄€ν•˜κ²Œ μœ μš©ν•˜λ‹€.

μ‹€μ œλ‘œ 카카였, 넀이버 등이 이런 λ””μžμΈ 체계λ₯Ό κ°–κ³  있(μ—ˆ)λ‹€. κ³ λ―Όν•΄ 보면, κ²°κ΅­ 이 체계λ₯Ό μ„ νƒν•˜κ²Œ λœλ‹€. μ„ΈλΆ€ λ””ν…ŒμΌμ—μ„œ λͺ‡ λ°”μ΄νŠΈ μ“Έ 것이냐, hash function 무엇을 μ“Έ 것이냐, url μ—μ„œ http/https λ–Όμ–΄λ‚Έ 것을 μ“Έ 것이냐 뢙이고 μ“Έ 것이냐 λ“± μ΄μŠˆκ°€ 있긴 ν•˜μ§€λ§Œ.

μ„Έλ²ˆμ§Έ 방법. Surrogate key λ₯Ό 직접 잘 λ§Œλ“ λ‹€.

Natural Key κ°€ 있으면 그것을 μ‚¬μš©ν•˜λŠ” 것이 μ’‹λ‹€. 그런데, Natural Key κ°€ μ—†λŠ” κ²½μš°κ°€ μžˆλ‹€.

νšŒμ› κ°€μž…μ„ 처음 λ°›λŠ” κ³³, μΉ΄μΉ΄μ˜€ν†‘ λ©”μ‹ μ €μ—μ„œ λ©”μ‹œμ§€λ₯Ό λˆ„κ΅°κ°€ μž‘μ„±ν•΄μ„œ μ „μ†‘ν•˜λ €λŠ” μ‹œμ  λ“±μ—λŠ”, νšŒμ›ID, λ©”μ‹œμ§€ID κ°€ μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ”λ‹€. νšŒμ›, λ©”μ‹œμ§€μ— λŒ€ν•œ Natural Key κ°€ μ—†λŠ” 것이닀.

이 κ²½μš°μ—λŠ”, μ—”μ§€λ‹ˆμ–΄λ§ μ—¬λ ₯이 λœλ‹€λ©΄, λΆ„μ‚°λœ incremental id 생성기λ₯Ό κ΅¬ν˜„ν•˜λ©΄ μ’‹κ² λ‹€. 예λ₯Ό λ“€μ–΄, 8 bytes μ •μˆ˜λ‘œ key λ₯Ό μƒμ„±ν•˜λŠ”λ°, μˆ˜μ‹­~수백개 key 생성기 instance κ°€ μ—¬λŸΏ λ™μ‹œμ— μž‘λ™ν•˜λŠ” 경우λ₯Ό κ°€μ •ν•˜κ³ , 각각의 key 생성기가 μ€‘μ•™μ˜ quorum based system μ—μ„œ key block 을 ν• λ‹Ή λ°›λŠ” 방식을 생각할 수 μžˆλ‹€.

μ—¬λŸ¬ μ‚¬λžŒμ΄ λΉ„μŠ·ν•œ λ°©μ‹μ˜ λ””μžμΈκ³Ό κ΅¬ν˜„μ„ μ‹œλ„ν–ˆμ—ˆλ‹€.

https://betterprogramming.pub/uuid-generation-snowflake-identifiers-unique-2aed8b1771bc

Twitter μ—μ„œλŠ” λ‹€μŒκ³Ό 같이 key λ₯Ό λ§Œλ“€μ—ˆλ‹€κ³  ν•œλ‹€.

To solve the above project, Twitter developed the Snowflake project as a Thrift Server written in Scala. The generated Ids were composed of:

  • Time β€” 41 bits (millisecond precision)
  • Configured machine ID β€” 10 bits
  • Sequence number β€” 12 bits β€” rolls over every 4096 per machine

https://stackoverflow.com/questions/18248644/proposed-solution-generate-unique-ids-in-a-distributed-environment

https://sqlblog.iridule.net/index.php/2009/08/30/surrogate-keys-in-distributed-databases/

We have two values to be combined: the database node identifier (DBNodeID), and the row identifier for a particular table on a particular database node (RowID). Let’s assume that both are integer values, which would not be unreasonable in practice. Each integer uses four bytes of storage, so to combine the two values without loss of information, we need eight bytes. We will use bigint as the data type for the combined value, which does require eight bytes of storage. To combine two integer values into one bigint value we will use a technique called bit shifting.

λ„€λ²ˆμ§Έ 방법. MySQL 섀정을 잘 ν•΄μ„œ, Auto increment id λ₯Ό 잘 λ§Œλ“ λ‹€.

Auto increment id 의 step 을 λŠ˜μ—¬μ„œ master-master replication 섀정을 μ μš©ν•˜κ³ , multi-region ꡬ성을 μ μš©ν•˜λŠ” 것이닀. 이 방법은 μ‹€μ œλ‘œ μž‘λ™ν•˜λŠ” 것을 λ³Έ 것은 μ•„λ‹ˆλ‹€. μž‘λ™μ€ 잘 ν•  것 같은데, μ• ν”Œλ¦¬μΌ€μ΄μ…˜, ν”Œλž«νΌ κ΅¬ν˜„ κ³Όμ •μ—μ„œ μ–΄λ–€ λ¬Έμ œκ°€ λ°œμƒν•  κ²ƒμΈμ§€λŠ”, 직접 κ²½ν—˜ν•΄ 보지 μ•Šμ•„μ„œ 잘 λͺ¨λ₯΄κ² λ‹€. 이 λ‹€μŒμ— DBλ₯Ό μƒˆλ‘œ κ΅¬μ„±ν•˜κ²Œ 되면 ν•œλ²ˆ μ‹œλ„ν•΄ 봐야겠닀.

https://w2.cleardb.net/faqs/

How does ClearDB work?

ClearDB uses a combination of standard MySQL, mixed in with β€œmaster-master” replication as well as our own specialized layered software stack to provide a highly available MySQL database environment for your applications and services. Each cluster is geographically separated to ensure your database’s availability, even if an entire network, datacenter, storage, or system failure occurs. Combined with our high availability routing technology, we ensure that your database is always online and fully available, 24/7.

마무리

μƒκ°λ‚œ 김에 κ°„λ‹¨νžˆ κΈ€λ‘œ μ •λ¦¬ν•˜λ©° 검색을 μ’€ ν•΄λ³΄λ‹ˆ, λ‹€λ₯Έ μ‚¬λžŒλ“€λ„ κ³ λ―Ό 많이 ν•΄μ„œ 쒋은 방법이 μ•Œλ €μ§„ λ¬Έμ œλΌλŠ” 것도 λ‹€μ‹œ μ•Œκ²Œ λ˜μ—ˆλ‹€.