Procedury przechowywane to zła praktyka w jednej z największych na świecie firm konsultingowych w zakresie oprogramowania IT?


148

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ą.


3
Jaki kod dodaje ponownie? Co jeśli twój klient korzysta z innej bazy danych. Muszę wyrzucić wszystkie te SP i zacząć od zera. Nie chronią cię przed iniekcją sql. W większości przypadków prędkość jest minimalna.
Przypon

32
Należy pamiętać, że większość dużych firm konsultingowych z branży IT ma motywację, aby zmaksymalizować rozliczane godziny, jednocześnie dbając o swoją dupę. Starzy ludzie, którzy mają jakąkolwiek siłę przebicia w tych firmach, są raczej graczami i biurokratami niż technikami. Wziąłbym takie rzeczy od firmy konsultingowej z odrobiną soli - niejednokrotnie wyciągnąłem firmy doradcze z gówna, ustalając ich „najlepszą” praktykę.
ConcernedOfTunbridgeWells

1
Ponowne użycie @Rig Code jest dodawane tak samo, jak w przypadku funkcji dowolnego języka - przez zawijanie kodu w pojemniku wielokrotnego użytku. Z pewnością procedury składowane chronią cię przed wstrzyknięciem SQL, o ile nie wykonasz napisanego łańcucha. Stwierdzenie, że prędkość jest minimalna, wydaje się po prostu niewykształcone. Większość przypadków nie mieści się w tych samych kategoriach pod względem korzyści w zakresie wydajności, ale wykazuje duże rozbieżności.
Garet Claborn

1
@GaretClaborn Ale o wiele bardziej prawdopodobne jest ponowne zaprojektowanie warstwy aplikacji niż lat historycznych danych w bazie danych. W każdym razie w każdej nietrywialnej aplikacji. A jeśli to zrobisz, spędzisz miesiące na przenoszeniu bogatego kodu procedury przechowywanej. Dodanie jeszcze jednej zależności do projektu ma niewielką korzyść, z wyjątkiem sytuacji skrajnych. Te istnieją, ale w większości przypadków stanowi to dodatkową przeszkodę dla zwinności projektu i ponownego wykorzystania kodu.
Rig

2
Opierając się na tle, w którym prawie wyłącznie używaliśmy sps, mogę powiedzieć, że czerpiesz korzyści z odejścia od nich i używania ORM, takich jak Entity Framework. Zbyt wiele razy logika biznesowa zostaje zawarta w procedurze. Chociaż możesz przetwarzać wersje za pomocą narzędzi do pracy lub innych firm. Nie jest to tak łatwe, jak byłoby to możliwe w ramach takich jak TFS czy GIT. Emitowany kod bazy danych jest niezależny od dostawcy RDBMS. Dzięki temu możesz później zrezygnować z dostawców RDBMS przy mniejszym bólu głowy.
ewahner

Odpowiedzi:


280

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.


37
Nie widzę rzeczy tak prosto. Dla mnie jest to CAŁA logika biznesowa. Baza danych, z procedurami przechowywanymi lub bez, zapewnia pewne usługi i daje pewne gwarancje. Idealnie byłoby niemożliwe, aby niepoprawny kod aplikacji wprowadził bazę danych w niespójny stan. Jeśli do zachowania tej spójności potrzebne są procedury składowane, korzystam z nich.
kevin cline,

12
@kevin cline: Zdefiniuj „niespójny stan”. Zgadzam się, że funkcje DB, takie jak integralność referencyjna, są cenne i znacznie zmniejszają prawdopodobieństwo błędu aplikacji powodującego poważne szkody. Jednak ogólnie mówiąc, definicja „spójnych danych” zależy od prawidłowego wykonania reguł biznesowych.
Eric J.

16
dodaj mój milion do miliona Mayo. Rozproszona logika biznesowa zabiera Cię z autostrady dobrej praktyki prosto na pas szaleństwa
Nico,

27
+1 Logika biznesowa przenikająca do DAL jest dużym problemem przy stosowaniu procedur przechowywanych.
System nie działa

