2008-09-02 17 views
14

Mam następujące tabele w mojej bazy danych, które mają wiele-do-wielu relacji, która jest wyrażona przez łączącej tabeli, która ma kluczy obcych do kluczy podstawowych każdego z głównych tabelach:Jeden lub dwa klucze główne w tabeli wielu do wielu?

  • Widget: widgetid (PK), tytuł, cena
  • użytkownika: ID użytkownika (PK), imię, nazwisko

Załóżmy, że każda kombinacja użytkownika Widget jest wyjątkowy. Widzę dwie opcje jak struktura stół łączący, który określa relację danych:

  1. UserWidgets1: UserWidgetID (PK), widgetid (FK), ID użytkownika (FK)
  2. UserWidgets2: widgetid (PK, FK), ID użytkownika (PK, FK)

Opcja 1 ma pojedynczą kolumnę klucza podstawowego. Jednak wydaje się to zbędne, ponieważ jedynymi danymi przechowywanymi w tabeli są relacje między dwiema podstawowymi tabelami, a ta sama relacja może tworzyć unikalny klucz. W ten sposób prowadząc do opcji 2, która ma dwukolumnowy klucz podstawowy, ale traci unikalny identyfikator jednej kolumny, który ma opcję 1. Mogłem również opcjonalnie dodać do pierwszej tabeli unikalny indeks dwukolumnowy (WidgetID, UserID).

Czy istnieje jakaś realna różnica między tymi dwoma względami pod względem wydajności lub jakiegokolwiek powodu preferowania jednego podejścia do drugiego w celu ukształtowania tabeli Wiele_ do wielu użytkowników UserWidget?

+0

Indeksy potrzebne są podyktowane wymaganiami zapytania, a nie swój projekt schematu. – dkretz

Odpowiedz

24

Masz tylko jeden klucz główny w obu przypadkach. Drugi to tak zwany klucz złożony. Nie ma żadnego powodu, dla którego warto wprowadzić nową kolumnę. W praktyce będziesz musiał zachować unikalny indeks wszystkich kluczy kandydatów. Dodanie nowej kolumny nie kosztuje nic innego, jak tylko koszty utrzymania.

Go z opcji 2.

+0

Klucz podstawowy może być używany - warunki nie są wyłączne. – paulmurray

+2

@paulmurray: Wierzę, że powyższa odpowiedź mówi, że w obu przypadkach masz klucz podstawowy, w tym przypadek, w którym masz klucz złożony. Czy masz coś do dodania? – Apocalisp

0

Ponieważ każda kombinacja User-Widget jest unikatowa, należy ją przedstawić w tabeli, tworząc unikalną kombinację. Innymi słowy, przejdź do opcji 2. W przeciwnym razie możesz mieć dwa wpisy o tym samym widżecie i identyfikatorach użytkowników, ale inne identyfikatory widżetów użytkowników.

0

userwidgetid w pierwszej tabeli nie jest potrzebne, ponieważ jak powiedział pan wyjątkowość wynika z kombinacji widgetid i identyfikatora.

Chciałbym użyć drugiej tabeli, zachować klucze foriegn i dodać unikalny indeks na widgetid i userid.

Więc:

 
userwidgets(widgetid(fk), userid(fk), 
      unique_index(widgetid, userid) 
) 

Istnieją pewne zyski w PreFormance nie mając dodatkowy klucz podstawowy, jak baza danych nie będzie musiał obliczyć indeks dla klucza. W powyższym modelu chociaż ten indeks (za pomocą unique_index) jest nadal obliczany, ale uważam, że jest to łatwiejsze do zrozumienia.

2

Jakie zalety ma klucz podstawowy w tym scenariuszu? Rozważ opcję braku klucza podstawowego: UserWidgets3: WidgetID (FK), identyfikator użytkownika (FK)

Jeśli chcesz unikatowość, użyj klucza złożonego (UserWidgets2) lub ograniczenia unikalności.

Zwykle zaletą posiadania klucza podstawowego jest to, że często przesyła on zapytanie do tabeli za pomocą klucza podstawowego, który jest szybki. W przypadku tabel wielu do wielu zwykle nie następuje zapytanie o klucz podstawowy, więc nie ma korzyści z wydajności. Tabele wielu do wielu są sprawdzane przez ich klucze obce, więc powinieneś rozważyć dodanie indeksów na WidgetID i UserID.

2

Opcja 2 jest poprawną odpowiedzią, chyba że masz naprawdę dobry powód, aby dodać zastępczy klucz numeryczny (który zrobiłeś w opcji 1).

Zastępcze kolumny kluczy numerycznych nie są "kluczami podstawowymi". Klucze podstawowe są technicznie jedną z kombinacji kolumn, które jednoznacznie identyfikują rekord w tabeli.

Każdy, kto tworzy bazę danych powinien przeczytać ten artykuł http://it.toolbox.com/blogs/database-soup/primary-keyvil-part-i-7327 autorstwa Josha Berkusa, aby zrozumieć różnicę między odpowiednimi kolumnami klucza numerycznego i kluczami podstawowymi.

Z mojego doświadczenia wynika, że ​​jedynym prawdziwym powodem dodania zastępczego klucza numerycznego do tabeli jest to, że klucz podstawowy jest kluczem złożonym i musi być używany jako odniesienie do klucza obcego w innej tabeli. Tylko wtedy powinieneś pomyśleć o dodaniu dodatkowej kolumny do stołu.

Ilekroć widzę strukturę bazy danych, w której każda tabela ma kolumnę "id", istnieje duże prawdopodobieństwo, że została zaprojektowana przez kogoś, kto nie docenia modelu relacyjnego i niezmiennie wyświetla jeden lub więcej problemów zidentyfikowanych w Josh's artykuł.

3

Zgadzam się z poprzednimi odpowiedziami, ale mam jedną uwagę do dodania. Jeśli chcesz dodać więcej informacji do relacji i zezwolić na więcej relacji między tymi samymi dwoma obiektami, potrzebujesz opcji pierwszej.

Na przykład, jeśli chcesz śledzić wszystkie czasy, w których użytkownik 1 używał widżetu 664 w tabeli userwidget, identyfikator użytkownika i widgetid nie jest już unikalny.

5

Osobiście byłoby mają syntetyczny/surogat kolumna klucz w wielu-do-wielu tabel z następujących powodów:

  • Jeśli używany klawiszy numerycznych syntetycznych w tabelach jednostki następnie mających to samo w tabelach relacji zachowuje spójność w konwencji projektowania i nazewnictwa.
  • Może się zdarzyć w przyszłości, że tabela "wiele do wielu" sama stanie się jednostką nadrzędną wobec podporządkowanej jednostki, która potrzebuje unikalnego odniesienia do pojedynczego wiersza.
  • To naprawdę nie będzie zużywać tak dużo dodatkowej przestrzeni dyskowej.

Kluczem syntetyczny nie jest zamiennikiem do naturalnej/KLUCZ związku ani staje się PRIMARY KEY dla tej tabeli, tylko dlatego, że jest to pierwsza kolumna w tabeli, więc częściowo zgodzić się z artykułem Josh Berkus. Jednak nie zgadzam się, że klucze naturalne są zawsze dobrymi kandydatami na PRIMARY KEY's i na pewno nie powinny być używane, jeśli mają być używane jako klucze obce w innych tabelach.

+0

Zdaję sobie sprawę, że odpowiedź została udzielona dawno temu, ale czy klucz złożony nadal nie byłby unikalnym odnośnikiem do pojedynczego wiersza dla tabeli nadrzędnej (twój punkt 2)? – crush

+1

@crush - tak, byłby unikatowy, ale utworzenie ograniczenia na złożonym kluczu jest fugly/inconsistent na platformach. Wolę być jednoznaczny i konsekwentny. Każda tabela ma kolumnę tożsamości. – Guy

5

Opcja 2 używa prostego klucza dostępu, opcja 1 używa numeru surrogate key. Opcja 2 jest preferowana w większości scenariuszy i jest zbliżona do modelu lojalnościowego, ponieważ jest to dobry klucz kandydujący.

Istnieją sytuacje, w których może chcesz użyć klucza zastępczego (Opcja 1)

  1. Nie jesteś że kluczem związek jest dobry klucz potencjalny w czasie. Szczególnie w przypadku danych czasowych (danych zmieniających się w czasie). A co jeśli chcesz dodać kolejny wiersz do tabeli UserWidget z tym samym UserId i WidgetId? Pomyśl zatrudnienia (EmployeeID, IDPracownika) - to działa w większości przypadków z wyjątkiem jeśli ktoś wrócił do pracy u tego samego pracodawcy w terminie późniejszym
  2. W przypadku tworzenia wiadomości/transakcji handlowych lub coś podobnego, które wymagają łatwiejszy klucz używać do integracji. Może replikacja?
  3. Jeśli chcesz utworzyć własne mechanizmy kontrolne (lub podobne) i nie chcesz, aby klucze były zbyt długie.

Z reguły podczas modelowania danych można zauważyć, że większość jednostek skojarzonych (wiele do wielu) jest wynikiem zdarzenia. Osoba podejmuje pracę, przedmiot jest dodawany do koszyka itp. Większość wydarzeń ma czasową zależność od wydarzenia, w którym data i godzina są istotne - w takim przypadku klucz zastępczy może być najlepszą alternatywą.

więc wziąć opcję 2, ale upewnij się, że masz kompletny model.

1

Chciałbym iść z obiema.

Wysłuchaj mnie:

klucz Związek jest oczywiście ładny, poprawny sposób, aby przejść w jakim odzwierciedla sens dane idzie. Bez pytania.

Jednakże: Miałem wszelkiego rodzaju kłopoty podejmowania pracy hibernacji właściwie chyba użyć pojedynczego wygenerowany klucz podstawowy - klucz zastępczy.

Więc użyłbym danych logicznych i fizycznych model. Logiczna ma klucz złożony. Model fizyczny - który implementuje model logiczny - ma klucz zastępczy i klucze obce.