7 คะแนน โดย GN⁺ 2026-02-10 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • เครื่องมือแบบ CLI สำหรับจัดการการย้ายข้อมูลฐานข้อมูลโดยเปรียบเทียบ ความแตกต่าง (diff) ระหว่าง SQL schema
  • สามารถจัดการสคีมาของ RDBMS ได้ด้วย ไวยากรณ์ SQL DDL แบบทั่วไป
  • รองรับฐานข้อมูลหลักอย่าง MySQL, MariaDB, TiDB, PostgreSQL, SQL Server, SQLite3
  • บนเว็บไซต์มีเดโมออนไลน์ที่ใช้ WebAssembly build ให้ทดลองฟังก์ชันเปรียบเทียบสคีมาและสร้าง DDL ได้
  • สามารถจัดการงานเปลี่ยนแปลงฐานข้อมูลแบบ idempotent ได้ จึงมีประโยชน์ต่อการซิงก์สคีมาอย่างเสถียร

ภาพรวมของ sqldef

  • sqldef เป็นเครื่องมือ CLI ที่เปรียบเทียบความแตกต่าง (diff) ของ SQL schema สองชุด วิเคราะห์ความต่าง และ สร้างคำสั่ง DDL จากผลลัพธ์
    • ผู้ใช้สามารถเปรียบเทียบสคีมาปัจจุบันกับสคีมาเป้าหมายเพื่อหาการเปลี่ยนแปลงที่จำเป็นได้โดยอัตโนมัติ
    • สามารถทำ migration ได้โดยใช้ไวยากรณ์ SQL DDL ทั่วไปตามเดิม
  • ระบุฐานข้อมูลที่รองรับไว้คือ MySQL, MariaDB, TiDB, PostgreSQL, SQL Server, SQLite3

ฟีเจอร์เดโมออนไลน์

  • บนเว็บไซต์มี Online Demo ให้ใช้งาน สามารถดูการเปลี่ยนแปลงของสคีมาได้แบบเห็นภาพ
    • ใช้ตัวเลือก “Enable DROP” เพื่อควบคุมว่าจะรวมคำสั่งลบหรือไม่
    • ในส่วน “Up (current → desired)” จะแสดงตัวอย่าง DDL เช่น การเพิ่มคอลัมน์ใหม่ การสร้างดัชนี และการเพิ่มข้อกำหนด
    • ในส่วน “Down (desired → current)” มีตัวอย่างการเปลี่ยนแปลงย้อนกลับ เช่น การลบข้อกำหนด

วิธีการทำงาน

  • เดโมออนไลน์ใช้ WebAssembly build ของ sqldef เพื่อเปรียบเทียบความแตกต่าง (diff) ของ SQL schema ภายในเบราว์เซอร์
    • คำนวณความต่างระหว่างสคีมาสองชุด และสร้างคำสั่ง DDL ที่จำเป็นโดยอัตโนมัติจากผลลัพธ์
    • สามารถดูซอร์สของ WebAssembly build ได้ผ่านลิงก์ไปยังที่เก็บบน GitHub

