Czy naprawdę potrzebuję wyzwalaczy dla relacyjnej bazy danych, na przykład PostgreSQL?

10

Wiem, że wyzwalaczy można używać do sprawdzania poprawności przechowywanych danych w celu zachowania spójności bazy danych. Dlaczego jednak nie przeprowadzić walidacji danych po stronie aplikacji przed zapisaniem ich w bazie danych?

Na przykład przechowujemy klientów i chcemy przeprowadzić weryfikację, której nie można łatwo wykonać na poziomie DDL. https://severalnines.com/blog/postgresql-triggers-and-stored-function-basics

Innym przykładem jest audyt.

Aktualizacja

Jak działają wyzwalacze i transakcje w bazie danych. Na przykład, jeśli chcę przeprowadzić weryfikację wstawianych danych. Odbywa się to w ramach transakcji. Co dzieje się wcześniej: transakcja zostaje zatwierdzona lub wyzwalacz jest wykonywany?

Yan Khonski
źródło
However, why not perform validation of data on the application side before storing them into the database?cóż, te dwa nie wykluczają się wzajemnie. Prawdopodobnie potwierdzisz różne rzeczy po obu stronach. Podczas gdy walidacje po stronie aplikacji są skoncentrowane na biznesie, walidacje w bazie danych są bardziej skoncentrowane na danych. Pomyśl w bazie danych zasilanej przez kilka różnych aplikacji.
Laiv
Czy będziesz musiał wstawić dane z zewnętrznego źródła, które po prostu robi bezmyślny zrzut danych do twojego systemu? Jeśli tak, możesz mieć przypadki, w których potrzebujesz danych wstawionych w niepoprawnym formacie w celu późniejszej korekty. W takim przypadku wyzwalacze powodują niekończące się problemy. Pamiętaj o tym. Czasami nie chcesz, aby wyzwalacz został wykonany.
Greg Burghardt
Twoja aktualizacja powinna być pytaniem samym w sobie, być może na SO, ale twoje pytanie ma już odpowiedź na Database Administrators.SE . Krótko mówiąc, nawet wyzwalacz „po aktualizacji” jest wykonywany przed zatwierdzeniem transakcji, a jeśli wyjątek zostanie zgłoszony w środku wyzwalacza, spowoduje wycofanie.
Doc Brown
@GregBurghardt Większość baz danych ma instrukcje, których można użyć do wyłączenia wyzwalaczy dla tego rodzaju działań.
Blrfl
1
@Blrfl: Tak, ale musisz pamiętać, że te wyzwalacze można tymczasowo wyłączyć dla wszystkich podłączonych użytkowników, gdy chcesz tylko warunkowo wyłączyć te kontrole dla bieżącej sesji.
Greg Burghardt

Odpowiedzi:

12

To zależy od rodzaju budowanego systemu aplikacji:

  • jeśli tworzysz system zorientowany na aplikacje, który zawiera tylko jedną główną aplikację, z dedykowaną bazą danych specjalnie dla tej aplikacji i idealnie jeden zespół odpowiedzialny za rozwijanie aplikacji i bazy danych obok siebie, możesz zachować całą logikę walidacji, a także audyt logika wewnątrz aplikacji.

    Główną zaletą tego rozwiązania jest to, że nie trzeba rozdzielać logiki biznesowej między aplikacją a bazą danych, dzięki czemu utrzymanie i rozwój systemu często staje się łatwiejszy. Jako bonus, nie wiążesz zbytnio aplikacji z konkretnym typem dostawcy DBMS lub DBMS. Takie podejście jest oczywiście wymagane, jeśli aplikacja chce mieć możliwość korzystania z lekkiego systemu DB, który nie zapewnia wyzwalaczy.

  • Jeśli jednak utworzysz system, w którym wiele różnych aplikacji ma wspólną bazę danych, i nie może wcześniej przewidzieć, które aplikacje będą do niej zapisywać w przyszłości lub które zespoły opracują aplikacje do wypełniania danych w bazie danych w przyszłości, wówczas jest lepsze, że Twoja baza danych będzie odpowiedzialna za zagwarantowanie jak największej spójności danych. I tutaj wyzwalacze stają się naprawdę pomocne. W większych systemach ograniczenia referencyjne często nie są do tego wystarczające, ale wyzwalacz wywołujący procedurę przechowywaną może zaimplementować prawie każdy rodzaj sprawdzania poprawności, jakiego potrzebujesz.

Innym powodem używania wyzwalaczy może być wydajność: w skomplikowanych modelach danych często zdarza się spotykanie złożonych reguł spójności, które wymagają użycia wielu dodatkowych danych, które nie są częścią bieżącego zestawu roboczego dostępnego w aplikacji klienta. Przeniesienie wszystkich tych danych najpierw przez sieć w celu umożliwienia weryfikacji po stronie klienta może mieć znaczący wpływ na wydajność.

Zobacz także ten starszy post SE: Logika aplikacji Vs DB Trigger do czyszczenia bazy danych

Więc sam zdecyduj, jaki system budujesz, a następnie możesz podjąć uzasadnioną decyzję, czy wyzwalacze są właściwym narzędziem dla twojej sprawy, czy nie.

Doktor Brown
źródło
3

Myślę, że pytanie dotyczy odpowiedzialności za jakość danych.

Odpowiedź zależy od tego, jak widzisz system.

Jeśli widzisz bazę danych jako niezależną, odrębną i autonomiczną usługę niezależną od aplikacji, baza danych jest odpowiedzialna za zapewnienie spójności i jakości zawartych w niej danych. Zasadniczo dlatego, że ta baza danych może być używana przez inną aplikację, więc nie może polegać na tym, że druga aplikacja ma taką samą spójność i jakość zachowania. W takich okolicznościach baza danych musi zostać zaprojektowana w taki sposób, aby ujawniała interfejs API i zachowanie autonomiczne. W tym widoku są co najmniej dwie aplikacje, jedna z nich to baza danych, a druga to aplikacja, która z niej korzysta.

I odwrotnie, bazę danych można uznać za skomplikowaną formę pliku, który znajduje się pod bezpośrednią i całkowitą kontrolą aplikacji. W tym sensie baza danych staje się czystym narzędziem do serializacji i nawigacji po dokumentach. Może zapewniać pewne zaawansowane zachowania do obsługi zapytań i obsługi dokumentów (takie jak JSON lub narzędzia XML), ale z drugiej strony nie musi (tak jak większość strumieni plików). W takim przypadku program odpowiada za utrzymanie właściwego formatu i zawartości pliku. W tym widoku jest jedna aplikacja.

W obu widokach kolejnym pytaniem jest, jak obsługiwać korzystanie z bazy danych jako fantazyjnego pliku lub oddzielnej usługi. Możesz to osiągnąć poprzez:

  • za pomocą narzędzi udostępnianych przez platformę bazy danych w postaci tabel / widoków / procedur przechowywanych / wyzwalaczy itp.
  • zawijanie samej bazy danych w ramach usługi, z której muszą korzystać wszyscy klienci, aby uzyskać dostęp do bazy danych
  • zawijanie bazy danych do biblioteki, z której muszą korzystać wszyscy klienci, aby uzyskać dostęp do danych.

Każda z nich ma swoje zalety / wady i będzie zależeć od architektonicznych ograniczeń środowiska, w którym działa system.

Niezależnie od tego, jaki widok bierzesz, zawsze opłaca się sprawdzać poprawność danych na granicach.

  • Sprawdź poprawność pól w interfejsie użytkownika wprowadzanych przez użytkownika
  • Sprawdź poprawność żądania sieci / interfejsu API przed opuszczeniem klienta
  • Sprawdź poprawność żądania sieci / interfejsu API na serwerze, zanim cokolwiek zrobisz
  • Sprawdź poprawność danych przekazywanych do reguł biznesowych
  • Sprawdź poprawność danych przed utrwaleniem
  • Sprawdź poprawność danych po odzyskaniu od trwałości
  • i tak dalej

To, ile walidacji jest uzasadnione na każdej granicy, zależy od tego, jak ryzykowne jest jej niepotwierdzenie.

  • pomnożenie dwóch liczb razem?
    • otrzymałeś zły numer, czy to problem?
  • wywoływanie procedury dla danej lokalizacji pamięci?
    • Co jest w tej lokalizacji pamięci?
    • Co się stanie, jeśli obiekt nie istnieje lub jest w złym stanie?
  • za pomocą wyrażenia regularnego w ciągu zawierającym kanji?
    • Czy moduł regex może obsłużyć Unicode?
    • Czy wyrażenie regularne może obsłużyć Unicode?
