我正在帮助开发 Rails 应用程序,目的是使该应用程序实现 Multi-Tenancy 。这意味着数据库表中将存在来自多个用户/组织的数据,并且访问路径通常是“获取我的组织的所有数据”。
我们使用 MYSQL 作为数据库。
默认情况下,Rails 使用 id 列在表上创建主键。 id 列自动递增。这在某些方面很好 - 行总是添加到表的末尾。但是,请考虑以下情况:
- 一个名为 foo 的对象。 foo 有一个 id,并且总是有一个 组织ID
- 随着时间的推移,每个组织都会在数据库中创建 foo,这些 foo 在整个表中交错排列(它们按 id 序列存储)
- 涉及列出该组织的所有 foo 的用例
我遇到的问题是,组织的 foo 在数据库中的位置并不紧密,事实上,它们的分布情况非常不理想。理想情况下,我会在表上创建一个主键 (organization_id, id),这将导致给定组织的所有 foos 并排在表中。
不幸的是,当我执行此操作时,Rails 给出了“模型 Foo 中表 foos 的主键未知”错误。我认为我可以通过使用 Rails 的复合键 gem 来解决这个问题,但似乎应该有某种方法可以使其在数据库级别透明。
有其他方法吗?
作为引用,数据库上更改索引的命令是:
更改表 foos 添加 key (id); # 需要,因为 id 列是自动递增的
更改表 foos 删除主键,添加主键(organization_id,id);
编辑1:一篇博客文章表明使用composite_primary_keys gem 成功做到了这一点。这让我对这种方法更有信心了,问题是它是 2008 年的,所以事情可能已经发生了变化。 http://www.joehruska.com/?p=6
编辑2:我正在考虑的另一个选择是分区 - 组织的数量可能不会超过最大分区,并且我可能可以将它们分组,而不会损失太多好处。不幸的是,关键引用是表上的每个唯一键都必须使用表分区表达式中的每一列。 (这还包括表的主键 - 来自 MYSQL 手册 http://dev.mysql.com/doc/refman/5.6/en/partitioning-limitations-partitioning-keys-unique-keys.html。
所以我仍然再次需要复合主键。让我有点惊讶的是,Rails 如此关心主键,而不仅仅是关心键的存在。
最佳答案
如果您不想使用composite_primary_keys,那么您可能会仅仅依靠:organization_id
或[:organization_id, :id]
上的标准索引而陷入困境
我的理解是,Rails 非常关心主键,因为它是对模型之间的关系做出的假设。也许它应该改进,你可以随时建议它作为 future 的功能。
关于mysql - 聚集索引、mysql 和 Rails,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17591364/