Tôi muốn có toàn bộ lịch sử của một trường văn bản lớn do người dùng chỉnh sửa, được lưu trữ bằng Django.Làm thế nào để làm toàn bộ lịch sử văn bản ở Django?
Tôi đã nhìn thấy các dự án:
Tôi đã một use-case đặc biệt mà có lẽ nằm ngoài phạm vi những gì những dự án này cung cấp. Hơn nữa, tôi cảnh giác với việc tài liệu, thử nghiệm và cập nhật những dự án này tốt như thế nào. Trong mọi trường hợp, đây là vấn đề tôi phải đối mặt:
Tôi đã là một người mẫu, likeso:
from django.db import models
class Document(models.Model):
text_field = models.TextField()
trường văn bản này có thể lớn - hơn 40k - và tôi muốn có một tính năng tự động lưu mà tiết kiệm lĩnh vực này cứ 30 giây một lần. Điều này có thể làm cho cơ sở dữ liệu khó sử dụng lớn, rõ ràng, nếu có rất nhiều tiết kiệm ở 40k mỗi (có lẽ vẫn còn 10k nếu nén). Giải pháp tốt nhất tôi có thể nghĩ là giữ sự khác biệt giữa phiên bản đã lưu gần nhất và phiên bản mới.
Tuy nhiên, tôi lo lắng về các điều kiện chủng tộc liên quan đến cập nhật song song. Có hai điều kiện chủng tộc khác biệt mà tôi suy nghĩ (thứ hai nghiêm trọng hơn nhiều so với lần đầu tiên):
HTTP giao dịch đua điều kiện: Người dùng A và User B X0 tài liệu yêu cầu và thực hiện thay đổi cá nhân, sản xuất Xa và Xb. Xa được cứu, sự khác biệt giữa X0 và Xa là "Xa-0" ("ít không"), Xa bây giờ được lưu trữ như là phiên bản chính thức trong cơ sở dữ liệu. Nếu Xb sau đó lưu lại, nó ghi đè Xa, diff là Xb-a ("b less a").
Trong khi không lý tưởng, tôi không quá lo ngại về hành vi này. Các tài liệu được ghi đè lên nhau, và người dùng A và B có thể không biết lẫn nhau (mỗi tài khoản đã bắt đầu bằng tài liệu X0), nhưng lịch sử vẫn giữ nguyên tính toàn vẹn.
Điều kiện cuộc đua đọc/cập nhật cơ sở dữ liệu: Điều kiện chủng tộc có vấn đề là khi Xa và Xb lưu cùng lúc với X0. Sẽ có (pseudo-) mã gì đó như:
def save_history(orig_doc, new_doc): text_field_diff = diff(orig_doc.text_field, new_doc.text_field) save_diff(text_field_diff)
Nếu xA và xB cả đọc X0 từ cơ sở dữ liệu (ví dụ orig_doc là X0), sự khác biệt của họ sẽ trở thành Xá-0 và XB-0 (như trái ngược với Xê-ri được xê-ri hóa sau đó Xb-a, hoặc tương đương Xb-0 rồi Xa-b). Khi bạn cố gắng vá các diff khác nhau để tạo ra lịch sử, nó sẽ thất bại trên cả hai bản vá Xa-0 hoặc Xb-0 (cả hai đều áp dụng cho X0). Tính toàn vẹn của lịch sử đã bị xâm phạm (hoặc có nó?).
Một giải pháp có thể là thuật toán điều chỉnh tự động, phát hiện các sự cố này xuất bản. Nếu việc xây dựng lại lịch sử thất bại, người ta có thể giả định rằng một điều kiện chủng tộc đã xảy ra, và vì vậy áp dụng các bản vá lỗi cho các phiên bản trước của lịch sử cho đến khi nó thành công.
Tôi rất vui khi có một số phản hồi và đề xuất về cách giải quyết vấn đề này.
Ngẫu nhiên, trong chừng mực đó là một cách hữu ích ra, tôi đã lưu ý rằng Django số nguyên tử sẽ được thảo luận ở đây:
- Django: How can I protect against concurrent modification of data base entries, và ở đây:
- Atomic operations in Django?
Cảm ơn bạn vui lòng.
Không phải là câu trả lời đầy đủ vì vậy tôi sẽ đưa nó vào phần bình luận. Thử nhìn vào trường Django RCS: http://code.google.com/p/django-rcsfield/ Hệ thống kiểm soát phiên bản để quản lý trường. Bài viết về cách làm việc: http://lethain.com/entry/2008/oct/15/setting-up-django-rcsfield/ –