Kain0_0
źródło
Centralizacja logiki sprawdzania poprawności jest dobra, ale wyzwalacze imho nie są dobrym sposobem na jej wdrożenie. Kiedyś pracowałem w systemie, w którym wiele aplikacji współużytkowało bazę danych, z całą logiką walidacji i efektami ubocznymi zaimplementowanymi w bazie danych za pomocą wyzwalaczy i procedur przechowywanych. Odniosłem wrażenie, że lepiej jest mieć mikrousługę przed bazą danych i zaimplementować tam całą logikę. Nietrywialna logika w bazie danych SQL jest anty-wzorcem.
Joeri Sebrechts
1
@JeriSebrechts Okay, ugryzę: dlaczego nietrywialna logika w bazie danych jest antypatternem, a co czyni ją bardziej antypatternem niż umieszczanie jej w osobnym programie?
Blrfl
@Blrfl Dwa powody, dla których interfejs API do uzyskiwania dostępu do logiki w bazie danych jest gorszy niż interfejs API usługi sieci Web (trudniejszy do wersji, trudniejszy w użyciu, trudny do buforowania, ...), a bazy danych utrudniają czystą strukturę i utrzymanie hostowana w nich baza kodów. Z mojego doświadczenia wynika, że ​​łatwiej jest hostować logikę w usłudze sieciowej przed bazą danych niż w tej bazie danych.
Joeri Sebrechts
@JeriSebrechts Zgadzam się, że większość platform baz danych zapewnia żałosne narzędzia do wdrażania wiarygodnego, użytecznego i rozwijalnego API. Pod wieloma względami jest to z pewnością zaproszenie do odczuwania dużego bólu. Chodziło mi o to, że chodzi o perspektywę, uświadomienie sobie, że DB jest fantazyjnym plikiem lub że to naprawdę osobna usługa, prowadzi do następnego pytania, jak owinąć to w celu obsługi tego stylu użytkowania. Opracuję moją odpowiedź, aby było jasne.
Kain0_0
2

Nie, nigdy nie należy używać wyzwalaczy do sprawdzania poprawności.

Baza danych odpowiada tylko za swoją integralność. Weryfikacja użytkownika powinna zostać przeprowadzona przez aplikację.

Bazy danych wykonują trzy poziomy sprawdzania poprawności pod kątem integralności. Pierwszym z nich jest walidacja na poziomie pola. Pole może być wymagane, jeśli nie ma wartości (null), oznacza to błąd. Może to być również ograniczenie sprawdzające; domena ma wyliczoną liczbę wartości.

Po drugie, istnieją relacje między tabelami. W jednej tabeli przechowujesz jeden lub więcej kluczy obcych, odnosząc tę ​​tabelę do innych tabel i wymagając, aby wartości były poprawnymi kluczami dla „drugiej tabeli”. Pomyśl o bazie danych adresów, w której obsługujemy adresy różnych krajów. Klucz kraju w adresie musi wskazywać znany kraj. To, czy dane (np. Kod pocztowy) są prawidłowe, nie jest przedmiotem tej kontroli integralności.

Po trzecie i najbardziej skomplikowane są wyzwalacze. Zasadniczo powinny one dotyczyć (pun nie zamierzony) dotyczy warunkowych zasad uczciwości. Wracając do przykładu adresu: jeśli kraj nie ma kodów pocztowych, problem pojawiałby się, gdyby kraj z tej listy miał kod pocztowy. Tak więc czek byłby następujący: jeśli ten kraj nie ma kodów pocztowych, pole kodu pocztowego powinno być puste.

Walidacja jest przedmiotem wniosku. Fakt, że niemiecki kod pocztowy składa się tylko z cyfr, jest sprawdzianem, który powinna wykonać aplikacja, a nie baza danych. Linia jest cienka, więc w niektórych przypadkach może być potrzebne przemyślenie / omówienie, czy coś powinno być w wyzwalaczu (chroń integralność bazy danych) lub w aplikacji (walidacja przez użytkownika).

