27.08.2013, Vladimír Klaus, navštíveno 10995x
Za termínem referenční integrita se skrývá speciální nastavení vztahu mezi údaji tabulek tak, aby nedošlo k porušení konzistence dat. Jednoduchým příkladem je již jinde zmíněné – mám objednávku, kterou udělal uživatel s ID = 15 a takový uživatel vůbec neexistuje. To může přinášet řadu potíží, počínaje zkreslenými statistikami, chybami v dotazech (občas bude někde NULL) až třeba k problému s objednávkou. Protože může dojít i k tomu, že na objednávce je produkt, který také již v tabulce produktů nemáme.
V databázi je tedy možné nastavit tuto integritu (omezení) a například provázat ID uživatele v tabulce Uživatelů s položkou IdUzivatele v tabulce Objednávek. My si to ukážeme na provázání ID produktu.
Příkaz se skládá z několika částí – budeme měnit tabulku Objednavky. Tam přidáme omezení pod názvem „fk_Objednavky“ a to tak, že pole IdProduktu v tabulce Objednavky bude odkazovat na pole ID v tabulce Produkty.
ALTER TABLE Objednavky
ADD CONSTRAINT fk_Objednavky
FOREIGN KEY (IdProduktu)
REFERENCES Produkty(ID)
Závislost tabulek si zobrazíte pomocí tlačítka Relace.
Pokud tam tabulky nevidíte, musíte je přidat pomocí tlačítka Zobrazit tabulku.
Takto tedy zatím vypadá propojení našich dvou tabulek, které zároveň ukazuje, že jeden produkt může být v tabulce objednávek použit vícekrát, tzv. vztah 1:m.
Pokud poklepete na spojení, objeví se další dialog, ze kterého je vidět, že byla nastavena referenční integrita.
Nyní tedy už máme integritu zajištěnu, ale jak se to projeví reálně? Při pokusu o přidání objednávky, která obsahuje neexitující IdProduktu to skončí chybou „narušení klíče“. Ale to v případě, že přidáváte záznam pomocí tohoto příkazu.
INSERT INTO Objednavky
(IdProduktu, Castka) VALUES (777, 1500)
A i když se pokusíte pokračovat v dotazu, k přidání nedoje. Pokud záznam budete přidávat ručně, objeví se trochu jiné varování.
Druhá varianta, kdy integrita zapůsobí, je pokus o odstranění nějaké již použité položky. V našem případě se pokusím odstranit produkt s ID = 2, který je použit v nějakých objednávkách, pomocí tohoto příkazu.
DELETE FROM Produkty WHERE ID=2
I zde při pokusu o pokračování dotazu k odstranění nedoje! Při ručním odstraňování se opět objeví trochu jiné hlášení.
Referenční integrity se pochopitelně můžete také zbavit. Ať už pomocí zaškrtávátka v dříve uvedeném dialogu nebo tímto příkazem.
ALTER TABLE Objednavky
DROP CONSTRAINT fk_Objednavky
Poznámka: Pokud zkopírujete tabulku Objednavky třeba do tabulky Objednavky2, tak nastavení referenční integrity se nepřenese! To pak musíte znovu nastavit i pro novou tabulku a pod jiným názvem – třeba fk_Objednavky2.
Co říci na závěr. Referenční integrita je velmi užitečná věc, ale má cenu ji nastavovat až v pokročilejší fázi projektu, kdy už třeba databáze nějaký čas běží v pilotním provozu. Během vývoje totiž může docházet k řadě změn, přejmenování nebo jiných nestandardních akcí a díky integritě by to vůbec nešlo realizovat. Jako reálný příklad mohu uvést třeba smazání uživatele, abych vyzkoušel jeho opětovné přidání apod. Pokud bych tam měl nastavenou integritu, tak mi to oznámí, že daný uživatel má na sebe navázané komentáře nebo objednávky a že ho odstranit nejde. A i když budu mít funkci na odstranění uživatele udělanou dobře (nejprve odstraním jeho komentáře a objednávky a až pak jeho), tak to třeba právě při vývoji nechci.