【问题标题】:Does MySQL ignore null values on unique constraints?MySQL 是否忽略唯一约束的空值?
【发布时间】:2011-04-12 08:25:40
【问题描述】:

我有一个我想要独一无二的电子邮件专栏。但我也希望它接受空值。我的数据库可以这样有 2 封空电子邮件吗?

【问题讨论】:

    标签: mysql database unique-constraint


    【解决方案1】:

    是的,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 值。

    【讨论】:

    • 关于它在 mysql 中的真实性的优秀评论,但不一定是普遍的。
    • 根据SQLite FAQ,行为在 MySQL、PostgreSQL、SQLite、Oracle 和 Firebird 中是相同的。
    • 请更新您的答案。 SQLServer 2008+ 绝对允许,您只需添加一个 WHERE 子句...在 2017 年,无论如何,没有人应该使用比 2008 年更旧的版本...stackoverflow.com/questions/767657/…
    • 这个小功能很难找到答案,不需要在数据库中添加新列或在非常旧的应用程序上升级 MySQL。我真的在寻找像 Postgres 这样的解决方案,我可以在其中使用 COALESCE,但似乎答案总是它不是一个错误,而是它的设计方式。甚至WHERE column IS NOT NULL 似乎都没有让我失望,因为我的 MySQL 版本不支持它。有人知道我在哪里可以看吗?
    • 注意:这也适用于具有更多列的唯一索引。因此,如果您希望 a、b 和 c 列是唯一的,您仍然可以在表中使用 null、b、c 的双行
    【解决方案2】:

    来自the docs

    "一个UNIQUE索引允许多个NULL 可以包含的列的值 无”

    这适用于除BDB 之外的所有引擎。

    【讨论】:

    • BDB 在当前 mysql 版本(从 5.1.12 开始)上不再可用。
    • 我的测试似乎表明 Java Derby 数据库 v10.13.1.1。类似地,在具有唯一索引的列中只允许一个空值。
    【解决方案3】:

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

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

    因为我在搜索“如何允许一个UNIQUENULL 值”时偶然发现了这个答案。对于在做同样的事情时可能偶然发现这个问题的其他人,我的其余答案是给你的......

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

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

    【讨论】:

    • 约束与索引无关。事实上,尽管事实上没有其他这样的行,但您甚至无法拥有一个具有 NULL 值的行。
    • @Pijusn “约束与索引无关”是什么意思?关于你的第二句话,我从来没有说过你可以有一个 NULL 值的行,这就是为什么我在帖子的开头说,只有当他没有设置使用空值时,这才是一个解决方案。跨度>
    • 我的意思是添加新元素失败不是因为UNIQUE 约束,而是因为NOT NULL 约束。我认为这个答案与问题无关,因为该问题专门针对 UNIQUE 约束的行为。
    • @Pijusn 我知道了。你是对的,我已经删除了其他建议的措辞。我误读了这个问题。但我相信这个答案对于那些偶然发现这个问题的用户仍然有用,就像我在试图找到一种方法来获得独特的“无”值时所做的那样,但错误地允许空能力。
    • 我发现这个答案很有用。但是,它也回答了here。这篇文章是我的谷歌搜索的第一个结果,虽然这个答案和链接的问题是我正在寻找的。​​span>
    【解决方案4】:

    避免可为空的唯一约束。您始终可以将该列放入新表中,使其非空且唯一,然后仅在您有值时才填充该表。这样可以确保正确强制执行对列的任何键依赖,并避免可能由 null 引起的任何问题。

    【讨论】:

    • 是的,但是您提出的几乎正是 mysql 在幕后所做的。如果内置了此功能,为什么要重新发明轮子?
    • 因为它不是有效的 SQL。我相信这个技巧将对所有想要(或需要)数据库无关设计的人有用。
    • @Arsen7 如果您有多个业务——每个业务都有多个客户,该怎么办。您将所有业务及其客户的电子邮件地址存储在一个文件中。所以你不能让 email_address 唯一,因为不同的企业可能有相同的客户。所以你必须做一个business_id和email_address的复合唯一索引。是否可以按照说明将其放入新表中?
    • 我有一个“电子邮件”列需要唯一或为空的情况。如果我要听从您的建议,我必须创建一个带有单个“电子邮件”列的新表。依靠这个 Mysql 特定的行为要容易得多,结果是一样的。客户不在乎我是否将电子邮件存储在新表中。此外,与数据库无关的设计常常被高估了。对于很多项目,您不能也可能不会轻易地从一个数据库切换到另一个数据库。
    • @djmj 当然,但是函数依赖对大多数人来说很重要,并且可为空的唯一约束版本不会强制执行与 BCNF 版本相同的依赖。因此,哪个选项或多或少实用可能取决于哪些依赖项对您很重要。这就是为什么值得考虑创建一个新表的原因。
    【解决方案5】:

    一个简单的答案是:No, it doesn't

    说明:根据唯一约束的定义(SQL-92)

    当且仅当表中没有两行在唯一列中具有相同的非空值时,才满足唯一约束

    这句话可以有两种解释:

    • 不允许两行具有相同的值,即 NULLNULL 是不允许的
    • 没有两个非空行可以有值,即NULLNULL 可以,但不允许使用StackOverflowStackOverflow

    由于 MySQL 遵循第二种解释,UNIQUE 约束列中允许有多个 NULL 值。其次,如果你尝试理解SQL中NULL的概念,你会发现两个NULL的值根本无法比较,因为SQL中的NULL指的是不可用或未赋值的值(你不能什么都没有比较)。现在,如果您不允许在UNIQUE 约束列中有多个NULL 值,那么您在SQL 中收缩了NULL 的含义。我会这样总结我的答案:

    MySQL 支持 UNIQUE 约束,但不以忽略 NULL 为代价 价值观

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-23
      • 1970-01-01
      • 1970-01-01
      • 2010-10-17
      相关资源
      最近更新 更多