2008.10.23 06:06
pamiętać co było, wiedzieć co jest

Zastanawiam się, czy nie powinno się projektować baz danych inaczej, niż to się zwykle robi. Wyobraźmy sobie, że chcemy przechowywać informacje o uczniach jeżdżących na wycieczki szkolne. Pierwszy pomysł jest taki, żeby zrobić trzy tabelki: tabelkę "uczniowie", tabelkę "wycieczki" i łączącą je wiele do wielu tabelkę "uczestnictwa_uczniów_w_wycieczkach". Jak tak zrobimy, to zawsze będziemy mogli sprawdzić, jaki jest stan - na przykład na jakie wycieczki jest zapisany Janek Kowalski. Ale nie możemy sprawdzić, jaka była historia - kiedy Janek Kowalski zapisał się na wycieczkę, czy był w historii taki moment, że liczba osób zapisanych na wycieczkę zmalała, kto był zapisany na wycieczkę do Malborka 1 stycznia 2009 o 07:00 itp. A często takie rzeczy chcemy wiedzieć. Można zrobić dodatkową tabelkę, w której będziemy trzymać log wszystkich wydarzeń. Będziemy zapisywać w niej wszystkie wydarzenia - kto się zapisał, kto się wypisał, że zmieniono cenę wycieczki do Malborka itp. Będzie ona miała klucze obce do tabelek "wycieczki" i "uczniowie", dzięki czemu łatwo będzie można sprawdzić, jaka była historia danej wycieczki. To działa całkiem nieźle, ale jest z tym kilka problemów.

  1. Trzeba robić kupę trigerów, które każdą zmianę będą odnotowywać w logu wydarzeń. Potem i tak okazuje się, że ktoś jakiegoś trigera nie napisał, bo nie było czasu, i kiedy po roku trzeba odtworzyć, co się działo, nie da się.
  2. Informacja w logu wydarzeń i w tabelkach ze stanem dubluje się, więc może być sprzeczna.
  3. Skoro wydarzenia mają klucz obcy do uczniów, nie da się usunąć ucznia z bazy danych.
  4. Nie zawsze jest jasne - zwłaszcza w skomplikowanej bazie danych - z czym powinno być powiązane dane wydarzenie. Niektóre wydarzenia daleką drogą wpływają na różne rzeczy i nie zawsze osoba pisząca triger widzi, że wydarzenie "zmarł wychowawca klasy" powinno mieć klucz obcy do tabelki "autokary".

Mój pomysł brzmi: a żeby tak w bazie danych przechowywać tylko wydarzenia, a stan wydobywać widokami z wydarzeń? W tym przypadku pewnie stworzyłbym trzy tabelki: zmiany w uczniach, zmiany w wycieczkach, zmiany w uczestnictwach. Do tego stworzyłbym trzy widoki korzystające z tych tabelek: uczniowie, wycieczki i uczestnictwa. Takie rozwiązanie miałoby kupę zalet. Na przykład można by bez problemu odtworzyć sobie stan z danej chwili - wystarczyłoby do zapytania dodać "where data_wydarzenia <= ta_chwila". Można by łatwo sprawdzić, w których momentach zmieniał się koszt wycieczki. Zwykłe zapytania pisałoby się nadal prosto, bo można by korzystać z widoków uczniowie, wycieczki i uczestnictwa.

Tylko ciekawe, jakby było z wydajnością.



komentarze:
2008.10.23 11:58 ktp

imho dużo zależy od tego, co bardziej (i częściej) chcesz wiedzieć: co jest (wtedy wydajniejszy wariant 1), czy co się działo (wtedy wariant2)

a może tworzyć wariant mieszany - log zdarzeń, ale w regularnych odstępach czasu - dzień, tydzień, miesiąc... (zależy od bazy) zapamiętywać aktualny stan - wtedy szukając następnych stanów przeszukiwało by się tylko następujące po nim zdarzenia


2008.10.23 12:06 Piotrek

Pewnie, niestety, trzeba by zacząć od porobienia porównawczych prób wydajności.


2009.01.12 04:53 Piotrek

Prawie wyjaśnione. Trzeba w googlach wrzucić \"temporal databases\" i sobie doczytać. Tylko zwykle oni robią to trochę inaczej, niż według mojego pomysłu.



ksywa:

tu wpisz cyfrę cztery: (tu wpisz cyfrę cztery: (to takie zabezpieczenie antyspamowe))

komentarze wulgarne albo co mi się nie spodobają będę kasował


powrót na stronę główną

RSS