Oto prosta tabela, w której rekordy mogą odnosić się do rekordów nadrzędnych w tej samej tabeli:
CREATE TABLE foo (
id SERIAL PRIMARY KEY,
parent_id INT NULL,
num INT NOT NULL,
txt TEXT NULL,
FOREIGN KEY (parent_id) REFERENCES foo(id)
);
Z dodatkowym wymogiem, że jedna z pozostałych wartości pól ( num
) musi być identyczna między rekordami nadrzędnymi i podrzędnymi, pomyślałem, że złożony klucz obcy powinien załatwić sprawę. Zmieniłem ostatnią linię na
FOREIGN KEY (parent_id, num) REFERENCES foo(id, num)
i dostał BŁĄD: nie ma unikalnego ograniczenia pasującego do podanych kluczy dla tabeli, do której istnieje odniesienie „foo” .
Mogę z łatwością dodać to ograniczenie, ale nie rozumiem, dlaczego jest to konieczne, skoro jedna z kolumn, do których istnieją odniesienia ( id
), jest już gwarantowana jako niepowtarzalna? Z mojego punktu widzenia nowe ograniczenie byłoby zbędne.
NULL != NULL
. W każdym razie .. :)UNIQUE INDEX
gdzie są kolumnyNULLABLE
... dlatego o tym wspomniałem. :) Ale zgadzam się - w przypadku, gdy nie ma wartości NULL (a także częściowego indeksu), jest to prawdopodobnie dość proste.Klucze obce w ogólności (nie tylko złożone) MUSZĄ wskazywać na WYJĄTKOWY KLUCZ w jakimś rodzaju tabeli. Gdyby tego nie zrobili, nie byłoby integralności danych relacyjnych.
To narzeka, ponieważ podczas gdy masz unikalny klucz na (id) .. NIE masz unikalnego klucza na (id, num) .. Zatem, jeśli chodzi o DB, para (id, num) jest NIE GWARANTOWANE, aby być wyjątkowym. My, jako ludzie, możemy domyślić się, że będzie on unikalny, ale jestem pewien, że będzie musiał wprowadzić wiele dodatkowych kodów, aby Postgres był wystarczająco inteligentny, aby zobaczyć, że „och, hej .. identyfikator powinien być unikalny , więc id, num również powinno być unikalne ”..
Byłbym bardzo zaskoczony, gdyby dodali ten kod, gdy wszystko, co musisz zrobić, to stworzyć inny unikalny indeks na dwóch kolumnach, aby rozwiązać problem.
Żeby było jasne, kod, który musieliby dodać, nie byłby zwykłym przypadkiem ... musiałby obsłużyć wszystkie przypadki, nawet te, w których klucz obcy jest na 4+ kolumnach itp. Jestem pewien logika byłaby dość złożona.
źródło