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

一张主表,多张关联表,查询逻辑写在 sql 中好,还是业务代码中好?

  •  
  •   shadow1949 · 2022-03-15 11:15:00 +08:00 · 2864 次点击
    这是一个创建于 1018 天前的主题,其中的信息可能已经有所发展或是发生改变。

    例如现在有表 a ,和多张关联表 a1,a2,a3……然后之间关系可能是 1:1,1:n,n:n 。 这种情况要查询 List<A>,然后 A 里面有多个关联表的对象,这种情况大家一般直接写在 mapper 中多表关联,还是写在业务代码中?

    个人以为: sql 中:只查一次,不用匹配字段,组装;但是不好维护; 业务代码中:逻辑清晰,便于维护;但是不好组装

    大家怎么看这个问题……

    23 条回复    2022-03-16 15:25:41 +08:00
    andytao
        1
    andytao  
       2022-03-15 11:21:39 +08:00
    这得看使用的框架是哪种,然后才能评估哪种维护成本更低、操控性更强。比如 Laravel 对连接支持很好,写在代码里没毛病。
    hhjswf
        2
    hhjswf  
       2022-03-15 11:29:40 +08:00   ❤️ 1
    为啥不好维护?代码中好维护在哪
    freeup
        3
    freeup  
       2022-03-15 11:37:05 +08:00
    我个人能通过 sql 一次性查出来的 肯定就写 sql 了 简单方便 一个查询就能把需要的查出来 而且分页 条件查询 排序 都比较的方便
    brezp
        4
    brezp  
       2022-03-15 11:38:49 +08:00
    我觉得业务代码中写好,封装的方法也能有效提高后续的开发效率;
    sql 里面 join 的查询很难写到业务通用,一般都是一个查询 sql 一个复杂 join 查询吧,难维护而且很难复用
    e7
        5
    e7  
       2022-03-15 11:47:22 +08:00
    join 一般最多 2 、3 张表,建议拆一下,查 2 次吧,剩下的数据整理写在业务中
    aababc
        6
    aababc  
       2022-03-15 12:09:39 +08:00
    感觉这个事情是针对场景的,如果是后端的复杂的筛选,排序写在 SQL 里可能有方便处理,但是连表的数量过多也是一个大问题。如果是针对单个数据的处理(1 -> N -> N) 可预见的小批量数据,感觉写在业务里更能方便数据的组装和业务的变更。
    xppppsfg
        7
    xppppsfg  
       2022-03-15 12:50:19 +08:00
    记得一个月前 v2 有个帖子有个老哥吐槽同事全写在 sql 里,下面吵起来了
    BeautifulSoap
        8
    BeautifulSoap  
       2022-03-15 12:59:44 +08:00 via Android
    代码里把逻辑拆开来必定需要先获取关联 id ,然后 where in (1,2,3,xx) ,所以我觉得问题在于 where in 的性能,只要 where in 性能没问题那代码里拆开来我觉得更好
    Chad0000
        9
    Chad0000  
       2022-03-15 13:06:54 +08:00 via iPhone
    一律写在业务中,这样方便缓存。比如你另外一张表是客户表,高度访问已经缓存起来了。
    onhao
        10
    onhao  
       2022-03-15 13:50:07 +08:00
    看结果, 过程最优,都是建立在看客自己的经验立场上的。一定要说那个好,还是很多老哥说的分场景。
    看了大部分人都建议你放到程序中处理,我偏偏建议你还是放 SQL 里,
    放 sql 简单,阅读简易。
    放代码中,估计看代码都挺费劲了
    简易简洁高效的代码比较好。
    aragakiyuii
        11
    aragakiyuii  
       2022-03-15 14:01:32 +08:00 via iPhone
    1 楼+1
    主要看你用的什么框架,框架不支持我觉得还是写到 SQL 里,除非说你代码写的挺漂亮
    dayeye2006199
        12
    dayeye2006199  
       2022-03-15 14:25:28 +08:00 via Android   ❤️ 3
    OP 得描述一下你的业务是什么,数据大概有多少,否则也不好推荐解决方案啊。

    比如你这应用是个 2b 的 erp ,那肯定是直接放 SQL 就可以了,不容易出错,数据库性能也好。

    如果你是 2c 需要大量 qps 的,数据库会变成瓶颈的,那可能考虑拉到服务端处理合理一些。

    但总体来说,只要数据库不是瓶颈,一律推荐 SQL ,数据库在表设计合理的情况下,做这样的工作性能比自己撸的代码强的多。
    THESDZ
        13
    THESDZ  
       2022-03-15 14:27:44 +08:00
    如果团队的水平比较高,建议拆分后放在业务里面,然后信任封装的方法,给人所见即所得的代码命名风格(或者框架支持)

    否则就 sql 一把梭好了...
    ToBeHacker
        14
    ToBeHacker  
       2022-03-15 14:28:47 +08:00
    数据库难以水平伸缩,现在的趋势都是把业务堆到应用里。
    jessun1990
        15
    jessun1990  
       2022-03-15 14:49:54 +08:00
    如果两者没有明显优势的话,倾向于 sql 。原因是
    1. 防止框架出现 bug ;(较少场景)
    2. 以后迁移框架方便。(极少场景)
    RainCats
        16
    RainCats  
       2022-03-15 15:32:19 +08:00
    只要不是作为过滤条件的关联表我都选择在代码里写多一个查询来拼接数据
    darksword21
        17
    darksword21  
       2022-03-15 15:35:37 +08:00 via iPhone
    快槽猛就 sql 不然就
    weizhen199
        18
    weizhen199  
       2022-03-15 15:40:18 +08:00
    如果真的是很多张,我还是建议你考虑下你 DB 的 tmp 空间。
    挺容易爆炸的。
    zergzq
        19
    zergzq  
       2022-03-15 19:17:13 +08:00
    建议写代码 不写 SQL 。级联查询对数据库来说 随着数据增长有很大的风险。
    gam2046
        20
    gam2046  
       2022-03-16 09:01:44 +08:00
    个人是一律丢数据库,毕竟写起来简单,后期数据库顶不住还可以读写分离、一主多从。有的小伙伴自己实现的 left join 逻辑真的感人,一言不合就笛卡尔乘积。

    都丢数据库,至少下限是比较高的。哪怕是初学者也不会写的太垃圾。
    yibo2018
        21
    yibo2018  
       2022-03-16 10:25:55 +08:00
    @gam2046 你好,我看到你说一言不合就笛卡尔积,就去查了一些资料,只有一种情况会产生:join (没有 on)的情况下,我说的对吗
    gadfly3173
        22
    gadfly3173  
       2022-03-16 12:51:18 +08:00
    mybatis 的 collection 和 association 这样的延迟查询感觉还是挺适合的,不会有很大的性能压力。
    gam2046
        23
    gam2046  
       2022-03-16 15:25:41 +08:00
    @yibo2018 唔 我的意思是,我的小伙伴在业务逻辑中自己组装数据的时候,很容易出现笛卡尔乘积。就是有一些小伙伴的业务能力相对欠缺,因此还不如直接把这些任务丢给数据库,至少数据库的下限高于许多开发人员。

    至于数据库上的笛卡尔乘积,除了 inner join 以外,在多表查询或者嵌套了子查询的情况下,也容易出现。但是数据库上的问题相对好解决(即数据是通过视图返回的,即使存在问题后修改,保证字段一致,不需要修改程序),同时存在 explain 方便排查。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5323 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 05:48 · PVG 13:48 · LAX 21:48 · JFK 00:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.