Rails 5,用Postgres数组替换连接表

3

假设我们有一个执行“作业”的系统。这些作业可以被连接成我们称之为“集成”的序列,它们实际上是一组有序的作业。

传统的解决方案是使用联接表:

integrations: id, name
jobs: id, name, commands
integrations_jobs: id, integration_id, job_id, integration_order

integration_order是指该集成作业在集成中的位置。

如果我们使用Postgres数组会怎样呢?

integrations: id, name, [job_id1, job_id2, job_id3]
jobs: id, name, commands

使用数组替代连接表是否存在任何明显的缺点?我们正在Heroku上使用Rails 5和Postgres。


Postgres目前不允许使用数组列作为外键,这意味着您将失去参照完整性。此外,ActiveRecord未构建为使用数组列进行关联,这意味着您将与框架作斗争。如果反转参数-在这种情况下,数组列给您带来了什么优势? - max
感谢您的帮助,Max。我们认为版本控制集成会更简单。在不同的表中跟踪连接对象并记录每个连接对象的顺序历史比拥有数组历史更加复杂。通过编写自定义Rails验证来维护完整性,我们将与框架进行一些斗争,但这似乎比对连接表进行版本控制更简单。 - Nicholas Erdenberger
你可以简单地使用 has_many through: 关联,并使用 Papertrail 对“关联模型”进行版本控制。 - max
2个回答

0

你可以使用Postgres数组或JSON或枚举字段,但这会影响性能。
看这里


不需要进行连接操作,性能不会提高吗? - Nicholas Erdenberger

0

第一个缺点是您无法查询集成方面的工作,例如:

jobs table
id
1
2

integrations table
id, name, job_ids
1, i1, [1,2]
2, i2, [2]

所以,如果你想找到一个ID为2的工作的集成,你需要扫描集成表并检查job_ids是否有值2。如果集成表有很多记录,这是一个很大的性能问题。

如果你有一个连接表,那么这只是一个非常简单的查询,速度更快。 我不明白如果你使用连接表会有什么问题。


Thanh,我相信你可以索引数组字段。https://www.postgresql.org/docs/9.5/static/gin-builtin-opclasses.html此外,这种用例不是 ANY / ALL 和 @> / <@ 运算符的使用场景吗? - Nicholas Erdenberger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接