Czy zapisywanie instrukcji SQL w tabeli do późniejszego wykonania jest złym pomysłem?

21

Czy zapisywanie instrukcji SQL w tabeli MySQL do późniejszego wykonania jest złym pomysłem? Instrukcje SQL będą gotowe do wykonania, tzn. Na przykład nie będzie żadnych parametrów do zamiany ani nic DELETE FROM users WHERE id=1.

Chyba jestem leniwy, ale pomyślałem o tym, ponieważ pracuję nad projektem, który będzie wymagał sporo zadań cron, które będą okresowo wykonywać instrukcje SQL.

Amged Rustom
źródło
Należy wyjaśnić, czy jeśli zamierzasz uruchomić te instrukcje SQL raz, czy chcesz wielokrotnie uruchamiać ten sam zestaw instrukcji.
GrandmasterB
10
Całe to pytanie wydaje się być jedną z tych sytuacji, w których podstawowe podejście jest błędne. Ale ciężko powiedzieć dokładnie, co tak mało wiemy o przestrzeni problemowej.
Erick Robertson

Odpowiedzi:

46

Jest bezpieczny, jeśli o to pytasz. Tak długo, jak dbasz o swoje bezpieczeństwo, tak samo jak o bezpieczeństwo swoich danych.

Ale nie wymyślaj na nowo koła, Procedury składowane TO fragmenty SQL przechowywane w tabeli. I wspierają, nie zachęcają, parametryzację.

Pamiętaj też, że możesz uprościć swoje bezpieczeństwo ORAZ zmniejszyć liczbę punktów awarii ORAZ zmniejszyć komunikację sieciową, używając Harmonogramu zdarzeń MySql zamiast crona.

Inne bazy danych mają te odpowiedniki, nie bez powodu. Nie jesteś pierwszym, który potrzebuje tej funkcjonalności.

pdr
źródło
1
+1 przy korzystaniu z harmonogramu. Ograniczenie dostępu programu planującego tylko do procesorów jest lepsze niż dostęp do tabeli.
JeffO
Ale co, jeśli chcesz dynamicznie tworzyć te zapytania, powiedzmy z interfejsu użytkownika? Na przykład, jeśli pozwalasz administratorom na dynamiczne ustawianie reguł dostępu do treści internetowych na podstawie złożonych zapytań. Nie chciałbyś, aby interfejs użytkownika tworzył nowy proces w bazie danych. Myślę, że w niektórych okolicznościach przechowywane zapytania są lepsze niż proc.
DiscipleMichael
32

Jeśli chcesz zapisać instrukcje SQL w bazie danych do późniejszego wykonania, istnieje lepsza opcja niż umieszczenie ich w tabeli: skorzystaj z wbudowanej funkcjonalności przewidzianej do tego konkretnego celu. Umieść je w procedurach przechowywanych.

Mason Wheeler
źródło
2
Gdzie więc zadanie cron przechowuje listę procedur przechowywanych do uruchomienia?
JeffO
1
może to być przydatne stackoverflow.com/questions/6560639/… chociaż nie używa crona
MetaFight
Nie wiem o czym myślałem. Lista proc może być wykonana z jednego procenta, więc zadanie crona musi tylko wykonać jeden.
JeffO
11

Nie, powiedziałbym, że to nie jest dobry pomysł.

Oznacza to, że każde „prawdziwe” zapytanie / aktualizacja będzie wymagało 2 trafień w bazie danych - jednego, aby uzyskać „prawdziwe” zapytanie / aktualizację, i jednego, aby je wykonać.

Może to nie być poważny problem w małym systemie, ale im więcej użytkowników / transakcji uzyska system, tym mniej będzie się skalować.

Zgaduję, że wynika to z szukania alternatywy dla osadzenia SQL w kodzie?

Hermetyzowanie SQL w procedurze przechowywanej, jak sugerował Mason Wheeler, byłoby jednym ze sposobów, który byłby o wiele lepszy niż ten pomysł.

ozz
źródło
+1, to główny powód, dla którego rozwiązanie @Mason Wheeler jest prawidłowe - po prostu tego nie zauważył. Chociaż IMHO nie jest problemem z wydajnością, widzę tutaj najważniejsze - po prostu nie trzeba komplikować rzeczy przez wyodrębnienie instrukcji SQL z bazy danych i odesłanie jej z powrotem do wykonania.
Doc Brown
Dlaczego lista instrukcji SQL musi być przechowywana w tej samej bazie danych / serwerze itp.?
JeffO
1
OP to propozycja 2 trafień w bazie danych. Mówię, że nie powinien tego robić. Następnie pytasz, dlaczego musi to być ta sama baza danych / serwer. Pytam, kto to powiedział? następnie pytasz, jak inaczej otrzymujesz 2 trafienia w DB. Dlaczego nie zadajesz rzeczywistego pytania zamiast tego, co robisz?
ozz
1
@JeffO Nawet jeśli jest to inna baza danych, to nadal są 2 zapytania do bazy danych, które powinny być 1 zapytaniem, co jest niepotrzebnym spowolnieniem
Izkata
1
@Ozz: przykładasz zbyt dużą wagę do aspektu wydajności w swojej odpowiedzi - wydajność jest najprawdopodobniej zaniedbana w większości rzeczywistych scenariuszy. Ale potrzeba dwóch akcji (pierwsza w celu uzyskania „prawdziwego” zapytania / aktualizacji, druga w celu jej wykonania) sprawia, że ​​sprawy są po prostu bardziej skomplikowane niż to konieczne.
Doc Brown
4

Niestety nie sądzę, że to dobry pomysł.

Rozważ przypadek, w którym zmienia się przedmiotowa tabela. Powiedzmy, że nazwa twojego identyfikatora zmienia się na new_id .

