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

Letmý pohled na Alfu MySQL 5.0 z pohledu postgresisty

Jak název napovídá, podíváme se, co nového přináší Alfa verze MySQL 5.0 nejen v porovnání se staršími verzemi, ale i s konkurenční databází PosgreSQL. Článek je krom teorie pln i zajímavých příkladů.

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

Před několika lety, když jsem si začínal hrát s SQL, byla MySQL první nainstalovanou SQL databází na mém počítači. A také první odinstalovanou. SQL jsem rozuměl jak koza petrželi a v MySQL mi nešly přepsat SQL příkazy z moudrých knížek, které jsem tehdy měl po ruce. Zkusil jsem PostgreSQL tehdy ve verzi 6.x a zůstal u ní. Všechny konstrukce, o kterých se tehdy psalo, zvládala. Navíc jsem si mohl poprvé vyzkoušet uložené procedury, které měly po zkušenostech okolí s MSSQL 6.x chuť zakázaného ovoce. Prostě nostalgicky na to vzpomínám. V prosinci MySQL AB ohlásili 5.0 Alfu, která by měla zvládat jak složitější SQL dotazy, tak uložené procedury, a já se nemohl dočkat, až si ji u sebe vyzkouším. Následující text si nehraje na důkladnou analýzu, obsahuje vlastně jen pár postřehů.

Instalace je na mém RH9 vcelku bezproblémová. Jediným drobným zádrhelem bylo, že uživatel mysql neměl přístupová práva do /usr/local/var, což dokumentace tiše předpokládá. Defaultní umístění databází je jiné než v Pg. Pro každou databázi se v /usr/local/var vytváří podadresář, soubory podpory InnoDB tabulek se vytvářejí také v tomto adresáři (pokud nezměníte konfiguraci).

cd zdroj
make
make install
do /etc/ld.so.conf pridat /usr/local/lib/mysql
ldconfig
cp zdroj/support-files/mysql.server /etc/init.d/mysql
chmod +x /etc/init.d/mysql
cp zdroj/support-files/mysql.conf /etc/my.cnf
mysql_install_db
mysqladmin -u root password 'newpass'
groupadd mysql
useradd -g mysql mysql
chown -R mysql /usr/local/var/mysql
chgrp -R mysql /usr/local/var/mysql
chmod o+rwx /usr/local/var
/etc/init.d/mysql start
mysqladmin create testdb
mysql testdb

MySQL verze 5.x umí prakticky vše, co zhýralý programátor čeká od databáze: uložené procedury, dotazy parametrizovatelné uživatelskými (session) proměnnými, vnořené dotazy, CASE, regulární výrazy. Sice se sem tam najde drobná vada na kráse, ale tváří se to hezky a na alfu i celkem použitelně. Některé konstrukce bych rád viděl i v PostgreSQL (v pohodlí práce s příkazovou řádkou má stále databáze s delfínkem co dohánět). Příkazy konzole jsou jen o trochu jiné. Pro mne jediným zásadním rozdílem je \. – provedení příkazů ze souborů.

SELECT @i:=3;
SELECT * FROM zamestnanci WHERE id=@i;

nebo jinak (číslování řádků)

SELECT @x:=0;
SELECT @x:=@x+1, zamestnanci.* FROM zamestnanci;

PostgreSQL něco podobného umí, ale pouze na úrovni psql, ne jako sql příkazy, takže parametrizaci nemůžeme použít ve svých aplikacích. Navíc nezvládne výrazy. Příkaz set nemůže být součástí sql výrazu. Zvládne na druhou stranu příkazy shellu (funkcionalita psql se pravděpodobně rozšíří o cykly a podmínky – stále se ale bude jednat o řešení na úrovni psql).

