V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
moxiaowei
V2EX  ›  Java

逻辑大量的写在 sql 语句里

  •  
  •   moxiaowei · 2022-02-21 16:40:54 +08:00 · 16180 次点击
    这是一个创建于 785 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

    就你发的这个示例 来说,一点问题都没。完全可以这样写。
    xsqfjys
        207
    xsqfjys  
       2022-02-22 15:06:20 +08:00
    如果你不是 leader 就少说话管好自己的代码就行
    kisick
        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 哪个更好维护呢?
    monkeydream
        209
    monkeydream  
       2022-02-22 15:30:56 +08:00
    这种级联的查询没有啥问题吧,只是这个 SQL 没有必要关联 role 表; ToB 业务很多比这个复杂多的场景要关联好多张表,如果拆开来做可能更复杂,所以还是要看具体场景。
    adoal
        210
    adoal  
       2022-02-22 15:33:37 +08:00
    @liprais 是这样的,如果实际业务对一致性要求搞,那就要在业务代码层里重新实现 RDBMS 的功能了。我不相信从一互大输送到社会上的小厂里当 CTO 、当夹狗屎的 cruders 在这方面能做得比关系数据库系统的开发者好。
    NeezerGu
        211
    NeezerGu  
       2022-02-22 16:27:14 +08:00
    @l00t 哦,是我看漏了。。

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

    我不知道为什么这么多牛人反驳楼主的论据是:“就这点 SQL 你看不懂?”

    能在工程领域说出这种话的人,水平能有多高?

    为什么要有这么多设计模式,为什么要有这么多方法去规约代码书写的方式,为什么《软件工程》这门课是大学必修?

    代码写出来谁不会啊...真正难的不就是如何让这么多行代码能够易读、可维护吗?数据层就干数据层的事情,业务层就干业务层的事情,这种最基本的东西都有争论的吗?

    最基本的,业务逻辑要改怎么办?是 SQL 语句好改还是 JAVA 代码好改?
    adoal
        223
    adoal  
       2022-02-23 00:42:07 +08:00 via iPhone
    难道在某些一互大(或者精神一互大) cruders 的母校里软工是必修课而数据库只配选修
    qaweqa
        224
    qaweqa  
       2022-02-23 00:54:14 +08:00
    @shadowfish0 按你这种需求那不需要用关系型数据库
    felixcode
        225
    felixcode  
       2022-02-23 04:01:20 +08:00 via Android
    @shadowfish0
    大量关系型数据库费死劲的优化 join 等性能,各种版本迭代,各种高价卖给客户,最后到你眼里还不属于数据层的东西。

    软件工程里数据库的功能难道不是以最高效的方式给其它系统提供数据增删改查吗?

    拿几行 SQL 语句出来这么多人都说不难看懂,那也就不难维护,到你这就是千难万难不好改,不想学 SQL 不想学关系型数据的理由各种各样,非得把拿难学难用难维护当挡箭牌吗?
    Chad0000
        226
    Chad0000  
       2022-02-23 05:09:19 +08:00 via iPhone
    @Joker123456789 #205 我和你的观点一致,技术要不断更新跟得上时代。

    而且我就是楼上个别所说的 35+程序员。
    cassyfar
        227
    cassyfar  
       2022-02-23 06:07:55 +08:00
    @Joker123456789

    你说的特别到位

    这个主题把好多人的水平都暴露无疑
    Chad0000
        228
    Chad0000  
       2022-02-23 06:16:24 +08:00
    @Chad0000 #226 而且我还搞得更极端,我连外键都不设置,也不在 DB 层做过多数据校验。当然 DB 能二次把关最好,但这无意中会增加 DB 的压力,于是干脆完全交给应用层好了,DB 就只做两个功能:存储和查询数据。

    越简单越不容易出错,同时也越容易扩展,迁移。
    yzbythesea
        229
    yzbythesea  
       2022-02-23 06:17:39 +08:00
    再补充下,数据库基本只能垂直扩展,即使水平扩展,收费也很贵。服务器可以很轻松的水平扩展,收费也便宜。所以基本运算压力都会放在服务器上。我从毕业到现在接触的生产服务都是用 nosql 作数据库,实际就是把运算压力减小到了极致。即使现在很多 nosql 做到了 sql 的 transcation ,我们也不敢多用,也是因为运算压力大。做好就是一个 put ,一个 get ,delete 都别,设个 TTL 就好了。
    fuchaofather
        230
    fuchaofather  
       2022-02-23 10:13:10 +08:00
    写 sql 也挺好的
    NeoZephyr
        231
    NeoZephyr  
       2022-02-23 10:21:25 +08:00
    这不才 3 个吗
    stephanew
        232
    stephanew  
       2022-02-23 10:38:18 +08:00
    @SuperXRay 那你哪来这么多戏啊,要你来揣测别人是陈述还是骂人秀优越?你在这咬文嚼字无非就是想说"我虽然同意 58 楼但那不是我说的,我只是帮你们翻译一下,所以那不是我的观点"? 这次我的理解到位了吗?
    stephanew
        233
    stephanew  
       2022-02-23 10:47:19 +08:00
    @mingl0280 人家哪句话说看不懂了?自己看屎山习惯了看出优越感来了?你用的工具方法别人也一定要用一样的?几个小时对于你可能多了,几秒吧。
    SuperXRay
        234
    SuperXRay  
       2022-02-23 10:57:56 +08:00
    @stephanew 你真是戏多
    stephanew
        235
    stephanew  
       2022-02-23 11:05:04 +08:00
    @SuperXRay 还好,看不惯某些人而已
    SeeYouNextTime
        236
    SeeYouNextTime  
       2022-02-23 13:46:35 +08:00
    互联网现状,眼看着从‘sql 里要不要写逻辑’ 变成 ‘这个 sql 复不复杂’
    ly1836
        237
    ly1836  
       2022-02-23 14:13:55 +08:00
    @Chad0000 赞同
    moxiaowei
        238
    moxiaowei  
    OP
       2022-02-23 16:06:00 +08:00
    @stephanew 别跟傻子计较,我都不理他们了
    mingl0280
        239
    mingl0280  
       2022-02-24 04:51:47 +08:00 via Android
    @yzbythesea 你这是带需求分析的,楼主是不带的,他数据库可能万年都扩不到需要增加第二台服务器的水平,这种情况考虑横向扩展就是脱了裤子放屁。
    mingl0280
        240
    mingl0280  
       2022-02-24 04:54:11 +08:00 via Android
    @stephanew 如果你把 SQL 都当屎山,我觉得你可能撑不到 35 岁失业。
    nolog
        241
    nolog  
       2022-02-24 11:18:16 +08:00
    个人觉得如果带筛选和排序只能这样写了啊,sql 排序比你代码排序快的多
    stephanew
        242
    stephanew  
       2022-02-24 12:27:56 +08:00
    @mingl0280 说不过了扣帽子?我说 SQL 是屎山了?自己喜欢堆屎山还要求别人跟你一样欣赏得津津有味?你要是担心失业平时堆习惯了我可以理解,毕竟只会 CRUD 的这年头确实不好找工作
    ecloud
        243
    ecloud  
       2022-03-15 13:52:56 +08:00
    我这随便一个查询 explain 一下都是 10 来行
    coyoteer
        244
    coyoteer  
       2022-04-13 11:46:02 +08:00
    @potatowish 那我们数据库实训,要做什么呢
    1  2  3  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1101 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 18:38 · PVG 02:38 · LAX 11:38 · JFK 14:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.