Ngày khác HB team chatting, Ben, dev-ops master, mentioned wished dùng ULIDs thay UUIDs cho particular system.
Như seasoned engineer, reaction: mumble non-committal thì sneak over Google figure out what the hell ULID is.
Hai giờ sau emerged với thousand-yard stare và realization: world of unique identifiers larger và more wondrous than imagined.
Trước ULIDs, back to basics discuss UUIDs:
Vấn Đề Với "Regular" IDs?
Hầu hết web apps dùng databases default numeric IDs auto-increment. Ví dụ Rails:
p1 = Person.create!
p1.id # => 1
p2 = Person.create!
p2.id # => 2
Database generate sequential IDs vì store counter increment on record creation.
Pattern cũng outside databases. Sometimes assign IDs manually, store custom counter in — say — Redis instance.
Sequential IDs easy implement low-volume, nhưng problematic khi volume increases:
- Impossible create records concurrently vì mỗi insert wait in line nhận ID.
- Request sequential ID may require network round trip → slower performance.
- Difficult scale out data stores provide sequential IDs. Worry counters different servers out of sync.
- Node với counter dễ become single point of failure.
Sequential IDs cũng leak data, may problematic:
- Dễ guess IDs resources may not belong to you.
- Tạo user ID 20 → biết service có 20 users.
UUIDs Are Web-Scale
UUIDs trông khác sequential IDs. 128-bit numbers, typically 32 hexadecimal digits:
123e4567-e89b-12d3-a456-426655440000
UUIDs created using algorithms defined RFC 4122. Attempt solve sequential IDs problems:
- Generate UUIDs any number nodes without shared state/coordination.
- Less guessable sequential IDs (more later)
- Không divulge dataset size.
Catch: small chance two nodes independently generate same ID. Event gọi "collision."
Many Flavors Of UUID
Five types UUID algorithm RFC 4122. Two categories:
- Time và randomness-based algorithms — discussed. New UUID every run.
- Type 4: Randomly-generated ID. Probably best bet new code.
- Type 1: ID chứa host MAC address và current timestamp. Deprecated vì too easy guess.
- Type 2: Uncommon. Purpose-built antiquated RPC form.
- Name based algorithms khác. Luôn produce same UUID given inputs.
- Type 5: SHA-1 hash generate UUID. Recommended.
- Type 3: MD5 hash, deprecated vì MD5 insecure.
Ruby generate UUIDs via uuidtools gem. Supports mọi type trừ mysterious type 2:
require "uuidtools"
# Type 1
UUIDTools::UUID.timestamp_create
# => #<UUID:0x2adfdc UUID:64a5189c-25b3-11da-a97b-00c04fd430c8>
# Type 4
UUIDTools::UUID.random_create
# => #<UUID:0x19013a UUID:984265dc-4200-4f02-ae70-fe4f48964159>
# Type 3
UUIDTools::UUID.md5_create(UUIDTools::UUID_DNS_NAMESPACE, "www.widgets.com")
# => #<UUID:0x287576 UUID:3d813cbb-47fb-32ba-91df-831e1593ac29>
# Type 5
UUIDTools::UUID.sha1_create(UUIDTools::UUID_DNS_NAMESPACE, "www.widgets.com")
# => #<UUID:0x2a0116 UUID:21f7f8de-8051-5b89-8680-0195ef798b6a>
Moving On To ULIDs
Note: Original blog post forgot link ULID spec. Here it is. Provides links implementations Ruby và other languages.
ULIDs useful new take unique identifiers. Obvious difference: look different:
01ARZ3NDEKTSV4RRFFQ69G5FAV
Made of two base32-encoded numbers: UNIX timestamp followed by random number. Structure per spec:
01AN4Z07BY 79KA1307SR9X4MV3
|----------| |----------------|
Timestamp Randomness
48bits 80bits
Structure fascinating! UUIDs rely timestamps HOẶC randomness, nhưng ULIDs dùng timestamps VÀ randomness.
Result, ULIDs interesting properties:
- Lexicographically (alphabetically) sortable.
- Timestamp accurate to millisecond
- Prettier UUIDs :)
Open cool possibilities:
- Partition database by date, dùng timestamp embedded ULID select correct partition.
- Sort by ULID thay vì separate created_at column nếu millisecond precision acceptable.
Possible downsides:
- Expose timestamp bad idea app, ULIDs may not best option.
sort by ulidmay not work nếu need sub-millisecond accuracy.- Theo internet, some ULID implementations không bulletproof.
Kết Luận
UUIDs là và continue to be standard. Been around forever, libraries every language. However, new approaches worth considering, especially entering world increasingly run by distributed systems. New unique-id approaches may help solve problems not prevalent at RFC4122 publication.