Jakie są zalety i wady przechowywania SQL w przechowywanych procesach kontra kod [zamknięte]

274

Jakie są zalety / wady trzymania SQL w kodzie źródłowym C # lub w przechowywanych procesach? Rozmawiałem o tym z przyjacielem przy projekcie open source, nad którym pracujemy (forum C # ASP.NET). W tej chwili większość dostępu do bazy danych odbywa się poprzez zbudowanie wbudowanego SQL w C # i wywołanie bazy danych SQL Server. Staram się więc ustalić, który z tych projektów byłby najlepszy.

Do tej pory mam:

Zalety w Kodeksie:

  • Łatwiejsze w utrzymaniu - nie trzeba uruchamiać skryptu SQL, aby aktualizować zapytania
  • Łatwiejsze przeniesienie do innej bazy danych - brak procedur do przeniesienia

Zalety przechowywanych procesów:

  • Występ
  • Bezpieczeństwo
Facet
źródło
50
Można również argumentować, że przechowywane procesy ułatwiają konserwację - nie trzeba ponownie instalować całej aplikacji, aby zmienić jedno zapytanie.
Darren Gosbell
27
@GvS: to dysfunkcja twojej firmy, a nie najlepsza praktyka. Oczywiście łatwiej jest zmieniać rzeczy o 1 miejsce niż 1000. DBA po prostu robią co w ich mocy, aby zapobiec kawalerskim zmianom w systemie, i należy tego przestrzegać.
Jeremy Holovacs,

Odpowiedzi:

179

Nie jestem fanem procedur przechowywanych

Procedury przechowywane są WIĘCEJ konserwowalne, ponieważ: * Nie musisz rekompilować aplikacji C # za każdym razem, gdy chcesz zmienić niektóre SQL

Skończysz na ponownej kompilacji, gdy zmieniają się typy danych, chcesz zwrócić dodatkową kolumnę lub cokolwiek innego. Liczba przypadków, w których można „transparentnie” zmienić kod SQL spod aplikacji, jest ogólnie niewielka

  • W końcu ponownie używasz kodu SQL.

Języki programowania, w tym C #, mają tę niesamowitą rzecz, zwaną funkcją. Oznacza to, że możesz wywoływać ten sam blok kodu z wielu miejsc! Niesamowity! Następnie możesz umieścić kod SQL wielokrotnego użytku w jednym z nich, a jeśli chcesz naprawdę zaawansowaną technologię, możesz skorzystać z biblioteki, która to zrobi za Ciebie. Sądzę, że nazywają się Object Relational Mappers i są obecnie dość powszechne.

Powtarzanie kodu jest najgorszą rzeczą, jaką możesz zrobić, gdy próbujesz zbudować łatwą do utrzymania aplikację!

Uzgodnione, dlatego przechowywane procesy są złą rzeczą. O wiele łatwiej jest refaktoryzować i rozkładać (rozkładać na mniejsze części) kod na funkcje niż SQL na ... bloki SQL?

Masz 4 serwery WWW i kilka aplikacji Windows, które używają tego samego kodu SQL. Teraz zdałeś sobie sprawę, że jest mały problem z kodem SQl, więc raczej ...... zmień proc w 1 miejscu lub przekaż kod wszystkim na serwerach WWW, zainstaluj ponownie wszystkie aplikacje komputerowe (clickonce może pomóc) we wszystkich oknach systemu Windows

Dlaczego aplikacje systemu Windows łączą się bezpośrednio z centralną bazą danych? To wydaje się być OGROMNĄ dziurą w zabezpieczeniach i wąskim gardłem, ponieważ wyklucza buforowanie po stronie serwera. Czy nie powinny łączyć się za pośrednictwem usługi internetowej lub podobnej do twoich serwerów sieciowych?

Wciśnij 1 nowy sproc lub 4 nowe serwery?

W tym przypadku jest to łatwiejsze do pchania jeden nowy sproc, ale z mojego doświadczenia, 95% "zmian barki wpływać na kod, a nie bazy danych. Jeśli przesyłasz 20 rzeczy do serwerów w tym miesiącu, a 1 do bazy danych, prawie nie tracisz dużo, jeśli zamiast tego wypychasz 21 rzeczy do serwerów, a zero do bazy danych.

Łatwiej przeglądany kod.

Czy możesz wyjaśnić jak? Nie rozumiem tego Zwłaszcza, że ​​sproki prawdopodobnie nie mają kontroli źródła i dlatego nie można uzyskać do nich dostępu za pośrednictwem przeglądarek SCM opartych na sieci i tak dalej.

Więcej wad:

Storedprocs żyją w bazie danych, która wydaje się światu zewnętrznemu jako czarna skrzynka. Proste rzeczy, takie jak kontrola nad źródłami, stają się koszmarem.

Jest też kwestia zwykłego wysiłku. Rozsyłanie wszystkiego na milion poziomów może mieć sens, jeśli próbujesz uzasadnić swojemu dyrektorowi generalnemu, dlaczego zbudowanie forów kosztuje ich 7 milionów dolarów, ale w przeciwnym razie utworzenie przechowywanego programu dla każdej drobnej rzeczy jest dodatkowym działaniem zasiłek.

