Як вказати унікальне обмеження для кількох стовпців у MySQL?


864

У мене є таблиця:

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

Тепер я хочу зробити колонки користувача, електронної пошти, адреси унікальною (разом).

Як це зробити в MySql?

Звичайно, приклад - це лише ... приклад. Тому, будь ласка, не хвилюйтесь щодо семантики.

Відповіді:


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

31
Чи правильно це буде працювати з пунктом ON DUPLICATE KEY для тверджень INSERT? Тобто, якби я намагався вставити рядок, який суперечив значенням користувача / електронної пошти / адреси іншого рядка, чи буде INSERT виконувати дії, визначені пунктом ON DUPLICATE KEY?
clizzin

6
Таким чином поєднання трьох було б унікальним? Або всі окремі три колонки були б унікальними?
Gary Lindahl

95
Для тих, хто використовує робочий стіл MySQL: перейдіть на вкладку "Індекси" та виберіть "УНІКАЛЬНИЙ" як тип. Назвіть ім’я свого індексу та перевірте відповідні стовпці в розділі "Стовпці індексу"
Пакман

10
Як і я, якщо хтось інший знайде це у пошукових системах ... і відповісти на запитання Клізіна про те, чи ON DUPLICATE KEY працюватиме із складеним ключем - це абсолютно так, проте це потребує незначних коригувань синтаксису. дивіться stackoverflow.com/questions/9537710/…
Joe

2
як змусити його працювати навіть із значенням NULL. Якщо ми вставимо два однакові рядки зі значенням NULL, це не працює ...
Васим А.

237

У мене таблиця 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`)
);

і UNIQUE KEY працює так, як очікувалося, він дозволяє кілька NULL рядків id_box_elements і id_router.

Я запускаю MySQL 5.1.42, тому, ймовірно, було якесь оновлення щодо проблеми, обговореної вище. На щастя, це працює і, сподіваємось, так і залишиться.


34
Я хотів позначити цю відповідь, оскільки вона показує вам, як створити нову таблицю з унікальним індексом, де відповідь jonstjohn вище говорить про те, як оновити існуючу таблицю. Вони роблять те ж саме, хоча просто залежить від того, створюєте ви нову таблицю або оновлюєте існуючу. :)
ГазБ

3
що з усіма зворотними цитатами, чи вони служать якійсь цілі?
puk

8
Це вихід з адміністратора (www.adminer.org), який автоматично вставляє ці зворотні котирування, тому немає проблеми зі стиканням ключових слів mysql, що використовуються як імена стовпців.
Фродик

50

Унікальні індекси з декількома стовпцями не працюють у MySQL, якщо у вас є значення NULL у рядку, оскільки MySQL трактує NULL як унікальне значення та принаймні на даний момент не має логіки обійти його в індексних колонках. Так, поведінка божевільна, тому що вона обмежує безліч законних застосувань багатоколонних індексів, але це те, що це є ... Наразі це помилка, яку зафіксували "не виправити" на MySQL помилка ...


11
Два моменти уточнення: 1) ця поведінка не відповідає ENGINE BDB, і 2) це документоване поведінка, хоча, ІМХО, недостатньо задокументоване, враховуючи, наскільки дивовижним / неприємним воно може бути. Див. Помилку MySQL 25544 bugs.mysql.com/bug.php?id=25544 для обговорення.
стовп

2
Дякую за голову NULL, вирішили питання, яке у мене було ... Я думаю, я піду з хеш-контрольною сумою
Даніель Доезма

7
Це не відповідь. Це має бути коментарем до початкового питання.
Обмежене спокутування

Офіційні документи кажуть: Зауважте, що, як і для MySQL 5.1, BDB вже не підтримується.
Джордж Д.

2
Дуже хороша інформація, але не відповідь. Є лише периферійне відношення до питання.
billynoah

23

Ви пробували це?

UNIQUE KEY `thekey` (`user`,`email`,`address`)

Що Erick сказав прекрасно працює для мене: UNIQUE KEY thekey` ( user, email, address) `. Я використовую MYSQL версії 5.5.24 Ви можете встановити це навіть у PHPMYADMIN, якщо ви його використовуєте. Я використовую 3.5.1 версію PMA.
WQC

Спробував це з MySql 5.6. Працює з першої спроби. Дякую Еріку!
Лоуренс


7

MySql 5 або вище поводиться так (я щойно тестував):

  • Ви можете визначити унікальні обмеження, що стосуються змінних стовпців. Скажімо, ви визначаєте унікальне обмеження (A, B), де A не є нульовим, але B є
  • при оцінці такого обмеження ви можете мати (A, null) стільки разів, скільки вам потрібно (те саме значення A!)
  • у вас може бути тільки одна (A, а не нульова B) пара

Приклад: PRODUCT_NAME, PRODUCT_VERSION 'келих', null 'келих', null 'wine', 1

Тепер, якщо ви спробуєте вставити знову ("wine" 1), це повідомить про порушення обмеження. Сподіваюся, це допоможе


дякую за пояснення. У мене є унікальний (A, B, C), і я не знав, чому це дозволяє комбінації null з однаковими ненульовими параметрами
Alexandru Topală

6

Ви можете додати унікальні індекси з декількома стовпцями через phpMyAdmin . (Я тестував у версії 4.0.4)

Перейдіть на сторінку структури для цільової таблиці. Додайте унікальний індекс в один із стовпців. Розгорніть список індексів у нижній частині сторінки структури, щоб побачити унікальний індекс, який ви тільки що додали. Клацніть піктограму редагування, і в наступному діалоговому вікні ви можете додати додаткові стовпці до цього унікального індексу.


3

Я роблю це так:

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

Моя конвенція про унікальне index_nameє TableName_Column1_Column2_Column3_uindex.


2

Для додавання унікального індексу потрібно:

1) table_name
2) index_name
3) стовпці, в які потрібно додати індекс

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

У вашому випадку ми можемо створити унікальний індекс таким чином:

ALTER TABLE `votes`ADD 
UNIQUE <votesuniqueindex>;(`user` ,`email`,`address`);

1

Якщо ви хочете уникнути дублікатів у майбутньому. Створіть інший стовпець скажіть id2.

UPDATE tablename SET id2 = id;

Тепер додайте унікальний на два стовпці:

alter table tablename add unique index(columnname, id2);

1

Якщо ви створюєте таблицю в mysql, використовуйте наступне:

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)
);

0

Спочатку позбудьтесь наявних дублікатів

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;

Потім додайте унікальне обмеження

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

Перевірте обмеження за допомогою

SHOW CREATE TABLE votes;

Зауважте, що користувач, електронна адреса та адреса будуть вважатися унікальними, якщо будь-яка з них має нульове значення.


0

Для PostgreSQL ... Це не працювало для мене з індексом; це дало мені помилку, тому я зробив це:

alter table table_name
add unique(column_name_1,column_name_2);

PostgreSQL дав унікальному індексу власну назву. Я думаю, ви можете змінити ім'я індексу в параметрах таблиці, якщо це потрібно змінити ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.