简体   繁体   English

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

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

Simplifying the question to its basics, we have three tables components , programs and users , related in many-to-many relationships with the two intermediate tables program_components and user_programs . 为了简化该问题的基础,我们有三个表组件程序用户 ,它们与两个中间表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)
- (...)

We are integrating user rights on program components within our cloud management system. 我们正在将用户对程序组件的权限集成到我们的云管理系统中。 I stumbled upon on query with many joins one after the other, and was wondering wether the middle table is required or not. 我在查询中偶然发现了许多个接一个的联接,并且想知道是否需要中间表。

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 (...)

Is the middle join necessary, or could we simplify this as 中间连接是否必要,或者我们可以简化为

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 (...)

From my tests, they both result in the same dataset, which I fully expected. 根据我的测试,它们都产生了我完全期望的相同数据集。 The question is more about what MySQL expects to get, and which query makes sense from a database perspective. 问题更多地是关于MySQL期望得到什么,以及从数据库的角度来看哪种查询有意义

For readability, I would advise the first version with the extra JOIN, as it promotes intent of joining across multiple tables, going through the common programs table. 为了提高可读性,我建议使用额外的JOIN的第一个版本,因为它可以促进跨公共程序表跨多个表进行连接的意图。 However I was often told that too many joins are often the wrong way to go about things. 但是,经常有人告诉我,太多的连接通常是处理问题的错误方法。 [1] [1]

Are there any recommendations in the docs for such queries? 在文档中是否有关于此类查询的建议?


[1] We are refactoring to include a proper user_components table, which will absolve us of these queries, and provide us with more flexibility, but this is outside the scope of the question. [1]我们正在重构,以包括一个适当的user_components表,它将免除我们这些查询的使用,并为我们提供了更大的灵活性,但这不在问题的范围内。

Since you only want the ids from your users and your components tables, there is no reason to join the programs table. 由于只需要用户和组件表中的ID,因此没有理由加入程序表。 It is actually not advisable to do so because it will likely result in a noticeable performance hit. 实际上不建议这样做,因为这可能会导致明显的性能下降。

When writing SQL queries it is always useful to examine how many rows are examined. 编写SQL查询时,检查多少行总是有用的。 By joining the programs table you have to examine it's ID row even though you don't need any info from it. 通过加入程序表,即使您不需要任何信息,也必须检查它的ID行。

For further info you might be interested in reading this , which explains some ways to boost the performance of your queries 有关更多信息,您可能有兴趣阅读此书 ,它解释了提高查询性能的一些方法。

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

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