Jak poprawnie tworzyć złożone klucze podstawowe - MYSQL

182

Oto rażące uproszczenie intensywnej konfiguracji, nad którą pracuję. table_1i table_2oba mają zastępcze klucze podstawowe z automatycznym zwiększaniem jako identyfikator. infoto tabela zawierająca informacje o obu table_1i table_2.

table_1 (id, field)  
table_2 (id, field, field)
info ( ???, field)

Próbuję zdecydować, czy powinienem zrobić klucz główny infozłożony z identyfikatorów z table_1i table_2. Gdybym to zrobił, który z nich ma największy sens?
(w tym przykładzie łączę ID 11209 z ID 437)

INT(9)11209437 (mogę sobie wyobrazić, dlaczego to jest złe)
VARCHAR (10) 11209-437
DECIMAL (10,4)11209.437

Albo coś innego?

Czy dobrze byłoby użyć tego jako klucza podstawowego w bazie danych MYYSAM DB MYSQL?

Filip
źródło
Możliwy duplikat klucza podstawowego wielu kolumn w MySQL 5
dotancohen,

Odpowiedzi:

343

Użyłbym klucza złożonego (wielokolumnowego).

CREATE TABLE INFO (
    t1ID INT,
    t2ID INT,
    PRIMARY KEY (t1ID, t2ID)
) 

W ten sposób możesz mieć t1ID i t2ID jako klucze obce wskazujące również na ich odpowiednie tabele.

AlexCuse
źródło
2
Och, wow, więc w ten sposób tworzysz klucz złożony! wygląda na to, że zupełnie nie zrozumiałem tej koncepcji. Dziękuję Ci!! Czy coś w tym celu służy wyłącznie do celów indeksowania? Ponieważ w tym przypadku nie byłbym w stanie odwołać się do rekordu za pomocą tego kompozytu, nadal musiałbym to zrobić UPDATE info ... WHERE t1ID=11209 AND t2ID=437?
Filip
2
poprawny. Chociaż ponieważ obie kolumny powinny być unikalne, prawdopodobnie wystarczające byłoby t1ID = 11209.
AlexCuse
39
@AlexCuse kombinacja obu kolumn jest unikalna, ale dla t1ID = 11209 może istnieć dowolna liczba t2ID.
e18r
21

Nie uczyniłbym klucza podstawowego tabeli „informacji” złożonym z dwóch wartości z innych tabel.

Inni mogą lepiej przedstawić przyczyny, ale źle jest mieć kolumnę, która naprawdę składa się z dwóch informacji. Co jeśli chcesz z jakiegoś powodu posortować według identyfikatora z drugiej tabeli? Co jeśli chcesz policzyć, ile razy wartość z dowolnej tabeli jest obecna?

Zawsze trzymałbym je jako dwie odrębne kolumny. Możesz użyć dwukolumnowego klucza podstawowego w mysql ... KLUCZ PODSTAWOWY (id_a, id_b) ... ale wolę używać dwukolumnowego unikalnego indeksu i pola automatycznego klucza podstawowego.

wmorse
źródło
1
Masz całkowitą rację, jeśli chodzi o zachowanie odrębnych kolumn. Nie wiedziałem, że możesz mieć unikalny dwukolumnowy indeks i myślę, że to może być dla mnie dobra opcja. Czy mogę jednak zapytać, dlaczego nadal wolałbyś zachować klucz podstawowy jako funkcję automatycznego zwiększania?
Filip
3
Nie mam naprawdę ważnych powodów i przyznaję, że jest to punkt sporny między mną a niektórymi z moich kolegów, ponieważ bardziej ekonomiczne jest posiadanie mniejszej liczby kolumn. Łatwiej jest mi napisać sprzężenia na jednym kluczu obcym. Czasami znaczenie tych tabel „Mapowania między dwiema tabelami” staje się tak samo ważne jak oryginalne tabele, a klucz podstawowy staje się kolumną klucza obcego w jeszcze innych tabelach.
wmorse
Dziękuję Ci. Myślę, że to, co mówisz, ma sens i spróbuję jako unikalny dwukolumnowy indeks + klucz podstawowy z automatyczną inkrementacją
Filip
1
Wydaje mi się, że powodem z góry mojej głowy jest to, że chcesz stworzyć tabelę relacji. masz trzy tabele, powiedzmy rynek, walutę i dostawcę, dostawca może istnieć TYLKO na rynku RAZ, więc twoja tabela relacji może zawierać tylko jedną walutę, dzięki czemu utworzysz (id_market, id_provider), co oznacza, że ​​możesz tylko tworzyć to połączenie raz, próba dodania ponownie tego samego rynku i dostawcy nie powiedzie się, co oznacza, że ​​są one unikalne, to masz drugą kolumnę, powiedzmy id_currency, co oznacza, że ​​waluta jest pojedyncza w całej tabeli, czy to ma sens?
Christopher Thomas
1
Dla każdego, kto zobaczy ten wątek później, należy pamiętać, że przyczyną tego złego postępowania jest to, że narusza ono bardzo podstawową zasadę projektowania baz danych. Pierwsza normalna forma wymaga, aby każda informacja miała własną kolumnę. Nie ma praktycznie żadnego powodu, aby naruszać tę i wiele korzyści normalizacji struktury bazy danych.
smcjones
15

