2013-07-29 36 views
6

Tôi phải lưu trữ dữ liệu như bài viết vào cơ sở dữ liệu mysql và nếu một bài viết được sửa đổi, tôi phải lưu phiên bản cũ để có thể khôi phục lại. Tôi đã tìm thấy một số câu hỏi và bài đăng tương tự về chủ đề này, nhưng tôi không chắc chắn, giải pháp nào là tốt nhất để giải quyết vấn đề.Thực hành tốt nhất cho hệ thống phiên bản dữ liệu mysql

Dưới đây là bảng "điều" cơ bản cho sự hiểu biết tốt hơn:

bài viết (id, tên, văn bản)

Đối với tôi, có hai cách tiếp cận khác nhau cho việc này:

Tiếp cận 1

Lưu trữ dữ liệu và mọi phiên bản của một bài viết trong bảng "bài viết" và thêm cột "phiên bản" và "trạng thái". Trong phiên bản tôi lưu trữ số phiên bản tăng dần của bài viết. Bài viết hoạt động được "trạng thái" 1 và những người khác "trạng thái" 2.

Pro:

  • Chỉ có một bảng là cần thiết

  • Một phiên bản mới là một chèn của dữ liệu mới và chỉ cập nhật trạng thái "trạng thái" của cột cũ

Con's

  • bảng rất lớn (có thể truy vấn chậm ???)

Tiếp cận 2

Thêm "phiên bản" để "điều" và lưu trữ chỉ có các dữ liệu tích cực vào bảng " bài viết". Các phiên bản cũ của dữ liệu được lưu trữ/di chuyển đến bảng mới "articles_versioned".

Pro:

  • Chỉ có dữ liệu hợp lệ thực tế là trong bảng "bài viết"

Con của

  • Dublication bảng

So. Tôi đã quên một aproach tốt? Cách xử lý dữ liệu liên quan trong các bảng khác (như hình ảnh, v.v.)?

+1

Điều này thường được gọi là "thay đổi dữ liệu chụp" (CDC). Google cho nó: http://www.google.com/search?aq = f & gcx = w & sourceid = chrome & ie = UTF-8 & q = mysql + change + data + capture & safe = active – duffymo

+0

Bạn thậm chí không cần cập nhật trạng thái trước đó, chỉ cần chọn id cao nhất cho bài viết đó – Anigel

+0

Trạng thái là nếu tôi muốn quay lại phiên bản trước – bernhardh

Trả lời

3

Lựa chọn của tôi sẽ là biến thể của phương pháp tiếp cận 2. Chữ đậm chỉ ra các trường trong khóa chính.

  • Bạn chèn mỗi bài viết trong một bảng articles_versioned (id, timestamp, tên, văn bản)
  • bảng thứ hai của bạn là articles (id, dấu thời gian, [tên, văn bản]). Lưu ý cách dấu thời gian không phải là chính; tên và văn bản có thể được nhân rộng hoặc bạn có thể sử dụng kết hợp với articles_versioned (sẽ nhanh chóng vì id và dấu thời gian là khóa chính)
  • articles_versioned có kích hoạt khi chèn vào hàng được chèn vào và sao chép nó trên articles
  • Để khôi phục phiên bản cụ thể của một bài viết bạn sửa đổi bảng articles.

Những lợi thế của phương pháp này là:

  1. Bạn nhận được miễn phí khác thông tin (ngày và thời gian của bài báo) trong bảng của bạn, mà bạn có thể cần nào
  2. Bạn không cần để truy vấn cơ sở dữ liệu để có được ngày hiện tại. Nếu bạn sử dụng phiên bản, bạn phải.
  3. Mã của bạn không phải chèn bài viết vào hai bảng. Bạn chỉ cần chèn vào articles_versioned và đọc từ articles, db sẽ quản lý dữ liệu di chuyển khi bạn chèn nó qua trình kích hoạt, tránh bất kỳ vấn đề nhất quán nào.

Con của

  1. Trong một môi trường nặng nề đồng thời, hai phiên bản có thể được chèn vào thời điểm rất giống nhau, vì vậy một trong số họ có thể thất bại. Đây không phải là vấn đề khi chèn các bài viết do người dùng viết (rất khó có thể đưa ra các dấu thời gian chính xác vào những ngày này). Nếu bạn không chỉ định dấu thời gian trong câu lệnh INSERT của mình, nhưng thay vào đó bạn đặt trường ngày giờ để có thời gian hiện tại làm giá trị mặc định, bạn có thể tránh hoàn toàn sự cố này.

Để trả lời phần còn lại của câu hỏi. Phương pháp tiếp cận 1 sẽ không dẫn đến các truy vấn dài hơn miễn là bạn thêm chỉ mục vào trạng thái. Điều này chỉ có ý nghĩa nếu bạn có xu hướng có nhiều phiên bản khác nhau của mỗi bài viết; miễn là bạn có 2 phiên bản cho mỗi bài viết trung bình hoặc ít hơn, chỉ mục sẽ chỉ làm chậm bạn xuống, và cách tiếp cận 2 sẽ không nhanh hơn một cách hợp lý (tôi vẫn khuyên bạn nên tiếp cận vì nó đơn giản hóa mã, kể từ khi khôi phục phiên bản không yêu cầu chuyển trạng thái cho hai hàng).

Tài nguyên có liên quan, như hình ảnh, phải theo một phiên bản tương tự. Tôi cho rằng bạn đang lưu chúng trên hệ thống tập tin; thay vì lưu chúng bằng tên thật của chúng, hãy sử dụng một bảng (id, image_name) để cung cấp cho từng hình ảnh một id, sau đó lưu hình ảnh là -id-.jpg. Trường image_name sẽ giúp bạn biết tên tệp gốc là gì (nếu bạn quan tâm đến điều đó). Bằng cách này, bạn có thể phiên bản hình ảnh giống như cách bạn sử dụng phiên bản bài viết và trong các bài viết bạn sẽ sử dụng một cái gì đó như <img src="-id-.jpg"> mà bạn biết sẽ vẫn tồn tại mãi mãi.

+0

Xin lỗi câu trả lời này đến trễ một chút, nhưng có thể hữu ích cho người khác. – p91paul

+0

Đi cho rằng khảo cổ học cồng chiêng? – Strawberry

+1

Thôi nào, tôi đã rơi vào câu hỏi này trong khi tìm kiếm một cái gì đó khác, và tôi bắt đầu trả lời trước khi nhận thấy ngày câu hỏi :). Tôi nghĩ rằng nó vẫn có thể có liên quan. – p91paul