W mojej strukturze bazy danych w SQL Server mam 3 rodzaje produktów, które wymagają różnych informacji o zamówieniu. Więc stworzyłem jeden Customers
stół i trzy różne zlecenia tabele: OrdersForProductAs
, OrdersForProductBs
, OrdersForProductCs
. Tabela wszystkich zamówień ma relację jeden do wielu na Customers
stole.
Mam też inny stolik, w którym są Payments
i będą przechowywane szczegóły płatności. Mam jednak wątpliwości, jak to ustrukturyzować.
Ponieważ mam wiele rodzajów produktów, a klient może mieć zamówienia na wiele produktów jednocześnie, muszę powiązać te trzy tabele zamówień z tabelami Payments
.
Inną kwestią jest to, że klient może mieć zamówienie tylko na jeden rodzaj produktu. Tak więc kolumny FK w Payments
tabeli muszą być nullable
.
Moje pytanie brzmi, czy te nullable
kolumny FK byłyby dla mnie problemem na dłuższą metę, czy nie? Ogólnie rzecz biorąc, czy uznanie za zerowe kolumny FK na stole byłoby uważane za złą praktykę?
Odpowiedzi:
Chciałbym zapytać, dlaczego
OrdersForProductX
w ogóle masz stoły. Możliwe, że problem FK, o który prosiłeś, można zaprojektować ...
Jeśli te tabele mają tę samą strukturę, wystarczy po prostu
ProductType
kolumna wOrderProduct
tabeli. NastępniePayment
wystarczy połączyć z tym jednym FKJeśli tabela ma różne struktury, zakładam, że mają pewne wspólne atrybuty. Możesz więc mieć wspólny
OrderProduct
stół, a następnie określony stół podrzędny dla każdego rodzaju produktu (patrz poniżej) Ponownie,Payment
po prostu linki do wspólnej tabeli z jednym FKJest to „wzorzec klucza / podtypu”
(OrderID, ProductType)
Zamów produkt
OrderProductA
OrderProductB
źródło
NULL
przy takim podejściu nie będziesz mieć żadnych kolumn FK.Unikaj zerowalnych „kluczy obcych”. Mają wiele wad.
Ograniczenie w wierszu odniesienia nie zawsze jest egzekwowane, gdy klucz obcy zawiera wartość null. Jednak to domyślne zachowanie nie jest spójne między różnymi systemami DBMS. Niektóre DBMS obsługują opcje konfiguracji do zmiany zachowania dopuszczalnych kluczy obcych, a niektóre nie. Deweloperzy i użytkownicy SQL mogą więc nie wiedzieć, co tak naprawdę oznacza zerowe ograniczenie klucza obcego z punktu widzenia integralności danych. Przeniesienie bazy danych między produktami DBMS lub nawet między różnymi serwerami korzystającymi z tego samego produktu może dawać niespójne wyniki.
Narzędzia do projektowania baz danych, narzędzia integracyjne i inne oprogramowanie nie zawsze obsługują je poprawnie, a uzyskiwane wyniki mogą być nieprawidłowe.
Klucze obce są często używane w sprzężeniach i innej logice zapytań, co komplikuje problemy użytkownikom, którzy uważają, że ograniczenie obowiązuje, gdy go nie ma lub nie znają logiki stosowanej przez dany system DBMS.
Niektóre funkcje optymalizacji zapytań, które umożliwiają przepisywanie zapytań i inne optymalizacje, mogą być niedostępne, gdy klucz obcy ma wartość zerową.
Z logicznego punktu widzenia nullowalne ograniczenie „klucza obcego” nie ma większego logicznego sensu. Zgodnie ze standardem SQL takie ograniczenie nie może zostać naruszone, nawet jeśli tabela, do której następuje odwołanie, jest pusta. Jest to sprzeczne z jednym z najczęstszych domniemanych uzasadnień użycia wartości zerowej - że reprezentuje przypadek „nieznany”. Jeśli nie ma prawidłowych wartości X, to każdy „nieznany” X z pewnością nie może być prawidłową wartością - a jednak SQL na to zezwala.
Klucze obce dopuszczające wartości zerowe są całkowicie niepotrzebne. Zawsze możesz albo rozłożyć klucz obcy na nową tabelę, albo użyć wzorca nadtypu / podtypu, aby wartości zerowe nie były potrzebne. W trosce o prostotę i dokładność lepiej jest zatem pozostawić wartości zerowe niż je wstawić.
źródło
Nigdy nie słyszałem, by stosowanie złych kolumn FK było uważane za złą praktykę. Idealnie pasują do kolumny, która odwołuje się do innej tabeli, ale może nie zostać wypełniona (tzn. Są to dane opcjonalne).
(Jak myślisz, dlaczego byłby to problem?)
źródło