Razem ze współpracownikami wdaliśmy się w debatę na temat najlepszego sposobu przechowywania danych historycznych. Obecnie w niektórych systemach używam oddzielnej tabeli do przechowywania danych historycznych i zachowuję oryginalną tabelę dla bieżącego, aktywnego rekordu. Powiedzmy, że mam FOO tabeli. W moim systemie wszystkie aktywne rekordy trafią do FOO, a wszystkie historyczne rekordy do FOO_Hist. Użytkownik może aktualizować wiele różnych pól w FOO, więc chcę mieć dokładne konto wszystkich aktualizowanych. FOO_Hist przechowuje dokładnie te same pola, co FOO, z wyjątkiem automatycznego zwiększania wartości HIST_ID. Za każdym razem FOO jest aktualizowana, ja wykonać instrukcji INSERT INTO FOO_Hist podobny do: insert into FOO_HIST select * from FOO where id = @id
.
Mój współpracownik mówi, że to zły projekt, ponieważ nie powinienem mieć dokładnej kopii tabeli z powodów historycznych i powinienem po prostu wstawić kolejny rekord do aktywnej tabeli z flagą wskazującą, że jest to do celów historycznych.
Czy istnieje standard postępowania z przechowywaniem danych historycznych? Wydaje mi się, że nie chcę zaśmiecać moich aktywnych rekordów wszystkimi moimi historycznymi rekordami w tej samej tabeli, biorąc pod uwagę, że może to być znacznie ponad milion rekordów (myślę długoterminowo).
Jak Ty lub Twoja firma radzicie sobie z tym?
Używam MS SQL Server 2008, ale chciałbym, aby odpowiedź była ogólna i arbitralna dla każdego DBMS.
źródło
Nie sądzę, aby istniał jakiś szczególny standardowy sposób, ale pomyślałem, że dorzucę możliwą metodę. Pracuję w Oracle i naszej wewnętrznej strukturze aplikacji internetowych, która wykorzystuje XML do przechowywania danych aplikacji.
Używamy czegoś, co nazywa się modelem Master - Detail, który w najprostszy sposób składa się z:
Master TableNa przykład nazywana
Widgets
często po prostu zawierającą identyfikator. Często zawiera dane, które nie zmieniają się w czasie / nie są historyczne.Na przykład tabela szczegółów / historii o nazwie
Widget_Details
zawierająca co najmniej:Zasadniczo więc encja zaczyna się od jednego wiersza we wzorcu i jednego wiersza w szczegółach. Szczegół mający NULL datę końcową i STATUS_CONTROL „C”. Kiedy następuje aktualizacja, bieżący wiersz jest aktualizowany tak, aby miał END_DATETIME aktualnego czasu, a status_control jest ustawiony na NULL (lub „A”, jeśli jest to preferowane). W tabeli szczegółów tworzony jest nowy wiersz, wciąż powiązany z tym samym wzorcem, ze status_control „C”, identyfikatorem osoby dokonującej aktualizacji i nowymi danymi przechowywanymi w kolumnie XMLDATA.
To jest podstawa naszego modelu historycznego. Logika tworzenia / aktualizacji jest obsługiwana w pakiecie Oracle PL / SQL, więc po prostu przekazujesz funkcji bieżący identyfikator, swój identyfikator użytkownika i nowe dane XML, a wewnętrznie wykonuje wszystkie aktualizacje / wstawienia wierszy, aby przedstawić to w modelu historycznym . Czasy rozpoczęcia i zakończenia wskazują, kiedy ten wiersz w tabeli jest aktywny dla.
Przechowywanie jest tanie, zazwyczaj nie USUWAMY danych i wolimy zachować ścieżkę audytu. Dzięki temu możemy zobaczyć, jak w danym momencie wyglądały nasze dane. Indeksując status_control = 'C' lub używając widoku, bałagan nie jest dokładnie problemem. Oczywiście twoje zapytania muszą być brane pod uwagę, zawsze powinieneś używać aktualnej (NULL end_datetime i status_control = 'C') wersji rekordu.
źródło
Myślę, że podejście jest prawidłowe. Tabela historyczna powinna być kopią tabeli głównej bez indeksów, upewnij się, że masz również znacznik czasu aktualizacji w tabeli.
Jeśli wkrótce spróbujesz innego podejścia, napotkasz problemy:
źródło
W SQL Server 2016 i nowszych wersjach dostępna jest nowa funkcja zwana tabelami czasowymi, która ma na celu rozwiązanie tego problemu przy minimalnym wysiłku ze strony programisty . Koncepcja tabeli temporalnej jest podobna do zmiany przechwytywania danych (CDC), z tą różnicą, że tabela czasowa wyodrębniła większość rzeczy, które trzeba było wykonać ręcznie, jeśli korzystałeś z CDC.
źródło
Zmień przechwytywanie danych: https://docs.microsoft.com/en-us/sql/relational-databases/track-changes/about-change-data-capture-sql-server?view=sql-server-2017
Jest obsługiwany w SQL Server 2008 R2, może być obsługiwany w SQL Server 2008.
źródło
to pytanie jest dość stare, ale ludzie wciąż pracują nad tym problemem. więc jeśli używasz oracle, możesz być zainteresowany flashbackami oracle: http://docs.oracle.com/cd/B28359_01/appdev.111/b28424/adfns_flashback.htm
źródło
Chciałem tylko dodać opcję, której zacząłem używać, ponieważ używam Azure SQL, a funkcja wielu tabel była dla mnie zbyt kłopotliwa. Dodałem wyzwalacz wstawiania / aktualizowania / usuwania w mojej tabeli, a następnie przekonwertowałem zmianę przed / po na json przy użyciu funkcji „FOR JSON AUTO”.
To zwraca reprezentację JSON dla rekordu przed / po zmianie. Następnie przechowuję te wartości w tabeli historii z sygnaturą czasową, kiedy nastąpiła zmiana (przechowuję również identyfikator bieżącego rekordu, którego dotyczy problem). Dzięki procesowi serializacji mogę kontrolować sposób wypełniania danych w przypadku zmian w schemacie.
Dowiedziałem się o tym z tego linku tutaj
źródło
Możesz po prostu podzielić tabele, nie?
„Strategie tabel i indeksów partycjonowanych przy użyciu programu SQL Server 2008 Gdy rozmiar tabeli w bazie danych rośnie do setek gigabajtów lub więcej, ładowanie nowych danych, usuwanie starych i utrzymywanie indeksów może być trudniejsze. Tylko sam rozmiar tabeli powoduje, że takie operacje trwają znacznie dłużej. Nawet dane, które muszą zostać załadowane lub usunięte, mogą być bardzo duże, przez co operacje INSERT i DELETE na tabeli są niepraktyczne. Oprogramowanie bazy danych Microsoft SQL Server 2008 zapewnia partycjonowanie tabel, aby ułatwić zarządzanie takimi operacjami ”.
źródło
Prawdziwe pytanie brzmi: czy musisz używać danych historycznych i aktywnych danych razem do raportowania? Jeśli tak, trzymaj je w jednej tabeli, podziel na partycje i utwórz widok dla aktywnych rekordów do wykorzystania w aktywnych zapytaniach. Jeśli potrzebujesz spojrzeć na nie tylko od czasu do czasu (aby zbadać kwestie leagalne lub inne), umieść je w osobnej tabeli.
źródło
JOIN
dwie tabele w kilku raportach historycznych, czy też trudniej jest zmodyfikować każdą wstawienie / aktualizację / usunięcie pojedynczej tabeli, aby mieć świadomość problemów historycznych? W rzeczywistości dziennik audytu zawierałby nawet aktualne dane w tabeli historii, więc bieżąca tabela nie powinna być nawet potrzebna w raporcie.Inną opcją jest archiwizacja danych operacyjnych [codziennie | co godzinę | cokolwiek]. Większość silników baz danych obsługuje wyodrębnianie danych do archiwum .
Zasadniczo chodzi o to, aby utworzyć zaplanowane zadanie systemu Windows lub CRON
Wiele silników baz danych SQL jest dostarczanych z narzędziem, którego można użyć w tym celu. Na przykład podczas korzystania z MySQL w systemie Linux w zadaniu CRON można użyć następującego polecenia, aby zaplanować wyodrębnianie:
źródło
Znam ten stary post, ale chciałem tylko dodać kilka punktów. Standardem takich problemów jest to, co działa najlepiej w danej sytuacji. zrozumienie potrzeby takiego przechowywania i potencjalnego wykorzystania danych historycznych / audytowych / śledzenia zmian jest bardzo ważne.
Audyt (cel bezpieczeństwa) : Użyj wspólnej tabeli dla wszystkich tabel podlegających audytowi. zdefiniuj strukturę do przechowywania nazwy kolumny, przed i po polach wartości.
Archive / Historical : w przypadkach takich jak śledzenie poprzedniego adresu, numeru telefonu itp. Utworzenie oddzielnej tabeli FOO_HIST jest lepsze, jeśli schemat tabeli aktywnych transakcji nie zmienia się znacząco w przyszłości (jeśli tabela historii musi mieć taką samą strukturę). jeśli przewidujesz normalizację tabel, dodanie / usunięcie kolumn w celu zmiany typu danych, przechowuj dane historyczne w formacie xml. zdefiniuj tabelę z następującymi kolumnami (ID, Data, Wersja schematu, XMLData). to z łatwością obsłuży zmiany schematu. ale musisz radzić sobie z xml, a to może spowodować pewien stopień komplikacji przy pobieraniu danych.
źródło
Możesz użyć funkcji inspekcji serwera MSSQL. Od wersji SQL Server 2012 znajdziesz tę funkcję we wszystkich wersjach:
http://technet.microsoft.com/en-us/library/cc280386.aspx
źródło
Możesz utworzyć zmaterializowane / zindeksowane widoki w tabeli. W zależności od wymagań możesz wykonać pełną lub częściową aktualizację widoków. Zobacz to, aby utworzyć mview i log. Jak tworzyć zmaterializowane widoki w SQL Server?
źródło