Kolumna (lub kolumny) klucza podstawowego nie może mieć wartości NULL. Rekord nie może być jednoznacznie identyfikowany przez NULL. Tak więc kolumny ID na wskazanym końcu klucza obcego muszą być zdefiniowane jako NOT NULL.
Jednak decyzja projektowa, aby relacja klucza obcego była opcjonalna, jest uzasadnioną decyzją, a sposobem na jej reprezentację jest opcjonalna część odwołująca się do końca klucza, tj. Zezwolenie na wartości NULL.
W kategoriach modelowania danych to, co opisałeś, jest (wyłącznym) łukiem:„tabela ... z co najmniej dwoma kluczami obcymi, gdzie jeden i tylko jeden z nich może być inny niż null”. W modelowaniu logicznym łuki są całkowicie akceptowalne, ale istnieje silna opinia przemawiająca za implementacją ich jako oddzielnych tabel. W twoim scenariuszu byłaby to ogólna Sale
tabela plus dwie tabele podtypów, VehicleSale
i PieceSale
.
Zalety oddzielnej implementacji tabeli to:
- łatwiejsze egzekwowanie ograniczeń klucza obcego;
- łatwiejsze dodawanie dodatkowych kolumn dotyczących (powiedzmy) sprzedaży pojazdów, które nie mają zastosowania do sprzedaży jednostkowej;
- łatwiejsze rozszerzenie modelu o dodatkowe podtypy;
- wyraźniejszy model danych, który może uprościć tworzenie aplikacji.
Jednak korzyści nie są jednostronne. Chociaż dość łatwo jest upewnić się, że Sale
dotyczy zarówno VehicleSale
lub PieceSale
ale nie jedno i drugie, wymuszając regułę, że Sale
musi posiadanie rekordu dziecka faktycznie staje się dość szorstkie.
Tak więc przeważającą radą jest to, że ekskluzywny łuk jest błędny i generalnie jest to dobra rada. Ale nie jest to tak jasne, jak niektórzy twierdzą.