2010-03-29 23 views
19

Tôi phải tạo một mã trong PHP cho phép tôi giữ lịch sử các bản cập nhật bản ghi trong cơ sở dữ liệu MySQL để tôi có thể tìm thấy theo ngày một bản sửa đổi cũ.Làm cách nào để giữ lịch sử cập nhật bản ghi trong MySQL?

Dưới đây là ví dụ về những gì tôi actualy muốn đạt được: http://en.wikipedia.org/w/index.php?title=Tunisia&action=history

Dữ liệu chủ yếu là số mà chúng tôi ghi lại về công ty để tạo ra các báo cáo và giải nén chỉ số.

Tôi dự định sử dụng trình viết mã để đơn giản và tôi đang tìm ý tưởng về một khung công tác hoặc dự án mã nguồn mở sử dụng cùng một phương pháp để giữ lịch sử sửa đổi trong cơ sở dữ liệu.

Trả lời

1

Điều đó không ghi nhật ký các bản cập nhật SQL thực tế. Nó đang ghi lại các cập nhật của dữ liệu. Nó sẽ có hiệu lực được lưu trữ mỗi sửa đổi của trang, và chỉ cung cấp một phiên bản mới nhất theo mặc định. Mã SQL đã được sử dụng cho nó không được lưu trữ.

Vì vậy, bạn sẽ phải thực hiện một phương pháp tương tự. Mỗi lần dữ liệu thay đổi, bạn sẽ cần phải tìm ra cách dữ liệu đã thay đổi và lưu trữ dữ liệu 'vá' này. Bạn có thể sẽ lưu trữ tốt nhất phiên bản mới nhất, thay vì sau đó phải làm việc thông qua tất cả các bản vá lỗi để có được nó. Điều này có nghĩa là bạn sẽ có thể nhìn thấy một cái gì đó như

! created file 
* added data to cell D4 'product descript' D5 'set of pens' E5 '£5.99' 
* added data to cell D6 'toaster' E5 '£10' 
& changed data in cell D4 'Product Description' 

Mỗi thay đổi này sẽ cần được lưu trữ bằng dấu thời gian hoặc khi chúng được thực hiện. Bạn cũng sẽ cần phải làm việc ra scheeme của riêng bạn để lưu trữ các thay đổi dữ liệu.

Một giải pháp đơn giản hơn, là sử dụng công cụ wiki, cung cấp tất cả các chức năng bạn muốn, nếu bạn sẵn sàng làm việc trong một trang web. Bạn có thể cần phải dành một chút thời gian để làm cho nó hoạt động tốt hơn cho nhu cầu của bạn, cho phép mọi người chỉnh sửa nó từ một cái nhìn hoàn chỉnh hơn, thay vì sau đó là một wiki thô.

2

Bạn phải sử dụng một lớp bổ sung giữa ứng dụng của bạn và db. Bạn có thể tự mình thực hiện rất đơn giản (thay vì gọi trực tiếp mysql_query bạn gọi một hàm do bạn thực hiện để kết thúc nó và theo dõi cập nhật) hoặc sử dụng một số ORM hiện có. Trong pseudo-code

my_mysql_query($query){ 
    if($query is an update){ 
     //Log stuff before query 
    } 
    $r = mysql_query($query); 

    if ($r && $query is an update){ 
     //Log stuff after query 
    } 
    return $r; 
} 

Và sau đó trong ứng dụng của bạn, bạn gọi my_mysql_query thay vì mysql_query. Bạn có thể kiểm tra xem bảng có phải là bảng bạn muốn theo dõi hay không và bạn có thể sao chép hàng đó trong bản sao của bảng gốc.

Nếu bạn sử dụng Doctrine ORM, bạn có thể sử dụng số Event Listeners để nhận được những gì bạn muốn.

7

Một cách đơn giản để giữ lịch sử phiên bản là tạo cơ bản một bảng giống hệt nhau (ví dụ: với hậu tố _version). Cả hai bảng sẽ có một trường phiên bản, cho bảng chính bạn tăng cho mỗi lần cập nhật bạn làm. Bảng phiên bản sẽ có khóa chính kết hợp trên (id, version).

Bất cứ khi nào bạn thực hiện cập nhật trên bảng thực tế, bạn cũng INSERT một hàng mới trong bảng phiên bản có dữ liệu trùng lặp. Bất cứ khi nào bạn muốn tìm lịch sử phiên bản, tất cả những gì bạn cần làm là một cái gì đó chẳng hạn như SELECT * FROM content_version WHERE id = CONTENT_ID ORDER BY version.