Menno Hölscher
źródło
Chciałem tylko dodać, że jeśli OP musi dodać regułę sprawdzania poprawności kompleksu, która musi znajdować się w bazie danych, zawsze może używać procedur przechowywanych jako bezpieczniejszej alternatywy.
Borjab
@ Borjab: Być może sprawdzanie poprawności w celu zachowania poprawności bazy danych. Ale walidacja przez użytkownika? Nie.
Menno Hölscher
1
Twoje pierwsze stwierdzenie mówi: „nigdy nie używaj wyzwalaczy do sprawdzania poprawności” , ale poniżej piszesz: „tak, możesz używać wyzwalaczy do pewnych rodzajów sprawdzania poprawności i nie jest z natury jasne, gdzie narysować linię”. Brzmi to dość sprzecznie. Poleciłbym usunąć twoje pierwsze zdanie, co znacznie poprawiłoby twoją odpowiedź. Aha, a twoje ostatnie zdanie nie odpowiada na pytanie o aktualizację OP, ponieważ „przed / po” nie ma nic wspólnego z transakcją. Polecam również go usunąć. (patrz mój komentarz poniżej pytania PO).
Doc Brown
@DocBrown Rozróżnia się między ochroną bazy danych przed uszkodzeniem a weryfikacją przez użytkownika. Tak więc w „każdej dalszej walidacji” odnoszę się do walidacji użytkownika. Jak mogę uczynić to rozróżnienie bardziej wyraźnym? Na początek usunąłem „dalszy”.
Menno Hölscher
2
Sprawdzanie poprawności w bazie danych jest w porządku. Tak, jak można to zrobić w aplikacji. Oba mają swoje zalety. Sprawdzanie poprawności w aplikacji oznacza, że ​​musisz być bardzo ostrożny za każdym razem, gdy uruchamiasz SQL bez ORM, co jest potrzebne w prawie każdej złożonej aplikacji.
Qwertie
1

Audyt jest klasycznym przykładem skutecznego użycia wyzwalaczy. Znalazłem błędy popełniane przez testera (przenoszenie klienta z jednego poziomu usługi na inny) dzięki tabeli Audit, która została zaimplementowana przez wyzwalacze. Bardzo polecam używanie wyzwalaczy do kontroli.

Walidacji można dokonać na poziomie interfejsu, ale widziałem dziwne błędy w bazie danych, które obsługiwałem (ludzie, którzy urodzili się w 3000 itd.), A ponieważ niektóre z nich zrobiłem sam, bardzo polecam posiadanie dodatkowej warstwy walidacji w bazie danych, na wszelki wypadek. Oczywiście tego rodzaju błędów można uniknąć dzięki ograniczeniom sprawdzania i wiele razy są one bardziej skuteczne (w MS SQL są preferowaną metodą; zawsze sprawdzaj dokumentację).

Hila DG
źródło
1

Ponieważ pytanie dotyczy tego, czy naprawdę potrzebujemy wyzwalaczy dla relacyjnych baz danych, oto kilka innych przypadków użycia wyzwalaczy:

  1. Do kontroli zgodnie z opisem w innych odpowiedziach.
  2. Audyt w szerszym znaczeniu: jeśli pozycja bazy danych zostanie zmieniona, wyzwalacz może zarejestrować zdarzenie w celu asytronicznego przetwarzania końcowego, np. Nocne eksportowanie do innej aplikacji.
  3. Wyzwalacze dla widoków: można zdefiniować wyzwalacze instead of. Dzięki temu można wstawiać, aktualizować i usuwać wpisy z widoku. Wyzwalacze mogą rozłożyć te działania na wiele tabel. Jest to sposób na udostępnienie ograniczonego widoku bez ujawniania szczegółów tabel bazowych.
  4. Aby jawnie zapisać odwrócenie bazy danych: załóż relacje N: M między tabelą A i B a tabelą pośrednią R. Możesz zdefiniować ograniczenia klucza obcego od R do A, a także B, określając, że wpis w R ma zostać usunięty, jeśli jego odpowiadający wpis w B zostaje usunięty. Jednak logika biznesowa wymaga czasem, aby wpisy w A musiały mieć co najmniej jedną relację z wpisem w B. W tym przypadku wyzwalacz po usunięciu R może pomóc w egzekwowaniu tej logiki: jeśli dla wpisu w A ostatni wpis w R jest usuwany, a następnie wyzwalacz może usunąć A. W widoku centralnym aplikacji konieczne są co najmniej dwa zawracanie. To jest przykład walidacji. Możliwe są inne przykłady: oprócz przypadków użycia (1), (2),
  5. Zaufanie: czasami administratorzy bazy danych zmieniają wpisy w wierszu poleceń, nie używając Twojej aplikacji. Administratorzy pracują ostrożnie i wiedzą, co robią. Czasami jednak mogą się mylić. Jeśli spójność ma kluczowe znaczenie, wyzwalaczem jest pas bezpieczeństwa.

Wadą logiki biznesowej jest rozłożona między warstwami, co stanowi poważną wadę w zakresie konserwacji. Jak napisał inny autor, jest to cienka granica między aplikacją a bazą danych, a wybór nie zawsze jest jasny. Moja osobista opinia jest taka, że ​​wyzwalacze obciążają programistów. Mogą zaoszczędzić czas na rozwój. Zdecydowanie zwiększają doświadczenie użytkowników, ponieważ zwiększają wydajność w przypadku wolnych połączeń sieciowych.

Claude
źródło