2013-06-11 15 views
7

Ostatnio myślę o najlepszych praktykach z przechowywaniem danych historycznych w bazie danych MySQL. Na razie każda wersja tabeli ma dwie kolumny - valid_from i valid_to, obie: DATETIME. Zapisy z aktualnymi danymi mają valid_from wypełniony dzień utworzenia. Gdy aktualizuję ten wiersz, wypełniam valid_to z datą aktualizacji i dodam nowy rekord z valid_from taki sam, jak valid_to w poprzednim wierszu - proste elementy. Ale wiem, że stół będzie ogromny bardzo szybko, więc pobieranie danych może być bardzo powolne.
Chciałbym wiedzieć, czy masz jakieś praktyki z przechowywaniem danych historycznych?Najlepsze praktyki z danymi historycznymi w bazie danych MySQL

+2

Wykonaj część archiwizacji, tzn. Przenieś dane historyczne do innej tabeli i zachowaj bieżącą bieżącą tabelę. –

+1

@PradeepPati to ogromnie skomplikuje aplikację, jeśli potrzebuje zapytań, które mogą wybrać zarówno dane historyczne, jak i bieżące. Jednak może on zrobić kilka poglądów, aby "scalić" historyczne i bieżące tabele. – Kamil

+0

@Kamil To naprawdę nie będzie komplikować niczego, a raczej zachować rozsądną aplikację. potrzebujesz historii, przechodzisz do tabeli historii, potrzebujesz aktualnych danych, przechodzisz do bieżącej tabeli. –

Odpowiedz

7

Powszechnym błędem jest martwienie się o "duże" tabele i wydajność. Jeśli możesz korzystać z indeksów, aby uzyskać dostęp do danych, nie ma znaczenia, czy masz 1000 z 1000000 rekordów - przynajmniej nie tak, jak mógłbyś zmierzyć. Wspomniany wzór jest powszechnie używany; to świetny projekt, w którym czas jest kluczową częścią logiki biznesowej.

Na przykład, jeśli chcesz dowiedzieć się, jaka była cena przedmiotu w momencie, w którym klient złożył zamówienie, można przeszukiwać rekordy produktów, których wartość valid_from < order_date i valid_until jest null lub> order_date jest zdecydowanie najprostsze rozwiązanie.

Nie zawsze tak jest - jeśli przechowujesz dane tylko w celu archiwizacji, bardziej sensowne może być tworzenie tabel archiwum. Jednak musisz być pewien, że czas jest naprawdę nie jest częścią logiki biznesowej, w przeciwnym razie trudność wyszukiwania wielu tabel będzie znacząca - wyobraź sobie, że musisz przeszukiwać tabelę produktów LUB tabelę product_archive za każdym razem, gdy chcesz się dowiedzieć o cenie produktu w momencie złożenia zamówienia.

0

To nie jest kompletna odpowiedź, tylko kilka sugestii.

Można dodać indeksowane pole boolowskie, takie jak is_valid. To powinno poprawić wydajność przy dużej tabeli z historycznymi i aktualnymi rekordami.

Ogólnie rzecz biorąc - przechowywanie danych historycznych w tabeli seprate może skomplikować aplikację (wystarczy wyobrazić sobie złożoność zapytania, które ma uzyskać dane z mieszanymi rekordami bieżącymi i historycznymi ...).

Dzisiejsze komputery są naprawdę szybkie. Myślę, że powinieneś porównać/przetestować wydajność z pojedynczą tabelą i osobną tabelą dla historycznych rekordów.

Dodatkowo - spróbuj przetestować swój sprzęt, aby zobaczyć, jak szybko jest MySQL z dużymi tabelami, aby określić sposób projektowania bazy danych. Jeśli jest zbyt wolny dla ciebie - możesz dostroić konfigurację MySQL (zacznij od zwiększania pamięci podręcznej/pamięci RAM).

0

Zbliżam się do zakończenia aplikacji, która robi dokładnie to. Większość moich indeksów indeksuje najpierw pola klucza, a następnie pole valid_to, które jest ustawione na NULL dla bieżących rekordów, umożliwiając łatwe i natychmiastowe znalezienie bieżących rekordów. Ponieważ większość moich aplikacji dotyczy operacji w czasie rzeczywistym, indeksy zapewniają szybką wydajność. Od czasu do czasu ktoś musi zobaczyć historyczne rekordy, w tym przypadku jest hit wydajności, ale z testowania nie jest tak źle, ponieważ większość zapisów nie ma bardzo wielu zmian w ciągu ich życia.

W przypadkach, w których można mieć znacznie więcej utraconych rekordów różnych kluczy niż bieżące rekordy, może zapłacić indeks do wartości powyżej przed dowolnych kluczowych pól.