Nếu bạn sử dụng một cái gì đó như Doctrine ORM, nó có một hành vi thực hiện điều này cho bạn tự động thông qua người nghe sự kiện.Bạn có thể xem tại đây: http://www.doctrine-project.org/documentation/manual/1_2/en/behaviors#core-behaviors:versionable

+5

tại sao không đi như thế này: 'bảng chính' chỉ chứa' id' và 'version_id'' phiên bản bảng chứa tất cả dữ liệu? – Shaheer

+0

Cảm ơn @Shaheer Tôi sẽ thử cái này. – Eric

+0

@Shaheer vì hầu hết các truy vấn đều chống lại dữ liệu hiện tại, vì vậy việc tách lịch sử thành một bảng riêng biệt đảm bảo rằng các truy vấn đó không nhận được hình phạt hiệu suất khi bảng trở thành * n * lần lớn. Làm thế nào lớn * n * sẽ phụ thuộc vào mức độ thường xuyên các bản ghi được cập nhật. –

1

Nếu tôi hiểu chính xác, bạn chỉ lưu một "số" trong một bảng cụ thể và bạn muốn lịch sử sửa đổi của số đó?

Tôi muốn nói: viết datamodel của bạn để nó chứa lịch sử của số đó. Vì vậy, bạn không chỉ ghi lại giá trị mới nhất của số đó mà còn giữ lại bất kỳ giá trị nào trước đó.

Một cách đơn giản để làm điều này là bởi có một bảng với các lĩnh vực sau:

  • id
  • companyId
  • số
  • timestamp

Nếu bạn muốn biết số hiện tại, chỉ cần

SELECT * FROM table WHERE companyId = X ORDER BY timestamp DESC LIMIT 1 

Nếu bạn muốn xem tất cả các phiên bản chỉ làm:

SELECT * FROM table WHERE companyId = X 
+0

Đó là trang tổng quan mà tôi đang cố di chuyển từ một tệp Excel đơn giản. Vì tôi không quen thuộc với cách ORM, tôi thích viết mã của riêng mình hơn. – Proxium

+0

Điều nào có thể là điều tốt :) –

+1

CHỌN * TỪ bảng Ở ĐÂU companyId = X THỨ TỰ B timNG dấu thời gian DESC LIMIT 1 – DarkSide

15

Giải pháp đơn giản nhất (tùy theo nhu cầu cụ thể của bạn) có lẽ sẽ là thêm một ngày cập nhật/chèn/xóa kích hoạt để bàn của bạn, vì vậy bạn có thể thực hiện ghi nhật ký thêm khi dữ liệu được chèn/cập nhật/xóa. Bằng cách đó, ngay cả các biện pháp can thiệp thủ công trên db cũng sẽ được bảo vệ ...

Kiểm tra http://dev.mysql.com/doc/refman/5.1/en/triggers.html để biết thêm thông tin.

6

Có khung nguồn mở (giấy phép MIT) để xây dựng các loại ứng dụng web dựa trên cơ sở dữ liệu CRM và ERP. Bạn có thể tải EPESI từ http://epe.si/ sẵn cũng trên SourceFroge: http://sourceforge.net/projects/epesi/

EPESI của CRUD động cơ - các Ghi Trình duyệt - có một lịch sử ghi lại rất hiệu quả cũng như tính năng khác như hệ thống cho phép tiên tiến (xuống một cánh đồng mức độ) và nhiều hơn nữa.

Một bản ghi duy nhất lưu trữ dữ liệu trong tối đa 10 bảng và đó là cơ sở dữ liệu bất khả tri (sử dụng PHPAdoDB). Bảng có tên là recordset_data lưu trữ dữ liệu "thô" và lịch sử thay đổi được lưu trữ trong 2 bảng bổ sung: recordset_edit_historyrecordset_edit_history_data.edit_history

Record có cấu trúc sau:

  • ID (Khóa chính cho bảng này, chỉ số)
  • Chỉnh sửa trên (timestamp: 2008/05/14 15:18:15)
  • Edited bằng cách: (user ID) edit_history_data

Record có cấu trúc sau:

  • edit_id = ID từ lịch sử chỉnh sửa
  • trường = tên của trường đã được thay đổi
  • old_value = giá trị của trường đã thay đổi.

Nó là một động cơ rất nhanh và hiệu quả và nó lưu trữ những thay đổi không có trên hồ sơ nhưng trên một cấp trường đơn.

Các vấn đề liên quan