W pracy mamy dużą bazę danych z unikalnymi indeksami zamiast kluczy podstawowych i wszystko działa dobrze.
Projektuję nową bazę danych dla nowego projektu i mam dylemat:
W teorii DB klucz podstawowy jest elementem podstawowym, to jest OK, ale w PRAWDZIWYCH projektach jakie są zalety i wady obu?
Czego używasz w projektach?
EDYCJA: ... a co z kluczami podstawowymi i replikacją na serwerze MS SQL?
sql
database
database-design
Cicik
źródło
źródło
Odpowiedzi:
Co to jest unikalny indeks?
Unikalny indeks w kolumnie to indeks w tej kolumnie, który wymusza również ograniczenie, że nie można mieć dwóch równych wartości w tej kolumnie w dwóch różnych wierszach. Przykład:
Ostatnia operacja wstawiania kończy się niepowodzeniem, ponieważ narusza unikalny indeks w kolumnie,
foo
gdy próbuje wstawić wartość 1 do tej kolumny po raz drugi.W MySQL unikalne ograniczenie zezwala na wiele wartości NULL.
Możliwe jest utworzenie unikalnego indeksu na wielu kolumnach.
Klucz podstawowy a unikalny indeks
Rzeczy, które są takie same:
Różne rzeczy:
źródło
Możesz to zobaczyć w ten sposób:
Klucz podstawowy JEST wyjątkowy
Unikalna wartość nie musi być reprezentacją elementu
Znaczenie?; Cóż, klucz podstawowy jest używany do identyfikacji elementu, jeśli masz „Osobę”, chciałbyś mieć osobisty numer identyfikacyjny (SSN lub inny), który jest nadrzędny dla Twojej osoby.
Z drugiej strony, osoba może mieć adres e-mail, który jest unikalny, ale nie identyfikuje osoby.
Zawsze mam klucze podstawowe, nawet w tabelach relacji (tabela środkowa / tabela połączeń), które mogę mieć. Czemu? Cóż, lubię kierować się standardem podczas kodowania, jeśli "Osoba" ma identyfikator, Samochód ma identyfikator, cóż, Osoba -> Samochód również powinien mieć identyfikator!
źródło
Klucze obce działają z unikatowymi ograniczeniami, a także z kluczami podstawowymi. Z Books Online:
Do replikacji transakcyjnej potrzebny jest klucz podstawowy. Z Books Online:
Obie odpowiedzi dotyczą programu SQL Server 2005.
źródło
Wybór, kiedy użyć zastępczego klucza podstawowego, a kiedy klucza naturalnego, jest trudny. Odpowiedzi typu „zawsze lub nigdy” rzadko są przydatne. Uważam, że to zależy od sytuacji.
Jako przykład mam następujące tabele:
CREATE TABLE toll_booths ( id INTEGER NOT NULL PRIMARY KEY, name VARCHAR(255) NOT NULL, ... UNIQUE(name) ) CREATE TABLE cars ( vin VARCHAR(17) NOT NULL PRIMARY KEY, license_plate VARCHAR(10) NOT NULL, ... UNIQUE(license_plate) ) CREATE TABLE drive_through ( id INTEGER NOT NULL PRIMARY KEY, toll_booth_id INTEGER NOT NULL REFERENCES toll_booths(id), vin VARCHAR(17) NOT NULL REFERENCES cars(vin), at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, amount NUMERIC(10,4) NOT NULL, ... UNIQUE(toll_booth_id, vin) )
Mamy dwie tabele encji (
toll_booths
icars
) oraz tabelę transakcji (drive_through
).toll_booth
Tabela używa klucza zastępczego, ponieważ ma naturalny atrybut, który nie jest gwarantowana do zmian (nazwa może być łatwo zmieniona).cars
Tabela wykorzystuje naturalne klucz podstawowy, ponieważ ma non zmieniających unikalny identyfikator (vin
).drive_through
Stół transakcja używa klucza zastępczego dla łatwej identyfikacji, ale ma również wyjątkową presję na atrybutach, które są gwarantowane, aby być unikatowa w momencie rekord jest włożona.http://database-programmer.blogspot.com zawiera świetne artykuły na ten temat.
źródło
Klucze podstawowe nie mają wad.
Aby dodać tylko trochę informacji do odpowiedzi @MrWiggles i @Peter Parker, gdy tabela nie ma klucza podstawowego, na przykład nie będziesz mógł edytować danych w niektórych aplikacjach (w końcu powiedzą coś takiego jak nie można edytować / usuwać danych bez klucz podstawowy). Postgresql zezwala na umieszczanie wielu wartości NULL w kolumnie UNIQUE, klucz PRIMARY KEY nie zezwala na wartości NULL. Również niektóre ORM, które generują kod, mogą mieć problemy z tabelami bez kluczy podstawowych.
AKTUALIZACJA:
O ile wiem, nie jest możliwa replikacja tabel bez kluczy podstawowych w MSSQL, przynajmniej bez problemów ( szczegóły ).
źródło
Jeśli coś jest kluczem podstawowym, w zależności od silnika bazy danych, cała tabela jest sortowana według klucza podstawowego. Oznacza to, że wyszukiwania są znacznie szybsze w przypadku klucza podstawowego, ponieważ nie musi wykonywać żadnych wyłuskiwania, jak ma to miejsce w przypadku każdego innego rodzaju indeksu. Poza tym to tylko teoria.
źródło
Oprócz tego, co powiedziały inne odpowiedzi, niektóre bazy danych i systemy mogą wymagać obecności podstawowego. Przychodzi mi na myśl jedna sytuacja; podczas korzystania z replikacji korporacyjnej z produktem Informix, aby tabela uczestniczyła w replikacji, musi być obecny PK.
źródło
Dopóki nie zezwalasz na NULL dla wartości, powinny być traktowane tak samo, ale wartość NULL jest obsługiwana inaczej w bazach danych (AFAIK MS-SQL nie zezwala na więcej niż jedną (1) wartość NULL, mySQL i Oracle pozwalają na to , jeśli kolumna jest UNIQUE), więc musisz zdefiniować tę kolumnę NOT NULL UNIQUE INDEX
źródło
W relacyjnej teorii danych nie ma czegoś takiego jak klucz podstawowy, więc na twoje pytanie należy odpowiedzieć na poziomie praktycznym.
Unikalne indeksy nie są częścią standardu SQL. Konkretna implementacja DBMS określi konsekwencje zadeklarowania unikalnego indeksu.
W Oracle zadeklarowanie klucza podstawowego spowoduje utworzenie w Twoim imieniu unikalnego indeksu, więc pytanie jest prawie dyskusyjne. Nie mogę ci powiedzieć o innych produktach DBMS.
Preferuję zadeklarowanie klucza podstawowego. Skutkuje to zakazem stosowania wartości NULL w kolumnach klucza, a także zakazu tworzenia duplikatów. Opowiadam się również za deklarowaniem ograniczeń REFERENCJI w celu wymuszenia integralności jednostki. W wielu przypadkach zadeklarowanie indeksu w coulmn (ach) klucza obcego przyspieszy łączenie. Ten rodzaj indeksu na ogół nie powinien być unikalny.
źródło
Istnieją pewne wady INDEKSÓW KLASTEROWANYCH w porównaniu z INDEKSAMI UNIQUE.
Jak już wspomniano, KLUSTEROWANY INDEKS fizycznie porządkuje dane w tabeli.
Oznacza to, że jeśli masz dużo wstawiania lub usuwania w tabeli zawierającej indeks klastrowy, za każdym razem (no prawie, w zależności od współczynnika wypełnienia) zmieniasz dane, fizyczna tabela musi zostać zaktualizowana, aby pozostać posortowana.
W przypadku stosunkowo małych tabel jest to w porządku, ale podczas uzyskiwania dostępu do tabel, które mają dane o wartości GB, a wstawianie / usuwanie wpływa na sortowanie, napotkasz problemy.
źródło
Prawie nigdy nie tworzę tabeli bez numerycznego klucza podstawowego. Jeśli istnieje również naturalny klucz, który powinien być unikalny, umieszczam na nim również unikalny indeks. Łączenia są szybsze w przypadku liczb całkowitych niż klucze naturalne w wielu kolumnach, dane muszą zmieniać się tylko w jednym miejscu (klucze naturalne zwykle wymagają aktualizacji, co jest złe, gdy znajdują się w relacjach klucz podstawowy - klucz obcy). Jeśli będziesz potrzebować replikacji, użyj identyfikatora GUID zamiast liczby całkowitej, ale w większości przypadków wolę klucz, który jest czytelny dla użytkownika, zwłaszcza jeśli muszą go zobaczyć, aby odróżnić John Smith od John Smith.
Kilka razy nie tworzę zastępczego klucza, gdy mam stół łączący, który jest zaangażowany w relację wiele do wielu. W tym przypadku deklaruję oba pola jako klucz podstawowy.
źródło
Rozumiem, że klucz podstawowy i unikalny indeks z ograniczeniem niezerowym są takie same (*); i przypuszczam, że jeden wybiera jedną lub drugą w zależności od tego, co wyraźnie stwierdza lub sugeruje specyfikacja (kwestia tego, co chcesz wyrazić i wyraźnie egzekwować). Jeśli wymaga unikalności i nie jest zerowy, uczyń go kluczem podstawowym. Jeśli po prostu się zdarzy, że wszystkie części unikatowego indeksu nie są zerowe bez żadnego wymagania, po prostu uczyń go unikalnym indeksem.
Jedyną pozostałą różnicą jest to, że możesz mieć wiele niepowtarzalnych indeksów niezerowych, podczas gdy nie możesz mieć wielu kluczy podstawowych.
(*) Z wyjątkiem praktycznej różnicy: klucz podstawowy może być domyślnym kluczem unikalnym dla niektórych operacji, takich jak definiowanie klucza obcego. Dawny. jeśli zdefiniowano klucz obcy odwołujący się do tabeli i nie podano nazwy kolumny, jeśli tabela, do której istnieje odniesienie, ma klucz podstawowy, wówczas kluczem podstawowym będzie kolumna, do której się odwołuje. W przeciwnym razie kolumna, do której istnieje odwołanie, będzie musiała zostać jawnie nazwana.
Inni tutaj wspominali o replikacji DB, ale ja o tym nie wiem.
źródło
Unikalny indeks może mieć jedną wartość NULL. Tworzy INDEKS BEZ KLASTERÓW. Klucz podstawowy nie może zawierać wartości NULL. Tworzy CLUSTERED INDEX.
źródło
W MSSQL klucze podstawowe powinny rosnąć monotonicznie, aby uzyskać najlepszą wydajność w indeksie klastrowym. Dlatego liczba całkowita z wstawką tożsamości jest lepsza niż jakikolwiek naturalny klucz, który może nie rosnąć monotonicznie.
źródło
Jeżeli to zależałoby ode mnie...
Musisz spełniać wymagania bazy danych i aplikacji.
Dodanie automatycznie zwiększającej się liczby całkowitej lub kolumny o długim identyfikatorze do każdej tabeli, która służy jako klucz podstawowy, spełnia wymagania bazy danych.
Następnie należy dodać co najmniej jeden inny unikalny indeks do tabeli, który będzie używany przez aplikację. Byłby to indeks na identyfikator_pracownika, identyfikator_konta lub identyfikator_klienta itp. Jeśli to możliwe, indeks ten nie powinien być indeksem złożonym.
Wolałbym indeksy na kilku polach indywidualnie w stosunku do indeksów złożonych. Baza danych będzie używać indeksów pojedynczego pola za każdym razem, gdy klauzula where zawiera te pola, ale użyje złożonego tylko wtedy, gdy podasz pola w dokładnie prawidłowej kolejności - co oznacza, że nie może użyć drugiego pola w indeksie złożonym, chyba że podasz zarówno pierwszą, jak i drugą w klauzuli where.
Jestem za korzystaniem z indeksów obliczanych lub typu funkcji - i polecam używanie ich zamiast indeksów złożonych. Ułatwia to używanie indeksu funkcji, używając tej samej funkcji w klauzuli where.
To zadba o wymagania aplikacji.
Jest wysoce prawdopodobne, że inne indeksy inne niż podstawowe są w rzeczywistości odwzorowaniami wartości klucza indeksów na wartość klucza podstawowego, a nie rowid (). Pozwala to na fizyczne sortowanie i usuwanie bez konieczności ponownego tworzenia tych indeksów.
źródło