Dlaczego ograniczenia są stosowane w bazie danych? Czy wstawienie go do kodu nie będzie bardziej elastyczne?
Czytam książkę dla początkujących na temat wdrażania baz danych, więc pytam o to jako początkujący. Powiedzmy, że zaprojektowałem bazę danych, w tym ten model encji:
entity type | sub-types
----------------+--------------------------------------------
Person | Employee, Student, ...
Student | Graduate, Undergraduate, ...
Employee | Teacher, Administrator, ...
Obecne ograniczenia:
- Zarejestrowaną osobą w systemie może być tylko Student lub Pracownik.
- Istota osobowa wymaga unikalności numeru społecznego, który, jak zakładamy, każda osoba posiada tylko jeden unikalny numer (czyli wystarczająco dobry klucz podstawowy). (patrz # 1)
Później decydujemy się usunąć numer 1: jeśli któregoś dnia kolegium zdecyduje, że Teacher
( Employee
podtyp) może być również Student
, biorąc udział w kursach w wolnym czasie, znacznie trudniej jest zmienić projekt bazy danych, który mógłby mieć tysiące, miliony, miliardy, zyliony wpisów, a nie tylko zmiana logiki w kodzie: tylko część, która nie pozwalała na rejestrację osoby jako ucznia i pracownika.
(To bardzo nieprawdopodobne, ale nie mogę teraz myśleć o niczym innym. Najwyraźniej jest to możliwe).
Dlaczego dbamy o reguły biznesowe w projektowaniu baz danych, a nie w kodzie?
# 1: Notatka 7 lat później, przykład z prawdziwego życia:
Widziałem rząd, w którym z powodu błędu wydano numery SSN: wiele osób, ten sam numer SSN. Projektanci oryginalnego DB zdecydowanie popełniali błąd, nie stosując tego ograniczenia unikatowości w bazie danych. (a później błąd w oryginalnej aplikacji? wiele aplikacji korzystających ze wspólnej bazy danych i nie zgadzających się, gdzie umieścić, sprawdzić i egzekwować ograniczenie? ...).
Ten błąd będzie nadal działał w systemie, a cały opracowany system będzie bazował na bazie danych tego oryginalnego systemu przez wiele lat. Czytając tutaj odpowiedzi, nauczyłem się stosować wszystkie ograniczenia, tak wiele z nich, jak to możliwe, mądrze (nie na ślepo) w bazie danych, aby reprezentować prawdziwy świat fizyczny tak dobrze, jak potrafię.
źródło
Odpowiedzi:
Niektóre ograniczenia najlepiej egzekwować w bazie danych, a niektóre najlepiej w aplikacji.
Zazwyczaj istnieją ograniczenia, które najlepiej egzekwować w bazie danych, ponieważ mają one fundamentalne znaczenie dla struktury modelu danych, takie jak ograniczenie klucza obcego w celu zapewnienia, że produkt jest ważny
category_id
.Ograniczenia, które są egzekwowane w aplikacji, mogą nie być fundamentalne dla modelu danych, tak jak wszystkie produkty FooBar muszą być niebieskie - ale później ktoś może zdecydować, że FooBars mogą być również żółte. Jest to logika aplikacji, która tak naprawdę nie musi znajdować się w bazie danych, chociaż można utworzyć osobną
colours
tabelę, a baza danych może wymagać, aby produkt odwoływał się do poprawnego wpisu z tej tabeli. ALE decyzja, że jedyny wpiscolours
ma wartośćblue
, nadal pochodziłaby spoza bazy danych.Zastanów się, co by się stało, gdybyś nie miał żadnych ograniczeń w bazie danych i wymagał, aby wszystkie były egzekwowane w aplikacji. Co by się stało, gdybyś miał więcej niż jedną aplikację, która musiała pracować z danymi? Jak wyglądałyby Twoje dane, gdyby różne aplikacje decydowały się na inne wymuszanie ograniczeń?
Twój przykład pokazuje sytuację, w której bardziej korzystne byłoby ograniczenie w aplikacji niż w bazie danych, ale być może istniał podstawowy problem z tym, że początkowy model danych był zbyt restrykcyjny i nieelastyczny?
źródło
teachers_as_students
która jest kolejnym podtypemStudents
i ma nowy klucz obcy odnoszący się do niegoTeachers
, oraz wygenerowany przez system klucz podstawowy zamiast Społeczności Numer zabezpieczający. W ten sposób „uczeń” jest aliasem dla nauczyciela, więc nauczyciel może się zarejestrować, aby wziąć udział w zajęciach. Trudno powiedzieć na pewno, jak dobrze by to działało, nie widząc całego modelu danych.color_products
, icolor
prawdopodobnie będziesz w stanie łatwiej tworzyć dodatkowe listy rozwijane - większość programów ładujących IDE / schematów, obsługuje następujące klawisze.Bo:
Tylko kilka ważnych dla mnie powodów.
źródło
Dane prawdopodobnie długo przeżyją kod aplikacji. Jeśli reguła ma kluczowe znaczenie dla danych, które są użyteczne w czasie (jak ograniczenia klucza obcego, które pomagają zachować integralność danych), musi znajdować się w bazie danych. W przeciwnym razie istnieje ryzyko utraty ograniczenia w nowej aplikacji, która trafia do bazy danych. Wiele aplikacji nie tylko uderza w bazy danych (w tym niektóre, które mogą nie zdawać sobie sprawy, że istnieje ważna reguła danych), ale niektóre z nich, takie jak import danych lub aplikacje raportujące, mogą nie być w stanie korzystać z warstwy danych skonfigurowanej w głównej aplikacji do wprowadzania danych. Szczerze mówiąc, w moim doświadczeniu prawdopodobieństwo wystąpienia błędu w ograniczeniu jest znacznie wyższe w kodzie aplikacji.
Moim osobistym zdaniem (w oparciu o ponad 30 lat pracy z danymi i doświadczeniem w setkach różnych baz danych wykorzystywanych do wielu różnych celów) każdy, kto nie umieści ograniczeń w bazie danych, do której należą, ostatecznie będzie miał słabe dane. Czasami złe dane do tego stopnia, że nie nadają się do użytku. Jest to szczególnie ważne, gdy masz dane finansowe / regulacyjne, które muszą spełniać określone kryteria badania.
źródło
Większość referencyjnych ograniczeń integralności, które są wdrażane poza bazą danych, można pokonać, więc jeśli chcesz, aby Twoje dane miały gwarantowaną integralność przez cały czas, musisz zastosować ograniczenia w bazie danych. Full stop, to wszystko.
Zazwyczaj ograniczenia na poziomie aplikacji są eliminowane przez mechanizm spójności odczytu bazy danych, dzięki któremu sesje nie mogą przeglądać danych innych sesji, dopóki nie zostaną zatwierdzone.
Na przykład dwie sesje mogą próbować wstawić tę samą wartość do kolumny, która ma być unikalna. Mogą one zarówno check jednocześnie , że wartość nie istnieje, można wstawić zarówno ich wartości, a może obie zobowiązują. Unikalne ograniczenie zaimplementowane w bazie danych nie pozwoli na to.
Nawiasem mówiąc, nie jest to nieznane projektantom języka aplikacji. Przeczytaj rozdział 3.10 o wyjątkowości w przewodnikach Ruby on Rails: Aktywne sprawdzanie poprawności rekordów i callbacki
źródło
Korzyści wynikające z ograniczeń wymuszonych przez bazę danych:
Prostota - Zadeklarowanie ograniczenia jest znacznie prostsze niż zadeklarowanie ograniczenia i napisanie kodu, który wymusi tę deklarację.
Dokładność - kod, który nie napisałeś, nigdy nie będzie zawierał błędu, który sam stworzyłeś. Dostawcy baz danych spędzają czas, upewniając się, że kod ograniczenia jest dokładny, więc nie musisz.
Szybkość - Twoja aplikacja nigdy nie może mieć więcej dystrybucji niż baza danych, na której jest oparta. Dostawcy baz danych spędzają czas, upewniając się, że kod ograniczenia jest wydajny, więc nie musisz. Sama baza danych ma również szybszy dostęp do danych, niż aplikacja mogłaby kiedykolwiek mieć, bez względu na to, jak wydajna.
Ponowne użycie - możesz zacząć od jednej aplikacji na jednej platformie, ale może tak nie być. Co zrobić, jeśli chcesz uzyskać dostęp do danych z innego systemu operacyjnego, innego sprzętu lub interfejsu głosowego? Dzięki ograniczeniom w bazie danych kod ten nigdy nie musi być przepisywany na nową platformę i nigdy nie musi być debugowany w celu zapewnienia dokładności ani profilowany pod kątem szybkości.
Kompletność - aplikacje wymuszają ograniczenia, gdy dane są wprowadzane do bazy danych i wymagałyby dodatkowego wysiłku, aby zweryfikować dokładność starszych danych lub manipulować danymi znajdującymi się już w bazie danych.
Długowieczność - Twoja platforma bazy danych prawdopodobnie przeżyje określoną aplikację.
źródło
Dlaczego na serwerze stosowane są ograniczenia? Ponieważ nie możesz zmusić złych do korzystania z twojego klienta.
Aby to wyjaśnić, jeśli przetwarzasz reguły biznesowe tylko w aplikacji klienckiej, wówczas osoba korzystająca z innego narzędzia może połączyć się z serwerem bazy danych i robić, co tylko zechce, bez ograniczeń wynikających z reguł biznesowych i kontroli integralności. Bardzo trudno jest uniemożliwić komukolwiek korzystanie z dowolnego narzędzia w dowolnym miejscu w sieci.
Jeśli wykonasz sprawdzanie integralności na serwerze bazy danych, każda próba dostępu do danych, niezależnie od narzędzia, będzie ograniczona twoimi regułami.
źródło
Kilka świetnych odpowiedzi tutaj i na ryzyko powtórzenia innych myśli:
UPDATE
instrukcję bezpośrednio w bazie danych, w jaki sposób Twoja aplikacja zapobiega nieprawidłowej zmianie? Innym problemem związanym z regułami biznesowymi w aplikacji jest to, że ponowna kompilacja / ponowne wdrożenie może być trudne, szczególnie w przypadku aplikacji rozproszonych, w których możliwe jest, że nie wszyscy otrzymają aktualizację w tym samym czasie. I wreszcie, zmiana reguł biznesowych w aplikacji nie ma absolutnie nic wspólnego z danymi, które już istnieją, co narusza nowe reguły - jeśli dodasz nowe ograniczenie do danych, musisz je naprawić.W przypadku, gdy wyraźnie wspominasz, że nagle zezwalasz na coś, co wcześniej było niedozwolone, nie jest to tak naprawdę problemem - usuwasz wszelkie wymuszone ograniczenia, niezależnie od tego, gdzie to istnieje. W przeciwnym przypadku, gdy nagle nauczycielom nie wolno już być uczniami, potencjalnie masz do wyczyszczenia mnóstwo danych, bez względu na to, gdzie wcześniej istniało ograniczenie.
źródło
Baza danych może skutecznie sprawdzać ograniczenia. Lepsze niż kod.
Ograniczenia integralności pomagają bazie danych znaleźć skuteczny plan wykonania
Aplikacja widzi spójny widok, dlatego nie może zagwarantować wyjątkowości. Podczas gdy baza danych może również zobaczyć dane niezaangażowane.
źródło
Krótka odpowiedź ... w celu zachowania integralności danych (tj. Dokładności i ważności).
Wyjątek ...
Jeśli baza danych przechowuje dane jednej aplikacji dla jednego użytkownika, na przykład w większości baz danych Sqlite, może nie wymagać ograniczeń. W rzeczywistości zazwyczaj tak nie jest, aby czas dostępu był tak szybki, że nie można go zmierzyć.
Do wszystkiego innego ...
Bazy danych zawsze obsługują dwa wzorce, które nazywam edytorami i użytkownikami .
Redaktorzy najczęściej umieszczają dane w bazie danych i pobierają dane jeden lub niewielką liczbę rekordów jednocześnie. Ich najważniejsze obawy to szybki, dokładny dostęp do wszystkich powiązanych danych oraz szybkie i niezawodne przechowywanie ich zmian.
Użytkownicy w większości pobierają dane, a najbardziej zależy im na szybkim dostępie do niewątpliwie dokładnych informacji. Często potrzebują różnych zliczeń, agregacji i list, które kiedyś były generowane w tych kultowych grubych na stosy stosach wydruków z zielonego papieru, ale zwykle trafiają dziś na strony internetowe.
Projekty tworzenia baz danych są prawie zawsze uruchamiane na żądanie użytkowników , ale projekt opiera się na potrzebach redaktorów dotyczących wprowadzania danych i nagrywania na raz . W związku z tym niedoświadczeni programiści często reagują na pilną potrzebę szybkości (przede wszystkim rozwoju ), nie nakładając ograniczeń w bazie danych.
Jeśli jedna i tylko jedna aplikacja będzie kiedykolwiek używana do wprowadzania zmian w danych przez cały okres życia bazy danych, a ta aplikacja jest rozwijana przez jedną lub niewielką liczbę dobrze skoordynowanych osób, uzasadnione może być poleganie na aplikacja do zapewnienia integralności danych.
Jednak o ile udajemy, że możemy przewidzieć przyszłość, nie możemy.
Wysiłek stworzenia bazy danych jest zbyt cenny, aby ją kiedykolwiek wyrzucić. Baza danych, podobnie jak dom, będzie wielokrotnie rozbudowywana, zmieniana i odnawiana. Nawet po całkowitym zastąpieniu wszystkie dane zostaną przeniesione do nowej bazy danych, zachowując jednocześnie wszystkie stare reguły biznesowe i relacje.
Ograniczenia implementują te reguły i relacje w zwięzłej, deklaratywnej formie w samym silniku bazy danych, gdzie są łatwo dostępne. Bez nich kolejni programiści musieliby przeglądać programy aplikacyjne, aby poddać inżynierii wstecznej te reguły. Powodzenia!
Nawiasem mówiąc, właśnie to muszą zrobić programiści COBOL na komputerach mainframe, ponieważ te ogromne bazy danych były często tworzone, zanim mieliśmy relacyjne mechanizmy i ograniczenia. Nawet po migracji do nowoczesnego systemu, takiego jak DB2 IBM, ograniczenia czasami nie są w pełni zaimplementowane, ponieważ logika starych reguł, zawartych być może w serii programów wsadowych COBOL, może być tak skomplikowana, że nie można ich przekonwertować. Zamiast tego można użyć zautomatyzowanych narzędzi do konwersji starego COBOL-a na nowszą wersję z interfejsami do nowego silnika relacyjnego i przy niewielkich poprawkach integralność danych zostaje zachowana ... do momentu napisania nowej aplikacji, która subtelnie psuje wszystko i firma zostaje przeniesiona do sądu, powiedzmy, wykluczając tysiące właścicieli domów, których nie powinni mieć.
źródło
Oprócz innych komentarzy ...
Jeśli / kiedy masz bazę danych, w której dowolna tabela może być aktualizowana przez jedną lub więcej aplikacji lub ścieżek kodu, wówczas umieszczenie odpowiednich ograniczeń w bazie danych oznacza, że twoje aplikacje nie będą duplikowały „tego samego” kodu ograniczenia. Przynosi to korzyść, upraszczając konserwację (zmniejszając liczbę miejsc do zmiany w przypadku zmiany modelu danych) i zapewnia konsekwentne stosowanie ograniczeń bez względu na aktualizację danych przez aplikację.
źródło
Osobiście uważam, że łatwiej jest tworzyć i modyfikować ograniczenia niż na przykład wyzwalacze, które mogłyby być jednym ze sposobów egzekwowania reguł biznesowych za pomocą kodu źródłowego.
Również wyzwalacze są mniej prawdopodobne, aby były przenośne, ponieważ zwykle są pisane w językach określonych przez dostawcę, takich jak PL / SQL.
Ale jeśli ograniczenia nie spełniają Twoich potrzeb, zawsze możesz użyć wyzwalaczy w celu egzekwowania reguł biznesowych.
źródło
Zawsze powinny być najpierw stosowane w bazie danych, ponieważ
varchar(5)
typ, istnieje duża szansa, że znajdziesz schemat ładujący ORM dla określonego języka, który mapuje typ języka na typ schematu i zestawia własne ograniczenie wielkości.DBIx for Perl is one such schema loader
; tutaj jest inny dla Entity Framework . Możliwości tych programów ładujących są różne, ale wszystko, co mogą zapewnić, to dobry początek, aby zapewnić integralność aplikacji bez podróży do bazy danych.źródło