MySQL (69) - Prepared Statements

Prepared statemets alebo pripravené výrazy - čo vlastne sú, s čím nám pomáhajú a prečo ich používať? Odpoveď nájdete v tomto článku.

9.3.2011 00:00 | Marek Beleščiak | přečteno 12981×

Prepared statemets alebo pripravené výrazy - čo vlastne sú, s čím nám pomáhajú a prečo ich používať? Odpoveď nájdete v tomto článku.

MySQL má ešte jednu schopnosť, o ktorej ste možno nevedeli. Tou schopnosťou sú pripravené výrazy (prepared statements). Statementy sú spôsob ako efektívnejšie a bezpečnejšie dotazovať databázu. Uveďme si teda malý príklad:

SELECT * FROM `Article` WHERE `id` = ?

Otáznik vo výraze zastupuje hodnotu ktorá sa naňho "lepí" a otáznik sa zmení na onú hodnotu. Znie to trochu zložito a aby som bol presný, ako to celé funguje uvediem kompletný príklad:

mysql> PREPARE my_stmt FROM "SELECT nickname FROM account WHERE id = ?"; Query OK, 0 rows affected (0,00 sec) Statement prepared mysql> SET @id = '17'; Query OK, 0 rows affected (0,00 sec) mysql> EXECUTE my_stmt USING @id; +----------+ | nickname | +----------+ | Tester | +----------+ 1 row in set (0,02 sec) mysql> SET @id = '18'; Query OK, 0 rows affected (0,00 sec) mysql> EXECUTE my_stmt USING @id; +----------+ | nickname | +----------+ | Tester2 | +----------+ 1 row in set (0,00 sec) mysql> DEALLOCATE PREPARE my_stmt; Query OK, 0 rows affected (0,00 sec)
Statement pripravíme nasledovane:
  1. Spustíme príkaz PREPARE, za ktorým nasleduje meno nového statementu, za ním ďalej nasleduje FROM a za ním nakoniec dané query uzavreté v úvodzovkách s otáznikmi namiesto hodnôt - pamätajte, že otázniky nikdy nedávame do úvodzoviek alebo apostrofov.
  2. Ďalej nasleduje lepenie hodnôt. Definícia je vlastne nastavenie premennej. Za každý otáznik jedna definícia, takže si dajte bacha, nech otáznikov není viac ako definícií alebo naopak definícií viac ako otáznikov. Definujeme ju príkazom SET @meno = "HODNOTA";.
  3. Keď už máme daný výraz pripravený, hodnoty máme priradené, spustíme ho príkazom: EXECUTE, za ktorým nasleduje meno nášho statementu, následne USING a naše na-definované premenné oddelené čiarkou (@param1, @param2, ...).
  4. A nakoniec, keď už daný pripravený výraz nebudeme ďalej potrebovať, jednoducho ho uvoľníme, a to príkazom DEALLOCATE PREPARE, za ktorým nasleduje meno nášho statementu.

Statementy sú rýchlejšie ako normálne query, pretože každé query musí prejsť parsovaním, zatiaľ, čo statement prejde iba raz, a to, keď ho vytvoríte, potom už len naňho "lepíte" iné hodnoty. Najviac pocítite rýchlostný rozdiel pri nahadzovaní záloh alebo pri opakovaní jedného príkazu dokola napr. INSERT. Je to taktiež bezpochyby bezpečnejší spôsob, pretože rozdeľuje logiku od dát a tak pomáha predísť veľmi známemu útoku SQL Injection. Za normálnych okolností musíte byť veľmi opatrní, keď vkladáte do dotazu pre MySQL vstupné dáta od užívateľa. Pri pripravených výrazoch vám stačí escapnuť zopár problémových znakov ako sú napr. úvodzovky, apostrof, spätné lomítko alebo ASCII nula.

Ešte je jedno riešenie, kde môžeme nabrať na rýchlosti, a ním je nový binárny protokol, ktorý môže používať prepared statementy. Pretože v normálnom protokole mysql aj klient vždy zmenía všetky dáta na reťazce, ktoré sú vo väčšine prípadov väčšie ako originálne dáta, a až na servery sa zmenia na správny typ. Binárny protokol tieto dáta nijako neprekladá a posiela ich v originálnej forme, čo je samozrejme výhodné, pretože to znižuje zátaž procesora a taktiež zaťaženie siete.

Aj napriek týmto všetkým výhodám, sa statementy nie vždy oplatí používať, a totiž ani na všetko ich nejde používať. Kompletný zoznam podporovaných funkcii pripravených statementov pre MySQL (5.5) je tu. Ďalší dôvod, prečo ich nepoužívať je fakt, že niekedy sú pomalšie ako normálne regulárne dotazy - a to väčšinou keď sa daný výraz spustí iba raz, ale stále tu máte výhodu v bezpečnosti, takže nechám na vás kedy použiť a naopak nepoužiť Prepared Statementy.

Pokiaľ ste niekedy robili s MySQL nemal by byť pre vás problém vytvoriť program, ktorý beží na tejto báze, pokiaľ nie, väčšina jazykov už túto podporu má, alebo ju bude mať v blízkom čase. Ako príklad uvediem napr. mysqli rozšírenie pre PHP.

Záverom si myslím, že ste nadobudli dostatočne informácií o pripravených výrazoch, a viete o ich výhodách i nevýhodách. Môžu byť naozaj kľúčom k rýchlosti, výkonu a bezpečnosti, ak sú dobré použíté.

Online verze článku: http://www.linuxsoft.cz/article.php?id_article=1813