Orion Edwards
źródło
99

Jest to obecnie omawiane w kilku innych wątkach. Jestem konsekwentnym zwolennikiem procedur przechowywanych, chociaż przedstawiono kilka dobrych argumentów dla Linq do Sql.

Osadzanie zapytań w kodzie ściśle wiąże się z modelem danych. Procedury przechowywane są dobrą formą programowania kontraktowego, co oznacza, że ​​DBA ma swobodę zmiany modelu danych i kodu w procedurze, o ile kontrakt reprezentowany przez dane wejściowe i wyjściowe procedury przechowywanej jest zachowany.

Strojenie produkcyjnych baz danych może być niezwykle trudne, gdy zapytania są zakopane w kodzie, a nie w jednej centralnej, łatwej do zarządzania lokalizacji.

[Edytuj] Oto kolejna bieżąca dyskusja

Eric Z Beard
źródło
47

Moim zdaniem nie możesz głosować na tak lub nie na to pytanie. Zależy to całkowicie od projektu twojej aplikacji.

Całkowicie głosuję przeciwko użyciu SP w środowisku 3-warstwowym, na którym znajduje się serwer aplikacji. W takim środowisku serwer aplikacji służy do obsługi logiki biznesowej. Jeśli dodatkowo użyjesz SP, zaczniesz rozpowszechniać implementację logiki biznesowej w całym systemie i stanie się bardzo niejasne, kto jest za co odpowiedzialny. W końcu otrzymasz serwer aplikacji, który zasadniczo nie będzie robił nic poza:

(Pseudocode)

Function createOrder(Order yourOrder) 
Begin
  Call SP_createOrder(yourOrder)
End

Tak więc ostatecznie masz środkową warstwę działającą na tym bardzo fajnym 4-serwerowym klastrze, każdy z nich wyposażony w 16 procesorów i tak naprawdę nic nie robi! Co za strata!

Jeśli masz grubego klienta GUI, który bezpośrednio łączy się z twoją bazą danych, a może nawet większą liczbą aplikacji, to inna historia. W tej sytuacji SP mogą służyć jako pewnego rodzaju pseudo-środkowa warstwa, która oddziela twoją aplikację od modelu danych i oferuje kontrolowany dostęp.

huo73
źródło
44

Zalety w Kodeksie:

  • Łatwiejsze w utrzymaniu - nie trzeba uruchamiać skryptu SQL, aby aktualizować zapytania
  • Łatwiejsze przeniesienie do innej bazy danych - brak procedur do przeniesienia

Właściwie myślę, że masz to do tyłu. IMHO, SQL w kodzie jest trudny do utrzymania, ponieważ:

  • w końcu powtarzasz się w powiązanych blokach kodu
  • SQL nie jest obsługiwany jako język w wielu IDE, więc masz po prostu szereg niezbadanych ciągów znaków wykonujących zadania za Ciebie
  • zmiany typu danych, nazwy tabeli lub ograniczenia są znacznie bardziej rozpowszechnione niż zamiana całych baz danych na nowe
  • poziom trudności wzrasta wraz ze wzrostem złożoności zapytania
  • a testowanie wbudowanego zapytania wymaga zbudowania projektu

Pomyśl o przechowywanych procesach jako metodach wywoływanych z obiektu bazy danych - są one znacznie łatwiejsze do ponownego użycia, istnieje tylko jedno miejsce do edycji, aw przypadku zmiany dostawców DB zmiany zachodzą w przechowywanych procesach, a nie w kodzie .

To powiedziawszy, wzrost wydajności przechowywanych procesów jest minimalny, jak Stu powiedział przede mną i nie możesz umieścić punktu przerwania w procedurze przechowywanej (jeszcze).

Rob Allen
źródło
33

KON

Uważam, że wykonywanie wielu operacji wewnątrz procedur przechowywanych sprawiłoby, że Twój serwer DB byłby jednym punktem elastyczności, jeśli chodzi o skalowanie twojego działania.

Jednak robienie tego całego załamania w programie, w przeciwieństwie do serwera SQL, może pozwolić na większe skalowanie, jeśli masz wiele serwerów, na których działa Twój kod. Oczywiście nie dotyczy to przechowywanych procesów, które tylko normalnie pobierają lub aktualizują, ale tych, które wykonują więcej przetwarzania, takich jak zapętlanie zestawów danych.

