我在postgres数据库中的一个表中有一个唯一的索引

"participation_uniqueness" UNIQUE, btree (event_id, firstname, lastname, email)

这很有效,但如果其中一个字段为零,它基本上会被忽略:
活动编号|名字|姓氏|电子邮件
1982年| John | Doe | [email protected]
1982年| Hans | Doe | [email protected]
1982年|空|空| [email protected]
1982年|空|空| [email protected]
如果值为空,我还希望应用唯一性约束,因此上面示例表中的最后一条记录不应该是可能的,因为它是针对唯一性约束的。
在Rails中,我可以简单地将其作为验证方法添加到我的模型中
participations
我想知道为什么这个验证会考虑使用validates_uniqueness_of :email, scope: [:event_id, :firstname, :lastname]进行唯一性检查,而SQL却不考虑?
研究这个主题我知道它是SQL标准,因为NULL被称为“丢失的信息”,并且不能将丢失的信息相互比较。
然而,从逻辑的角度来看,这对我来说毫无意义。我希望在这种情况下DB插入失败。例如,如果不实现这里发布的肮脏的解决方案,我怎么能做到这一点呢
https://www.pgrs.net/2008/01/11/postgresql-allows-duplicate-nulls-in-unique-columns/

最佳答案

使用部分索引有一个潜在的答案here

CREATE UNIQUE INDEX ab_c_null_idx ON my_table (a, b) WHERE c IS NULL;

Rails的行为不同,因为它在uniqueness validator中做的更多。它不仅仅是运行一个查询。

关于ruby-on-rails - Postgres唯一约束忽略空值,但Rails通过,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50813712/

10-12 01:26