Jak określić unikalne ograniczenie dla wielu kolumn w MySQL?

864

Mam stolik:

table votes (
    id,
    user,
    email,
    address,
    primary key(id),
);

Teraz chcę, aby kolumny użytkownik, adres e-mail, adres były unikalne (razem).

Jak to zrobić w MySql?

Oczywiście przykład jest tylko ... przykładem. Więc proszę nie martw się semantyką.

Niyaz
źródło

Odpowiedzi:

1436
ALTER TABLE `votes` ADD UNIQUE `unique_index`(`user`, `email`, `address`);
jonstjohn
źródło
31
Czy działałoby to poprawnie z klauzulą ​​ON DUPLICATE KEY instrukcji INSERT? Oznacza to, że gdybym próbował wstawić wiersz, który był w konflikcie z wartościami użytkownika / adresu e-mail / adresu innego wiersza, INSERT wykonałby zamiast tego działania określone w klauzuli ON DUPLICATE KEY?
clizzin
6
W ten sposób połączenie trzech byłoby wyjątkowe? Czy wszystkie trzy kolumny byłyby niepowtarzalne?
Gary Lindahl,
95
Dla osób korzystających ze środowiska roboczego MySQL: przejdź do karty Indeksy i wybierz UNIQUE jako swój typ. Nadaj swojemu indeksowi nazwę i sprawdź odpowiednie kolumny w sekcji „Kolumny indeksu”
Pakman
10
Podobnie jak ja, jeśli ktokolwiek znalazł to w wyszukiwarkach ... i aby odpowiedzieć na pytanie Clizzina, czy ON DUPLICATE KEY będzie działał z kluczem złożonym - absolutnie tak będzie, jednak będzie wymagało drobnych poprawek w składni. patrz stackoverflow.com/questions/9537710/...
Joe
2
jak sprawić, by działał nawet z wartością NULL. Jeśli wstawimy dwa takie same wiersze o wartości NULL, to nie
zadziała
237

Mam tabelę MySQL:

CREATE TABLE `content_html` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_box_elements` int(11) DEFAULT NULL,
  `id_router` int(11) DEFAULT NULL,
  `content` mediumtext COLLATE utf8_czech_ci NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_box_elements` (`id_box_elements`,`id_router`)
);

a UNIKALNY KLUCZ działa zgodnie z oczekiwaniami, pozwala na wiele NULL wierszy id_box_elements i id_router.

Korzystam z MySQL 5.1.42, więc prawdopodobnie pojawiła się aktualizacja omawianego wyżej problemu. Na szczęście działa i mam nadzieję, że tak pozostanie.

Frodik
źródło
34
Chciałem zaznaczyć tę odpowiedź, ponieważ pokazuje ona, jak utworzyć nową tabelę z unikalnym indeksem, w której powyższa odpowiedź jonstjohn mówi, jak zaktualizować istniejącą tabelę. Robią to samo, ale zależy to tylko od tego, czy tworzysz nowy stół, czy aktualizujesz już istniejący. :)
GazB
3
o co chodzi z tymi wszystkimi cytatami, czy mają jakiś cel?
puk
8
Dane wyjściowe pochodzą z narzędzia Adminer (www.adminer.org), które automatycznie wstawia te cudzysłowy, więc nie ma problemu z kolizją słów kluczowych mysql używanych jako nazwy kolumn.
Frodik
50

Wielokolumnowe unikalne indeksy nie działają w MySQL, jeśli masz wartość NULL w wierszu, ponieważ MySQL traktuje NULL jako unikalną wartość i przynajmniej obecnie nie ma logiki do obejścia go w indeksach wielokolumnowych. Tak, zachowanie jest szalone, ponieważ ogranicza wiele uzasadnionych aplikacji indeksów wielokolumnowych, ale takie właśnie jest ... Na razie jest to błąd, który został oznaczony jako „nie naprawi” na MySQL śledzenie błędów ...

niksoft
źródło
11
Dwa punkty wyjaśnienia: 1) takie zachowanie nie ma zastosowania ENGINE BDB, i 2) jest to udokumentowane zachowanie, chociaż IMHO nie zostało wystarczająco udokumentowane zbyt jawnie, biorąc pod uwagę, jak zaskakujące / nieprzyjemne może być. Zobacz dyskusję na temat błędu MySQL 25544 bugs.mysql.com/bug.php?id=25544 .
pilcrow
2
Dzięki za NULL heads up, rozwiązałem problem, który miałem ... Myślę, że pójdę z sumą kontrolną skrótu
Daniel Doezema
7
To nie jest odpowiedź. Powinien to być komentarz do pierwotnego pytania.
Ograniczone Zadośćuczynienie
Oficjalne dokumenty mówią: Zwróć uwagę, że od MySQL 5.1 BDB nie jest już obsługiwane.
George D.
2
Bardzo dobra informacja, ale nie odpowiedź. Jest tylko peryferyjnie związany z pytaniem.
billynoah
23

