- PostgreSQL 18 รองรับ UUIDv7 โดยตรงในตัว และมอบ ตัวระบุเฉพาะที่สามารถเรียงลำดับได้และเป็นมิตรกับดัชนี
- UUIDv7 ยังคงรักษา ความเป็นเอกลักษณ์และความปลอดภัยในสภาพแวดล้อมแบบกระจาย ของ UUID แบบเดิมไว้ พร้อมใช้ โครงสร้างการเรียงลำดับตามเวลาที่เหมาะกับดัชนี
btree
- มันแก้ปัญหาสองข้อแรกจากข้อเสียเดิมของ UUID คือ ไม่สามารถเรียงลำดับได้, ดัชนีกระจัดกระจาย, ขนาดหน่วยความจำใหญ่ โดยทำให้ เรียงตามเวลาและเพิ่มประสิทธิภาพการแทรกข้อมูล ได้
- ใน PostgreSQL 18 สามารถสร้าง UUID ได้ด้วยฟังก์ชัน
uuidv7() และยังมี ความสามารถในการดึง timestamp และป้อนค่าเวลาแบบกำหนดเอง
- ตอนนี้ เหตุผลที่เคยลังเลจะใช้ UUID เป็น primary key ได้หมดไปแล้ว ทำให้มันเป็น ตัวเลือกที่เหมาะสมยิ่งขึ้นสำหรับระบบแบบกระจายและสภาพแวดล้อมหลายผู้เช่า
PostgreSQL 18
- PostgreSQL 18 รุ่นเบต้าได้เปิดตัวแล้ว และกำลังทดสอบโดยตั้งเป้าออกเวอร์ชันจริงในเดือนกันยายน
- ฟีเจอร์สำคัญ:
- Async I/O: อินพุต/เอาต์พุตแบบอะซิงก์บนพื้นฐาน
io_uring ช่วยเพิ่มความเร็วของ sequence scan และ vacuum ได้ 2~3 เท่า
- Skip scan ของดัชนี
btree แบบหลายคอลัมน์, การปรับแต่งคิวรี OR/IN ให้เหมาะสม
- คงสถิติของ planner ไว้ข้ามการอัปเกรด
- ฟังก์ชัน UUIDv7
- virtual generated columns, การล็อกอินด้วย OAuth, การเพิ่มข้อมูล I/O/CPU/WAL ใน EXPLAIN เป็นต้น
ข้อดีของ UUID
- สามารถ สร้าง ID ที่ไม่ซ้ำกันในสภาพแวดล้อมแบบกระจาย ได้
- เพิ่มความปลอดภัยด้วย ตัวระบุสาธารณะที่คาดเดาไม่ได้
- สามารถ สร้าง ID ได้จากฝั่งไคลเอนต์โดยตรง ช่วยลดการสื่อสารกับเซิร์ฟเวอร์
ข้อเสียของ UUID แบบเดิม
- ไม่สามารถเรียงลำดับได้
- ประสิทธิภาพการแทรกลดลงจาก ความไม่เป็นเชิงพื้นที่ของดัชนี
- มีโอเวอร์เฮดจาก ขนาด 128 บิต
ทางออกของ UUIDv7
- เป็น UUID รุ่นใหม่ที่นำมาใช้ตาม RFC 9562 (ประกาศเมื่อเดือนพฤษภาคม 2024)
- ใช้ timestamp แบบ Unix Epoch ใน 48 บิตแรก และส่วนที่เหลือเป็นการผสม ค่าสุ่ม + ตัวนับ
- เรียงตามลำดับเวลาได้ และ เพิ่มประสิทธิภาพการแทรกลงดัชนี
- UUIDv6 มีไว้เพื่อความเข้ากันได้ย้อนหลัง ส่วน UUIDv8 มีไว้สำหรับการทดลอง/การขยายของผู้ขาย
- UUIDv7 เท่านั้นที่เป็นมาตรฐานใหม่ที่มีความหมายในทางปฏิบัติจริง
การใช้ UUIDv7 ใน PostgreSQL 18
- สร้าง UUID ตามเวลาปัจจุบันได้ด้วยฟังก์ชัน
uuidv7()
uuidv7(INTERVAL) ใช้สะท้อนค่าเวลา offset ตามต้องการได้
- สามารถดึงเวอร์ชันของ UUID และเวลาที่สร้างได้ด้วยฟังก์ชัน
uuid_extract_version(), uuid_extract_timestamp()
- ตัวอย่าง:
CREATE TABLE test (
id uuid DEFAULT uuidv7() PRIMARY KEY,
name text
);
INSERT INTO test (name) VALUES ('foo');
INSERT INTO test (name) VALUES ('bar');
INSERT INTO test (id, name) VALUES (uuidv7(INTERVAL '-1 hour'), 'oldest');
SELECT uuid_extract_timestamp(id), name FROM test ORDER BY id;
- มีการเพิ่ม
uuidv4() เป็นชื่อเรียกแทนของ gen_random_uuid()
บทสรุปและคำแนะนำ
- UUIDv7 เหมาะสำหรับ ผู้ใช้ที่เคยเจอปัญหาด้านประสิทธิภาพเมื่อใช้ UUID แบบเดิม
- ได้ทั้งการเรียงลำดับและประสิทธิภาพของดัชนี พร้อมยังคงข้อดีของ UUID เอาไว้
- สามารถทดสอบได้ทันทีใน PostgreSQL 18 เบต้า
- เป็นตัวเลือกที่เหมาะสำหรับ การสร้าง ID ในระบบแบบกระจาย, แอปแบบหลายผู้เช่า, และสภาพแวดล้อม serverless
> “UUIDv7 เป็นฟีเจอร์ที่เพิ่มเข้ามาอย่างเงียบ ๆ แต่ทรงพลัง และทำให้ต้องกลับมาคิดใหม่เรื่องการใช้ UUID เป็น primary key ใน Postgres”
4 ความคิดเห็น
ผมใช้ Prisma + ULID แทนอยู่ครับ สั้นกว่ามากและดีกว่า
ก่อนหน้านี้ผมใช้งานโดยสร้างฟังก์ชันอย่าง
uuid_generate_v7()ขึ้นมาเอง เลยเป็นข่าวที่น่ายินดีครับโอ้!!
โอ...!