我使用唯一约束来避免除了null值之外的重复,因为此列可以保持为null(这不是必填字段,但它有助于通过电子邮件e.t.c进行搜索(
在上述情况下,选择唯一约束是否正确?
可选由于unique只允许一个null值,因此是否可以为unique约束生成不同的默认值?i-e对于每一行都是唯一的。
您标记了sqlite和mysql这两个问题,所以我将同时介绍这两个。
SQLite
在SQLite中,UNIQUE约束将根据需要发挥作用。
UNIQUE约束的文档中写道:
出于UNIQUE约束的目的,NULL值被认为不同于所有其他值,包括其他NULL。
CREATE INDEX的文档中写道:
如果UNIQUE关键字出现在CREATE和INDEX之间,则不允许出现重复的索引项。任何插入重复条目的尝试都将导致错误。出于唯一索引的目的,所有NULL值都被视为不同于所有其他NULL值,因此是唯一的。这是SQL-92标准的两种可能解释之一(标准中的语言不明确(,也是PostgreSQL、MySQL、Firebird和Oracle遵循的解释。Informix和Microsoft SQL Server遵循该标准的其他解释。
但是,在大多数其他数据库中,UNIQUE约束的列不能为NULL,因此为了一致性,我建议使用UNIQUE INDEX,以免混淆人员。
MySQL
在MySQL中,UNIQUE约束将根据您的需要发挥作用。
Unique Indexes的文档中写道:
UNIQUE
索引允许为可以包含NULL
的列提供多个NULL
值。
UNIQUE KEY是UNIQUE INDEX的同义词。
SQL Server
正如SQLite文档中所提到的,Microsoft SQL Server对UNIQUE索引的NULL处理有不同的解释。
UNIQUE INDEX的文档中写道:
在唯一索引中使用的列应设置为NOT NULL,因为创建唯一索引时,多个NULL值被视为重复。
要解决此问题,请使用过滤索引,例如
CREATE UNIQUE INDEX Person_Email
ON Person ( Email )
WHERE Email IS NOT NULL;
您可以对生成的列使用技巧。类似这样的东西:
alter table t add unique_val as
( concat(coalesce(col, ''), ':', (case when col is null then pk end)) ) unique;
其中pk
是主键列。
这将用每行上已知的唯一值替换NULL
值。