Zakładając, że mam wiele relacji w mojej bazie danych, na przykład Sklep, Pracownik i Sprzedaż, i chcę połączyć pary za pomocą prostej relacji binarnej. Osobiście tworzyłem tabele o nazwie Employee_Store i Employee_Sale z naturalnym kluczem złożonym z kluczy obcych.
Teraz mój kolega nalega na stworzenie jednego stołu dla wielu relacji. W powyższym przykładzie może istnieć tabela o nazwie EmployeeLinks:
EmployeeLinks(
IdLink int PK,
IdEmployee int FK null,
IdStore int FK null,
IdSale int FK null,
LinkType int not null
)
Pomóż mi z ważnymi powodami, dla których nie jest to dobry pomysł. Mam własne argumenty, ale chciałbym zachować ich prywatność i poznać wasze obiektywne opinie.
EDYTOWAĆ:
Początkowo powyższa tabela nie miałaby klucza podstawowego (!). Ponieważ klucze obce umożliwiają zerowanie, klucz zastępczy jest jedyną opcją.
database-design
Tomasz Pluskiewicz
źródło
źródło
Odpowiedzi:
Co twój kolega proponuje jako klucz podstawowy dla tej tabeli łączy?
Oczywiście kolumny klucza podstawowego nie mogą mieć wartości NULL: powyższa tabela ma wartość zerową.
W powyższym przykładzie nie ma żadnego naturalnego identyfikatora wiersza (którym jest PK) (kolumna TOŻSAMOŚĆ nie jest kluczem podstawowym), dlatego nie udaje się to w żadnym procesie modelowania. Nawet nie myśl o tworzeniu tabel bez jakiegoś modelu (ERD, ORM, IDEF1X, cokolwiek)
Potrzebujesz również ograniczeń CHECK, aby upewnić się, że nie masz linków trójstronnych.
Wreszcie, zbłądzisz na terytorium czwartej i piątej normalnej formy, ale z niewłaściwych powodów.
Nie mogę znaleźć żadnych przykładów w Internecie: to pokazuje, jak głupie to jest
źródło
I can't find any examples on the internet: that shows how stupid this is
Pierwszym praktycznym powodem, dla którego mogę wymyślić, jest wydajność.
W „tradycyjnym” modelu możesz mieć unikalny indeks na
Idemployee, Idstore
polach lub cokolwiek to jest, i uzyskać doskonałą wydajność wyszukiwania. Jest również łatwy w utrzymaniu dla wkładek. Unikalne indeksy sprawiają, że łączenie połączeń jest częstsze, co może znacznieJOIN
przyspieszyć.W twoim przykładowym modelu, aby uzyskać przyzwoitą wydajność, będziesz musiał mieć pojedynczy indeks pól dla każdego pola FK w tabeli, najlepiej indeks obejmujący wszystkie kombinacje, do których będzie się odwoływać, tj .:
Nie jestem pewien, jaki jest typ linku, ale jeśli się do niego odwołujesz, prawdopodobnie powinien zostać zindeksowany.
Te indeksy będą musiały być utrzymywane dla każdego wiersza w tabeli, niezależnie od tego, czy pole jest wypełnione. Możesz dodać filtr, ale przy tak wielu kombinacjach będzie to trudne.
Skomplikuje to również twoją logikę. Musisz albo wyszukać pracownika, znaleźć wiersz z pustą wartością sklepu i zaktualizować; lub po prostu wstaw nowy wiersz dla każdego nowego linku, co w pewnym sensie uniemożliwia konsolidację pól.
Zasadniczo będziesz używać WIĘCEJ miejsca na dysku, utrzymywać MORE indeksy do utrzymania i komplikować logikę bez żadnego powodu. Jedyną „korzyścią” jest to, że jest mniej stolików do czynienia.
źródło
Umieszczenie wielu relacji w jednej tabeli może być przydatne, jeśli te relacje mają te same atrybuty i / lub jeśli chcesz agregować dane w wielu relacjach.
Jest to konieczne, jeśli typy relacji są zdefiniowane przez użytkownika w czasie wykonywania. Jednak tak naprawdę rzadko tak jest.
W twoim przykładzie relacje nie dzielą atrybutów, a nawet odnoszą się do dwóch różnych tabel. Utrudnia to egzekwowanie ograniczeń, a projekt jest mniej intuicyjny.
Wybrałbym ten projekt tylko wtedy, gdy tworzenie stołów dosłownie kosztuje.
źródło