逻辑大量的写在 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 的也很多。
18730 次点击
所在节点    Java
244 条回复
xuanbg
2022-02-22 11:54:22 +08:00
例子里面的鉴权逻辑确实不应该放在 sql 里面。然而,sql 里面 join 几张表,根据条件拼一下查询语句也不能算把业务逻辑写在 sql 里面吧。
NotFoundEgg
2022-02-22 12:18:25 +08:00
确实这种多表 left join 看着挺头大的,尤其是遇到那种 ( mybatis )xml 里格式化不规范的更是血压上升;

我司的业务也是很多复杂 SQL ,我刚毕业时领导分给我一个查询,写完了查询逻辑 SQL 将近 300 行我人都傻了(用 oracle ,需要根据多张关联表查询出的字段,自定义排序);

虽然我从一开始到现在都很反感这种长 SQL ,但没办法我也改变不了现状,还是得写,写了快 3 年了
Marszm
2022-02-22 12:24:59 +08:00
楼主我坚定的支持你。。。。喷你的人很简单,平时就喜欢堆 SQL 。。。写一堆天书,谁也没办法维护接手,从而体现其重要性,这样就不会失业。
acmerliu
2022-02-22 12:27:37 +08:00
一条 sql 能搞定的,为什么要写业务代码?
cocong
2022-02-22 12:33:24 +08:00
典型的坑害后人,我以前就遇到过,无力吐槽。
c6h6benzene
2022-02-22 12:37:54 +08:00
讲真,这就是习惯。我自己写惯 SQL ,JOIN 那是常事,很多逻辑甚至还是在 JOIN 里面写的。刚换用 JPA 的时候还得捋一捋这边的 JOIN 写法,甚至还有 class 用 immutable 一个 select 查询信息的。
smallparking
2022-02-22 12:44:30 +08:00
@msg7086 数据库不是也有分布式数据库吗 像 greenplum 这种的
cocong
2022-02-22 12:50:52 +08:00
对了,突然想起来,以前接收过一个项目,人家不仅在 sql 里写逻辑,还在 正则表达式 里写 case ,那正则表达式老长,改一点都心惊肉跳,后来我直接重写了。
felixcode
2022-02-22 12:54:09 +08:00
会 sql 的得要迁就不会 sql 的?为了所有人能维护就只能最原始方式做 CRUD ?团队能力取决于学的最少的人,不会 sql join 还能骂会用的人不懂
所以到后来为了不用 sql ,全都是暴力查询,做个多条件的查询就得在数据库里做几十次全表扫描?速度不够怪服务器性能低
ctrlpanel
2022-02-22 13:00:22 +08:00
企业级软件公司有个职位叫“数据库开发工程师”,主要工作就是写 SQL ,大量的函数包、存储过程、触发器、跨库查询等等,尤其是硅谷的公司很多人就干这个吃饭。业务逻辑在数据库执行效率高,是肯定的,因为没有和应用程序的 IO 开销,而且大型关系型数据本身对复杂查询有优化。但如果楼主是在互联网公司,那开发模式就不一样了,用应用程序解决业务逻辑非常有助于代码管理,SQL 理应简单化。
iseki
2022-02-22 13:01:32 +08:00
这 sql 没什么问题,你是没见过把文案塞 sql 里,在 SQL 里格式化时间日期的,这才是真的滥用。
RockShake
2022-02-22 13:04:29 +08:00
一堆人也蛮奇怪的,现代架构逻辑不就是通过分层让逻辑可控么,SQL 内嵌逻辑本身会增加后续维护成本,取舍问题,没必要上纲上线
iseki
2022-02-22 13:05:05 +08:00
sql 只做数据层面的更基础和通用的业务逻辑就没啥问题
potatowish
2022-02-22 13:07:40 +08:00
这个例子举的不够有说服力,换一个
msg7086
2022-02-22 13:24:05 +08:00
@smallparking 确实有分布式数据库,但是数据库要保证 ACID 还要做分布式,复杂性会高很多。
比如说做大型数据仓库,hadoop 或者 bigtable 就可以搞定,但是如果你要把 MySQL 搞成分布式(比如 galera 多主)你就会发现开发和运维难度直线上升。(这里开发主要指 MySQL/galera 平台开发。)你说的 GreenPlum 我没有看,但是我想,像这些方案,背后还是会有大量的开发成本,运行起来还是会有一定的非线性损耗惩罚。

但是应用服务器做横向扩展却很简单,堆一打机器,对着数据库干就是了,几乎是零惩罚的。
(比如堆 100 台机器就能有近乎 100 倍的性能。)

归根结底,技术选型还是要考虑到人力和机器成本。只要你高兴,HTML 和 CSS 都能写在存储过程里。但是不同的做法之间,消耗的人力成本完全不同。不仅仅是开发成本和运行成本,还有招人成本,学习成本,测试成本,维护成本,二次开发成本等等。
yunxiao99
2022-02-22 13:25:03 +08:00
举的例子确实不合适,把你所说的十几个 join 的查询贴出来可能好点
buermo
2022-02-22 13:25:45 +08:00
看下来对于这么多人不会 SQL 感到震惊
SuperXRay
2022-02-22 13:28:47 +08:00
@stephanew
#155 “你们这种优越感是从哪里来的?”
哪里被你看出流露出优越感?真是很令人迷惑.

我就想看看楼主贴个两种代码的对比而已,不管哪种,倾向于简洁的那种.
danhahaha
2022-02-22 13:30:20 +08:00
已经成了一个博弈了,v 站的风气有点太技术了,实话各位平时也这么写代码吗?纯为了炫技,几十行几百行的堆 sql ? 这帖子好像如果回个帖子认同楼主就好像认同自己菜一样,没必要吧
msg7086
2022-02-22 13:31:30 +08:00
@felixcode 不是所有的数据库都能在 LEFT JOIN 和子查询上做到最高性能。
比如以前 MySQL 在子查询上的性能就稀烂,像楼主贴的这段代码,放在以前就可能会去扫全表导致性能低。
反而是合理拆分查询才能更高效率利用上缓存,同时避免稀烂的查询执行器扫全表。

当然我也不是说无脑拆,至少是要看过查询计划以后,有理有据地去拆,去改写。
除非楼主家用的 Oracle 或者 MSSQL 之类的企业级软件,什么查询喂进去都能跑的,那另当别论。

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

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

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

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

© 2021 V2EX