MySQL是否会根据唯一约束忽略空值?


Answers:


422

是的,MySQL在具有唯一约束的列中允许多个NULL。

CREATE TABLE table1 (x INT NULL UNIQUE);
INSERT table1 VALUES (1);
INSERT table1 VALUES (1);   -- Duplicate entry '1' for key 'x'
INSERT table1 VALUES (NULL);
INSERT table1 VALUES (NULL);
SELECT * FROM table1;

结果:

x
NULL
NULL
1

并非对于所有数据库都是如此。例如,SQL Server 2005和更早的版本仅在具有唯一约束的列中允许单个NULL值。


37
关于它在mysql中的正确性的出色评论,但不一定总的来说。
user2910265

11
根据SQLite FAQ,在MySQL,PostgreSQL,SQLite,Oracle和Firebird中,行为相同的。
阿米尔·阿里·阿克巴里

4
请更新您的答案。SQLServer的2008+绝对允许的情况下,你只需要添加一个WHERE子句...在2017年,没有人应该是一个较旧的版本比2008年反正... stackoverflow.com/questions/767657/...
马修特科特

这个小功能很难找到答案,不需要在数据库中添加新列或在非常老的应用程序上升级MySQL。我确实在寻找像Postgres这样的解决方案,可以在其中使用COALESCE,但似乎答案始终是它的设计方式并非错误。甚至不WHERE column IS NOT NULL似乎它不在我的版本的MySQL支持令我失望。有人知道我在哪里看吗?
newdark-it

1
注意:这也适用于具有更多列的唯一索引。因此,如果您希望a,b和c列是唯一的,那么您仍然可以在表中包含带null,b,c的双行
Mihai Crăiță 19/10/13


7

我不确定作者最初只是在问这是否允许重复值,还是在这里有一个隐含的问题,问“ NULL在使用时如何允许重复值UNIQUE?” 或“如何只允许一个UNIQUE NULL值?”

该问题已得到解答,是的NULL,使用UNIQUE索引时可以有重复的值。

由于我在寻找“如何允许一个UNIQUE NULL值”时偶然发现了这个答案。对于可能在执行此操作时偶然发现此问题的其他任何人,我剩下的答案都是给您的...

在MySQL中,您不能有一个UNIQUE NULL值,但是可以UNIQUE通过插入一个空字符串的值来获得一个空值。

警告:字符串以外的数字和类型可能默认为0或其他默认值。


1
约束与索引无关。实际上,即使没有一行这样的值,您甚至都无法包含NULL值的一行。
Pijusn

1
@Pijusn“约束与索引无关”是什么意思?关于第二句话,我从来没有说过可以有一个带有NULL值的行,这就是为什么我在帖子开头提到的原因,只有当他不设置使用null值时,这才是解决方案。
bluegman991

我的意思是添加新元素失败不是因为UNIQUE约束,而是因为NOT NULL约束。我认为这个答案与这个问题无关,因为这个问题专门关于UNIQUE约束的行为。
Pijusn

@Pijusn我懂了。没错,我删除了暗示的措词。我看错了问题。但是我相信答案对于那些偶然发现这个问题的用户仍然有用,就像我在尝试找到具有唯一“无”值但错误地允许空值能力的方法时那样。
bluegman991

1
我发现这个答案很有用。但是,这里也回答。这篇文章是我的Google搜索的第一个结果,尽管这个答案和链接的问题正是我想要的。
Kingledion

5

避免可为空的唯一约束。您始终可以将列放在新表中,使其变为非空且唯一,然后仅在有值时填充该表。这样可以确保对列的任何键依赖关系都能得到正确实施,并避免了可能由null引起的任何问题。


6
是的,但是您建议的几乎完全是mysql在幕后所做的事情。如果内置此功能,为什么还要重新发明轮子呢?
ProfileTwist

2
因为它不是有效的SQL。我相信该技巧对所有想要(或需要)数据库不可知设计的人都将是有用的。
2014年

@ Arsen7如果您有多个业务-每个都有多个客户,该怎么办。您将所有业务及其客户的电子邮件地址存储在一个文件中。因此,您不能使email_address唯一,因为不同的企业可能具有相同的客户端。因此,您必须制作一个business_id和email_address的复合唯一索引。是否可以将其放在新表中-如所解释的那样?
Gerhard Liebenberg

4
我遇到“电子邮件”列需要唯一或为空的情况。如果我要听从您的建议,则必须用一个“电子邮件”列创建一个新表。依赖于此Mysql特定的行为要容易得多,并且结果是相同的。客户不在乎我是否将电子邮件存储在新表中。同样,数据库不可知论的设计经常被高估。对于许多项目,您不能而且很可能不会轻易地从一个数据库切换到另一个数据库。
conradkleinespel

1
@djmj可以肯定,但是功能依赖性对于大多数人来说很重要,并且可为空的唯一约束版本与BCNF版本没有相同的依赖性。因此,哪个选项或多或少是可行的,可能取决于哪个依赖项对您很重要。这就是为什么值得考虑创建一个新表的原因。
nvogel
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.