składnia jest CONSTRAINT constraint_name PRIMARY KEY(col1,col2,col3)na przykład:

CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)

powyższy przykład będzie działał, jeśli piszesz go podczas tworzenia tabeli, na przykład:

CREATE TABLE person (
   P_Id int ,
   ............,
   ............,
   CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
);

aby dodać to ograniczenie do istniejącej tabeli, musisz przestrzegać następującej składni

ALTER TABLE table_name ADD CONSTRAINT constraint_name PRIMARY KEY (P_Id,LastName)
Ritabrata Gautam
źródło
8

Załóżmy, że już utworzyłeś tabelę, teraz możesz użyć tego zapytania, aby utworzyć złożony klucz podstawowy

alter table employee add primary key(emp_id,emp_name);
Usman Yaqoob
źródło
5

Oprócz osobistych preferencji projektowych istnieją przypadki, w których chce się użyć złożonych kluczy podstawowych. Tabele mogą mieć dwa lub więcej pól, które zapewniają unikalną kombinację i niekoniecznie za pomocą kluczy obcych.

Na przykład, każdy stan USA ma zestaw unikalnych okręgów kongresowych. Chociaż wiele stanów może mieć CD-5 indywidualnie, nigdy nie będzie więcej niż jeden CD-5 w dowolnym z 50 stanów i odwrotnie. Dlatego utworzenie pola autonumerowania dla Massachusetts CD-5 byłoby zbędne.

Jeśli baza danych obsługuje dynamiczną stronę internetową, pisanie kodu do zapytania w kombinacji z dwoma polami może być znacznie prostsze niż wyodrębnianie / ponowne przesyłanie klucza z automatycznym kodowaniem.

Więc chociaż nie odpowiadam na pierwotne pytanie, z pewnością doceniam bezpośrednią odpowiedź Adama.

KiloVoltaire
źródło
4

Złożone klucze podstawowe są tym, czego chcesz, tam gdzie chcesz utworzyć relację wiele do wielu z tabelą faktów. Na przykład możesz mieć pakiet wynajmu wakacyjnego, który zawiera wiele nieruchomości. Z drugiej strony nieruchomość może być również dostępna jako część szeregu pakietów najmu, zarówno samodzielnie, jak i z innymi nieruchomościami. W tym scenariuszu ustanawiasz związek między nieruchomością a pakietem wynajmu za pomocą tabeli faktów o nieruchomości / pakiecie. Powiązanie właściwości z pakietem będzie unikalne, dołączysz tylko za pomocą property_id z tabelą właściwości i / lub id_pakietu z tabelą pakietów. Każda relacja jest unikalna, a klucz auto_increment jest zbędny, ponieważ nie będzie występował w żadnej innej tabeli. Zatem zdefiniowanie klucza złożonego jest odpowiedzią.

Adam Penny
źródło
1
CREATE  TABLE `mom`.`sec_subsection` (

  `idsec_sub` INT(11) NOT NULL ,

  `idSubSections` INT(11) NOT NULL ,

  PRIMARY KEY (`idsec_sub`, `idSubSections`) 

);
Mistrz umysłu
źródło
1

@AlexCuse Chciałem dodać to jako komentarz do twojej odpowiedzi, ale zrezygnowałem po wielu nieudanych próbach dodania nowego wiersza w komentarzach.

To powiedziawszy, t1ID jest unikalny w tabeli_1, ale to nie czyni go również unikalnym w tabeli INFO.

Na przykład:

Tabela_1 zawiera:
Identyfikator Pole
1 A
2 B

Tabela_2 ma:
Identyfikator Pole
1 X
2 Y

INFO może wtedy mieć:
t1ID pole t2ID
1 1 jakieś
1 2 dane
2 1 w każdym
2 2 rzędzie

Tak więc w tabeli INFO, aby jednoznacznie zidentyfikować wiersz, potrzebujesz zarówno t1ID, jak i t2ID

sactiw
źródło
nazywa się kluczem kompozytowym
Pavel P
1
@PavelP moja odpowiedź brzmi: komentarz Alexa „Chociaż ponieważ obie kolumny powinny być unikalne, prawdopodobnie wystarczające byłoby t1ID = 11209”. ... Zgadzam się, że użycie klucza kompozytowego jest prawidłowe, ale aby zidentyfikować dokładne dopasowanie, potrzebujesz zarówno t1ID, jak i t2ID ... Mam nadzieję, że teraz jest jasne.
sactiw