Pracuję nad projektem w jednej z 3 najlepszych firm konsultingowych na świecie, a DBA powiedział mi, że stanowe procedury magazynowe najlepszych praktyk firmy nie są „najlepszą praktyką”. Jest to tak sprzeczne ze wszystkim, czego się nauczyłem.
Przechowywane procedury zapewniają ponowne użycie kodu i hermetyzację (dwa filary rozwoju oprogramowania), bezpieczeństwo (możesz udzielać / cofać uprawnienia do pojedynczego przechowywanego proc), chronić cię przed atakami iniekcji SQL, a także pomagać w szybkości (chociaż DBA powiedział, że począwszy od SQL Server 2008, że nawet regularne zapytania SQL są kompilowane, jeśli są uruchamiane wystarczająco dużo razy.
Tworzymy złożoną aplikację przy użyciu metodologii tworzenia oprogramowania Agile. Czy ktoś może wymyślić dobre powody, dla których nie chciałby korzystać z przechowywanych procesów? Domyślam się, że DBA nie chcieli utrzymywać tych przechowywanych proc, ale wydaje się, że istnieje zbyt wiele negatywów, aby uzasadnić taką decyzję projektową.
źródło
Odpowiedzi:
Z mojego doświadczenia w pracy nad bardzo dużymi projektami, musisz bardzo jasno wiedzieć, gdzie mieszka logika biznesowa. Jeśli dopuścisz środowisko, w którym indywidualni programiści mogą umieszczać logikę biznesową w warstwie obiektów biznesowych lub w procedurze przechowywanej według własnego uznania, duża aplikacja staje się BARDZO trudna do zrozumienia i utrzymania.
Procedury przechowywane świetnie przyspieszają niektóre operacje DB. Moją architektoniczną decyzją jest pozostawienie całej logiki w warstwie biznesowej aplikacji i stosowanie procedur przechowywanych w ukierunkowany sposób, aby poprawić wydajność tam, gdzie analiza porównawcza wskazuje, że jest to uzasadnione.
źródło
Kilka uwag
Tylko jeśli użyjesz ich poprawnie w kontekście, w którym mają być używane. To samo twierdzenie można powiedzieć o funkcjach (w programowaniu strukturalnym) lub metodach (w programowaniu obiektowym), a jednak widzimy funkcje 1K i obiekty mega-ass.
Artefakty nie dają tych korzyści. Właściwe użycie tych artefaktów daje te korzyści.
Tak. To dobra uwaga i jeden z głównych powodów, dla których lubię procedury składowane. Zapewniają bardziej szczegółową kontrolę dostępu niż to, co zwykle można osiągnąć za pomocą samych widoków i kont użytkowników.
Nie jest to specyficzne dla SP, ponieważ można osiągnąć ten sam poziom ochrony dzięki sparametryzowanym instrukcjom SQL i czyszczeniu danych wejściowych. Chciałbym jednak używać SP oprócz tych, ponieważ jest to kwestia „głębokiego bezpieczeństwa” .
Jest to ściśle zależne od dostawcy bazy danych, ale ogólnie rzecz biorąc, Twój DBA ma rację. Instrukcje SQL (statyczne lub parametryzowane) są kompilowane. SP pomagają, jeśli chcesz / potrzebujesz agregować i obliczać dane, których nie możesz zrobić za pomocą prostych instrukcji SQL, ale są ściśle zintegrowane z SQL i nie gwarantują powrotu do serwera aplikacji.
Dobrym przykładem jest zapytanie danych do tymczasowego kursora (lub kursorów), z którego można uruchomić inny sam SQL. Możesz to zrobić programowo na serwerze aplikacji lub możesz zapisać wiele podróży w obie strony, robiąc to w db.
Nie powinno to jednak być normą. Jeśli masz wiele takich przypadków, oznacza to, że projekt bazy danych jest zły (lub pobierasz dane z niezbyt zgodnych schematów bazy danych w różnych działach).
Zwinność dotyczy procesów inżynierii oprogramowania i zarządzania wymaganiami, a nie technologii.
Złe pytanie
Pytanie jest błędne i równoznaczne z pytaniem „czy istnieją dobre powody, aby nie używać GOTO”? Popieram ten temat z Niklausem Wirthem bardziej niż z Dijkstrą. Rozumiem, skąd się wziął sentyment Dijkstry, ale nie sądzę, aby miał on zastosowanie w 100% we wszystkich przypadkach. To samo dotyczy procedur sklepowych i dowolnej technologii.
Narzędzie jest dobre, gdy jest dobrze używane zgodnie z przeznaczeniem i jest najlepszym narzędziem do określonego zadania. Używanie go w inny sposób nie oznacza, że narzędzie jest złe, ale że posiadacz nie wie, co robi.
Prawidłowe pytanie brzmi: „jakiego rodzaju wzorców użycia procedur składowanych należy unikać”. Lub „pod jakimi warunkami powinienem (lub nie powinienem) stosować procedur przechowywanych” . Szukanie powodów, dla których nie należy korzystać z technologii, to po prostu obwinianie narzędzia, a nie odpowiedzialność inżyniera dokładnie tam, gdzie należy - inżyniera.
Innymi słowy, jest to przekręt lub oświadczenie o ignorancji.
To, co robią, to rzutowanie wyników złych decyzji inżynieryjnych na narzędzia, których źle używali.
Co robić w twoim przypadku?
Moje doświadczenie polega na tym, że w Rzymie postępujcie tak, jak Rzymianie .
Nie walcz z tym. Jeśli ludzie w Twojej firmie chcą oznaczyć procesy sklepowe jako złą praktykę, pozwól im. Należy jednak pamiętać, że może to być czerwona flaga w ich praktykach inżynierskich.
Typowe etykietowanie rzeczy jako złych praktyk jest zwykle wykonywane w organizacjach z mnóstwem niekompetentnych programistów. Umieszczając na czarnej liście niektóre rzeczy, organizacja stara się ograniczyć szkody wyrządzone wewnętrznie przez własną niekompetencję. Nie gówno mnie.
Uogólnienia są matką wszystkich wpadek. Mówienie, że przechowywane procy (lub jakikolwiek rodzaj technologii) to zła praktyka, to uogólnienie. Uogólnienia są wyłudzeniami dla niekompetentnych. Inżynierowie nie pracują z rażącymi uogólnieniami. Wykonują analizy indywidualnie dla każdego przypadku, dokonują analizy kompromisów i wykonują decyzje i rozwiązania inżynierskie zgodnie z faktami, w kontekście, w którym mają rozwiązać problem.
Dobrzy inżynierowie nie określają rzeczy jako złej praktyki w tak uogólniony sposób. Patrzą na problem, wybierają odpowiednie narzędzia, dokonują kompromisów. Innymi słowy, zajmują się inżynierią.
Moja opinia o tym, jak ich nie używać
Nie umieszczaj w nich złożonej logiki poza gromadzeniem danych (i być może niektórymi transformacjami). Można w nich umieścić logikę masowania danych lub zsumować z nimi wynik wielu zapytań. Ale to jest o tym. Cokolwiek poza tym kwalifikuje się jako logika biznesowa, która powinna znajdować się gdzie indziej.
Nie używaj ich jako jedynego mechanizmu obrony przed wstrzyknięciem SQL. Zostawiasz je tam na wypadek, gdyby coś złego im się przydarzyło , ale przed nimi powinna być logika obronna - walidacja / szorowanie po stronie klienta, walidacja / szorowanie po stronie serwera, ewentualnie transformacja w typy, które mają sens w twoim model domeny, a na koniec przekazywane do sparametryzowanych instrukcji (które mogą być sparametryzowanymi instrukcjami SQL lub sparametryzowanymi przechowywanymi proc.)
Nie rób baz danych jedynym miejscem zawierającym informacje o sklepach. Procesy sklepu powinny być traktowane tak samo, jak traktujesz kod źródłowy C # lub Java. Oznacza to, że kontroluj źródła tekstową definicją Twojego sklepu. Ludzie twierdzą, że procesy sklepowe nie mogą być kontrolowane przez źródło - byk, po prostu nie wiedzą o czym, do diabła, mówią.
Moja opinia o tym, jak / gdzie ich używać
Twoja aplikacja wymaga transponowania lub agregacji danych z wielu zapytań lub widoków. Możesz odciążyć to z aplikacji do bazy danych. W tym przypadku musisz wykonać analizę wydajności, ponieważ a) silniki baz danych są bardziej wydajne niż serwery aplikacji, ale b) serwery aplikacji są (czasami) łatwiejsze do skalowania w poziomie.
Kontrola dostępu do drobnych ziaren. Nie chcesz, żeby jakiś idiota prowadzący połączenia kartezjańskie w twojej bazie danych, ale nie możesz po prostu zabronić ludziom wykonywania dowolnych instrukcji SQL w ten sposób. Typowym rozwiązaniem jest dopuszczanie dowolnych instrukcji SQL w środowiskach programistycznych i UAT, przy jednoczesnym zabronieniu ich w środowisku systest i produkcyjnym. Każde oświadczenie, które musi przejść do systestu lub produkcji, przechodzi do procedury sklepu, sprawdzanej zarówno przez programistów, jak i dbas.
Każda ważna potrzeba uruchomienia instrukcji SQL spoza procesu sklepu przechodzi przez inną nazwę użytkownika / konto i pulę połączeń (użycie jest wysoce monitorowane i odradzane).
To, czy uruchomisz to na db jako procesorze sklepu, czy na serwerze aplikacji, zależy od analizy kompromisowej, którą musisz wykonać jako inżynier. Obie opcje muszą zostać przeanalizowane i uzasadnione pewnym rodzajem analizy. Idąc w tę lub inną stronę, po prostu oskarżając inną alternatywę jako „złą praktykę”, jest to po prostu kiepska inżynieria.
Niezależnie od tego, czy stanie się to trwałym rozwiązaniem, czy nie, jest to specyficzne dla ograniczeń zaobserwowanych w danym momencie.
Mam nadzieję, że to pomoże.
źródło
Uzasadnieniem jest to, że poleganie na warstwie procedur przechowywanych ogranicza przenośność i wiąże cię z określoną bazą danych. Powodem są również dodatkowe koszty utrzymania. Chciałem również skomentować ten punkt, który uczyniłeś:
To właściwie parametryzowane zapytania, które cię chronią, co możesz łatwo zrobić w zapytaniach sql w postaci zwykłego tekstu.
źródło
+ "blablabla"
ponieważ należy zezwolić na zwykły SQL i na tym kończy się kontrola.Niektóre z powodów, dla których zgadzam się na przechowywane procedury nie są najlepszą praktyką.
źródło
Tak, ale kosztem osiągnięcia innych zwinnych celów projektowych. Po pierwsze, są trudniejsze do utrzymania. Jeśli projekt, który wykonuję, jest jakimś wskaźnikiem, prawdopodobnie skończy się na wielu niezgodnych SP, które wykonują zasadniczo tę samą pracę, bez żadnych korzyści.
Nie, oni nie. Nie mogę nawet zacząć zgadywać, skąd wziął się ten pomysł, jak to często słyszę, i to po prostu nieprawda. Może to złagodzić niektóre typy ataków typu SQL injection, ale jeśli nie używasz sparametryzowanych zapytań, nie będzie to miało znaczenia. Nadal mogę ”; DROP TABLE Konta; -
Są one zwykle kompilowane, gdy używasz przygotowanych, sparametryzowanych instrukcji (przynajmniej z kilkoma bazami danych, których użyłem). Do czasu, gdy aplikacja zacznie wykonywać zapytanie (a zwłaszcza, jeśli wykonujesz to samo przygotowane zapytanie wiele razy), wszelkie korzyści wydajnościowe, które Twoim zdaniem mają SP, są całkowicie dyskusyjne.
Tylko powód do korzystania z procedury przechowywanej, IMHO, kiedy trzeba zrobić kompleksowy, wielostopniowe kwerendę, która ściąga z wielu źródeł z sortowaniem. SP nie powinny zawierać logiki decyzyjnej niskiego poziomu i nigdy nie powinny po prostu zawierać prostego zapytania. Nie ma żadnych korzyści i tylko wiele wad.
Słuchaj swojego DBA. On wie, co jest grane.
źródło
To była oficjalna linia, kiedy kilka lat temu pracowałem dla jednej z Wielkiej Piątki. Uzasadnieniem było to, że ponieważ SP są powiązane z konkretnymi implementacjami (PL / SQL vs T / SQL vs ...), niepotrzebnie ograniczają możliwości wyboru technologii.
Po przejściu migracji jednego dużego systemu z T / SQL na PL / SQL, rozumiem ten argument. Myślę, że to trochę jak kanarek - ile miejsc naprawdę przenosi się z jednej bazy danych do drugiej kaprysem?
źródło
Wszystkie trzy firmy, w których pracuję, używają procedur przechowywanych do ich logiki aplikacji w SQL Server. Tak naprawdę nie widziałem rzeczy w drugą stronę. Ale dla mnie to wielki bałagan. Zwykle nie ma bardzo dobrych narzędzi do obsługi błędów lub narzędzi do ponownego użycia kodu z procedurami przechowywanymi.
Załóżmy, że masz procedurę składowaną, która zwraca zestaw danych, którego chcesz użyć. Jak możesz go wykorzystać w przyszłych procedurach przechowywanych? Mechanizmy SQL Server do tego nie są bardzo dobre. EXEC INTO ... działa tylko na jeden lub dwa poziomy zagnieżdżenia (teraz zapominam). Lub musisz wstępnie zdefiniować stół roboczy i zlecić jego przetworzenie kluczem. Lub musisz wstępnie utworzyć tabelę tymczasową i wypełnić ją procedurą. Ale co, jeśli dwie osoby nazywają tabelę tymczasową tą samą rzeczą w dwóch różnych procedurach, których nigdy nie planowały stosować w tym samym czasie? W dowolnym normalnym języku programowania możesz po prostu zwrócić tablicę z funkcji lub wskazać obiekt / strukturę globalną współdzieloną między nimi (z wyjątkiem języków funkcjonalnych, w których zwrócisz strukturę danych, a nie tylko zmieniając strukturę globalną ... )
Co powiesz na ponowne użycie kodu? Jeśli zaczniesz umieszczać typowe wyrażenia w UDF (lub jeszcze gorzej podpytania), spowolnisz kod. Nie można wywołać procedury składowanej w celu wykonania obliczeń dla kolumny (chyba że użyjesz kursora, przekażesz wartości kolumn jeden po drugim, a następnie jakoś zaktualizujesz tabelę / zestaw danych). Zasadniczo, aby uzyskać najwyższą wydajność, musisz wycinać / wklejać wspólne wyrażenia w dowolnym miejscu, co jest koszmarem konserwacyjnym ... Za pomocą języka programowania można utworzyć funkcję generowania wspólnego SQL, a następnie wywoływać go z dowolnego miejsca podczas budowania ciąg SQL. Jeśli chcesz dostosować formułę, możesz dokonać zmiany w jednym miejscu ...
Co z obsługą błędów? SQL Server ma wiele błędów, które natychmiast zatrzymują wykonywanie procedury przechowywanej, a niektóre nawet zmuszają do rozłączenia. Od 2005 r. Występuje próba złapania, ale wciąż istnieje wiele błędów, których nie można wykryć. To samo dzieje się z powielaniem kodu w kodzie obsługi błędów i naprawdę nie można tak łatwo przekazywać wyjątków ani przenosić ich na wyższe poziomy tak łatwo, jak większość języków programowania .....
Również po prostu prędkość. Wiele operacji na zestawach danych nie jest zorientowanych na SET. Jeśli spróbujesz robić rzeczy zorientowane na wiersze, albo użyjesz kursora, albo użyjesz „kursora” (gdy programiści często sprawdzają każdy wiersz jeden po drugim i przechowują zawartość w zmiennych @ tak jak kursor. .. Nawet jeśli jest to często wolniejsze niż kursor FORWARD_ONLY). Z SQL Server 2000 miałem coś, co działało przez 1 godzinę, zanim go zabiłem. Przepisałem ten kod w Perlu i skończył się w 20 minut. Kiedy język skryptowy, który jest 20-80x wolniejszy niż C, pali SQL w wydajności, na pewno nie ma biznesowych operacji pisania w SQL w wierszach.
Teraz SQL Server ma integrację z CLR i wiele z tych problemów zniknie, jeśli użyjesz procedur przechowywanych CLR. Ale wielu DBA nie wie, jak pisać programy .NET lub wyłączać CLR ze względów bezpieczeństwa i trzymać się Transact SQL .... Również z CLR nadal masz problemy z efektywnym udostępnianiem danych między wieloma procedurami .
Ogólnie najtrudniejszą rzeczą do skalowania jest baza danych. Jeśli cała logika biznesowa znajduje się w bazie danych, wtedy, gdy baza danych stanie się zbyt wolna, wystąpią problemy. Jeśli masz warstwę biznesową, możesz po prostu dodać więcej pamięci podręcznej i więcej serwerów biznesowych, aby zwiększyć wydajność. Tradycyjnie inny serwer do instalowania systemu Windows / Linux i uruchamiania .NET / Java jest znacznie tańszy niż kupowanie innego serwera bazy danych i licencjonowanie większej ilości SQL Server. SQL Server ma teraz więcej obsługi klastrów, pierwotnie tak naprawdę nie miał. Więc jeśli masz dużo pieniędzy, możesz dodać klastrowanie lub nawet wysłać dziennik, aby utworzyć wiele kopii tylko do odczytu. Ale ogólnie będzie to kosztować znacznie więcej niż tylko zapis za pamięcią podręczną lub coś takiego.
Zobacz także narzędzia Transact-SQL. Manipulacja ciągiem? Przyjmę klasy Java String Class / Tokenizer / Scanner / Regex każdego dnia. Tabele skrótów / Listy połączone / Itd. Wezmę frameworki Java Collection itp. I to samo dla .NET ... Zarówno C #, jak i Java są znacznie bardziej rozwiniętymi językami niż Transact SQL ... Kodowanie Heck za pomocą Transact-SQL sprawia, że jestem zazdrosny o C .. .
Dodatkowo, procedury składowane są bardziej wydajne do pracy z dużym zbiorem danych i stosowania wielu zapytań / kryteriów w celu zmniejszenia go przed powrotem do warstwy biznesowej. Jeśli musisz wysłać kilka ogromnych zestawów danych do aplikacji klienckiej i rozbić dane na kliencie, będzie to znacznie bardziej nieefektywne niż wykonywanie całej pracy na serwerze.
Również procedury składowane są dobre dla bezpieczeństwa. Możesz wyciąć cały dostęp do bazowych tabel i zezwolić na dostęp tylko poprzez procedury składowane. Dzięki niektórym nowoczesnym technikom, takim jak XML, możesz mieć procedury składowane, które wykonują aktualizacje wsadowe. Następnie cały dostęp jest kontrolowany za pomocą procedur przechowywanych, tak długo, jak długo są one bezpieczne / poprawne, dane mogą mieć większą integralność.
Argument wtrysku SQL tak naprawdę już nie ma zastosowania, ponieważ sparametryzowaliśmy zapytania po stronie języka programowania. Również naprawdę, nawet przed sparametryzowanymi zapytaniami, trochę zastąpienia („” „,” „”) również działało przez większość czasu (chociaż nadal istnieją sztuczki, aby przejść poza koniec łańcucha, aby uzyskać to, czego chcesz).
Ogólnie myślę, że SQL i Transact SQL są świetnymi językami do wysyłania zapytań / aktualizacji danych. Ale za kodowanie dowolnego rodzaju logiki, manipulowanie ciągami (lub cholera manipulacja plikiem ... zdziwiłbyś się, co możesz zrobić z xp_cmdshell ....), proszę nie. Mam nadzieję, że znajdę przyszłe miejsce, które najczęściej nie korzysta z procedur przechowywanych. Z punktu widzenia utrzymania kodu są koszmarem. Co się stanie, jeśli chcesz zmienić platformę (chociaż tak naprawdę, jeśli zapłaciłeś za Oracle / DB2 / Sybase / Sql Server / itp.) Możesz równie dobrze uzyskać z nich wszystko, korzystając z każdego zastrzeżonego rozszerzenia, które ci pomoże. ..).
Co zaskakujące, często logika biznesowa nie jest taka sama. W idealnym świecie umieściłbyś całą logikę w procedurach przechowywanych i podzieliłbyś się nimi między aplikacjami. Ale dość często logika różni się w zależności od aplikacji, a twoje procedury składowane stają się zbyt złożonymi monolitami, których ludzie boją się zmienić i nie rozumieją wszystkich implikacji. Podczas gdy w dobrym języku obiektowym można kodować warstwę dostępu do danych, która ma pewne standardowe interfejsy / haki, które każda aplikacja może zastąpić według własnych potrzeb.
źródło
Jak oceniasz wersje procedur przechowywanych na serwerze?
Jeśli ponownie wdrożysz procedury przechowywane na serwerze z kontroli wersji, wysadzisz zapisany plan wykonania.
Procedury przechowywane nie powinny być modyfikowalne bezpośrednio na serwerze, w przeciwnym razie skąd wiesz, co tak naprawdę działa _ teraz? Jeśli nie są, narzędzie wdrażania potrzebuje dostępu do zapisu procedur przechowywanych w bazie danych. Będziesz musiał wdrożyć na każdej kompilacji (być może plan wykonania musi być inny)
Chociaż procedury składowane nie są przenośne, SQL nie jest w ogóle (nigdy nie widziałem obsługi daty Oracle - uggghhh).
Jeśli więc chcesz mieć przenośność, zbuduj wewnętrzny interfejs API dostępu do danych. Możesz wywoływać to jak wywołania funkcji, a wewnętrznie możesz wbudować w dowolny żargon, jakiego potrzebujesz, ze sparametryzowanymi zapytaniami, i może być kontrolowany pod kątem wersji.
źródło
Być może będziesz musiał wydostać się więcej. [uśmiech] Poważnie, przechowywane procy spadają od co najmniej 10 lat. Prawie odkąd n-poziom zastąpił klient-serwer. Spadek ten został przyspieszony dopiero dzięki przyjęciu języków OO, takich jak Java, C #, Python itp.
Nie oznacza to, że przechowywane procy nadal nie mają swoich zwolenników i zwolenników - ale jest to długotrwała dyskusja i debata. Nie jest nowy i prawdopodobnie będzie trwał przez dłuższy czas; IMO, przeciwnicy przechowywanych proców wyraźnie wygrywają.
Bardzo prawdziwe. Ale także przyzwoicie zaprojektowana warstwa OO.
Chociaż możesz to zrobić, niewielu robi to z powodu poważnych ograniczeń. Bezpieczeństwo na poziomie DB nie jest wystarczająco szczegółowe, aby podejmować decyzje kontekstowe. Ze względu na narzut związany z wydajnością i zarządzaniem niezwykłe są również połączenia dla poszczególnych użytkowników - więc nadal potrzebujesz pewnego poziomu autoryzacji w kodzie aplikacji. Możesz korzystać z loginów opartych na rolach, ale musisz je utworzyć dla nowych ról, utrzymać rolę, którą uruchamiasz, przełączyć połączenia, aby „na poziomie systemu” działały jak logowanie itp. I na koniec, jeśli Twoja aplikacja jest własnością - podobnie jak twoje połączenie z bazą danych.
Nie więcej niż robienie sparametryzowanych zapytań. Co i tak musisz zrobić.
Myślę, że zaczęło się to w MSSQL 7 lub 2000. Było wiele debat, pomiarów i dezinformacji na temat przechowywanego proc vs. wbudowanej wydajności SQL - zbijam to wszystko pod YAGNI. A jeśli potrzebujesz, przetestuj.
Nie mogę myśleć o wielu powodów byś chcą się. Java / C # / jakikolwiek trzeci język GL są znacznie bardziej zdolne niż T-SQL do enkapsulacji, ponownego użycia i elastyczności itp. Większość z nich jest darmowa, biorąc pod uwagę przyzwoitą ORM.
Ponadto, biorąc pod uwagę radę „rozpowszechniać w miarę potrzeb, ale nie więcej” - myślę, że ciężar dowodu spoczywa obecnie na zwolennikach SP. Częstym powodem przechowywania zapisanego proc heavy jest to, że T-SQL jest łatwiejszy niż OO, a sklep ma lepsze T-SQL dev niż OO. Lub, że DBA zatrzymuje się na warstwie bazy danych, a przechowywane procy to interfejs między dev i DBA. Lub wysyłasz pół-niestandardowy produkt, a przechowywane procesy można dostosować do własnych potrzeb. Bez takich rozważań myślę, że domyślnym domyślnym projektem Agile SW będzie ORM.
źródło
Biorąc pod uwagę wszystkie powyższe przypadki, chciałbym dodać jeszcze jeden. Wybór SP może zależeć również od wyboru ludzi.
Osobiście czuję się sfrustrowany, gdy ludzie wprowadzają bardzo złożoną logikę do SP i uważam, że takie SP jest bardzo skomplikowane w utrzymaniu i debugowaniu. Nawet w wielu przypadkach sam deweloper ma problem z debugowaniem kodu z tyłu (powiedzmy część językową) jest znacznie łatwiejszy niż w SP.
SP należy używać wyłącznie do prostych operacji. To mój wybór.
źródło
Chcę objąć zarówno niektóre problemy pro, jak i problemy zapisanymi procesami. Używamy ich szeroko z LedgerSMB , a naszą zasadą jest, z kilkoma bardzo szczegółowymi rozszerzeniami, „jeśli jest to zapytanie, uczyń z niego przechowywany proc”.
Naszym powodem było ułatwienie ponownego wykorzystania zapytań między językami. Nie ma lepszego sposobu, aby to zrobić uczciwie.
W końcu pytanie zawsze dotyczy szczegółów. Dobrze stosowane, przechowywane procedury znacznie ułatwiają, a źle stosowane znacznie utrudniają.
Przejdźmy do strony przeciwnej.
Tradycyjnie stosowane procedury przechowywane są kruche. Używane osobno stwarzają możliwość dodawania błędów w kodzie w miejscach, których nie spodziewałeś się bez żadnego innego powodu niż zmiana składni wywołania. Używanie w pojedynkę to trochę problemu. Zbyt duża spójność między warstwami powoduje problemy.
Tak, możliwe jest wykonanie iniekcji SQL-sproc podczas wykonywania dowolnego dynamicznego SQL. Nie należy być zbyt pewnym siebie w tej dziedzinie, dlatego należy mieć duże doświadczenie w zakresie bezpieczeństwa w tej dziedzinie.
Zmiany w interfejsach są nieco problematyczne w przypadku procedur przechowywanych z powodu nr 1 powyżej, ale może to stać się bardzo dużym koszmarem, jeśli zaangażowana jest duża liczba aplikacji klienckich.
Trudno zaprzeczyć powyższym. Zdarzają się. Wszyscy, pro-SP i anty-SP, prawdopodobnie mieli na ten temat horrory. Problemy nie są nierozwiązywalne, ale jeśli nie zwracasz na nie uwagi, nie możesz ich rozwiązać (w LedgerSMB używamy lokalizatora usług do dynamicznego budowania wywołań SP w czasie wykonywania, unikając całkowicie powyższych problemów. Podczas gdy jesteśmy PostgreSQL tylko coś podobnego można zrobić dla innych baz danych).
Do pozytywów. Zakładając, że możesz rozwiązać powyższe problemy, otrzymasz:
Możliwość zwiększenia przejrzystości w ustawionych operacjach. Jest to szczególnie prawdziwe, jeśli zapytanie jest bardzo duże lub bardzo elastyczne. Prowadzi to również do lepszej testowalności.
Jeśli mam już lokalizator usług działający w tym obszarze, uważam, że procedury przechowywane przyspieszają tempo programowania, ponieważ uwalniają programistę aplikacji od problemów z db i odwrotnie. Ma to pewne trudności z właściwym postępowaniem, ale nie jest to trudne.
Ponowne użycie zapytania.
No i kilka rzeczy, których prawie nigdy nie powinieneś robić w SP:
logika nietransakcyjna. Wysłałeś wiadomość e-mail, że zamówienie zostało wysłane, ale transakcja została wycofana ... lub teraz czekasz, aby serwer e-mail przeszedł w tryb online ... lub, co gorsza, wycofujesz transakcję tylko dlatego, że nie możesz dotrzeć do serwer e-mail ....
wiele małych zapytań luźno powiązanych ze sobą, pokrytych logiką proceduralną ...
źródło
Dla kogo pracujesz?
Odpowiedź może zależeć od tego, kim jesteś zatrudniony, firmą konsultingową lub samą firmą. To, co najlepsze dla firmy, często nie jest najlepsze dla firmy konsultingowej lub innego dostawcy oprogramowania. np. Inteligentna firma pragnie mieć stałą przewagę nad konkurentami. Z drugiej strony sprzedawca oprogramowania chce mieć możliwość zaoferowania tego samego rozwiązania wszystkim firmom w danej branży za najniższy koszt. Jeśli im się to uda, klient nie uzyska przewagi konkurencyjnej netto.
W tym konkretnym przypadku aplikacje przychodzą i odchodzą, ale bardzo często korporacyjna baza danych trwa wiecznie. Jedną z podstawowych rzeczy, którą robi RDBMS, jest zapobieganie przedostawaniu się niepotrzebnych danych do bazy danych. Może to obejmować procedury składowane. Jeśli logika jest dobra i bardzo mało prawdopodobne jest, aby zmieniała się z roku na rok, dlaczego nie powinna znajdować się w bazie danych, utrzymując ją wewnętrznie spójną, niezależnie od tego, jaką aplikację napisano w celu korzystania z bazy danych? Wiele lat później ktoś będzie miał pytanie, które chce zadać z bazy danych, i odpowie na nie, jeśli śmieci nie wejdą do bazy danych.
Może więc ma to coś wspólnego z faktem, że Twój DBA pracuje dla firmy konsultingowej. Im bardziej przenośne mogą tworzyć kod, tym bardziej mogą ponownie wykorzystywać kod od klienta do klienta. Im więcej logiki mogą powiązać w swojej aplikacji, tym bardziej firma jest przywiązana do dostawcy. Jeśli zostawią po sobie wielki bałagan, otrzymają zapłatę za sprzątanie lub nigdy więcej nie zobaczą bałaganu. Tak czy inaczej, jest to dla nich wygrana.
Aby uzyskać (dużo) więcej dyskusji po obu stronach ogrodzenia, przeczytaj dyskusję na temat kodowania horroru . FWIW Opieram się na zwolennikach SP.
źródło
Bardzo trudno jest zmienić marki baz danych i korzystać z tych samych procedur przechowywanych.
Twój zespół albo nie ma DBA i nikt inny nie chce mieć nic wspólnego z sql.
To nic innego jak konkurs programistyczny przeciwko DBA sikaniu.
źródło
IMO to zależy. Procedury składowane mają swoje miejsce, ale nie są one najlepszą praktyką ani nie należy ich za wszelką cenę unikać. Inteligentny programista wie, jak właściwie ocenić daną sytuację i ustalić, czy procedura przechowywana jest odpowiedzią. Osobiście jestem fanem korzystania z pewnego rodzaju ORM (nawet podstawowego, takiego jak surowy Linq do Sql) zamiast procedur przechowywanych, z wyjątkiem może predefiniowanych raportów lub podobnych, ale znowu jest to naprawdę indywidualna sprawa.
źródło
Podział logiki biznesowej na różne warstwy przy użyciu różnych języków programowania zawsze jest źródłem problemów. Śledzenie błędu lub wprowadzanie zmiany jest znacznie trudniejsze, gdy trzeba przełączać się między światami.
To powiedziawszy, znam firmy, które radzą sobie całkiem dobrze, umieszczając całą logikę biznesową w pakietach PL / SQL żyjących w bazie danych. Nie są to bardzo duże aplikacje, ale też nie są trywialne; powiedzmy LK-100K. (PL / SQL jest bardziej odpowiedni dla tego rodzaju systemu niż T-SQL, więc jeśli znasz tylko T-SQL, prawdopodobnie teraz potrząsasz głową z niedowierzaniem ...)
źródło
To kolejny punkt, o którym jeszcze nie wspomniano:
Narzędzia do generowania kodu i narzędzia inżynierii odwrotnej naprawdę nie radzą sobie dobrze z procedurami przechowywanymi. Narzędzie na ogół nie potrafi powiedzieć, co robi proc. Czy proc zwraca zestaw wyników? Kilka zestawów wyników? Czy pobiera zestawy wyników z kilku tabel i tabel tymczasowych? Czy proc jest tylko enkapsulowaną instrukcją aktualizacji i nic nie zwraca? Czy zwraca zestaw wyników, wartość zwracaną i jakieś „wyjście konsoli”?
Jeśli więc chcesz użyć narzędzia do automatycznego utworzenia obiektu DTO i warstwy DAO służącego do przesyłania danych (takiego jak „konstruktor usług” Liferay), nie możesz tego łatwo zrobić.
Ponadto ORM, takie jak Hibernacja, nie mogą naprawdę działać poprawnie, gdy źródłem danych jest SP. Dostęp do danych jest w najlepszym razie tylko do odczytu.
źródło
Programując solo, nie mogę się oprzeć zapisywaniu procedur przechowywanych.
Korzystam głównie z MySQL. Wcześniej nie korzystałem z obiektowych baz danych, takich jak PostGreSQL, ale to, co mogę zrobić z SP w MySQL, to nieco odciąć strukturę tabeli. SP pozwalają mi zaprojektować te prymitywne akcje, których dane wejściowe i wyjściowe nie zmienią się , nawet jeśli baza danych pod nimi się zmieni.
Mam więc procedurę o nazwie
logIn
. Kiedy się logujesz, zawsze po prostu przechodziszusername
ipassword
. Wynik jest zwracany jako liczba całkowitauserId
.Kiedy
logIn
jest procedura składowana, teraz mogę dodać dodatkową pracę do wykonania przy logowaniu, która dzieje się w tym samym czasie, co początkowe logowanie. Uważam, że seria instrukcji SQL z logiką osadzoną w procedurze przechowywanej jest łatwiejsza do napisania niż (wywoływanie środowisko FETCH) -> (uzyskaj wynik) -> (wywołanie środowiska FETCH) seria, którą musisz zrobić, pisząc po stronie serwera logicznego.źródło
Chcę również zauważyć, że procedury przechowywane używają czasu procesora na serwerze. Nie dużo, ale trochę. Część pracy wykonanej w procedurze pracy można wykonać w aplikacji. Łatwiej jest skalować warstwę aplikacji niż warstwę danych.
źródło
Zgadzam się z Markiem, że społeczność naprawdę już od dłuższego czasu odchodzi od procedur przechowywanych. Choć wiele punktów, które pierwotny plakat podniósł, dlaczego warto chcieć korzystać z SP, były ważne w tym samym czasie, minęło sporo czasu i, jak powiedział inny plakat, środowisko się zmieniło. Pamiętam na przykład, że jednym argumentem za użyciem SP w przeszłości było zwiększenie wydajności, ponieważ ich plany wykonania zostały „wstępnie skompilowane”, a dynamiczny SQL z naszego kodu musiał być „ponownie skompilowany” przy każdym wykonaniu. Tak już nie jest, ponieważ główne bazy danych uległy zmianie, poprawie, dostosowaniu itp.
To powiedziawszy, używamy SP w moim obecnym projekcie. Powodem jest po prostu to, że budujemy nowe aplikacje na bazie istniejącej bazy danych, która nadal obsługuje starsze aplikacje. W rezultacie wprowadzanie zmian w schemacie jest bardzo trudne, dopóki nie wyłączymy starszych aplikacji. Podjęliśmy świadomą decyzję, aby zaprojektować nasze nowe aplikacje w oparciu o zachowanie i reguły wymagane dla aplikacji oraz użyć SP do tymczasowego połączenia z bazą danych w taki sposób, w jaki chcielibyśmy, aby umożliwić SP dostosowywanie się do istniejącego SQL . Odnosi się to do punktu poprzedniego postera, że SP ułatwiają wprowadzanie zmian na poziomie bazy danych bez konieczności zmiany kodu aplikacji. Używanie SP jako implementacji wzorca adaptera z pewnością ma dla mnie sens (szczególnie biorąc pod uwagę mój obecny projekt),
Fwiw, naszym zamiarem jest usunięcie SP po aktualizacji schematu. Ale, podobnie jak w przypadku wszystkich innych aspektów rozwoju korporacyjnego, zobaczymy, czy to się kiedykolwiek wydarzy! [szeroki uśmiech]
źródło
Chciałem tylko zrobić zwięzły przegląd tego, jak poleciłbym korzystanie z procedur przechowywanych. Nie sądzę, aby były to w ogóle złe praktyki i podobnie jak inni powiedzieli, że należy ich używać we właściwych sytuacjach.
Widzę problemy, w których procedury pisania dla różnych aplikacji mogą być mylące w funkcjonowaniu i rozdzielać logikę biznesową aplikacji, co powoduje, że baza danych staje się bardziej zdezorganizowana i restrykcyjna.
Dlatego użyłbym procedury przechowywanej w relacyjnych zadaniach zorientowanych na dane, specyficznych dla bazy danych. Innymi słowy, jeśli do operacji na bazie danych używana jest logika spójna z danymi dla dowolnej aplikacji, można zastosować procedurę składowaną, aby zachować spójność przechowywania danych (ma sens). Myślę, że dobrymi przykładami tego są: spójne rejestrowanie, konsekwentna konserwacja, praca z poufnymi informacjami itp.
Myślę, że inne zadania polegające na manipulowaniu danymi w celu dopasowania do potrzeb aplikacji, które są zgodne z silnym modelem danych bazy danych, powinny być następnie przechowywane w innej warstwie zawierającej logikę biznesową. Krótko mówiąc, specyficzne dla bazy danych manipulowanie danymi w celu zachowania spójności mogłoby wykorzystywać procedury składowane, w których spójność rozciąga się poza model schematu integralności bazy danych.
źródło
Procedury składowane „dla mnie” są odpowiednie do operacji „tylko do odczytu” OLAP, rzadkie użycie.
Jeśli chodzi o reguły biznesowe, operacje odczytu / zapisu OLTP preferuję serwery aplikacji Java. Dla ułatwienia kodowania i maksymalnego zmniejszenia obciążenia procesora i pamięci z głównych serwerów db. W tej konfiguracji cały kod na serwerach aplikacji nie jest trudny do przejrzenia ani zalogowania, a jego skalowalność.
Ważną rzeczą dla mnie jest łatwiejsze debugowanie w warstwie biznesowej niż debugowanie procedur przechowywanych.
źródło
Oprócz niepotrzebnej dystrybucji logiki biznesowej i powiązania Cię z konkretnym dostawcą bazy danych, mocno wierzę również w zastosowanie technologii zgodnej z jej przeznaczeniem. Baza danych to po prostu relacyjny magazyn danych. Użyj go do przechowywania danych, nic więcej.
Wybierz mądrze swoje narzędzia, a na dłuższą metę uratujesz sobie świat bólu.
źródło