逻辑大量的写在 sql 语句里

2022-02-21 16:40:54 +08:00
 moxiaowei

今天看了下同事写的代码,才发现他居然喜欢把大量的逻辑写在 sql 语句里,跟他讲了下,他说是以前同事教的,我认为这样写可读性实在太差了,但是他也不愿意听我的!想听听各位大佬怎么讲。 下面是一段 sql

      SELECT
        m.id,
        m.menuname,
        m.link,
        m.parent_id,
        m.menutype,
        m.sort
--         CASE
--         WHEN pm.parent_id > 0 THEN
--         1 ELSE 0
--         END hasChildren
        FROM
        menu m
--         LEFT JOIN ( SELECT DISTINCT parent_id FROM menu ) pm ON pm.parent_id = m.id
        WHERE
        m.is_deleted = 0
        <if test="userId !=null and userId !=''">
            and m.id in (SELECT DISTINCT
            rm.menu_id
            FROM
            role2menu rm
            LEFT JOIN role r ON r.id = rm.role_id
            LEFT JOIN user2role ur ON ur.role_id = r.id
            WHERE
            rm.is_deleted = 0
            AND ur.user_id = #{userId} )
        </if>
        ORDER BY
        m.sort

这只牵扯到 3 张表,就这么多 left join ,我后面又去翻了翻 10 来次 left join 的也很多。
18751 次点击
所在节点    Java
244 条回复
banmuyutian
2022-02-22 14:41:53 +08:00
我也不想啊,但是要做各种复杂报表,各种关联表,就变成这样了
1M163W1E2fyRhLt4
2022-02-22 14:45:45 +08:00
其实 34 楼之前的都是挺正常的讨论。
20 楼的 “又不是存储过程 一个小查询没啥问题 不能 join?不能子查询? 不如写下你的做法给大家看看” 在我看来是询问楼主觉得问题在哪,楼主大概理解成挑衅和反问了,在 34 楼和 38 楼一阵反击。
HankAviator
2022-02-22 14:48:41 +08:00
@NeezerGu join 除非写崩坏了才会出笛卡尔积(应该算是比较低级的错误),左右连接好像不会出笛卡尔积吧
AlkTTT
2022-02-22 14:49:19 +08:00
lz : 你们觉得这种屎山是对的吗?不应该在代码里写,更容易维护吗?
楼上: 你这个菜 b 懂什么,我们吃过又臭又长的屎,这才多少你就不行了
ps. 代码架构本身就是一直在进步的,那 20 年前的架构在今天说没问题的,年龄都不小了吧?
这也是为什么程序员 35 岁失业的原因(新时代的大船承载不了旧时代的残党)
Joker123456789
2022-02-22 14:59:56 +08:00
数据库,数据库,他的主要功能就是存数据的啊。

把逻辑写在 sql 是 是很古老的 做法,那会儿 程序基本上都不大,并发量也不高,基本上单节点就可以搞定。所以为了提高查询效率,采用存储过程,sql 函数 是一种相对较好的解决方案。

而现在,动不动就要负载均衡,分布式,数据库自己都自身难保了,需要用 redis 来帮他挡住流量。 如果还把业务逻辑写在 sql 里,那不是扯淡吗? 还想不想要这个项目了?

业务逻辑 就是一个 web 程序里 计算量最大的地方,写在程序里,可以多机器部署,将压力分散开来,而写在 sql 里呢? 你是打算 部署几个数据库?
Joker123456789
2022-02-22 15:01:19 +08:00
@Joker123456789 不好意思,看劈叉了,看成写存储过程了,,哈哈哈。 我的错。

就你发的这个示例 来说,一点问题都没。完全可以这样写。
xsqfjys
2022-02-22 15:06:20 +08:00
如果你不是 leader 就少说话管好自己的代码就行
kisick
2022-02-22 15:16:03 +08:00
只要索引建的合理,使用 left join 有什么问题吗?
如果不用 join ,那这个 sql 需要先查 user2role 表,再查 role 表,再查 menu 表。
10 来次的 left join 使用代码来写照样很混乱,而且性能肯定不如 sql 。
复杂的 lambda 表达式和使用 left join 的 sql 哪个更好维护呢?
monkeydream
2022-02-22 15:30:56 +08:00
这种级联的查询没有啥问题吧,只是这个 SQL 没有必要关联 role 表; ToB 业务很多比这个复杂多的场景要关联好多张表,如果拆开来做可能更复杂,所以还是要看具体场景。
adoal
2022-02-22 15:33:37 +08:00
@liprais 是这样的,如果实际业务对一致性要求搞,那就要在业务代码层里重新实现 RDBMS 的功能了。我不相信从一互大输送到社会上的小厂里当 CTO 、当夹狗屎的 cruders 在这方面能做得比关系数据库系统的开发者好。
NeezerGu
2022-02-22 16:27:14 +08:00
@l00t 哦,是我看漏了。。

的确,如果要这样的效果,直接 join 就行了
stephanew
2022-02-22 16:32:34 +08:00
@SuperXRay "说菜狗可能真这么觉得,#58 楼认为属于客观称述" 能得出这个结论说明你也是这么认为的咯,随便评论人家"菜狗"这种优越感是从哪里来的?说了又不敢认,你反驳之前先自己想个好点的说辞不要说出这么令人迷惑的发言。
sampeng
2022-02-22 16:32:52 +08:00
就这?我看了一下我们数据库里面几千行的 sql 在那笑而不语。。还有 20 多 M 的存储过程。。
代码里面随便拿出几百行的 sql 跟玩一样。。一开始还觉得新奇,现在基本麻木了
SuperXRay
2022-02-22 16:46:59 +08:00
@stephanew #212 “说了又不敢认”,“说菜狗可能真这么觉得”明显的省略主语(特指骂菜狗的层主),我要是表达自己的观点需要带上可能这个修辞吗,你的理解能力是真的差,我是比较质疑楼主的表述的,但也不至于到抨击人的程度
magicyao
2022-02-22 17:56:08 +08:00
谢谢,血压满了,曾经维护过四个一千行以上的存储过程的人路过,光速跑路
superfatboy
2022-02-22 19:24:51 +08:00
我 TM 的在头条上看到了一样的内容,楼主是在头条又发了一次,还是内容被头条抓取了
mingl0280
2022-02-22 20:12:57 +08:00
这东西有啥不可维护 /可读性差的……不知道这种“不可维护 /可读性差”是哪里冒出来的神仙定义,好像 SQL 编辑器不带语法高亮或者 SQL 代码不是文本文件了一样。楼主是真的菜。
mingl0280
2022-02-22 20:17:56 +08:00
@stephanew 因为这种 SQL 看不懂还抱怨可读性差是真的菜,任何一个稍微学过几个小时 SQL 的都应该能看懂理解。数据库工具里面一堆一堆的查询分析和代码分析合着都是给他当摆设的……
lovelyded
2022-02-22 22:19:07 +08:00
前司用的 daas 平台,直接写 SQL 就能生成接口,这种 SQL 对我们很常见哈哈哈哈哈哈
shadowfish0
2022-02-22 22:29:43 +08:00
评论区里一堆指责楼主的圣母我是看不太懂,发个帖子下面一堆人喷你菜狗,你是什么感觉?这帖子明显是评论区一群人不友善发言的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/835439

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX