UUID
Universal Unique Identifier — ตัวระบุไม่ซ้ำกันขนาด 128-bit (แสดงเป็น string 36 ตัวอักษร เช่น 550e8400-e29b-41d4-a716-446655440000)
ทุก Version
| Version | วิธีสร้าง | ใช้เมื่อไหร่ |
|---|---|---|
| v1 | timestamp + MAC address ของเครื่อง | ต้องการ uniqueness จาก hardware — แต่เปิดเผย MAC address |
| v2 | เหมือน v1 + user/group ID ของ OS | DCE security — แทบไม่มีใครใช้แล้ว |
| v3 | MD5 hash จาก namespace + name | สร้าง ID เดิมซ้ำได้จาก input เดิม (deterministic) |
| v4 | สุ่มล้วน (random 122 bits) | ใช้ง่าย ไม่ต้องคิดเยอะ — ยอดนิยมที่สุด |
| v5 | SHA-1 hash จาก namespace + name | เหมือน v3 แต่ปลอดภัยกว่า (SHA-1 > MD5) |
| v6 | v1 แต่สลับ byte ให้ timestamp มาก่อน | sort ตามเวลาได้ — เป็น stepping stone ไป v7 |
| v7 | Unix timestamp (48-bit) + random | sort ได้ + ไม่เปิดเผย MAC — ตัวเลือกที่ดีที่สุดสำหรับ DB |
| v8 | custom format ตามที่ vendor กำหนด | กรณีพิเศษที่ต้องการ format เฉพาะ |
v4 vs v7 — ทำไมถึงต่างกันมากใน Database
v4 สุ่มล้วน → ค่าที่ได้กระจายทั่ว B-Tree index → ทุกครั้งที่ insert ต้องไปหา page ที่ random → cache miss เยอะ → index กิน buffer cache จนไม่เหลือให้ table/index อื่น
v7 มี timestamp นำหน้า → ค่าใหม่เรียงต่อท้ายเสมอ → insert แค่ต่อท้าย index → cache hit สูง → ประสิทธิภาพใกล้เคียง bigint
Benchmark บน PostgreSQL (insert 1 ล้าน rows + concurrent queries)
| วิธีเก็บ | เวลา insert | TPS | ขนาด DB | เทียบกับตัวก่อนหน้า |
|---|---|---|---|---|
| uuid::text | 410 วินาที | 2,421 | 4.31 GB | — |
| uuidv4 | 375 วินาที | 2,670 | 2.65 GB | เร็วขึ้น 10%, เล็กลง 63% |
| uuidv7 | 290 วินาที | 3,420 | 2.47 GB | เร็วขึ้น 30%, เล็กลง 7% |
| bigint | 290 วินาที | 3,480 | 1.97 GB | เร็วเท่ากัน, เล็กลง 25% |
สาเหตุหลักที่ v4 ช้า: index ไม่มี data locality → กิน buffer cache ของ PostgreSQL → page อื่นโดนไล่ออก → ทุก operation ต้องอ่านจาก disk
เลือกอะไรดี
- v4 — ใช้ได้ถ้าแค่ต้องการ unique ID ไม่ต้อง sort ไม่ใช่ database PK (เช่น expense tracker app)
- v7 — เหมาะเป็น database primary key เพราะ insert เร็ว + sort ตามเวลาได้
- bigint — เร็ว + เล็กที่สุด แต่ไม่ globally unique ข้าม system
- v3/v5 — ต้องการ deterministic ID จาก input เดิมได้ผลเดิม (เช่น URL → UUID)
ใช้ใน Dart
import 'package:uuid/uuid.dart';
const uuid = Uuid();
uuid.v4(); // "a1b2c3d4-..."
uuid.v7(); // "018f..." (เรียงตามเวลา)