Sqlite NULL和唯一?

kat*_*tie 24 sql sqlite null unique unique-constraint

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

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

use*_*740 32

虽然以下解决了多个空值,但它没有解决与此类设计相关的任何"问题",除了可能的数据库/ SQL可移植性 - 因此,它可能不应被视为答案,并留在此仅供参考.


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

SQL标准要求强制执行UNIQUE约束,即使约束中的一个或多个列为NULL,但SQLite不执行此操作.这不是一个bug吗?

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

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

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

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

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

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

查看NULL处理比较.

  • 我有一个:用户拥有一张带有唯一 ID 的钥匙卡,这意味着没有两个用户可以拥有相同的钥匙。但有些用户不再拥有钥匙卡(NULL)。他们可能已将钥匙卡交给了其他用户。 (2认同)

Jan*_*cek 7

如果您希望您的唯一索引在两行相同时抛出错误,如果您忽略 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
Run Code Online (Sandbox Code Playgroud)