将问题简化为基本概念,我们有三个表 components , programs 和 users ,它们之间存在多对多关系两个中间表 program_components 和 user_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,因为它通过通用的 programs 表促进了跨多个表进行联接的意图。但是,经常有人告诉我,太多的连接通常是处理问题的错误方法。 [1]
文档中是否有针对此类查询的建议?
[1]我们正在重构,以包括一个适当的user_components表,该表将为我们免除这些查询的使用,并为我们提供了更大的灵活性,但这不在问题的范围之内。 >
答案 0 :(得分:0)
由于只需要用户和组件表中的ID,因此没有理由加入程序表。实际上不建议这样做,因为这可能会导致明显的性能下降。
在编写SQL查询时,检查多少行总是有用的。通过加入程序表,即使您不需要任何信息,也必须检查它的ID行。
有关更多信息,您可能有兴趣阅读this,其中介绍了一些提高查询性能的方法