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

时间:2015-06-22 10:50:46

标签: mysql ruby-on-rails rdbms

我在add_index ~ unique: true中看到schema.rb声明,并认为唯一性是的约束,而不是索引。使用索引是实现方式之一唯一性,程序员不应该指定RDBMS“如何”和索引加快搜索速度,但需要插入成本。事实上,还有另一种方法来保持唯一性约束吗?如果没有,为什么Rails只为我们提供add_index唯一性约束声明?

2 个答案:

答案 0 :(得分:2)

因为不需要其他方式。在引擎盖下,它们完全相同:当您定义UNIQUE约束时,会在该表上创建UNIQUE索引以强制执行它。

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

      

    因此,对于支持这两种功能的数据库,选择使用哪种功能通常会归结为首选样式和一致性。

    因此在Rails中使用索引是一致的。这就是原因。

  • 来自PostgreSQL's docs的引用:

      

    当为表定义唯一约束或主键时,PostgreSQL会自动创建唯一索引。索引涵盖构成主键或唯一约束的列(如果适用,则为多列索引),并且是强制执行约束的机制。

我没有在权威来源中找到MySQL的相关引用,但“谣言随处可见”。

答案 1 :(得分:1)

保证唯一性约束的唯一安全方法是在数据库级别强制执行它。它没有任何问题,事实上,这是真正正确的方法。任何数据库设计者或管理员都会向您确认。

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

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

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

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