Pokud chceme sledovat vazby mezi položkami stejné tabulky (např. podobné výrobky), nejspíš za tím účelem vytvoříme dvousloupcovou tabulku vyrobky_podobne (vyrobek, podobny)
, kde oba sloupce budou směřovat na primární klíč hlavní tabulky. Vazba nemusí být symetrická, v tom případě se s tabulkou pracuje jako s běžnou vazební tabulkou a faktu, že oba sloupce ukazují do stejné tabulky, si nemusíme všímat.
Pokud má však být vazba symetrická (takže když je jeden výrobek podobný druhému, tak je také druhý podobný prvnímu), je zbytečné ukládat do tabulky obě vazby. Tento přístup ale zkomplikuje všechny dotazy do tabulky – místo vyrobek = @id
musíme psát @id IN (vyrobek, podobny)
, při vypisování nebo spojování s dalšími tabulkami se to zkomplikuje o nutnost zjišťovat, jestli je vazba ve sloupci vyrobek
nebo podobny
.
Jak z toho ven? Řešení je překvapivě jednoduché. Stačí nadefinovat pohled:
CREATE VIEW vyrobky_podobne_vsechny AS SELECT vyrobek, podobny FROM vyrobky_podobne UNION SELECT podobny, vyrobek FROM vyrobky_podobne
Data potom můžeme vybírat z tohoto pohledu, mazat je ze základní tabulky pomocí zmíněného @id IN (vyrobek, podobny)
a vkládat obvyklým způsobem.
Někdo data organizuje tak, aby v jednom sloupci byla vždy menší hodnota než ve druhém, při vytvoření pohledu to je ale zbytečná práce navíc díky čemuž se nemůže stát, že by v tabulce byla stejná vazba dvakrát. Pohled nám tyto řádky sice sjednotí do jednoho, ovšem pouze za předpokladu, že v tabulce není další sloupec s různou hodnotou v jednotlivých řádcích. Pro zajištění konzistence tedy můžeme použít trigger:
CREATE TRIGGER vyrobky_podobne_bi BEFORE INSERT ON vyrobky_podobne FOR EACH ROW SET @vyrobek = NEW.vyrobek, NEW.vyrobek = LEAST(@vyrobek, NEW.podobny), NEW.podobny = GREATEST(@vyrobek, NEW.podobny); CREATE TRIGGER vyrobky_podobne_bu BEFORE UPDATE ON vyrobky_podobne FOR EACH ROW SET @vyrobek = NEW.vyrobek, NEW.vyrobek = LEAST(@vyrobek, NEW.podobny), NEW.podobny = GREATEST(@vyrobek, NEW.podobny);
Přijďte si o tomto tématu popovídat na školení Návrh a používání MySQL databáze.
Diskuse je zrušena z důvodu spamu.