Pod pojmem databáze si můžeme představit soubor dat, který je strukturovaný a je uzpůsobený pro snadné vyhledání v těchto datech. Vyhledávání může probíhat na základě obecných kritérií. Nejčastější se bavíme o relačních databázích, které udržují data ve formě vzájemně provázaných tabulek. V rámci tohoto tématu se budeme věnovat právě relačním databázím. Cílem je osvojit si vytváření tabulek, vkládání a úpravu dat a hlavně se naučit v datech vyhledávat - formulovat dotazovací kritéria tak, abychom dostali ty odpovědi, které nás zajímají.
Hlavní vlastnosti relačních databází:
Abychom mohli s databázemi pracovat, nabízí nám výrobci unifikovaný jazyk, pomocí kterého s databází komunikujeme. Ten se rozděluje na 3 základní druhy:
Pro jednoduchost začneme rovnou jazykem SQL. Budeme tedy pro začátek předpokládat, že databázi za nás někdo vytvořil a naplnil nějakými daty. Naším úkolem tedy bude osvojení si pokládání správných dotazů. Pro tvoření dotazů slouží jazyk SQL, který je navržen tak, aby vypadal pokud možno co nejvíce jako obyčejná anglická věta.
Jak už bylo v úvodu řečeno, relační databáze uchovávají data v podobě tabulek. Představme si tedy, že se naše databáze skládá z planet sluneční soustavy. Mohla by vypadat třeba následovně.
| nazev | delka_obehu [roky] | vzdalenost_od_slunce [km] |
|---|---|---|
| Merkur | 0,240 | 57 900 000 |
| Venuše | 0,615 | 108 200 000 |
| Země | 1,000 | 149 600 000 |
| Mars | 1,880 | 227 900 000 |
| Jupiter | 11,862 | 778 300 000 |
| Saturn | 29,447 | 1 429 200 000 |
| Uran | 84,016 | 2 875 000 000 |
| Neptun | null | 4 504 000 000 |
Za slovem SELECT vyjmenujeme sloupce, které chceme zobrazit a za slovem FROM napíšeme jméno tabulky, ve které chceme vyhledávat. Všimněte si, že název sloupce může být vždy pouze jedno slovo, proto víceslovné názvy spojujeme většinou pomocí podtržítka. Bývá také dobrým zvykem nepoužívat u názvů tabulek a sloupečků diakritiku.
V tabulce nemusí být vždy všechny hodnoty u všech sloupců vyplněny. V takovém případě mluvíme o tzv. NULL hodnotách. V předchozí tabulce se jedná o případ Neptunu a jeho délky oběhu.
V relačních databázích musí být každý řádek jasně definován pomocí tzv. primárního klíče. Je to hodnota sloupečku, která musí být v celé tabulce unikátní. V našem případě bychom mohli jako primární klíč zvolit například název planety - to by nám zajistilo, že nikdo nebude moci vložit do tabulky dva řádky se stejným názvem. Nicméně nejčastější praxí je, že se do každé tabulky přidává sloupeček s názvem ID, který představuje pro každý řádek unikátní číslo. Naše tabulka planet by pak mohla vypadat takto.
| id | nazev | delka_obehu [roky] | vzdalenost_od_slunce [km] |
|---|---|---|---|
| 1 | Merkur | 0,240 | 57 900 000 |
| 2 | Venuše | 0,615 | 108 200 000 |
| 3 | Země | 1,000 | 149 600 000 |
| 4 | Mars | 1,880 | 227 900 000 |
| 5 | Jupiter | 11,862 | 778 300 000 |
| 6 | Saturn | 29,447 | 1 429 200 000 |
| 7 | Uran | 84,016 | 2 875 000 000 |
| 8 | Neptun | null | 4 504 000 000 |
Tento přidaný sloupec si můžeme jako každý jiný sloupec zobrazit:
Primární klíče budeme používat hlavně pro spojování tabulek, které si ukážeme v dalších kapitolách.
Jak lze vybrat seznam sloupců k zobrazení jsme si již ukázali dříve. Přidáme tedy pouze pár jednoduchých poznámek. Pořadí sloupců nemusí dodržovat pořadí sloupců definovaných v tabulce. Můžeme si vybrat pouze podmnožinu sloupců, nebo můžeme stejný sloupec zobrazit třeba dvakrát - to ale není moc praktické. Každý vybraný sloupec si můžeme ve výstupních datech pojmenovat podle vlastního uvážení tím, že za název sloupce uděláme mezeru a napíšeme, jak chceme, aby se sloupec jmenoval ve výstupních datech.
Poslední poznámka k výběru sloupců k možnosti zobrazit jednoduše všechny sloupce, aniž bychom je museli všechny vypisovat. Toho dosáhneme pomocí hvězdičky.
Sloupce lze také spojovat mezi sebou nebo přidávat textové řetězce či čísla. Spojování jednotlivých sloupečků, textu i čísel se provádí pomocí znaku |. Spojením pak vznikne jeden sloupeček ve výstupní tabulce.
U takových sloupců, které vznikly spojením několika výrazů, pak většinou používáme přejmenování, aby název výsledného sloupečku vypadal lépe. Konkrétně zde ho celý pojmenujeme názvem veta.
Z tabulky planety zobrazte sloupečky ID a název.
Z tabulky planety zobrazte sloupečky ID a název, kde název bude přejmenovaný na sloupeček planeta.
Z tabulky planety zobrazte všechny sloupečky, které tabulka má, aniž byste je museli všechny vyjmenovávat.
Z tabulky planety zobrazte data tak, aby se pro každou řádku zobrazila věta ve tvaru př: "Mars oběhne Slunce 1,88 krát za rok s průměrnou vzdáleností 227 900 000 km." Tato věta ať se zobrazí ve sloupečku pojmenovaném pojednani_o_planetach_nasi_slunecni_soustavy.
Stejně tak jako nám SQL umožňuje vybrat sloupečky tabulek, máme také možnost vybírat konkrétní řádky. Toho nedosahujeme vyjmenováním řádků jako v případě sloupců (řádky totiž nemají své jméno), ale nadefinováním podmínek, které musí být pro řádek splněny, aby se dostal do výstupu dat. Tyto podmínky se skládají z logických výrazů a můžeme tak vytvořit podmínky od těch nejsnazších až po velice komplexní. Podmínky většinou obsahují názvy sloupečků a píší se za klíčové slovo WHERE.
Podmínky můžeme skládat pomocí logických spojek AND a OR, kde AND má větší prioritu - stejně jako má násobení přednost před sčítáním. Pokud tuto potřebujeme tuto prioritu změnit, můžeme použít závorky, stejně jako v matematickém výrazu.
Při tvoření podmínek můžeme používat následující operátory (výčet obsahuje pouze základní operátory):
Pojďme si zmíněné operátory vyzkoušet na příkladech. Nejdříve si zobrazíme všechny planety, které mají ID větší než 3.
Nyní si zobrazíme planety, které se v názvu obsahují písmeno a - na kterémkoli místě.
Nebo si můžeme nechat vypsat ty planety, které končí na slovo tun.
Můžeme si také vypsat řádky, které neobsahují část slova tu.
Nebo můžeme použít obdobu pomocí NOT LIKE operátoru.
Nebo si můžeme nechat vypsat ty planety, které nemají zadanou hodnotu delka_obehu.
Nebo naopak ty planety, které mají délku oběhu zadanou.
Napište dotaz pro nalezení všech planet, které se nejmenují Mars.
Napište dotaz pro nalezení všech planet, které jsou od Slunce vzdálené aspoň 300 000 000 km.
Napište dotaz pro nalezení všech planet, které obíhají Slunce méně než dva roky a nebo nemají dobu oběhu vůbec zadanou. Ve výstupu přejmenujte délku oběhu na doba.
Výstup dat můžeme kromě filtrování také řadit sestupně nebo vzestupně dle výběru. Vždy uvedeme název sloupce a směr řazení. Můžeme také řadit v několika úrovních - nejdříve podle jednoho sloupce a v případě shody podle druhého atd. Důležité je ale poznamenat, že při definování řazení se musí používat názvy sloupců tak, jak se objevují na výstupu. Pokud jsme si tedy některé sloupce přejmenovali, je lepší uvést naše vlastní jméno sloupečku.
Pro řazení se používá klíčové slovo ORDER BY a za něj se vyjmenují sloupečky, podle kterých chceme řadit. Pro sestupné řazení přidáme klíčové slovo DESC, pro vzestupné ASC.
Na příkladu si ukážeme, jak seřadit planety podle názvu vzestupně.
V případě podmínky pro výběr řádků se řazení definuje až za podmínkami. následující dotaz zobrazí planety, které jsou blíže Slunci než Země (mají délku oběhu menší než jeden rok) a seřadí je dle vzdálenosti sestupně. V případě, že by byly dvě planety stejně daleko, jako druhou úroveň třízení použije název vzestupně.
V případě, že se přejmenuje název výstupního sloupce, uvádíme v řazení nové jméno.
Napište dotaz pro nalezení názvů všech planet, které začínají na písmeno M a výslednou tabulku seřaďte podle těchto názvů sestupně.
Planety vypište pomocí jednoho sloupce, který bude mít formát "ID - nazev", bude se jmenovat planeta a podle tohoto sloupce setřiďte výsledek vzestupně. Do výsledné tabulky zahrňte pouze řádky, které mají ID větší než 3.
Někdy nás může zajímat pouze agregační pohled na data. S tím nám mohou pomoci tzv. agregační funkce, které vracejí pouze jednu hodnotu vypočtenou ze všech řádků (které splňují podmínku WHERE).
Například celkový počet vybraných řádků - konkrétně například těch, co mají zadanou délku oběhu. Použijeme funkci COUNT.
Nebo průměrná doba oběhu planet, které mají dobu oběhu větší než 1. Použijeme funkci AVG.
Nebo minimální a maximální vzdálenost planet od Slunce. Použijeme funkci MIN a funkci MAX.
Napište dotaz pro nalezení maximální doby oběhu ze všech planet, které mají ve svém názvu písmeno u. Výsledný sloupeček pojmenujte MAX_DOBA_OBEHU.
Napište dotaz pro nalezení počtu planet, které mají dobu oběhu menší než 2 roky.
Náš první případ, kdy databázi tvořil seznam platet, nebyl příliš komplexní. V praxi potřebujeme pracovat se složitější strukturou dat, která se pomocí jedné tabulky špatně modelují. Uveďme si následující příklad. Pro evidenci jednoho ročníku výuky čar a kouzel v bradavické škole potřebujeme následující data.
chceme vědět, jací žáci školu navštěvují
chceme na ně znát kontakt - bude stačit e-mail
dále chceme znát seznam učitelů, kteří na škole působí
u učitelů je důležité znát jejich funkci a jakým titulem je žáci oslovují
dále potřebujeme znát seznam předmětů, které se na škole vyučují
ke každému předmětu musíme znát vyučujícího, který předmět vyučuje
a také chceme vědět, kteří žáci jsou na který předmět zapsaní
Pokud bychom vzali tento seznam a vytvořili z něj jednu strukturu, do které budeme data ukládat, vznikla by nám asi následující tabulka.
| Jméno studenta | Příjmení studenta | Pohlaví studenta | Email studenta | Kolej | Předmět | Titul učitele | Jméno učitele | Příjmení učitele | Pohlaví učitele |
|---|---|---|---|---|---|---|---|---|---|
| Harry | Potter | muž | potter@bradavice.uk | Nebelvír | Lektvary | profesor | Severus | Snape | muž |
| Hermiona | Grangerová | žena | grangerova@bradavice.uk | Nebelvír | Přeměňování | profesor | Albus | Brumbál | muž |
| Ron | Weasley | muž | weasley@bradavice.uk | Nebelvír | Lektvary | profesor | Severus | Snape | muž |
| Draco | Malfoy | muž | malfoy@bradavice.uk | Zmijozel | Lektvary | profesor | Severus | Snape | muž |
| Luna | Láskorádová | žena | laskoradova@bradavice.uk | Havraspár | Lektvary | profesor | Severus | Snape | muž |
| Neville | Longbottom | muž | longbottom@bradavice.uk | Nebelvír | Kouzla | profesor | Minerva | McGonagallová | žena |
| Cho | Changová | žena | changova@bradavice.uk | Havraspár | Pozemky | lesník | Rubeus | Hagrid | muž |
| Vincent | Crabbe | muž | Zmijozel | Černá magie | profesor | Severus | Snape | muž | |
| Gregory | Goyle | muž | Zmijozel | Bylinkářství | Pomona | Prýtová | žena | ||
| Cedric | Diggory | muž | diggory@bradavice.uk | Mrzimor | |||||
| Astronomie | |||||||||
| profesor | Filius | Kratiknot | |||||||
| Fred | Weasley | muž | fwealsey@bradavice.uk | Nebelvír | Jasnovidectví | profesorka | Sybila | Trelawneyová | žena |
| Fred | Weasley | muž | fwealsey@bradavice.uk | Nebelvír | Pozemky | lesník | Rubeus | Hagrid | muž |
| Fred | Weasley | muž | fwealsey@bradavice.uk | Nebelvír | Černá magie | profesor | Severus | Snape | muž |
| Fred | Weasley | muž | fwealsey@bradavice.uk | Nebelvír | Bylinkářství | Pomona | Prýtová | žena |
Tabulka sice obsahuje všechna data, která obsahovat má, ale při podrobnějším pohledu objevíme hned několik problémů.
Předně je to zřejmá duplicita dat. To znamená, že některá data se zbytečně opakují. Podivme se třeba na předmět Lektvary. Na něj jsou zapsaní 4 žáci. Jelikož u každého předmětu chceme vidět, kdo jej vyučuje, jméno Severus Snape se nám neustále opakuje na všech 4 řádcích. A to i včetně jeho titulu, pohlaví atd. Ale ve skutečnosti se jedná stále o téhož stejného profesora Snapa. V čem je problém? Obecně duplicitu v datech nemáme rádi a snažíme se jí vyhnout. Duplicita totiž vede:
ke zbytečně zabranému místu - uvědomte se, že databáze běžně pracují se stovkami miliónů řádek. Pokud v každé řádce budeme zbytečně ukládat data, objem těchto zbytečných dat může být nezanedbatelný.
k nekonzistenci dat - nekonzistence znamená, že se data a vztahy mezi nimi nějakým způsobem rozbila. Představte si, že na jedné řádce bychom uvedli, že profesor Snape je muž (například u Harryho Pottera), kdežto u Draca Malfoye, že profesor Snape je žena. Tento fakt je zřejmě v rozporu, ale naše struktura dat toto "nastavení" umožňuje. Při návrhu datové struktury se vždy snažíme o to, aby nekonzistence nemohla vůbec nastat.
k evidenci stejných dat na více místech - někdo by mohl říct, že bude kontrolovat při editaci dat, zda k nekonzistenci nedochází. Ano, to je možné - budeme se kontrolami bránit, aby se nekonzistence do našich dat nedostala. Ovšem i kdyby se nám toto povedlo, vede duplicita dat k potřebě evidovat změny "jednoho záznamu" na více místech. Představte si, že Hagrid složí profesůru a vy mu budete chtít změnit titul na profesora. To znamená, že musíte projít celou tabulku a ve všech řádcích, kde se Hagrid vyskytuje, jeho titul změnit. V našem malém příkladu by to ještě nebylo tak hrozné, změnu bychom prováděli pouze u dvou řádků, ale u milionu záznamů už to dopad mít bude.
Podobné duplicity můžeme v tabulce vidět hned na několika místech. Je to například:
opakování pohlaví u jednotlivých studentů
opakování pohlaví u jednotlivých učitelů
opakování titulů u jednotlivých učitelů
již zmíněný učitel u všech žáků navštěvující stejný předmět
opakování detailů studenta, který je zapsaný na více předmětech - například Fred Weasley.
Mezi duplicitu bychom mohli zařadit i příklad s kolejí. Na první pohled se může zdát, že informace o tom, jak přiřadit studenta do koleje, není možno vyjádřit jiným způsobem, než že uvedeme, ke které koleji student náleží. Ale duplicita vzniká přímo i s uvedením názvu koleje - v případě, že bychom chtěli nebelvírskou kolej přejmenovat, tak musíme opět projít všechny záznamy a všechny výskyty slova Nebelvír zaměnit za nový název.
Problémů s naší tabulkou je tedy více než dost. Lékem na naše problémy bude lepší navržení struktury, do které budeme data ukládat - mluvíme o navržení datového modelu. Tabulky sice budeme používat nadále, ale jednu velkou tabulku se pokusíme rozbít do více menších a uvidíme, jestli to náš problém vyřeší. Budeme se snažit o tzv. dekompozici dat.
|
|
|
Zkusme se podívat na to, čeho jsme zmíněným rozdělením docílili.
Určitě se nám neopakují názvy předmětů.
Stejně tak jsme odstranili duplicitu u učitelů. Seznam všech učitelů budeme dávat pouze do jedné tabulky a každý učitel (ať už nějaký předmět vyučuje či nikoli) se v tabulce objeví pouze jednou.
A to stejné můžeme říci o studentech - odstranili jsme jejich duplicity v případě, že navštěvují více předmětů.
Některé problémy ale zatím nezmizely a některé jsme rozdělením naopak zavedli:
Stále máme problém s duplicitou u názvů koleje. Pokud budeme chtít změnit jeden název, budeme muset změnit několik řádků.
Stejná věc se dá vlastně říct i o titulu učitele. V případě, že budu chtít titul profesor přejmenovat na prof., tak musím zase změnit hned několik záznamů. Tady je problém ještě trochu komplikovanější, protože název titulu se mění v závislosti na tom, zda se jedná o ženu či muže - profeska versus profesor.
Pokud by většina studentů neměla zadaný email, tak u většiny řádků v tabulce student bude ve sloupečku email prázdná hodnota. Nešlo by tomuto nějak předejít, ať se nemusíme zbytečně tahat se sloupečkem, kde může být stejně většinou prázdná hodnota?
Problém můžeme ještě vidět u pohlaví. Pohlaví udržujeme jak u učitele, tak u studenta. Přitom jde o informaci stejného typu. Představte si navíc, že bychom chtěli například název muž a žena zaměnit za kratší M a Ž. Co to znamená? No, musíme projít celou tabulku a na všech místech provést záměnu. U milionu řádků je to strašná dřina. A nemluvě o tom, že nemusíme procházet tabulku jednu, ale ve skutečnosti dvě - student i ucitel.
Zároveň tušíme, že mezi tabulkami ucitel a predmet je ve skutečnosti jakási vazba, o kterou jsme rozdělením tabulky přišli. Najednou nejsme schopni říci, jaký učitel vyučuje jaký předmět. Tuto informaci o provázání tabulek budeme tedy muset ještě nějak doplnit. Napadne vás způsob, jak by to šlo udělat?
To stejné platí o vazbě mezi tabulkami student a predmet. Najednou nejsme schopni říci, jaký předmět student navštěvuje. Tady je navíc situace ještě malinko komplikovanější, protože oproti předchozímu bodu, kde je jeden předmět vyučován maximálně jedním učitelem, může jeden student chodit hned na několik různých předmětů (třeba Fred Weasley ) a nebo taky na žádný (třeba Cedric Diggory - to nemá nic společného s tím, že ho ve 4. díle pán zla zabil). A zároveň na jeden předmět může chodit hned několik různých žáků (Lektvary) a nebo taky nikdo (Astronomie). Jak byste si poradili s tímto problémem? Jak všechny tyhle informace pomocí nějakých tabulek a přidaných sloupců postihnout?
Zkuste se na tabulky podívat a pokračujte v dekompozici ještě dále (nebo navrhněte úplně jinou strukturu podle vaší libosti) tak, abyste se zbavili všech (nebo aspoň většiny ) problémů. Tabulky si zkopírujte do excelu (to už umíte - pamatujete na kopírování dat s formátem nebo jenom s hodnotami :-) ?) a v excelu pracujte s tabulkami tak, že je budete rozdělovat a možná pro vyřešení všech problémů budete muset nějaké sloupce (které zatím naše tabulky nemají) do tabulek přidat - bude to potřeba pro vyřešení vazeb mezi jednotlivými tabulkami. Například abyste byli schopni říct, jaký předmět je vyučován jakým učitelem, do jaké koleje studenti patří, nebo jací studenti navštěvují jaké předměty.
Nápověda může znít takto: zaveďte si primární klíče a odkazujte se na ně.
V této kapitole se pokusíme vyřešit všechny problémy plynoucí z naší dekompozice, jak jsme nastínili v předchozí kapitole. Začněme postupně. Nicméně důležité je říci, že obecně dekompozice dat nemá vždy jedno správné řešení. Podmínky datového modelu se mohou pro každý případ lišit - i malá změna v zadání může vést na odlišný datový model. Pojďme si tedy ukázat jedno z možných řešení.
Duplicitu snadno odstraníme stejně jako u duplicit studentů a předmětů tak, že si pro koleje zavedeme samostatnou tabulku. Pro každou kolej budeme mít pouze jeden řádek. Přejmenování koleje pak bude spočívat ve změně pouze jednoho řádku.
Tady to uděláme podobně. Akorát tentokrát si nezavedeme tabulku jednu, ale rovnou dvě. V první budou tituly podle druhu - nebudeme rozlišovat, zda se jedná a ženský či mužský druh titulu. Bude to prostě titul profesor. atd. V druhé tabulce, kterou nazveme oslovení, přidáme každou řádku pro mužské (profesor) i ženské (profesorka) oslovení. Oba tyto záznamy budou napojeny na titul, ze kterého pocházejí. Z tabulky ucitel se budeme odkazovat na oslovení podle toho, jaký titul učitel má a zároveň jakého je pohlaví.
Abychom se vyhnuli problémům s "řídkými" hodnotami emailů, můžeme si pro tabulku kontaktů vytvořit samostatnou tabulku. Do této tabulky vložíme řádek pouze v případě, kdy studentův email známe. Musíme samozřejmě zajistit, že správně propojíme tuto novou tabulku kontakt a tabulku student, abychom poznali, ke kterému studentovi email patří.
S duplicitou si už umíme poradit. Pro danou hodnotu zavedeme samostatnou tabulku pohlavi, do které uvedeme všechny přípustné hodnoty. S výhodou můžeme tuto tabulku napojit jak na tabulku student, tak na tabulku ucitel.
V našem prvním pokusu o dekompozici jsme již tabulky ucitel a predmet rozdělili, čímž jsme vyřešili duplicity. Takže nám zbývá už jenom zajistit vazbu mezi těmito tabulkami, aby bylo poznat, který učitel učí který předmět.
Poslední bod k řešení (vztah tabulek student a predmet) je skoro stejný jako problematika vazby mezi učitelem a předmětem. Ale skutečně jenom skoro. Ve skutečnosti se jedná o trochu složitější problém. Zatímco u předmětu si můžeme dovolit napojit jeden předmět na jednoho učitele, u studentů je to tak, že jeden předmět můžeme napojit na více studentů.
Pojďme všechny předchozí body realizovat a podívejme se, jak budou vypadat jednotlivé tabulky. Na první pohled je vidět, kam se nám namapují různá data. Co na první pohled vidět není, jsou vztahy mezi tabulkami. Částečně si vztahy můžeme zobrazit tak, že zajedeme myší nad buňky tabulek, čímž se nám červeně rozsvítí relevantní záznamy v ostatních tabulkách (poznámka: zobrazení provázání není vždy úplně kompletní, berte to vždy jako ukázku toho, jaké tabulky spolu souvisí).
|
|
|
|
|
|
|
|
|
Interaktivní podbarvení sice může vypadat efektivně, ale ve skutečnosti takto databáze nefungují a ani by to při větším počtu řádků nebylo přehledné. Musí tedy existovat způsob, jak vztahy mezi tabulkami vepsat přímo do tabulek. Než si povíme jak na to, podivme se blíže, jaké druhy takovýchto vztahů mohou vlastně existovat.
Vztahům mezi tabulkami se v databázích říká nejčastěji vazby nebo relace a je to důvod proč jsme na začátku zmínili, že se budeme bavit o relačních databázích. Relační databáze jsou tedy tvořeny tabulkami a vazbami mezi těmito tabulkami. Databáze nám umožňují tyto vazby definovat a využívat je při dotazování se nad daty. Vazeb může existovat celá řada a navíc vazby mohou mít ještě nejrůznější vlastnosti jako je povinnost nebo násobnost, ale my si ukážeme jenom tři základní vazby.
Toto je nejsnazší způsob, jak provázat dvě tabulky dohromady. Název nám říká, že v nejprostším případě bude jeden řádek z tabulky A odpovídat jednomu řádku z tabulky B. Ve skutečnosti ale není důležité, zda tabulky obsahují stejný počet řádků. Důležité je, že k jednomu řádku tabulky A můžeme přiřadit maximálně jeden řádek tabulky B. V našem případě bradavické školy tomu odpovídá vztah mezi tabulkami student a kontakt - jeden student může mít maximálně jeden email.
Kdybychom podmínku v přechozím odstavci změnili a řekli bychom, že jeden student může mít více (N) emailů, už by se nejednalo o vazbu 1:1, ale vazbu 1:N. Vazba 1:N tedy říká, že k jedné řádce tabulky A může existovat 0 až N řádků z tabulky B. Ale zároveň musí platit, že jednomu řádku z B odpovídá vždy maximálně jeden řádek z tabulky A. V našem datovém modelu můžeme vazeb 1:N najít hned několik.
Do jedné koleje může chodit 0 až N studentů a zároveň platí, že každý student je přiřazen do jedné koleje.
V tabulce studentů může být 0 až N mužů a 0 až N žen a zároveň platí, že každý student je buď muž či žena.
To stejné platí ohledně pohlaví u učitelů.
Každý učitel může vyučovat 0 až N předmětů a zároveň platí, že každý předmět může být vyučován maximálně jedním učitelem.
Možná, že někdo z vás chtěl příklady ještě rozšířit o vazbu mezi studenty a zapsanými předměty. Ale to by byla chyba. Tato vazba totiž nesplňuje podmínky vazby 1:N. A to z toho důvodu, že jeden student může mít zapsáno 0..N předmětů, ale jeden předmět nemusí být zapsaný maximálně jedním studentem - na stejný předmět může chodit vícero studentů. Tato vazba totiž odpovídá typu N:M.
Jak je v předchozím odstavci uvedeno, naše tabulky student a předmět jsou ve vztahu N:M. Při označení není důležité co je N a co M. Ani není řečeno, že N je více než M atd. Jedná se pouze o označení stavu, kdy jednomu řádku z tabulky A může odpovídat 0 až N řádků z tabulky B a zároveň každému řádku z tabulky B může odpovídat 0 až M řádků z tabulky A.
Když jsme si rozdělili, s jakými typy vazeb se můžeme v relačních databázích potkat, můžeme si ukázat, jak jednotlivé typy vazeb v tabulkách realizovat. Trik spočívá v přidání sloupců, pomocí kterých se budeme odkazovat do jiných tabulek. Na začátku jsme se zmínili o tzv. primárních klíčích - primary key, což jsou sloupečky, které nám jasně identifikují řádek tabulky. Tyto primární klíče můžeme použít jako odkaz v jiných tabulkách. Takovýto odkaz na primární klíč jiné tabulky nazýváme cizí klíč - foreign key. Pokud je takovýchto klíčů určující jiný řádek v jiné tabulce více, hovoříme o složených klíčích. V předchozím schématu datového modelu můžeme klikat na PK a FK u jednotlivých tabulek pro zobrazení použitých primárních a cizích klíčů.
Řekli jsme si, že tabulky student a kontakt jsou v našem případě ve vztahu 1:1. Každá z těchto tabulek má svůj primární klíč ID a tak je velmi snadné tyto tabulky provázat. Prostě si řekneme, že záznamy, které k sobě patří, budou mít stejnou hodnotu primárního klíče. Pokud nějaký student email mít nebude, tak se prostě v tabulce kontakt jeho ID neobjeví. Vyzkoušejte si to na interaktivním schématu.
Jako příklad vazby 1:N si uvedeme vztah mezi tabulkami kolej a student. Vazbu zrealizujeme tak, že k tabulce student přidáme cizí klíč kolej_id, který bude ukazovat na primární klíč ID tabulky kolej. ID jedné koleje se může u několika studentů opakovat - to představuje fakt, že několik studentů může patřit do stejné koleje. Jen tak na okraj: pokud bychom dovolili, že některý student ještě není do koleje zapsán, pak by na místě jeho cizího klíče ukazující na kolej byla hodnota null.
Podobným způsobem jsme přidali do tabulky student další cizí klíč se jménem pohlavi_id, který ukazuje na primární klíč ID v tabulce pohlavi a určuje nám tak, jakého pohlaví student je. Podobný cizí klíč pohlavi_id je zaveden i v tabulce ucitel.
Jak už jsme dříve naznačili, v našem modelu existuje jedna vazba typu N:M. Jedná se o vazbu mezi tabulkou student a predmet - stejný student může navštěvovat několik předmětů a zároveň několik různých studentů může navštěvovat stejný předmět. Předpokládejme, že obě tabulky budou mít primární klíč ID identifukující příslušný řádek. Jak provážeme tyto primární klíče, abychom postihli příslušnou vazbu? Můžeme zkusit přidat cizí klíč predmet_id do tabulky student. Tím jsme schopni zachytit fakt, že několik studentů navštěvuje jeden předmět, ale už nejsme schopni postihnout případ, že jeden student chodí na více předmětů. Jasně, mohli bychom místo jednoho cizího klíče přidat klíčů několik - predmet_1, predmet_2 a predmet_3. Tímto způsobem už bychom uměli jednoho studenta zapsat až na 3 předměty. Ale toto řešení není vhodné ze dvou důvodů:
Jsme omezeni právě těmito třemi předměty - co když příští rok bude možné zapsat předmětů více? Taková Hermiona by toho určitě využila.
Ten student, který nemá zapsané všechny 3 předměty, bude mít v příslušných sloupečcích null hodnoty.
Pokud nám tedy nevyhovuje toto řešení, můžeme zkusit věc otočit a přidat do tabulky predmet sloupeček student_id. No ale po zamyšlení dojdeme k poznání, že tím jsme opět problém nevyřešili. Akorát jsme předchozí nedostatek otočili. Zatím jsme na optimální řešení tedy nepřišli, ale to neznamená, že neexistuje.
Prakticky si to můžeme znázornit na schématu, pro který se při modelování tabulek a vztahů mezi nimi říká ER - diagram z anglického Entity - Relationship diagram.
ER diagram znázorňuje jednotlivé tabulky a jejich sloupečky. Mezi sloupečy jsou zachyceny i primární a cizí klíče realizující vazby mezi tabulkami. Nás nyní zajímá vztah mezi tabulkou student a predmet. Zde je znázorněna vazba N:M.
Pokud použijeme pravidlo o substituci N:M vazby pomocí dvou 1:N vazeb, můžeme ER diagram upravit následovně. Zavedeme si umělou tzv. vazební tabulku, na kterou z obou stran pomocí 1:N vztahu napojíme původní tabulky, které mezi sebou vystupovaly ve vztahu N:M. Vazební tabulka se bude sestávat pouze ze dvou sloupečků obsahující cizí klíče - jeden (student_id), ukazující na primární klíč tabulky student a druhý (predmet_id), ukazující na primární klíč tabulky predmet. V našem případě dává smysl, abychom vazební tabulku pojmenovali třeba vyuka. Ale jsou situace, kdy se nám ani žádné "hezké" jméno nalézt nepodaří. Pak se dá jméno vytvořit prostou složeninou názvů obou tabulek - něco jak studento_predmet nebo prostě student_predmet. V tomto případě je čeština spíše na škodu oproti anglickému způsobu skládání jmen. Je to jeden z důvodů proč i čeští databázoví analytici a programátoři používají spíše anglické názvy tabulek a sloupců. ER diagram s vazební tabulkou vyuka vypadá následovně.
A proč jsme říkali, že vazební tabulka se na původní tabulky váže vazbou 1:N? Je to z toho důvodu, že jeden student (student_id) se v tabulce vyuka může objevit 0..N krát. A to stejné platí i pro jeden předmět (predmet_id). Vraťte se zpátky k finálnímu dekomponovanému modelu a zapněte si zobrazení primárních i sekundárních klíčů, čímž se objeví vazební tabulka vyuka, u které můžete při najetí myši sledovat, jak se cizí klíče starají o propojení navázaných tabulek.
Navrhněte ER diagram pro databázi pro následující případy:
Pro místní jídelnu navrhněte DB pro evidenci žáků, jídel a objednávek na konkrétní den. Každý žák si může na jeden den objednat maximálně jedno jídlo.
Pro místní pobočku Kaflandu navrhněte systém, který eviduje druh zboží, jeho jednotkovou cenu, v jakém počtu je na skladě k dispozici. Podle zákaznických karet evidujte, jaký zákazník si který produkt koupil - evidujte jednotlivé položky, datum a cenu nákupu. Zkuste si pamatovat, kolik za ně skutečně v daný čas zákazník zaplatil.
Nyní už víme, jak lze data dekomponovat pomocí několika tabulek a vztahů mezi nimi. Ovšem to, že jsme data "rozdrobili", nám může vadit v momentě, kdy chceme tabulky pomocí SQL selectů procházet a data zobrazovat. Zatím jsme se naučili zobrazovat data pouze z jedné tabulky, ale to ve většině případů nestačí a my se musíme naučit, jak lze v selectu jednotlivé tabulky přes cizí klíče spojovat dohromady. Asi se ptáte, proč jsme tabulky rozdělovali, když je nyní opět budeme spojovat dohromady. Dobrá otázka. Jde o to, že dekomponovaná data se dobře ukládají. Pamatujete? Dekompozici jsme dělali kvůli odstranění duplicit. Ale v náhledu na data se nám duplicity mohou hodit. Nicméně duplicitní zobrazení použijeme třeba jenom na malý vzorek dat, který omezíme pomocí podmínky WHERE. Navíc občas data nemusíme zobrazovat celá - můžeme nad daty provádět agregační výpočty (například počítat, kolik záznamů k tabulce A existuje v tabulce B). Místo dlouhého popisování si to pojďme raději ukázat na příkladu.
Dříve než začneme tabulky spojovat, ukážeme si ještě jednu vlasnost SQL dotazu, bez které bychom se u propojení více tabulek neobešli. Jelikož nyní budeme pracovat s vícero tabulkami, které mohou obsahovat stejné názvy sloupečků, musíme jasně rozlišit, jaké tabulce konkrétní sloupečky náleží. Abychom před každým názvem sloupečku nemuseli opakovat celý název tabulky, můžeme si pro každou tabulku zvolit tzv. alias.
V následující ukázce jsme si pro tabulku student zavedli alias s, pomocí kterého se na tabulku můžeme odkazovat jak v sekci vybrání sloupečků, tak v sekci podmínky WHERE.
Představte si, že si chceme vypsat studenty společně s informací o tom, do které koleje chodí. Určitě se budeme dotazovat na tabulku student, ale zároveň budeme chtít tuto tabulku napojit na tabulku kolej. A to pomocí cizího klíče kolej_id v tabulce student. Výsledný select bude vypadat takto:
Spojení tabulek je implementované pomocí klíčového slova JOIN, za které se napíše název tabulky, kterou chceme s první tabulkou propojit. Aby databáze věděla, které řádky má spojit dohromady, za klíčové slovo ON napíšeme názvy sloupečků, u kterých se zkoumá rovnost.
V našem případě jsme si pro tabulku student zvolili alias s a pro tabulku kolej alias k a tabulky jsme spojili přes sloupce k.id a s.kolej_id. Jinými slovy říkáme, že chceme zobrazit všechny řádky z tabulky student, u kterých existuje vazba na tabulku kolej a to tak, že ke každému řádku přidáme řádek z tabulky kolej tak, aby si odpovídaly student.kolej_id a kolej.id. Výsledek si můžete prohlédnout v editoru.
Všimněte si, že výsledná spojená tabulka obsahuje všechny sloupce z obou tabulek. Pokud bychom chtěli vypsat pouze některé sloupečky, můžeme použít způsob zápisu, který známe ze selectů nad jednoduchou tabulkou. Prostě požadované sloupečky vyjmenujeme, místo toho, abychom použili *. I zde bývá dobrým zvykem před každý název sloupce uvádět alias tabulky. Jako příklad si uveďme vypsání tabulky, která zobrazí pouze jméno a příjmení studenta (to rovnou zobrazíme sloučené v jednom sloupci s názvem jméno_studenta), jeho id a název koleje, kterou navštěvuje.
Spojením dvou či více tabulek nám ve skutečnosti vznikne nová tabulka a s jako takovou s ní můžeme pracovat úplně stejně, jako kdyby se jednalo pouze o základní jednu tabulku. Na spojenou tabulku můžeme aplikovat například podmínky pro filtrování řádků nebo aplikovat řazení podle jednotlivých sloupců. Můžeme si například vypsat pouze studenty, kteří chodí do Nebelvíru a výsledný seznam můžeme seřadit podle příjmení studentů. V tom případě bude lepší otočit výpis jmen tak, aby se první zobrazovalo příjmení a až pak jméno.
Spojovat samozřejmě můžeme i více tabulek. Představte si, že bychom k našemu seznamu chtěli uvést i e-mail studenta. E-mail najdeme v tabulce kontakt a pokud si vzpomínáte, vazba mezi tabulkou student a kontakt je typu 1:1 - příslušný studentův kontakt najdeme podle shodnosti primárních klíčů. Pro přehlednost vypíšeme podstatné sloupečky a některé přejmenujeme tak, aby nedošlo k duplicitě názvů - konkrétně sloupec id z tabulek student a kontakt.
Všimněte si, že jsme naši tabulku propojili s další tabulkou kontakt (jako alias jsme zvolili knt, protože samotné k by nám vedlo ke konfliktu s aliasem pro tabulku kolej). a přes primární klíče s.id a knt.id jsme tabulku z kontakty připojili. Z nově připojené tabulky jsme použili pouze sloupec knt.id a knt.email. Podobným způsobem můžeme výslednou tabulku seskládat z velkého množství zdrojových tabulek tak, že jednotlivé tabulky budeme přidávat pomocí klíčového slovo JOIN ... ON ....
Pokud se pozorně podíváte na předchozí příklad, všimnete si, že z nějakého důvodu nám ze seznamu vypadli někteří studenti - jsou to Crabbe a Goyle. Proč se to stalo? Je to právě kvůli spojování tabulek. Konkrétně v našem případě kvůli připojení tabulky kontakt. Mezi tabulkou studnet a kontakt sice existuje vazba 1:1, ale zároveň jsme řekli, že to neznamená, že pro každého studenta musí být kontakt uveden - vazba 1:1 říká, že každý student může mít maximálně jeden kontakt a naopak. V našem případě mluvíme o tom, že záznam z tabulky kontakt je ve vazbě nepovinný. A to právě nastalo u studentů Crabbe a Goyle.
Když jsme se snažili tabulku kontakt připojit k tabulce student pomocí klíčového slova JOIN, databáze pro tyto dva studenty nenašla existující záznam v tabulce kontakt, a proto tyto dva řádky reprezentující studenty neměla s čím spojit. Výsledkem je vynechání těchto studentů z výsledného seznamu.
Chování JOINu popsané v předchozí kapitole se nám nemusí vždy hodit. Někdy budeme potřebovat seznam všech studentů, ať už kontakt uvedený mají či nikoli. U těch, kteří kontakt mají, by se ve výpise objevil e-mail, a u těch, kteří kontakt nemají, by zůstalo prázdné políčko - vlastně null hodnota (schválně jestli si ještě vzpomínáte, co to null hodnota je).
Popsaného chování jsme schopni dosáhnout pomocí tzv. LEFT JOINU. Správný název by měl být LEFT OUTER JOIN (oproti obyčejnému JOINU, který někdy nazýváme správně INNER JOIN), ale databáze nás nenutí slovo INNER a OUTER používat, tak se obejdeme bez nich. Důležité je vědět, jaký je mezi JOIN a LEFT JOIN rozdíl. A ten spočívá přesně v tom, co bylo popsána na začátku této kapitoly.
Můžeme si to hned ověřit na našem přechozím příkladu, kde místo obyčejného JOINu použijeme LEFT JOIN (pro názornost budeme spojovat pouze tabulku student a kontakt). Studenti Crabbe a Goyle se nám tentokrát v tabulce objeví přesně tak, jak jsme chtěli.
Nenechte se zmást. Ani použití LEFT JOINu vám nezaručí, že se do výsledného seznamu dostane každý student právě jednou. To bude fungovat pouze v případě, že spojujete tabulky s vazbou 1:1. Pokud jakýkoli JOIN použijete na vazbu 1:N nebo M:N, tak se řádek do výsledku dostane tolikrát, kolikrát se objeví ve vztahu s druhou tabulkou. Jako příklad si můžeme uvést vazbu 1:N, která je mezi tabulkami pohlavi a ucitel.
V příkladu vidíme, že položka muž či žena se ve výsledné tabulce vyskytne tolikrát, kolikrát je obsažena ve vazbě - jinými slovy, tolikrát kolik je na dané pohlaví napojeno učitelů.
Jako další příklad si uvedeme jedinou vazbu N:M, kterou v našem databázovém schématu máme. Jde o vazbu mezi tabulkou predmet a student. Víme, že je realizována pomocí vazební tabulky vyuka. Tuto tabulku použijeme v následujícím selectu.
Jak je vidět, v seznamu se opakují jak studenti (pokud si zapsali vícero předmětů), tak předměty (pokud si jeden předmět zapsalo více studentů). Protože jsme použili JOIN, z výsledného seznamu vypadnou ti studenti, kteří nemají zapsaný žádný předmět a také ty předměty, který si nikdo nezapsal.
Kdybychom chtěli zachovat v seznamu všechny studenty, museli bychom použít LEFT JOIN. Na tomto příkladu si také ukážeme, že u LEFT JOINu záleží na pořadí spojovaných tabulek - jinými slovy záleží na tom, která tabulka se objeví vlevo (první) a která vpravo (druhá). V následujícím LEFT JOINu uvedeme první jako tabulku student. Tím se nám do seznamu dostane i Luna Láskorádová, která nemá zapsaný žádný předmět. Ale ty předměty, které si nikdo nezapsal, se v seznamu neobjeví.
Kdežto v následujícím příkladu uvedeme jako první tabulku predmet, čímž se nám do seznamu dostane Jasnovidectví a Astronomie, které žádný student nenavštěvuje. Luna Láskorádová v seznamu ale není.
V následujícím ukázce můžeme vidět, že v podmínce (LEFT) JOIN ... ON ... můžeme použít i složitější podmínky složené pomocí logických operátorů AND a OR. Vazba mezi tabulkami ucitel a osloveni není tvořena pouze jedním sloupcem - tabulka osloveni má totiž složený primární klíč tvořený dvěma sloupci titul_id a pohlavi_id. Pokud chceme ke každému učiteli zobrazit jeho titul závislý na pohlaví, musíme vytvořit následující select.
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Zobrazte z učitelského sboru pouze ženy.
Zobrazte pouze ty studenty, kteří nemají zadaný email.
Zobrazte profesory (muže) s jejich správným oslovením.
Zobrazte studentky, které chodí do nebelvíru.
Zobrazte všechny studentky, které chodí na nějaký předmět s Hermionou Grangerovou.
Zobrazte předměty, které vyučuje ředitel školy.
Zobrazte pouze ty studenty, kteří mají zadaný email a mají ve jméně slovo bottom.
Zobrazte studenty, kteří chodí na předmět Lektvary.
Zobrazte studentky, které učí nějaká profesorka.
Zobrazte studenty, kteří nejsou zapsáni na žádný předmět.
Zobrazte studenty, kteří nejsou zapsáni na žádný předmět.
Zobrazte učitele, kteří neučí žádný předmět.
Vypiště předměty předměty, kde se mohou setkat studenti z Nebelvíru a Zmijozelu.
Při spojování tabulek dost často používáme tzv. seskupování. Jedná se o způsob jak odstranit duplicitní řádky ve výstupní tabulce. Možná bychom to mohli nazvat termínem setřesení. Při setřesení často používáme agregační funkce, pomocí kterých můžeme se setřásanými záznamy provádět různé operace - například spočítat počet duplicitních řádků, nebo spočítat maximální, minimální nebo průměrné hodnoty.
Nejlepší bude ukázat si to na příkladu. Představme si, že chceme zjistit obsazenost jednotlivých kolejí. Začněme tím, že si vypíšeme seznam kolejí a studentů.
Když chceme zjistit obsazenost kolejí, jednotlivá jména studentů nás ve skutečnosti nezajímají. Proto je můžeme z výsledné tabulky odstranit. Tím nám ve výsledné tabulce zbudou pouze hodnoty, které jsou v několika řádcích duplicitní.
Tyto duplicitní řádky můžeme odstranit a zároveň si pro každý unikátní řádek nechat spočítat, kolikrát se ve výsledné tabulce vyskytoval. Pro seskupení použijeme klíčové slovo GROUP BY, za které uvedeme seznam sloupců, přes které chceme zjišťovat duplicitu - tento seznam nám určí, které sloupečky mají být považovány za unikátní. Počet duplicitních řádků pro každý unikátní skupinu řádků zjistíme pomocí agregační funkce COUNT. Počet duplicitních řádků pro každou kolej představuje počet studentů patřící k této koleji. Proto jsme sloupeček s COUNT(*) přejmenovali na pocet_studentu.
Dost často chceme mít výstup seřazený podle agregačních kritérií. V našem případě podle obsazenosti kolejí - od nejobsazenější koleje až po nejméně obsazenou. Abychom toho dosáhli, stačí k předchozímu selectu přidat klauzuli ORDER BY a říct, že chceme řadit podle sloupečku pocet_studentu sestupně.
Ukážeme si ještě, že klíčové slovo GROUP BY můžeme samozřejmě používat ve spojení se vším, co jsme se zatím naučili. Výslednou tabulku můžeme řadit podle sloupců a stejně tak můžeme filtrovat řádky pomocí klíčového slova WHERE. U seskupování si ale musíme uvědomit, že při použití WHERE dochází k filtrování řádků před samotným seskupením. Proto se také WHERE píše před GROUP BY. Kdybychom chtěli zjistit obsazenost kolejí dívkami, použili bychom následující select.
Kolik můžů působí v učitelském sboru?
Zobrazte seznam předmětů a počty studentů, kteří předmět navštěvují.
Zobrazte seznam studentek a počet předmětů, které navštěvují.
Zobrazte seznam učitelů a kolik předmětů vyučují.
Co kdybychom ale chtěli filtrovat řádky po seskupení? A ještě k tomu podle výsledku agregačních funkcí. Například chtěli bychom vypsat jenom ty koleje, kde je obsazenost větší než nějaká hodnota? V ten moment nám WHERE moc nepomůže a musíme použít nové klíčové slovo HAVING. Za toto klíčové slovo napíšeme podmínky, podle kterých se do výsledné tabulky buď řádky dostanou nebo ne.
Pokud bychom chtěli vypsat jenom ty koleje, kde je více než jedna dívka, použili bychom následující select.
Další příkladem může být select, který vypisuje pouze ty učitele, kteří učí více jak jeden předmět. V tomto příkladě je zároveň ukázáno, že za GROUP BY nemusíme použít název sloupečku, ale můžeme zde napsat přímo název agregační funkce určující počet předmětů na jednoho učitele.
Kromě seskupování se v SQL poměrně často pracuje také s tzv. subselecty - neboli podselecty. Subselect je obyčejný select, který se provádí pro každou řádku výsledné tabulky. V subselectech je důležité, aby byla výsledkem pouze jedna konkrétní hodnota - pouze jeden řádek a jeden sloupec. Většinou se jedná o výsledek funkce COUNT, MIN nebo MAX. Subselecty se mohou objevit na dvou místech - v seznamu zobrazovaných sloupců nebo v podmínce za WHERE nebo HAVING.
Ukážeme si stejný příklad jako jsme dělali pomocí seskupování. Spočteme si, jaká je obsazenost kolejí, ale tentokrát to uděláme pomocí subselectu.
Jak je vidět, ke každé řádce z tabulky kolej se provede subselect, který pro každou řádku spočítá, kolik studentů náleží konkrétní koleji.
Subselect můžeme použít také v podmínce WHERE, kde se pro každou řádku spočítá konkrétní hodnota (třeba počet studentů) a do výsledné tabulky se dostanou pouze řádky, které danou podmínku splňují. Můžeme například vypsat jenom ty koleje, kde je obsazenost větší než 2
Subselecty můžeme samozřejmě kombinovat a uvádět je jak v seznamu sloupců tak i v podmínce WHERE.
Seznam učitelů vyučující více jak jeden předmět můžeme pomocí subselectu získat takto.
Do této doby jsme se zabývali pouze vyhledáváním v datech. Nyní si ukážeme, jak můžeme data vytvářet, upravovat a mazat v rámci existujících tabulek. K tomu slouží příkazy INSERT, UPDATE a DELETE jazyka DML (data manipulation language).
Pro vkládání řádků do tabulek se používá příkaz INSERT, který má následující podobu. Nejdříve se uvede název tabulky, do které chceme data vložit, společně se seznamem sloupečků, pro které pak definujeme ve stejném pořadí konkrétní data. Následující příkaz vloží do tabulky kolej jednu novou řádku s ID=5 a názvem Brumbálov. Přesvědčte se o tom selectem pro zobrazení všech kolejí.
Pro úpravu řádků v tabulce se používá příkaz UPDATE, který má následující podobu. Nejdříve se uvede název tabulky, pak seznam sloupců s novými hodnotami (můžeme změnit víc sloupců naráz - oddělíme je čárkami) a nakonec seznam řádků, kterých se změna týká, definovaných pomocí podmínky WHERE. Následující příkaz přejmenuje v tabulce kolej řádku Havraspár (ID=4) na Vránospár. Přesvědčte se o tom selectem pro zobrazení všech kolejí.
Jako další příklad si ukážeme trošku komplexnější update, který změní jména všech studentek na Brenda a před příjmení přidá slovo slečna. To, že se jedná o studentky zajistíme v podmínce WHERE pomocí subselectu, který vyhledá id pohlaví, které má název žena.
Pro smazání řádků v tabulce se používá příkaz DELETE, který má následující podobu. Nejdříve se uvede název tabulky a pak seznam řádků, které chceme smazat, definovaný pomocí podmínky WHERE. Následující příkaz smaže z tabulky predmet řádku odpovídající Astronomii (ID=8). Přesvědčte se o tom selectem pro zobrazení všech předmětů.
Nebo stejného cíle bychom dosáhli následovně
I v příkazech delete můžeme používat složitější konstrukce - například subselecty. Následující příkaz smaže všechny předměty, na které není zapsaný žádný student a nevyučuje je žádný učitel.
Zkuste například smazat učitele Brumbála z tabulky ucitel.
Když si nyní vylistujete seznam učitelů, zjistíte, že učitel s ID=2 v tabulce již není, ale v tabulce predmety na něj stále odkazuje předmět Přeměňování.
DDL (jazyk pro definování dat) definuje příkazy pro vytváření a mazání tabulek. Detaily v tomto kurzu nebudeme nijak rozebírat, pouze si ukážeme příklad pomocí kterého lze vytvořit pár tabulek našeho schématu z Bradavic.
V případě, že chceme nějakou tabulku odstranit, můžeme použít příkaz DROP.
Tady zakončíme teorii ohledně databází. Pokud rozumíte výše uvedenému textu, máte již velmi pokročilé znalosti ohledně databází a jazyka SQL. Nasbírané vědomosti se pokusíme zužitkovat v následujících příkladech.
Tento příklad funguje na sdílené serverové databázi, takže řádky, které vloží jeden student uvidí celá třída. Můžete komentáře vkládat, mazat a zároveň si je lajkovat. Vyzkoušejte si svoje znalosti na následující stránce Třídní chatovací místnost