草庐IT

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

coder 2023-10-04 原文

我已经阅读了很多关于在每个 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/

有关MySQL JOIN 滥用?它能变得多糟糕?的更多相关文章

  1. 网站日志分析软件--让网站日志分析工作变得更简单 - 2

    网站的日志分析,是seo优化不可忽视的一门功课,但网站越大,每天产生的日志就越大,大站一天都可以产生几个G的网站日志,如果光靠肉眼去分析,那可能看到猴年马月都看不完,因此借助网站日志分析工具去分析网站日志,那将会使网站日志分析工作变得更简单。下面推荐两款网站日志分析软件。第一款:逆火网站日志分析器逆火网站日志分析器是一款功能全面的网站服务器日志分析软件。通过分析网站的日志文件,不仅能够精准的知道网站的访问量、网站的访问来源,网站的广告点击,访客的地区统计,搜索引擎关键字查询等,还能够一次性分析多个网站的日志文件,让你轻松管理网站。逆火网站日志分析器下载地址:https://pan.baidu.

  2. ruby - 这是 ruby​​ 元编程滥用吗? - 2

    我是Ruby的新手,我正在制作一个gem来与JSONRPCAPI交互,基本上所有调用和响应都非常相似,每个API调用都可以用一个函数处理,例如:Module::api_command('APINamespace.NamespaceMethod')但我也想(为了方便起见)能够做到:Module::APINamespace.NamespaceMethod是否有任何理由不通过使用Module.const_missing返回一个具有method_missing的虚拟类来执行此操作,这将允许将调用从Module::APINamespace.NamespaceMethod传递到Module::ap

  3. ruby - 为什么 split (' ' ) 试图变得(太)聪明? - 2

    我刚刚发现String#split有以下奇怪的行为:"a\tbc\nd".split=>["a","b","c","d"]"a\tbc\nd".split('')=>["a","b","c","d"]"a\tbc\nd".split(//)=>["a\tb","c\nd"]Thesource(来自2.0.0的string.c)超过200行,包含这样一段话:/*L5909*/elseif(rb_enc_asciicompat(enc2)==1){if(RSTRING_LEN(spat)==1&&RSTRING_PTR(spat)[0]==''){split_type=awk;}}后来,在

  4. ruby - 缓慢的 Ruby 正则表达式通过奇怪的变化变得快速 - 2

    我一直在调试网站以查找页面加载时间过长的根源,并将其缩小为用于从文本中提取URL的正则表达式:/(?:([\w+.-]+):\/\/|(?:www\.))[^\s在一大块文本上运行大约需要3秒。我发现如果我将第一个子句的逆语句添加到正则表达式((?:[^\w+.-]|^))的开头,它几乎会立即运行:/(?:[^\w+.-]|^)(?:([\w+.-]++):\/\/|(?:www\.))[^\s在我看来,添加的子句根本不应该影响正则表达式,因为没有什么可以导致该子句失败(因为这些字符将与“[\w+.-]++”子句匹配)。为什么这会使正则表达式运行得更快?编辑有些人要求提供我正在尝试做的

  5. ruby-on-rails - 在 Rails 中子类化用户模型真的很糟糕吗? - 2

    我从Rails收到了很多回击,因为我将User子类化为许多不同的子类。在我的应用程序中,并非所有用户都是平等的。实际上有很多模型对象,并不是每个用户类型都可以访问它们。我还需要一种方法来执行多态行为。例如,许多方法的行为会因类型而异。多态性不就是为了这个吗?但问题是,我总是被Rails拒之门外。默认值——尤其是表单提交到参数哈希的方式——似乎像非子类模型一样工作。链接和参数哈希值只是默认值真正让您厌烦的两种方式。在Rails中处理不同类型用户的复杂逻辑的“正确”方法是什么?在Java中,子类化模型是有效的——您不必为了让它按照您想要的方式工作而费尽心思。但是在Rails中,很难让子类与

  6. ruby-on-rails - 我是否滥用 "rescue"进行零检查? - 2

    我对所有事情都使用rescue,而不仅仅是“拯救”异常。我的意思是,我只是喜欢它省去验证和双重检查数据的方式。例如,假设我有一个模型Item,它可能有也可能没有User。然后,当我想获得我写的元素的所有者姓名时:item.user.namerescue""而不是类似的东西item.user.nil??"":item.user.name它产生了同样的想法,因为nil.name触发了我用""挽救的异常,但我不太确定这是一个好习惯。它实现了我想要的,并且用更少的代码实现了,但是...我不知道,到处都是rescue字眼让我感到不安全。这是一种不好的做法还是滥用rescue关键字是否有效?

  7. ruby-on-rails - REXML::RuntimeError(实体扩展变得太大) - 2

    今天升级到Ruby-1.9.3-p392后,REXML在尝试检索超过一定大小的XML响应时抛出运行时错误-一切正常,当接收到25条以下的XML记录时不会抛出错误,但是一旦达到特定的XML响应长度阈值,我收到此错误:Erroroccurredwhileparsingrequestparameters.Contents:RuntimeError(entityexpansionhasgrowntoolarge):/.rvm/rubies/ruby-1.9.3-p392/lib/ruby/1.9.1/rexml/text.rb:387:in`blockinunnormalize'我意识到这在最

  8. ruby-on-rails - Rails bundle - 糟糕的解释器 - 2

    我一直在使用sublimetext开发一个Rails项目,然后切换到ruby​​mine。它说没有安装项目中需要的一些gem。好吧,我尝试安装它们,但失败并出现错误,指出使用的ruby​​版本与gem文件中指定的版本不同。当我输入ruby-v时,它看起来像是同一个版本。然后我尝试重新安装ruby​​版本(2.0.0),但没有成功,我安装了2.1.0,希望它能设置正确的路径和所有内容。当我现在尝试输入bundle时,出现以下错误:bash:/Users/user/.rvm/gems/ruby-2.0.0-p353/bin/bundle:/Users/user/.rvm/rubies/ru

  9. ruby - 一个在 Ruby 上表现非常糟糕的简单正则表达式 - 2

    我有一个简单的Ruby正则表达式,需要很长时间才能计算:"fußball"*20=~/^([\S\s]{1000})/i如果我删除/i标志,它会工作得非常快。为什么运行这么慢?(我没有等到执行完毕)我知道这个正则表达式可能没有意义,但我想知道幕后是什么。错误报告:https://bugs.ruby-lang.org/issues/14418 最佳答案 默认.不匹配换行符。[\s\S]是解决该问题的方法。在Ruby中,您可以使用/m标志使点匹配所有字符。它在文档中RubyMetacharactersandEscapes[\S\s]由于

  10. javascript - "monkey patching"真的那么糟糕吗? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭3年前。Improvethisquestion某些语言(如Ruby和JavaScript)具有开放类,允许您修改核心类(如数字、字符串、数组等)的接口(interface)。显然这样做会使熟悉API的其他人感到困惑,但有充分的理由这样做吗?假设您要添加到界面而不更改现有行为,否则请避免使用它?例如,添加一个Array.map可能会很好不实现ECMAScript第5版的Web浏览器的实现(如果你不需要所有的jQuery)。或者您的Rub

随机推荐