V SQL Server je omezení cizího klíče (a CHECK
omezení) může být důvěryhodné nebo nedůvěryhodné.
Když je omezení důvěryhodné, znamená to, že omezení bylo ověřeno systémem. Když to není důvěryhodné, omezení není byla ověřena systémem.
V zásadě, když máte nedůvěryhodné omezení, můžete mít ve své databázi také neplatná data. Tím chci říct, že byste mohli mít data, která porušují omezení.
To znamená, že již neudržujete referenční integritu ve svých vztazích, což při péči o relační databázi ve výrobě obvykle není dobrou praxí.
V tomto článku zkontroluji svá stávající omezení z hlediska jejich „důvěryhodnosti“ a poté je aktualizuji, aby se opět staly důvěryhodnými.
Příklad 1 – Kontrola existujících omezení
Zda je omezení důvěryhodné nebo ne, můžete zjistit dotazem na sys.foreign_keys
systémový pohled.
Takhle:
SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys;
Výsledek:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 1 | 1 | | FK_Albums_Genres | 0 | 1 | +-------------------+---------------+------------------+
Dobře, takže to mi říká, že mám dvě omezení cizího klíče a obě jsou nedůvěryhodná.
Jedno z omezení je zakázáno, takže dává smysl, že není důvěryhodné (špatná data se mohou dostat do databáze, kdykoli je omezení zakázáno).
Ale další omezení je povoleno, takže by opravdu nemělo být nedůvěryhodné. Být nedůvěryhodný znamená, že v databázi mohou být neplatná data. Neznamená to, že existuje neplatná data, právě to tam mohlo být.
V zásadě tím, že je povolen, bude kontrolovat budoucí data, ale nemůže ručit za existující data. Pokud je omezení důvěryhodné, můžete si být jisti, že všechna existující data jsou platná.
Vrátit pouze nedůvěryhodná omezení
Možná zjistíte, že dáváte přednost použití WHERE
klauzule vrátit pouze nedůvěryhodná omezení. Takhle:
SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys WHERE is_not_trusted = 1;
Výsledek:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 1 | 1 | | FK_Albums_Genres | 0 | 1 | +-------------------+---------------+------------------+
Takže v tomto případě je výsledek stejný (protože všechna aktuální omezení jsou nedůvěryhodná).
Příklad 2 – Obnovení důvěry
Chcete-li obnovit důvěryhodnost vašeho povoleného omezení, jednoduše jej znovu povolte pomocí WITH CHECK
možnost.
Takhle:
ALTER TABLE Albums WITH CHECK CHECK CONSTRAINT FK_Albums_Genres;
Nyní, když se dotazujeme na sys.foreign_keys
dostaneme jiný výsledek:
SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys;
Výsledek:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 1 | 1 | | FK_Albums_Genres | 0 | 0 | +-------------------+---------------+------------------+
Vidíme, že omezení je nyní důvěryhodné, protože is_not_trusted
příznak je nastaven na 0
.
Příklad 3 – Jak se omezení stalo nedůvěryhodným?
Když zakážete omezení cizího klíče, automaticky se stane nedůvěryhodným. Když znovu povolíte stejné omezení, máte příležitost obnovit jeho důvěru. Pokud to neuděláte, zůstane nedůvěryhodný.
Když povolíte omezení cizího klíče, máte možnost zadat WITH CHECK
nebo WITH NOCHECK
. Pokud zadáte pozdější, vaše omezení zůstane nedůvěryhodné, jakmile bude povoleno.
Je důležité si uvědomit, že WITH NOCHECK
je výchozí možnost, takže pokud výslovně neurčíte, že by mělo být důvěryhodné, omezení bude povoleno jako nedůvěryhodné.
Je to však naopak, když vytvoříte omezení cizího klíče. Když poprvé vytvoříte omezení, výchozí možnost je WITH CHECK
. Pokud tedy toto nastavení vynecháte, bude ve výchozím nastavení důvěryhodné (pokud nemáte neplatná data, v takovém případě nebude povoleno). Toto nastavení však můžete přepsat explicitním zadáním WITH NOCHECK
když vytvoříte omezení.
Abych ukázal, jak mohou vaše povolená omezení snadno zůstat nedůvěryhodná, znovu povolím druhý klíč (ten deaktivovaný), ale použiji výchozí nastavení:
ALTER TABLE Albums CHECK CONSTRAINT FK_Albums_Artists; SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys;
Výsledek:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 0 | 1 | | FK_Albums_Genres | 0 | 0 | +-------------------+---------------+------------------+
Takže tím, že budete líní (nebo zapomnětliví) a výslovně neuvedete WITH CHECK
, úspěšně se mi podařilo povolit omezení a zároveň zachovat jeho stav „nedůvěryhodný“ nedotčený.
Klíčové z toho plyne:pokud chcete, aby vaše znovu povolená omezení byla důvěryhodná, měli byste je vždy povolit pomocí WITH CHECK
.