PostgreSQL中的自我多对多关系

3
使用PostgreSQL,我有一个表格应该与自身建立多对多的关系。这个表格叫做tools,我使用一个名为integrations的辅助表来实现多对多关系,它包含两个字段:tool_a_idtool_b_id
是否有更好的方法?这种方法的问题在于每当我想要查找所有的集成时,都需要检查tool_atool_b两个字段,例如:
SELECT * FROM integrations
WHERE tool_a_id = x AND tool_b_id = x

当我想选择所有与另一个工具集成的工具时,我需要执行以下操作:

SELECT "tools".* FROM tools, integrations
WHERE ((tools.id = integrations.tool_a_id AND integrations.tool_b_id = x) 
   OR (tools.id = integrations.tool_b_id AND integrations.tool_a_id = x))

例如,在Rails中将集成定义为关系不太容易,因为Rails期望有一个且仅有一个外键匹配。有更好的方法吗?这感觉很不优雅。我不介意使用PostgreSQL。

@ClodoaldoNeto 你是什么意思? - pupeno
我的意思是这个问题描述得不够清楚。要不加上一点代码怎么样? - Clodoaldo Neto
@ClodoaldoNeto,我真的不知道你想要什么代码,我在问一个数据库设计问题。如果你认为有用的话,我添加了一些查询,但我的问题是概念性的。 - pupeno
1个回答

1

好的,这是我们从关系数据库书籍中学到的方法。 ;)

但在你的SQL示例中,你没有正确定义对象。我认为你可能更需要像这样的东西(具有相同的数据库模式):

SELECT t1.* FROM tools t1 JOIN integrations i ON (t1.id = i.tool_a_id)
       JOIN tools t2 ON (t2.id = i.tool_b_id)
WHERE t2.id = x

那更加优雅,因为它将t1标记为可以选择的工具列表,将t2标记为我将从中选择想要了解哪些被集成到其中的工具的列表。

谢谢你的回答,马丁。我不是每次都手动发送查询。我正在使用ORM,所以我不确定像你那样给表取别名会产生什么影响。我尽量只在必要时违反ORM,因为做得太多会导致它失控。 - pupeno
这里的别名只是为了缩短SQL,您可以忽略它们。主要思想是两次使用工具表,一次用于所选工具,另一次用于它引用的工具。 - Martín

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