Czy dopuszczalne jest okrągłe odniesienie między dwiema tabelami w polu klucza obcego?
Jeśli nie, jak można uniknąć takich sytuacji?
Jeśli tak, w jaki sposób można wstawić dane?
Poniżej znajduje się przykład, w którym (moim zdaniem) dopuszczalne byłoby użycie okólnika:
CREATE TABLE Account
(
ID INT PRIMARY KEY IDENTITY,
Name VARCHAR(50)
)
CREATE TABLE Contact
(
ID INT PRIMARY KEY IDENTITY,
Name VARCHAR(50),
AccountID INT FOREIGN KEY REFERENCES Account(ID)
)
ALTER TABLE Account ADD PrimaryContactID INT FOREIGN KEY REFERENCES Contact(ID)
database-design
foreign-key
rdbms
KidCode
źródło
źródło
Odpowiedzi:
Ponieważ używasz pól zerowalnych dla kluczy obcych, możesz w rzeczywistości zbudować system, który działa poprawnie tak, jak go sobie wyobrażasz. Aby wstawić wiersze do tabeli Konta, musisz mieć wiersz w tabeli Kontakty, chyba że zezwalasz na wstawianie do kont z zerowym PrimaryContactID. Aby utworzyć wiersz kontaktu bez obecnego wiersza konta, musisz zezwolić, aby kolumna AccountID w tabeli Kontakty miała wartość null. Dzięki temu Konta nie mają kontaktów, a Kontakty nie mają konta. Być może jest to pożądane, a może nie.
Powiedziawszy to, moim osobistym wyborem będzie mieć następującą konfigurację:
Zapewnia to możliwość:
IX_AccountsContactsXRef_Primary
indeksu. Ten indeks zawiera filtr, więc będzie działał tylko na platformach, które je obsługują. Ponieważ ten indeks jest określony zUNIQUE
opcją, dla każdego konta może istnieć tylko jeden główny kontakt.Na przykład, jeśli chcesz wyświetlić listę wszystkich kontaktów z kolumną oznaczającą status „podstawowy”, pokazującą główne kontakty na górze listy dla każdego konta, możesz:
Filtrowany indeks zapobiega wstawianiu więcej niż jednego głównego kontaktu na konto, a jednocześnie zapewnia szybką metodę zwrotu listy głównych kontaktów. Można łatwo wyobrazić sobie inną kolumnę
IsActive
z nieunikalnym przefiltrowanym indeksem do przechowywania historii kontaktów na konto, nawet jeśli kontakt nie jest już powiązany z kontem:źródło
Nie, niedopuszczalne są okrągłe odwołania do kluczy obcych. Nie tylko dlatego, że wstawianie danych byłoby niemożliwe bez ciągłego upuszczania i odtwarzania ograniczeń. ale ponieważ jest to zasadniczo wadliwy model dowolnej dziedziny, o której mogę myśleć. W twoim przykładzie nie mogę wymyślić żadnej domeny, w której relacja między kontem a kontaktem nie jest NN, wymagająca tabeli połączeń z referencjami FK z powrotem do konta i kontaktu.
źródło
Twój obiekt zewnętrzny może wskazywać na główny kontakt, a nie na konto. Twoje dane wyglądałyby tak:
źródło