Zapomeňte na MySQL! Nic horšího není!

MyEgo.cz

home foto blogy mywindows.cz kontakt

Zapomeňte na MySQL! Nic horšího není!

PHP 14.04.04
MySQL

Lidé kolem webu mají rádi MySQL. Proč? Protože je to skvělá databáze? Ne. Protože to je primitivní, a v konečném důsledku i mimořádně pomalá databáze, které ovšem ONI rozumí. Pár triviálních SELECT, INSERT, UPDATE příkazů se totiž naučí každý a hned si myslí, že "rozumí databázím"…

Je načase říci, že MySQL je špatná databáze, jednoduchý filesystém, která je v konečném důsledku pomalá a nepodporuje správné programátorské zvyky a postupy. Tahat data na klienta, kvůli sub-SELECTu, či suplovat funkci TRIGGERu v PHP je mimořádně špatná koncepce!

Kdyby se lidi weboví chtěli naučit trošku více SQL a PL/SQL a začali používat (taky open-source) PostgreSQL či Firebird, namísto MySQL, řada složitých aplikací by běžela mnohem rychleji.

V čem je MySQL tak špatná?

Mýtus rychlosti MySQL

MySQL je prý rychlá. Hm. Ale v čem? Dělá 2x rychleji toto?

SELECT name FROM table 
  WHERE UID=1 

Rychleji než Oracle? No, možná. Nicméně, co pokud potřebujeme něco více než primitivní sériový přístup? Třeba toto:

SELECT name, title, url FROM article 
  WHERE time=(SELECT max(time) 
  FROM article) 

Můžete toto udělat v MySQL? Ne. V Oracle či PostgreSQL ano! Co musíte udělat v MySQL? No, minimálně toto:

$query=mysql_query('SELECT max(time) as itime FROM article
$row=mysql_fetch_object($query);
$query=mysql_query('SELECT name,title,url 
  FROM article WHERE time='.$row->itime);

Nejenže je v tomto případě MySQL mnohem pomalejší, ale musíte suplovat její chybějící triviální funkce v nějakém aplikačním jazyku, v tomto případě konkrétně v PHP, a přenášet tak na klienta mnohem více dat, dělat více SQL dotazů, více zatěžovat server.

V důsledku je pro cokoliv jiného než nesmírně triviální dotazy nesmírně triviálních aplikací MySQL pomalejší než konkurence, a mnohem hůře udržovatelná (protože požaduje aplikační logiku i na straně klienta; co když ovšem klienta změníme?).

Mýtus dobré funkčnosti MySQL

Fuknčnost MySQL je prý dostatečná. To rozhodně ne! Příklad: máte webový redakční systém. Po 2 letech jeho provozu si někdo vzpomene, že chce, aby články v něm měly automatickou expiraci. Co uděláte ve slušné databázi? Přidáte dané tabulce položku expiration typu DATETIME a změníte jedno VIEW:

namísto současného 
CREATE VIEW article_current AS SELECT * FROM article WHERE  time>NOW()
vytvoříte nové view
CREATE VIEW article_current AS 
  SELECT * FROM article 
  WHERE time>NOW() AND expiration<=NOW()

A to je celé. V klientské aplikaci nic neměníte. Jak Vám to dlouho zabere? Tak 1 minutu. I s testováním.

Co budete muset udělat v MySQL? No, budete muset překopat celý PHP kód, celý parser, všechny pluginy, a do každého SQL dotazu doplnit WHERE… expiration<=NOW(), protože MySQL neumí ani to VIEW. Jak Vám to dlouho zabere? Možná i pár dní, než vše otestujete…

Nebo jiný příklad. Máte články, a máte komentáře. Chcete při každém přidání komentáře generovat tabulku se statistikou, poslední komentáře, poslední diskuse, nejkomentovanější.

Jak na to ve skutečné databázi? Použijete samozřejmě TRIGGER.

CREATE TRIGGER update_comment_count
 AFTER INSERT ON comments 
  FOR EACH ROW
  BEGIN
  UPDATE article SET comment_count=comment_count+1 WHERE uid=:NEW.article_id;
 END; 

Co to udělá? Ať už vložíte komentář jakkoliv, skutečná databáze databáze zajistí, tímto jednoduchým kódem, že v položce article.comment_count bude vždy aktuální počet komentářů daného článku.

A co v MySQL? MySQL toto opět neumí. Musíte si pomoci na aplikační úrovni. Mimo MySQL. Jak? No, na všech místech, kde vkládáte článek, musíte zavolat třeba proceduru PostAddComment(uid). Jaká to má rizika? Můžete na toto volání zapomenout. Pokud do databáze budete přistupovat i jinak než z tohoto PHP kódu, musíte všechnu funkčnost zduplikovat.

V případě skutečné databáze je naprosto jedno, zda se tam napojím z PHP, Delphi, C++, či Javy. Trigger se vždy provede. V MySQL nic takového není. Musím to dělat aplikačně. A to je moc špatně.

TRIGGER je přitom pouze základní věc, PL/SQL obsahuje mnohem více prvků, PACKAGE, FUNCTION, CURSOR, a další nezbytné komponenty, podporuje práci s XML, popřípadě umí i nativně komunikovat přes TCP/IP s klientskou realtime aplikací. MySQL nic z toho nezvládá.

Mýtus použitelnosti MySQL

MySQL je zjevně to nejhorší koncepce tzv. databáze. Ona MySQL totiž není databáze. Je to primitivní filesystém. Filesystém, který navíc ani nepodporuje (pořádně) transakce, což je další obrovský problém. Pro libovolné aplikace.

MySQL je prostě soubor, a kus kódu, který v tom souboru čte. Není moc velký rozdíl používat MySQL, nebo si v PHP napsat knihovny pro práci s textovými soubory a pracovat s nimi. Tedy, rozdíl v tom je, binárka MySQL má 20MB, tato Vaše knihovna by měla tak 100Kb. Kdysi moc dávno jsem si napsal lepší funkčnost než má dnešní MySQL v Turbo Pascalu (pro MS-DOS). Trvalo mi to týden, a ta knihovna uměla efektivně SELECTY, WHERE, INSERT, UPDATE. Tedy to, co zvládá dnešní MySQL.

Proč je tedy MySQL populární?

  • Protože je zdarma? To snad ne. Máme tu třeba řádově lepší PostgreSQL, která je rovněž open-source.
  • Protože je jednoduchá? Jasně. Je. Je doslova primitivní. Lidem, co sotva zvládají kódování pár tagů (X)HTML toto vyhovuje. Učit se PostgreSQL či (nedejbože PL/SQL v Oracle), na to nemají znalosti a buňky (tedy, někteří).

Bůh dopusť, ať nám MySQL zahyne! Věnuji se databázím více než 10 let, ale toto vidět v roce 2004 je… neuvěřitelné. Oracle měl už v roce 1992 podstatně lepší funkčnost, když jsem s ním začínal.

Shrnutí

Kdyby se lidi weboví chtěli naučit trošku více SQL a PL/SQL a začali používat (taky open-source) PostgreSQL či Firebird, namísto MySQL, řada složitých aplikací by běžela mnohem rychleji. Jakákoliv, byť jen mírně složitější aplikace, potřebuje sub-SELECT a VIEWS a dokonce by hodně použila i triggery…

Někomu prostě primitivnost MySQL vyhovuje. Je načase ale říci, že to je špatná databáze, která je v důsledku pomalá a nepodporuje správné programátorské zvyky a postupy.

Tahat data na klienta, kvůli sub-SELECTu, či psát PHP kód místo TRIGGERu je mimořádně špatná koncepce! Jenže 99% lidí, co dělá web, jsou nedouci, a nikoliv skuteční programátoři…


Komentáře

  1. 1 enemy 15.04.04, 10:04:55
    FB

    Mozna by stacilo rici, ze na nektere veci staci multiplatformni MySQL. Na jine pouziji PgSql a jinde Oracle databazi.
    V prizpevku MySQL porovnavate rychlosti a prenositelnost s Oracle, jinde cenu s PgSQL. Treba prehledna tabulka s vyhody/nevyhody by pomohla udelat ctenari nezaujaty nazor, kdy kterou DB uzit, nez slohova cviceni...

  2. 2 Japan 16.04.04, 10:04:33
    FB

    Ja naprostou souhlasim s nazorem ze MySQL neni moc dobra DB, ale je treba si uvedomit ze 99% freewebu a dokonce velky pocet komercnich webhostingu nabizi na linuxove platforme prave toto a kdyz adminy pozadate o Posta ci Firebirda, vesele vam odpovi ze s nim nemaji zkusenosti a vsechno maji na MySQL a menit nebudou... Navic, spousty free PHP kodu, redakcnich systemu, ukazek etc. je napsano pro MySQL a diky tomu se lidi co s PHP (ci jinym) zacinaji nedozvi ze existuje neco lepsiho.

    Je to asi jako s Woknama - spousty lidi vi, ze nejsou nejlepsi, nejspolehlivejsi a nejstabilnejsi, ale presto je pouzivaji, diky tunam aplikaci etc. a spousta lidi si mysli ze woka = pocitac... a myslim ze v IT je takovych prikladu spousta a vsechny by se dali podobnym zpusobem zobecnit.

  3. 3 MiP 16.04.04, 02:04:58
    FB

    Ale clovece. Ve vetsine veci mas pravdu, mozna by stacilo min agresivity do psani...

    Vadi mi trosku:

    "Tahat data na klienta, kvůli sub-SELECTu..."

    co je pro tebe klient?

    jiste ze napr. bezici php skript je take klient v jistem pohledu ale ja si pod pojmem klient predstavuju prohlizec koncoveho uzivatele, a tomu se nic neposila!

    Doufejme ze pristi verze MySql prinesou potrebna vylepseni protoze nikoho nedonutis ho prestat pouzivat a zvolit jine (ne nutne lepsi) alternativy.

  4. 4 Radek Hulán 16.04.04, 03:04:24
    FB

    [3] PHP je, v určitém smyslu, klient. Rozhodně podstatně zvyšuje režii a přenosy dat v rámci serveru, na rozdíl od funkčních sub-SELECTů, triggerů, views..

  5. 5 otty 16.04.04, 11:04:05
    FB

    [1] Porovnanie PostgreSQL a MySQL

    http://openacs.org/philosop...

  6. 6 Ondrej Valek 23.04.04, 11:04:56
    FB

    A tak si vsichni koupime Oracle, a budeme stastni ;-)

    Ne, je to jedna z nekolika alternativ, a stale se zlepsuje. Samozrejme, ze mi take chybi vnorene selecty a referencni integrita, ale co neni, casem bude. Nikdo vas nenuti ji pouzivat.

    A vzdycky bude databaze v MySQL (ktere autor ovlada) lepe udelana nez v Oraclu (ktery ovladat neumi).

  7. 7 Miloslav Ponkrác 20.05.04, 03:05:16
    FB

    Musím chtě nechtě s článkem hrubě nesouhlasit. Živím se jako databázista, a měl jsem v ruce nejrůznější databáze. Řekl bych, že autor nepochopil vůbec účel, ani cenu, ani další aspekty různých databází.

    Bylo by určitě fajn, kdyby všude byl Oracle a jeho možnosti. Ale už z důvodu ceny a také z důvodů dalších tomu není, a asi nikdy nebude. Oracle je jedna z databází velkého stylu, a pro 90% databázových aplikací kanón na vrabce.

    MySQL se prostě rozšířila. Je to takové výrazně lepší pokračování DBF formátu. Že nemá všechny možnosti Oracle, nebo PostgreSQL? To je přeci samozřejmé a nikdo netvrdí opak. MySQL je určená jako nenáročná databáze pro mnoho platforem pro aplikace malé složitosti.

    Osobně mi MySQL nevadí, protože vím, kde je její místo, a kde je její síla, a kde slabiny. Proto by mě ani ve skrytu duše nenapadlo srovnávat možnosti MySQL s Oracle.

    Možnosti MySQL nejsou zase tak malé, pokud vám stačí jednoduché datové modely, což velmi často stačí, tak MySQL zvládne velmi rychlou práci nad milióny řádky, a mnohdy od malé databáze víc nepotřebujete.

    MySQL svoje místo jako databáze rozhodně má. Už díky svojí rozšířenosti. Jako malý telefonní seznam pro Windows/Linux na jedno CD s aplikací spouštěnou s CD je MySQL bezkonkurenční. Na rychlé logování, třídění jednoduchých dat ideální.

    Každá databáze má svůj účel. Na něco jiného je Oracle, na něco jiného je MySQL.

  8. 8 gt-x 28.06.04, 11:06:14
    FB

    verim ze v buducich verziach MySQL autorom spomenute problemy budu fixnute. prosim autora clanku, aby ich poslal do BUG-report/FEATURE-request ;)

  9. 9 spaceboy 02.07.04, 03:07:07
    FB

    K tomu prvnímu příkladu: Opravdu si myslíš, že se to dá řešit jedině subselektem? Co třeba konstrukce jako SELECT t1.col1 FROM tab1 as t1 INNER JOIN tab2 as t2 ON max(t2.time) = t1.time ? Tenhle postup je mimochodem doporučován jako mnohem čistší než vnořené selekty (a kdo měl někdy co do činění s opravdu většími databázemi, ví, že vnořený select je skoro to nejhorší zlo, co existuje)...

  10. 10 Arcao 03.07.04, 12:07:27
    FB

    [7] mno nevim, ale na ten telefoni seznam bych mozna radeji pouzil SQLite.

  11. 11 mIREK 25.08.04, 01:08:53
    FB

    [7][9] Mám podobný názor... Kydání nepodložených nebo špatně porovnatelných údajů na mySQL, o ničem jiném tento článek není... Pokud potřebujete jenom jednoduché selekty a potřebujete jich hodně, není nad mySQL. Pokud už chcete databází data nějak zpracovávat není nad jiné DB viz třeba Postgre nebo Oracle...
    Pokud jde o komerční věci, je potřeba se zamyslet nad tím, zda-li je třeba kupovat licenci nebo použít OpenSource...
    Finanční politika zde není vůbec zohledněna... Dostupnost zde také byla zmíněna v komentářích... Budeme stavět vlastní server a nebo využijeme hosting, kde krom mySQL bývá jiná db vyjímkou...
    Radek chce být agresivní, občas se mi to líbí, s mnoha věcmi bych i souhlasil, ale občas ne...

  12. 12 Aldik 16.09.04, 07:09:48
    FB

    nic proti autorovi ,ma celkem pravdu,ale proboha co je tohle za konstrukci

    SELECT name, title, url FROM article
    WHERE time=(SELECT max(time)
    FROM article)

    to je nesmyslnej vnorenej select

    co spis tohle

    SELECT max(time),name, title, url FROM article
    group by name,title,url

    vnorene selecty se maji obecne pouzivat minimalne...
    i v masivnich databazich typu MSSQL nebo Oracle
    FROM article)

  13. 13 KOCHI 17.09.04, 09:09:54
    FB

    Mýtus rychlosti MySQL
    SELECT name, title, url FROM article order by time desc limit 1;

    Mýtus dobré funkcnosti MySQL
    a nebudete muset ve vsech dotazech zmenit nazev tabulky na pohled? article -> article_current?

    Moznost Triggeru je u Oracle jiste lepsi.

    Mýtus použitelnosti MySQL
    transakce MySQL podporuje, akorat o nich lidi moc nevi, protoze jsou defaultne vypnute :o(

    Rozdil mezi MySQL a textovym souborem jiste je.. ;o) nikdy to nenapisete tak, jako je to alespon v MySQL. klice, uniqe, ruzne varchary, set, enum atd... se z toho po...

    Co jsem se docetl, tak referencni integritu si muzete zajistit, pokud pouzijete typ tabulky InnoDB, vytvorite par indexu a provazete.

    KOCHI

    PS: PL/SQL mi rika pane a presto na to, co delam MySQL bohate dostacuje. Problem neni v databazich, ale v managerech, kteri nevi co chteji a porad se musi neco dobastlovavat a pridelavat, mazat...

  14. 14 Václav Macůrek 08.10.10, 11:10:45
    FB

    [9]
    Komentáře k tomuto článku jsou zcela evidentně velmi staré - šest let. Za tu dobu se MySQL nepochybně zlepšila, což ale nemohu posoudit, protože jsem se k programování v PHP dostal až v dubnu 2007, tedy před více než třemi roky - a tak nemohu důvěryhodně srovnávat s stavem z roku 2004.

    Ale musím říct, že dotaz s poddotazem uvedený v článku tj. "SELECT name, title, url FROM article WHERE time=(SELECT max(time) FROM article)" v verzi 5.0.51b funguje. Zkusil jsem to sice s jinými sloupci (řídící sloupec však čas - tedy stejně jako v vzorovém dotazu) a na jiné tabulce - ale funguje.

    Rozhodně však musím souhlasit, že je ten dotaz poněkud postavený na hlavu - a dotaz "SELECT max(time),name, title, url FROM article group by name,title,url" je opravdu snesitelnější.

  15. 15 Martin Bárta 05.06.12, 10:06:20
    FB

    MySQL pro malé a nenáročné aplikace? Ano, v základu možná, ale s pár úpravami není problém, aby na tom běželi obří databáze s mnoha requesty za sekundu.