30
@ChristopherMahan, NIGDY nie chciałbym używać projektowanej bazy danych. To najgorsza możliwa praktyka z perspektywy bazy danych. Na bazy danych często wpływa bezpośrednio baza danych. Krótkowzrocznie jest myśleć, że ktoś użyje warstwy biznesowej, aby zaktualizować milion rekordów lub innych rzeczy, które zdarzają się z czasem. Importowanie zazwyczaj nie przechodzi przez warstwę biznesową (tak, chcę przetworzyć mój import 21 milionów rekordów jeden rekord na raz w warstwie biznesowej). Oszustwo jest znacznie łatwiejsze, gdy nie masz ograniczeń na poziomie bazy danych. Złe dane są prawie w 100% pewne.
HLGEM

163

Kilka uwag

Procedury przechowywane zapewniają ponowne użycie kodu i enkapsulację (dwa filary rozwoju oprogramowania),

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.

bezpieczeństwo (możesz udzielić / cofnąć uprawnienia dla pojedynczego przechowywanego proc),

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.

chronić cię przed atakami iniekcyjnymi SQL,

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” .

a także pomoc w szybkości (chociaż DBA powiedział, że począwszy od SQL Server 2008, nawet regularne zapytania SQL są kompilowane, jeśli są uruchamiane wystarczająco dużo razy).

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).

Tworzymy złożoną aplikację przy użyciu metodologii tworzenia oprogramowania Agile.

Zwinność dotyczy procesów inżynierii oprogramowania i zarządzania wymaganiami, a nie technologii.

Czy ktoś może wymyślić dobre powody, dla których nie chciałby korzystać z przechowywanych procesów?

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.

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ą.

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).

  • W systemach takich jak Oracle można uzyskać dostęp do LDAP lub tworzyć dowiązania symboliczne do zewnętrznych baz danych (np. Wywoływanie proc. Sklepu na db partnera biznesowego przez vpn.) Łatwy sposób na zrobienie kodu spaghetti, ale dotyczy to wszystkich paradygmatów programowania, a czasem masz określone wymagania biznesowe / środowiskowe, dla których jest to jedyne rozwiązanie. Procesy sklepu pomagają zawrzeć tę nieprzyjemność w jednym miejscu, blisko danych i bez konieczności przechodzenia do serwera aplikacji.

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.

  • W sytuacjach, w których po prostu nie można skalować serwera aplikacji (np. Brak budżetu na nowy sprzęt lub wystąpienia w chmurze), ale z dużą ilością miejsca na zapleczu db (jest to bardziej typowe, że wiele osób chce to przyznać), opłaca się przenieść logikę biznesową do przechowywania proc. Nie ładna i może prowadzić do anemicznych modeli domen ... ale z drugiej strony ... analiza kompromisowa, rzecz, do której wciąga większość hacków oprogramowania.

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.


14
To jest naprawdę dobra odpowiedź.
yfeldblum,

5
Dobra odpowiedź, ale czy to miało być ironiczne? „Uogólnienia są matką wszystkich wpadek”.
bedwyr

2
Tak i nie. Ten mój komentarz był przeznaczony do tego konkretnego zdania, o którym wspomniał OP w swoim pierwotnym pytaniu ( procedury składowane nie są „najlepszą praktyką” ). Zgrubny opis procedur sklepowych jako najlepszej lub złej praktyki jest uogólnieniem. Ignorowanie kontekstu, w którym mogą być dobre LUB złe może (i często prowadzi) do
popsuć się

7
+1 za „Typowe oznaczanie rzeczy jako zła praktyka jest zwykle stosowane w organizacjach z mnóstwem niekompetentnych programistów”. - Byłem tam, przeżyłem to, w tym powiedziano mi prosto w twarz menedżera deweloperów, że myślał, że mam świetne rozwiązanie dla jednego podstępnego problemu, ale jeśli zobaczył, że pozwolił mi go wdrożyć, otworzyłoby to wrota muppety.
Julia Hayward

1
@Shane Masz rację. Uważam jednak, że to, co ta odpowiedź stara się przekazać, to tendencja niektórych grup inżynierów do usprawiedliwiania braku wiedzy lub analizy przez wzywanie karty złych praktyk. Odpowiedź może jednak poprawić sytuację niedoświadczonych z nas.
Cesar Hernandez,

