聚集索引、mysql和Rails

聚集索引、mysql和Rails,mysql,ruby-on-rails,Mysql,Ruby On Rails,我正在帮助一个Rails应用程序,目的是使该应用程序成为多租户的。这意味着数据库表中会有来自多个用户/组织的数据,访问路径通常是“为我的组织获取所有数据” 我们使用MYSQL作为数据库 默认情况下,Rails使用id列在表上创建主键。id列是自动递增的。这在某些方面很好——行总是添加到表的末尾。然而,考虑以下情况: 一个名为foo的对象。foo有一个id,并且总是有一个 机构识别号 随着时间的推移,每个组织都会在数据库中创建foo,这些foo 在整个表中交错(它们以id顺序存储) 一个涉及列出

我正在帮助一个Rails应用程序,目的是使该应用程序成为多租户的。这意味着数据库表中会有来自多个用户/组织的数据,访问路径通常是“为我的组织获取所有数据”

我们使用MYSQL作为数据库

默认情况下,Rails使用id列在表上创建主键。id列是自动递增的。这在某些方面很好——行总是添加到表的末尾。然而,考虑以下情况:

  • 一个名为foo的对象。foo有一个id,并且总是有一个 机构识别号
  • 随着时间的推移,每个组织都会在数据库中创建foo,这些foo 在整个表中交错(它们以id顺序存储)
  • 一个涉及列出该组织所有FoO的用例
我的问题是,一个组织的FOO在数据库中的位置并不紧密,事实上,它们的分布非常不理想。理想情况下,我会在表中创建一个主键(organization_id,id),这将导致给定组织的所有foo在表中并排出现

不幸的是,当我这样做时,Rails给了我一个“模型Foo中表foos的未知主键”错误。我想我可以通过使用复合键gem-to-rails来处理这个问题,但是似乎应该有某种方法在数据库级别使其透明

有没有其他办法

作为参考,数据库上更改我的索引的命令为:

ALTER TABLE foos ADD KEY(id);#需要,因为id列是自动递增的

更改表foos删除主键,添加主键(组织id,id)

编辑1:一篇博客文章,表明使用复合_主_键成功地做到了这一点。这让我对这种方法更有信心,问题是这是从2008年开始的,所以事情可能已经开始了

编辑2:我正在考虑的另一个选择是分区——组织的数量可能不会超过最大分区,我可能会对它们进行分组,而不会损失太多好处。不幸的是,键引号是表上的每个唯一键都必须使用表分区表达式中的每一列。(这还包括表的主键-来自MYSQL手册


所以我还是需要一个复合主键。我有点惊讶Rails如此关心主键,而不仅仅是有一个键存在。

如果你不想使用复合主键,那么你可能仅仅依靠
:organization\u id
[:organization\u id,:id]上的标准索引就卡住了

我的理解是Rails非常关心PrimaryKeys,因为它假设了模型之间的关系。也许它应该改进,你可以建议它作为未来的功能。

很抱歉,我不知道复合PrimaryKeys在数据库级别是如何不透明的,它与
alter选项卡有什么关系le
事情?对不起,我的意思是相反的。我想要对Rails应用程序透明的东西,而不是寻找对数据库透明的东西。在数据库级别调整性能时,我通常的目标是进行应用层不知道的更改—添加索引、更改Optimier参数我发现了一篇博客文章,表明复合_主键gem(我将在上面添加)取得了成功,但我仍然希望通过移动到复合_主键来避免我的应用程序可能发生的变化——可以说这可能会破坏升级(到rails 4)。我知道它关心的是id是自动递增的和唯一的,我只是不清楚为什么它介意它是主键。我主要关心的是,标准索引仍然会给我的数据库提供大量IO和随机读取,而聚类索引可以避免这一点。但我也看到Postgres甚至不支持c聚集索引,所以可能我对什么都不抱幻想。啊,是的,你最初的问题是mysql,所以我的回答是。我完全理解你的担心,但除非你想在组织id上设置水平分区(除非你只有几个,否则不太好)我会留下的。我不知道数据有多大,但我做过大的工作,不会太在意这个。对不起,应该更清楚。Rails对数据库不太挑剔,所以另一个选择是改为Postgres。但是Postgres根本不支持聚集索引,所以很明显他们觉得这不是问题。sample case我在foo表中创建了大约300万行,分为1000个组织。我循环加载了它们,因此foo分布在整个数据库中。按id聚集,查询一个组织的所有foo需要10秒钟(在我的低规格服务器上)下一个问题是我是否会有300万条记录。如果你看的是几百万条记录,我会说不要看,因为它通常很容易放进内存。体面的模式和索引设计以及避免疯狂的SQL基本上就是处理这么大的数据所需要的。是的,我有点失望我的日常工作我有一个(Oracle)数据库,它正是这个优化问题,这是生产中的一个难题。我告诉自己我不会这么做。但我的应用程序的大小应该小很多。啊,好吧。