- Công cụ CLI để quản lý migration cơ sở dữ liệu bằng cách so sánh khác biệt (diff) giữa các SQL schema
- Có thể quản lý schema RDBMS bằng cú pháp SQL DDL thông thường
- Hỗ trợ các cơ sở dữ liệu chính như MySQL, MariaDB, TiDB, PostgreSQL, SQL Server, SQLite3
- Trên website có bản demo trực tuyến dùng bản build WebAssembly để trải nghiệm tính năng so sánh schema và tạo DDL
- Có thể quản lý các thay đổi cơ sở dữ liệu theo cách idempotent, hữu ích cho việc đồng bộ schema ổn định
Tổng quan về sqldef
- sqldef là công cụ CLI so sánh sự khác biệt (diff) giữa hai SQL schema, phân tích khác biệt và tạo câu lệnh DDL dựa trên đó
- Người dùng có thể so sánh schema hiện có với schema mục tiêu để tự động suy ra các thay đổi cần thiết
- Có thể thực hiện migration bằng cách dùng nguyên vẹn cú pháp SQL DDL thông thường
- Các cơ sở dữ liệu được hỗ trợ gồm MySQL, MariaDB, TiDB, PostgreSQL, SQL Server, SQLite3
Tính năng demo trực tuyến
- Website cung cấp Online Demo, cho phép kiểm tra trực quan các thay đổi schema
- Có thể kiểm soát việc có bao gồm lệnh xóa hay không thông qua tùy chọn “Enable DROP”
- Trong mục “Up (current → desired)”, hiển thị các ví dụ DDL như thêm cột mới, tạo index, thêm ràng buộc
- Trong mục “Down (desired → current)”, cung cấp ví dụ thay đổi theo chiều ngược lại như xóa ràng buộc
Cách hoạt động
- Demo trực tuyến sử dụng bản build WebAssembly của sqldef để thực hiện so sánh khác biệt (diff) giữa các SQL schema ngay trong trình duyệt
- Tính toán sự khác biệt giữa hai schema, rồi tự động tạo các câu lệnh DDL cần thiết từ kết quả đó
- Có thể kiểm tra mã nguồn bản build WebAssembly thông qua liên kết kho lưu trữ GitHub
1 bình luận
Ý kiến trên Hacker News
Nếu muốn mức độ bao phủ toàn diện hơn cho Postgres, có thể tham khảo pgschema do tôi làm
Mùa hè năm ngoái tôi đã nghĩ nó khá hoàn thiện, nhưng sau khi xử lý hơn 100 issue do người dùng báo trong suốt 6 tháng, tôi mới nhận ra mình ngây thơ đến mức nào
Không biết nó có hỗ trợ tính năng kiểm tra sai lệch giữa nhiều cụm cơ sở dữ liệu hay không
Tôi đã thử với SQLite, nhưng ở những migration khó như thêm ràng buộc khóa ngoại vào bảng hiện có, nó tạo ra SQL không hợp lệ
Ví dụ, cú pháp như
ALTER TABLE books ADD CONSTRAINT fk_books_author FOREIGN KEY (author_id) REFERENCES authors (id)không được phép trong SQLiteTài liệu liên quan xem tại SQLite ALTER TABLE
Tôi dùng Atlas
Cả cách tiếp cận dựa trên migration và dựa trên schema đều có ưu và nhược điểm, nên tôi dùng song song cả hai trong cùng một project
Cách dựa trên schema giúp tăng tốc độ phát triển, còn cách dựa trên migration cho phép triển khai đáng tin cậy hơn
Vì Atlas tự động tạo migration trong PR, nên phần lớn developer không phải trực tiếp xử lý workflow quản lý phiên bản
Tài liệu liên quan: Declarative vs Versioned Workflows, Atlas Action
Tôi thích việc nó hỗ trợ migration flow một cách tường minh. Tôi muốn biết chính xác thay đổi nào sẽ được áp dụng trước khi triển khai thực tế
Tôi thắc mắc có công cụ tốt nào hỗ trợ background migration không
Ví dụ, thêm một cột nullable tạm thời vào bảng lớn, để code mới bắt đầu ghi dữ liệu vào cột đó, rồi ở nền điền dữ liệu cũ theo lô, và cuối cùng chuyển nó thành non-nullable
Sẽ rất hay nếu có công cụ cho phép biểu diễn những thay đổi mang tính thủ tục như vậy theo kiểu khai báo, đồng thời review·test cùng với code
Hiện tại phần lớn vẫn xử lý bằng script tạm và hướng dẫn triển khai thủ công
Nó dễ thiết lập trong môi trường phát triển, và cũng có ví dụ như FastEndpoints-SqlJobQueues
Công cụ này thật sự rất hay
Nhờ nó mà tôi có thể dừng project sở thích của mình vốn định làm cùng chức năng
Thay vào đó tôi sẽ bắt đầu một project mới xử lý một vấn đề khác cũng đã được giải quyết khoảng 100 lần rồi — ví dụ như một công cụ đơn giản theo dõi log systemd và gửi email khi có lỗi
Tôi thấy vui vì đây không phải là một migration manager nữa, mà là một công cụ nhỏ nhưng hữu ích
Nó mang lại cảm giác bù đắp tốt cho những điểm yếu của SQL. Tôi cũng nghĩ sẽ tuyệt nếu nó có tính khai báo như Spanner DDL
Trong Postgres, tôi cố giữ các script schema ở trạng thái idempotent. Bắt đầu với
CREATE TABLE IF NOT EXISTS, và khi thêm cột mới thì đểALTERriêngNhưng theo thời gian script trở nên phức tạp, và khi đã ổn định thì tôi dọn dẹp các câu lệnh ALTER
Nếu cần khôi phục một bản backup cũ, công cụ kiểu này có thể giúp nhanh chóng đưa khả năng tương thích về đúng trạng thái
Tôi tò mò không biết nó so với Entity Framework hay sqitch/liquibase thế nào
Tôi hiểu cách tiếp cận khai báo, nhưng với DB production quy mô lớn thì migration không chỉ đơn thuần là khai báo
Một trình quản lý schema lý tưởng phải hiểu chi phí truy vấn và chiến lược giảm thiểu downtime
Việc thêm cột hoặc thay đổi index có thể gây ra quét toàn bộ bảng
Ví dụ nếu tách Fullname thành FirstName và LastName thì diff đơn thuần chỉ mô tả được một nửa
Trong EF Core, các phương thức Up/Down xử lý biến đổi có thể đảo ngược
Tôi tò mò không biết họ xử lý việc biến đổi dữ liệu thế nào nếu không có khái niệm này
Chúng tôi đã tự làm một công cụ biến đổi dựa trên XML
Vì XML dễ parse hơn SQL, nên chúng tôi so sánh schema được định nghĩa trong XML với DB và chỉ áp dụng những thay đổi cần thiết
Chúng tôi dùng Sybase SQLAnywhere, và khi materialized view bị liên quan thì việc thêm/xóa cột có độ phức tạp cao vì phải tạo lại view và index
Vì thế chúng tôi thêm cơ chế an toàn để việc xóa cột chỉ được phép khi chỉ định rõ ràng, còn đổi kiểu chỉ thực hiện trong những trường hợp an toàn
Nó giúp migration trở nên rất đơn giản trong hàng trăm môi trường cài đặt on-premise
Chỉ cần sửa XML là công cụ sẽ tự xử lý, và có thể bổ sung tính năng khi cần
Trên SQLite, việc xử lý xóa cột không tốt
Chỉ đến các phiên bản gần đây mới có DROP COLUMN, nhưng trên phần lớn thiết bị thì vẫn chưa được hỗ trợ
Trong ví dụ, tôi thêm
x integer not nullrồi thử DROP, nhưng chỉ thấy thông báo “-- Skipped”Cách chuẩn là tạo bảng tạm, sao chép dữ liệu rồi thay thế, nhưng công cụ này không tự động hóa việc đó
Đây là phần rất dễ mắc lỗi khi có ràng buộc liên quan, nên khá đáng tiếc
Cuối cùng tôi nghĩ nếu chỉ xử lý được các tác vụ dễ thì làm thủ công còn hơn
Công cụ này có vẻ chỉ hữu ích với cơ sở dữ liệu trống
Nó không xử lý được data migration, và với những bảng có dữ liệu thực tế — ví dụ chuyển cột JSONB sang dạng có cấu trúc, hoặc khi xóa cột rồi reverse migration thì sinh
ADD COLUMN … NOT NULL— thì không thể dùng được