PROS

  1. Wydajność za to, co może być warta (pozwala uniknąć analizy zapytań przez sterownik DB / odtwarzanie planu itp.)
  2. Manipulowanie danymi nie jest osadzone w kodzie C / C ++ / C #, co oznacza, że ​​mam mniej kodu niskiego poziomu do przejrzenia. SQL jest mniej szczegółowy i łatwiej go przejrzeć, gdy jest wymieniony osobno.
  3. Ze względu na separację ludzie są w stanie znacznie łatwiej znaleźć i ponownie użyć kodu SQL.
  4. Łatwiej jest zmieniać rzeczy, gdy zmienia się schemat - wystarczy podać ten sam wynik kodowi i będzie działać dobrze
  5. Łatwiejsze przeniesienie do innej bazy danych.
  6. Mogę wyświetlić listę indywidualnych uprawnień do moich procedur przechowywanych i kontrolować dostęp również na tym poziomie.
  7. Mogę profilować mój kod zapytania / trwałości danych osobno od kodu transformacji danych.
  8. Mogę zaimplementować zmienne warunki w mojej procedurze składowanej i łatwo byłoby je dostosować w witrynie klienta.
  9. Łatwiej jest korzystać z niektórych zautomatyzowanych narzędzi do konwertowania mojego schematu i instrukcji razem, niż gdy jest on osadzony w moim kodzie, gdzie musiałbym je wyłapać.
  10. Zapewnienie najlepszych praktyk w zakresie dostępu do danych jest łatwiejsze, gdy cały kod dostępu do danych znajduje się w jednym pliku - mogę sprawdzać zapytania, które uzyskują dostęp do tabeli niedziałającej lub wykorzystującej wyższy poziom serializacji lub wybierając * w kodzie itp. .
  11. Łatwiej jest znaleźć zmiany schematu / zmiany logiki manipulacji danymi, gdy wszystkie są wymienione w jednym pliku.
  12. Łatwiej jest wyszukiwać i zamieniać zmiany w SQL, gdy znajdują się w tym samym miejscu, np. Zmień / dodaj instrukcje izolacji transakcji dla wszystkich przechowywanych proc.
  13. Ja i facet z DBA stwierdziliśmy, że posiadanie osobnego pliku SQL jest łatwiejsze / wygodniejsze, gdy DBA musi przejrzeć moje rzeczy SQL.
  14. Na koniec nie musisz się martwić atakami iniekcyjnymi SQL, ponieważ leniwy członek twojego zespołu nie używał sparametryzowanych zapytań podczas korzystania z osadzonych plików SQL.
komputerze
źródło
22

Przewaga wydajności procedur przechowywanych jest często nieistotna.

Więcej zalet procedur przechowywanych:

  • Zapobiegaj inżynierii wstecznej (oczywiście jeśli została utworzona z szyfrowaniem)
  • Lepsza centralizacja dostępu do bazy danych
  • Możliwość transparentnej zmiany modelu danych (bez konieczności wdrażania nowych klientów); szczególnie przydatne, gdy wiele programów uzyskuje dostęp do tego samego modelu danych
Stu
źródło
16

Wpadam na kod stronie . Budujemy warstwę dostępu do danych, która jest używana przez wszystkie aplikacje (zarówno w Internecie, jak i kliencie), więc z tej perspektywy jest SUCHY. Upraszcza to wdrażanie bazy danych, ponieważ musimy tylko upewnić się, że schematy tabel są prawidłowe. Upraszcza obsługę kodu, ponieważ nie musimy patrzeć na kod źródłowy i bazę danych.

Nie mam większego problemu z ciasnym sprzężeniem z modelem danych, ponieważ nie widzę, gdzie naprawdę można przerwać to połączenie. Aplikacja i jej dane są ze sobą ściśle powiązane.

Stóg
źródło
13

Procedury składowane.

Jeśli błąd ześlizguje się lub logika nieco się zmienia, nie trzeba ponownie kompilować projektu. Ponadto umożliwia dostęp z różnych źródeł, a nie tylko z jednego miejsca, w którym zakodowano zapytanie w projekcie.

Nie sądzę, że trudniej jest przechowywać procedury składowane, nie należy ich kodować bezpośrednio w bazie danych, ale najpierw w osobnych plikach, a następnie można je uruchomić na dowolnym DB, który należy skonfigurować.

Mbillard
źródło
24
Jeśli podejmiesz podstawowe decyzje architektoniczne, aby uniknąć ponownej kompilacji kodu, zanim w ogóle cokolwiek zrobisz, ustal proces kompilacji, który nie jest do kitu. To nie jest argument.
Michael Borgwardt,
13

Zalety procedur przechowywanych :

Łatwiej przeglądany kod.

Mniej sprzężony, dlatego łatwiej go przetestować.

Łatwiej dostrojony.

Wydajność jest na ogół lepsza z punktu widzenia ruchu sieciowego - jeśli masz kursor lub podobny element, nie ma wielu podróży do bazy danych

Możesz łatwiej chronić dostęp do danych, usuwać bezpośredni dostęp do tabel, egzekwować bezpieczeństwo poprzez procs - pozwala to również stosunkowo szybko znaleźć dowolny kod, który aktualizuje tabelę.

Jeśli w grę wchodzą inne usługi (takie jak usługi raportowania), łatwiejsze może być przechowywanie całej logiki w procedurze przechowywanej niż w kodzie i konieczność jej duplikowania