56

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ś:

(procedury składowane) chronią Cię przed atakami iniekcyjnymi SQL

To właściwie parametryzowane zapytania, które cię chronią, co możesz łatwo zrobić w zapytaniach sql w postaci zwykłego tekstu.


18
A jeśli przechowywany proc używa dowolnego typu dynamicznego kodu SQL wraz z parametrem string, to od razu zaczynasz.
JeffO,

4
Różnica polega na tym, że uprawnienia dostępu można ustawić dla procedur przechowywanych dla poszczególnych procedur, w przypadku sparametryzowanych zapytań SQL należy polegać na rozsądku programistów, aby tego nie robić, + "blablabla"ponieważ należy zezwolić na zwykły SQL i na tym kończy się kontrola.
Koder

19
Nigdy nie rozumiałem argumentu „przywiązuje cię do pewnego DB”. Jak często bierzesz swój program i migrujesz go do zupełnie innej bazy danych?
Mason Wheeler

11
@MasonWheeler - +1 za każdym razem. W każdym wystarczająco dużym projekcie twoja aplikacja jest napisana przeciwko słabościom danego produktu DB. Konwersja na inną bazę danych staje się ważnym zadaniem bez względu na wszystko, ponieważ nowa baza danych będzie miała różne osobliwości!
Michael Kohne

6
@HLGEM - ale w świecie COTS oczekuje się na początku wielu DB (w rzeczywistości wybierasz kompatybilne DB). Nie chodzi o to, że portujesz, ale o to, że obsługujesz różne back-endy, co jest zupełnie inną bestią niż wykonywanie portu.
Michael Kohne

46

Niektóre z powodów, dla których zgadzam się na przechowywane procedury nie są najlepszą praktyką.

  • Logika biznesowa i aplikacji powinna znajdować się w kodzie, a nie w bazie danych. Umieszczenie logiki w bazie danych budzi obawy.
  • Nie można testować przechowywanych procesów tak płynnie jak kodu w konwencjonalnych projektach testów jednostkowych z resztą logiki aplikacji.
  • Nie uważam, że przechowywane procy sprzyjają testowaniu pierwszego programowania podczas pisania kodu.
  • Przechowywane procy nie są tak łatwe do debugowania jak kod aplikacji podczas debugowania programu w IDE.
  • Kontrola wersji / kontrola źródła SP w porównaniu do normalnego kodu

7
Możesz równie łatwo wykonać pierwsze testowanie procedur przechowywanych.

5
Hmmm, cóż ... 1) Wykorzystanie procedur przechowywanych db nie musi koniecznie oznaczać umieszczenie w nich logiki biznesowej. 2) przechowywane procy to jedne z najłatwiejszych do przetestowania jednostek. 3) procedury sklepowe niekoniecznie prowadzą praktyki testowe, to prawda, ale nie wszystko, co można obliczyć, można przetestować jako pierwsze. 4) debugowanie nie powinno stanowić problemu, ponieważ procedury sklepu nie powinny zawierać niczego poza łatwymi do zweryfikowania instrukcjami SQL i kursorami. Ponadto debugowanie powinno odbywać się najpierw poprzez przetestowanie i debugowanie instrukcji SQL w kodzie, a następnie przeniesienie do proc. Sklepowych ... po prostu IMO btw.
luis.espinal

6
Oczywiście nie jesteś deweloperem DB. Kontrola źródła, IDE - to cholernie łatwe debugowanie SP, jeśli używasz TOAD lub podobnego IDE, to samo z wersjonowaniem.
gbjbaanb

6
2) w testach jednostkowych przechowywane proc. idk na temat innych frameworków testów jednostkowych, ale przynajmniej przy pomocy MS Test (VisualStudio.TestTools.UnitTesting), uruchomienie dowolnej metody Assert na przechowywanym proc wymaga przynajmniej połączenia Db, co z definicji czyni go bardziej testem integracyjnym niż jednostką test. Przechowywany proc może odwoływać się do stanu bazy danych na poziomie globalnym bazy danych. Mogą nie być fałszywe lub mieć interfejsy.
T. Webster,

