今天看了下同事写的代码,才发现他居然喜欢把大量的逻辑写在 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 的也很多。
201
banmuyutian 2022-02-22 14:41:53 +08:00
我也不想啊,但是要做各种复杂报表,各种关联表,就变成这样了
|
202
1M163W1E2fyRhLt4 2022-02-22 14:45:45 +08:00 1
其实 34 楼之前的都是挺正常的讨论。
20 楼的 “又不是存储过程 一个小查询没啥问题 不能 join?不能子查询? 不如写下你的做法给大家看看” 在我看来是询问楼主觉得问题在哪,楼主大概理解成挑衅和反问了,在 34 楼和 38 楼一阵反击。 |
203
HankAviator 2022-02-22 14:48:41 +08:00
@NeezerGu join 除非写崩坏了才会出笛卡尔积(应该算是比较低级的错误),左右连接好像不会出笛卡尔积吧
|
204
AlkTTT 2022-02-22 14:49:19 +08:00 1
lz : 你们觉得这种屎山是对的吗?不应该在代码里写,更容易维护吗?
楼上: 你这个菜 b 懂什么,我们吃过又臭又长的屎,这才多少你就不行了 ps. 代码架构本身就是一直在进步的,那 20 年前的架构在今天说没问题的,年龄都不小了吧? 这也是为什么程序员 35 岁失业的原因(新时代的大船承载不了旧时代的残党) |
205
Joker123456789 2022-02-22 14:59:56 +08:00 4
数据库,数据库,他的主要功能就是存数据的啊。
把逻辑写在 sql 是 是很古老的 做法,那会儿 程序基本上都不大,并发量也不高,基本上单节点就可以搞定。所以为了提高查询效率,采用存储过程,sql 函数 是一种相对较好的解决方案。 而现在,动不动就要负载均衡,分布式,数据库自己都自身难保了,需要用 redis 来帮他挡住流量。 如果还把业务逻辑写在 sql 里,那不是扯淡吗? 还想不想要这个项目了? 业务逻辑 就是一个 web 程序里 计算量最大的地方,写在程序里,可以多机器部署,将压力分散开来,而写在 sql 里呢? 你是打算 部署几个数据库? |
206
Joker123456789 2022-02-22 15:01:19 +08:00
|
207
xsqfjys 2022-02-22 15:06:20 +08:00
如果你不是 leader 就少说话管好自己的代码就行
|
208
kisick 2022-02-22 15:16:03 +08:00
只要索引建的合理,使用 left join 有什么问题吗?
如果不用 join ,那这个 sql 需要先查 user2role 表,再查 role 表,再查 menu 表。 10 来次的 left join 使用代码来写照样很混乱,而且性能肯定不如 sql 。 复杂的 lambda 表达式和使用 left join 的 sql 哪个更好维护呢? |
209
monkeydream 2022-02-22 15:30:56 +08:00
这种级联的查询没有啥问题吧,只是这个 SQL 没有必要关联 role 表; ToB 业务很多比这个复杂多的场景要关联好多张表,如果拆开来做可能更复杂,所以还是要看具体场景。
|
210
adoal 2022-02-22 15:33:37 +08:00
@liprais 是这样的,如果实际业务对一致性要求搞,那就要在业务代码层里重新实现 RDBMS 的功能了。我不相信从一互大输送到社会上的小厂里当 CTO 、当夹狗屎的 cruders 在这方面能做得比关系数据库系统的开发者好。
|
212
stephanew 2022-02-22 16:32:34 +08:00
@SuperXRay "说菜狗可能真这么觉得,#58 楼认为属于客观称述" 能得出这个结论说明你也是这么认为的咯,随便评论人家"菜狗"这种优越感是从哪里来的?说了又不敢认,你反驳之前先自己想个好点的说辞不要说出这么令人迷惑的发言。
|
213
sampeng 2022-02-22 16:32:52 +08:00
就这?我看了一下我们数据库里面几千行的 sql 在那笑而不语。。还有 20 多 M 的存储过程。。
代码里面随便拿出几百行的 sql 跟玩一样。。一开始还觉得新奇,现在基本麻木了 |
214
SuperXRay 2022-02-22 16:46:59 +08:00
@stephanew #212 “说了又不敢认”,“说菜狗可能真这么觉得”明显的省略主语(特指骂菜狗的层主),我要是表达自己的观点需要带上可能这个修辞吗,你的理解能力是真的差,我是比较质疑楼主的表述的,但也不至于到抨击人的程度
|
215
magicyao 2022-02-22 17:56:08 +08:00
谢谢,血压满了,曾经维护过四个一千行以上的存储过程的人路过,光速跑路
|
216
superfatboy 2022-02-22 19:24:51 +08:00
我 TM 的在头条上看到了一样的内容,楼主是在头条又发了一次,还是内容被头条抓取了
|
217
mingl0280 2022-02-22 20:12:57 +08:00 via Android
这东西有啥不可维护 /可读性差的……不知道这种“不可维护 /可读性差”是哪里冒出来的神仙定义,好像 SQL 编辑器不带语法高亮或者 SQL 代码不是文本文件了一样。楼主是真的菜。
|
218
mingl0280 2022-02-22 20:17:56 +08:00 via Android
@stephanew 因为这种 SQL 看不懂还抱怨可读性差是真的菜,任何一个稍微学过几个小时 SQL 的都应该能看懂理解。数据库工具里面一堆一堆的查询分析和代码分析合着都是给他当摆设的……
|
219
lovelyded 2022-02-22 22:19:07 +08:00 via Android
前司用的 daas 平台,直接写 SQL 就能生成接口,这种 SQL 对我们很常见哈哈哈哈哈哈
|
220
shadowfish0 2022-02-22 22:29:43 +08:00
评论区里一堆指责楼主的圣母我是看不太懂,发个帖子下面一堆人喷你菜狗,你是什么感觉?这帖子明显是评论区一群人不友善发言的
|
221
cedoo22 2022-02-22 22:48:55 +08:00
你如果不举例子, 我会支持你反对写大量逻辑在 sql 里。
但是你这个例子 并不复杂。。。我见过极端的 SQL ,一个 SQL ,80 多行,各种嵌套各种 in 各种 case , 一旦数据准确性有问题,看到眼睛疼 |
222
shadowfish0 2022-02-22 22:49:27 +08:00
赞同#204 ,#205
我不知道为什么这么多牛人反驳楼主的论据是:“就这点 SQL 你看不懂?” 能在工程领域说出这种话的人,水平能有多高? 为什么要有这么多设计模式,为什么要有这么多方法去规约代码书写的方式,为什么《软件工程》这门课是大学必修? 代码写出来谁不会啊...真正难的不就是如何让这么多行代码能够易读、可维护吗?数据层就干数据层的事情,业务层就干业务层的事情,这种最基本的东西都有争论的吗? 最基本的,业务逻辑要改怎么办?是 SQL 语句好改还是 JAVA 代码好改? |
223
adoal 2022-02-23 00:42:07 +08:00 via iPhone
难道在某些一互大(或者精神一互大) cruders 的母校里软工是必修课而数据库只配选修
|
224
qaweqa 2022-02-23 00:54:14 +08:00
@shadowfish0 按你这种需求那不需要用关系型数据库
|
225
felixcode 2022-02-23 04:01:20 +08:00 via Android
@shadowfish0
大量关系型数据库费死劲的优化 join 等性能,各种版本迭代,各种高价卖给客户,最后到你眼里还不属于数据层的东西。 软件工程里数据库的功能难道不是以最高效的方式给其它系统提供数据增删改查吗? 拿几行 SQL 语句出来这么多人都说不难看懂,那也就不难维护,到你这就是千难万难不好改,不想学 SQL 不想学关系型数据的理由各种各样,非得把拿难学难用难维护当挡箭牌吗? |
226
Chad0000 2022-02-23 05:09:19 +08:00 via iPhone
|
227
cassyfar 2022-02-23 06:07:55 +08:00
|
228
Chad0000 2022-02-23 06:16:24 +08:00
@Chad0000 #226 而且我还搞得更极端,我连外键都不设置,也不在 DB 层做过多数据校验。当然 DB 能二次把关最好,但这无意中会增加 DB 的压力,于是干脆完全交给应用层好了,DB 就只做两个功能:存储和查询数据。
越简单越不容易出错,同时也越容易扩展,迁移。 |
229
yzbythesea 2022-02-23 06:17:39 +08:00
再补充下,数据库基本只能垂直扩展,即使水平扩展,收费也很贵。服务器可以很轻松的水平扩展,收费也便宜。所以基本运算压力都会放在服务器上。我从毕业到现在接触的生产服务都是用 nosql 作数据库,实际就是把运算压力减小到了极致。即使现在很多 nosql 做到了 sql 的 transcation ,我们也不敢多用,也是因为运算压力大。做好就是一个 put ,一个 get ,delete 都别,设个 TTL 就好了。
|
230
fuchaofather 2022-02-23 10:13:10 +08:00
写 sql 也挺好的
|
231
NeoZephyr 2022-02-23 10:21:25 +08:00
这不才 3 个吗
|
232
stephanew 2022-02-23 10:38:18 +08:00
@SuperXRay 那你哪来这么多戏啊,要你来揣测别人是陈述还是骂人秀优越?你在这咬文嚼字无非就是想说"我虽然同意 58 楼但那不是我说的,我只是帮你们翻译一下,所以那不是我的观点"? 这次我的理解到位了吗?
|
233
stephanew 2022-02-23 10:47:19 +08:00
@mingl0280 人家哪句话说看不懂了?自己看屎山习惯了看出优越感来了?你用的工具方法别人也一定要用一样的?几个小时对于你可能多了,几秒吧。
|
236
SeeYouNextTime 2022-02-23 13:46:35 +08:00
互联网现状,眼看着从‘sql 里要不要写逻辑’ 变成 ‘这个 sql 复不复杂’
|
239
mingl0280 2022-02-24 04:51:47 +08:00 via Android
@yzbythesea 你这是带需求分析的,楼主是不带的,他数据库可能万年都扩不到需要增加第二台服务器的水平,这种情况考虑横向扩展就是脱了裤子放屁。
|
241
nolog 2022-02-24 11:18:16 +08:00
个人觉得如果带筛选和排序只能这样写了啊,sql 排序比你代码排序快的多
|
242
stephanew 2022-02-24 12:27:56 +08:00
@mingl0280 说不过了扣帽子?我说 SQL 是屎山了?自己喜欢堆屎山还要求别人跟你一样欣赏得津津有味?你要是担心失业平时堆习惯了我可以理解,毕竟只会 CRUD 的这年头确实不好找工作
|
243
ecloud 2022-03-15 13:52:56 +08:00
我这随便一个查询 explain 一下都是 10 来行
|
244
coyoteer 2022-04-13 11:46:02 +08:00
@potatowish 那我们数据库实训,要做什么呢
|