Pracowałem w niektórych projektach, w których większość logiki biznesowej została zaimplementowana w bazie danych (głównie poprzez procedury składowane). Z drugiej strony słyszałem od innych programistów, że jest to zła praktyka („Bazy danych służą do przechowywania danych. Aplikacje służą do reszty”).
Które z tych podejść jest ogólnie lepsze?
Zalety wdrażania logiki biznesowej w DB, o których mogę myśleć, to:
- Centralizacja logiki biznesowej;
- Niezależność rodzaju aplikacji, języka programowania, systemu operacyjnego itp .;
- Bazy danych są mniej podatne na migrację technologii lub duże refaktoryzacje (AFAIK);
- Brak przeróbek dotyczących migracji technologii aplikacji (np. .NET do Java, Perl do Python itp.).
Wady:
- SQL jest mniej produktywny i bardziej złożony w programowaniu logiki biznesowej, ze względu na brak bibliotek i konstrukcji językowych, które są najbardziej zorientowane na aplikacje;
- Trudniejsze (jeśli w ogóle możliwe) ponowne użycie kodu przez biblioteki;
- Mniej produktywne IDE.
Uwaga: bazy danych, o których mówię, są relacyjnymi, popularnymi bazami danych, takimi jak SQL Server, Oracle, MySql itp.
Dzięki!
Odpowiedzi:
Logika biznesowa nie wchodzi do bazy danych
Jeśli mówimy o aplikacjach wielowarstwowych, wydaje się całkiem jasne, że logika biznesowa, rodzaj inteligencji, która prowadzi określone przedsiębiorstwo, należy do warstwy logiki biznesowej, a nie do warstwy dostępu do danych.
Bazy danych wykonują kilka rzeczy naprawdę dobrze:
Teraz możesz oczywiście kodyfikować w bazie danych wszelkiego rodzaju rzeczy, które dotyczą twoich problemów biznesowych, takich jak stawki podatkowe, rabaty, kody operacyjne, kategorie i tak dalej. Ale działania biznesowe podejmowane na tych danych nie są generalnie zakodowane w bazie danych, z różnych powodów, o których wspominają już inni, chociaż w bazie danych można wybrać akcję i wykonać ją gdzie indziej.
I oczywiście mogą istnieć rzeczy, które są wykonywane w bazie danych z powodu wydajności i innych powodów:
Naturalnie nic nie jest wygrawerowane w kamieniu. Procedury przechowywane są odpowiednie dla szerokiego zakresu zadań po prostu dlatego, że żyją na serwerze bazy danych i mają pewne zalety i zalety.
Procedury przechowywane w dowolnym miejscu
Kodowanie wszystkich zadań przechowywania, zarządzania i pobierania danych w procedurach przechowywanych jest pewne, a korzystanie z powstałych usług danych jest pewne. Z pewnością skorzystasz z maksymalnej możliwej optymalizacji wydajności i bezpieczeństwa, jaką mógłby zapewnić serwer bazy danych, i to nie jest mała rzecz.
Ale co ryzykujesz?
I oczywiście, jeśli potrzebujesz usługi internetowej (i tak zapewne do tego właśnie zmierza), nadal będziesz musiał ją zbudować.
Jaka jest typowa praktyka?
Powiedziałbym, że typowym, nowoczesnym podejściem jest użycie Mapera relacyjno-obiektowego (takiego jak Entity Framework) do tworzenia klas modelujących tabele. Następnie możesz porozmawiać z bazą danych za pośrednictwem repozytorium, które zwraca kolekcje obiektów, co jest bardzo znane każdemu kompetentnemu twórcy oprogramowania. ORM dynamicznie generuje SQL odpowiadający Twojemu modelowi danych i żądanym informacjom, które następnie serwer bazy danych przetwarza, aby zwrócić wyniki zapytania.
Jak dobrze to działa? Bardzo dobrze i znacznie szybciej niż pisanie procedur przechowywanych i widoków. Zasadniczo obejmuje to około 80% wymagań dostępu do danych, głównie CRUD. Co obejmuje pozostałe 20%? Zgadłeś: procedury składowane, które bezpośrednio obsługują wszystkie główne ORM.
Czy możesz napisać generator kodu, który robi to samo co ORM, ale z procedurami przechowywanymi? Oczywiście że możesz. Ale ORM są na ogół niezależne od dostawcy, dobrze zrozumiałe dla wszystkich i lepiej obsługiwane.
źródło
Mocno wierzę w to, by logika biznesowa była jak najdalej od bazy danych. Jednak jako programista wydajności mojej firmy doceniam to, że czasami konieczne jest osiągnięcie dobrej wydajności. Ale myślę, że jest to konieczne znacznie rzadziej niż twierdzą ludzie.
Kwestionuję twoje zalety i wady.
Twierdzisz, że centralizuje ona logikę biznesową. Przeciwnie, myślę, że to je decentralizuje. W produkcie, nad którym obecnie pracuję, używamy procedury składowanej w dużej części naszej logiki biznesowej. Wiele naszych problemów z wydajnością wynika z wielokrotnego wywoływania funkcji. Na przykład
Problem z tym podejściem polega na tym, że ogólnie (w niektórych przypadkach może to być fałsz) zmusza bazę danych do uruchomienia funkcji N razy, raz na rząd. Czasami ta funkcja jest droga. Niektóre bazy danych obsługują indeksy funkcji. Ale nie można indeksować każdej możliwej funkcji względem każdego możliwego wejścia. Czy potrafisz
Typowym rozwiązaniem powyższego problemu jest wyodrębnienie logiki z funkcji i scalenie jej z zapytaniem. Teraz złamałeś enkapsulację i zduplikowaną logikę.
Kolejny problem, jaki widzę, to wywoływanie procedur przechowywanych w pętli, ponieważ nie ma możliwości połączenia ani przechowania przechowywanych zestawów wyników proc.
Jeśli wyciągniesz kod z zagnieżdżonego proc, następnie ponownie zdecentralizujesz. Dlatego musisz wybierać między enkapsulacją a wydajnością.
Ogólnie uważam, że bazy danych są złe w:
Bazy danych są dobre w:
Biorąc drogie operacje, takie jak pętle i analizowanie ciągów, i utrzymując je w warstwie aplikacji, możesz skalować aplikację w poziomie, aby uzyskać lepszą wydajność. Dodawanie wielu serwerów aplikacji za modułem równoważenia obciążenia jest zwykle znacznie tańsze niż konfigurowanie replikacji bazy danych.
Masz jednak rację, że oddziela logikę biznesową od języka programowania aplikacji, ale nie rozumiem, dlaczego jest to zaleta. Jeśli masz aplikację Java, masz aplikację Java. Przekształcanie wiązki kodu Java w procedury składowane nie zmienia faktu, że masz aplikację Java.
Preferuję utrzymywanie kodu bazy danych na trwałości. Jak utworzyć nowy widżet? Musisz wstawić do 3 tabel, które muszą być w transakcji. To należy do procedury składowanej.
Zdefiniowanie, co można zrobić z widgetem oraz reguł biznesowych dotyczących wyszukiwania widgetów należy do Twojej aplikacji.
źródło
Pracowałem w 2 różnych firmach, które miały odmienne zdanie na ten temat.
Moją osobistą sugestią byłoby użycie Procedur składowanych, gdy czas wykonania jest ważny (wydajność). Ponieważ procedura składowana jest kompilowana, jeśli masz złożoną logikę do wysyłania zapytań do danych, lepiej zachować ją w samej bazie danych. Ponadto wyśle tylko ostateczne dane do twojego programu na końcu.
W przeciwnym razie myślę, że logika programu powinna zawsze znajdować się w samym oprogramowaniu. Dlaczego? Ponieważ program musi być testowalny i nie sądzę, że istnieje prosty sposób na testowanie jednostkowe procedury składowanej. Nie zapominaj, że program, który nie jest testowany, jest złym programem.
Dlatego zachowaj ostrożność, gdy jest to konieczne.
źródło
Jest środek, który musisz znaleźć. Widziałem przerażające projekty, w których programiści używają bazy danych jako niczego więcej niż drogiego magazynu kluczy / wartości. Widziałem innych, w których programiści nie używają obcych kluczy i indeksów. Na drugim końcu spektrum widziałem projekty, w których większość, jeśli nie cała logika biznesowa, jest zaimplementowana w kodzie bazy danych.
Jak zauważyłeś, T-SQL (lub jego odpowiednik w innych popularnych RDBMS) nie jest najlepszym miejscem do kodowania złożonej logiki biznesowej.
Staram się zbudować całkiem przyzwoity model danych, używam funkcji bazy danych do ochrony moich założeń dotyczących tego modelu (tj. FK i ograniczeń) oraz oszczędnie używam kodu bazy danych. Kod bazy danych jest przydatny, gdy potrzebujesz czegoś (np. Sumy), którą baza danych robi bardzo dobrze i może zaoszczędzić ci przenoszenia zillionowych rekordów przez drut, kiedy ich nie potrzebujesz.
źródło
Jeśli logika biznesowa obejmuje operacje na zestawach, najprawdopodobniej dobrym miejscem jest baza danych, ponieważ systemy baz danych są naprawdę dobre w wykonywaniu operacji na zestawach.
http://en.wikipedia.org/wiki/Set_operations_(SQL)
Jeśli logika biznesowa wymaga pewnego rodzaju obliczeń, prawdopodobnie należy do procedury bazy danych / sklepu, ponieważ bazy danych nie są tak naprawdę zaprojektowane do zapętlania i obliczania.
Chociaż nie są to twarde i szybkie zasady, jest to dobry punkt wyjścia.
źródło
Nie ma jednej właściwej odpowiedzi na to. To zależy od tego, do czego używasz bazy danych. W aplikacji korporacyjnej logika w bazie danych wymaga kluczy obcych, ograniczeń, wyzwalaczy itp., Ponieważ jest to jedyne miejsce, w którym wszystkie możliwe aplikacje współużytkują kod. Ponadto umieszczenie wymaganej logiki w kodzie ogólnie oznacza, że baza danych jest niespójna, a dane niskiej jakości. Może się to wydawać trywialne dla devloper aplikacji, który tylko nie rozumie, jak działa GUI, ale zapewniam cię, że ludzie próbujący wykorzystać dane w raportach zgodności uważają to za bardzo denerwujące i kosztowne, gdy dostają kary pieniężne w wysokości miliarda dolarów za posiadanie danych, które nie nie przestrzegaj poprawnie zasad.
W środowisku nieregulacyjnym, gdy nie dbasz o cały zestaw rekordów i tylko jedna lub dwie aplikacje trafiają do bazy danych, być może uda ci się utrzymać wszystko w aplikacji.
źródło
Po kilku latach pytanie jest nadal ważne ...
Prosta praktyczna zasada: jeśli jest to ograniczenie logiczne lub wszechobecne wyrażenie (pojedyncza instrukcja), umieść je w bazie danych (tak, klucze obce i ograniczenia sprawdzania również są logiką biznesową!). Jeśli jest to proceduralne, zawierające pętle i gałęzie warunkowe (i tak naprawdę nie można ich zmienić w wyrażenie), umieść je w kodzie.
Unikaj baz danych zrzutu śmieci
Próby umieszczenia naprawdę całej logiki biznesowej w kodzie aplikacji prawdopodobnie zdegenerują (relacyjną) bazę danych do kosza na śmieci, gdzie projekt relacyjny jest w większości całkowicie pomijany, gdzie dane mogą mieć dowolny niespójny stan i brakuje normalizacji (często głównie XML, JSON , CSV itp. Kolumny kosza).
Ten rodzaj logiki opartej tylko na aplikacjach jest prawdopodobnie jednym z głównych powodów wzrostu NoSQL - oczywiście z wadą, że aplikacja musi zadbać o całą logikę, która była wbudowana w relacyjną bazę danych od dziesięcioleci. Jednak bazy danych NoSQL są bardziej odpowiednie do tego rodzaju przetwarzania danych, na przykład dokumenty danych zachowują w sobie „integralność relacyjną”. W przypadku relacyjnych baz danych jest to po prostu nadużycie, powodujące coraz więcej problemów.
Wyrażenia (oparte na zestawie) zamiast kodu proceduralnego
W najlepszym przypadku każde zapytanie lub operacja na danych powinny być kodowane jako wyrażenie, a nie kod proceduralny. Świetnym wsparciem jest to, gdy języki programowania obsługują wyrażenia, takie jak LINQ w świecie .NET (niestety, tylko zapytania obecnie, bez manipulacji). Po stronie relacyjnej bazy danych od dłuższego czasu uczy się, jak preferować wyrażenia instrukcji SQL zamiast proceduralnych pętli kursora. Więc DB może zoptymalizować, wykonać operację równolegle lub cokolwiek, co może być przydatne.
Wykorzystaj mechanizmy integralności danych DB
Jeśli chodzi o RDBMS z ograniczeniami klucza obcego i sprawdzania, kolumn obliczeniowych, ewentualnie wyzwalaczy i widoków, jest to miejsce do przechowywania podstawowej logiki biznesowej w bazie danych. Właściwa normalizacja pomaga zachować integralność danych, aby zapewnić unikalny i wyraźny przypadek danych. Nawet jeśli musisz powielić go w kodzie i DB, te podstawowe mechanizmy integralności danych nie powinny zostać pominięte!
Procedury przechowywane?
Procedury przechowywane są w dzisiejszych czasach rzadko potrzebne, ponieważ bazy danych przechowują skompilowane plany wykonania dla SQL i wykorzystują je ponownie, gdy pojawi się to samo zapytanie, tylko z różnymi parametrami. Zatem argument prekompilacji dla SP nie jest już prawidłowy. Można przechowywać lub automatycznie generować zapytania SQL w aplikacji lub ORM, które przez większość czasu znajdą wstępnie skompilowane plany zapytań. SQL jest językiem wyrażeń, o ile nie używa się jawnie elementów proceduralnych. Zatem w najlepszym przypadku używasz wyrażeń kodu, które można przetłumaczyć na SQL.
Podczas gdy strona aplikacji, w tym wygenerowany ORM, SQL, nie znajduje się już w bazie danych, w przeciwieństwie do procedur przechowywanych, nadal liczę go jako kod bazy danych. Ponieważ nadal wymaga znajomości SQL i bazy danych (z wyjątkiem najprostszego CRUD), a przy prawidłowym zastosowaniu działa znacznie inaczej niż kod proceduralny zwykle tworzony w językach programowania takich jak C # lub Java.
źródło
To zależy od biznesu, jego kultury i dziedzictwa. Pomijając względy techniczne (zostały omówione z obu stron), podane odpowiedzi mówią, że sprowadza się to do tego, skąd pochodzą ludzie. W niektórych organizacjach dane są najważniejsze, a DBA jest potężną postacią. Jest to typowe scentralizowane środowisko, centrum danych z dołączoną do niego grupą terminali. Preferowanie w tego typu środowisku jest jasne. Pulpit może się radykalnie zmieniać wiele razy, zanim cokolwiek zmieni się w centrum danych, a pomiędzy nimi będzie niewiele.
Drugi koniec spektrum to czysta architektura 3-poziomowa. A może wielopoziomowy w biznesie zorientowanym na sieć. Prawdopodobnie usłyszysz tutaj inną historię. DBA, jeśli istnieje, będzie tylko pomocnikiem, który wykonuje niektóre zadania administracyjne.
Współczesny twórca aplikacji będzie miał większe powinowactwo z drugim modelem. Jeśli dorastałeś z dużym systemem klient-serwer, prawdopodobnie byłbyś w innym obozie.
Często występuje tu tak wiele nietechnicznych czynników związanych ze środowiskiem, że nie ma ogólnej odpowiedzi na to pytanie.
źródło
Pojęcie logiki biznesowej jest otwarte na interpretację. Budując systemy, chcemy zapewnić integralność bazy danych i jej zawartości. Pierwszym krokiem powinny być różne granty dostępu użytkowników. Jako bardzo prosty przykład rozważmy aplikację ATM.
Aby uzyskać saldo konta, należy dokonać wyboru w odpowiednim widoku. Ale aby przelać środki, transakcja powinna zostać zamknięta w procedurze przechowywanej. Logika biznesowa nie powinna mieć możliwości bezpośredniego aktualizowania tabel dla kwot kredytu i obciążenia.
W tym przykładzie logika biznesowa może sprawdzić saldo przed zażądaniem przeniesienia lub po prostu wywołać zapisany proc dla przeniesienia i zgłosić awarię. IMHO, logika biznesowa, w tym przykładzie, powinna uprzednio sprawdzić, czy dostępne są wystarczające środki i czy istnieje rachunek docelowy, i dopiero wtedy wywołać fundusze transferowe. Jeśli między początkowymi krokami a przechowywanym wywołaniem proc nastąpi kolejne obciążenie, tylko wtedy zwrócony zostanie błąd.
źródło