2009-06-17 13 views
22

Kiedy w bazie danych dopuszczalne są odwołania kołowe?Czy w bazie danych dopuszczalne są okrągłe odniesienia?

Teoretyczna i praktyczna, każda pomoc jest doceniana.

+0

nawet nie będąc blisko pytania! Napisz więcej szczegółów ... –

+0

Jakie jest twoje pytanie? – Macarse

+0

Kołowe odniesienia, nie. Odnośniki sferyczne są w porządku. Zachęca cię do tego. – fig

Odpowiedz

11

Rejestry wskazujące na inne zapisy są przydatne w bazie danych. Czasami te zapisy tworzą cykl. To może być przydatne. Jedyną prawdziwą irytacją w praktyce jest unikanie naruszania ograniczeń.

Na przykład, jeśli masz tabelę użytkownika i transakcji, użytkownik może mieć wskaźnik do swojej ostatniej transakcji. Najpierw należy wprowadzić transakcję, a następnie zaktualizować last_transaction_id do poprawnej wartości. Chociaż oba te rekordy istnieją, nie można ich usunąć, ponieważ user.last_transaction_id wskazuje na transaction.id i transaction.user_id wskazuje na user.id. Oznacza to, że użytkownik bez transakcji ma wartość null last_transaction_id. Oznacza to również, że musisz usunąć to pole, zanim będziesz mógł usunąć transakcję.

Zarządzanie tymi ograniczeniami klucza obcego to ból, ale na pewno jest to możliwe.Mogą pojawić się problemy, jeśli później dodamy ograniczenia do bazy danych, które wprowadzają nowe zależności cykliczne. Musisz być ostrożny w tej sytuacji. Jednak dopóki jeden z zapisów w cyklu ma pole zerowe klucza obcego, cykl może zostać przerwany, a rekordy mogą zostać usunięte. Aktualizacje zwykle nie stanowią problemu, o ile wstawisz rekordy w odpowiedniej kolejności.

1

Należy unikać okrężnych odniesień, takich jak dżuma. Możliwe jest ustanowienie dwukierunkowych relacji, a nawet relacji z samym sobą (jeśli byłaby to tabela), ale zależność cykliczna polega jedynie na kłopotach.

+0

co masz na myśli przez dwukierunkową relację? zanotować punkty do B i C? W przeciwieństwie do punktów A do punktów B i B do A? drugi jest zdecydowanie okrągły. –

1

Widziałem okrągłe odniesienia wykonane ze względu na wydajność. Wygląda jednak paskudnie, a wydajność może być znikoma.

Przykład: niektóre tablice ogłoszeń (uważam, że phpBB to robi) mają ostatnią pozycję w tabeli kategorii, która jest skrótem do ostatniego posta w wątku.

Spowoduje to utworzenie okręgu, w którym ostatni wpis ma FK do tabeli kategorii, a tabela kategorii ma FK z powrotem do ostatniego wpisu.

Tak jak powiedziałem, nie bardzo to lubię, ale widziałem, jak to się stało.

0

rzadko i biegną w stosunku 1: 1, relacji, które są niezbędne i nakłada okrągłym związkowi

wiadomości, że zagraniczne klucz pola w takiej relacji musi być pustych, w przeciwnym razie nigdy nie można usunąć wiersze z tabel

0

Domyślam się, że to nie problem, jeśli używasz bazy danych tylko do zapisu. Jeśli planujesz używać części CRUD z RUD, prawdopodobnie napotkasz (zazwyczaj można uniknąć) skomplikowane problemy w radzeniu sobie z nimi.

3

Jest to technicznie możliwe, ale może powodować różnego rodzaju problemy podczas usuwania zapisów, ponieważ generuje problemy z kurczakiem i jajkiem. Te problemy często wymagają drastycznych działań, takich jak ręczne upuszczenie plików FK i usunięcie przedmiotów, które mogą zostać rozwiązane.

Jeśli masz relacje jak:

create table foo_master (
     foo_master_id int not null primary key 
     ,current_foo_id int 
) 


create table foo_detail (
     foo_detail_id int not null primary key 
     foo_master_id int not null 
) 

alter table foo_master 
    add constraint fk_foo_current_detail 
     foreign key (current_foo_id) 
     references foo_detail 

alter table foo_detail 
    add constraint fk_foo_master 
     foreign key (foo_master_id) 
     references foo_master 

Następnie usunięcie rekordu może powodować taki problem z kurczaka-and-AGG ze względu na wzajemnie od siebie zależnych.

Lepszym schematu na to wygląda:

create table foo_master (
     foo_master_id int not null primary key 
) 


create table foo_detail (
     foo_detail_id int not null primary key 
     foo_master_id int not null 
     is_current char (1) 
) 

alter table foo_detail 
    add constraint fk_foo_master 
     foreign key (foo_master_id) 
     references foo_master 

Oznacza to, że związek nie jest cykliczna i „prąd” rekord foo_detail może być jeszcze zidentyfikowane.

3

Jeden z najnowszych dodatków do hierarchicznej składni zapytania Oracle - słowo kluczowe NOCYCLE - został napisany specjalnie w tym celu - aby zajmować się odwołaniami cyklicznymi w danych. Nie widzę w tym nic złego i wcześniej musiałem sobie z tym poradzić. Nie jest to zbyt trudne, szczególnie w Oracle, który obsługuje odraczające ograniczenia.

20

Rozważ miasta i stany. Każde miasto istnieje w państwie. Każde państwo ma stolicę.

CREATE TABLE city (
    city VARCHAR(32), 
    state VARCHAR(32), 
    PRIMARY KEY (city), 
    FOREIGN KEY (state) REFERENCES state (state) 
); 

CREATE TABLE state (
    state VARCHAR(32), 
    captial_city VARCHAR(32), 
    PRIMARY KEY (state), 
    FOREIGN KEY (captial_city) REFERENCES city (city) 
); 

Pierwszy problem - Nie można utworzyć tych tabel, jak pokazano. Rozwiązaniem jest utworzenie ich bez obcych kluczy, a następnie dodanie obcych kluczy.

Drugi problem - nie można wstawiać wierszy do żadnej z tabel, ponieważ każda wstawka będzie wymagać wcześniejszego wiersza w drugiej tabeli. Rozwiązaniem jest ustawienie jednej z kolumn klucza obcego na wartość NULL i wstawienie tych danych w dwóch fazach. na przykład

INSERT INTO city (city, state) VALUES ('Miami', NULL); 
INSERT INTO state (state, capital_city) VALUES ('Florida', 'Miami'); 
UPDATE city SET state='Florida' WHERE city='Miami'; 
+0

Dzięki. Dobry przykład. Serwer SQL podaje błąd w odniesieniu do tego okrągłego klawisza refreignowania "FK__city__state__007EABC" odwołuje się do niepoprawnej tabeli "state". Nie można utworzyć ograniczenia. Zobacz poprzednie błędy. – Steam

+0

Inne możliwości wstawiania wierszy bez dopuszczania wartości NULL: 1. WSTAW WSZYSTKO, 2. Wiązania z możliwością zwężenia. Również podczas usuwania: 3. DELESE CASCADE – Falco

+1

@Falco Czy możesz wskazać na (działający) przykład użycia INSERT ALL z okrągłym FK? –

Powiązane problemy