W SQL Server, ograniczenie klucza obcego (i CHECK
) ograniczenie) może być zaufana lub niezaufana.
Kiedy ograniczenie jest zaufane, oznacza to, że ograniczenie zostało zweryfikowane przez system. Gdy nie jest zaufane, ograniczenie nie zostały zweryfikowane przez system.
Zasadniczo, gdy masz niezaufane ograniczenie, możesz również mieć nieprawidłowe dane w swojej bazie danych. Rozumiem przez to, że możesz mieć dane, które naruszają ograniczenie.
Oznacza to, że nie zachowujesz już integralności referencyjnej w swoich relacjach, co zwykle nie jest dobrą praktyką podczas dbania o relacyjną bazę danych w środowisku produkcyjnym.
W tym artykule sprawdzę moje istniejące ograniczenia pod kątem ich „wiarygodności”, a następnie zaktualizuję je, aby ponownie stały się godne zaufania.
Przykład 1 – Sprawdź istniejące ograniczenia
Możesz dowiedzieć się, czy ograniczenie jest zaufane, czy nie, wysyłając zapytanie do sys.foreign_keys
widok systemu.
Tak:
SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys;
Wynik:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 1 | 1 | | FK_Albums_Genres | 0 | 1 | +-------------------+---------------+------------------+
OK, to mówi mi, że mam dwa ograniczenia klucza obcego i oba z nich nie są zaufane.
Jedno z ograniczeń jest wyłączone, więc ma sens, że nie jest zaufane (złe dane mogą dostać się do bazy danych, gdy ograniczenie jest wyłączone).
Ale drugie ograniczenie jest włączone, więc naprawdę nie powinno być nieufne. Brak zaufania oznacza, że w bazie danych mogą znajdować się nieprawidłowe dane. Nie oznacza to, że jest nieprawidłowe dane, tylko że może być.
Zasadniczo, po włączeniu, sprawdzi przyszłe dane, ale nie może ręczyć za istniejące dane. Jeśli ograniczenie jest zaufane, możesz być pewien, że wszystkie istniejące dane są prawidłowe.
Zwróć tylko niezaufane ograniczenia
Może się okazać, że wolisz użyć WHERE
klauzula zwracająca tylko niezaufane ograniczenia. Tak:
SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys WHERE is_not_trusted = 1;
Wynik:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 1 | 1 | | FK_Albums_Genres | 0 | 1 | +-------------------+---------------+------------------+
Więc w tym przypadku wynik jest taki sam (ponieważ wszystkie obecne ograniczenia są niezaufane).
Przykład 2 – Przywróć zaufanie
Aby przywrócić zaufanie do włączonego ograniczenia, po prostu włącz je ponownie podczas korzystania z WITH CHECK
opcja.
Tak:
ALTER TABLE Albums WITH CHECK CHECK CONSTRAINT FK_Albums_Genres;
Teraz, gdy zapytamy sys.foreign_keys
otrzymujemy inny wynik:
SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys;
Wynik:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 1 | 1 | | FK_Albums_Genres | 0 | 0 | +-------------------+---------------+------------------+
Widzimy, że ograniczenie jest teraz zaufane, ponieważ is_not_trusted
flaga jest ustawiona na 0
.
Przykład 3 – Jak Ograniczenie stało się Niezaufane?
Po wyłączeniu ograniczenia klucza obcego automatycznie staje się ono niezaufane. Po ponownym włączeniu tego samego ograniczenia masz możliwość przywrócenia jego zaufania. Jeśli tego nie zrobisz, pozostanie niezaufane.
Po włączeniu ograniczenia klucza obcego masz możliwość określenia WITH CHECK
lub WITH NOCHECK
. Jeśli określisz później, Twoje ograniczenie pozostanie niezaufane po włączeniu.
Należy pamiętać, że WITH NOCHECK
jest opcją domyślną, więc jeśli nie określisz wyraźnie, że powinno być zaufane, ograniczenie zostanie włączone jako niezaufane.
Jednak jest odwrotnie, gdy tworzysz ograniczenie klucza obcego. Kiedy tworzysz ograniczenie po raz pierwszy, domyślną opcją jest WITH CHECK
. Jeśli więc pominiesz to ustawienie, będzie ono domyślnie zaufane (chyba że masz nieprawidłowe dane, w takim przypadku nie zostanie włączone). Możesz jednak zmienić to ustawienie, jawnie określając WITH NOCHECK
kiedy tworzysz ograniczenie.
Aby zademonstrować, jak twoje włączone ograniczenia mogą łatwo pozostać niezaufane, ponownie włączę drugi klucz (wyłączony), ale użyję ustawienia domyślnego:
ALTER TABLE Albums CHECK CONSTRAINT FK_Albums_Artists; SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys;
Wynik:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 0 | 1 | | FK_Albums_Genres | 0 | 0 | +-------------------+---------------+------------------+
Więc będąc leniwym (lub zapominalskim) i nie określając jawnie WITH CHECK
, udało mi się włączyć ograniczenie, zachowując jego status „niezaufany” w stanie nienaruszonym.
Kluczowym wnioskiem z tego jest:jeśli chcesz, aby Twoje ponownie włączone ograniczenia były zaufane, zawsze powinieneś je włączać za pomocą WITH CHECK
.