Jak zaprojektować tę bazę danych, aby uniknąć cyklicznej zależności?

12

Istnieją dwie tabele:

  1. Użytkownik
  2. Adres

Użytkownik zawiera odniesienie do adresu.

Adres zawiera kolumny CreatedBy i ModifiedBy, które są odniesieniem do użytkownika.

Jak zaprojektować tę bazę danych, aby uniknąć cyklicznej zależności?

Shashi
źródło
4
Czy jesteś pewien, że ModifiedBy nie jest odniesieniem do użytkownika bazy danych, który dokonał zmiany, a nie do użytkownika aplikacji (który znajduje się w tabeli użytkowników)? Tak czy inaczej, to naprawdę nie ma znaczenia. Nie rozumiem, dlaczego istnieje rzeczywisty problem?
Philᵀᴹ
Który stworzy pierwszy. As CreatedBy ANd Modifiedby to dane obowiązkowe. A tabela użytkowników nie powinna mieć adresuID jako zerowego. Problem z jajkiem kurzym. Gdy rozwiązuję ten problem, tworzę nową tabelę UserAddress, która zawiera odniesienie do identyfikatora użytkownika i adresu
Shashi
2
Zawsze możesz użyć odroczonych ograniczeń, jeśli DBMS je obsługuje.
Colin 't Hart
Uwaga: Model relacyjny obsługuje robienie dwóch wstawek lub aktualizacji w ramach jednej operacji atomowej, szkoda, że ​​nie jest to obsługiwane w SQL (ponieważ odroczone ograniczenia - nawet jeśli je zasugerowałem - są dość okropne).
Colin 't Hart

Odpowiedzi:

7

Zamiast szukać wskazówek i sztuczek (w tym odroczonych ograniczeń) sugerowałbym, aby po prostu zaprojektować wyjście z tej „blokady referencyjnej” - spróbuj więc czegoś takiego:


Fakty

  • Użytkownik(UserID) istnieje.
  • Adres(AddressID) został utworzony przez użytkownika(UserID) .
  • Adres(AddressID) został stworzony na Date(DateCreated) .
  • Adres(AddressID) był ostatnio modyfikowany przez użytkownika(UserID) na Date(ModifiedOn) .
  • Użytkownik(UserID) przebywa pod adresem(AddressID) od daty(ValidFrom) .

Ograniczenia

  • Each Adres został utworzony przez exactly one użytkownika . It is possible that more than one Adres został utworzony przez the same użytkownika .

  • Each Adres został stworzony na exactly one Date . It is possible that more than one Adres został stworzony na the same Date .

  • For each Adres and Data , that adres został zmodyfikowany przez at most one użytkownika na that Date .

  • For each User and Data , that Instrukcja mieszka at most one Adres od that Date .


Logiczny

wprowadź opis zdjęcia tutaj


Jeśli chodzi o adres obowiązkowy, sprawdź, czy na warstwie aplikacji i zawiń instrukcje ładowania w transakcji - w ten sposób otrzymasz wszystko lub nic.

Damir Sudarevic
źródło
5

Nie masz wyboru, ale musisz utworzyć zależność cykliczną w 2 operacjach, jak poniżej, ponieważ jedna tabela nie istnieje podczas tworzenia pierwszej.

CREATE TABLE A (A_ID INT PRIMARY KEY, B_FK INT);
CREATE TABLE B (B_ID INT PRIMARY KEY, A_FK INT REFERENCES A(A_ID));

ALTER TABLE A ADD B_FK INT;

Jeśli chcesz uniknąć cyklicznej zależności. Następnie musisz usunąć jedno ograniczenie ODNIESIENIA lub możesz dodać odwołanie KASUJ i AKTUALIZUJ w jeden sposób. Możesz również zaimplementować TRIGGER, jeśli twoja logika jest nieco złożona.

PollusB
źródło
1
Usunięcie więzów usuwa cykliczną zależność z definicji, ale nie z projektu. Możesz dodać tabelę Zdarzenia, aby zarejestrować UserID i AddressID, który ostatnio utworzył lub zmodyfikował adres, ale to tylko przesuwa zależność o krok dalej. Idąc w drugą stronę, gdyby tabela użytkowników zawierała kolumny CreatedBy i ModifiedBy, zależność cykliczna istniałaby w jednej tabeli. Jest to podobne do tabeli pracowników z kolumną przełożonego, w której przełożony jest również pracownikiem. Jak wskazał Phil - Nie ma problemu.
Leigh Riffel
@LeighRiffel Zgadzam się. Ale zaproponowana przez ciebie tabela Zdarzenia faktycznie usuwa wszystkie cykliczne zależności.
ypercubeᵀᴹ
@ypercube Rzeczywiście tak; nie jestem pewien, w jaki sposób udało mi się to skrzyżować. Żeby było jasne, prawdopodobnie nie powinieneś tworzyć tabeli Zdarzenia, nawet jeśli usuwa ona cykliczną zależność.
Leigh Riffel
W każdym razie nie sądzę, że ta odpowiedź rozwiązuje problem. Pytanie (jak sądzę) dotyczy w ogóle tego, jak w ogóle uniknąć ścieżki cyklicznej, a nie jak stworzyć FK za pomocą ścieżki cyklicznej.
ypercubeᵀᴹ