我在每个SELECT上使用许多JOIN语句阅读了很多关于关系数据库的内容。但是,我一直想知道在滥用这种方法时长期存在任何性能问题。
例如,假设我们有一个users
表。我通常会添加“最常用”的数据,而不是做任何额外的JOIN。例如,当我说“最常用”的数据时,就是用户名,显示图片和位置。
在网站上显示任何用户互动时,始终需要此数据,例如:在comments
的每个articles
表JOIN上。而不是在users
&上进行加入。获取“位置”和“显示”的users_profiles
表,只需使用users
表中的信息。
这是我的方法,但我知道有很多优秀且经验丰富的程序员可以就此事给我一些建议。
我的问题是:
我应该尝试对JOIN保守吗?或者我应该更多地使用它们?为什么呢?
长期使用JOIN时是否存在任何性能问题?
注意:我必须澄清一点,我根本不想避免加入JOINS。我只在需要时使用它们。在这个例子中将是评论/文章作者,仅显示在用户个人资料页面上的额外个人资料信息......等等。
答案 0 :(得分:8)
我对数据建模的建议是:
更多Database Development Mistakes Made by AppDevelopers。
现在关于模型的直接性,让我举个例子。假设您正在设计一个用于身份验证和授权的系统。过度设计的解决方案可能如下所示:
因此,您需要6个联接才能从输入的用户名获得实际权限。当然可能有一个实际的要求,但是这种系统通常被放入,因为一些开发人员认为即使每个用户只有一个别名,他们可能有一天会需要它,但登录的用户是1 :1等等。一个更简单的解决方案是:
而且,就是这样。也许如果你需要一个复杂的角色系统,但你也很可能不这样做,如果你这样做很容易插入(用户类型成为用户类型或角色表中的外键),或者通常很容易映射老到新。
这是关于复杂性的事情:它很容易添加并且难以删除。通常它是针对意外复杂性的持续守夜,这是非常糟糕的,不会因为增加不必要的复杂性而使情况变得更糟。
答案 1 :(得分:5)
归一化直到它受伤,反规范化直到它起作用!
这一切都取决于连接的类型和连接条件,但它们没有任何问题。加入ON table1.PK = table2.FK非常有效。
答案 2 :(得分:1)
如果数据是1 - < - > 1,你不会有很多空字段,不要过度规范化。您仍然可以在select语句中指定所需的字段(“最常用的数据”)。
答案 3 :(得分:0)
害怕没有加入。关系模型很强大,你应该使用它。有人总是讨论N + 1,但也考虑 - 在您的上下文中 - 出于安全目的经常加入用户,因为查询还可以强制要求用户存在,状态,会话正确性和字段期望。
许多大型网站都为每个请求提供了会话表和 http请求表,并且总是相互联系以进行页面查询。好处是参数始终与会话匹配,与适当用户的会话,用户状态始终检查,以及更多,因为它允许一些有趣的横向扩展优势。
长话故事,明智地做,但不要吝啬加入。
答案 4 :(得分:0)
正如其他人所说的那样 - 加入并不是一件可以避免的事情。事实上,在大多数模型中,很少在应用程序运行的每个查询中都没有少量连接。
即使在最大的查询中,它们通常也不会出现性能问题 - 并且通常可以解决在整个地方都有冗余和重复数据时可能出现的性能问题。
但是,请注意,在封面下,数据库一次只能连接两个表。因此,连接需要数据库的多个步骤,这些步骤对于开发人员是不可见的。当它进行这些连接时,它必须做出一些关于如何去做的决定:
因此,如果您的联接最终很复杂,那么效率将由优化程序/计划程序的复杂程度以及统计信息的货币和详细信息驱动。 MySQL在这里不是一个强有力的竞争者 - 所以我通常会保持我的模型和SQL比我使用其他东西更简单。但是每个查询的一些连接几乎总是很好。