MySQL JOIN 滥用?它能变得多糟糕?

标签 mysql database database-design

我已经阅读了很多关于在每个 SELECT 上使用许多 JOIN 语句的关系数据库。但是,我一直想知道滥用这种方法从长远来看是否会出现任何性能问题。

例如,假设我们有一个users 表。我通常会添加“最常用”的数据,而不是做任何额外的 JOIN。例如,当我说“最常用”的数据时,将是用户名、显示图片和位置。

在网站上显示任何用户交互时始终需要此数据,例如:在每个 comments 表中加入 articles。不要在 usersusers_profiles 表上执行 JOIN 来获取“位置”和“显示”,只需使用 users 表上的信息.

这是我的方法,但我知道有很多优秀且经验丰富的程序员可以就此事给我一些建议。

我的问题是:

我应该尽量保守地使用 JOIN 吗?还是我应该更多地使用它们?为什么?

从长远来看,大量使用 JOIN 是否会出现性能问题?

注意:我必须澄清,我根本不是要避免 JOINS。我只在需要时使用它们。在这个例子中将是评论/文章作者,仅显示在用户个人资料页面上的额外个人资料信息......等等。

最佳答案

我对数据建模的建议是:

  • 一般来说,您应该比 1:1 连接更喜欢可选(可空)列。仍然存在 1:1 有意义的情况,通常围绕子类型。与奇怪的连接相比,人们对可为空的列更敏感;
  • 不要使模型间接,除非确实合理(下文详述);
  • 赞成联合而不是聚合。这可能会有所不同,因此需要对其进行测试。参见 Oracle vs MySQL vs SQL Server: Aggregation vs Joins举个例子;
  • 联接优于 N+1 选择。例如,N+1 选择是从数据库表中选择订单,然后发出单独的查询以获取该订单的所有订单项;
  • 联接的可伸缩性通常只是在您进行批量选择时才会出现的问题。如果您选择一行,然后将其与一些事物连接起来,这很少是一个问题(但有时是);
  • 外键应该总是被索引,除非你正在处理一个非常小的表;

更多信息 Database Development Mistakes Made by AppDevelopers .

关于模型的直接性,我举个例子。假设您正在设计一个用于用户身份验证和授权的系统。过度设计的解决方案可能看起来像这样:

  • 别名(id、用户名、user_id);
  • 用户 (id, ...);
  • 电子邮件(id、user_id、电子邮件地址);
  • 登录(id、user_id、...)
  • 登录角色(id、login_id、role_id);
  • 角色(id,姓名);
  • 角色权限(id、role_id、privilege_id);
  • 权限(id、名称)。

因此您需要 6 次连接才能从输入的用户名到实际权限。当然可能对此有实际要求,但通常情况下,这种系统之所以被安装,是因为一些开发人员认为他们可能有一天会需要它,即使每个用户只有一个别名,用户登录是 1 :1 等等。一个更简单的解决方案是:

  • 用户(id、用户名、电子邮件地址、用户类型)

好吧,就是这样。也许如果你需要一个复杂的角色系统,但你也很有可能不需要,如果你这样做了,它就相当容易插入(用户类型成为用户类型或角色表的外键),或者通常可以直接映射从旧到新。

这是关于复杂性的事情:添加容易,删除难。通常它是对意外复杂性的持续警惕,如果不去增加不必要的复杂性就已经够糟糕了。

关于MySQL JOIN 滥用?它能变得多糟糕?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1851885/

相关文章:

java - 通过 Java 数据库到 XML(反之亦然)

database - Hibernate外键约束多个数据库

asp.net - 为什么我在 asp.net 中收到数据库连接错误?

php - Eloquent 查询 1 :n relationship

mysql - 从 MySQL 的数据库列中使用 LIMIT 进行 SELECT 查询

mysql - 自动化 excel 表格下载、修改和上传到 MySQL 数据库

java - 拥有一个具有所有模型对象的所有功能的 DatabaseManager 好吗?

php - 如何在 PHP 中以整数形式返回枚举列值

php - 用于私有(private)消息传递的单个 mysql 表

c# - 存储过程或应用程序中的业务逻辑