Nejvíc jsem v praxi asi narazil kvůli (o komentář výše zmíněnému) nepoužívání indexů uvnitř sub selectů. Tedy třeba
SELECT * FROM (SELECT * FROM customers) ORDER BY name
nepoužije index nad customers.name. Vtipné je, že pokud bych totéž zapsal pomocí view (tj. vznitřní select bych uložil jako view), index by se použil.
Řada odlišností se týká MyISAM a InnoDB tabulek. Kromě zmíněné absence full text indexů v InnoDB (ale ony reálně zas tak užitečné stejně nejsou) se jinak chová AUTO_INCREMENT. InnoDB nezaručuje, že nepřidělí již dříve použitý a smazaný index, protože si prostě hodnotu auto incrementu nepamatuje. Stejně tak nelze v InnoDB použít autoincrement nad klíčem tvořeným více sloupci.
Mám také pocit, že transakce se nesnesou s uzamykáním tabulek, takže i příkaz LOCK automaticky commitne transakci. Ale možná je to složitější a jen kecám.
Na druhou stranu, MySQL přišla s několika veleúspěšnými rozšířeními, které ostatní databáze mohou jen závidět (tedy byl bych raději, kdyby se zmohly i na víc než jen závidění ;) takže odsuzovat ji jako neschopný kus software není fér.
V INNO DB nelze kromě fulltextových indexů používat ani spatial indexy :( Sice to zní pěkně, že MySQL umí kde co, ale prakticky je dost nepoužitelné, protože si musíte vybrat, kterou „půlku“ věcí chcete používat.
Jinak je fakt, že některé věci se mi na MySQL líbí a kdyby opravili/dodělali ty zmíněné nedostatky, tak by to byla i celkem fajn DB. Ale to bude trvat ještě dlouho, pokud se tak vůbec stane.
Další věc je jakási licenční nejistota. Myslím, že většina lidí ani neví, kdy lze použít MySQL zdarma a kdy nikoli. Myslím, že to v poslední době také nějak změnilo.
InnoDB si autoincrement udrzuje v pameti takze pokud nespadne mysql tak je to jeste dobre.. V pripade padu, si InnoDB ziska pri startu posledni id cca dotazem
SELECT MAX(ID) FROm tables FOR UPDATE…
Pokud tedy posledni radek smazu, restartnu db, novy radek bude mit autoincrement onoho smazaneho.
Pokud se nepletu autoincrement muzes mit nad vice primarykey, jen musi byt prvni.
S tím AUTO_INCREMENT
to je trochu složitější. Zvýší se např. i při rollbacku transakce, kde byl zvýšen (což by možná neměl), ale při restartu ne (jak popisuje Petr Bíža).
LOCK
transakci skutečně commitne.
Netvrdim ze pri restartu db se zvysi autoincrement, to v zadnem pripade. Pri restartu se autoincrement zjisti znovu a to pri prvnim INSERT INTO (at jsem presny) a zde prave je zakopany pes.
Pokud napriklad vytvorim prazdnou tabulku a v definici mam auto_increment = 10 a restartnu DB tak po restarnu a vlozeni prvniho radku bude auto_increment = 1.
Při rollbacku by se rozhodně snižovat neměl. AUTO_INCREMENT by měl stát mimo transakci. Jinak by mohl nastat problém v situaci, kdy si (někde mimo databázi, třeba v cache) uložím id vloženého záznamu a provedu rollback, ale „nezapomenu“ hodnotu id. Pak získám při dalším insertu opět stejné id. A jsem v situaci, kdy mám dvě stejné hodnoty, které by měly ale odpovídat různým záznamům v databázi.
Ukládat si do cache řádek, který není v databázi, je nesmysl.
ROLLBACK by měl databázi vrátit do stavu před zahájením transakce. Někdy to samozřejmě nejde (např. když dvě transakce vloží dva záznamy a dřívější si to potom rozmyslí, tak v záznamech vznikne díra), čistě akademicky by se to ale takhle chovat mělo. Proč to tak není? Byla by s tím práce navíc a nikoho to vlastně netrápí.
Nemyslím si, že to je nesmysl, cache byl jen příklad. Zcela reálně se může stát, že v průběhu transakce nastane chyba a dojde k rollbacku a nová IDčka zůstanou „viset někde v aplikaci“ v části, která není (a ani snadno nemůže být) ošetřena transakčně (např. právě ta souborová cache). Nechme stranou, že zápis do těchto vrstev je možné provést až po skončení transakce…
Podstatné u rollbacku vidím spíš, že musí dojít k zachování integrity dat. Data se opravdu vrátí do stavu před začátkem transakce. Auto increment ale možná spadá i do oblasti metadat – může být i součástí CREATE TABLE statementu.
Nevim jak je to u MySQL ale u Oracle sekvence jako jedina neni uzavrena v transakci. A pri rollbacku se jeji hodnota nevraci. Existuje i NOCACHE verze, ktera se chova a tak jak navrhujete, ta ma ale jeden podstatny problem. sekvence se pak stava bodem synchronizace a DB nemuze pridelit dalsi ID dokud prvni transakce neskonci. Je zajimave kolik lidi rozciluje fakt, ze v IDckach mohou byt „diry“ a zpusoby jak to obejit jsou jeste zajimavejsi. Uz jsem videl system kde IDcka nepridelovala sekvence, ale aplikace. Protoze ale byly aplikacni servery dva, musely si cisla sekvence synchronizovat pres RMI. Kdyby jeden server prestal fungovat tak by nefungoval ani ten druhej.