【问题标题】:It is possible to modify unique constraint in sql?可以修改sql中的唯一约束吗?
【发布时间】:2020-07-24 03:34:15
【问题描述】:

我使用唯一约束来避免除空值之外的重复项,因为此列可以保持为空(它不是必填字段,但它有助于搜索,例如通过电子邮件搜索等)

在上述情况下,选择唯一约束是否正确?

替代方案 由于 unique 只允许一个空值,所以可以为唯一约束生成不同的默认值吗?即每一行都是唯一的。

【问题讨论】:

  • 如果你想允许 NULL 的重复并且正在使用 MySQL,那么唯一约束不会做你想要的。

标签: java mysql sql sqlite


【解决方案1】:

您同时标记了 的问题,所以我将同时介绍这两个问题。

SQLite

在 SQLite 中,UNIQUE 约束将按您的意愿工作。

UNIQUE constraint 的文档说:

出于 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 的列。

唯一键是唯一索引的同义词。

SQL 服务器

如 SQLite 文档中所述,Microsoft SQL Server 对 UNIQUE 索引的 NULL 处理遵循不同的解释。

UNIQUE INDEX 的文档说:

唯一索引中使用的列应设置为 NOT NULL,因为在创建唯一索引时多个空值被视为重复

要解决这个问题,请使用过滤索引,例如

CREATE UNIQUE INDEX Person_Email
    ON Person ( Email )
    WHERE Email IS NOT NULL;

【讨论】:

  • email 可以为空
  • @Coder1 是的,但过滤后的索引会排除那些,因此允许使用空电子邮件的多条记录,因为这些记录被过滤出索引。
  • 在电子邮件列上创建唯一索引后,它说:-------------------------------- ------------对数据库“唯一”执行 SQL 查询时出错:唯一约束失败:path.Emial。
  • 根据sqlite的结果。
  • 插入路径值 ('');
【解决方案2】:

您可以对生成的列使用技巧。像这样的:

alter table t add unique_val as
     ( concat(coalesce(col, ''), ':', (case when col is null then pk end))  ) unique;

其中pk 是主键列。

这会将NULL 值替换为每行上已知的唯一值。

【讨论】:

    猜你喜欢
    • 2010-12-16
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-01
    • 2016-03-13
    • 2014-02-14
    • 1970-01-01
    相关资源
    最近更新 更多