6

W przypadku korzystania z bazy danych znormalizowanej zgodnie z zasadami 6NF, w jaki sposób przechowujesz dane atrybutów historycznych?6NF i dane atrybutów historycznych

powiedzmy na przykład weźmiemy this example z @PerformanceDBA ale z następującym dodatkowym wymogiem:

Musimy przechowywania danych historycznych dla wszystkich naszych produktów, powinniśmy stanie po prostu wprowadzić datę i uzyskać migawka atrybutów produktu w tym konkretnym czasie.

Bardziej praktyczny przykład:
Załóżmy dysków i procesorów z powyższym przykładzie są wirtualne, a użytkownik może zmienić pojemność dysku do woli. W jaki sposób możemy zmienić bazę danych tak, abyśmy mogli pobrać atrybuty danego dysku w dowolnym czasie w przeszłości (oczywiście po jego dacie utworzenia), jednocześnie zachowując wystarczająco szybki podgląd 5NF.

miejsca Zastanawiam

  • Dodaj kolumnę timestamp „CHANGEDATE” do każdej tabeli atrybutów (Spowodowałoby to całkiem złożone zapytania z podzapytania i dołączenia do każdej tabeli atrybutów)
  • Utwórz osobną tabelę historii dla każdej tabeli atrybutów (może spowodować ogromną liczbę tabel, ponieważ mamy około 70 atrybutów rozłożonych na 20 typów produktów:)
  • Dodatkowo: dodać indeksowanego „aktualny” kolumny do każdej tabeli atrybutów przyspieszyć widok 5NF

Każda pomoc jest mile widziana!


Edit: wiem pojęcie czasowych baz danych, ale problemem jest to, że dla silnika bazy danych pracuję z (PostgreSQL) rozszerzenie czasowy nie jest jeszcze w pełni wdrożone. Wszelkie porady, jak to osiągnąć bez tymczasowych baz danych?

+1

Tylko po to, aby Cię ostrzec - poszedłem drogą NIE mając tabel historii i używając dat "od" i "do" w każdym rzędzie moich "podmiotów". To był największy błąd, który popełniłem i zamienił projekt w koszmar. Zajęło to przewodnictwo osoby, którą wymieniłeś, PerformanceDBA, aby sprawić, że bym naprawdę zrozumiał, czym naprawdę jest baza danych (to znaczy nie tylko wiadro dla obiektów). Od tego czasu przepisałem projekt, stosując bardziej tradycyjne podejście (tabele/widoki historii) i jest ono lepsze pod każdym względem. W porządku, nie ma wiele argumentów, ale szczegółowe informacje wymagałyby ogromnej ilości dokumentacji. – Mark

+1

To jest wpis, który pozwolił mi zmienić sposób, w jaki patrzę na bazy danych w ogóle (z punktu widzenia inżynierów oprogramowania, z punktu widzenia DBA): - http://stackoverflow.com/questions/4491173/historical- auditable-database - nie mówię, że nie należy robić tego, co zostało zasugerowane (używając "od" i "do" i bez tabel historii), ale dla mnie stworzyło to wielki bałagan, i nigdy nie zejdę z tym znowu droga. – Mark

Odpowiedz

9

Niedawno zatwierdzony standard SQL: 2011 zawiera funkcje, które pozwalają lepiej radzić sobie z tego rodzaju problemami niż kiedykolwiek wcześniej.

Nie, że będziesz w stanie zrobić wszystko, co chcesz robić na arenie czasowej, ale to, co zostało wprowadzone, jest rzeczywiście dość znaczącą poprawą.

Dobra prezentacja na ten temat jest pod numerem http://metadata-standards.org/Document-library/Documents-by-number/WG2-N1501-N1550/WG2_N1536_koa046-Temporal-features-in-SQL-standard.pdf.

Należy zauważyć, że w jego produkcie SQL jest tylko jeden dostawca, który ma uzasadnione wsparcie dla tych funkcji, a jeden z nich prawdopodobnie pracuje nad nim, a trzeci otworzył kanał głosowania dla swoich klientów.

Na stronie www.linkedin.com znajduje się również grupa dyskusyjna "Dane temporalne" poświęcona dokładnie temu tematowi.

EDYCJA próbuje adresować "Wszelkie porady, jak to osiągnąć bez tymczasowych baz danych?"

Nie dodawaj do swoich modeli tylko jednej kolumny typu data/czas. Pierwszy powód jest taki, jaki podałeś, a drugim powodem jest to, że to rozwiązanie jest również promowane przez nowy standard i ułatwi przejście do silników, które obsługują nowe funkcje, gdy są już dostępne:

Dodaj więc ZARÓWNO kolumnę początkową, jak i datę końcową/czas, NIE UMIESZCZAJCIE NIESTABILNYCH NOWYCH.Nowy standard wymaga tego ze względu na cechy czasowe Jeśli koniec-MIT (moment-w-czasie) jest wciąż nieznany, użyj najwyższej wartości odpowiedniego typu czasu, np. 9999-12-31.

Nie musisz "tworzyć oddzielnych tabel historii dla każdego atrybut "jest równie możliwe jest posiadanie "tabeli pojedynczych encji", która zachowuje "historię całego wystąpienia jednostki". Minusem jest to, że trudno będzie zapytać, kiedy zmiana nastąpiła w przypadku jakiegoś konkretnego atrybutu (ponieważ otrzymujesz nowe historyczne wiersze dla jakiejkolwiek zmiany dowolnego atrybutu, możliwe że kopiowanie o tę samą wartość atrybutu dla większości atrybutów). "Pojedynczy stół" może być chętnie konsumentem przestrzeni, "osobna historia dla każdego atrybutu" może być gorliwym konsumentem zapytań o czas procesora. Będzie to działanie równoważące, a gdzie równowaga jest precyzyjna, zależy od twojej konkretnej sytuacji.

Nie "dodawaj indeksowanej kolumny" aktualnej "do swoich tabel. Po pierwsze, nie pomogą ci przejść do nowych funkcji, gdy masz ich silnik, a po drugie, kolumny Y/N są bardzo złymi dyskryminatorami, a zatem bardzo słabymi kandydatami do indeksowania. Wolę dodać indeks początkowy lub końcowy do indeksu, można oczekiwać, że dadzą ci te same wygrane dla "bieżących" wierszy, i lepszą wygraną dla ostatnich wierszy, ilekroć będziesz musiał zapytać o te .

Jeśli chodzi o egzekwowanie ograniczeń baz danych, takich jak brak nakładania się w okresach w kluczach czasowych i uwzględnianie okresów w tymczasowym RI, to jesteś całkowicie sam. Zapisz kod potrzebny w wyzwalaczach lub SPROC lub kodzie aplikacji, w kolejności malejącej.

Czy to było bardziej pomocne?

+0

Dzięki, dowiedziałem się o tymczasowym rozszerzeniu dla postgresql (https://github.com/jeff-davis/PostgreSQL-Temporal/downloads), który wydaje się być tym, czego szukam. Pomogą w tym trochę bardziej praktyczne przykłady. – ChrisR

+0

To było bardzo pomocne! Dzięki za doskonałą poradę! – ChrisR