2013-01-08 20 views
18

Dziś dowiedziałem się, że możesz mieć klucz podstawowy za pomocą dwóch kolumn (tsql). PK musi być unikalny, ale obie kolumny nie (kombinacja musi być unikalna).Dwie kolumny jako klucze podstawowe w mysql?

Myślałem, że to było bardzo fajne. Pojawiły się co najmniej dwa pytania dotyczące SO, które zapytałem, gdzie ludzie krzyczeli na mnie, że robię moje (mysql) bazy danych źle, tylko z jedną osobą, która mówi, że zrobiłem to dobrze. Więc ... to pozostawia mi pewne wątpliwości:

Czy robi to, co myślę?

create table User(
    id INT primary key AUTO_INCREMENT , 
    ipaddr TEXT NOT NULL , 
    email TEXT NOT NULL 
); 
create table test(
    a INT NOT NULL , 
    b INT NOT NULL , 
    dummy INT NOT NULL , 
    FOREIGN KEY (a) REFERENCES User(id), 
    FOREIGN KEY (b) REFERENCES User(id), 
    PRIMARY KEY(a,b) 
); 

Pobiegłem poniżej więc wydaje się, że robi to, co myślę (combo musi być unikalna. Ale sama wartość w kolumnie nie muszą być unikalne). Czy powinienem być świadomy czegoś? Musiał być powód, dla którego nikt mi o tym nie wspomniał, jeśli chodzi o mysql?

mysql> insert into test(a,b,dummy) select 1,1,1; 
Query OK, 1 row affected (0.03 sec) 
Records: 1 Duplicates: 0 Warnings: 0 

mysql> insert into test(a,b,dummy) select 1,2,2; 
Query OK, 1 row affected (0.03 sec) 
Records: 1 Duplicates: 0 Warnings: 0 

mysql> insert into test(a,b,dummy) select 2,1,3; 
Query OK, 1 row affected (0.03 sec) 
Records: 1 Duplicates: 0 Warnings: 0 

mysql> insert into test(a,b,dummy) select 2,2,4; 
Query OK, 1 row affected (0.03 sec) 
Records: 1 Duplicates: 0 Warnings: 0 

mysql> insert into test(a,b,dummy) select 1,2,5; 
ERROR 1062 (23000): Duplicate entry '1-2' for key 'PRIMARY' 
+3

Sposób, w jaki to demonstrujesz, sugeruje mi, że rozumiesz to poprawnie. –

+0

@ s.bandara yep. Zamierzam to spekulować do analnych noobów. (krzycząc, że mój stół jest źle zaprojektowany i potrzebuję PK, ale nie sugeruję powyższego). –

+0

Cóż, jeden punkt, do którego należy się odnieść, byłby również uzasadnieniem dla tego, dlaczego chcesz to zrobić. –

Odpowiedz

1

wierzę, co się dzieje jest sparowane kolumny razem są podstawowym. Na przykład wiesz, że nie możesz mieć zduplikowanej kolumny głównej Ex: jeśli col "a" jest podstawową, nie możesz mieć dwóch wierszy, które mają taką samą wartość dla a.

W tym przykładzie masz dwa primaries; co oznacza, że ​​możesz mieć tylko jedną niepowtarzalną wartość dla każdej pary coli. Na przykład, jeśli col "a" i "b" są podstawowymi, a "c" nie jest: a | b | c 1,2,3 działa 1,4,5 działa i 5,1,6 działa 9,1,10 działa

ale nie można mieć: 9,8,10 9,8,6 ponieważ dla tej pary (9,8) można mieć tylko jedną wartość unikalną ...

Czy to ma sens, czy chciałbyś, bym się dalej rozwinęła?

2

Tak trzeba mieć świadomość, powielając swoje primary_key który jest połączeniu klucz w Twoim przypadku nie może być powielany.

W każdym razie, gdy ustawisz dwie PK, oznacza to, że twój podpis to PK1 + PK2, więc możesz zduplikować PK1 lub PK2, ale nie obydwa.

nadzieję, że pomogło

30

Jesteś na myśli to:

  • kluczy podstawowych (bez względu na to, ile kolumn są zaangażowani) muszą być unikalne
  • podstawowy klucz jest dwie kolumny a, b

Dlatego też i b razem musi być uniq ue.

Indywidualna wartość aib nie ma znaczenia.

+2

Ok, tylko chciałem się upewnić, że nie dostanę trochę w tyle. Zamiast tego ludzie krzyczeli na mnie na dwa pytania i kazali mi dodać kolumnę int o nazwie id, którą mogliby zasugerować i NO ONE: x –

4

Tak, jest to normalne działanie w SQL i działa (o złożonym kluczu podstawowym, w którym wiele pól razem stanowi unikalną wartość).

Dwie uwagi:

  1. upewnić się, że jest to konieczne. Często tak jest i wtedy jest w porządku. Ale czasami jest to znak, że musisz dalej normalizować swój model danych.

  2. Myślę, że nie chcesz tego robić, a b to klucze obce z innej tabeli, a następnie uczyń je złożonym kluczem podstawowym swojego stołu. Co się stanie, jeśli skonfigurujesz usuwanie kaskadowe, w którym jeden identyfikator użytkownika, ale nie drugi, zostanie usunięty? Więc złożony klucz podstawowy jest w porządku, ale wtedy nie chcesz, aby pochodziły z "niepowiązanych" kluczy obcych.

+1

+1, ale co masz na myśli przez "ale potem nie chcesz pochodzić" niepowiązane "klucze zagraniczne"? Powiedzmy, że robię kaskadowe usuwanie (atm nie jestem). Czy usunąłby wszystkie wiersze z a lub b jako usuniętym użytkownikiem? ale nie ma żadnych innych wierszy? Pasuje mi to. Jest to bardziej tabelę porównawczą (naprawdę powinna być nazywana danymi) –

4

Twoje myślenie jest dobre. Często korzystam z podstawowych kluczy o wielu polach, ponieważ sprawia to, że mój projekt bazy danych jest bardziej logiczny, zarządzalny i czytelny. Możesz myśleć o wielobazowych kluczach podstawowych, na przykład o unikalnej nazwie. Na przykład:

Multi-Pole podstawowe przyciski:

(First ,Middle, Last) 

Przykładowe wartości:

('Michael', 'A.', 'Kline') 

Nie może być wiele osób z 'pierwszym' Nazwa 'Michael' i/lub „Middle ' Nazwij.' i/lub "ostatnia" nazwa "Kline", ale jeśli chodzi o twoją bazę danych, może być tylko JEDEN "Michael A. Kline".

Zwykle klucz podstawowy z wieloma polami jest kombinacją innych kluczy podstawowych z innych tabel, a zawartość rekordu opisuje treść powiązaną z określonymi wartościami klucza. Na przykład:

Table #1: Student Records (KEY: student_id) 
Table #2: Course Records (KEY: course_id) 
Table #3: Student Grades (KEY: student_id, course_id) 

Mam nadzieję, że to pomoże.

2

Należy również pamiętać: Klucze podstawowe są automatycznie indeksowane w MySQL. Kolejność kolumn, o których wspominasz w kluczu podstawowym, ma znaczenie dla wydajności, jak wspomniano: here

Powiązane problemy