3
+1 Ponadto języki procedur składowanych (pl / sql, t-sql, plpgsql itp.) Są bardzo niezgrabne i pełne. Znacznie łatwiej jest mi używać języka skryptowego do nawiązywania połączenia z bazą danych i obsługi logiki biznesowej poza bazą danych.

22

Procedury przechowywane zapewniają ponowne użycie kodu i enkapsulację (dwa filary rozwoju oprogramowania),

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.

chronić cię przed atakami iniekcyjnymi SQL,

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; -

a także pomoc w szybkości (chociaż DBA powiedział, że począwszy od SQL Server 2008, nawet regularne zapytania SQL są kompilowane, jeśli są uruchamiane wystarczająco dużo razy).

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.


1
Red Gate ma produkt SQL Source Control dla SQL Server, ale zgadzam się, przekazywanie logiki do przechowywanych procs jest doskonałym sposobem na upewnienie się, że masz ważną logikę, która nie podlega żadnej kontroli wersji.
Carson63000,

17
@greyfade - „Nie widziałem jeszcze kontroli źródła dla SP” - żartujesz sobie? Proces sklepu to po prostu cholerny plik tekstowy, który przesyłasz do silnika bazy danych (który go pobiera, kompiluje i instaluje w celu wykonania.) W każdym miejscu, w którym pracowałem, w którym przechowywane są procesy, przechowujemy kod źródłowy procesu, np. CVS, clearcase lub inny SCM, który był w użyciu. Mówienie, że procy sklepów nie mogą być kontrolowane przez źródło (ponieważ znajdują się w bazie danych), jest jak stwierdzenie, że mój kod źródłowy aplikacji (Java, C # lub cokolwiek innego) nie może być kontrolowany przez źródło, ponieważ jest on kompilowany i wdrażany w środowisku produkcyjnym.
luis.espinal

2
@ luis.espinal: Nie powiedziałem, że nie mogą mieć kontroli źródła. Powiedziałem tylko, że nie znam narzędzia specjalnie do utrzymywania historii SP, co oznacza utrzymywanie tej historii w bazie danych. Proszę nie narzekać na mnie tylko dlatego, że coś źle odczytałeś.
greyfade,

1
Wszystkie procesy przechowywane w opur są kontrolowane przez źródło, tylko fakt, że widziałeś złe parcetyki w przeszłości, nie oznacza, że ​​są one nieodłącznie związane z używaniem przechowywanych procesów.
HLGEM,

1
@ luis.espinal czy typowe jest, że źródło procedury składowanej można później pobrać z bazy danych? Jeśli tak, możesz mieć narzędzie, które regularnie je wyciąga i mieć inne narzędzia do odtworzenia instalacji od zera. Rób to raz na jakiś czas, aby upewnić się, że jest dokładny.

17

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?


10
@DaveE: Prawdopodobnie masz rację w przypadku rozwiązania dla przedsiębiorstw. Jeśli tworzysz oprogramowanie w pakiecie, jak tylko dostarczysz na MSSQL, twoja największa szansa będzie chciała, aby działał na Oracle.
Eric J.,

3
@Eric: zbyt prawdziwe. Gdzie jestem teraz, używamy ton SP i mówimy ludziom „nie”, jeśli nie chcą MSSQL. Miło jest móc to zrobić.
DaveE

3
@DaveE: Czy zespół sprzedaży chciałby powiedzieć „tak”?
Eric J.

2
To nie tyle przenoszenie jednego systemu z jednej bazy danych do drugiej, ale fakt, że jeden system może korzystać z dowolnego systemu bazy danych, który klient już posiada. Duże bazy danych są drogie.

@EricJ: tak, ale kiedy zobaczą, jaki koszt będzie miał ich prowizja, prośba trochę znika.
DaveE,

17

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.


6
Nie mogę się jednak oprzeć propozycji zastanowienia się nad kwestią zorientowaną na zestaw vs. proceduralną. Widziałem kursory baz danych używane we wszystkich przypadkach, w których takie podejście było po prostu szalone. Osobiście zastąpiłem jawny SQL oparty na kursorach (w tym przypadku Oracle PL / SQL) zapytaniem zorientowanym na zestaw i zobaczyłem, że wyniki wracają w ciągu sekundy, zamiast 8 minut. 30 minut zajęło mi przeanalizowanie tego kodu kursora o długości 1000 linii i „pobranie” go. Wynikowe zapytanie SQL było zwięzłe, eleganckie, proste. Ludzie nie doceniają mocy swoich serwerów baz danych zbyt często i zbyt szybko.
Craig

12

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.


6
Jak oceniasz wersje procedur przechowywanych na serwerze? - kontrolujesz wersję kodu źródłowego sklepu proc. Kiedy nadchodzi czas na wdrożenie, łapiesz procs ze sklepu (z danej linii bazowej) i ty (lub twój dba) wdrażasz do produkcji. Ponowne wdrożenie (testowe lub produkcyjne) z pewnością wysadza zapisany plan wykonania, ale nastąpi to niezależnie od tego, czy kontrolujesz źródła swoich SP, czy nie.
luis.espinal

1
@BarryBrown Nie działa, jeśli ludzie mają bezpośredni dostęp do serwera i mogą zmieniać procedury składowane. Musiałbym mieć proces, który obserwuje SP, lub sprawdzać przed każdym użyciem ...
Christopher Mahan

2
Jeśli masz ludzi, którzy po prostu zmieniają sproki na serwerach, nie popełniając ich zmian w kontroli źródła, masz problem z procesem, który prawie na pewno wpływa na rozwój twojego kodu imperatywnego, nawet jeśli nie wiesz, że tak jest.
Craig,

1
Jedną z rzeczy, które zrobiłem w przeszłości, było umieszczenie instancji programistycznej serwera bazy danych na stacjach roboczych poszczególnych programistów, a jeśli nie było to możliwe, to przynajmniej mieć instancje „dev” i „produkcyjne” baz danych , a wszystkie skrypty DDL i DML, a także przykładowe dane i skrypty ładowania mieszkały we własnym katalogu w drzewie źródłowym, a baza danych była rutynowo budowana z tych skryptów przy użyciu pliku MAKE. Deweloperzy mogli również używać nmake do budowania pojedynczych przechowywanych proc. Gdyby nie poddali go kontroli źródła, zniknęliby na nich i wiedzieli o tym.
Craig

1
... nie chciałem brzmieć dyskredytująco w moim wcześniejszym komentarzu słowem „..., nawet jeśli nie jesteś świadomy ...”. Chciałem przekazać, że jeśli coś takiego dzieje się z procedurami przechowywanymi, prawdopodobnie dzieje się to również w innych częściach projektu. Osobiście nie lubię zintegrowanej kontroli źródła w IDE, po części dlatego, że myślę, że to sprawia, że ​​ludzie są trochę leniwi, jeśli chodzi o myślenie o tym, co tak naprawdę oznacza zespół i cały projekt, aby wprowadzić zmiany i zatwierdzić te zmiany magazyn. Moim zdaniem te rzeczy nie powinny być „automatyczne”.
Craig

9

Jest to tak sprzeczne ze wszystkim, czego się nauczyłem.

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ą.

Procedury przechowywane zapewniają ponowne użycie kodu i enkapsulację (dwa filary rozwoju oprogramowania)

Bardzo prawdziwe. Ale także przyzwoicie zaprojektowana warstwa OO.

bezpieczeństwo (możesz przyznać / cofnąć uprawnienia dla pojedynczego przechowywanego proc)

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.

chronić cię przed atakami iniekcyjnymi SQL

Nie więcej niż robienie sparametryzowanych zapytań. Co i tak musisz zrobić.

a także pomoc w szybkości (chociaż DBA powiedział, że począwszy od SQL Server 2008, nawet regularne zapytania SQL są kompilowane, jeśli są uruchamiane wystarczająco dużo razy).

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.

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?

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.


1
Istnieje wiele LOTów do poprawienia wydajności, jeśli nie musisz przesyłać gigantycznych zbiorów danych z bazy danych, aby robić proste rzeczy. Zmierz i optymalizuj w razie potrzeby.

Dokładnie. Procedury przechowywane mogą być używane jak skalpel. Jest absolutną gwarancją, że operacje we / wy na serwerze bazy danych mają większą przepustowość niż operacje we / wy między serwerem bazy danych a warstwą środkową. I nie będziesz pisać szybszego, wydajniejszego kodu dołączającego dane w środkowej warstwie, niż napisane przez programistę silnika bazy danych na serwerze bazy danych. Jeśli przenosisz 1 000 000 wierszy danych do środkowej warstwy, aby wykonać łączenie, co z pewnością widziałem, po prostu powinieneś zostać wychłostany ... To tak, jak ludzie, którzy twierdzą, że powinieneś „napisać własny kod wycofania”. Niepoczytalność.
Craig

1
Nie lekceważ swojego serwera bazy danych. Dowiedz się, jak używać go poprawnie.
Craig

1
FWIW, nie potrzebujesz przechowywanego proc, aby wykonać złączenie po stronie bazy danych. A jeśli używasz kursora do logiki proceduralnej, prawdopodobnie już przegrałeś wojnę o wydajność. Rezygnacja z procedur przechowywanych z pewnością nie jest tym samym, co rezygnacja z SQL lub rozwiązań opartych na zestawach.
Mark Brackett

1
Zupełnie prawda, a tak naprawdę argumentowałem na korzyść SQL, a nie argumentów specjalnie dla sproców. Ale posiadanie SQL wbudowanego w twój imperatywny kod niekoniecznie musi być kluczem do szczęścia, prawda? Co często prowadzi do całej debaty ORM, co następnie prowadzi mnie do wskazania porównań wydajności między dostępem do bazy danych opartym na ORM a samą nauką używania SQL. Zarówno widziałem, jak i słyszałem o systemach, w których, powiedzmy, konsultanci Oracle zalecili utrzymanie całego obciążenia poza serwerem bazy danych, co prowadzi do ciężkiego (i rażąco drogiego!) Oprogramowania pośredniego o niesamowitej wydajności.
Craig

4

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.


4

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.

  1. 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.

  2. 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.

  3. 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:

  1. 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.

  2. 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.

  3. Ponowne użycie zapytania.

No i kilka rzeczy, których prawie nigdy nie powinieneś robić w SP:

  1. 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 ....

  2. wiele małych zapytań luźno powiązanych ze sobą, pokrytych logiką proceduralną ...


Wyraźnie się zgadzam, ponownie: utrzymywanie śmieci nietransakcyjnych poza procedurami przechowywanymi. W tym przykładzie wiadomości e-mail wiadomość e-mail powinna zostać upuszczona do kolejki i obsługiwana asynchronicznie. Mówisz o przygotowaniu się na ogromny hit wydajności i funky pod obciążeniem, uzależniając transakcje bazy danych od odpowiedzi serwera pocztowego? Yikes!
Craig

3

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.

wprowadź opis zdjęcia tutaj

Aby uzyskać (dużo) więcej dyskusji po obu stronach ogrodzenia, przeczytaj dyskusję na temat kodowania horroru . FWIW Opieram się na zwolennikach SP.


1
Ta odpowiedź koncentruje się na powiązaniu pytania, czy stosować procedury składowane z pytaniem, dla kogo pracujesz i jakie są ich motywacje. Głosuj Zamiast tego należy skoncentrować się na powiązaniu pytania, czy korzystać z procedur przechowywanych, wady i zalety procedur przechowywanych. Gdyby odpowiedź koncentrowała się na pomyśle, że SP nie dopuszczają śmieci do bazy danych, nie oddałbym głosu. Nie zgodziłbym się w interesie ujawnienia, ale nie oddałbym głosu.
yfeldblum,

Również link do artykułu z 2004 roku, IMHO krajobraz zmienił się dość mocno od tego czasu. OR / M stały się znacznie bardziej powszechne. Ruby / Rails ActiveRecord, MS wyszło z linq & EF, Django dla python itp.
Brook

@ Justice, ma rację, ale to, czy najlepsza praktyka w obszarze storageprocs zależy od tego, kim jest firma i jaką rolę odgrywają. Na przykład przechowywane procy pozwalają ustawić uprawnienia dla samego proca, a nie bezpośrednio na stole. Jeśli wykonujesz jakąkolwiek pracę finansową i musisz wziąć pod uwagę kontrole wewnętrzne, są one jedyną realną opcją ochrony twoich danych przed użytkownikami. Ale jeśli tworzysz produkty COTS z możliwością wielu backendów, są one zbyt specyficzne dla bazy danych. Jeśli jesteś firmą konsultingową, być może będziesz musiał rozważyć kilka różnych podejść, które najlepiej pasują do okoliczności.
HLGEM,

3
@HLGEM Nie sprzeciwiam się żadnym z poruszonych przez ciebie punktów . Ale sprzeciwiam się tezie odpowiedzi, że głównym powodem, dla którego DBA może wprowadzić logikę do aplikacji, jest to, że jest konsultantem i zamierza pieprzyć klienta. Wiąże to pozycję moralną osoby z jej wyborem, czy stosować procedury składowane. Moim zdaniem są argumenty techniczne po obu stronach, a argumenty po obu stronach będą się różnić od zastosowania do zastosowania, technologii do technologii, firmy do firmy, branży do branży. Najpierw będę szukał zasługi, zanim zakwestionuję motyw.
yfeldblum,

Powiedział, że pracuje dla firmy konsultingowej. Zachowanie większej kontroli nad kodem w porównaniu z procedurami przechowywanymi wdrażanymi w witrynie klienta jest bardzo uzasadnionym powodem, dla którego może to być ich „najlepsza praktyka”. Może to nie być „pieprzenie klienta”, ale może to być kwestia większej kontroli.
Jesse

3

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.


2

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.


Downvoters komentują.
SandRock

2

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 ...)


