繁体   English   中英

多对多到多对多:是否需要中间联接?

[英]Many-to-many through many-to-many: is there a need for the middle join?

为了简化该问题的基础,我们有三个表组件程序用户 ,它们与两个中间表program_componentsuser_programs有多对多的关系。

simplified table structure

users
- id (primary key)
- (...)

user_programs
- user_id (foreign key to users id)
- program_id (foreign key to programs id)

programs
- id (primary key)
- (...)

program_components
- program_id (foreign key to programs id)
- component_id (foreign key to components id)

components
- id (primary key)
- (...)

我们正在将用户对程序组件的权限集成到我们的云管理系统中。 我在查询中偶然发现了许多个接一个的联接,并且想知道是否需要中间表。

SELECT users.id, components.id FROM components
JOIN program_components ON c.id = program_components.component_id
JOIN programs ON program_components.program_id = programs.id
JOIN user_programs ON programs.id = user_programs.program_id
JOIN users ON user_programs.user_id = users.id
WHERE (...)

中间连接是否必要,或者我们可以简化为

SELECT users.id, components.id FROM components
JOIN program_components ON c.id = program_components.component_id
JOIN user_programs ON program_components.programId = user_programs.programId
JOIN users ON user_programs.user_id = users.id
WHERE (...)

根据我的测试,它们都产生了我完全期望的相同数据集。 问题更多地是关于MySQL期望得到什么,以及从数据库的角度来看哪种查询有意义

为了提高可读性,我建议使用额外的JOIN的第一个版本,因为它可以促进跨公共程序表跨多个表进行连接的意图。 但是,经常有人告诉我,太多的连接通常是处理问题的错误方法。 [1]

在文档中是否有关于此类查询的建议?


[1]我们正在重构,以包括一个适当的user_components表,它将免除我们这些查询的使用,并为我们提供了更大的灵活性,但这不在问题的范围内。

由于只需要用户和组件表中的ID,因此没有理由加入程序表。 实际上不建议这样做,因为这可能会导致明显的性能下降。

编写SQL查询时,检查多少行总是有用的。 通过加入程序表,即使您不需要任何信息,也必须检查它的ID行。

有关更多信息,您可能有兴趣阅读此书 ,它解释了提高查询性能的一些方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM