Internet Info, s.r.o. Lupa Měšec Podnikatel Root Zdroják DigiZone Slunečnice Vitalia TopDrive KupDnes Navrcholu NovýTarif Dobrý web Weblogy Woko Jagg Computer.cz SK: MojeLinky

Hlavní navigace

Co nefunguje v MySQL a jak to obejít

Velmi rozšířený a oblíbený databázový server MySQL udělal za posledních několik let významný pokrok a k jednoduchému rychlému úložišti přidal i některé pokročilejší funkce. Na část vlastností je ale potřeba si dát pozor, některé z nich přímo nefungují. V následujícím článku uvádím ty nejviditelnější z nich.

Tweetni to Twitter Jaggni to! Jagg Del.icio.us Delicious

U sloupce typu date nelze nastavit výchozí čas na aktuální

Problém: Hodnota DEFAULT CURRENT_TIMESTAMP z historických důvodů funguje pouze u sloupce typu timestamp a navíc ji lze použít jen u jednoho takovéhoto sloupce v tabulce.

Řešení: Častý požadavek na existenci dvou sloupců vytvoreno a zmeneno se tedy řeší poněkud krkolomně. Dá se zajistit vytvořením BEFORE INSERT triggeru:

CREATE TRIGGER tabulka_bi BEFORE INSERT ON tabulka FOR EACH ROW
SET NEW.vytvoreno = NOW()

Sloupec zmeneno může být klasický timestamp.

Sestupné indexy

Problém: MySQL při definici indexů ignoruje požadavek na sestupné třídění položek – (skupina DESC, poradi) vytvoří stejný index jako (skupina, poradi).

Řešení: MySQL dokáže takovýto index použít i pro sestupné třídění, důležité ale je, aby pořadí všech částí indexu bylo při třídění stejné: ORDER BY skupina DESC, poradi DESC index využije, dotaz ORDER BY skupina DESC, poradi ne. Pokud to nedokážeme zaručit, můžeme do tabulky vložit opačnou hodnotu sloupce a řadit podle něj, obvykle to ale potřeba není.

Indexy nad výsledkem funkce

Problém: MySQL na rozdíl třeba od PostgreSQL nedovoluje vytvářet indexy nad výsledkem funkce. Pokud na sloupec v dotazu aplikujeme nějakou funkci, tak se index až na výjimky nepoužije.

Řešení: Při porovnávání je tedy vhodné indexované sloupce uvádět samotné:

-- index se nepoužije
SELECT * FROM tabulka WHERE zmeneno + INTERVAL 1 DAY >= NOW();

-- použije se index nad sloupcem (zmeneno)
SELECT * FROM tabulka WHERE zmeneno >= NOW() - INTERVAL 1 DAY;

Materializované pohledy

Problém: Pohledy se v MySQL vyhodnocují při každém dotazu znovu. Na rozdíl od jiných databázových serverů nedokáže MySQL vytvořit tzv. materializovaný pohled, který by data fyzicky ukládal (a při změně aktualizoval) a nad kterým by třeba šly definovat i indexy.

Řešení: Vyřešit se to obvykle dá doplněním dopočítávaných sloupců a jejich automatickou aktualizací pomocí triggerů, dá to ale dost práce.

Trigger nemůže měnit stejnou tabulku

Problém: Trigger nemůže měnit data ve stejné tabulce, pro kterou je definován.

Řešení: Žádný work-around neznám, ale pokud nám stačí upravit modifikovaný záznam, lze to udělat změnou hodnot v „tabulce“ NEW.

Stejné omezení platí i pro poddotazy při modifikaci záznamu – ty se také nemohou dotazovat do stejné tabulky. Takový příkaz je nutné rozdělit do dvou – nejprve získat data a v druhém kroku provést aktualizaci.

Triggery se nespustí při kaskádovém mazání

Problém: Pokud definujeme cizí klíč s příznakem ON DELETE CASCADE a v tabulce je definovaný trigger pro smazání, tak se tento trigger nespustí, pokud se záznam smaže v důsledku kaskády.

Řešení: Řešení je pro tabulky s takovýmto triggerem nepoužívat kaskádové mazání a záznamy mazat ručně. Často ale trigger pouze mění záznam v rodičovské tabulce, kdy nám jeho nespuštění nemusí vadit.

Příkazy ukončující transakci

Problém: Všechny příkazy pracující se strukturou tabulek vyvolají implicitní COMMIT právě probíhající transakce. Platí to i pro další příkazy, např. ty pro práci s uživateli a donedávna třeba i pro příkaz LOAD DATA.

Řešení: V transakcích je tedy vhodné používat jen příkazy manipulující s daty.

Omezující podmínky

Problém: MySQL ignoruje omezující podmínky definované klauzulí CHECK při vytváření tabulky.

Řešení: Obejít se to dá triggerem, který v případě nesplnění podmínky vyvolá chybu:

CREATE TRIGGER uzivatel_bi BEFORE INSERT ON uzivatel FOR EACH ROW
IF CHAR_LENGTH(NEW.login) < 3 THEN
	DO `Login musí mít alespoň tři znaky.`;
END IF

Stejný trigger bychom samozřejmě museli definovat i pro změnu záznamu.

Všimněte si také krkolomného způsobu vyvolání chyby, který navíc MySQL obalí hláškou, že sloupec daného jména neexistuje. V MySQL totiž neexistuje příkaz SIGNAL, který by se dal pro vyvolání chyby použít.

Valentýna vyřešíte v našem butiku

Pánové, Valentýn je tu a tak jsme pro vás v našem butiku připravili balíček dámských kalhotek a trička za zvýhodněnou cenu 365 Kč.

       

Závěr

MySQL je stále mladý databázový server a otázkou je, jestli budou uvedené nedostatky v blízké budoucnosti odstraněny. Lepší je proto o nich vědět a naučit se s nimi žít.

Pokud jste narazili na další gotchas, tak s nimi čtenáře můžete seznámit v diskusi.

Jakub Vrána

Jakub Vrána

Autor se živí programováním v PHP, podílí se na jeho oficiální dokumentaci, vyučuje ho na MFF UK a vede odborná školení. Poznámky si zapisuje na weblog PHP triky.

Školení: Pokročilejší kurz jazyka Java

Java je multiplatformní programovací jazyk, který vytvořila a vyvíjí společnost Sun. Java je silný, objektově orientovaný jazyk se širokou komunitou, nabízející především vysokou produktivitu vývoje.

  • Práce s řetězci
  • Regulární výrazy
  • Kolekce
  • Generiky
  • Smyčka typu "for" ve verzi Java 1.5
  • Výčty
  • Vlákna, synchronizace
  • Polymorfismus, RTTI
  • Java Beany
  • JDBC (práce s databázemi)
  • GUI (knihovny AWT a Swing)
  • Java na serveru (servlety, JSP)

Podrobnější informace a přihláška

Ohodnoťte jako ve škole:
Průměrná známka 3,03

Přehled názorů

výkon view a implicitni commit a fulltextove klice, nazvyTabulek
jakub 16. 12. 2009 02:12
Nový
├ 
Re: výkon view a implicitni commit a fulltextove klice, nazvyTabulek
Petr Bíža 16. 12. 2009 08:15
Nový
│
└ 
Re: výkon view a implicitni commit a fulltextove klice, nazvyTabulek
jakub 18. 12. 2009 13:10
Nový
└ 
Re: výkon view a implicitni commit a fulltextove klice, nazvyTabulek
anonym 16. 12. 2009 10:38
Nový
 
└ 
Re: výkon view a implicitni commit a fulltextove klice, nazvyTabulek
Martin Soušek 16. 12. 2009 11:46
Nový
 
 
└ 
Re: výkon view a implicitni commit a fulltextove klice, nazvyTabulek
vecernik 18. 12. 2009 10:55
Nový
Dva (a vice) sloupce timestamp s vychozi hodnotou CURRENT_TIMESTAMP
Karel Barel 16. 12. 2009 07:15
Nový
└ 
Re: Dva (a vice) sloupce timestamp s vychozi hodnotou CURRENT_TIMESTAMP
Peter Helcmanovsky 16. 12. 2009 11:12
Nový
 
└ 
Re: Dva (a vice) sloupce timestamp s vychozi hodnotou CURRENT_TIMESTAMP
jos 16. 12. 2009 14:41
Nový
funkcionalni indexy
Pavel Stěhule 16. 12. 2009 09:02
Nový
└ 
Re: funkcionalni indexy
anonym 16. 12. 2009 10:40
Nový
 
├ 
Re: funkcionalni indexy
Tomáš Crhonek 16. 12. 2009 10:44
Nový
 
│
├ 
Re: funkcionalni indexy
Tango 16. 12. 2009 11:07
Nový
 
│
│
├ 
Re: funkcionalni indexy
Pavel Stěhule 16. 12. 2009 11:34
Nový
 
│
│
└ 
Re: funkcionalni indexy
Karel 16. 12. 2009 13:13
Nový
 
│
└ 
Re: funkcionalni indexy
Karel 16. 12. 2009 12:36
Nový
 
└ 
Re: funkcionalni indexy
Pavel Stěhule 16. 12. 2009 11:39
Nový
 
 
└ 
Re: funkcionalni indexy
mofo 16. 12. 2009 11:47
Nový
 
 
 
└ 
Re: funkcionalni indexy
Pavel Stěhule 16. 12. 2009 11:50
Nový
Dobry napad
Eduard DRUSA 16. 12. 2009 09:13
Nový
Re: Co nefunguje v MySQL a jak to obejít
xvasek 16. 12. 2009 09:21
Nový
└ 
Re: Co nefunguje v MySQL a jak to obejít
dush 16. 12. 2009 10:47
Nový
Mlada databaze?
Kuk 16. 12. 2009 09:38
Nový
├ 
Re: Mlada databaze?
Lisk 16. 12. 2009 10:28
Nový
├ 
Re: Mlada databaze?
pavel 16. 12. 2009 10:36
Nový
│
└ 
Re: Mlada databaze?
Petr Bíža 16. 12. 2009 10:38
Nový
└ 
Re: Mlada databaze?
Pavel Říha 16. 12. 2009 10:43
Nový
 
├ 
Re: Mlada databaze?
Lenin POWER! 16. 12. 2009 11:14
Nový
 
└ 
Re: Mlada databaze?
mofo 16. 12. 2009 11:53
Nový
 
 
└ 
Re: Mlada databaze?
Michal Kára 16. 12. 2009 12:08
Nový
 
 
 
├ 
Re: Mlada databaze?
... 16. 12. 2009 12:39
Nový
 
 
 
│
├ 
Re: Mlada databaze?
VM 16. 12. 2009 12:58
Nový
 
 
 
│
└ 
Re: Mlada databaze?
Pavel Stěhule 16. 12. 2009 16:52
Nový
 
 
 
├ 
Re: Mlada databaze?
Tomas 16. 12. 2009 13:00
Nový
 
 
 
│
├ 
Re: Mlada databaze?
Michal Kára 16. 12. 2009 14:18
Nový
 
 
 
│
│
└ 
Re: Mlada databaze?
jos 16. 12. 2009 14:24
Nový
 
 
 
│
└ 
Re: Mlada databaze?
Pavel Říha 16. 12. 2009 14:55
Nový
 
 
 
│
 
└ 
Re: Mlada databaze?
mofo 16. 12. 2009 17:34
Nový
 
 
 
└ 
Re: Mlada databaze?
muhehe 16. 12. 2009 21:37
Nový
 
 
 
 
└ 
Re: Mlada databaze?
Lenin POWER! 17. 12. 2009 00:19
Nový
triggery - update tabulky
Pavel Stěhule 16. 12. 2009 09:44
Nový
├ 
Re: triggery - update tabulky
Gorila 16. 12. 2009 10:39
Nový
│
└ 
Re: triggery - update tabulky
Pavel Stěhule 16. 12. 2009 11:14
Nový
└ 
Re: triggery - update tabulky
Lenin POWER! 16. 12. 2009 12:04
Nový
 
└ 
Re: triggery - update tabulky
Pavel Stěhule 16. 12. 2009 12:25
Nový
Trigger nemůže měnit stejnou tabulku
Jan Smrz 16. 12. 2009 10:46
Nový
poddotazy a modifikace stejne tabulky
dush 16. 12. 2009 10:53
Nový
└ 
Re: poddotazy a modifikace stejne tabulky
Petr Bíža 16. 12. 2009 11:00
Nový
 
├ 
Re: poddotazy a modifikace stejne tabulky
dush 16. 12. 2009 11:16
Nový
 
│
└ 
Re: poddotazy a modifikace stejne tabulky
Petr Bíža 16. 12. 2009 11:33
Nový
 
└ 
Re: poddotazy a modifikace stejne tabulky
Kajman 16. 12. 2009 23:30
Nový
default
jos 16. 12. 2009 11:46
Nový
├ 
Re: default
Pavel Stěhule 16. 12. 2009 11:53
Nový
│
└ 
Re: default
jos 16. 12. 2009 12:24
Nový
│
 
├ 
Re: default
logik 16. 12. 2009 12:53
Nový
│
 
│
└ 
Re: default
jos 16. 12. 2009 14:32
Nový
│
 
└ 
Re: default
Pavel Lang 19. 12. 2009 01:47
Nový
└ 
Re: default
Filip Jirsák 16. 12. 2009 13:40
Nový
 
└ 
Re: default
jos 16. 12. 2009 14:27
Nový
 
 
├ 
Re: default
Filip Jirsák 16. 12. 2009 19:13
Nový
 
 
│
└ 
Re: default
jos 16. 12. 2009 19:48
Nový
 
 
│
 
└ 
Re: default
Filip Jirsák 17. 12. 2009 22:24
Nový
 
 
│
 
 
└ 
Re: default
jos 18. 12. 2009 15:31
Nový
 
 
│
 
 
 
└ 
Re: default
Pavel Lang 19. 12. 2009 02:14
Nový
 
 
└ 
Re: default
Ivan 17. 12. 2009 14:00
Nový
 
 
 
└ 
Re: default
jos 17. 12. 2009 15:23
Nový
jsem rad za usetrene roky zivota
backup 16. 12. 2009 12:24
Nový
├ 
Re: jsem rad za usetrene roky zivota
Pavel Stěhule 16. 12. 2009 12:32
Nový
└ 
Re: jsem rad za usetrene roky zivota
Karel 16. 12. 2009 13:50
Nový
 
└ 
Re: jsem rad za usetrene roky zivota
jos 16. 12. 2009 14:36
Nový
ad Příkazy ukončující transakci
lolek 16. 12. 2009 14:11
Nový
├ 
Re: ad Příkazy ukončující transakci
jos 16. 12. 2009 14:48
Nový
│
└ 
Re: ad Příkazy ukončující transakci
lolek 16. 12. 2009 15:07
Nový
│
 
├ 
Re: ad Příkazy ukončující transakci
jos 16. 12. 2009 15:40
Nový
│
 
└ 
Re: ad Příkazy ukončující transakci
Lenin POWER! 16. 12. 2009 17:29
Nový
│
 
 
└ 
Re: ad Příkazy ukončující transakci
Michal Kára 16. 12. 2009 18:34
Nový
└ 
Re: ad Příkazy ukončující transakci
Pavel Stěhule 16. 12. 2009 17:02
Nový
PROBLEM S EVENTY
tomkass 16. 12. 2009 15:48
Nový
dalsie veci
jozko 16. 12. 2009 17:28
Nový
└ 
Re: dalsie veci
podlesh 16. 12. 2009 18:01
Nový
 
└ 
Re: dalsie veci
jozko 16. 12. 2009 20:09
Nový
 
 
└ 
Re: dalsie veci
logik 17. 12. 2009 00:07
Nový
 
 
 
└ 
Re: dalsie veci
Lenin POWER! 17. 12. 2009 00:11
Nový
MySQL neumí indexy v subselectech (poddotazech), ve WHERE IN
mcmatak 16. 12. 2009 21:18
Nový
└ 
Re: MySQL neumí indexy v subselectech (poddotazech), ve WHERE IN
Jan Garaj 17. 12. 2009 00:49
Nový
FULL OUTER JOIN
iBej 16. 12. 2009 21:57
Nový
Gotchas
David Grudl 16. 12. 2009 22:03
Nový
├ 
Re: Gotchas
Honza77 16. 12. 2009 23:49
Nový
├ 
Re: Gotchas
Petr Bíža 17. 12. 2009 09:04
Nový
└ 
Re: Gotchas
Jakub Vrána 17. 12. 2009 10:35
Nový
 
├ 
Re: Gotchas
Petr Bíža 17. 12. 2009 10:41
Nový
 
│
└ 
Re: Gotchas
Jakub Vrána 17. 12. 2009 10:49
Nový
 
│
 
└ 
Re: Gotchas
Petr Bíža 17. 12. 2009 11:00
Nový
 
│
 
 
└ 
Re: Gotchas
Jakub Vrána 17. 12. 2009 11:09
Nový
 
│
 
 
 
└ 
Re: Gotchas
Petr Bíža 17. 12. 2009 11:23
Nový
 
│
 
 
 
 
└ 
Re: Gotchas
Martin 17. 12. 2009 12:10
Nový
 
├ 
Re: Gotchas
Martin 18. 12. 2009 09:13
Nový
 
│
└ 
Re: Gotchas
Jakub Vrána 18. 12. 2009 10:24
Nový
 
│
 
├ 
Re: Gotchas
Martin 18. 12. 2009 20:47
Nový
 
│
 
└ 
Re: Gotchas
Pavel Lang 19. 12. 2009 02:48
Nový
 
│
 
 
└ 
Re: Gotchas
Pavel Stěhule 19. 12. 2009 05:45
Nový
 
└ 
Re: Gotchas
Ivan 18. 12. 2009 14:30
Nový
Velmi rozšířená a oblíbený databázový server MySQL…
Ondřej Caletka 17. 12. 2009 23:15
Nový
└ 
Re: Velmi rozšířená a oblíbený databázový server MySQL…
Jakub Vrána 18. 12. 2009 10:11
Nový
nemoznost pouzit tmp table dvakrat v jednom dotazu
jakub 18. 12. 2009 13:36
Nový
└ 
Re: nemoznost pouzit tmp table dvakrat v jednom dotazu
Pavel Stěhule 18. 12. 2009 13:44
Nový
 
└ 
Re: nemoznost pouzit tmp table dvakrat v jednom dotazu
jakub 19. 12. 2009 01:33
Nový
Máloco dodat
Alegorické kozy 24. 12. 2009 08:31
Nový
panove lahudka! dump a nasledny import zazdi typ enginu a cizi klice
jakub 28. 12. 2009 14:40
Nový
└ 
Re: panove lahudka! dump a nasledny import zazdi typ enginu a cizi klice
jakub 28. 12. 2009 18:20
Nový
       

Tento text je již více než dva měsíce starý. Chcete-li na něj reagovat v diskusi, pravděpodobně vám již nikdo neodpoví. Pro řešení aktuálních problémů doporučujeme využít naše diskusní fórum.

Zasílat nově přidané příspěvky e-mailem