Rails 可以在没有索引的情况下处理数据库唯一性吗?

Can Rails deal with DB uniqueness without index?

我在 schema.rb 中看到 add_index ~ unique: true 语句,认为唯一性是 table 的约束,而不是 index。使用索引是实现唯一性的一种方式,程序员不应该指定给RDBMS "how"和索引来加快查找速度而承担插入成本。事实上,还有另一种方法来保持唯一性约束吗?如果不是,为什么 Rails 只为我们提供 add_index 唯一性约束声明?

保证唯一性约束的唯一安全方法是在数据库级别实施它。没有什么错,事实上,这才是真正正确的做法。任何数据库设计者或管理员都会向您确认。

Rails 提供了唯一性验证器,但它并不完全安全。事实上,它是基于对你的数据库的一个简单查询,但是在执行 select 和执行插入之间有一个小的时间间隔,这使得它成为可能(并且很可能在高并发系统中或者如果你的插入由于这种竞争条件,需要花费合理的时间)才能创建重复的记录。

因此,保证唯一性的唯一方法就是在数据库上建立唯一索引。如果您担心它,您可能需要阅读一些数据库设计书籍或资源,以不同的角度重新评估问题。

您仍然希望在模型中进行验证的原因是,数据库(通常)不会以用户友好的方式尝试解决冲突。模型中的验证将预先验证数据并防止 DBMS 引发异常。您可以检查验证结果并向用户显示友好消息。

尽管如此,数据库约束仍然存在,如果您的验证由于前面提到的竞争条件而通过,您的数据完整性将由引发异常的 DBMS 确保。

因为不需要其他方式。在引擎盖下它都是一样的:当你定义一个 UNIQUE 约束时,一个 UNIQUE 索引会在那个 table 上创建以强制执行它。

  • 来自DBA.SE的问题:When should I use a unique constraint instead of a unique index?

    So for a database that supports both features the choice of which to use will often come down to preferred style and consistency.

    所以在Rails中到处使用索引是一致的。就是这个原因。

  • 引自PostgreSQL's docs:

    PostgreSQL automatically creates a unique index when a unique constraint or primary key is defined for a table. The index covers the columns that make up the primary key or unique constraint (a multicolumn index, if appropriate), and is the mechanism that enforces the constraint.

我没有在权威来源中找到 MySQL 的相关引用,但是 "rumors are everywhere".