Oprócz samej zmiany istnieje wersja kodu napisana dla starego rocznika bazy danych, który może już nie działać. Pewnie, możesz wiedzieć, aby sprawdzić w tabeli kodów, ale nie jest to od razu oczywiste dla kogoś innego.

W przypadku zmiany, którą opisałem, zwykle patrzę na samodzielne pliki SQL, procedury składowane, wyzwalacze, wbudowany SQL w kodzie klienta (VB, C #, C ++ itp.), Ale ostatnie miejsce, w którym chciałbym szukać znajduje się w tabelach bazy danych. Chociaż może teraz to zrobię! :)

Robbie Dee
źródło
2

Istnieją ważne powody, aby przechowywać SQL w tabeli. Oprogramowanie, z którym pracuję w pracy, obejmuje teraz system generowania dokumentów, a dokumenty muszą zawierać dość złożone obliczenia z wykorzystaniem danych w bazie danych. Dokumenty są często aktualizowane, często różnią się znacznie pod względem potrzebnych danych i obliczeń, które należy wykonać. SQL jest zasadniczo używany jako język skryptowy do wykonywania tych obliczeń, a SQL jest przechowywany w tabelach, które przechowują również inne informacje dla tych dokumentów. Osoby obsługujące te dokumenty nie są programistami ani DBA, ale znają schemat bazy danych i biegle posługują się językiem SQL. Utrzymanie tego kodu SQL w postaci procedur przechowywanych byłoby dużym obciążeniem.

W przypadku tego, co opisałeś - „... projekt, który będzie wymagał sporo zadań cron, które będą okresowo wykonywać instrukcje SQL” - inne odpowiedzi prawdopodobnie są poprawne, sugerując, że używałeś procedur przechowywania lub równoważnych dla DBMS, który „ ponownie używam.

Dobrym kryterium decydującym o tym, czy rozsądnie jest przechowywać SQL w tabeli czy w procedurze przechowywanej, jest ustalenie, kto będzie utrzymywał ten SQL. Jeśli użytkownicy utrzymują ten SQL, tzn. Piszą go i zmieniają, kiedy tylko chcą, wówczas może być idealnie, a najlepiej najlepiej, przechowywać ten SQL w tabeli. Jeśli programiści będą utrzymywać ten SQL, powinien on być przechowywany w formie, która może być aktualizowana przez (miejmy nadzieję zautomatyzowane) procedury kompilacji i wdrażania, np. Przechowywany jako obiekt taki jak procedura przechowywana w samej bazie danych.

Kenny Evitt
źródło
1
Dziękuję za Twoją odpowiedź. Skończyło się na użyciu zdarzeń MySQL, aby zaplanować uruchamianie zapytań. Sporo osób uważało, że „podstawowe podejście jest błędne” :), gdy wszystko, czego potrzebowałem, to uruchomienie kilku instrukcji SQL po 15 minutach od określonego działania użytkownika.
Amged Rustom,
2
@AmgadSuliman - ważne jest, aby być charytatywnym dla wszystkich, szczególnie na stronach SE. Dobrze jest mieć mocne opinie, ale zbyt łatwo jest prześcignąć się w wzorach, z którymi lubimy się ważyć. Ale część bycia charytatywnym dla innych na tych stronach zapewnia wystarczający kontekst; zbyt wiele może przesłonić prawdziwe pytanie, ale ogólnie jest to dość łatwe do naprawienia przez późniejszą edycję.
Kenny Evitt,
1

Najłatwiejszym wyjściem byłoby posiadanie pliku .ini lub innego pliku konfiguracyjnego do przechowywania zapytań. W ten sposób możesz mieć je w jednym miejscu, zmieniać wszystko bez konieczności dostępu do bazy danych, aby to zrobić, nie uderzać bazy danych wiele razy a także możesz chcieć / potrzebować w pewnym momencie użyć parametrów lub dodać warunki do swoich zapytań (rozszerz je o bardziej złożone rzeczy dla konkretnego przypadku w kodzie).

Oczywiście możesz trzymać je na poziomie bazy danych (albo w tabeli, albo jeszcze lepiej, jako procedury składowane), jednak jeśli jesteś tak leniwy jak ja ;-), ale martwisz się również wydajnością, plikiem .ini i PHP ukochana metoda parse_ini , aby ją przeczytać, to droga do wyjścia (jeśli wybierasz inny język programowania, sam zastanawiasz się nad podobnymi podejściami)! Zwykle czytałem ten plik w bootloaderze aplikacji i trzymałem go w obiekcie statycznym (być może z warstwą pamięci podręcznej na wierzchu), aby naprawdę przyspieszyć, jeśli mówimy o bardzo dużej liczbie różnych zapytań.

Tiamarkos
źródło
1

Jeśli potrzebujesz instrukcji SQL tylko raz, na przykład, jeśli ustawisz w kolejce kilka operacji do wykonania poza godzinami pracy, to tak, umieszczenie ich w tabeli będzie działać dobrze.

Jeśli musisz wykonywać tę samą instrukcję SQL w określonych odstępach czasu, trasa procedury składowanej, o której wspominali inni, jest prawdopodobnie lepszym wyborem dla Ciebie.

To powiedziawszy, o co pytasz, jest dość niezwykłe i może wskazywać na jakiś inny problem. Na przykład, jeśli czekasz na usunięcie użytkownika z bazy danych, lepiej może wywołać zaplanowany skrypt, który wykonuje operację za pomocą kodu aplikacji, niż rejestrować rzeczywiste instrukcje SQL. W ten sposób SQL i kod nigdy nie są zsynchronizowane.

Grandmaster B.
źródło