Niedogodności:

Trudniej jest zarządzać programistom: kontrola wersji skryptów: czy każdy ma własną bazę danych, czy system kontroli wersji jest zintegrowany z bazą danych i IDE?

Matthew Farwell
źródło
Tak, możesz mieć kontrolę wersji w Procedurach przechowywanych i bazie danych w projekcie bazy danych Visual Studio 2012 i tfs.
hajirazin
11

W niektórych okolicznościach dynamicznie tworzone kody SQL mogą mieć lepszą wydajność niż przechowywane procy. Jeśli utworzyłeś zapisany proc (powiedzmy sp_customersearch), który staje się niezwykle skomplikowany z dziesiątkami parametrów, ponieważ musi być bardzo elastyczny, prawdopodobnie możesz wygenerować znacznie prostszą instrukcję SQL w kodzie w czasie wykonywania.

Można argumentować, że to po prostu przenosi przetwarzanie z SQL na serwer WWW, ale ogólnie byłoby to dobre.

Inną wspaniałą rzeczą w tej technice jest to, że jeśli patrzysz na profil SQL, możesz zobaczyć wygenerowane zapytanie i debugować je o wiele łatwiej niż zobaczyć zapisane wywołanie proc z 20 parametrami.

Joel Hendrickson
źródło
1
Nie jestem pewien, dlaczego odrzucono tę odpowiedź. To prawda, że ​​mniejsze zapytanie może działać lepiej. Zostało to nawet skomentowane przez zespół SQL Server.
Brannon
9

Lubię przechowywane procy, nie wiem ile razy mogłem dokonać zmiany w aplikacji przy użyciu procedury składowanej, która nie spowodowała żadnych przestojów w aplikacji.

Wielki fan Transact SQL, dostrajanie dużych zapytań okazało się dla mnie bardzo przydatne. Nie napisałem żadnego wbudowanego SQL od około 6 lat!

Natron
źródło
Po prostu nie rozumiem innego punktu widzenia przy użyciu kwerend w kodzie, po prostu nie mogę zrozumieć ...
Chaki_Black
8

Wymieniasz 2 pro-punkty dla sprocków:

Wydajność - niezupełnie. W Sql 2000 lub nowszym optymalizacje planu zapytań są całkiem dobre i buforowane. Jestem pewien, że Oracle itp. Robią podobne rzeczy. Nie sądzę, żeby było więcej argumentów za sprockami dla wydajności.

Bezpieczeństwo? Dlaczego sproki byłyby bardziej bezpieczne? O ile i tak nie masz dość niezabezpieczonej bazy danych, cały dostęp będzie pochodził z twoich DBA lub przez twoją aplikację. Zawsze parametryzuj wszystkie zapytania - nigdy nie wstawiaj niczego na podstawie danych wprowadzonych przez użytkownika, a wszystko będzie dobrze.

To i tak najlepsza praktyka w zakresie wydajności.

Linq to zdecydowanie sposób, w jaki teraz wybrałbym nowy projekt. Zobacz ten podobny post .

Keith
źródło
Ad-hoc plany wykonania SQL są ponownie wykorzystywane tylko w szczególnych okolicznościach: tinyurl.com/6x5lmd [SO odpowiedź z potwierdzeniem kodu] LINQ do SQL jest oficjalnie martwy: tinyurl.com/6298nd [post na blogu]
HTTP 410
1
Procesory są zdecydowanie najbezpieczniejszym sposobem. Ograniczają one użytkownika do podejmowania działań tylko w procesach. Nie mogą przejść bezpośrednio do tabeli lub widoku, do którego mają dostęp do zapisu i zmieniać rzeczy. Procesy są konieczne, aby zapobiec szkodom wynikającym z wewnętrznych zagrożeń.
HLGEM,
8

@Keith

Bezpieczeństwo? Dlaczego sproki byłyby bardziej bezpieczne?

Jak sugeruje Komradekatz, możesz zabronić dostępu do tabel (dla kombinacji nazwy użytkownika / hasła, która łączy się z bazą danych) i zezwalać tylko na dostęp SP. W ten sposób, jeśli ktoś dostanie nazwę użytkownika i hasło do bazy danych, może wykonać SP, ale nie może uzyskać dostępu do tabel ani żadnej innej części DB.

(Oczywiście wykonanie sproków może dać im wszystkie potrzebne dane, ale to zależy od dostępnych pulpitów. Danie im dostępu do tabel daje im dostęp do wszystkiego.)

Chłopak
źródło
1
@Joe Philllips, widoki nie zapewniają lepszego lub nawet równego bezpieczeństwa procesom i NIE będą one przydatne w zapobieganiu oszustwom lub szkodom wewnętrznym. Gdy używasz procs, model bezpieczeństwa polega na tym, że użytkownicy uzyskują dostęp do proc, a nie do tabel i widoków, a zatem nie mogą nic robić poza tym, co robi proc. Jeśli masz dane finansowe i nie korzystasz z procs, twój system jest zagrożony.
HLGEM
7

