2013-07-11 91 views
0

我正在帮助一个Rails应用程序,其目的是让该应用程序成为多租户应用程序。这意味着数据库表中会有来自多个用户/组织的数据,并且通常访问路径将沿着“为我的组织获取所有数据”的路线。集群索引,mysql和Rails

我们使用MYSQL作为数据库。

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

  • 一个名为foo的对象。一个Foo有一个id,始终有一个 organisation_id
  • 随着时间的推移每个组织在数据库中创建的Foo,这些FOOS 在整个表(它们存储在ID序列)交错
  • ,涉及到上市用例这个组织的所有foos

我遇到的问题是组织的foos不在数据库中紧密地位于一起,实际上他们是非常不理想的。理想情况下,我会在表上创建(organisation_id,id)的主键,这将导致给定组织的所有表单并排放置在表中。

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

是否有替代方法?

作为参考,对数据库的命令改变我指数是:

ALTER TABLE FOOS添加项(ID); #需要,因为ID列是自动增加的

ALTER TABLE foos DROP PRIMARY KEY,ADD PRIMARY KEY(organisation_id,id);

编辑1:一个博客文章,指出成功与composite_primary_keys gem完全相同。这让我对这种方法有了更多的信心,问题在于它是从2008年开始的,所以事情可能已经开始了。编辑2:我正在考虑的另一个选项是分区 - 组织的数量可能不会超过最大分区,并且我可能会将它们分组一点,而不会损失太多的好处。不幸的是,关键引用是表上的每个唯一键必须使用表的分区表达式中的每一列。 (这也包括表的主键 - 来自MySQL手册http://dev.mysql.com/doc/refman/5.6/en/partitioning-limitations-partitioning-keys-unique-keys.html

所以我还是回来需要一个复合主键再次我有点惊讶的是,Rails的关心这么多关于主键,而不是简单的一个关键是存在的。

+0

对不起,我没有看到composite_primary_keys在数据库级别不透明以及它如何与'alter table'事物相关? –

+0

对不起,我的意思是相反。我想要一些对Rails应用程序透明的东西,而不是寻找对数据库透明的东西。调整数据库级别的性能时,我通常的目标是进行应用程序层不知道的更改 - 添加索引,更改优化器参数。我发现了一篇博客文章,指出composite_primary_keys gem(我将在上面添加)取得成功,但我仍然倾向于通过转到composite_primary_keys来避免可能会发生的更改,这可能会导致升级失败(到导轨4)。 – PaulL

回答

0

如果你不想使用composite_primary_keys那么你可能被卡住仅仅依靠对:organisation_id[:organisation_id, :id] 我理解的标准指数是Rails所关心PrimaryKeys这么多,因为的假设是模型之间的关系。也许它应该得到改进,你总是可以建议它作为未来的功能。

+0

我知道它关心的是自动递增和唯一的id,我只是不清楚为什么它认为它是主键。我主要关心的是,标准索引仍然会给我很多IO数据和随机读取数据库的数据,而聚簇索引会避免这种情况。但是我也看到Postgres并没有真正支持聚簇索引,所以也许我没有任何偏执。 – PaulL

+0

嗯,你最初的问题是说mysql,所以我的回复。我完全理解你的担忧,但除非你想在organisation_id上设置水平分区(除非你只有几个,否则不是很好),否则我会离开它。我不知道这些数据有多大,但是我从事过大量工作,不会太在意这一点。 – TomDunning

+0

对不起,应该更清楚了。 Rails对数据库并不是太挑剔,所以另一种选择是改变为Postgres。但postgres根本不支持聚簇索引,显然他们不觉得这是一个问题。我创建的一个示例案例将大约300万行加载到foo表中,并将其分成1000个组织。我把它们循环加载,所以foos遍布整个数据库。通过id聚集,需要10秒钟查询所有foos组织(在我的低规格服务器上),通过org_id聚集,id需要300ms。下一个问题是,如果我有300万条记录。 – PaulL