字段特定值对表的唯一约束

Unique constraint on tables for particular values of a field

我有发票table。它有很多领域,但问题是围绕2个主要领域

我们的业务要求 InvoiceNo 是唯一的。但是,如果删除一行,我们可以重新使用 InvoiceNo

InvoiceNo    Deleted
123Er        1
123Er        0

以上是一个有效的用例。但我不想再有 123Er & 0 的记录。

是否可以在 2 个字段的组合上为某些值 Unique(InvoiceNo,Deleted=0)创建唯一键,还是我们应该使用存储过程或触发器?

您只需创建一个唯一键(InvoiceNo、Deleted),即可完成。我不明白你为什么要制作 (InvoiceNo, Deleted=0),这是不支持的。拥有这两列的唯一键可以满足您的需求。

更新: 我遇到了你的问题,你可能有 2 个相同值的已删除行。在这种情况下,我建议您将 something 添加到已删除值的 InvoiceNo 列中,这样它们就不会是唯一的。

例如: 你有123er,然后删除它,所以它变成了123er-1。当你删除另一个时,它变成123er-2。您甚至可以基本上在更新(之前)触发器中完成。

借助 function based index 在其他 RDBMS 系统中很容易实现

至于现在 MySql 没有这样的功能,但是从 5.7 版开始可以使用虚拟(或生成的)列来模拟它。

简单的工作示例:http://rextester.com/HGY68688

CREATE TABLE IF NOT EXISTS mytable1234(
  InvoiceNo varchar(10),
  Deleted int,
  xxx varchar(10) generated always as (case when deleted = 0 then InvoiceNo end) virtual
);

create unique index myindex12 on mytable1234( xxx );

INSERT INTO mytable1234( InvoiceNo, Deleted)  VALUES ('aaa1', 0 );
INSERT INTO mytable1234( InvoiceNo, Deleted)  VALUES ('aaa1', 1 );
INSERT INTO mytable1234( InvoiceNo, Deleted)  VALUES ('aaa1', 1 );

-- INSERT INTO mytable1234( InvoiceNo, Deleted)  VALUES ('aaa1', 0 );

如果您取消注释此代码段中的最后一个 INSERT,然后尝试 运行 此代码段,那么您将得到:Duplicate entry 'aaa1' for key 'myindex12' 错误。
这样,table中可能会有多条记录,deleted = 1的值相同,InvoiceNo,而deleted = 0的值只有一条,因为MySql会不允许这样。

您可以将字段重命名为 DeletedIfNull(或 IsActive)。

然后,如果该列处于活动状态,该字段将采用值“1”或 "true" 或其他任何值。对于任何其他值,它将是 NULL。然后你可以创建:

create unique index unq_t_invoiceno_isactive on t(invoiceno, isactive);

MySQL(虽然不是所有数据库)在定义唯一索引时允许重复。因此,这将解决您眼前的问题。