Próbowałeś tego?

UNIQUE KEY `thekey` (`user`,`email`,`address`)
Erick
źródło
Co powiedział Erick działa dobrze dla mnie: UNIQUE KEY thekey` ( user, email, address) `. Używam MYSQL w wersji 5.5.24 Możesz ustawić to nawet w PHPMYADMIN, jeśli go używasz. Używam wersji PMA 3.5.1.
WQC,
Wypróbowałem to z MySql 5.6. Działa od pierwszej próby. Dzięki Erick!
Lawrence
11

Działa to dla mysql w wersji 5.5.32

ALTER TABLE  `tablename` ADD UNIQUE (`column1` ,`column2`);
Rizon
źródło
1
Wydaje się, że działa bez pojedynczych cudzysłowów w nazwie kolumny.
Pratik Singhal
7

MySql 5 lub nowszy zachowuje się tak (właśnie przetestowałem):

  • możesz zdefiniować unikalne ograniczenia obejmujące kolumny zerowalne. Załóżmy, że definiujesz ograniczenie unikalne (A, B), w którym A nie jest zerowalne, ale B jest
  • oceniając takie ograniczenie, możesz mieć (A, null) tyle razy, ile chcesz (ta sama wartość A!)
  • możesz mieć tylko jedną parę (A, nie zerową B)

Przykład: PRODUCT_NAME, PRODUCT_VERSION „szkło”, zerowe „szkło”, zerowe „wino”, 1

Teraz, jeśli spróbujesz ponownie wstawić („wino” 1), zgłosi naruszenie zasad ograniczenia. Mam nadzieję, że to pomoże

Cristian Botiza
źródło
dzięki za wyjaśnienie. Mam unikalny (A, B, C) i nie wiedziałem, dlaczego pozwala na kombinacje wartości null z tymi samymi opcjami innymi niż null
Alexandru Topală
6

Możesz dodać wiele kolumn unikalne indeksy poprzez phpMyAdmin . (Testowałem w wersji 4.0.4)

Przejdź do strony struktury tabeli docelowej. Dodaj unikalny indeks do jednej z kolumn. Rozwiń listę Indeksy na dole strony struktury, aby zobaczyć dodany właśnie unikalny indeks. Kliknij ikonę edycji, aw kolejnym oknie dialogowym możesz dodać dodatkowe kolumny do tego unikalnego indeksu.

Vince K.
źródło
3

Robię to tak:

CREATE UNIQUE INDEX index_name ON TableName (Column1, Column2, Column3);

Moja konwencja dotycząca wyjątkowego index_nameto TableName_Column1_Column2_Column3_uindex.

Sam Malayek
źródło
2

Aby dodać unikalny indeks, wymagane są:

1) nazwa_tabeli
2) nazwa_indeksu
3) kolumny, do których chcesz dodać indeks

ALTER TABLE  `tablename` 
ADD UNIQUE index-name
(`column1` ,`column2`,`column3`,...,`columnN`);

W twoim przypadku możemy stworzyć unikalny indeks w następujący sposób:

ALTER TABLE `votes`ADD 
UNIQUE <votesuniqueindex>;(`user` ,`email`,`address`);
Sandeep Vanama
źródło
1

Jeśli chcesz uniknąć duplikatów w przyszłości. Utwórz kolejną kolumnę, powiedz id2.

UPDATE tablename SET id2 = id;

Teraz dodaj unikat do dwóch kolumn:

alter table tablename add unique index(columnname, id2);
kumar
źródło
1

Jeśli tworzysz tabelę w mysql, użyj następujących poleceń:

create table package_template_mapping (
mapping_id  int(10) not null auto_increment  ,
template_id int(10) NOT NULL ,
package_id  int(10) NOT NULL ,
remark      varchar(100),
primary key (mapping_id) ,
UNIQUE KEY template_fun_id (template_id , package_id)
);
Devendra Singraul
źródło
0

Najpierw pozbądź się istniejących duplikatów

delete a from votes as a, votes as b where a.id < b.id 
and a.user <=> b.user and a.email <=> b.email 
and a.address <=> b.address;

Następnie dodaj unikalne ograniczenie

ALTER TABLE votes ADD UNIQUE unique_index(user, email, address);

Sprawdź ograniczenie za pomocą

SHOW CREATE TABLE votes;

Pamiętaj, że użytkownik, adres e-mail i adres będą uważane za niepowtarzalne, jeśli którykolwiek z nich ma w nim wartość zerową.

Ganesh Krishnan
źródło
0

Dla PostgreSQL ... Nie działało to dla mnie z indeksem; dał mi błąd, więc zrobiłem to:

alter table table_name
add unique(column_name_1,column_name_2);

PostgreSQL nadał unikatowemu indeksowi własną nazwę. Myślę, że możesz zmienić nazwę indeksu w opcjach tabeli, jeśli trzeba ją zmienić ...

błąd piąty
źródło