Sqlite NULL和唯一?

时间:2014-03-27 21:18:08

标签: sql sqlite null unique unique-constraint

我注意到在具有UNIQUE约束的列中我可以有NULL值:UNIQUE(col)

在某些情况下会产生任何问题吗?

3 个答案:

答案 0 :(得分:29)

虽然以下地址解决了多个空值,但解决任何"问题"与这样的设计相关联,除了可能的数据库/ SQL可移植性 - 因此,它应该被认为是答案,并留在这里仅供参考。


这实际上包含在SQLite FAQ中。这是一个设计选择 - SQLite(与SQL Server不同)选择多个NULL值计入索引中的唯一性。

The SQL standard requires that a UNIQUE constraint be enforced even if one or more of the columns in the constraint are NULL, but SQLite does not do this. Isn't that a bug?

  

也许您指的是SQL92中的以下语句:

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

该陈述含糊不清,至少有两种可能的解释:

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

  2.   
  3. 当且仅当表中没有两行在非空的唯一列子集中具有相同的值时,才会满足唯一约束。

  4.         

    SQLite遵循解释(1),PostgreSQL,MySQL,Oracle和Firebird也是如此。确实,Informix和Microsoft SQL Server使用了解释(2),但我们SQLite开发人员认为解释(1)是最自然的需求读取,我们也希望最大化与其他SQL数据库引擎的兼容性,以及大多数其他数据库引擎也与(1)一起使用,这就是SQLite所做的。

查看comparison of NULL handling

答案 1 :(得分:3)

您可以在表上创建2个触发器,以检查在任何插入或更新操作之前是否存在列为null的行,如果是,则引发异常。

class Features::AppRolesController < ApplicationController
  def index
  end
end

答案 2 :(得分:1)

如果你想要你的唯一索引在两行相同时抛出错误,如果你忽略了NULL列(并且不想使用Satyam的回答中的触发器)你可以做这样的事情

CREATE TABLE `test` (
    `Field1`    INTEGER,
    `Field2`    INTEGER
);
CREATE UNIQUE INDEX `ix` ON `test` (
    `Field1`,
    `Field2`
);
INSERT INTO `test`(`Field1`,`Field2`) VALUES (1,NULL);
INSERT INTO `test`(`Field1`,`Field2`) VALUES (1,NULL); -- This shouldn't be allowed

DROP INDEX IF EXISTS `ix`;
CREATE UNIQUE INDEX `ix2` ON `test` (
    `Field1`,
    ifnull(`Field2`, 0)  --use this instead
); --will fail