ruby-on-rails - 两列之一为空时的唯一索引

标签 ruby-on-rails unique-constraint database-indexes

(Rails 4.2.1,Sqlite3)我有三个模型——M1、M2、M3。

M1 belongs_to M2

M1 也属于_to M3

M1 有一个 :name(字符串)字段。

我有以下必须验证的约束:

1) M1 记录可以关联 M2 或 M3,但不能同时关联两者。

2) M1名称在指定的M2或M3中必须是唯一的。

我已经在模型中实现了约束条件 (1),它按预期工作。 (我提到它只是因为它可能与场景有关)。

对于约束(2),我在迁移中添加了一个索引,如下所示:

add_index :m1s, [:name, :m2_id, :m3_id], unique: true, name: "idx_m1_name"

然后我调用:

> m2 = M2.create! # success
> m1_1 = M1.create!(name: 'm1_1', m2: m2) #success
> m1_2 = M1.create!(name: 'm1_1', m2: m2) # this line should fail, but doesn't

m1_1 和 m1_2 已创建 - 我预计 m1_2 应该由于唯一性约束而失败。

我检查了索引是否按预期添加。此外,根据约束 1,m3_id 在 m1_1 和 m1_2 中均为 nil,不确定是否相关。

为什么约束没有被检查?

最佳答案

所以 m3_id 在这两种情况下都是 NULL ?在 Sqlite3 中,空值被认为与唯一索引上下文中的另一个空值不同。

For the purposes of unique indices, all NULL values are considered to different from all other NULL values and are thus unique

参见 https://sqlite.org/lang_createindex.html

我认为在 MySQL 和 Postgres 中也是一样。

关于ruby-on-rails - 两列之一为空时的唯一索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34703803/

相关文章:

MySQL 唯一和 NULL 索引建议

SQLite 表约束 - 在多列上唯一

ruby-on-rails - 使用设计上下文的 "super"和 "super do |u|"之间的区别

html - 如何制作侧边栏?

mysql - 创建对同一个表的两个外键引用,其中一个具有唯一的复合索引

mysql - 对具有重复值的列建立索引

mysql - 为什么 MySQL 使用索引交集而不是组合索引?

postgresql - 如何在 PostgreSQL 中为具有 int4range 值的 hstore 类型创建一个运算符

ruby-on-rails - rails : elasticsearch error deploying to EC2 with Rubber

html - Rails - 使用 h() 转义 HTML 并排除特定标签