Mam tabelę, która przechowuje dane, a jeden z tych wierszy musi istnieć w innej tabeli. Dlatego chcę, aby klucz obcy zachował integralność referencyjną.
CREATE TABLE table1
(
ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
AnotherID INT NOT NULL,
SomeData VARCHAR(100) NOT NULL
)
CREATE TABLE table2
(
ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
AnotherID INT NOT NULL,
MoreData VARCHAR(30) NOT NULL,
CONSTRAINT fk_table2_table1 FOREIGN KEY (AnotherID) REFERENCES table1 (AnotherID)
)
Jednak, jak widać, tabela, do której mam klucz obcy, nie jest kolumną PK. Czy istnieje sposób na utworzenie tego klucza obcego, czy może lepszy sposób na zachowanie tej referencyjnej integralności?
sql
sql-server
Craig
źródło
źródło
table1.ID
?Odpowiedzi:
Jeśli naprawdę chcesz utworzyć klucz obcy dla klucza innego niż podstawowy, MUSI to być kolumna z unikalnym ograniczeniem.
Z Books Online :
Więc w twoim przypadku, jeśli stworzysz
AnotherID
unikalny, będzie to dozwolone. Jeśli nie możesz zastosować unikalnego ograniczenia, nie masz szczęścia, ale to naprawdę ma sens, jeśli się nad tym zastanowić.Chociaż, jak już wspomniano, jeśli masz doskonale dobry klucz podstawowy jako klucz kandydujący, dlaczego nie użyć go?
źródło
Jak zauważyli inni, idealnie byłoby, gdyby klucz obcy został utworzony jako odniesienie do klucza podstawowego (zwykle kolumny TOŻSAMOŚĆ). Jednak nie żyjemy w idealnym świecie i czasami nawet „mała” zmiana w schemacie może mieć znaczący wpływ na logikę aplikacji.
Rozważmy przypadek tabeli Customer z kolumną SSN (i głupim kluczem podstawowym) oraz tabeli Claim, która zawiera również kolumnę SSN (wypełniona logiką biznesową z danych klienta, ale nie istnieje FK). Projekt jest wadliwy, ale był używany przez kilka lat, a na schemacie zbudowano trzy różne aplikacje. Powinno być oczywiste, że wyrzucenie Claim.SSN i nawiązanie prawdziwej relacji PK-FK byłoby idealne, ale byłoby też znaczącym remontem. Z drugiej strony nałożenie UNIQUE ograniczenia na Customer.SSN i dodanie FK na Claim.SSN może zapewnić integralność referencyjną, z niewielkim lub żadnym wpływem na aplikacje.
Nie zrozum mnie źle, jestem za normalizacją, ale czasami pragmatyzm wygrywa z idealizmem. Jeśli przeciętnemu projektowi można pomóc za pomocą opaski, można uniknąć operacji.
źródło
Nekromancja.
Zakładam, że kiedy ktoś tu ląduje, potrzebuje klucza obcego do kolumny w tabeli zawierającej klucze nieunikalne.
Problem polega na tym, że jeśli masz ten problem, schemat bazy danych jest zdenormalizowany.
Na przykład przechowujesz pokoje w tabeli z kluczem podstawowym identyfikatora pokoju, polem DateFrom i DateTo oraz innym uid, tutaj RM_ApertureID, aby śledzić ten sam pokój, i polem do usuwania nietrwałego, takiego jak RM_Status, gdzie 99 oznacza „usunięte”, a <> 99 oznacza „aktywne”.
Więc kiedy tworzysz pierwsze pomieszczenie, wstaw RM_UID i RM_ApertureID jako te same wartości co RM_UID. Następnie, gdy zamkniesz pokój na określoną datę i ustawisz go ponownie z nowym zakresem dat, RM_UID to newid (), a RM_ApertureID z poprzedniego wpisu stanie się nowym RM_ApertureID.
Więc jeśli tak jest, RM_ApertureID jest polem nieunikalnym, więc nie możesz ustawić klucza obcego w innej tabeli.
I nie ma możliwości ustawienia klucza obcego na nieunikalną kolumnę / indeks, np. W T_ZO_REM_AP_Raum_Reinigung (gdzie RM_UID to faktycznie RM_ApertureID).
Ale aby zabronić nieprawidłowych wartości, musisz ustawić klucz obcy, w przeciwnym razie raczej prędzej niż później wynikiem będzie śmieci danych ...
Teraz, co możesz zrobić w tym przypadku (oprócz przepisania całej aplikacji), to wstawienie ograniczenia CHECK z funkcją skalarną sprawdzającą obecność klucza:
źródło
Klucze podstawowe zawsze muszą być unikalne, klucze obce muszą zezwalać na wartości nieunikalne, jeśli tabela jest relacją jeden do wielu. Użycie klucza obcego jako klucza podstawowego jest w porządku, jeśli tabela jest połączona relacją jeden do jednego, a nie relacją jeden do wielu.
Ograniczenie FOREIGN KEY nie musi być połączone tylko z ograniczeniem PRIMARY KEY w innej tabeli; można go również zdefiniować jako odniesienie do kolumn ograniczenia UNIQUE w innej tabeli.
źródło