Minule jsme rozebrali databázový návrh uspořádání alb a písní na
našem hudebním webu. Dnes je tedy čas něco pořádného s tím udělat
prakticky. Půjde o to, jak to celé zorganizovat a dovést ke zdárnému
konci.
Ještě lehká úvaha
Ačkoli jsme úvahou strávili celý minulý díl, ještě jednu věc bychom
si měli rozmyslet. Při zadávání a zobrazování koncertů jsme nejprve
vyřešili zadávání dat a potom jejich zobrazování na webu. V případě
diskografie to ale zkusíme opačně. Důvody jsou dva:
- Abych Vám ukázal, že to jde, jak se to od opačného postupu liší a
na co dávat pozor
- Protože diskografie zpracovává tři tabulky najednou a zobrazení
dat bude neskonale jednodušší než jejich zadávání
Tak či tak, pokud budeme chtít nejprve řešit zobrazování alb a
písní, měli bychom si nachystat nějaký vzorek dat. Takže vymyslíme
testovací data, naplníme je do databáze a pokusíme se je zobrazit.
Tvorba testovacích dat může být náročný oříšek, pokud nevíte, jak na
to. Tady je několik podnětů:
- Testovací data by měla být alespoň trochu podobná datům skutečným
(objem, rozsahy, hodnoty)
- Všechny nestadndardní situace by měly být zastoupeny (například,
jedna píseň na více albech)
- Do vzorku dat se rovněž můžete pokusit zanést chyby a sledovat,
zda a jak na to aplikace bude reagovat.
My budeme brýt v úvahu především první dvě hlediska problému - a
pořídíme si testovací data s několika alby a opakujícími se písněmi.
Pokud byste to doma chtěli testovat na stejných datech jako já, zde
najdete odpovídající příkaz pro MySQL pro tvorbu tabulek a dat.
Pozn.: Člověk je tvor líný a
vymýšlet se mi to nechtělo. Půjčil jsem
si tedy z http://music.clnet.cz/zalman/diskografie.htm diskografii existující skupiny.
Při přípravě testovacích dat obyčejně přijdete na nějaké věci, které
by se měly v návrhu databáze upravit. Tak například já jsem přišel na
to, že by bylo dobrá kontrolovat, zda jedna píseň není v tabulce písní
zbytečně dvakrát, a pořídil jsem pro sloupec nazev v tabulce písní
unikátní index.
Zobrazujeme diskografii
Při zobrazení diskografie bychom měli mít na paměti, že by měla jít
zobrazit
- buď alba, tedy jejich názvy, nebo
- alba a na každém albu písně
Pokusíme se tedy diskografii podle toho navrhnout. Pokud by soubor
diskografie.php zobrazoval pouze alba, mohl by fungovat nějak takto:
$vysledek=mysql_query("select nazev from alba",$GLOBALS["link"]);
if (mysql_num_rows($vysledek)==0)
echo "-- Není
vydáno žádné album --";
else
{
echo "<TABLE>";
while ($zaznam=MySQL_Fetch_Array($vysledek)):
?>
<TR>
<TD><?echo $zaznam["nazev"]?></TD>
</TR>
<?
endwhile;
echo "</TABLE>";
}
Pokud by měl obsahovat alba a písně, můžeme to provést například
tak, že vnoříme smyčku pro průchod písněmi do smyčky pro průchod alby.
Celá taškařice pak může vypadat nějak takto:
$vysledek=mysql_query("select id, nazev from
alba",$GLOBALS["link"]);
if (mysql_num_rows($vysledek)==0)
echo "-- Není
vydáno žádné album --";
else
{
echo "<TABLE>";
while ($zaznam=MySQL_Fetch_Array($vysledek)):
$album=$zaznam["id"];
?>
<TR>
<TD><B><?echo $zaznam["nazev"]?></B></TD>
</TR>
<?
$vysledek2=mysql_query("select nazev from pisne
join obsahyalb on pisne.id = obsahyalb.pisen where obsahyalb.album=".$album,$GLOBALS["link"]);
if (mysql_num_rows($vysledek2)==0)
echo "-- Nejsou k dispozici písně na tomto albu
--";
else
{
while ($zaznam2=MySQL_Fetch_Array($vysledek2)):
?>
<TR>
<TD><?echo $zaznam2["nazev"]?></TD>
</TR>
<?
endwhile;
}?>
<?
endwhile;
echo "</TABLE>";
}
Pozn.: Kdybych byl v zanořování kódu
důsledný, vložím do jedné tabulky (s alby) jinou tabulku (s písněmi).
Protože ale vnořené tabulky nemám rád, raději jsem pokračoval v kódu
přidáním dalšího řádku do již existující tabulky. Pochopitelně,
fantazii se meze nekladou.
Všimněte si toho vnořeného databázového dotazu. Je to poprvé, co
jsme v seriálu použili dotaz obsahující klauzuli join, takže si to
pojďme vysvětlit. Dotaz nyní vybírá data ze dvou tabulek (pisne a
obsahyalb), přičemž tyto tabulky spojuje. To je v pořádku, protože nás
nezajímají názvy všech písní, ale jen názvy písní z určitého alba.
Tabulka písní však nemá o uspořádání alb ani ponětí, to znamená, že se
musí spojit s tabulkou obsahyalb a danou informaci dohledat.
Napsat
select nazev from pisne
join obsahyalb on pisne.id = obsahyalb.pisen where obsahyalb.album=1
je tedy úplně stejné jako napsat:
select nazev from pisne,
obsahyalb where pisne.id=obsahyalb.pisen and obsahyalb.album=1
Spojení jsou ve světě relačních databází na denním pořádku, proto
byste jim měli věnovat pozornost a dobře se je naučit, zejména pokud to
s prací s daty myslíte vážně.
V dalším díle seriálu se zamyslíme na tím, jak elegantně ošetřit
volbu zobrazení a budeme pokračovat dalšími úkoly.
Změny na portálu
Na současný stav projektu se můžete na našem webu podívat
nebo si jej můžete stáhnout.
Pozn.: Aby Vám stažená verze
fungovala na lokálním stroji, upravte si hodnotu konstant SQL_HOST,
SQL_USERNAME, SQL_PASSWORD a SQL_DBNAME. Případně si je můžete včlenit
do konfiguračního souboru podobně, jako jsem to udělal v souboru
func.php.