\set txt `links -dump  /clanek/1987`|sed "s/'/''/g"`
\set txt '\'':txt'\''
INSERT INTO texty VALUES(:txt); 

Vnořené dotazy: MySQL zvládla všechno, co mne napadlo. Sledoval jsem pouze schopnost provést dotaz, nikoliv už efektivitu provádění dotazu. Pohledy ještě tato alfa nepodporuje (v ToDo pro 5.0).

SELECT nazev, prijmeni FROM oddeleni, zamestnanci
  WHERE zamestnanci.odd = oddeleni.id AND
    zamestnanci.mzda =
      (SELECT max(mzda) FROM zamestnanci WHERE odd = oddeleni.id);

SELECT (SELECT 1) FROM (SELECT * FROM zamestnanci) z; 

Dokumentace k uloženým procedurám existuje, najdeme ji na www.mysql.com/doc/en/­Stored_Procedu­res.html. Potřebovala by HODNĚ doplnit. Oproti PostgreSQL zvládá nejen funkce, ale i procedury s INOUT parametry (PostgreSQL podporuje pouze IN, které nezvládá MySQL :-)). Naopak nemůže psát SRF funkce a zatím ani triggery. Chybí také možnost dynamicky vykonávat sql dotazy, vyvolat chyby, jakákoliv rozumná možnost trasování (lze plnit globální proměnné). Ve funkcích není dovoleno (je omezeno) používání SQL příkazů. Ostatní jsou víceméně nuance, tj. tam, kde PostgreSQL má vzor Oracle, mysql DB2 (SQL2003 syntaxe pro uložené procedury). Množiny jsou přístupné pouze pomocí kurzorů. Nicméně i s těmito funkcemi se dají dělat věci. Občas ještě ne úplně všechno zafunguje.

DROP PROCEDURE foo;
DELIMITER ~;

CREATE PROCEDURE foo(OUT param VARCHAR(1000))
BEGIN
  DECLARE c CURSOR FOR SELECT prijmeni FROM zamestnanci;
  DECLARE done int DEFAULT 0;
  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
  DECLARE a VARCHAR(1000) DEFAULT '';
  DECLARE p VARCHAR(100);
  OPEN c;
  REPEAT
    FETCH c INTO p;
    IF NOT done THEN
      IF a = '' THEN
        SET a = p;
      ELSE
        SET a = CONCAT(a, ', ', p);
      END IF;
    END IF;
  UNTIL done END REPEAT;
  CLOSE c;
  SET param = a;
END; ~
DELIMITER ;~

CALL foo(@a);
SELECT @a; --> Kresl, Bidlák, Stehule

DROP FUNCTION foof;
DELIMITER ~;

CREATE FUNCTION foof() RETURNS VARCHAR(1000)
BEGIN
  DECLARE c CURSOR FOR SELECT prijmeni FROM zamestnanci;
  DECLARE done int DEFAULT 0;
  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
  DECLARE a VARCHAR(1000) DEFAULT '';
  DECLARE p VARCHAR(100);
  OPEN c;
  SET @b = '';
  REPEAT
    FETCH c INTO p;
    IF NOT done THEN
      SET @b = CONCAT(@b, ' ', p);
      IF a = '' THEN
        SET a = p;
      ELSE
        SET a = CONCAT(a, ', ', p);
      END IF;
    END IF;
  UNTIL done END REPEAT;
  CLOSE c;
  SET @b = a;
  RETURN a;
END; ~
DELIMITER ;~

SELECT foof();  --> Stehule ????
SELECT @b;      --> Kresl, Bidlák, Stehule 

totéž v PL/pgSQL

CREATE OR REPLACE function foo() RETURNS varchar AS '
DECLARE a varchar = ''''; p varchar;
BEGIN
  FOR p IN SELECT prijmeni FROM zamestnanci LOOP
    IF a <> '''' THEN
      a := a ||'',''||p
    ELSE
      a := p;
    END IF;
    RAISE NOTICE ''a = %'', a;
  END LOOP;
  RETURN a;
END; 'LANGUAGE plpgsql; 

Obsahuje obsluhu chyb (to PostgreSQL chybí), ve výše zmíněném příkladu se bez ní ani neobejde.

  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1; 

Při chybě 02000, tj. nenalezen záznam, se lokální proměnné nastaví na hodnotu 1 (následně se ukončí cyklus).

Dočasné tabulky vytvářené v uložené proceduře mají pouze session platnost (stejně jako v PostgreSQL). To mírně komplikuje procedury, které si vytvářejí vlastní dočasné tabulky – například pro uložení mezivýsledků, atd Nejedná se ovšem o žádný těžký problém, stačí ošetřit na začátku SP chybový stav (něco podobného v PostgreSQL v tuto chvíli nejde, resp. musíme si zjistit, zdali tabulka náhodou už neexistuje, a potom ji případně nevytvářet – příklad kódu).

DROP PROCEDURE tmpfoo;
DELIMITER ~;
CREATE PROCEDURE tmpfoo()
BEGIN
  DECLARE existuje int DEFAULT 0;
  -- ERROR 1050 (42S01): Table already exists
  DECLARE CONTINUE HANDLER FOR SQLSTATE '42S01' SET existuje=1;
  CREATE TEMPORARY TABLE aaa(x integer);
  IF existuje = 1 THEN
    DELETE FROM aaa;
  END IF;
  INSERT INTO aaa VALUES(10);
  SELECT COUNT(*) INTO @b FROM aaa;
  DROP TABLE aaa;
END; ~ 

Uložené procedury v MySQL nemají žádný problém s dočasnými tabulkami jako v PostgreSQL, kde k dočasným tabulkám můžeme přistupovat pouze prostřednictvím dynamických dotazů. PostgreSQL boužel nedokáže dynamicky překompilovat uložené procedury podle potřeby – v okamžiku, kdy je neplatné id dočasné tabulky.

CREATE OR REPLACE FUNCTION tmpfoo() RETURNS bool AS '
DECLARE pocet integer; rec RECORD;
BEGIN
  PERFORM 1 FROM pg_catalog.pg_class c
    WHERE c.relname=''aaa'' AND pg_catalog.pg_table_is_visible(c.oid)
     AND c.relkind=''r'';
  IF NOT FOUND THEN
    CREATE TEMPORARY TABLE aaa(x integer);
  ELSE
    EXECUTE ''DELETE FROM aaa'';
  END IF;
  EXECUTE ''INSERT INTO aaa VALUES(10)'';
  FOR rec IN EXECUTE ''SELECT COUNT(*) AS c FROM aaa'' LOOP
    pocet := rec.c;
  END LOOP;
  RAISE NOTICE ''V tabulce bylo % zaznamu'', pocet;
  EXECUTE ''DROP TABLE aaa'';
  RETURN ''t'';
END; ' LANGUAGE plpgsql; 

Procedury chodily tak, jak měly, volání funkce vracelo nesmysly. Netuším, zdali to bylo nedovoleným použitím SELECTu ve funkci, nebo něčím jiným.

davame_internetu_obsah
       

Jen tak nevážně jsem si vyzkoušel rychlost interpretace (jedná se přeci jen o Alfu a uložené procedury dlouhou dobu byly pro MySQL AB na okraji zájmu). Na jednoduchém příkládku hledání největšího společného dělitele se ukazuje (zatím), že interpret MySQL je zhruba dvacetkrát pomalejší než interpret PL/pgSQL. Je mi ale jasné, že rychlost interpretu není všechno, zvlášť ne při programování uložených procedur.

DROP FUNCTION delitel;
DELIMITER ~;

CREATE FUNCTION delitel(a int, b int) RETURNS int
BEGIN
  WHILE a <> b DO
    IF a > b THEN SET a = a - b; ELSE SET b = b - a; END IF;
  END WHILE;
  RETURN a;
END; ~
DELIMITER ;~

SELECT delitel(263535344, 868); --> cca 10 sec oproti 460 milisec PostgreSQL
SELECT delitel(263535344, 868);
SELECT delitel(263535344, 868);
SELECT delitel(263535344, 868); 

Chování a vlastnosti MySQL na mě celkem udělaly dojem i přes několik nesporných chyb (referenční integrita, ačkoliv mám locales nastaveno správně – def. charset mám švédštinu). Zřetelně je znát, že vývojáři MySQL si jdou svou vlastní cestou, kdy jejich cílem zůstává malá a rychlá SQL databáze, přednost má funkcionalita a jednoduchost před „stylovou čistotou“ (např. umožnění přístupu do cizích databází bez podpory dvoufázového potvrzování). A inspiraci hledají jak u IBM (syntaxe uložených procedur), tak u Oracle (budoucí syntaxe rekurzivních dotazů).

Pavel Stěhule

Pavel Stěhule

Pavel Stěhule je odborníkem na relační databázový systém PostgreSQL, který v současnosti pracuje jako vývojář ve společnosti GoodData.

Školení: Linux – Firewall, Samba, VPN

Na třídenním školení se naučíte nainstalovat a spravovat Firewall a Router, SAMBA Doménový a Souborový server. Dále si zprovozníte vlastní, zabezpečený VPN server.

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

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

Přehled názorů

Migracie
Nepto 29. 1. 2004 07:06
Nový
└ 
Re: Migracie
Dusan 29. 1. 2004 11:31
Nový
 
├ 
Re: Migracie
xyz 29. 1. 2004 14:15
Nový
 
└ 
Re: Migracie
martin 29. 1. 2004 14:29
Nový
 
 
├ 
Re: Migracie
Jan Havrda 29. 1. 2004 16:48
Nový
 
 
│
└ 
Re: Migracie
Michal Kara 29. 1. 2004 17:02
Nový
 
 
│
 
└ 
Re: záloha zaživa
Michal Kubeček 29. 1. 2004 23:07
Nový
 
 
│
 
 
└ 
Re: záloha zaživa
Michal Kara 30. 1. 2004 09:25
Nový
 
 
├ 
Re: Migracie
Milda 29. 1. 2004 17:03
Nový
 
 
│
└ 
Re: Migracie
Milda 29. 1. 2004 17:06
Nový
 
 
└ 
Re: Migracie
anonym 1. 2. 2004 15:03
Nový
mysql
Lampa 29. 1. 2004 08:37
Nový
└ 
Re: mysql
Pavel 29. 1. 2004 09:28
Nový
PGSQL a SET
Jiri Chaloupka 29. 1. 2004 10:09
Nový
└ 
Re: PGSQL a SET
Pavel 29. 1. 2004 11:01
Nový
PostgreSQL
PaJaSoft 29. 1. 2004 10:10
Nový
├ 
Re: PostgreSQL
Pavel 29. 1. 2004 10:53
Nový
│
└ 
Re: Doplňování
Yeti 29. 1. 2004 11:20
Nový
│
 
└ 
Re: Doplňování
Pavel 29. 1. 2004 11:26
Nový
└ 
Re: PostgreSQL
Jerry III 29. 1. 2004 20:47
Nový
bezpecnost ?
anonymní uživatel 29. 1. 2004 10:57
Nový
Postgres na Win32
MeX 29. 1. 2004 12:08
Nový
└ 
Re: Postgres na Win32
Pavel 29. 1. 2004 12:24
Nový
 
└ 
Re: Postgres na Win32
agent 29. 1. 2004 13:03
Nový
 
 
├ 
Re: Postgres na Win32
Pichi 29. 1. 2004 13:40
Nový
 
 
│
└ 
Re: Postgres na Win32
Pichi 29. 1. 2004 13:41
Nový
 
 
└ 
Re: Postgres na Win32
Michal Kubeček 30. 1. 2004 11:40
Nový
Pokrok
Karel Zak 29. 1. 2004 13:47
Nový
└ 
Re: Pokrok
Jerry 29. 1. 2004 20:35
Nový
 
└ 
Re: Pokrok
Jozef Hribik 30. 1. 2004 08:17
Nový
 
 
└ 
Re: Pokrok
Jerry 30. 1. 2004 11:58
Nový
Mala noticka
Behemoth 29. 1. 2004 15:17
Nový
└ 
Re: Mala noticka
Pavel 29. 1. 2004 17:15
Nový
 
└ 
Re: Mala noticka
Tomas 30. 1. 2004 09:55
Nový
 
 
└ 
Re: Mala noticka
Behemoth 30. 1. 2004 11:48
Nový
replikace
hanz 29. 1. 2004 21:01
Nový
└ 
Re: replikace
Pavel 30. 1. 2004 07:21
Nový
obavam se, ze se ritime do slepe ulicky
Johann 30. 1. 2004 01:20
Nový
├ 
Re: obavam se, ze se ritime do slepe ulicky
Pavel 30. 1. 2004 07:55
Nový
│
├ 
Re: obavam se, ze se ritime do slepe ulicky
Karel Zak 30. 1. 2004 09:35
Nový
│
└ 
Re: obavam se, ze se ritime do slepe ulicky
Johann 31. 1. 2004 00:57
Nový
│
 
└ 
Re: obavam se, ze se ritime do slepe ulicky
anonymní uživatel 31. 1. 2004 18:31
Nový
├ 
Re: obavam se, ze se ritime do slepe ulicky
Michal Kubeček 30. 1. 2004 11:38
Nový
│
└ 
Re: obavam se, ze se ritime do slepe ulicky
Johann 30. 1. 2004 12:16
Nový
│
 
├ 
Re: obavam se, ze se ritime do slepe ulicky
Michal Kubeček 30. 1. 2004 12:38
Nový
│
 
│
└ 
Re: obavam se, ze se ritime do slepe ulicky
Karel Zak 2. 2. 2004 11:48
Nový
│
 
├ 
Re: obavam se, ze se ritime do slepe ulicky
Jerry III 30. 1. 2004 22:22
Nový
│
 
│
└ 
Re: obavam se, ze se ritime do slepe ulicky
Johann 31. 1. 2004 00:30
Nový
│
 
│
 
├ 
Re: obavam se, ze se ritime do slepe ulicky
Q 31. 1. 2004 02:17
Nový
│
 
│
 
└ 
Re: obavam se, ze se ritime do slepe ulicky
Jerry III 31. 1. 2004 08:41
Nový
│
 
└ 
Re: obavam se, ze se ritime do slepe ulicky
anonymní uživatel 31. 1. 2004 18:43
Nový
│
 
 
└ 
Re: obavam se, ze se ritime do slepe ulicky
Johann 31. 1. 2004 22:34
Nový
│
 
 
 
└ 
Re: obavam se, ze se ritime do slepe ulicky
Pavel 2. 2. 2004 12:01
Nový
└ 
Re: obavam se, ze se ritime do slepe ulicky
Vita 2. 2. 2004 19:31
Nový
 
└ 
Re: obavam se, ze se ritime do slepe ulicky
vladimir 4. 2. 2004 16:59
Nový
MaxDB (SAP DB) a MySQL 5
PSIkappa 30. 1. 2004 12:14
Nový
├ 
Re: MaxDB (SAP DB) a MySQL 5
agent 30. 1. 2004 17:40
Nový
└ 
Re: MaxDB (SAP DB) a MySQL 5
inf 21. 11. 2005 03:17
Nový
budoucnost mysql ??
Pavel Kysilka 1. 2. 2004 03:25
Nový
└ 
Re: budoucnost mysql ??
Vita 2. 2. 2004 19:43
Nový
 
└ 
Re: budoucnost mysql ??
Pavel Kysilka 8. 2. 2004 00:02
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