Klucz obcy to łącze między dwiema tabelami, które jest używane do wymuszania integralności referencyjnej w bazie danych. Zaufane klucze zapewniają, że dane w bazie danych pozostają „czyste” i logiczne.

Tworząc zaufane klucze obce w SQL Server między tabelami, optymalizator jest w stanie przyjąć pewne założenia dotyczące danych, a tym samym opracować bardziej wydajne plany wykonania zapytań.

Utworzone klucze obce są domyślnie zaufane, ponieważ sprawdzane są wszystkie dane. Jeśli dane nie są zgodne z oczekiwaniami, przekazywane są błędy i klucz nie jest tworzony. Po utworzeniu klucze zapobiegną wprowadzaniu „złych” danych do bazy danych, o ile pozostaną one zaufane.

Niezaufany klucz obcy to taki, dla którego usunięto referencyjną integralność relacji. SQL Server nie może „ufać”, że dane w obu tabelach są czyste i dlatego nie jest pewien, jaki jest najlepszy sposób postępowania. Może to zacząć się objawiać, gdy zapytania stają się wolniejsze, gdy optymalizator zaczyna wykonywać dodatkowe testy, aby upewnić się, że dane, które otrzymuje, są dobre.

Klucze obce są ważne w relacyjnych bazach danych, ponieważ sprawdzają i pomagają wymusić referencyjną integralność danych. Bardzo często w naszej relacyjnej bazie danych zdarza się wyłączyć na chwilę klucze obce, które mogą przeszkadzać podczas ładowania dużej ilości danych. Następnie je włączamy …. no ale …..może się zdarzyć taka sytuacja gdzie klucze obce stają się niezaufane, gdy nie zostaną ponownie poprawnie włączone po zakończeniu ładowania dużej ilości danych.

Zwykle klucz obcy jest ponownie włączany za pomocą opcji CHECK CONSTRAINT w instrukcji ALTER TABLE . Ponowne włączenie klucza obcego jest w porządku, ale nie nakazuje SQL Server ponownej weryfikacji integralności danych !!!

SQL Server nie będzie wiedział, czy relacja nadal jest godna zaufania i czy dane między dwiema tabelami są „czyste”. Powoduje to, że optymalizator SQL Server ignoruje ograniczenie klucza obcego i sprawdza samą integralność danych z dodatkowymi procesami dodanymi do planu wykonania zapytania.

W związku z tym należy najpierw zidentyfikować te klucze, które nie są już zaufane. Poniższy kod pozwoli zidentyfikować schemat, obiekt i nazwę kluczy, które są włączone ale nie są zaufane w Twojej bazie danych. Wyświetli on instrukcje ALTER TABLE, dzięki czemu możesz ją skopiować i wykonać.

SELECT  'ALTER TABLE [' + s.name + '].[' + o.name + '] WITH CHECK CHECK CONSTRAINT [' + i.name + ']' AS keyname
FROM    sys.foreign_keys i
        INNER JOIN sys.objects o ON i.parent_object_id = o.object_id
        INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
WHERE   i.is_not_trusted = 1
        AND i.is_not_for_replication = 0
        AND i.is_disabled = 0

A teraz kilka słów wyjaśnienia co do poniższej kontrukcji:

ALTER TABLE <s.name from results>.<o.name from results> 
WITH CHECK CHECK CONSTRAINT <i.name from results>

Polecenie CHECK CHECK w składni wydaje się dziwne, ale wynika to po prostu z wyrównania 2 różnych opcji z instrukcją alter table.

Pierwszą z nich jest instrukcja WITH CHECK . To mówi instrukcji ALTER , aby sprawdzić poprawność zawartości tabeli względem klucza obcego. Domyślnie podczas ponownego włączania istniejącego klucza obcego lub ograniczenia jest to ustawione na WITH NOCHECK . Musisz jawnie zdefiniować to podczas ponownego włączania klucza obcego lub ograniczenia.

Drugą jest instrukcja CHECK CONSTRAINT . Służy do konfigurowania, czy ograniczenie jest włączone, czy wyłączone. CHECK CONSTRAINT jest włączone, a NOCHECK CONSTRAINT wyłącza klucz obcy.


Dariusz Brejnak

Od prawie trzydziestu lat jest pasjonatem informatyki, a zwłaszcza dziedzin dotyczących baz danych, hurtowni danych oraz ogólnie rozumianej tematyki BI. Jego druga pasja to fotografia http://dariuszbrejnak.pl