Как указать уникальное ограничение для нескольких столбцов в MySQL?

865

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

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

Теперь я хочу сделать столбцы user, email, address уникальными (вместе).

Как мне сделать это в MySql?

Конечно, пример просто ... пример. Поэтому, пожалуйста, не беспокойтесь о семантике.

Нияз
источник

Ответы:

1436
ALTER TABLE `votes` ADD UNIQUE `unique_index`(`user`, `email`, `address`);
jonstjohn
источник
31
Будет ли это работать правильно с предложением ON DUPLICATE KEY операторов INSERT? То есть, если я пытаюсь вставить строку, которая конфликтует со значениями пользователя / адреса электронной почты / адреса другой строки, будет ли INSERT выполнять действия, указанные в предложении ON DUPLICATE KEY?
clizzin
6
Таким образом, комбинация из трех будет уникальной? Или все три отдельных столбца будут уникальными?
Гэри Линдал
95
Для тех, кто использует MySQL Workbench: перейдите на вкладку Indexes и выберите UNIQUE в качестве вашего типа. Дайте вашему индексу имя и проверьте соответствующие столбцы в разделе «Столбцы индекса»
Pakman
10
Как и я, если кто-то еще узнал об этом из поисковых систем ... и чтобы ответить на вопрос Клиззина о том, будет ли ON DUPLICATE KEY работать с составным ключом, - это абсолютно точно, однако это потребует незначительных корректировок синтаксиса. см. stackoverflow.com/questions/9537710/…
Джо
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 работает так, как ожидалось, он допускает несколько пустых строк id_box_elements и id_router.

Я использую MySQL 5.1.42, поэтому, возможно, произошли некоторые изменения в проблеме, рассмотренной выше. К счастью, это работает и, надеюсь, так и останется.

Frodik
источник
34
Я хотел пометить этот ответ, так как он показывает, как создать новую таблицу с уникальным индексом, где, как в ответе jonstjohn выше, рассказывается, как обновить существующую таблицу. Они делают то же самое, хотя зависит только от того, создаете ли вы новую таблицу или обновляете существующую. :)
ГазБ
3
что со всеми обратными цитатами, они служат какой-то цели?
Пук
8
Он выводится из Adminer (www.adminer.org), который автоматически вставляет эти обратные кавычки, поэтому проблем со связыванием ключевых слов mysql, используемых в качестве имен столбцов, не возникает.
Фродик
50

Многостолбцовые уникальные индексы не работают в MySQL, если в строке указано значение NULL, поскольку MySQL рассматривает NULL как уникальное значение и, по крайней мере, в настоящее время не имеет логики для его обхода в многостолбцовых индексах. Да, это безумное поведение, потому что оно ограничивает множество легитимных приложений многостолбцовых индексов, но это то, чем оно является ... На данный момент это ошибка, которая была помечена как "не исправит" в MySQL. ошибка-трек ...

niksoft
источник
11
Два уточняющих момента: 1) это поведение не выполняется ENGINE BDB, и, 2) это документированное поведение, хотя, ИМХО, не документировано достаточно открыто, учитывая, насколько оно может быть удивительным / неприятным. См. MySQL bug 25544 bugs.mysql.com/bug.php?id=25544 для обсуждения.
Пилкроу
2
Спасибо за NULL
заголовки, решил
7
Это не ответ. Это должен быть комментарий к исходному вопросу.
Ограниченное искупление
Официальные документы говорят: обратите внимание, что, начиная с MySQL 5.1, BDB больше не поддерживается.
Джордж Д.
2
Очень хорошая информация, но не ответ. Это только периферийно связано с вопросом.
Биллиноа
23

Вы пробовали это?

UNIQUE KEY `thekey` (`user`,`email`,`address`)
Erick
источник
Что Erick сказал прекрасно работает для меня: UNIQUE KEY thekey` ( user, email, address) `. Я использую MYSQL версии 5.5.24. Вы можете установить это даже в PHPMYADMIN, если вы его используете. Я использую 3.5.1 версию PMA.
WQC
Пробовал с MySql 5.6. Работает с первой попытки. Спасибо, Эрик!
Лоуренс
11

Это работает для MySQL версии 5.5.32

ALTER TABLE  `tablename` ADD UNIQUE (`column1` ,`column2`);
Rizon
источник
1
Кажется, работает без одинарных кавычек на имя столбца.
Пратик Сингхал
7

MySql 5 или выше ведет себя так (я только что проверил):

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

Пример: PRODUCT_NAME, PRODUCT_VERSION 'стекло', ноль 'стекло', ноль 'вино', 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 дал уникальному индексу собственное имя. Я думаю, вы можете изменить имя индекса в опциях для таблицы, если это необходимо изменить ...

bugthefifth
источник