Audit fields - potrzebne?

0

Czy dodajecie do tabel audit fields (created_by, created_at, modified_by, modified_at)? Czy w 2021 roku są one dalej tak samo potrzebne?

0

Nawet bardziej niż przed RODO.

0

a czemu nie?

0

Myślę, że teraz jest łatwiej robić tabele historyczne czy jakieś śledzenie requestów po stronie aplikacji niż kiedyś. Poza tym ModifiedBy i ModifiedAt dostarcza info tylko o ostatniej zmianie - nie mamy zmian zaszłych pomiędzy pierwszą a ostatnią. IMO jak chcemy mieć historię, to róbmy pełnoprawną historię, a jak nie chcemy, to nie róbmy wcale.

0

co to znaczy niż kiedyś? triggerki od dawna istnieją w relacyjnych bazach ;)

1

https://pl.seequality.net/sql-server-2016-temporal-tables/

Nie twierdzę, że takie pola nic nie dają. Po prostu ciekaw jestem, czy są lepsze mechanizmy do śledzenia zmian.

0

A ta temporal table to skąd ma wyczarować kolumny created_by czy modified_by? Co te kolumny oznaczają w ogóle? Jeśli to ma być np. nazwa użytkownika aplikacji (a nie użytkownika bazodanowego) to trzeba to chyba na to dodatkową kolumnę w tabeli (własnie te created_by czy modified_by).

0

Temporal table takich kolumn nie wyczaruje, ale np. własne SaveChanges w EF Core już tak :)

https://www.meziantou.net/entity-framework-core-history-audit-table.htm

I tak normalnie modified by byśmy ustawiali tutaj, więc czemu nie pójść dalej?

Nie lepsze to niż dodawanie tych samych kolumn do każdej tabeli?

0

Abstrakcje na zapisywanie swoją drogą, ale i tak musisz wysłać do bazy tego użytkownika i go zapisać w jakiejś kolumnie. Dalej więc kolumny created_by i modified_by same się nie wyczarują, co najwyżej created_at i modified_at za pomocą tych temporal tables.

My mamy oddzielne tabele audytowe u siebie. Zaleta jest taka, że mają one osobny zestaw kolumn (i to takich generycznych, trochę podobnie jak w przykładzie, który podałeś), więc jak się doda czy usunie kolumny w tabeli źródłowej to zapytania o historię dalej działają (chociaż może być lekki WTF jeśli widzi się w historii zmian kolumny, których już nie ma, ale lepsze to niż pominięcie takich zdarzeń). Ogólnie to i tak trzeba się kierować wymaganiami biznesowymi przy projektowaniu takiej tabeli audytowej.

0

Do SaveChanges możemy wstrzyknac jakieś IUserContext i id użytkownika dokonującego zmiany zapisać do audit table. :)

Jeśli nie chcemy mieć pełnej historii, a tylko informacje o tym, kto i kiedy coś zmienił, to możeny to załatwić dodatkowym interfejsem.

4

Mieszasz pojęcia bazy danych i ORM. Dobrze zaprojektowana baza danych sama zapisuje co tylko chcesz zarówno do pól audytowych, jak i do tabel audytowych.
I to zmian wykonanych nie tylko a aplikacji, ale również bezpośrednio na bazie.
Niech pierwszy rzuci kamieniem, kto nigdy nie dokonywał zmian bezpośrednio w bazie.

0

No ok, to jest argument. Czyli puenta z tego wątku będzie taka, że każda tabelka jednak musi te pola mieć.

0
Marcin.Miga napisał(a):

Mieszasz pojęcia bazy danych i ORM. Dobrze zaprojektowana baza danych sama zapisuje co tylko chcesz zarówno do pól audytowych, jak i do tabel audytowych.

I to zmian wykonanych nie tylko a aplikacji, ale również bezpośrednio na bazie.
Niech pierwszy rzuci kamieniem, kto nigdy nie dokonywał zmian bezpośrednio w bazie.

Co to znaczy, że baza sama zapisuje dane do pól audytowych i tabel audytowych? Jaki format mają te tabele audytowe? Jak zrobić zapytania do wyciągania danych z tych tabeli audytowych? Jest to odporne na zmiany w strukturze tabeli (dodawanie, usuwanie, zmiana typów itd kolumn)?

0
Wibowit napisał(a):

Co to znaczy, że baza sama zapisuje dane do pól audytowych i tabel audytowych?

No, może nie do końca baza, a trigger(y).

Wibowit napisał(a):

Jaki format mają te tabele audytowe?

