2010-03-29 14 views
19

Muszę utworzyć kod w PHP, który pozwoli mi zachować historię aktualizacji rekordów w bazie danych MySQL, dzięki czemu mogę znaleźć datę wydania starej wersji.Jak zachować historię aktualizacji rekordów w MySQL?

Oto przykład tego, co ja właściwie chcę achive: http://en.wikipedia.org/w/index.php?title=Tunisia&action=history

Dane są głównie Liczby, że wzmianka o firmy do generowania raportów oraz wyodrębnienie indeksów.

Mam zamiar używać codeigniter, ponieważ jest to prostota i szukam pomysłu na framework lub projekt opensource, który używa tego samego podejścia, aby zachować historię modyfikacji w bazie danych.

Odpowiedz

1

To nie jest rejestrowanie faktycznych aktualizacji SQL. Rejestruje aktualizacje danych. W efekcie będzie przechowywać każdą wersję strony, a po prostu domyślnie dostarczać najnowszą. Kod SQL, który był używany, nie został zapisany.

W ten sposób będziesz musiał przyjąć podobne podejście. Za każdym razem, gdy dane ulegną zmianie, musisz ustalić, w jaki sposób zmieniły się dane, i zapisać dane "łatki". Najprawdopodobniej najlepiej będzie przechowywać najnowszą wersję, a potem trzeba przejść przez wszystkie łatki, aby się do niej dostać. Oznacza to, będzie można zobaczyć coś podobnego

! 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' 

Każda z tych zmian musiałyby być przechowywane ze znacznikiem czasu lub gdy gdzie zrobić. Będziesz także musiał opracować własny scheeme do przechowywania zmian danych.

Innym prostszym rozwiązaniem jest użycie silnika wiki, który zapewnia wszystkie wymagane funkcje, jeśli chcesz pracować na stronie internetowej. Być może trzeba będzie poświęcić trochę czasu, aby działało lepiej dla twoich potrzeb, pozwalając ludziom edytować go z bardziej skończonego widoku, a nie surowego wiki.

2

Musisz użyć dodatkowej warstwy między aplikacją a bazą danych. Możesz zrobić bardzo proste na własną rękę (zamiast wywoływania funkcji mysql_query możesz wywołać utworzoną przez ciebie funkcję, która owija ją i która śledzi aktualizacje) lub użyć istniejącej ORM. W pseudo-kodzie

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; 
} 

A potem w aplikacji zadzwonić my_mysql_query zamiast mysql_query. Możesz sprawdzić, czy tabela jest tą, którą chcesz śledzić, i możesz skopiować wiersz w kopii oryginalnej tabeli.

Jeśli używasz Doctrine ORM, możesz użyć jego Event Listeners, aby uzyskać to, co chcesz.

7

Jednym z prostych sposobów na zachowanie historii wersji jest utworzenie zasadniczo identycznej tabeli (np. Z sufiksem _version). Obie tabele będą miały pole wersji, które dla głównej tabeli zwiększasz o każdą aktualizację, którą wykonujesz. Tabela wersji miałby złożony klucz podstawowy na (id, version).

Za każdym razem, gdy aktualizujesz rzeczywistą tabelę, INSERT nowy wiersz w tabeli wersji ze zduplikowanymi danymi. Ilekroć chcesz znaleźć historię wersji, wszystko, co musisz zrobić, to coś takiego jak SELECT * FROM content_version WHERE id = CONTENT_ID ORDER BY version.

Jeśli używasz czegoś takiego jak Doctrine ORM, ma to zachowanie, które robi to automatycznie za pomocą detektorów zdarzeń.Możesz to sprawdzić tutaj: http://www.doctrine-project.org/documentation/manual/1_2/en/behaviors#core-behaviors:versionable

+5

dlaczego nie jest tak: "tabela główna" zawiera tylko tabele 'id' i' version_id' 'version' zawiera wszystkie dane? – Shaheer

+0

Dzięki @Shaheer Spróbuję tego. – Eric

+0

@Shaheer, ponieważ większość zapytań jest sprzeczna z bieżącymi danymi, więc dzielenie historii na oddzielną tabelę zapewnia, że ​​te zapytania nie powodują obniżenia wydajności, ponieważ tabela staje się * n * razy większa. Wielkość * n * zależy od tego, jak często rekordy są aktualizowane. –

1

Jeśli dobrze rozumiem, zapisujesz tylko "liczbę" w określonej tabeli, a chcesz historię wersji tego numeru?

Powiedziałbym: napisz swój datamodel, aby zawierał historię tego numeru. Więc nie tylko rejestrujesz najnowszą wartość tej liczby, ale także zachowujesz wszelkie poprzednie wartości.

Prostym sposobem na to jest poprzez tabelę z następujących dziedzin:

  • id
  • companyId
  • liczba
  • datownik

Jeśli chcesz wiedzieć aktualny numer, po prostu wykonaj:

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

Jeśli chcesz zobaczyć wszystkie wersje po prostu zrobić:

SELECT * FROM table WHERE companyId = X 
+0

To pulpit nawigacyjny, który próbuję przenieść z prostego pliku Excel. Ponieważ nie znam formy ORM, wolę napisać własny kod. – Proxium

+0

Co może być dobre :) –

+1

WYBIERZ * Z tabeli WHERE companyId = X ORDER BY timestamp DESC LIMIT 1 – DarkSide

15

Najprostszym rozwiązaniem (w zależności od konkretnych potrzeb) byłoby prawdopodobnie dodaj na aktualizacji/insert/delete spust do stolika, więc może wykonać dodatkowe rejestrowanie po wstawieniu/zaktualizowaniu/usunięciu danych. W ten sposób zostaną objęte nawet ręczne interwencje na serwerze db ...

Aby uzyskać więcej informacji, sprawdź numer http://dev.mysql.com/doc/refman/5.1/en/triggers.html.

6

Istnieje framework open source (MIT license) do budowy aplikacji internetowych opartych na bazach danych CRM i ERP. Można pobrać epesi z http://epe.si/ dostępne również na SourceFroge: http://sourceforge.net/projects/epesi/

epesi na CRUD silnik - w Record Browser - posiada bardzo wydajną historii rekord, jak również inne funkcje, takie jak zaawansowany system uprawnień (do pola poziom) i wiele więcej.

Pojedynczy zestaw rekordów przechowuje dane w maksymalnie 10 tabelach i jest agnostyczny (używa PHPAdoDB). Tabela o nazwie recordset_data przechowuje "surowe" dane i historię zmian jest przechowywana w 2 dodatkowych tabelach: recordset_edit_history i recordset_edit_history_data.edit_history

rekordu ma następującą strukturę:

  • identyfikator (klucz podstawowy dla tabeli, index)
  • edytowane (datownik: 2008-05-14 15:18:15)
  • Edited przez: (ID użytkownika) edit_history_data

rekordu ma następującą strukturę:

  • edit_id = identyfikator z historii edycji
  • pole = nazwa zmienionego pola
  • old_value = wartość zmienionego pola.

Jest to bardzo szybki i wydajny silnik, który przechowuje zmiany nie w zapisie, ale na jednym poziomie pola.

Powiązane problemy