mysql防止多字段冗余记录

mysql防止多字段冗余记录,mysql,duplicates,Mysql,Duplicates,我这里有个问题。我有一个具有以下模式的表: id : int(11) not null primary key name : varchar(255) not null status : enum('ACTIVE','DELETED') 注意:记录是“软删除”的,我们只是将状态标记为“已删除” 问题是,我不希望a fella能够通过两个不同的线程创建相同名称(冗余)的条目,除非db中的现有记录处于“已删除”状态。有什么可能的方法可以做到这一点 我不能只对名称+状态进行唯一索引,因为如果我们在“

我这里有个问题。我有一个具有以下模式的表:

id : int(11) not null primary key
name : varchar(255) not null
status : enum('ACTIVE','DELETED')
注意:记录是“软删除”的,我们只是将状态标记为“已删除”

问题是,我不希望a fella能够通过两个不同的线程创建相同名称(冗余)的条目,除非db中的现有记录处于“已删除”状态。有什么可能的方法可以做到这一点


我不能只对名称+状态进行唯一索引,因为如果我们在“已删除”中有一个项目(同名),并且我的“希望被删除”区域为“活动”,则在我将该区域标记为“已删除”时会发生错误。

您应该通过编程实现您的目标。使用您的语言检查是否存在“名称+状态活动”以限制插入。

用您的数据添加一个“已删除”字段如何?然后你可以在name+status+deleted\u上有一个唯一的键。当status=ACTIVE时,deleted_at只能有一个值,这样将使唯一性仅在name上

编辑为清晰起见:

CREATE TABLE mytable (
  id int not null primary key,
  name varchar(255) not null,
  status enum('active','delete'),
  deleted_at datetime not null default 0,
  UNIQUE KEY one_active (name, status, deleted_at)
);

编辑#2:实际上,如果您将“检查是否已删除”代码检查为0,而不是检查status=deleted,那么您甚至不需要status字段。

mmm尝试过了,我们正在使用hibernate,如果多个客户端的速度足够快,我无法阻止冗余记录插入数据库。我同意。更复杂的约束应该在应用程序级别完成,例如通过Hibernate拦截器或DAO中的拦截器。这似乎还表明,考虑到对唯一性的限制,您将需要处理应用程序级锁定。是的,我知道正确的解决方案应该在应用程序级。为了让事情更简单,我想我会选择sql级别,至少现在是这样。@PaulBellora很遗憾,您不能将其设置为可空,否则唯一索引将无法按预期工作。它必须不为空,默认值必须为0,表示记录未被软删除。你自己试试看。如果将“已删除的”设置为“可为空”,则可以使用name='Associated unique',deleted_at创建任意数量的记录=NULL@zi42-你完全正确-我没有意识到-抱歉怀疑+1@PaulBellora永远不要因为怀疑而后悔。怀疑和反复检查你不确定的事情是非常健康的。太棒了!顺便说一句,我们需要状态,因为我不希望其他团队(例如后端)中断,至少目前是这样。我认为你的建议适合我的情况。非常感谢你的帮助!