5.1
Integrita dat
Požadavek integrity dat v databázi (jejich souladu se zobrazovaným světem objektů) vede k nutnosti definovat pro domény atributů jednotlivých relačních schémat a jejich vzájemné vztahy jistá omezení, která zabraňují možnostem atributů nabývat nereálných hodnot. Tato omezení se formulují pomocí soustavy uzavřených logických formulí v jazyce predikátové logiky. Pro relační báze dat je kromě skutečnosti, že entity i vztahy se reprezentují stejným způsobem, tj. pomocí relací, charakteristickým rysem i to, že splňují tři pravidla integrity.
Prvním z těchto pravidel je pravidlo entitní integrity pro relační báze dat a spočívá v požadavku, aby primární klíč relace měl pro všechny její prvky (n-tice) svou hodnotu.
Druhé pravidlo integrity je doménová integrita, která požaduje, aby hodnoty atributů odpovídaly předem definovaným doménám (množinám hodnot atributů).
Třetí je pravidlo referenční integrity (vztahové), které se týká možností používání "cizích" klíčů relací a spočívá v požadavku, aby ke každé definované hodnotě cizího klíče existoval odpovídající prvek nadřazené (nezávislé) relace.
Jednou z podstatných výhod SŘBD je ta skutečnost, že uživatel se nemusí starat o to, jak jsou integritní omezení kontrolována. Kontrola IO je plně v kompetenci SŘBD. Uživatel (správce databáze) má povinnost integritní omezení správně definovat. Při všech aktualizačních operacích, u kterých by mohlo dojít k narušení integrity, jsou pak tato omezení automaticky kontrolována systémem řízení báze dat.
Doménové integritní omezení je především definováno přiřazením datových typů pro jednotlivé atributy a dále podmínek platnosti, které musí hodnoty atributů splňovat. Cílem je zajistit, aby sloupce obsahovaly pouze logicky správné údaje. Například pro sloupec tabulky uvádějící hodnocení v procentech můžeme požadovat pouze hodnoty od 0 do 100. Naší snahou je proto zajistit, aby se čísla nad sto do této tabulky nedostala. Řešením je využít klauzule CHECK v příkazu CREATE TABLE. U výčtových typů použijeme deklaraci ENUM. Výraz v části CHECK může obsahovat i poměrně složité výrazy.
Příklad
CREATE TABLE platy
(
jmeno VARCHAR(50),
hodin INTEGER,
CHECK hodin < 45)
);
Tato konstrukce zajistí, že nelze vložit takové hodnoty, jejichž výsledkem by byl počet odpracovaných hodin přesahujících nebo rovno 45.
Entitní integritní omezení je definováno primárním klíčem. Primární klíč zajišťuje entitní IO. Proto je naprosto nutné, aby každá relace měla primární klíč.
K definování referenční integrity slouží primární klíč nezávislé entity a cizí klíč závislé entity. Nadefinováním cizího klíče je vytvořeno referenční IO. Systém řízení báze dat se bude při aktualizačních operacích starat o to, zda hodnota cizího klíče je správná.
Podmínky kladené na cizí klíč:
- Cizí klíč a primární klíč se musí skládat ze stejného počtu atributů.
- Pokud primární klíč nezávislého entitního typu slouží k definování vztahu, musí být na tento primární klíč vytvořen unikátní index.
- Atributy musí být definovány nad stejnými doménami a jejich pořadí musí být stejné.
- Závislý entitní typ může mít více cizích klíčů a tím i odkazy na více entit.
- Cizí klíč může nabývat hodnoty NULL, pokud definuje existenční typ vztahu.
- Cizí klíč nesmí nabývat hodnoty NULL, pokud definuje identifikační typ vztahu.
- Cizí klíč nabývá hodnoty NULL, pokud aspoň jedna jeho složka nabývá hodnoty NULL.
Pro nezávislé entitní typy je referenční integrita hlídána u operací DELETE a UPDATE. Pro závislé entitní typy je hlídána operace INSERT a UPDATE.
Požadavek integrity znamená zajistit správnost a konzistenci uložených dat. Budeme-li se držet teorie relačních databází, tak ji musíme zajistit na úrovni systému řízení databáze, nikoli na úrovni aplikace. První přístup spočívá v zajištění konzistentnosti dat bez ohledu na to, kdo a jak k nim přistupuje. Druhý přístup spočívá v důsledném sledování vkládaných dat na úrovni aplikace a klade vyšší nároky na programátora. Rozlišujeme v zásadě tři typy integrity: doménovou, entitní a referenční.
Referenční integrita je velmi důležitým integritním omezením. V relaci je atribut (resp. skupina atributů) vybrána za cizí klíč, což znamená, že musí odpovídat primárnímu klíči nějaké jiné relace. Referenční integrita se týká vztahů dvou a více vzájemně provázaných tabulek. Představme si situaci, kdy máme v jedné tabulce seznam zaměstnanců a v jiné tabulce seznam služebních aut. Nebylo by moudré dávat tyto údaje do jedné tabulky, protože sloupce s údaji o autě by tak byly i u zaměstnanců, kteří auto nemají. Proto oddělujeme osobní data pracovníků od technických parametrů aut a spojujeme je vztahem přidělení automobilu.
Jistě vás napadne, co se stane, když se pokusíme smazat záznam o zaměstnanci, který je ovšem zanesen v tabulce přidělených automobilů. Stejně tak je otázkou, jak se postavit k situaci změny v odkazované tabulce. Náš příklad změny jména není reálný, ale jistě jsou situace, kdy i operace UPDATE může působit problémy. Právě toto chování lze nastavovat dalšími parametry a to pomocí restriktivního řešení, kaskádovitého řešení nebo Nullify řešení.
Restriktivní řešení popsaného problému spočívá v tom, že databázový systém prostě nedovolí smazat zaměstnance, pokud mu je přiděleno auto. Tento způsob přináší větší nároky na programátora či uživatele, protože je nejprve nutné upravit záznam v tabulce aut a pak teprve mazat. Restriktivní řešení je defaultní, takže je použito, pokud neuvedeme jiné.
Tento princip přináší kaskádové změny. Tedy je-li smazán či upraven záznam v tabulce osob, pak jsou smazány či upraveny příslušné řádky tabulky. Syntakticky to SQL řeší připsáním ON DELETE CASCADE případně ON UPDATE CASCADE za definici reference.
Tato možnost spočívá v nastavení odkazovaných řádků závislé tabulky na NULL, tedy neurčenou hodnotu. Pokud bychom tedy vymazali zaměstnance a ten měl přidělen automobil, pak se u tohoto vozu nastaví vlastník na neurčenou hodnotu. To se nám velice hodí, protože tak to většinou ve skutečnosti funguje. Pro úpravy záznamu to pro nás ale vhodné není. Tento typ řešení realizujeme připsáním ON DELETE SET NULL či ON UPDATE SET NULL.