2

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.


Interesujące jest to, że narzędzia do generowania kodu najwyraźniej mają trudności z ustaleniem, czy procedura przechowywana zwraca zestaw wyników, gdy sama procedura przechowywana nie ma z tym żadnych problemów.
Craig

2

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 przechodzisz usernamei password. Wynik jest zwracany jako liczba całkowita userId.

Kiedy logInjest 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.


1

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.


3
Czy trudno jest skalować bazę danych?
JeffO,

1
Jest co najmniej znacznie droższy (chyba że korzystasz z MySQL), aw wielu miejscach pracowałem nad uzyskaniem kolejnej licencji na SQL Server Enterprise Edition to jak ciągnięcie za zęby
korzyści.

skalowanie bazy danych nie jest trudniejsze niż skalowanie warstwy aplikacji na koniec historii
Brian Ogden

1

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]


0

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.


-1

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.


Przyjęliście pewne założenia: że PO potrzebuje OLAP (nie podano w pytaniu); że używana platforma ma serwery aplikacji Java (mało prawdopodobne, ponieważ znacznik dotyczy SQL Server). Odpowiadasz również nie przynosi niczego, czego pozostałe 22 odpowiedzi jeszcze nie obejmowały
Adam Zuckerman

Mówiłem tylko, że jeśli rozpocznę nowy projekt, rzadko będę używał procedury składowanej do operacji tylko do odczytu, to tylko osobisty wybór. Uważam, że wygodniej jest wykonywać większość kodowań w warstwie logiki biznesowej zamiast w warstwie danych.
jaizon lubaton

wydaje się, że nie oferuje to nic istotnego w porównaniu z punktami podanymi i wyjaśnionymi w poprzednich 24 odpowiedziach, nie jest to treść warta obalenia 4-letniego pytania
komara

-2

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.


jeśli masz zamiar głosować, zrób to, ale przynajmniej wyjaśnij dlaczego.
Nico,

prawdopodobnie dlatego, że się mylisz. SP nie oznacza, że ​​piszesz tam kod, tylko piszesz zapytania o dostęp do danych (w 99% przypadków, jak sądzę). Poza tym samo nałożenie wyzwalaczy i ograniczeń na model danych liczy się jako „kod” - tj. Logika operacyjna, a nie dane. Stąd moja uwaga, że ​​się mylisz.
gbjbaanb

Gdzie ustawiasz transformacje na przechowywanych danych innych niż w bazie danych?
Chris Travers
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.