【发布时间】:2009-08-07 06:58:50
【问题描述】:
我发现,在尝试在多个表之间构建复杂的 MySQL 连接和组时,我通常会遇到冲突,并且必须花费大量的“试错”时间来获得我想要的结果。
我想知道其他人如何处理这些问题。您是否在分支末端隔离较小的数据块并首先让它们工作?还是从想要返回的内容开始,然后根据需要开始链接表格?
也想知道是否有任何关于解决问题的好书或网站。
【问题讨论】:
我发现,在尝试在多个表之间构建复杂的 MySQL 连接和组时,我通常会遇到冲突,并且必须花费大量的“试错”时间来获得我想要的结果。
我想知道其他人如何处理这些问题。您是否在分支末端隔离较小的数据块并首先让它们工作?还是从想要返回的内容开始,然后根据需要开始链接表格?
也想知道是否有任何关于解决问题的好书或网站。
【问题讨论】:
我不在 mySQL 中工作,但我经常编写极其复杂的 SQL,以下是我的处理方法。
首先,彻底了解您的数据库结构是无可替代的。
接下来我尝试将任务分解成块。
例如,假设我正在写一份关于会议细节的报告(我工作的公司负责会议策划)。我需要知道会议名称和销售代表、会议地点和日期、参加者和演讲者信息。
首先,我确定哪些表格将包含报告中每个字段的信息。现在我知道我必须加入什么,但还不知道如何加入。
所以首先我编写一个查询来获取我想要的会议。这是报告其余部分的基础,所以我从那里开始。现在报告的其余部分可能可以按任何顺序完成,尽管我更喜欢首先处理应该具有一对一关系的部分,所以接下来我将添加连接和字段,这些字段可以让我获得所有相关的销售代表信息。
假设我每次会议只需要一个代表(如果有多个代表,我只需要主要代表),所以我检查以确保我返回的记录数量与我刚刚获得会议信息时的记录数量相同。如果不是,我会查看我的联接并决定哪一个给我的记录比我需要的多。在这种情况下,它可能是地址表,因为我们正在为代表存储多个地址。然后我调整查询只得到一个。这可能很容易(您可能有一个字段指示您想要的特定唯一地址,因此只需要添加一个 where 条件)或者您可能需要执行一些分组和聚合函数来获得您想要的内容。
然后我继续下一个块(首先处理所有应该与中心数据具有 1-1 关系的块,在这种情况下是会议)。每次添加后运行查询并检查数据。
最后,我转到那些可能具有一对多关系的记录并添加它们。我再次运行查询并检查数据。例如,我可能会检查特定会议的原始数据,并确保我的查询返回的内容正是我期望看到的。
假设在其中一个加入的添加中,我发现不同会议的数量减少了。糟糕,我刚刚添加的一个表中没有数据,我需要将其更改为左连接。
另外一次我可能会发现返回的记录太多。然后我看看我的 where 子句是否需要更多过滤信息,或者我是否需要使用聚合函数来获取我需要的数据。有时我会临时将其他字段添加到报告中,以查看是否可以查看导致重复数据的原因。这有助于我了解需要调整的内容。
真正的关键是慢慢地工作,了解您的数据模型并在添加每个新块后检查数据,以确保它以您认为应该的方式返回结果。
有时,如果我要返回大量数据,我会临时在查询中添加一个额外的 where 子句,以限制我可以轻松检查的几个项目。我还强烈建议使用 order by,因为它可以帮助您查看是否收到重复记录。
【讨论】:
分解 MySQL 查询的最佳方法是运行EXPLAIN 命令以及查看Optimization with the EXPLAIN 命令的 MySQL 文档。
MySQL 还提供了一些很棒的免费GUI tools,您需要使用 MySQL 查询浏览器。
运行 EXPLAIN 命令时,这将分解 MySQL 如何解释您的查询并显示复杂性。解码输出可能需要一些时间,但这本身就是另一个问题。
我推荐一本好书:High Performance MySQL: Optimization, Backups, Replication, and More
【讨论】:
我自己没有使用过它们,因此无法评论它们的有效性,但也许基于 GUI 的查询构建器(例如 dbForge 或 Code Factory 可能会有所帮助?
虽然使用维恩图来考虑 MySQL 连接并不一定有助于 SQL,但它们可以帮助可视化您试图拉回的数据(请参阅 Jeff Atwood's post)。
【讨论】: