Czy każdy stół powinien mieć klucz podstawowy?

340

Tworzę tabelę bazy danych i nie mam przypisanego logicznego klucza podstawowego. Tak więc myślę o pozostawieniu go bez klucza podstawowego, ale czuję się trochę winny. Czy powinienem?

Czy każdy stół powinien mieć klucz podstawowy?

Daniel Silveira
źródło
5
Czy możesz podać więcej szczegółów na temat stołu? Prawdopodobnie odpowiedź brzmi „tak”.
Ryan Bair
7
Tak, każda tabela powinna mieć klucz podstawowy.
Syed Tayyab Ali

Odpowiedzi:

313

Krótka odpowiedź: tak .

Długa odpowiedź:

  • Potrzebujesz stolika, aby coś do niego dołączyć
  • Jeśli chcesz, aby twoja tabela była klastrowana, potrzebujesz jakiegoś klucza podstawowego.
  • Jeśli projekt stołu nie wymaga klucza podstawowego, ponownie przemyśl projekt: najprawdopodobniej czegoś brakuje. Po co prowadzić identyczne dokumenty?

W MySQL silnik pamięci InnoDB zawsze tworzy klucz podstawowy, jeśli nie został on wyraźnie określony, tworząc dodatkową kolumnę, do której nie masz dostępu.

Pamiętaj, że klucz podstawowy może być złożony.

Jeśli masz tabelę łączy wiele do wielu, tworzysz klucz podstawowy na wszystkich polach związanych z łączem. W ten sposób upewniasz się, że nie masz dwóch lub więcej rekordów opisujących jeden link.

Oprócz problemów z logiczną spójnością większość silników RDBMS skorzysta z włączenia tych pól do unikalnego indeksu.

A ponieważ każdy klucz podstawowy wymaga utworzenia unikalnego indeksu, należy go zadeklarować i uzyskać zarówno logiczną spójność, jak i wydajność.

Zobacz ten artykuł na moim blogu, aby dowiedzieć się, dlaczego zawsze powinieneś tworzyć unikalny indeks unikatowych danych:

PS Istnieją pewne bardzo, bardzo szczególne przypadki, w których nie potrzebujesz klucza podstawowego.

Najczęściej zawierają tabele dziennika, które nie mają żadnych indeksów ze względu na wydajność.

Quassnoi
źródło
nadal mają klucz podstawowy, klucz złożony
Kristof
2
@annakata: powinny mieć złożony klucz podstawowy
Quassnoi
1
„A ponieważ jakikolwiek KLUCZ PODSTAWOWY wymaga utworzenia indeksu UNIQUE”, nie jest to prawdą w przypadku Oracle. Można użyć nieunikalnego indeksu do wymuszenia klucza podstawowego. W rzeczywistości czasami WYMAGANE jest, aby ograniczenia unikalne i PK korzystały z indeksów nieunikalnych.
Stephanie Page
3
Tylko komentarz do retorycznego pytania „Po co prowadzić identyczne zapisy?”. Pamiętaj, że samo dodanie PK nie zapewni, że nie będzie duplikacji. Często PK nie jest widoczne dla użytkownika, dlatego ważne jest w widocznych polach, które mogą zawierać zduplikowane dane. W zależności od projektu może to być pożądane lub nie.
Rossco,
1
Klucze nie mają nic wspólnego z łącznością. A argument grupowania zależy od używanego DBMS i łączy logiczne i fizyczne względy.
Jon Heggland,
36

Zawsze najlepiej mieć klucz podstawowy. W ten sposób spełnia pierwszą normalną formę i umożliwia kontynuację ścieżki normalizacji bazy danych .

Jak twierdzą inni, istnieją pewne powody, dla których nie trzeba mieć klucza podstawowego, ale większość z nich nie ucierpi, jeśli klucz podstawowy będzie istniał

Michael Wheeler
źródło
5
@PaulSuart Dane nie zawsze muszą mieć normalne formy. W rzeczywistości, gdy dane stają się ogromne, nie powinny być utrzymywane w normalnej formie, w przeciwnym razie dostęp do danych byłby strasznie powolny dla zapytań wykonujących łączenia tabel itp. Normalne formularze są „idealizacją” i praktycznie możliwe tylko wtedy, gdy nie oczekuje się wzrostu danych olbrzymi.
Pacerier,
13

Prawie za każdym razem, gdy tworzę tabelę bez klucza podstawowego, myśląc, że nie będę go potrzebował, w końcu wróciłem i dodałem jeden. Teraz tworzę nawet tabele połączeń z automatycznie generowanym polem tożsamości, którego używam jako klucza podstawowego.

tvanfosson
źródło
13
Tabela łączenia JEST kluczem podstawowym - złożonym, składającym się z łączonych PK obu rekordów. Np. UTWÓRZ TABELĘ PersonOrder (PersonId int, OrderId int, PRIMARY KEY (PersonId, OrderId)).
Keith Williams
3
Tak, ale co jeśli tabela łączy ma również trzeci atrybut, powiedzmy „OrderDate”. Czy dodałbyś to również do klucza złożonego? IMHO nie - ponieważ jest dalej redukowalny i nie służy właściwościom nieredukowalnym, jaki powinien mieć klucz podstawowy.
stevek
13

Poza kilkoma bardzo rzadkimi przypadkami (być może tabelą relacji wiele do wielu lub tabelą, której tymczasowo używasz do masowego ładowania ogromnych ilości danych), chciałbym powiedzieć:

Jeśli nie ma klucza podstawowego, to nie jest to tabela!

Marc

marc_s
źródło
10
Ściśle mówiąc, to zdanie jest złe. Tabele mogą być „Wyświetl tabele” utworzone przez Twój język zapytań. RDBMS składa się z relacji, a nie tabel. To zdanie powinno brzmieć: „Jeśli nie ma klucza podstawowego, nie jest to relacja!”.
stevek
A może „jeśli nie ma kluczy kandydujących, to nie jest to tabela relacyjna”. Ale zobacz bardzo rzadkie przypadki, w których dobrze jest mieć tabelę, która nie reprezentuje relacji.
Walter Mitty
Dlaczego tabela wiele do wielu nie miałaby klucza podstawowego? Możesz utworzyć oddzielny klucz podstawowy, a następnie utworzyć unikalny indeks dla surogatu kluczy obcych. Myślę, że lepiej mieć klucz podstawowy na każdym stole. Nawet w tabeli ładowania zbiorczego możesz chcieć osobno zidentyfikować klucz podstawowy, który nie obejmuje importowanych danych, ponieważ może to pomóc w identyfikacji duplikatów rekordów w procesie ETL. Wydaje mi się, że każdy stół powinien nadal mieć klucz podstawowy, nawet jeśli jest to trochę więcej miejsca. Tabela utworzona przez widok jest podzbiorem tabeli, a nie samą tabelą.
John Ernest
1
W tabeli relacji wiele do wielu można utworzyć złożony klucz podstawowy składający się z obu identyfikatorów relacji.
Jaap
8

Po prostu dodaj, później będziesz żałować, kiedy tego nie zrobiłeś (wybierając, usuwając. Linkowanie itp.)

raphaëλ
źródło
8

Czy kiedykolwiek będziesz musiał dołączyć ten stół do innych stołów? Czy potrzebujesz sposobu na jednoznaczną identyfikację rekordu? Jeśli odpowiedź brzmi tak, potrzebujesz klucza podstawowego. Załóżmy, że Twoje dane są czymś w rodzaju tabeli klientów, która zawiera nazwiska osób będących klientami. Może nie być naturalnego klucza, ponieważ potrzebujesz adresów, e-maili, numerów telefonów itp., Aby ustalić, czy ta Sally Smith różni się od tej Sally Smith, i będziesz przechowywać te informacje w powiązanych tabelach, ponieważ osoba może mieć wiele telefonów, dodatków , e-maile itp. Załóżmy, że Sally Smith poślubia Johna Jonesa i staje się Sally Jones. Jeśli nie masz sztucznego klucza na stole, po aktualizacji nazwy zmieniłeś właśnie 7 Sally Smiths na Sally Jones, chociaż tylko jeden z nich się ożenił i zmienił jej imię.

Mówisz, że nie masz naturalnego klucza, dlatego też nie masz żadnych kombinacji pól, aby uczynić go wyjątkowym, dlatego klucz sztuczny jest krytyczny.

Zauważyłem, że za każdym razem, gdy nie mam klucza naturalnego, klucz sztuczny jest absolutną koniecznością do zachowania integralności danych. Jeśli masz naturalny klucz, możesz go użyć jako pola klucza. Ale osobiście, chyba że klucz naturalny jest jednym polem, nadal wolę klucz sztuczny i unikalny indeks klucza naturalnego. Pożałujesz tego później, jeśli go nie włożysz.

HLGEM
źródło
6

Dobrą praktyką jest mieć PK na każdym stole, ale to NIE MUSI. Najprawdopodobniej będziesz potrzebować unikalnego indeksu i / lub indeksu klastrowego (który jest PK lub nie), w zależności od potrzeb.

Sprawdź sekcję Podstawowe klucze i indeksy klastrowe w Books Online (dla SQL Server)

Ograniczenia klucza podstawowego identyfikują kolumnę lub zestaw kolumn, które mają wartości jednoznacznie identyfikujące wiersz w tabeli. Żadne dwa wiersze w tabeli nie mogą mieć tej samej wartości klucza podstawowego. Nie można wprowadzić wartości NULL dla żadnej kolumny w kluczu podstawowym. Mamy zalecamy użycie małej, całkowitej liczby jako klucza podstawowego. Każda tabela powinna mieć klucz podstawowy. Kolumna lub kombinacja kolumn, które kwalifikują się jako wartość klucza podstawowego, nazywana jest kluczem kandydującym.

Ale sprawdź to także: http://www.aisintl.com/case/primary_and_foreign_key.html

endo64
źródło
4
ta strona jest dość głupia. Po pierwsze, klucz podstawowy jest potrzebny ze względu na wydajność. Czytając jego stronę, dowiaduję się, że dodanie identyfikatora do stolika z książkami jest bezużyteczne, ponieważ tekst książki jest unikalny; oczywiście facet nigdy nie pracował z bazami danych, ale ma również problemy ze zrozumieniem tego, co krytykuje. Strona napisana, że ​​1) wartość PK odnosi się do wiersza 2) możesz połączyć 2 tabele według dowolnego zestawu kolumn. Nie ma sprzeczności. To niesamowite, że autor artykułu akademickiego nie rozumie bardzo podstawowych teorii relacyjnych.
Federico Razzoli,
1
„Po pierwsze, klucz podstawowy jest potrzebny ze względu na wydajność” jest to niepoprawne, PK nie wpływa bezpośrednio na wydajność. Brak PK może powodować wiele problemów (identyfikowanie wiersza, łączenie itp.), Ale wydajność nie jest jednym z nich. Gdy tworzysz PK na stole, SQL Server tworzy indeks klastrowy unikalny, który wpływa na wydajność, a nie sam PK. Jako prawdziwy przykład, moja tabela ma klastrowany indeks w kolumnie daty i PK w polu GUID, ponieważ moje wiersze powinny być uporządkowane fizycznie według kolumny daty w tabeli, ponieważ wszystkie zapytania mają zakres dat (w moim przypadku).
endo64
Ten klastrowany indeks jest odmianą klucza podstawowego, utworzonego przez SQL Server i kilka innych DBMS-ów. Czy jesteś pewien, że warto go używać? Na przykład w MySQL nie jest z kilku nieudokumentowanych powodów.
Federico Razzoli,
1
Należy pamiętać, że GUID nie jest optymalnym typem dla PK, w InnoDB. Wszystkie indeksy zawierają odniesienie do PK, więc im większy jest PK, tym większe będą wszystkie pozostałe indeksy.
Federico Razzoli
6

Nie zgadzaj się z sugerowaną odpowiedzią. Krótka odpowiedź brzmi: NIE .

Celem klucza podstawowego jest jednoznaczna identyfikacja wiersza w tabeli w celu utworzenia relacji z inną tabelą. Tradycyjnie do tego celu używana jest automatycznie zwiększana wartość całkowita, ale istnieją odmiany.

Zdarzają się jednak przypadki, na przykład rejestrowanie danych szeregów czasowych, w których istnienie takiego klucza po prostu nie jest potrzebne i zajmuje tylko pamięć. Unikanie wiersza jest po prostu ... nie wymagane!

Mały przykład: Tabela A: LogData

Columns:  DateAndTime, UserId, AttribA, AttribB, AttribC etc...

Klucz podstawowy nie jest potrzebny.

Tabela B: Użytkownik

Columns: Id, FirstName, LastName etc. 

Klucz podstawowy (Id) potrzebny do użycia jako „klucz obcy” w tabeli LogData.

Theodore Zographos
źródło
3

Wiem, że do korzystania z niektórych funkcji widoku siatki w .NET potrzebny jest klucz podstawowy, aby widok siatki mógł wiedzieć, który wiersz wymaga aktualizacji / usunięcia. Ogólną praktyką powinno być posiadanie klucza podstawowego lub klastra kluczy głównych. Ja osobiście wolę ten pierwszy.

Tacoman667
źródło
3

Aby był to dowód na przyszłość, naprawdę powinieneś. Jeśli chcesz go powtórzyć, będziesz go potrzebować. Jeśli chcesz dołączyć do innego stołu, twoje życie (i życie biednych głupców, którzy będą musieli je utrzymać w przyszłym roku) będzie o wiele łatwiejsze.

Gulasz Szlachetny
źródło
Nie jestem jeszcze przekonany, że jest to konieczne, ale „zrób to, bo inaczej ktoś będzie musiał poradzić sobie z konsekwencjami później” wystarczy, że popełniam błąd po stronie robienia tego. Zawsze mogę po prostu upuścić kolumnę później, jeśli warto zmniejszyć ją ...
ArtOfWarfare
3

Jestem odpowiedzialny za utrzymanie aplikacji stworzonej przez zespół programistów offshore. Teraz mam wiele problemów w aplikacji, ponieważ oryginalny schemat bazy danych nie zawierał PODSTAWOWYCH KLUCZY w niektórych tabelach. Więc proszę, nie pozwól innym cierpieć z powodu twojego złego projektu. Zawsze dobrze jest mieć klucze podstawowe na stołach.

siedmiodniowa żałoba
źródło
2

Zawsze mam klucz podstawowy, nawet jeśli na początku nie mam na to celu. Było kilka razy, kiedy w końcu potrzebowałem PK w tabeli, która go nie ma, i zawsze trudniej jest włożyć go później. Myślę, że zawsze jest coś więcej niż zawsze.

Rvarcher
źródło
1

Krótko mówiąc, nie. Należy jednak pamiętać, że niektóre operacje CRUD z dostępem klienta wymagają tego. W celu korekty w przyszłości zawsze używam kluczy podstawowych.

Rich.Carpenter
źródło
1

Jeśli używasz Hibernacji, nie można utworzyć encji bez klucza podstawowego. Te problemy mogą powodować problemy, jeśli pracujesz z istniejącą bazą danych, która została utworzona za pomocą zwykłych skryptów sql / ddl i nie dodano klucza podstawowego

Schildmeijer
źródło