2012-07-02 7 views
5

Jakie są ogólne strategie projektowania DB, aby zachować historię zmian? Gdyby to był tylko jeden stół, z którym miałem do czynienia, myślę, że nie byłoby to takie trudne. Po prostu zapisz każdą aktualizację jako nowy rekord w tabeli. Ostatnia płyta zawsze będzie ostatnią wersją.Projektowanie bazy danych: jak śledzić historię?

Ale kiedy dane są przechowywane w wielu tabelach, jaki jest dobry sposób zaprojektowania tego, aby można było śledzić wersje?

Odpowiedz

2

Wolę mieć dodatkową tabelę historyczną dla każdej tabeli wersji. Ta sama struktura co tabela główna z dodatkowymi polami z time_from i time_to. Przezroczyste wypełnienie wyzwalaczy. time_to najnowszej aktualizacji ustawionej na dalszą przyszłość.

państwa na określonym momencie mogą być pobierane z kwerendy tak:

SELECT * FROM user_history 
WHERE time_from >= '2012-02-01' AND time_to <= '2012-02-01' 

Jak dla mnie, przechowywanie historii wewnątrz głównej tabeli generalnie nie jest dobrym pomysłem, ponieważ wymaga skomplikowanych warunków podczas pobierania lub łączenia aktualnych danych .

+0

Więc główne tabele mają najnowsze dane. Wówczas tabele "historyczne" mają kopie każdej wersji? Czy to nie znosi normalizacji? – StackOverflowNewbie

+0

Tak, pojawia się denormalizacja, jest to cena za prostotę (stany historyczne są generowane automatycznie z prostego 'INSERT',' DELETE', 'UPDATE' na głównej tablicy) i wydajność ostatniej wersji (na przykład główna tabela ma indeksy oparte na danych, podczas gdy historia ma indeksy daty). Jeśli najnowsza wersja nie jest główną wersją do pracy, to podejście może cierpieć z powodu zerwanej normalizacji. – vearutop

0

Włącz MySQL's binary logging i po prostu użyj tego.

+0

Myślę, że to pytanie dotyczy historii, którą można przypisać. – MaxSem

0

Używam podejścia, w którym każdy obiekt, z którym mam do czynienia, zawiera co najmniej jedną instancję o nazwie , w której przechowuję dane, które z czasem ulegają zmianie. Zazwyczaj takie tabele są zgodne z następującą koncepcją:

  • mają przyrostek _HISTORY w nazwie;
  • mają 2 dodatkowe pola, start_dt i end_dt, wskazujące czas życia instancji obiektu;
  • start_dt jest NOT NULL, end_dt może być NULL, co oznacza, że ​​instancja jest aktualna i nie jest ograniczona w swoim czasie;
  • możliwe jest wstawić zmian przyszłych przestarzałe, że chcesz nową nazwę firmy, aby być aktywowane z 1/Jan-2013, wtedy trzeba ustawić end_dt bieżącej instancji 31/Dec-2012 23:59:59 i wstawić nowy rekord z start_dt z 1/Jan-2013 00:00:00;
  • Czasami dodam również pole revision, jeśli konieczne jest śledzenie wersji.

Aby mieć odpowiednie ograniczenia RI z takim projektem, zawsze mam 2 tabele dla wersjonowanych obejcts. Powiedzmy, za Customer obejct Mam następujący zestaw tabel:

customer (customer_id INTEGER, PRIMARY KEY (customer_id)); 
customer_history (customer_id INTEGER, start_dt TIMESTAMP, end_dt TIMESTAMP, 
        name VARCHAR(50), sex CHAR(1), ..., 
        PRIMARY KEY (customer_id, start_dt)); 
customer_bank_history (customer_id INTEGER, start_dt TIMESTAMP, end_dt TIMESTAMP, 
         bank_id INTEGER, iban VARCHAR(34)); 

we wszystkich innych miejscach używam customer(customer_id) zbudować kluczy obcych.Odpytywanie rzeczywistych danych klienta jest prosty:

SELECT c.customer_id, ch.name, ch.sex 
    FROM customer c 
    JOIN customer_history ch ON c.customer_id = ch.customer_id 
     AND now() BETWEEN ch.start_dt AND coalesce(end_dt, now()); 

Dlaczego wolę taką konstrukcję:

  1. Mam wersjonowany instancji obiektu na poziomie bazy danych w fazie projektowania;
  2. Muszę przechowywać mniej tabel;
  3. Nie można uzyskać historii utraconej na wypadek, gdyby ktoś upuścił/zablokował jakiekolwiek wyzwalacze;
  4. Mogę łatwo planować i utrzymywać przyszłe zmiany.

Mam nadzieję, że to ci pomoże.

0

Najtrudniejsza część to nie wersja tabel "bazowych" - po prostu zmieniasz wersje osobno, tak jak w pojedynczej tabeli.

Najtrudniejszą częścią jest śledzenie połączeń między nimi.

To, jak dokładnie to zrobisz, zależy od wymagań konkretnego projektu. Oto przykład tego, jak sales orders could be "historized", ale istnieje wiele innych możliwych wariantów.

0

Datadiff. Śledzenie zmian wersji DB zasilanej interfejsem API.

Pełne ujawnienie:

Zbudowałem Datadiff. Potrzebowałem rozwiązania, które zapewniło historię wizualną modelu danych w MongoDB, aby pomóc w obsłudze produktu SASS. Będzie działać również z bazami danych SQL.

Możesz użyć wykonać podstawowe zapytania z notacją key:val. tzn. id:123