MySQL初入门

本文记录了一位实习生在处理复杂SQL查询时遇到的问题和解决方案。需求涉及论坛帖子详情查询,包括帖子、评论、回复和用户信息等多个字段。最初尝试通过leftjoin四表查询,发现无法获取所有所需字段。经过分析表结构和关系,最终采用嵌套相关子查询实现,但担心性能问题。作者寻求更优的SQL写法和性能优化建议。
摘要由CSDN通过智能技术生成

1、随笔杂谈

今天遇到了一个需求,类似于论坛帖子查询详情,实现的需求功能如下:
在这里插入图片描述
可以从图中看出,需要查询出来的字段有帖子标题、帖子内容、帖子图片、发帖用户姓名及头像、点赞数、回复数、以及回复人头像及姓名、被回复人姓名、回复时间、回复内容、评论时间、评论内容、评论人头像及姓名等诸多字段。
光看到这么一个功能,起初我以为只用一个left join连接四表就可以拿到页面上所展示的全部数据,后来我发现太天真了。。。实践证明,那样做有些字段是带不出来的,话不多说,讲讲我自己对这个需求从最初的实现经过一点点的调整到最后写出来的sql的整个思路吧。。。

1.1 表结构概述

这里大概的讲一下表结构的设计,不贴图了,一会儿贴出SQL语句,想请各位大佬给予我指正,以及优化层面的建议

1.1.1 需求涉及到的主表post_question(帖子表)

该表字段主要有主键id、以及发帖用户关联的用户id、和帖子标题、内容、图片、点赞数、回复数、发帖时间、是否逻辑删除等相关字段。

1.1.2 comments(评论表)

该表字段主要有主键id、与评论所关联的帖子id、以及发表评论的用户id、发布评论时间等字段

1.1.3 reply(评论回复表)

该表主要用于某个登录小程序用户进行回复评论操作相关的数据存储,涉及的字段主要有主键id、回复的评论id、被回复用户的id、回复用户的id、回复内容、回复时间等相关字段

1.1.4 user(用户表)

该表主要存储登录小程序的用户的一些基础信息字段,业务涉及到的字段主要有主键id、用户姓名、用户头像。

1.2 需求分析

理清楚了业务要操作的是哪几张表、以及带什么字段出来返给前端后,就接着来理理表与表之间的连接关系

1.2.1 四表之间的关系如何

以post_question为主表出发,一条帖子下肯定可以存放多个用户的评论,所以post_question和comments两表一定是个一对多关系,那么我亦可以使用帖子表的id与评论表中的帖子id进行连接查询。
接着再来看看comments,一条评论下必定会存储多个用户的不同回复,亦为一对多的关系,我就可以使用评论表的id与评论回复表中的回复评论id进行关联。
最后再来看看user表,这个需求如果是只查评论内容、回复内容、评论时间、回复时间、帖子信息及发帖用户头像、姓名这些字段,那么如上的三表联完后再用帖子表的用户id与user表的id连接即可,可是,现实的需求却不满足于如此简单。。。
回顾需求,除开刚刚上述提及查询的字段外,还需要另外带出回复用户姓名、头像、评论用户姓名、头像、被回复人姓名等字段,于是我想到了使用相关子查询,但是一开始我却想的是把整个需求拆开成为四个不同的语句去做到,然后Controller层传个帖子id过来,我把查到的四个List放入到Map集合中,返给前端。。。只能说思路可行并且能查数据,但是联调的话,前端必定就要来找我了。。。
按如上思路实现后,自测接口,返回的数据截图如下。。。
在这里插入图片描述
可以看到,我丢给前端的是四个分开的集合,那么前端来调我接口的时候,想取字段是非常不方便的,数据返回的形式,可以从两个层面去解决。
①、如果分成四个SQL去写那么,我后端必定要想办法把查出来的四个List集合进行遍历封装,以树形结构的方式,将多个子集合的数据封装到一个最外层的集合里面去,最后将最外层的集合丢出去给前端,这样,前端调用接口时,就可以以点的形式去层层调用的属性字段。
②、按第一种方式去做的话,我感觉挺麻烦,而且也没有具体的代码实现思路,所以我选择了第二种方式,看能不能在SQL层面上动手脚,将四个SQL合并成一条SQL语句,然后三层后端代码只需要将帖子id,从Controller一路传递到Mapper中,最后只对帖子id做一个动态sql查询。最好是一个SQL把需求页面上需要的所有字段查询出来,于是乎,就实现了如下的嵌套相关子查询。。。。。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
对于我这么一个应届实习生来说,这应该是我接触过最难的SQL语句了。。。虽然功能是实现了,但是后续如果数据库中数据过多了,我这么一个套娃,显然SQL性能是比较低的,不知道各位看官有没有更加合适的SQL写法,欢迎留贴指正

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值