Pomyśl o tym w ten sposób

Masz 4 serwery WWW i kilka aplikacji Windows, które używają tego samego kodu SQL. Teraz zdałeś sobie sprawę, że jest mały problem z kodem SQl, więc raczej ...... zmień proc w 1 miejscu lub przekaż kod wszystkim na serwerach WWW, zainstaluj ponownie wszystkie aplikacje komputerowe (clickonce może pomóc) we wszystkich oknach systemu Windows

Wolę przechowywane procy

Łatwiej jest także przeprowadzić testy wydajności w stosunku do proc, umieścić go w analizatorze zapytań zestaw statystyk io / time na zestawie showplan_text on i voila

nie trzeba uruchamiać profilera, aby zobaczyć dokładnie, co się nazywa

tylko moje 2 centy

SQLMenace
źródło
6

Wolę trzymać je w kodzie (używając ORM, a nie inline lub ad-hoc), aby były objęte kontrolą źródła bez konieczności zapisywania plików .sql.

Ponadto procedury składowane nie są z natury bardziej bezpieczne. Możesz napisać złe zapytanie za pomocą sproc tak łatwo, jak inline. Sparametryzowane zapytania wbudowane mogą być tak samo bezpieczne jak sproc.

John Sheehan
źródło
6

Użyj kodu aplikacji tak, jak najlepiej: obsługi logiki.
Użyj swojej bazy danych do tego, co najlepiej robi: przechowuj dane.

Możesz debugować procedury składowane, ale łatwiej będzie debugować i utrzymywać logikę w kodzie. Zwykle kompilacja kodu kończy się przy każdej zmianie modelu bazy danych.

Również procedury składowane z opcjonalnymi parametrami wyszukiwania są bardzo przydatne, ponieważ musisz z góry określić wszystkie możliwe parametry, a złożone wyszukiwanie czasami nie jest możliwe, ponieważ nie możesz przewidzieć, ile razy parametr będzie powtarzany w wyszukiwaniu.

Santi
źródło
2
Gdy wiele aplikacji trafi do tej samej bazy danych, a na bazy danych ma wpływ import i inny bezpośredni dostęp (zaktualizuj wszystkie ceny o 10%), logika musi znajdować się w bazie danych, w przeciwnym razie utracisz integralność bazy danych.
HLGEM
W przypadku wielu aplikacji umieszczenie logiki w bibliotece używanej przez wszystkie aplikacje umożliwia zachowanie integralności przy jednoczesnym zachowaniu logiki w języku aplikacji. W przypadku importu / bezpośredniego dostępu zasadniczo zależy od tego, czy reguły mające zastosowanie do aplikacji powinny być egzekwowane, czy nie.
Dave Sherohman
3
wiele aplikacji nie powinno wprowadzać tego samego rodzaju zmian w bazie danych. powinien istnieć jeden komponent aplikacji, który zajmuje się jednym rodzajem zmian. Następnie ta aplikacja powinna udostępnić usługę, jeśli inni są zainteresowani. Wiele aplikacji zmieniających tę samą bazę danych / tabelę w dowolny sposób, który uznają za odpowiedni, powoduje, że system aplikacji i baza danych stają się nie do utrzymania.
Jiho Han
2
„powinien istnieć jeden komponent aplikacji, który zajmuje się jednym rodzajem zmian” - może to być procedura składowana, powiedzmy w PL / SQL.
RussellH
6

Jeśli chodzi o bezpieczeństwo, procedury przechowywane są znacznie bezpieczniejsze. Niektórzy twierdzą, że i tak cały dostęp będzie możliwy za pośrednictwem aplikacji. Wiele osób zapomina o tym, że większość naruszeń bezpieczeństwa pochodzi z wewnątrz firmy. Zastanów się, ilu programistów zna „ukrytą” nazwę użytkownika i hasło do aplikacji?

Ponadto, jak zauważył MatthieuF, wydajność można znacznie poprawić ze względu na mniejszą liczbę rund między aplikacją (na komputerze stacjonarnym lub serwerze sieciowym) a serwerem bazy danych.

Z mojego doświadczenia wynika, że ​​abstrakcja modelu danych za pomocą procedur przechowywanych również znacznie poprawia łatwość konserwacji. Jako ktoś, kto w przeszłości musiał utrzymywać wiele baz danych, jest to wielka ulga w obliczu wymaganej zmiany modelu, aby móc po prostu zmienić procedurę przechowywaną lub dwie i mieć całkowitą przejrzystość dla WSZYSTKICH aplikacji zewnętrznych. Wiele razy twoja aplikacja nie jest jedyną wskazaną w bazie danych - istnieją inne aplikacje, rozwiązania raportujące itp., Więc śledzenie wszystkich dotkniętych punktów może być kłopotliwe z otwartym dostępem do tabel.

W kolumnie plus sprawdzę również, czy programowanie SQL jest w rękach tych, którzy się w nim specjalizują, a także czy SP ułatwiają izolację i testowanie / optymalizację kodu.

