![]() |
![]() |
Spojení relací
Na vojně se vždycky říkávalo - bez spojení není velení. Ve světě databází bychom mohli říkat, že bez spojení není relační databáze. Je to pravda. Listování v jednotlivých tabulkách je sice někdy užitečné, ale rozumná síla relačních jazyků se začne projevovat až od možností spojování relací. Připomeňme si opět schémata relací FILM(JMÉNO_F, REŽISÉR), popisující data o filmech a jejich režisérech, a PŘEDSTAVENÍ(NÁZEV_K, JMÉNO_F), pro data o kinech hrajících filmy. Coddova relační algebra nabízí operaci přirozené spojení, značí se tradičně * , která, aplikována na dané relace vytvoří relaci se schématem NÁZEV_K, JMÉNO_F, REŽISÉR. Řádky této nové relace, řekněme T, vzniknou spojením řádků aktuální relace FILM s řádky aktuální relace PŘEDSTAVENÍ přes společné hodnoty atributu JMÉNO_F (viz obr. 1). FILM JMÉNO_F REŽISÉR PŘEDSTAVENÍ NÁZEV_K JMÉNO_F Karla Máša Práce Karla Matka Mencl Práce Babička Babička Průcha Mír Babička Obr. 1 Relace FILM a PŘEDSTAVENÍ Relace T daná výrazem FILM * PŘEDSTAVENÍ je na obrázku 2. T NÁZEV_K JMÉNO_F REŽISÉR Práce Karla Máša Práce Babička Průcha Mír Babička Průcha Obr. 2 Výsledek spojení Princip je zřejmý. Spojuje se, co lze. Např. dvojice (Matka, Mencl) se spojení neúčastní, protože film Matka zrovna nikde nedávají. Tento typ spojení se nazývá přirozené proto, že spojuje přes množinu atributů, které se vyskytují v obou relacích. Zde šlo o jediný atribut - JMÉNO_F. Vedle tohoto spojení obsahuje relační algebra další užitečná spojení, jako je = - spojení, £ - spojení apod., tj. spojení přes podmínku. V nich se ovšem musí říci, pro které atributy se spojovací podmínka daná porovnávacím operátorem v názvu spojení uplatní. Formálně můžeme taková spojení označovat např. R [ A£ B] S, existují-li třeba relace R(B,A), S(A,G,H). Výsledkem je ovšem relace, kde se atribut A vyskytuje dvakrát, narozdíl od přirozeného spojení, kde se jeden ze společných atributů eliminoval. Dva výskyty atributu však podle definice relačního databázového modelu nejsou povoleny, takže bychom si ještě museli vypomoci přejmenováním atributů ve výsledku. Jak se ke spojení relací staví SQL? Pozor, je třeba si uvědomit, které SQL. Tak nejprve klasické SQL89, tj. standard z roku 1989. Přirozené spojení v něm nemá odpovídající konstrukt. Je nutné si vypomoci = - spojením a vhodnou projekcí atributů do výsledku. Dotaz pro získání relace T na obrázku 2 by se musel zapsat např. následovně: SELECT PŘEDSTAVENÍ * , FILM.REŽISÉR FROM FILM, PŘEDSTAVENÍ WHERE FILM.JMÉNO_F = PŘEDSTAVENÍ.JMÉNO_F; Tímto způsobem lze zapsat i vícenásobné spojení, kdy se spojují obecně více než 2 relace. Čím více relací, tím více spojovacích podmínek za WHERE. SQL92, tj. standard z roku 1992, nabízí uživateli jazyka SQL, co se spojení týče, mnohem větší možnosti. Patří sem vedle již uvedené možnosti “starého stylu”:
Přirozené spojení FILM * PŘEDSTAVENÍ se v SQL92 zapíše takto: SELECT * FROM FILM NATURAL JOIN PŘEDSTAVENÍ; Spojení křížem je pouze syntaktické rozšíření možnosti vytvořit kartézský součin dvou relací ve starém SQL. Toho se dalo docílit pro relace R a S takto: SELECT * FROM R, S; V SQL92 je možné použít explicitní pojmenování tohoto druhu spojení (kartézský součin se chápe jako případ, kdy se spojuje každý řádek z R s každým z S), tj. SELECT * FROM R CROSS JOIN S; Spojení přes podmínku je opět modifikací výraziva starého SQL, kdy se za WHERE dalo zapsat přes co se spojuje. Po vzoru předchozích nových konstruktů, podmínka se stěhuje za FROM s oddělovačem ON. Spojení R [ A£ B] S pak má v SQL tvar SELECT * FROM R JOIN S ON A£ B; Zdůrazněme, že takových spojení lze za FROM napsat více, přičemž za WHERE lze psát další podmínky týkající se všech atributů, které tvoří relaci vzniklou spojením. Zdá se, že tendence je oddělit pro uživatele fázi spojení a fázi selekce. Tyto fáze nebyly v původním SQL rozlišovány - vše vymezující data jdoucí na výstup se objevovalo za WHERE. Připomeňme však, že skutečné vyhodnocení takových dotazů je samozřejmě optimalizováno, tj. není pravda, že by se obecně dělalo spojení dříve než selekce za WHERE. Spojení přes vyjmenované sloupce rozšiřuje možnosti přirozeného spojení. Uvažujme relace U(X, Z, Y, P) a V(Z,Y,P,Q). Přirozeným spojením bychom spojovali přes všechny společné atributy, tj. Z,Y,P. Je-li požadavkem spojení pouze přes Z a Y, pak v SQL92 můžeme psát SELECT * FROM U JOIN V USING (Z, Y); Uvedená spojení se nazývají vnitřní spojení (inner join). Dokonce lze i psát INNER NATURAL JOIN nebo INNER JOIN. Označení se zavádí proto, aby by se systematicky tato spojení odlišila o vnějších spojení (outer joins). Tato spojení slouží k přidávání některých řádků, které se s ničím nespojily, do výsledku. Zbývající atributy v takových řádcích mají přiřazenu prázdnou hodnotu NULL. Spojovat lze opět přirozeně nebo s ON. Podle označení LEFT, RIGHT a FULL se přidává z levého, resp. pravého, resp. z obou operandů spojení. Napíšeme-li tedy SELECT * FROM PŘEDSTAVENÍ NATURAL RIGHT OUTER JOIN FILM; obdržíme tabulku T NÁZEV_K JMÉNO_F REŽISÉR Práce Karla Máša Práce Babička Průcha Mír Babička Průcha NULL Matka Mencl Obr. 3 Výsledek levého vnějšího spojení Opět lze za FROM psát více vnějších spojení. Ovšem pozor! Vnější spojení je nebezpečné, protože není asociativní, tj. dvě různá pořadí několika takto spojovaných tabulek může vést k různým výsledkům. Posledním typem spojení je spojení sjednocením (union join). Připomíná FULL OUTER JOIN až na to, že se v něm nespojí žádné řádky. Každý řádek z levého, resp. pravého operandu je ve výsledku doplněn zprava, resp. zleva hodnotou NULL. Zápis v SQL92 je SELECT * FROM U UNION JOIN V; Řada čtenářů, uživatelů různých SQL serverů, rozpozná, že některá spojení zná. Např. OUTER JOIN se v některých relačních SŘBD vyskytuje. Bohužel ale s jinou syntaxí. Zdá se, že někdy zbytečný spěch ve vývoji může znamenat krok zpátky, anebo alespoň stranou. Takových příkladů ovšem SQL92 (a již známá koncepce zvaná zatím SQL3) poskytuje mnoho.
<seznam dílů seriálu> <COMPUTERWORLD> |