Proč jsou data v několika tabulkách
Zatím každý dotaz četl jedinou tabulku. Odpověď na běžnou otázku o obchodě je ale často rozložená do několika tabulek. Kdo zadal objednávku 4? Tabulka objednavky zná jen ID zákazníka. A co v ní bylo? To je v tabulce polozky, a zase jen jako ID her. Proč databáze ukládá věci takhle odděleně, když se na ně pak hůř ptá?
Představte si, že by obchod měl všechno v jedné velké tabulce, s řádkem pro každou položku každé objednávky a se vším, co k položce patří, přímo v jejím řádku. Objednávky Evy Novotné by vypadaly takhle:
| objednavka_id | jmeno | mesto | nazev | cena | |
|---|---|---|---|---|---|
| 1 | Eva Novotná | eva.novotna@mail.cz | Praha | Cube Logic | 129 |
| 1 | Eva Novotná | eva.novotna@mail.cz | Praha | Moon Farm | 499 |
| 4 | Eva Novotná | eva.novotna@mail.cz | Praha | Dragon Forge | 999 |
| 14 | Eva Novotná | eva.novotna@mail.cz | Praha | Ice Hockey Pro | 1199 |
| 14 | Eva Novotná | eva.novotna@mail.cz | Praha | Zombie Town | 799 |
| 26 | Eva Novotná | eva.novotna@mail.cz | Praha | Knight's Oath | 1599 |
Čte se to snadno, ale pořád dokola se v tom opakuje totéž. Jméno, e-mail a město Evy Novotné jsou v každém řádku každé její objednávky a název každé hry by byl v řádku každé objednávky, ve které hra byla. To přináší potíže:
- Každou změnu je nutné udělat na mnoha místech. Když si Eva změní e-mail, musí se změnit ve všech jejích řádcích. Když na jeden zapomenete, tabulka tvrdí dvě různé věci a nikdo neví, která z nich platí.
- Překlep udělá z jedné věci dvě. Když bude v jednom řádku „Eva Novotna“, vypadá to najednou jako dvě různé zákaznice.
- Některé věci se nemají kam uložit. Zákazník, který si ještě nic neobjednal, nebo hra, kterou nikdo nekoupil, by neměli žádný řádek.
- Tabulka je zbytečně velká, protože se stejný text ukládá mnohokrát.
Proto databáze rozdělí data do tabulek tak, aby každá věc byla uložená právě jednou: každý zákazník má jeden řádek v tabulce zakaznici, každá hra jeden řádek v tabulce hry. Jak víte z první lekce, každý z těchto řádků má primární klíč, sloupec id s číslem, které žádný jiný řádek tabulky nemá. Ostatní tabulky na řádek ukazují tímto číslem v cizím klíči: zakaznik_id v tabulce objednavky obsahuje id zákazníka, hra_id v tabulce polozky id hry. Když si Eva změní e-mail, změní se v jednom řádku a všechny její objednávky na ni ukazují dál.
Háček je v tom, že odpověď na jednu otázku je teď rozložená do několika tabulek. S tím, co zatím umíte, musíte klíče sledovat sami, dotaz po dotazu. Nejdřív kdo zadal objednávku 4:
SELECT zakaznik_id
FROM objednavky
WHERE id = 4;| zakaznik_id |
|---|
| 1 |
Zákazník s ID 1. Číslo si přečtete ve výsledku a použijete ho ve druhém dotazu:
SELECT jmeno, email
FROM zakaznici
WHERE id = 1;| jmeno | |
|---|---|
| Eva Novotná | eva.novotna@mail.cz |
Funguje to, ale je to pracné: číslo jste museli opsat z jednoho výsledku do dalšího dotazu. Seznam všech třiceti objednávek se jmény zákazníků by zabral jedenatřicet dotazů. V dalším cvičení to necháte na databázi: tabulky spojíte v jednom dotazu.
Jak psát:
Pokyny
Kdo zadal objednávku 13? Napište dotaz, který ukáže zakaznik_id a datum objednávky, jejíž id je 13:
| zakaznik_id | datum |
|---|---|
| 10 | 2024-12-05 |
Pod něj přidejte dotaz, který ukáže jmeno a mesto zákazníka s ID, které jste našli:
| jmeno | mesto |
|---|---|
| Vojtěch Pokorný | Plzeň |
A co si koupil? Řádky tabulky polozky, jejichž objednavka_id je 13, obsahují ID her. Najděte je na kartě Tabulky, nebo vlastním dotazem. Pak přidejte dotaz, který ukáže id a nazev těchto her, seřazené podle id. S IN a seznamem ID stačí jeden dotaz:
| id | nazev |
|---|---|
| 3 | Moon Farm |
| 16 | Bakery Story |
Začněte programovat zdarma
1/12