Jedyną wadą, którą widzę, jest to, że wiele języków nie zezwala na przekazywanie parametrów tabeli, więc przekazywanie nieznanych wartości danych liczbowych może być denerwujące, a niektóre języki nadal nie są w stanie poradzić sobie z pobieraniem wielu zestawów wyników z jednej procedury składowanej (chociaż to ostatnie nie czyni go gorszym niż wbudowany SQL pod tym względem).

Tom H.
źródło
Kiedy model się zmienia, zwykle kod również musi ulec zmianie, niezależnie od tego, czy używa się sproców, czy dynamicznego SQL. A kiedy tworzysz tabele / schemat, jak często zmieniasz tylko tabelę / schemat? Nie często. Zazwyczaj zmiany pochodzą z firm, w których trzeba dodać kolejną kolumnę lub inną tabelę. W takim przypadku wątpię, czy można to zrobić bez zmiany kodu.
Jiho Han
4

Jedna z sugestii z sesji Microsoft TechEd na temat bezpieczeństwa, w której uczestniczyłem, aby wykonywać wszystkie połączenia za pośrednictwem przechowywanych procedur i odmawiać dostępu bezpośrednio do tabel. To podejście zostało rozliczone jako zapewniające dodatkowe bezpieczeństwo. Nie jestem pewien, czy warto ze względów bezpieczeństwa, ale jeśli już korzystasz z przechowywanych proc, nie zaszkodzi.

Eugene Katz
źródło
Bezpieczeństwo danych jest ważne, gdy usuwasz dane osobowe lub w szczególności informacje finansowe. Większość oszustów popełniają osoby z wewnątrz. Nie chcesz dać im dostępu, którego potrzebują, aby ominąć kontrole wewnętrzne.
HLGEM
4

Zdecydowanie łatwiejsze do utrzymania, jeśli umieścisz go w procedurze przechowywanej. Jeśli zaangażowana jest trudna logika, która potencjalnie może się zmienić w przyszłości, zdecydowanie warto umieścić ją w bazie danych, gdy łączy się wielu klientów. Na przykład pracuję teraz nad aplikacją, która ma interfejs WWW użytkownika końcowego i administracyjną aplikację komputerową, które współużytkują bazę danych (oczywiście) i staram się zachować jak najwięcej logiki w bazie danych. To doskonały przykład zasady DRY .

Andrew G. Johnson
źródło
4

Jestem zdecydowanie po stronie przechowywanych proc, zakładając, że nie oszukiwasz i nie używasz dynamicznego SQL w przechowywanym proc. Po pierwsze, użycie przechowywanych procs pozwala dba ustawić uprawnienia na poziomie przechowywanych proc, a nie na poziomie tabeli. Ma to kluczowe znaczenie nie tylko w walce z atakami SQL wstrzykiwania, ale także w zapobieganiu bezpośredniemu dostępowi do bazy danych i zmianie rzeczy. Jest to sposób na zapobieganie oszustwom. Żadna baza danych, która zawiera dane osobowe (numery SSN, numery kart kredytowych itp.) Lub która w jakikolwiek sposób tworzy transakcje finansowe, nie powinna być nigdy dostępna, z wyjątkiem procedur poufnych. Jeśli użyjesz innej metody, pozostawiasz bazę danych szeroko otwartą dla osób w firmie do tworzenia fałszywych transakcji finansowych lub kradzieży danych, które można wykorzystać do kradzieży tożsamości.

Przechowywane procy są również znacznie łatwiejsze do utrzymania i dostrajania wydajności niż SQL wysyłany z aplikacji. Pozwalają również dba zobaczyć, jaki wpływ będzie miała zmiana strukturalna bazy danych na sposób uzyskiwania dostępu do danych. Nigdy nie spotkałem dobrego dba, który umożliwiłby dynamiczny dostęp do bazy danych.

HLGEM
źródło
4

Używamy procedur przechowywanych z Oracle DB, w których teraz pracuję. Używamy również Subversion. Wszystkie procedury składowane są tworzone jako pliki .pkb i .pks i zapisywane w Subversion. Zrobiłem wcześniej SQL w linii i to jest ból! Wolę sposób, w jaki to tutaj robimy. Tworzenie i testowanie nowych procedur przechowywanych jest znacznie łatwiejsze niż robienie tego w kodzie.

Theresa

Theresa
źródło
3

Mniejsze dzienniki

Kolejny drobny pro dla procedur przechowywanych, o którym nie wspomniano: jeśli chodzi o ruch SQL, dostęp do danych opartych na sp generuje znacznie mniejszy ruch. Staje się to ważne, gdy monitorujesz ruch w celu analizy i profilowania - dzienniki będą znacznie mniejsze i czytelne.

Constantin
źródło
3

Nie jestem wielkim fanem procedur przechowywanych, ale używam ich pod jednym warunkiem:

