如何在MySQL中为多个列指定唯一约束?

1041

我有一个表格:

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

现在,我想让列 user,email,address (三个一起)成为唯一的。

我该如何在MySQL中实现这一点?

当然,这只是一个示例,请不要担心语义。

15个回答

1686

要添加唯一约束,需要使用两个组件:

ALTER TABLE - 更改表模式和,

ADD UNIQUE - 添加唯一约束。

然后,您可以使用格式'name'('column1', 'column2'...)定义新的唯一键。

因此,对于您特定的问题,您可以使用以下命令:

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

121
对于使用MySQL Workbench的人:进入索引选项卡,选择UNIQUE作为索引类型。给你的索引起一个名字,并在“索引列”部分下检查适当的列。 - Pakman
17
如果有人像我一样是通过搜索引擎找到这篇文章的……回答Clizzin的问题,关于ON DUPLICATE KEY是否适用于复合键 - 它绝对适用,但需要对语法进行一些小调整。请参见https://dev59.com/e2kw5IYBdhLWcg3w9vJ- - Joe

313

我有一个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 `my_uniq_id` (`id_box_elements`,`id_router`)
);

唯一键(UNIQUE KEY)的作用和预期一样,可以允许id_box_elements和id_router有多个NULL行。

我正在运行MySQL 5.1.42,所以可能对上面讨论的问题进行了一些更新。幸运的是它能够正常工作,希望它能保持这种状态。


48
我想将这个答案标记为优秀,因为它展示了如何创建一个带有唯一索引的新表,而上面jonstjohn的答案则告诉你如何更新现有表格。它们做的事情是相同的,只取决于你是要创建新表还是更新现有表格。 :) - GazB
为什么要使用UNIQUE KEY my_uniq_id?在当前的MariaDB中,只使用UNIQUE就可以了。 - EML

63

如果在行中有空值,MySQL 中的多列唯一索引不起作用,因为 MySQL 将 NULL 视为唯一值,并且目前没有逻辑来解决多列索引中的此问题。是的,这种行为很疯狂,因为它限制了许多合法的多列索引应用,但事实就是如此...截至目前,这是一个已经标记为“不会修复”的 MySQL bug。


3
很有趣,我可以确认在MySQL 5.7.37中,在唯一列中可以有多个空值。 - Adam Fowler
这不是一个错误,你可以通过组合主键来解决这个问题。 - Syed Waqas Bukhary

27

您尝试过这个吗?

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

Erick所说的对我来说完全有效:UNIQUE KEY thekey (user,email,address)。我正在使用MYSQL版本5.5.24,如果您使用它,甚至可以在PHPMYADMIN中设置此项。我正在使用PMA的3.5.1版本。 - WQC

21

这适用于mysql 5.5.32版本

ALTER TABLE  `tablename` ADD UNIQUE (`column1` ,`column2`);

8

MySql 5或更高版本的行为如下(我刚刚测试过):

  • 您可以定义涉及可空列的唯一约束。例如,您定义了一个约束unique(A,B),其中A不可为空但B可为空
  • 在评估此类约束时,您可以有(A,null)多次(相同的A值!)
  • 您只能有一个(A,非null B)对

示例: 产品名称,产品版本 'glass',null 'glass',null 'wine',1

现在,如果您尝试再次插入('wine' 1),它将报告约束违规。 希望这可以帮助


6

您可以通过phpMyAdmin添加多列唯一索引。(我在版本4.0.4中进行了测试)

导航到目标表的结构页面。将唯一索引添加到其中一个列。展开结构页面底部的索引列表,以查看刚刚添加的唯一索引。单击编辑图标,在以下对话框中,您可以将其他列添加到该唯一索引。


6

5
我这样做:

我是这样做的:

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

我对唯一index_name的约定是TableName_Column1_Column2_Column3_uindex


4
如果您要在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)
);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接