Vztah M:N

Obchod chce hrám přidělit štítky, třeba „multiplayer“, „rodinná“ nebo „příběhová“, aby zákazníci snáz našli, co je baví. Hra může mít několik štítků a jeden štítek patří k mnoha hrám. To je vztah M:N (mnoho k mnoha), který jste poznali v lekci o spojování tabulek, a do stávajících tabulek obchodu se nevejde:

  • Sloupec stitek_id v tabulce hry pojme jen jeden štítek pro každou hru.
  • Sloupec stitky se seznamem, třeba 'multiplayer, rodinná', nejde s ničím spojit, databáze ho nemůže zkontrolovat a hledání v něm pomocí LIKE je těžkopádné a najde i to, co nemá.

Řešením je třetí, spojovací tabulka s jedním řádkem pro každou dvojici: tahle hra má tenhle štítek. Má dva cizí klíče, do každé tabulky jeden, a dvojice je jejím primárním klíčem. Protože má klíč dva sloupce, píše se za poslední sloupec: PRIMARY KEY (hra_id, stitek_id). Každá hra pak může být v mnoha řádcích a každý štítek také, ale stejná dvojice dvakrát být nemůže.

Takové tabulky už znáte. polozky spojují objednávky a hry (objednávka obsahuje mnoho her, hra je v mnoha objednávkách) a recenze spojují hry a zákazníky. Obě mají primární klíč ze dvou sloupců a obě ukazují, že spojovací tabulka může o dvojici říkat i něco dalšího: počet kusů a cenu, nebo hvězdičky a komentář.

Takhle to vypadá pro platformy, na kterých hry běží: tabulka platforem, spojovací tabulka a dotaz, který spojí všechny tři:

CREATE TABLE platformy (
    id INTEGER PRIMARY KEY,
    nazev TEXT NOT NULL UNIQUE
) STRICT;

CREATE TABLE hry_platformy (
    hra_id INTEGER NOT NULL REFERENCES hry (id),
    platforma_id INTEGER NOT NULL REFERENCES platformy (id),
    PRIMARY KEY (hra_id, platforma_id)
) STRICT;

INSERT INTO platformy (nazev)
VALUES ('PC'), ('Switch');

INSERT INTO hry_platformy (hra_id, platforma_id)
VALUES (3, 1), (3, 2), (6, 1);

SELECT h.nazev, p.nazev AS platforma
FROM hry_platformy hp
JOIN hry h ON h.id = hp.hra_id
JOIN platformy p ON p.id = hp.platforma_id
ORDER BY h.nazev, p.nazev;
nazevplatforma
Cube LogicPC
Moon FarmPC
Moon FarmSwitch

Moon Farm běží na dvou platformách, a tak má v hry_platformy dva řádky. Dotaz začíná od spojovací tabulky a každý její cizí klíč spojí s jeho tabulkou, jak jste se naučili v lekci o spojování tabulek.

Typická chyba: napsat PRIMARY KEY za oba sloupce. Vznikly by tak dva primární klíče a tabulka může mít jen jeden:

CREATE TABLE hry_platformy (
    hra_id INTEGER PRIMARY KEY,
    platforma_id INTEGER PRIMARY KEY
) STRICT;
Error on line 1: table "hry_platformy" has more than one primary key

Pokyny

Vytvořte dvě tabulky pro štítky, obě STRICT:

  • stitky se sloupci id (celočíselný primární klíč) a nazev (text, vždycky vyplněný, a žádné dva štítky se stejným názvem),
  • hry_stitky se sloupci hra_id a stitek_id, cizími klíči do hry a stitky, a primárním klíčem z obou.

Vložte štítky 'multiplayer', 'rodinná' a 'příběhová' v tomto pořadí, aby dostaly ID 1, 2 a 3. Pak hrám štítky přidělte (jejich ID najdete na kartě Tabulky): Pixel Racer a Turbo Karts dostanou štítky multiplayer a rodinná a Dragon Forge, Knight's Oath a Lost Temple štítek příběhová. Nakonec ukažte název hry a štítek každé dvojice jako sloupce nazev a stitek, seřazené podle názvu a pak podle štítku. Řádků je sedm a začínají takto:

nazevstitek
Dragon Forgepříběhová
Knight's Oathpříběhová
Lost Templepříběhová
Pixel Racermultiplayer
Pixel Racerrodinná
……

Přidejte dotaz, který ukáže, kolik her má každý štítek: sloupce stitek a pocet_her, seřazené podle počtu her od největšího a štítky se stejným počtem podle názvu:

stitekpocet_her
příběhová3
multiplayer2
rodinná2

Začněte programovat zdarma

Registrací souhlasíte s provozními podmínkami a zásadami ochrany osobních údajů.

Nebo se registrujte pomocí:

7/10