Gdy zapytanie jest dość duże, lepiej jest przechowywać je w bazie danych jako procedurę przechowywaną zamiast wysyłać je z kodu. W ten sposób, zamiast wysyłać ogromne ilości znaków łańcuchowych z serwera aplikacji do bazy danych, tylko"EXEC SPNAME" wysyłane będzie polecenie.

Jest to nadmiar, gdy serwer bazy danych i serwer WWW nie znajdują się w tej samej sieci (na przykład komunikacja internetowa). I nawet jeśli tak nie jest, zbyt duży stres oznacza dużo zmarnowanego pasma.

Ale stary, tak strasznie sobie radzą. Unikam ich tak bardzo, jak potrafię.

Grzech
źródło
3

Procedura przechowywana w języku SQL nie zwiększa wydajności zapytania

Gagnaire Eric
źródło
Jak może nie być? Wyjaśnij o tym.
Sandesh
Zwiększy to wydajność, jeśli można skompilować zapytanie SQL.
TT.
3

Oczywiście użycie procedur przechowywanych ma kilka zalet w stosunku do konstruowania kodu SQL w kodzie.

  1. Implementacja kodu i SQL stają się od siebie niezależne.
  2. Kod jest łatwiejszy do odczytania.
  3. Napisz raz użyj wiele razy.
  4. Zmodyfikuj raz
  5. Nie trzeba podawać programiście wewnętrznych szczegółów dotyczących bazy danych. itd itd.
Bilal Khan
źródło
Nigdy nie byłem w sytuacji, w której posiadanie mniejszej ilości informacji o problemie z kodem lub nowej funkcji było dla mnie korzystne, czy mógłbyś wyjaśnić numer 5?
OpenCoderX
2

Procedury przechowywane są WIĘCEJ utrzymywane, ponieważ:

  • Nie musisz ponownie kompilować aplikacji C # za każdym razem, gdy chcesz zmienić część kodu SQL
  • W końcu ponownie używasz kodu SQL.

Powtarzanie kodu jest najgorsze rzeczą, jaką możesz zrobić, gdy próbujesz zbudować łatwą do utrzymania aplikację!

Co się stanie, gdy znajdziesz błąd logiczny, który należy poprawić w wielu miejscach? Bardziej prawdopodobne jest, że zapomnisz zmienić ostatnie miejsce, w którym kopiujesz i wklejasz swój kod.

Moim zdaniem wzrost wydajności i bezpieczeństwa to dodatkowy plus. Nadal możesz pisać niepewne / nieefektywne procedury składowane SQL.

Łatwiejsze przeniesienie do innej bazy danych - brak procedur do przeniesienia

Skryptowanie wszystkich procedur przechowywanych w celu utworzenia w innym DB nie jest trudne. W rzeczywistości - jest to łatwiejsze niż eksportowanie tabel, ponieważ nie musisz się martwić kluczami głównymi / obcymi.

Seibar
źródło
Tylko uwaga: „Łatwiejszy do przeniesienia na inny system DB - bez procedur do portu” odnosi się do przeniesienia do innego DBMS , a nie tylko innej instalacji. Istnieją alternatywy, wiesz ;-).
sleske,
2

@Terrapin - sproki są równie podatne na ataki iniekcyjne. Tak jak powiedziałem:

Zawsze parametryzuj wszystkie zapytania - nigdy nie wstawiaj niczego na podstawie danych wprowadzonych przez użytkownika, a wszystko będzie dobrze.

Dotyczy to sproców i dynamicznego Sql.

Nie jestem pewien, czy przekompilowanie Twojej aplikacji jest zaletą. Mam na myśli, że przeprowadziłeś testy jednostkowe dla tego kodu (zarówno aplikacji, jak i DB) przed ponownym uruchomieniem.


@Guy - tak, masz rację, sproki pozwalają kontrolować użytkowników aplikacji, dzięki czemu mogą oni wykonywać tylko sproc, a nie bazową akcję.

Moje pytanie brzmiałoby: jeśli cały dostęp do niego za pośrednictwem aplikacji, przy użyciu połączeń i użytkowników z ograniczonymi prawami do aktualizacji / wstawiania itp., Czy ten dodatkowy poziom zwiększa bezpieczeństwo lub dodatkową administrację?

Moja opinia jest w dużej mierze tym drugim. Jeśli skompromitowali Twoją aplikację do tego stopnia, że ​​mogą ją ponownie napisać, mają wiele innych ataków, których mogą użyć.

Zastrzyki SQL mogą być nadal wykonywane przeciwko tym sprokom, jeśli dynamicznie wstawiają kod, więc złota zasada nadal obowiązuje, wszystkie dane wejściowe użytkownika muszą być zawsze parametryzowane.

Keith
źródło
Musisz walczyć nie tylko na zewnątrz. Nie można zezwolić na bezpośredni dostęp do tabel użytkownikom, którzy mogliby następnie zmienić dane w celu popełnienia oszustwa.
HLGEM
Jako zasada, przechowywane procy nie powinny mieć możliwości korzystania z dynamicznego sql, prawie zawsze istnieje rozwiązanie niedynamiczne, jeśli go szukasz.
HLGEM
Wstrzykiwanie SQL nie jest tak skuteczne przeciwko sprocom z dynamicznie wstawianym kodem, ponieważ kod dynamiczny jest wykonywany za zgodą osoby dzwoniącej, a nie za zgodą właściciela (w przeciwieństwie do kodu statycznego). Dotyczy to SQL Server - nie jestem pewien co do Oracle.
HTTP 410
2

Coś, o czym do tej pory nie wspominałem: ludzie, którzy najlepiej znają bazę danych, nie zawsze są ludźmi, którzy piszą kod aplikacji. Procedury składowane dają użytkownikom bazy danych sposób na komunikację z programistami, którzy tak naprawdę nie chcą się tak dużo uczyć o SQL. Duże - a zwłaszcza starsze - bazy danych nie są najłatwiejsze do zrozumienia, więc programiści mogą po prostu preferować prosty interfejs, który zapewnia im to, czego potrzebują: pozwól DBA wymyślić, jak połączyć 17 tabel, aby tak się stało.

Biorąc to pod uwagę, języki używane do pisania procedur przechowywanych (przykładowo PL / SQL) są dość brutalne. Zazwyczaj nie oferują żadnych uprzejmości, które można zobaczyć w dzisiejszych popularnych imperatywach, OOP lub językach funkcjonalnych. Pomyśl o COBOL.

Dlatego trzymaj się procedur przechowywanych, które jedynie wyodrębniają relacyjne szczegóły, zamiast tych, które zawierają logikę biznesową.

yukondude
źródło
„Języki używane do pisania procedur przechowywanych (np. PL / SQL) są dość brutalne [i] nie oferują żadnych uprzejmości, które można by zobaczyć w dzisiejszych popularnych językach”. Musisz ponownie przeczytać dokumenty PL / SQL ( download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/toc.htm ). PL / SQL ma enkapsulację za pomocą pakietów, OOP poprzez typy obiektów, obsługę wyjątków, dynamiczne wykonywanie kodu, debuggery, profilery itp., A także setki standardowych pakietów / bibliotek dostarczanych przez Oracle do robienia wszystkiego, od wywołań HTTP do szyfrowania i wyrażeń regularnych . PL / SQL ma DUŻO subtelności.
ObiWanKenobi,
2

Generalnie piszę kod OO. Podejrzewam, że prawdopodobnie większość z was też. W tym kontekście wydaje mi się oczywiste, że cała logika biznesowa - w tym zapytania SQL - należy do definicji klas. Podział logiki tak, aby jej część znajdowała się w modelu obiektowym, a część w bazie danych, nie jest lepsza niż umieszczenie logiki biznesowej w interfejsie użytkownika.

Wiele powiedziano we wcześniejszych odpowiedziach na temat korzyści bezpieczeństwa przechowywanych procesów. Można je podzielić na dwie ogólne kategorie:

1) Ograniczanie bezpośredniego dostępu do danych. Jest to z pewnością ważne w niektórych przypadkach, a gdy je napotkasz, przechowywane procy są właściwie jedyną opcją. Z mojego doświadczenia wynika jednak, że takie przypadki są raczej wyjątkiem niż regułą.

2) Wstrzykiwanie SQL / zapytania parametryzowane. Sprzeciw ten jest czerwonym śledziem. Inline SQL - nawet dynamicznie generowany wbudowany SQL - może być tak samo sparametryzowany jak każdy przechowywany proc i może być równie łatwo wykonany w każdym nowoczesnym języku wartym swojej soli. Nie ma tu żadnej przewagi. („Leniwi programiści nie mogą zawracać sobie głowy używaniem parametrów” nie jest uzasadnionym sprzeciwem. Jeśli masz programistów w swoim zespole, którzy wolą po prostu konkatenować dane użytkownika do ich kodu SQL zamiast używać parametrów, najpierw spróbuj je edukować, a następnie zwolnij je jeśli to nie zadziała, tak jak w przypadku programistów, którzy mają inne złe, wyraźnie szkodliwe nawyki).

Dave Sherohman
źródło
2

Jestem wielkim zwolennikiem kodu nad SPROC. Powodem numer jeden jest ścisłe powiązanie kodu, a następnie na drugim miejscu jest łatwość kontroli źródła bez dużej liczby niestandardowych narzędzi do jego przyciągnięcia.

W naszym DAL, jeśli mamy bardzo złożone instrukcje SQL, zwykle uwzględniamy je jako pliki zasobów i aktualizujemy w razie potrzeby (może to być również osobny zestaw i zamieniany na db itp.).

Dzięki temu nasz kod i nasze wywołania SQL są przechowywane w tej samej kontroli wersji, bez „zapominania” o uruchamianiu zewnętrznych aplikacji do aktualizacji.

Tom Anderson
źródło
Co powiesz na „zapomnienie” o powieleniu zmian w tabelach?
craigmoliver
Proces może rozwiązać problemy z wdrażaniem.
Tom Anderson,