今天看了下同事写的代码,才发现他居然喜欢把大量的逻辑写在 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 的也很多。
101
moxiaowei OP @l00t 来秀你的智商下限?真不想跟傻逼多说什么?去问问你的 leader 吧,你这么干没一个公司能在你手下活着!害人害己,毒瘤。
|
103
l00t 2022-02-22 08:52:24 +08:00 3
@moxiaowei 笑死。问 leader ,你的 leader 跑我这来是谁领导谁都还难说。你是对业界一无所知。我就这么说吧,大把大把的公司,大把大把的项目都是这么写出来的,从政府到金融到电信到一般企业 OA 乃至到你上学时的选课系统,人家都活得好好的。
|
104
moxiaowei OP @l00t 对不起我司的 leader 就是我,我就是不允许。我不管别人(你)怎么写,怎么做,我希望我司在我的领导下,不至于代码是一坨屎!我也不觉得你的水平能有多高,至于谁领导谁,你要领导我,你也不配!懂么?
|
106
liunaijie 2022-02-22 09:03:43 +08:00 7
你说这样不好, 那你拿出一个方案来, 大家讨论讨论? 只要回复跟你不一致, 你就开喷, 你这是什么脑子.
|
108
krixaar 2022-02-22 09:08:54 +08:00
不用连表或者子查询的话,打个比方我这整天要跑营业数据做分析的:
1 、按时间跑出来订单 id 2 、按订单 id 跑订单各项内容的 id 3 、按订单各项内容的 id 分别一个查询去取对应的内容 4 、拼起来发出去 现在一堆 left join 做一个 materialized view 让它自己刷新谁想要数据直接一行 select 出去它不香吗…… |
109
fanchenio 2022-02-22 09:11:20 +08:00
不用 join 的话,那还要 mysql 干什么啊,直接用 mongodb 得了。
|
110
18500592934 2022-02-22 09:14:24 +08:00
这样的 sql 还好,这才几张表啊, 我司都是七八张表起步联查,而且你要拆开就会说你怎么查好几次数据库啊???
所以啊 领导让咋样就咋样吧 |
111
jackchenly 2022-02-22 09:21:03 +08:00 2
我看到一个菜鸡急眼了,呵呵
|
112
CallMeReznov 2022-02-22 09:22:33 +08:00
你认为代码不好,那是你的问题.
因为给钱的的人觉得有问题才是真正的问题. |
113
dengji85 2022-02-22 09:23:03 +08:00
我做 erp 的,逻辑也写 sql 实现,以前还经常写存储过程,但实在太难维护了</br>
用 sql 实现时一段业务 sql 尽可能功能明确,写好注释就行了,有时一段简单 sql 可以实现的,java 代码可能又臭又长, |
114
wupher 2022-02-22 09:25:08 +08:00 4
Client-Server 时代的设计风格。那时大家 Client 使用诸如 VB VC Delphi 等编写。但上述语言或者平台只负责客户端的样式与展现,业务逻辑多使用存储过程或者 SQL 存放于 DB 中运行。
好处是更新业务逻辑,只要修改 SQL 即可,无需上述平台重新编写,编译,打包,升级。缺点么,那也是 N 多的。比如 SQL 语言不是一门 OO 语言,业务描述能力在某些场景就会非常难用。SQL 基本谈不上并发,写操作,尤其是存储过程运行涉及临时表,经常有并发问题,而你有 100 个 CPU 都没用。 进入 Web-Service 时代以来,这种设计基本被大家放弃,更多使用编写语言来实现业务逻辑的封装与维护。 |
115
Morton996 2022-02-22 09:26:37 +08:00
真是又菜素质又差,十几个 left join 就看不懂了,这种理解能力能 hold 住 10 万行以上代码的系统不
|
116
superchijinpeng 2022-02-22 09:28:48 +08:00
没什么问题吧,不过楼主素质真的差
|
117
Aumujun 2022-02-22 09:29:43 +08:00 via Android
那么问题来了,几百上千行的 SQL ,你用代码来实现就一定是好的?
|
118
weizhen199 2022-02-22 09:32:18 +08:00
@yazinnnn 弄分布式的数据库呗。哪有这么多规矩
|
119
nicebird 2022-02-22 09:36:44 +08:00
找领导完事。
|
120
javen73 2022-02-22 09:38:11 +08:00
这没什么吧...相反我更讨厌在代码里看一堆 if 。
什么玩意儿是叫把逻辑写在 SQL 里?<if> 这种标签不是 mybatis 解析的东西么?什么时候轮到数据库来解析了 |
121
Mandelo 2022-02-22 09:39:30 +08:00 1
#101 楼主破防了。。。你发出来的我没看到任何代码逻辑,你可能没见过我同事那种上百行的存储过程
|
122
moxiaowei OP 说我素质差没问题。但是,一群彪炳自己素质高的,张口闭口菜鸡菜鸡的,我菜鸡我拿你工资了?而且,我没说 10 几个 left join 我看不懂,我只是觉得可读性差,换做我,超过 3 个 left join 的,我会写到代码里,而不是死堆 sql 语句,导致后续有人离职项目维护困难。我的标题写的很明确,只是个小实例,更复杂的我没贴出来!我只是想征求下大家的意见,这么写有没有问题!大家的时间都很宝贵,没必要在这儿喷。
|
124
yibo2018 2022-02-22 09:42:00 +08:00 3
sql 只做基本的功能,业务代码去组合,这样不好吗?否则你一个业务对应一个 sql ,先不说 sql 一定不能覆盖所有业务,其次 sql 的改动涉及到索引,覆盖等问题产生慢查询,死锁问题,都不考虑的?
好多人喷楼主,2 个 join 怎么了,就难懂吗?这不是关键呀,首先多几个 for 循环是没 SQL 查直接快,那又怎样,这根本不会是瓶颈,反而 MySQL 复杂之后引发的各种死锁,慢查询才是瓶颈 |
126
moxiaowei OP @Jwyt 哎 中途升的,不是自己培养的人,我跟他说,他回是之前同事教的,之前的同事写了 10 来年 java 了,我目前也不好说啥。
|
128
lipaa 2022-02-22 09:49:04 +08:00
仁者见仁智者见智 其实都行 我也觉得不复杂 如果没什么效率问题完全可以放 sql 里.放 java 代码不一定比这简洁 性能问题我估摸着也不会有 不是非黑即白的
|
129
deplivesb 2022-02-22 09:50:23 +08:00 4
菜狗就是菜狗,还不让人说?干了 8 年还是外包,不是菜狗?
|
130
lipaa 2022-02-22 09:50:48 +08:00
@moxiaowei 可能因为你这种事他遇到过改了呗 其实都可以为啥要听你的 你来写不就完事了 让别人该首先要确定自己一定是对的 或者证明别人错了
|
131
SuperXRay 2022-02-22 09:52:14 +08:00 1
@moxiaowei 贴一下 sql 写法和 java 代码写法的对比,更有说服力,就拿十几个 join 的那个例子
|
132
raptor 2022-02-22 09:52:15 +08:00 2
20 年前流行的 CS 架构都是这样干的啊,存储过程加触发器搞定业务逻辑,客户端就写个 UI 。
老程序员表示这很亲切。 当然这是 20 年前的事情了。 |
133
andy2415 2022-02-22 09:52:17 +08:00
谢谢 lz 让我开开心心的摸了一早上鱼
|
134
yuancoder 2022-02-22 09:52:44 +08:00
跑路吧,后期完全没法维护了
|
135
ltruntu 2022-02-22 09:53:18 +08:00
能跑不就行了 写的再好,能升职加薪么 咋老有人觉得别人的代码都是屎 ,资本社会
|
136
zhaol 2022-02-22 10:04:41 +08:00
OP 是举个例子,就怼着例子说 OP 看不懂并且菜?有些人真的是没脑子或者秀优越
|
139
daimubai 2022-02-22 10:13:49 +08:00
不是#58 先喷人的吗
|
140
hhjswf 2022-02-22 10:16:25 +08:00
这也没有业务逻辑啊,就是单纯的查表...
|
142
Henry399 2022-02-22 10:28:05 +08:00
某公司的作风
|
143
Telegram 2022-02-22 10:30:59 +08:00
我感觉问题不大啊,也就是可读性差点。
sql 这东西本来就相对来说比较不容易理解的,特别是联查,各种左右连接之类的。 搞过存储过程的,这个应该还算一般复杂啊。 以前看过管家婆的数据库,里面全是存储过程,可比这个复杂多了 |
144
hernuo 2022-02-22 10:47:03 +08:00
这个没看出有什么问题,难道不让用 join 吗。不这样写,那只能在代码里查单表取 id ,再根据 id 去查另一张表,或许还要再查其他表,最后拼起来不是更麻烦吗。
|
145
nba2k9 2022-02-22 10:51:25 +08:00
十几行的 sql 算什么可读性啊
维护过上百行的 sql 表示无所畏惧 |
146
mencounter 2022-02-22 10:52:46 +08:00
你们有见过银行的面向 SQL 编程?
|
147
statement 2022-02-22 10:54:20 +08:00
大概是用 MySQL 惯的 Oracle 即使出现比这复杂十倍的也太正常了
|
148
seakingii 2022-02-22 10:55:45 +08:00 1
楼主列的 SQL 并不复杂,这种程序的 SQL 应该是允许的
业务要不要写在 SQL 里要看具体的场景,脱离场景讨论就是耍流氓 互联网业务尽量少写复杂 SQL 中小型的 ERP 之类的无所谓,因为那些业务逻辑复杂的一批,用其它编程语言拉数据再处理会搞死人,特别是各种复杂的业务报表 不要以为自己是搞互联网的就一杆子打死所有人 |
149
ZeroDu 2022-02-22 11:01:28 +08:00
首页楼主列的这个 sql 其实还好,没啥问题。毕竟 menu 、role 数据不会太多,怎么玩都不会出问题。
当数据量较多的时候自然不能这样写。 还有上面各种一堆人上来直接就开喷,开怼,真的就是二极管 |
150
micean 2022-02-22 11:07:32 +08:00
写 sql 不让写 join ,等于残废
既然不让写,为什么不 jpa cache 上全套? |
151
Huelse 2022-02-22 11:08:26 +08:00
话说戾气不要这么重吧?
首先每个人都有自己的编程习惯,甚至一些自身的小癖好,换他人都不一定敢直接说出来 其次环境不同,我们也不知道楼主写的什么业务,用的什么框架什么编程语言,基本就凭楼主贴出的 sql 就开骂 逮着一点不放直接骂的,在我看来不是非常骄傲且牛逼的大佬就是傻逼 |
153
Goat121 2022-02-22 11:30:24 +08:00
如果是接触过 ERP 的,见过数据库里几百上千行的存储过程和触发器
就真不会觉得这算复杂 sql 了 |
154
hhjswf 2022-02-22 11:35:02 +08:00
反正我的习惯就是 sql 能简单尽量简单,多表能连尽量连。
|
157
lolizeppelin 2022-02-22 11:49:58 +08:00
oracle 真是没落了....以前用 oracle 的存储里大把几千行的代码 233333
小 case 了! |
158
caixiangyu17 2022-02-22 11:50:15 +08:00
见过 6000+行的 c#方法用来拼接一个 sql ,你能理解有多崩溃么?
|
159
WFDAK 2022-02-22 11:50:25 +08:00
借楼问一下,大家会不会把 SQL 语句写在代码了啊?
|
160
krixaar 2022-02-22 11:52:43 +08:00
@lolizeppelin #157 正在用 oracle 的感觉管你什么复杂逻辑几百行 sql 往里塞就行了真不错🤣
|
161
xuanbg 2022-02-22 11:54:22 +08:00
例子里面的鉴权逻辑确实不应该放在 sql 里面。然而,sql 里面 join 几张表,根据条件拼一下查询语句也不能算把业务逻辑写在 sql 里面吧。
|
162
NotFoundEgg 2022-02-22 12:18:25 +08:00
确实这种多表 left join 看着挺头大的,尤其是遇到那种 ( mybatis )xml 里格式化不规范的更是血压上升;
我司的业务也是很多复杂 SQL ,我刚毕业时领导分给我一个查询,写完了查询逻辑 SQL 将近 300 行我人都傻了(用 oracle ,需要根据多张关联表查询出的字段,自定义排序); 虽然我从一开始到现在都很反感这种长 SQL ,但没办法我也改变不了现状,还是得写,写了快 3 年了 |
163
Marszm 2022-02-22 12:24:59 +08:00
楼主我坚定的支持你。。。。喷你的人很简单,平时就喜欢堆 SQL 。。。写一堆天书,谁也没办法维护接手,从而体现其重要性,这样就不会失业。
|
164
acmerliu 2022-02-22 12:27:37 +08:00
一条 sql 能搞定的,为什么要写业务代码?
|
165
cocong 2022-02-22 12:33:24 +08:00
典型的坑害后人,我以前就遇到过,无力吐槽。
|
166
c6h6benzene 2022-02-22 12:37:54 +08:00 via iPhone
讲真,这就是习惯。我自己写惯 SQL ,JOIN 那是常事,很多逻辑甚至还是在 JOIN 里面写的。刚换用 JPA 的时候还得捋一捋这边的 JOIN 写法,甚至还有 class 用 immutable 一个 select 查询信息的。
|
167
smallparking 2022-02-22 12:44:30 +08:00 via Android
@msg7086 数据库不是也有分布式数据库吗 像 greenplum 这种的
|
168
cocong 2022-02-22 12:50:52 +08:00
对了,突然想起来,以前接收过一个项目,人家不仅在 sql 里写逻辑,还在 正则表达式 里写 case ,那正则表达式老长,改一点都心惊肉跳,后来我直接重写了。
|
169
felixcode 2022-02-22 12:54:09 +08:00 via Android 1
会 sql 的得要迁就不会 sql 的?为了所有人能维护就只能最原始方式做 CRUD ?团队能力取决于学的最少的人,不会 sql join 还能骂会用的人不懂
所以到后来为了不用 sql ,全都是暴力查询,做个多条件的查询就得在数据库里做几十次全表扫描?速度不够怪服务器性能低 |
170
ctrlpanel 2022-02-22 13:00:22 +08:00
企业级软件公司有个职位叫“数据库开发工程师”,主要工作就是写 SQL ,大量的函数包、存储过程、触发器、跨库查询等等,尤其是硅谷的公司很多人就干这个吃饭。业务逻辑在数据库执行效率高,是肯定的,因为没有和应用程序的 IO 开销,而且大型关系型数据本身对复杂查询有优化。但如果楼主是在互联网公司,那开发模式就不一样了,用应用程序解决业务逻辑非常有助于代码管理,SQL 理应简单化。
|
171
iseki 2022-02-22 13:01:32 +08:00 via Android
这 sql 没什么问题,你是没见过把文案塞 sql 里,在 SQL 里格式化时间日期的,这才是真的滥用。
|
172
RockShake 2022-02-22 13:04:29 +08:00 1
一堆人也蛮奇怪的,现代架构逻辑不就是通过分层让逻辑可控么,SQL 内嵌逻辑本身会增加后续维护成本,取舍问题,没必要上纲上线
|
173
iseki 2022-02-22 13:05:05 +08:00 via Android
sql 只做数据层面的更基础和通用的业务逻辑就没啥问题
|
174
potatowish 2022-02-22 13:07:40 +08:00 via iPhone
这个例子举的不够有说服力,换一个
|
175
msg7086 2022-02-22 13:24:05 +08:00
@smallparking 确实有分布式数据库,但是数据库要保证 ACID 还要做分布式,复杂性会高很多。
比如说做大型数据仓库,hadoop 或者 bigtable 就可以搞定,但是如果你要把 MySQL 搞成分布式(比如 galera 多主)你就会发现开发和运维难度直线上升。(这里开发主要指 MySQL/galera 平台开发。)你说的 GreenPlum 我没有看,但是我想,像这些方案,背后还是会有大量的开发成本,运行起来还是会有一定的非线性损耗惩罚。 但是应用服务器做横向扩展却很简单,堆一打机器,对着数据库干就是了,几乎是零惩罚的。 (比如堆 100 台机器就能有近乎 100 倍的性能。) 归根结底,技术选型还是要考虑到人力和机器成本。只要你高兴,HTML 和 CSS 都能写在存储过程里。但是不同的做法之间,消耗的人力成本完全不同。不仅仅是开发成本和运行成本,还有招人成本,学习成本,测试成本,维护成本,二次开发成本等等。 |
176
yunxiao99 2022-02-22 13:25:03 +08:00
举的例子确实不合适,把你所说的十几个 join 的查询贴出来可能好点
|
177
buermo 2022-02-22 13:25:45 +08:00 via Android
看下来对于这么多人不会 SQL 感到震惊
|
178
SuperXRay 2022-02-22 13:28:47 +08:00
|
179
danhahaha 2022-02-22 13:30:20 +08:00
已经成了一个博弈了,v 站的风气有点太技术了,实话各位平时也这么写代码吗?纯为了炫技,几十行几百行的堆 sql ? 这帖子好像如果回个帖子认同楼主就好像认同自己菜一样,没必要吧
|
180
msg7086 2022-02-22 13:31:30 +08:00
@felixcode 不是所有的数据库都能在 LEFT JOIN 和子查询上做到最高性能。
比如以前 MySQL 在子查询上的性能就稀烂,像楼主贴的这段代码,放在以前就可能会去扫全表导致性能低。 反而是合理拆分查询才能更高效率利用上缓存,同时避免稀烂的查询执行器扫全表。 当然我也不是说无脑拆,至少是要看过查询计划以后,有理有据地去拆,去改写。 除非楼主家用的 Oracle 或者 MSSQL 之类的企业级软件,什么查询喂进去都能跑的,那另当别论。 |
181
liprais 2022-02-22 13:35:06 +08:00
@msg7086
"但是应用服务器做横向扩展却很简单,堆一打机器,对着数据库干就是了,几乎是零惩罚的。 (比如堆 100 台机器就能有近乎 100 倍的性能。)" 无非不过是放弃了数据库的一致性保证而已 你要自己写 code 能做到跟数据库一样的一致性保证的话肯定跑不过数据库。 |
182
onionKnight888 2022-02-22 13:35:20 +08:00
oracle 上跑这点 sql 完全不是问题
|
184
onionKnight888 2022-02-22 13:37:48 +08:00
@raptor 改以前的存储过程真是 tm 痛苦,sql 相对而言简单多了
|
185
Braisdom 2022-02-22 13:38:12 +08:00
建议你看一下: https://github.com/braisdom/ObjectiveSql
一种比较优雅的方式写 SQL |
186
guabimian 2022-02-22 13:46:57 +08:00
这种配置表 简单联合查询 有什么问题? 分开几个循环去处理比较优雅?
不要拿关系数据库当 kv 来用好吧 |
187
msg7086 2022-02-22 13:53:29 +08:00
@liprais 对,无非是让数据库保证一致性,还是自己重新发明一遍一致性的问题。
对于大多数应用来说,会话之间不需要保证一致性,所以靠多开应用服务器(以及在单台机器上多开线程和进程)来提升运行速度。 如果有特殊需要,那当然特殊处理,所以银行、电信那些项目都有他们自己的特殊癖好,弄个大机,搞个 Oracle 之类的扛着,这个就不多说了。 |
188
FlyingShark 2022-02-22 13:55:17 +08:00 1
@danhahaha 楼主自找的啦,34 楼就开炮了,我看得笑死
|
189
cocong 2022-02-22 13:56:21 +08:00
没被坑过是体会不到这种痛的,例子里几十行 sql 还好,你们是没见过上千行的 sql ,动不动就死锁,一天到晚的出故障。
|
190
msg7086 2022-02-22 13:56:54 +08:00
|
192
28Sv0ngQfIE7Yloe 2022-02-22 14:04:55 +08:00
示例没啥问题吧,也没看到太多逻辑啊
|
193
guabimian 2022-02-22 14:08:24 +08:00
@msg7086 看他表名就知道没几行数据 还考虑各种缓存。过度设计考虑真是没必要 具体情况具体分析吧。不要把 mysql 想太弱鸡啦。另外很多脚本语言都特别怕循环,数据拿出来处理如果不用 pandas 这种 lib 大多数会很慢不会比数据库快。
总之还是要具体情况具体分析 ,教条主义要不得,没有万能药。 |
194
wangsd 2022-02-22 14:09:02 +08:00
你得看实际场景,不能一棍子打死,EPR 、工业领域这些领域写这种 SQL 很常见,很多 SQL 写好了以后基本不会去做改动。
|
195
aitaii 2022-02-22 14:11:22 +08:00
我写可以,其他同事不能这么写,我怎么维护。(:dog
|
196
clf 2022-02-22 14:12:30 +08:00
曾经还有全都写存储过程来实现业务逻辑的,项目基础代码就是调用存储过程去 CRUD 。
|
197
liangch 2022-02-22 14:13:34 +08:00
示例的 sql 算简单的了,没啥复杂的。
|
198
NeezerGu 2022-02-22 14:16:21 +08:00
|
199
unregister 2022-02-22 14:35:01 +08:00 1
以前搞 BI ,整天写 SQL,真的写到吐。我觉得 sql 复杂的话可读性不是很好,关联查询不要超过三张表,而且有些高级函数不同的数据库不一样。
|
200
l00t 2022-02-22 14:39:39 +08:00
@NeezerGu 在第二个 left join 里有用到。 当然它的这两个 left join 多半是 join 的误用,写成这样说明这人的 SQL 功底也不太行。
|