Najlepszy projekt dla tabeli bazy danych dziennika zmian / inspekcji? [Zamknięte]

114

Muszę utworzyć tabelę bazy danych, aby przechowywać inny dziennik zmian / inspekcję (gdy coś zostało dodane, usunięte, zmodyfikowane itp.). Nie muszę przechowywać szczególnie szczegółowych informacji, więc pomyślałem coś w stylu:

  • id (dla zdarzenia)
  • użytkownik, który go uruchomił
  • Nazwa wydarzenia
  • opis wydarzenia
  • sygnatura czasowa wydarzenia

Czy coś mi umyka? Oczywiście mogę nadal ulepszać projekt, chociaż nie planuję go komplikować (tworzenie innych tabel dla typów zdarzeń lub podobnych rzeczy nie wchodzi w rachubę, ponieważ jest to komplikacja dla moich potrzeb).

rcphq
źródło
Przeczytałem twoją odpowiedź i jestem zaskoczony, że nikt nie mówi o prawie. Wiem, że niektóre dokumenty prawne lub dobre praktyki wyjaśniają, w jaki sposób MUSIMY wdrożyć tabelę audytu (tylko do odczytu). Ale nie mam więcej informacji niż to. Po prostu wiem, że istnieje. Myślę o ścieżce audytu w CFR 21 część 11.
Bastien Vandamme

Odpowiedzi:

70

W projekcie, nad którym pracuję, dziennik audytu również zaczynał się od bardzo minimalistycznego projektu, takiego jak ten, który opisałeś:

event ID
event date/time
event type
user ID
description

Pomysł był ten sam: aby wszystko było proste.

Szybko jednak stało się oczywiste, że ten minimalistyczny projekt nie wystarczy. Typowy audyt sprowadzał się do takich pytań:

Who the heck created/updated/deleted a record 
with ID=X in the table Foo and when?

Aby więc móc szybko odpowiedzieć na takie pytania (za pomocą SQL), otrzymaliśmy dwie dodatkowe kolumny w tabeli audytu

object type (or table name)
object ID

Wtedy projekt naszego dziennika audytu naprawdę się ustabilizował (od kilku lat).

Oczywiście ostatnie „ulepszenie” działałoby tylko dla tabel, które miały klucze zastępcze. Ale zgadnij co? Wszystkie nasze stoliki, które warto sprawdzić, mają taki klucz!

Yarik
źródło
Jedynym problemem, jaki miałem z tym projektem (ścieżka audytu oparta na opisie), jest lokalizacja języka używanego w tej dziedzinie.
Sam Wilson
@Sam, nie widzę takiego problemu, jeśli wiadomość jest generowana przez system, po prostu użyj tutaj klucza do tłumaczenia;
JCM
4
@Hiru: Kiedy "mieszasz" dwa lub więcej odrębnych pojęć w jedną kolumnę, najczęściej prędzej czy później przyniesie to odwrotny skutek. Na przykład, jeśli „połączysz” typ zdarzenia i typ obiektu, wpłynie to na zapytania typu „pokaż rekordy dla wszystkich obiektów danego typu” i „pokaż rekordy dla wszystkich zdarzeń danego typu” (zapytań byłoby więcej skomplikowane i najprawdopodobniej działałyby znacznie wolniej).
Yarik
3
Oprócz tych kolumn można mieć dodatkową kolumnę dla ładunku opisu strukturalnego / zdarzenia strukturalnego . Ta kolumna zawierałaby szczegóły zdarzeń (o dowolnej złożoności) w formacie czytelnym dla komputera, XML / JSON. Łatwy do serializacji, do wykonywania zapytań (przynajmniej w Postgres / MSSQL), do rozumowania.
turdus-merula
1
@Benjamin: Odpowiedź jest w modelu domeny (czyli modelu biznesowym). Jeśli model pozwala na jednoczesne tworzenie encji (np. W ramach transakcji logicznej), to nie widzę problemu w posiadaniu wielu rekordów dziennika z dokładnie tym samym znacznikiem czasu. Np. Jeśli utworzenie zamówienia (jako transakcji) może obejmować utworzenie N pozycji zamówienia, wówczas wszystkie odpowiadające im rekordy dziennika 1 + N będą miały ten sam znacznik czasu. Późniejsza analiza takiego dziennika mogłaby to wykorzystać, traktując te rekordy 1 + N nie jako niezależne, ale jako elementy transakcji logicznej. Mam nadzieję, że to ma sens.
Yarik
24

