我注意到在具有UNIQUE约束的列中我可以有NULL值:UNIQUE(col)
在某些情况下会产生任何问题吗?
答案 0 :(得分:29)
虽然以下地址解决了多个空值,但不解决任何"问题"与这样的设计相关联,除了可能的数据库/ SQL可移植性 - 因此,它应该不被认为是答案,并留在这里仅供参考。
这实际上包含在SQLite FAQ中。这是一个设计选择 - SQLite(与SQL Server不同)选择多个NULL值不计入索引中的唯一性。
也许您指的是SQL92中的以下语句:
- 当且仅当表中没有两行在唯一列中具有相同的非空值时,才满足唯一约束。
该陈述含糊不清,至少有两种可能的解释:
当且仅当表中没有两行具有相同的值并且在唯一列中具有非空值时,才满足唯一约束。
- 醇>
当且仅当表中没有两行在非空的唯一列子集中具有相同的值时,才会满足唯一约束。
SQLite遵循解释(1),PostgreSQL,MySQL,Oracle和Firebird也是如此。确实,Informix和Microsoft SQL Server使用了解释(2),但我们SQLite开发人员认为解释(1)是最自然的需求读取,我们也希望最大化与其他SQL数据库引擎的兼容性,以及大多数其他数据库引擎也与(1)一起使用,这就是SQLite所做的。
答案 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