15 คะแนน โดย GN⁺ 2025-05-22 | 4 ความคิดเห็น | แชร์ทาง WhatsApp
  • 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 ความคิดเห็น

 
jaylee 2025-05-23

ผมใช้ Prisma + ULID แทนอยู่ครับ สั้นกว่ามากและดีกว่า

 
ssssut 2025-05-22

ก่อนหน้านี้ผมใช้งานโดยสร้างฟังก์ชันอย่าง uuid_generate_v7() ขึ้นมาเอง เลยเป็นข่าวที่น่ายินดีครับ

 
stomx 2025-05-22

โอ้!!

 
halfenif 2025-05-22

โอ...!