1 ความคิดเห็น

 
GN⁺ 2026-02-10
ความคิดเห็นจาก Hacker News
  • ถ้าต้องการการรองรับที่ครอบคลุมกว่าสำหรับ Postgres ลองดู pgschema ที่ผมทำไว้ได้
    ตอนแรกเมื่อหน้าร้อนปีที่แล้วผมคิดว่ามันเสร็จค่อนข้างสมบูรณ์แล้ว แต่หลังจากแก้ ปัญหากว่า 100 รายการ ที่ผู้ใช้รายงานเข้ามาในช่วง 6 เดือน ผมก็ได้รู้ว่าตัวเองมองโลกสวยแค่ไหน

    • เป็นเครื่องมือที่เจ๋งมาก ทีมเราน่าจะลองทำ PoC ด้วยกัน
      อยากรู้ว่ารองรับการตรวจหาความไม่สอดคล้องกันข้ามหลายคลัสเตอร์ฐานข้อมูลด้วยไหม
    • ทำให้นึกถึง Migra
    • ดูเหมาะกับการย้ายสคีมา แต่สงสัยว่าถ้าต้องย้ายข้อมูลจริง ๆ จะจัดการ update/insert อย่างไร
    • pg_roll ของ Xata ก็น่าจะเป็นอีกทางเลือกที่ควรพิจารณา
  • ลองทดสอบกับ SQLite แล้วพบว่าสำหรับมิเกรชันที่ยากอย่างการเพิ่มข้อจำกัด foreign key ให้ตารางเดิม มันสร้าง SQL ที่ใช้ไม่ได้
    ตัวอย่างเช่น ไวยากรณ์แบบ ALTER TABLE books ADD CONSTRAINT fk_books_author FOREIGN KEY (author_id) REFERENCES authors (id) ไม่ได้รับอนุญาตใน SQLite
    ดูเอกสารที่เกี่ยวข้องได้ที่ SQLite ALTER TABLE

    • สรุปว่าถ้าจะเพิ่ม foreign key ต้อง ลบคอลัมน์แล้วเพิ่มกลับเข้าไปใหม่ ใช่ไหม?
  • ผมใช้ Atlas
    ทั้งแนวทางแบบอิงมิเกรชันและแบบอิงสคีมาต่างก็มีข้อดีข้อเสีย เลยใช้ทั้งสองแบบควบคู่กันในโปรเจกต์เดียว
    แบบอิงสคีมาช่วยให้พัฒนาได้เร็วขึ้น ส่วนแบบอิงมิเกรชันช่วยให้ การปล่อยขึ้นระบบมั่นใจได้มากกว่า

    • ผม Ariel จากทีม Atlas การใช้แบบ declarative ในเครื่อง local และแบบ versioned ในสภาพแวดล้อมจริงควบคู่กันเป็นรูปแบบที่พบได้บ่อย
      Atlas สร้างมิเกรชันให้อัตโนมัติใน PR ดังนั้นนักพัฒนาส่วนใหญ่จึงไม่ต้องจัดการเวิร์กโฟลว์แบบ versioned เองโดยตรง
      เอกสารที่เกี่ยวข้อง: Declarative vs Versioned Workflows, Atlas Action
    • ผมเองก็ไปเจอ Atlas หลังจากดู sqldef กับทางเลือกอื่น ๆ
      ผมชอบที่มันรองรับ migration flow แบบชัดเจน อยากรู้ให้แน่ชัดว่าจะมีการเปลี่ยนแปลงอะไรถูกนำไปใช้ก่อน deploy จริง
  • สงสัยว่ามีเครื่องมือดี ๆ ที่รองรับ background migration ไหม
    เช่น เพิ่มคอลัมน์ชั่วคราวที่ nullable ให้กับตารางขนาดใหญ่ จากนั้นให้โค้ดใหม่เริ่มเขียนข้อมูลลงคอลัมน์นั้น แล้วค่อยเติมข้อมูลเดิมเป็นชุด ๆ ในเบื้องหลัง สุดท้ายจึงเปลี่ยนให้เป็น non-nullable
    ถ้ามีเครื่องมือที่ทำให้แสดงการเปลี่ยนแปลงเชิงกระบวนการแบบนี้ในรูป declarative และสามารถ รีวิว·ทดสอบ ไปพร้อมกับโค้ดได้ก็น่าจะดีมาก
    ตอนนี้ส่วนใหญ่ยังจัดการด้วย สคริปต์ชั่วคราวกับคู่มือ deploy แบบ manual

    • ปกติผมเขียน schema migration เอง แต่ส่วนใหญ่ใช้ grate
      ตั้งค่าในสภาพแวดล้อมพัฒนาได้ง่าย และมีตัวอย่างอย่าง FastEndpoints-SqlJobQueues
  • เครื่องมือนี้เจ๋งมาก
    มันทำให้ผมเลิกทำ โปรเจกต์งานอดิเรก ที่กำลังจะสร้างฟีเจอร์เดียวกันได้เลย
    แทนที่จะทำอันนั้น ผมคงไปเริ่มโปรเจกต์ใหม่อีกอันที่มีคนแก้ไปแล้วราว 100 ครั้ง — อย่างเช่นเครื่องมือง่าย ๆ ที่คอยมอนิเตอร์ log ของ systemd แล้วส่งอีเมลเมื่อเกิด error

  • ดีใจที่นี่ไม่ใช่ migration manager อีกตัว แต่เป็น เครื่องมือเล็ก ๆ ที่มีประโยชน์
    ให้ความรู้สึกเหมือนเข้ามาอุดจุดอ่อนของ SQL ได้ดี ถ้าเป็นแบบ declarative เหมือน Spanner DDL ได้ก็คงดี
    บน Postgres ผมพยายามทำให้สคริปต์สคีมาเป็นแบบ idempotent โดยเริ่มด้วย CREATE TABLE IF NOT EXISTS แล้วแยก ALTER ไว้ต่างหากเมื่อต้องเพิ่มคอลัมน์ใหม่
    แต่พอเวลาผ่านไปสคริปต์ก็เริ่มซับซ้อนขึ้น และเมื่อทุกอย่างนิ่งแล้วก็ค่อยเก็บกวาดคำสั่ง ALTER
    ถ้าต้อง restore จากแบ็กอัปเก่า เครื่องมือแบบนี้น่าจะช่วยปรับความเข้ากันได้ให้ตรงกันได้เร็ว

  • อยากรู้ว่าเทียบกับ Entity Framework หรือ sqitch/liquibase แล้วเป็นอย่างไร
    ผมเข้าใจแนวทางแบบ declarative แต่สำหรับ DB production ขนาดใหญ่ มิเกรชันไม่ได้เป็นเรื่อง declarative ล้วน ๆ
    ตัวจัดการสคีมาที่ดีในอุดมคติควรเข้าใจ ต้นทุนของ query และกลยุทธ์ลด downtime
    การเพิ่มคอลัมน์หรือเปลี่ยนดัชนีอาจทำให้เกิดการสแกนทั้งตารางได้

    • ปัญหาที่ใหญ่กว่านั้นคือบางครั้งข้อมูลเองก็เป็นส่วนหนึ่งของมิเกรชัน
      เช่น ถ้าจะแยก Fullname ออกเป็น FirstName และ LastName การทำ diff อย่างเดียวจะแสดงได้แค่ครึ่งเดียว
      ใน EF Core จะใช้เมธอด Up/Down เพื่อจัดการ การแปลงที่ย้อนกลับได้
      เลยสงสัยว่าถ้าไม่มีแนวคิดแบบนี้จะจัดการการแปลงข้อมูลอย่างไร
  • พวกเราเคยสร้างเครื่องมือแปลงของตัวเองที่อิง XML
    XML แยกวิเคราะห์ได้ง่ายกว่า SQL ดังนั้นเราจึงเปรียบเทียบสคีมาที่นิยามใน XML กับฐานข้อมูล แล้วใช้เฉพาะการเปลี่ยนแปลงที่จำเป็น
    เราใช้ Sybase SQLAnywhere และเมื่อต้องเพิ่มหรือลบคอลัมน์ในกรณีที่มี materialized view พัวพันอยู่ ความซับซ้อนจะสูงเพราะต้องสร้าง view และ index ใหม่
    เพราะแบบนั้นเราจึงใส่กลไกป้องกันไว้ โดยอนุญาตให้ลบคอลัมน์ได้เฉพาะเมื่อระบุชัดเจนเท่านั้น และเปลี่ยนชนิดข้อมูลได้เฉพาะกรณีที่ปลอดภัย
    มันทำให้การมิเกรตในสภาพแวดล้อมติดตั้งแบบ on-premises หลายร้อยแห่ง ง่ายมาก
    แค่แก้ XML แล้วเครื่องมือจะจัดการที่เหลือให้เอง และยังเพิ่มความสามารถใหม่ได้เมื่อจำเป็น

  • ใน SQLite การจัดการการลบคอลัมน์ยังทำได้ไม่ดี
    แม้เวอร์ชันใหม่ ๆ จะเพิ่งเพิ่ม DROP COLUMN เข้ามา แต่บนอุปกรณ์ส่วนใหญ่ก็ยังไม่รองรับอยู่ดี
    ในตัวอย่างมีการเพิ่ม x integer not null แล้วลอง DROP แต่กลับขึ้นแค่ข้อความ “-- Skipped”
    วิธีมาตรฐานคือ สร้างตารางชั่วคราว คัดลอกข้อมูล แล้วสลับแทนที่ แต่เครื่องมือนี้ไม่ได้ทำให้โดยอัตโนมัติ
    ถ้ามี constraint เข้ามาเกี่ยวข้องก็เป็นจุดที่พลาดได้ง่าย เลยค่อนข้างน่าเสียดาย
    สุดท้ายถ้าจัดการได้แค่งานง่าย ๆ ก็รู้สึกว่าทำเองด้วยมืออาจดีกว่า

  • เครื่องมือนี้ดูเหมือนจะมีประโยชน์แค่กับ ฐานข้อมูลว่างเปล่า
    มันจัดการ data migration ไม่ได้ และใช้ไม่ได้กับตารางที่มีข้อมูลจริงในกรณีอย่างการเปลี่ยนคอลัมน์ JSONB ให้เป็นรูปแบบที่มีโครงสร้าง หรือกรณีลบคอลัมน์แล้วทำ reverse migration จนสร้าง ADD COLUMN … NOT NULL เป็นต้น