Taki, jak sobie zaprojektujesz. Ja z reguły stosuję do każdej audytowanej tabeli jedną dodatkową tabelę z historią.
Mniej więcej postaci:
id, pole, stara_wartosc, nowa_wartosc, insert_user, insert_time
(można jeszcze dodać kolumnę z informacją o tabeli, wtedy tabela audytowa może być jedna dla wielu tabel - mnie generalnie interesują zmiany danych osobowych, więc to monitoruję)

Wibowit napisał(a):

Jak zrobić zapytania do wyciągania danych z tych tabeli audytowych?

Normalnie, szukasz największego id dla insert_time mniejszego niż twój żądany wskaźnik czasowy...

Wibowit napisał(a):

Jest to odporne na zmiany w strukturze tabeli (dodawanie, usuwanie, zmiana typów itd kolumn)?

Pola stara_wartosc i nowa_wartosc są typu varchar lub text, więc problemu z przechowywaniem danych nie ma.
A zmianę struktury np. na PostgreSQL też można monitorować. CREATE EVENT TRIGGER

1
WeiXiao napisał(a):

triggerki od dawna istnieją w relacyjnych bazach

OK Boomer

nobody01 napisał(a):

No ok, to jest argument. Czyli puenta z tego wątku będzie taka, że każda tabelka jednak musi te pola mieć.

A jeśli te dane nie są potrzebne, to po co je mieć? A jeśli informacje jedynie o ostatniej edycji są niewystarczające, to co wtedy?

0
Marcin.Miga napisał(a):
Wibowit napisał(a):

Co to znaczy, że baza sama zapisuje dane do pól audytowych i tabel audytowych?

No, może nie do końca baza, a trigger(y).

Ach, widzisz, to robi sporą różnicę w odbiorze oryginalnego posta. Wychodzi na to, że w stosunku do rozwiązania https://www.meziantou.net/entity-framework-core-history-audit-table.htm (przytoczonego przez @nobody01 ) proponujesz tylko zamienić mechanizm zapisu do bazy audytowej z bezpośredniego okodowania w C# na triggery w bazie. To ma wady i zalety. Z jednej strony trigger daje większą pewność, że zmiany zostaną zarejestrowane (tak jak w przypadku ręcznych zmian na bazie, o których wspomniałeś), ale z drugiej strony aktualizacja zapytania naklepanego w C# jest raczej mniej pracochłonna niż aktualizacja triggera. No chyba, że da się napisać takiego sprytnego triggera, że nie będzie musiał mieć w żaden sposób zahardkodowanych nazw kolumn z tabeli źródłowej (oprócz np. kolumny last_modification_author, bo tego trigger sam nie wyczaruje) i tym samym nie będzie potrzeby aktualizowania go.

0

Można mieć procedurę generująca triggery na podstawie jakichś tabelek konfiguracyjnych :)

Coś podobnego, ale bardziej konfigurowalnego:
https://www.mssqltips.com/sqlservertip/1770/auto-generate-sql-server-update-triggers-for-data-auditing/

U mnie audit table jest generyczna: ma kolumny column_name, previous_value, current_value, change_id. Change_id odnosi się do drugiej tabelki z kolumnami object_id, object_type, datetime, user_id, change_type.

@somekind W którymś wątku pisałeś chyba, że triggery są niepotrzebne. Zgaduje, że miałeś na myśli wykorzystywanie ich do logiki biznesowej, ale dalej ciekaw jestem, jak Ty robisz historię.

2
nobody01 napisał(a):

@somekind W którymś wątku pisałeś chyba, że triggery są niepotrzebne. Zgaduje, że miałeś na myśli wykorzystywanie ich do logiki biznesowej, ale dalej ciekaw jestem, jak Ty robisz historię.

No raczej nie robiłbym triggerami, bo to po pierwsze trzeba napisać, po drugie trzeba utrzymać. Łatwiej to zrobić po stronie aplikacji: https://www.nuget.org/packages/NHibernate.Envers
To ma oczywiście tę wadę, że jak ktoś wpuszcza coś do bazy bokiem, to nie będzie historii. Ale tym bym się nie przejmował, bo jeśli w jakiejś firmie taka patologia jest możliwa, to i binarki na produkcję można wrzucić przez FTP, a to dużo większy problem. :P
No chyba, że baza nie jest bazą tylko jednej aplikacji, pełni rolę jakiejś szyny między systemami, wystawia swoje API przez procedury składowane, no i ogólnie aplikacja nie ma nawet dostępu do tabel. W takiej sytuacji, to triggery są nieuniknione.
A jeśli mamy event sourcing, to żadnego audytu nie potrzebujemy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1