To pytanie pojawia się po przeczytaniu komentarza do tego pytania:
Tworząc tabelę „wiele do wielu”, należy utworzyć złożony klucz podstawowy na dwóch kolumnach klucza obcego, czy też utworzyć zastępczy klucz podstawowy „ID” z automatyczną inkrementacją i po prostu umieścić indeksy w dwóch kolumnach FK (i być może unikalne ograniczenie)? Jakie są konsekwencje dla wydajności wstawiania nowych rekordów / ponownego indeksowania w każdym przypadku?
Zasadniczo to:
PartDevice
----------
PartID (PK/FK)
DeviceID (PK/FK)
w porównaniu z tym:
PartDevice
----------
ID (PK/auto-increment)
PartID (FK)
DeviceID (FK)
Komentator mówi:
uczynienie dwóch identyfikatorów PK oznacza, że tabela jest fizycznie sortowana na dysku w tej kolejności. Więc jeśli wstawimy (Part1 / Device1), (Part1 / Device2), (Part2 / Device3), to (Part 1 / Device3) baza danych będzie musiała rozdzielić tabelę i wstawić ostatnią pomiędzy wpisy 2 i 3. Dla wielu rekordów, staje się to bardzo problematyczne, ponieważ wiąże się z tasowaniem setek, tysięcy lub milionów rekordów za każdym razem, gdy jest dodawany. Z kolei autoinkrementacja PK pozwala na dopięcie nowych rekordów do końca.
Pytam o to, że zawsze skłaniałem się do tworzenia złożonego klucza podstawowego bez zastępczej kolumny autoinkrementacji, ale nie jestem pewien, czy klucz zastępczy jest rzeczywiście bardziej wydajny.
źródło
Odpowiedzi:
W przypadku prostego mapowania wiele-do-wielu z dwiema kolumnami, nie widzę żadnych korzyści z posiadania klucza zastępczego. Posiadanie klucza podstawowego
(col1,col2)
jest gwarantowane jako unikalne (zakładając, że twojecol1
icol2
wartości w tabelach, do których się odwołujesz są unikalne), a oddzielny indeks na(col2,col1)
włączyłby te przypadki, w których odwrotna kolejność wykonywałaby się szybciej. Surogat to strata miejsca.Nie będziesz potrzebować indeksów w poszczególnych kolumnach, ponieważ tabela powinna być używana tylko do łączenia dwóch tabel, do których istnieją odniesienia.
Moim zdaniem ten komentarz, do którego odnosisz się w pytaniu, nie jest wart wykorzystanych przez niego elektronów. Wygląda na to, że autor uważa, że tabela jest przechowywana w tablicy, a nie w zbalansowanej strukturze drzewiastej o wyjątkowo wysokiej wydajności.
Po pierwsze, nigdy nie jest konieczne przechowywanie ani pobieranie posortowanej tabeli , tylko indeks. Indeks nie będzie przechowywany sekwencyjnie, będzie przechowywany w efektywny sposób, aby można go było szybko odzyskać.
Ponadto zdecydowana większość tabel bazy danych jest czytana znacznie częściej niż zapisywana. To sprawia, że wszystko, co robisz po stronie wybranej, jest znacznie bardziej istotne niż cokolwiek po stronie wkładki.
źródło
insert
będzie miało znaczenie, jeśli będzie to wykonywane tysiące razy na godzinę. Nie można go po prostu zignorować tylko dlatego, że stosunekinsert
doselect
wynosi <1. W tym przypadku klientowi zależy na tym, ile czasu zajmuje złożenie zamówienia.W przypadku tabel linków nie jest wymagany klucz zastępczy.
Jeden PK na (col1, col2) i inny unikalny indeks na (col2, col1) to wszystko, czego potrzebujesz
Chyba że używasz ORM, który nie może sobie poradzić i dyktuje ci projekt DB ...
Edycja: Odpowiedziałem to samo tutaj: SQL: Czy potrzebujesz automatycznego przyrostowego klucza podstawowego dla wielu tabel?
źródło
(col2, col1)
nie jest(col1, col2)
. PK(col1, col2)
może nie być odpowiedni dla wszystkich zapytań i generowania skanów, więc odwrócenie tego poprawia wydajność, ponieważ umożliwia wyszukiwanie, gdzie col2 jest lepsze. Na przykład walidacja FK, gdy tabela z col2 ma usunięcie. Stolik podrzędny może być sprawdzonyJeśli istnieje odwołanie do tabeli, może być potrzebny przyrostowy klucz podstawowy. W tabeli wiele-do-wielu mogą znajdować się szczegóły, które należy pobrać z innej tabeli przy użyciu przyrostowego klucza podstawowego.
na przykład
Można łatwo pobrać „Inne szczegóły”, używając PartDevice.ID jako FK. W związku z tym konieczne jest użycie przyrostowego klucza podstawowego.
źródło
Najkrótszym i najbardziej bezpośrednim sposobem, w jaki mogę odpowiedzieć na twoje pytanie, jest stwierdzenie, że wpłynie to na wydajność, jeśli dwie tabele, które łączysz, nie mają sekwencyjnych kluczy podstawowych. Jak powiedziałeś / cytowałeś, indeks tabeli dowiązań albo zostanie pofragmentowany, albo DBMS będzie pracował ciężej, aby wstawić rekordy, jeśli tablica dowiązań nie ma własnego sekwencyjnego klucza podstawowego. To jest powód, dla którego większość ludzi umieszcza sekwencyjnie rosnący klucz podstawowy w tabelach łączy.
źródło
Wygląda więc na to, że jeśli JEDYNYM zadaniem jest połączenie dwóch tabel, najlepszym PK będzie PK z dwoma kolumnami.
Ale jeśli służy to innym celom, dodaj kolejny NDX jako PK z obcymi kluczami i drugim unikalnym indeksem.
Indeks lub PK to najlepszy sposób na upewnienie się, że nie ma duplikatów. PK pozwala narzędziom takim jak Microsoft Management Studio wykonać część pracy (tworzenie widoków) za Ciebie
źródło