Rejestrujemy również stare i nowe wartości oraz kolumnę, z której pochodzą, a także klucz główny tabeli poddawanej inspekcji w tabeli szczegółów kontroli. Pomyśl, do czego potrzebujesz tabeli audytu? Nie tylko chcesz wiedzieć, kto i kiedy dokonał zmiany, ale także gdy nastąpi zła zmiana, potrzebujesz szybkiego sposobu na przywrócenie danych.

Podczas projektowania powinieneś napisać kod, aby odzyskać dane. Kiedy musisz dojść do siebie, zwykle się spieszysz, najlepiej już być przygotowanym.

HLGEM
źródło
1
To jest naprawdę dobre, nie rozumiem, dlaczego ludzie ignorują ostatnie posty.
Maddy.Shik
3
Pozyskiwanie zdarzeń to alternatywne podejście do zapewniania funkcji przywracania przy zachowaniu historii.
Sam
23

Istnieje kilka innych rzeczy, które możesz chcieć poddać audytowi, takie jak nazwy tabel / kolumn, komputer / aplikacja, z której dokonano aktualizacji i nie tylko.

Teraz zależy to od tego, jak szczegółowego audytu naprawdę potrzebujesz i na jakim poziomie.

Zaczęliśmy budować własne rozwiązanie audytowe oparte na wyzwalaczach i chcieliśmy wszystko skontrolować, a także mieć pod ręką opcję odzyskiwania. Okazało się to zbyt skomplikowane, więc zakończyliśmy inżynierię wsteczną opartego na wyzwalaczu narzędzia innej firmy ApexSQL Audit, aby stworzyć własne niestandardowe rozwiązanie.

Porady:

  • Uwzględnij wartości przed / po

  • Uwzględnij 3-4 kolumny do przechowywania klucza podstawowego (w przypadku, gdy jest to klucz złożony)

  • Przechowuj dane poza główną bazą danych, zgodnie z sugestią Roberta

  • Poświęć przyzwoitą ilość czasu na przygotowanie raportów - zwłaszcza tych, których możesz potrzebować do odzyskania

  • Zaplanuj przechowywanie nazwy hosta / aplikacji - może to być bardzo przydatne do śledzenia podejrzanych działań

Kenneth Hampton
źródło
2
Dlaczego miałbyś go poddawać inżynierii wstecznej zamiast kupować?
Jowen
1
większa kontrola nad produktem
Tebe
1
Mam nadzieję, że cię nie pozwali.
Sorter
9

Tutaj i w podobnych pytaniach jest wiele ciekawych odpowiedzi. Jedyne rzeczy, które mogę dodać z własnego doświadczenia, to:

  1. Umieść swoją tabelę audytu w innej bazie danych. Idealnie byłoby, gdybyś chciał oddzielić dane od oryginalnych danych. Jeśli chcesz przywrócić bazę danych, tak naprawdę nie chcesz przywracać ścieżki audytu.

  2. Denormalizuj tak bardzo, jak to tylko możliwe. Chcesz, aby tabela miała jak najmniej zależności od oryginalnych danych. Tabela audytu powinna być prosta i błyskawiczna do pobierania danych. Żadnych wymyślnych łączeń ani wyszukiwań w innych tabelach w celu uzyskania danych.

Robert4Real
źródło
8
Czy dane nieznormalizowane naprawdę byłyby szybsze do odczytania w porównaniu ze znormalizowanymi danymi z odpowiednimi indeksami? (Czy całe powielanie nie spowodowałoby odczytania większej ilości danych z dysku twardego?)
Sam
4

Co mamy w naszej tabeli: -

Primary Key
Event type (e.g. "UPDATED", "APPROVED")
Description ("Frisbar was added to blong")
User Id
User Id of second authoriser
Amount
Date/time
Generic Id
Table Name

