Thủ thuật
Giải pháp lưu trữ lịch sử văn bản trên SQLite bằng cách nén JSON với zlib/zstd
(giờ Việt Nam)
Tóm tắt AI
Simon Willison đề xuất kỹ thuật lưu trữ toàn bộ lịch sử chỉnh sửa văn bản vào SQLite bằng cách gom các phiên bản vào mảng JSON, sau đó nén bằng zlib hoặc zstd để tối ưu dung lượng lưu trữ.
Bản dịch AI
Nghiên cứu các nguyên mẫu lưu trữ lịch sử văn bản nén trên SQLite — Các nguyên mẫu lưu trữ lịch sử văn bản nén trên SQLite so sánh `WholeBlobHistoryStore`, cơ chế ghi đè một blob lịch sử nén cho mỗi lần chỉnh sửa, với `ChunkedHistoryStore`, cơ chế đóng gói các đoạn (chunk) nén để cải thiện khả năng mở rộng cho các lịch sử dài. Cả hai đều bảo toàn văn bản và dấu thời gian trước đó, mặc định bỏ qua các thay thế không thay đổi, và tuần tự hóa các tác vụ ghi bằng lệnh `BEGIN IMMEDIATE` để đảm bảo cập nhật nguyên tử (atomic).
Tôi luôn quan tâm đến các tùy chọn lưu trữ lịch sử sửa đổi trong cơ sở dữ liệu quan hệ. Trong lúc đi dạo, tôi đã nảy ra một ý tưởng mới: tại sao không lấy toàn bộ văn bản của mọi phiên bản trước đó đưa vào một mảng JSON lớn chứa các chuỗi, rồi áp dụng nén zlib hoặc zstd cho toàn bộ khối đó? Chắc chắn cách này sẽ nén rất hiệu quả nhờ vào tất cả các chuỗi lặp lại.
Chế độ giọng nói GPT‑Live mới trong ứng dụng ChatGPT trên iPhone đã trở nên thực sự tốt, vì vậy tôi đã thảo luận về nguyên mẫu này với nó. Bạn vẫn chưa thể chia sẻ URL của các cuộc hội thoại giọng nói, nhưng đây là những gì tôi đã nói, được sao chép từ bản ghi dưới dạng một luồng suy nghĩ liền mạch:
Tôi có một ý tưởng thú vị về một lược đồ để lưu tất cả các phiên bản trước đó của một đoạn văn bản được chỉnh sửa liên tục trong một cột của cơ sở dữ liệu SQLite theo cách hiệu quả nhất có thể. Được rồi, tôi đã từng xây dựng những hệ thống kiểu này trong quá khứ, và việc tìm ra một cách hiệu quả để làm điều này luôn rất khó khăn. Cách dễ nhất là bạn có một hàng cho mỗi bản sao trước đó của giá trị chuỗi cũ. Nhưng nếu đó là một tài liệu dài, ví dụ như 20 kilobyte dữ liệu, thì có nghĩa là mỗi lần chỉnh sửa lại thêm 20 kilobyte dữ liệu vào cơ sở dữ liệu, đúng không? Vì vậy, điều tôi đang nghĩ đến là, ừm, nén dữ liệu sẽ hoạt động rất hiệu quả, phải không? Nếu bạn gộp tất cả những phiên bản khác nhau đó, mọi phiên bản của tài liệu này từ đầu đến cuối, nếu bạn áp dụng một thuật toán nén tốt cho chúng, nó sẽ loại bỏ phần lớn các văn bản dư thừa. Vì vậy, điều tôi đang nghĩ là tại sao không dùng một cơ chế thực sự đơn giản? Có một cột lịch sử trên bảng này và nó là một blob, một BLOB nên nó lưu trữ dữ liệu nhị phân, và sau đó bạn chỉ cần đưa vào đó một mảng văn bản JSON đã nén bằng Zlib hoặc thậm chí là ZSTD của tất cả các tài liệu trước đó. Và có lẽ bạn sẽ có hai cột, đúng không? Bạn sẽ có một cột là mảng JSON kỳ diệu chứa văn bản đó, và bạn có cột thứ hai là một mảng JSON chứa các dấu thời gian (timestamp) và cột đó không cần phải nén chút nào, đúng không? Một dấu thời gian có thể chỉ là một mảng các số nguyên, đúng không? Các số nguyên Unix. Đó chính là toàn bộ lược đồ.
Sau đó, tôi dừng chế độ giọng nói và nhập lời nhắc văn bản sau đây cho GPT-5.6 Sol Pro:
Hãy sử dụng Python và xây dựng các nguyên mẫu thử nghiệm dựa trên ý tưởng này.
Nó đã xử lý trong 38 phút và đưa ra câu trả lời này cùng với các tệp bạn thấy trong thư mục này.
Cách tiếp cận này hoạt động rất hiệu quả! 1.000 lần sửa đổi mô phỏng cho một tài liệu tạo ra 20,4 MB văn bản sửa đổi thô, sau khi nén thành mảng JSON bằng Zstandard chỉ còn 80,3 KB.
Để tránh chi phí giải nén và nén lại toàn bộ mảng sau mỗi lần chỉnh sửa, Sol đề xuất chia lịch sử thành nhiều hàng, mỗi hàng chứa tối đa 128 lần sửa đổi hoặc 3MB dữ liệu JSON chưa nén.
Bài viết được AI dịch và tổng hợp tự động từ Simon Willison Blog. Liên kết bài gốc ở phía trên. Dữ liệu đồng bộ qua API công khai được ghi nguồn tại AI HOT (canonical) ↗. AIHOT.vn luôn dẫn nguồn đầy đủ — nếu bạn thấy điểm cần chỉnh sửa, hãy gửi ý kiến tại trang phản hồi.