Nikdy nevíš, kdy to přijde
Zobrazit menu   MENU

9. Spojování více tabulek - základy

Spojování tabulek je něco s čím se v práci s databází setkáme velmi často. Jde o poměrně rozsáhlé téma, které si zde rozdělíme do dvou tutoriálových článků.

Zatím jsme zde pracovali pouze s jednou tabulkou u níž byla logika jasná. Ve skutečných databázích to většinou tak prosté není a tabulku na sebe mají různé vazby, které mohou být i značně komplikované. Proto se často využívá znázornění této logiky vazeb pomocí nějakého diagramu.


Diagram pro novou databázi.
Diagram pro novou databázi.


V našem diagramu vidíme, že budeme pracovat s těmito entitami: kniha ; autor ; hodnocení ; vydání knihy. Máme tedy 4 entity, to ale neznamená, že v naší databázi budou právě 4 tabulky. Ve skutečnosti často potřebujeme spojovací tabulky, které sami nereflektují žádnou fyzickou entity, ale pro správný vztah mezi daty jsou nutné.


Vztahy entit

Vztahy neboli vazby mezi entitami určují, kolik entit typu A se může vztahovat k entitě typu B. Tyto vztahy mohou být různé a při návrhu databáze je zcela nutné si je dopředu ujasnit.

1:N

Podívejme se v našem příkladu na Knihu a Vydání knihy. Zde je vazba 1:N, to znamená, že k 1 knize (1 řádek tabulky) může náležet N (různý, neznámý počet) vydání knihy. Ale k jednomu vydání musí náležet jenom jedna kniha. Což odráží skutečnost, kniha skutečně může mít více vydání. Ale jedno konkrétní vydání knihy nemůže náležet k několik různým knihám.

Obecně může N být i nulou - tedy v druhé tabulce nemusí být žádný odpovídající záznam (pak můžeme vztah označovat jako 1:0..N). V našem příkladě by to ale smysl nedávalo, kniha vždy vydání mít musí, mohli bychom tedy použít označení 1:1..N.

1:1

Tento vztah znamená, že k jednom řádku tabulky A náleží právě jeden řádek tabulky B. Takový vztah obecně v databázi není vhodný a většinou postrádá smysl rozdělovat tabulku na dvě, protože data 1:1 mohou být rovnou uložena v tabulce jedné.

N:M

Jde o druh vztahu, kdy jenom záznamu z A může náležet různý počet z B a naopak. V takovém případě musíme využít novou spojovací tabulku. V našem případě jde o vztah Kniha - Autor. Jedna kniha může mít různý počet autorů a zároveň jeden autor může napsat různý počet knih.

Potřebujeme tedy spojovací tabulku knihy_autori kde každý řádek bude mút uloženou informaci o knize a jejím autorovi. Bude tedy vždy obsahovat "odkaz" do tabulky knihy a tabulky autori.


Vytvoření tabulek

Dost bylo teorie, pojďme zpátky k databázi a tabulkám. Nejdříve bude opět nutné smazat předchozí tabulku knihy, vytvořit novou sadu tabulek: knihy, autori, knihy_autori, hodnoceni, vydani_knihy a naplnit je daty. Kód pro tyto akce by byl příliš dlouhý na zobrazení v článku, proto si můžete stáhnout sql soubor na odkazu níže a spustit ho ve vaší databázi.

Tutoriál spojování

Stáhnout soubor


Dotazy nad více tabulkami

Nyn si můžeme vyzkoušet spojení dvou tabulek. V našem případě to bude vypsání všech knih a jejich vydání. Informace o knihách máme uložené v tabulce knihy a vydání v vydani_knihy. Abychom mohli tabulky spojit, musí obě tabulky mít sloupec, přes který se spojení provede - který bude obsahovat odpovídající hodnotu z druhé tabulky.

V našem případě je to v tabulce knihy sloupec kniha_id a v tabulce vydani_knihy stejně pojmenovaný kniha_id. Je kvůli přehlednosti je vhodné zachovávat stejná jména sloupců, které si logicky odpovídají a slouží ke spojování.

SELECT knihy.nazev, vydani_knihy.rok, vydani_knihy.isbn, vydani_knihy.pocet_stran
FROM `knihy` JOIN `vydani_knihy` ON knihy.kniha_id = vydani_knihy.kniha_id;


V dotazu je nutné specifikovat názvy sloupců i tabulek. Není vhodné použít zástupný znak *, protože je pravděpodobné, že obě tabulky budou mít sloupec se stejným názevm, v takovém případě MySQL vrátí chybu, protože neví, z jaké tabulky sloupec použít a dva se stejným názvem být nemohou. Pokud bychom přesto chtěli využít zástupný znak (protože třeba z druhé tabulky nenačítáme vůbec žádná data), zapsali bychom ho jako tabulka.*.

Po výčtu sloupců následuje FROM a zadání tabulky a pak nové klíčové slovo JOIN, za kterým následuje název tabulky kterou budeme napojovat. Následuje další klíčové slovo ON, za kterým uvedeme na základě rovnosti kterých sloupců z obou tabulek ma být spojení vytvořeno. Výsledek v naší knižní databázi:

+------------------+------+-------------------+-------------+
| nazev            | rok  | isbn              | pocet_stran |
+------------------+------+-------------------+-------------+
| Duna             | 2016 | 978-80-269-0517-2 |         592 |
| Duna             | 2014 | 978-80-269-0063-4 |         639 |
| Duna             | 1988 | 80-205-0001-4     |         586 |
| Malý princ       | 2018 | 978-80-7549-803-8 |         112 |
| Malý princ       | 2017 | 978-80-00-04733-1 |          79 |
| Záskok           | 2005 | 80-7185-290-2     |          85 |
| Svět ledu a ohně | 2015 | 978-80-7197-550-2 |         336 |
+------------------+------+-------------------+-------------+

Pokud v některé z tabulek budou řádky, které nemají v daném sloupci odpovídající hodnotu v druhé tabulce, nebou vy výsledku zahrnuty. Později si povíme, jak zahrnout i tyto vynechané řádky.

Spojení bez JOIN

Existuje ještě jiná varianta zápisu bez klíčové slova JOIN. Ja osobně ji využívám raději, protože mi připadá přehlednější. Místo uvádění JOIN vypíšeme všechny tabulky, které budeme spojovat oddělené čárkou. Samotné spojení pak popíšeme v klauzuli WHERE:

SELECT knihy.nazev, vydani_knihy.rok, vydani_knihy.isbn, vydani_knihy.pocet_stran
FROM `knihy`, `vydani_knihy`
WHERE knihy.kniha_id = vydani_knihy.kniha_id;

Výsledek pak bude totožný jako v předchozím případě.


Ukázali jsme si základní spojení dvou tabulek, tzn. INNER JOIN. V přístím díle budeme pokračovat dalšími variantami spojování které MySQL nabízí a ukážeme si i spojení více než jen dvou tabulek.


Další díly tutoriálu

7. Základy vyhledávání
8. Pokročilé podmínky výběru
9. Spojování více tabulek - základy
10. Spojování více tabulek - pokročilé
11. Agregační funkce