Identyfikator ogólny wskazuje wiersz w zaktualizowanej tabeli, a nazwa tabeli to nazwa tej tabeli w postaci ciągu. Niezbyt dobry projekt DB, ale bardzo użyteczny. Wszystkie nasze tabele mają jedną zastępczą kolumnę klucza, więc działa to dobrze.

W W.
źródło
2
Co oznacza „kwota”?
turdus-merula
Jest to aplikacja finansowa, więc jest to wartość autoryzacji rzeczy w dolarach itd.
WW.
4

Ogólnie audyt niestandardowy (tworzenie różnych tabel) jest złą opcją. Wyzwalacze bazy danych / tabeli można wyłączyć, aby pominąć niektóre działania dziennika. Niestandardowe tabele audytu mogą być modyfikowane. Mogą wystąpić wyjątki, które spowodują obniżenie poziomu aplikacji. Nie wspominając o trudnościach w zaprojektowaniu solidnego rozwiązania. Jak dotąd w tej dyskusji widzę bardzo proste przypadki. Potrzebujesz całkowitego oddzielenia od aktualnej bazy danych i od wszystkich uprzywilejowanych użytkowników (DBA, Developers). Każdy główny nurt RDBMS zapewnia funkcje audytu, których nawet DBA nie jest w stanie wyłączyć, manipulują w tajemnicy. Dlatego udostępniona przez dostawcę RDBMS możliwość audytu musi być pierwszą opcją. Inną opcją byłby czytnik dziennika transakcji innej firmy lub niestandardowy czytnik dziennika, który wypycha zdekomponowane informacje do systemu przesyłania wiadomości, który kończy się w niektórych formach hurtowni danych audytu lub modułu obsługi zdarzeń w czasie rzeczywistym. W podsumowaniu: Architekt rozwiązań / "Hands on Data Architect" musi się zaangażować w przeznaczenie takiego systemu na podstawie wymagań. Zwykle jest to zbyt poważna sprawa, aby przekazać ją programistom do rozwiązania.

Joel Mamedov
źródło
3

Istnieje wiele sposobów, aby to zrobić. Mój ulubiony sposób to:

  1. Dodaj mod_userpole do tabeli źródłowej (tej, którą chcesz zarejestrować).

  2. Utwórz tabelę dziennika zawierającą pola, które chcesz rejestrować, log_datetimeoraz seq_numpola i . seq_numjest kluczem podstawowym.

  3. Zbuduj wyzwalacz w tabeli źródłowej, który wstawia bieżący rekord do tabeli dziennika po każdej zmianie dowolnego monitorowanego pola.

Teraz masz zapis każdej zmiany i tego, kto ją wprowadził.

JosephStyons
źródło
Więc ... co ma robić pole mod_user?
Conny
1
Powiedz, kto dokonał zmiany. Aktualizacja kodu powinna zawierać coś, co ustawia to pole dla bieżącego użytkownika.
JosephStyons,
A co z usuwaniem? Jeśli usuniesz wiersz, jak obsłużysz wartość w kolumnie mod_user?
Kenn Cal
Wyzwalacze @KennCal mogą używać wirtualnych tabel, możesz zobaczyć dane przed i po tym samym wyzwalaczu. Nie ma znaczenia operacja. stackoverflow.com/questions/6282618/…
Renan Cavalieri
2
@KennCal Masz rację, wyzwalacz usuwania będzie musiał albo przechowywać te informacje za Ciebie. Diabeł tkwi jednak w szczegółach - jeśli używasz uwierzytelniania SQL, wyzwalacz może po prostu uruchomić [wybierz CURRENT_USER]. Jeśli jest to aplikacja kliencka, kod klienta musi ogłosić, kto to jest. Jeśli jest to wywołanie API, użytkownik usuwający musi być wymaganym parametrem wywołania.
JosephStyons
1

Zgodnie z zasadą separacji:

  1. Tabele danych inspekcji muszą być oddzielone od głównej bazy danych. Ponieważ bazy danych inspekcji mogą zawierać wiele danych historycznych, z punktu widzenia wykorzystania pamięci sensowne jest ich oddzielenie.

  2. Nie używaj wyzwalaczy do audytu całej bazy danych, ponieważ skończysz z bałaganem różnych baz danych do obsługi. Będziesz musiał napisać jeden dla DB2, SQLServer, Mysql itp.

Bhagat007
źródło