以下是我遇到的唯一约束问题:假设我有一个表app_user。它有一个列“name”和一列“is_active”。因此,如果“is_active”为false,则删除该用户。
现在我想要对“name”列进行唯一约束。然后用户被删除,然后有人想要再次添加具有相同名称的用户,由于唯一约束,它失败了。我可以将检查放在上层(对于用户触发的操作,这些操作并非真正发生,通常它可能足够安全,尽管它是额外的代码)。
但是我想建立一个PostgreSQL唯一约束,它只能在is_active = true的行上运行。
我查看了PostgreSQL 9 EXCLUDES功能。
我想出了类似的东西:
alter table test add exclude (name with =, is_active with ||)
所以这个想法是,所以存在一个独特的冲突,我必须有两个相同的名字,并且两个is_active也必须是真的。遗憾的是,在这种情况下||
运算符不存在。
无论如何可以实现吗?或者您是否建议其他仍然符合要求的解决方案(能够重新创建与已删除用户同名的用户)?一种选择是,这是不可能的,但阻止用户永远访问某个用户名有点强。
此外,业务逻辑并不真正依赖于非重复,但它仍然是一种健康的做法来防止它。在这种情况下,我将导入系统中的数据,并通过名称进行导入。所以,如果我有两个同名的记录,我就会遇到问题。如果有一个6个月之前被删除的记录,并且同时创建了一个新记录,那不是问题。
如果有一个解决方案也兼容其他SQL服务器,我会非常高兴,但我怀疑是否存在...此外,我宁愿不添加额外的表来实现这一目标。所以我想这可能是排除方式还是没有...
答案 0 :(得分:3)
您不需要排除约束。
部分唯一索引就够了
create unique index unique_active_name
on app_user (name)
where is_active;
(这假设is_active
被定义为boolean
)