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

你们使用的级联删除策略是怎样的?

  •  
  •   tctc4869 · 2020-05-18 09:55:31 +08:00 · 3418 次点击
    这是一个创建于 1679 天前的主题,其中的信息可能已经有所发展或是发生改变。

    网上有一个想法是不要用外键做级联删除,那不用数据库自带的外键功能实现级联删除的程序员们,你们是如何使实现级联删除的,是使用 orm 框架自带的,还是自己设计的一个级联删除策略的框架?

    级联删除策略的框架,这种在单数据源的情况下,一般都是通过 Model 类注解的项进行配置,执行删除操作的时候都是生成一大堆 delete 语句(有的会缓存为模板,删除的时候先执行 replace 操作,然后用替换后的 delete 语句 sql )。目前这种框架有现成的吗?

    19 条回复    2020-05-18 18:41:30 +08:00
    AngryMagikarp
        1
    AngryMagikarp  
       2020-05-18 09:57:34 +08:00
    一个事务,删除相关数据呗。你是不是把事情想复杂了。
    bnm965321
        2
    bnm965321  
       2020-05-18 09:59:33 +08:00
    看情况设置啊,PROTECT/SET_NULL/CASCADE
    bnm965321
        3
    bnm965321  
       2020-05-18 10:01:06 +08:00
    https://stackoverflow.com/questions/38388423/what-does-on-delete-do-on-django-models

    我用的是 Django 的级联,但是这是 SQL 标准,也就是在 db 层执行
    Aresxue
        4
    Aresxue  
       2020-05-18 10:02:34 +08:00
    不要用外键, 不要用外键, 不要用外键。
    而且 jpa 和 hibernate 上才有使用这东西的价值, 可以考虑在业务层做这种处理, 而像 mybatis 这种基本靠 sql 的可以直接在 sql 里完成这个逻辑。
    sansanhehe
        5
    sansanhehe  
       2020-05-18 10:11:43 +08:00
    一般都是软删除,所以我一般都会在 transaction 里执行所有级联删除
    xuanbg
        6
    xuanbg  
       2020-05-18 10:13:01 +08:00
    delete a,b,c from a left join b on b.aid = a.id left join c on c.bid = b.id where a.id = 'x';
    tctc4869
        7
    tctc4869  
    OP
       2020-05-18 10:15:49 +08:00
    @Aresxue
    实体关联增多了,mybatis 写起来就有点麻烦,想通过注解配置,生成 delete 语句这种方式,然后交给 jdbc 或 orm 框架执行,这种有现成的吗?
    shangfabao
        8
    shangfabao  
       2020-05-18 10:16:37 +08:00
    一般现在都没有设置外键,都是一行行执行
    wysnylc
        9
    wysnylc  
       2020-05-18 10:30:39 +08:00
    不使用外键不使用级联查询(join)不使用级联删除
    在代码中做约束进行删除,查询分开查询后使用 map 拼接
    Aresxue
        10
    Aresxue  
       2020-05-18 10:30:56 +08:00
    @tctc4869 这个不了解,感觉不一定有框架因为功能太小了,可以自己实现两个注解,一个用于实体, 一个用于字段, 然后实现 mybatis-plugin 的 Interceptor, 检测到 po 上有实体注解时就在数据删除后进行级联数据的删除(软删除和物理删除都行), 注解里面有表名, 然后在作为删除条件的字段上加上字段注解用来动态提取字段值
    Aresxue
        11
    Aresxue  
       2020-05-18 10:31:46 +08:00
    @tctc4869 只是个大概思路,细节需要你自己敲定,甚至也不一定要用注解,切面也可以
    12tall
        12
    12tall  
       2020-05-18 10:37:22 +08:00
    用外键它不香么
    ISSSSSSS
        13
    ISSSSSSS  
       2020-05-18 10:42:04 +08:00
    前提是:不做物理删除,那么本质上所有的删除,其实就是更新。
    如果是单体应用,事务管理是比较合适的。
    chmaple
        14
    chmaple  
       2020-05-18 10:45:42 +08:00   ❤️ 1
    前置:MyBatis
    1 、不用外键
    2 、代码做事务
    3 、不 delete,update del_flag,逻辑删除
    4 、自建开发了 mapper 自动构建的工具,先设计好数据库再一键生成项目或者实体类+mapper 接口+mapperXML 文件
    5 、自建 BaseMapper,提供基本的 select/selectById/insertSelective/insertBatch/updateByIdSelective/delete(逻辑删)
    fkdog
        15
    fkdog  
       2020-05-18 11:39:23 +08:00
    现在没有搞物理删除的,都是设置一个删除标记
    xhf1024
        16
    xhf1024  
       2020-05-18 11:52:30 +08:00
    @fkdog 逻辑删除,然后会定时清理嘛
    fkdog
        17
    fkdog  
       2020-05-18 11:55:01 +08:00
    @xhf1024 不清理的。产生的都是数据,都算是价值。
    事后翻旧数据留个底总比没有的好。
    而且关联关系复杂的系统,删除数据产生的问题可能会有很多。
    deco
        18
    deco  
       2020-05-18 16:31:04 +08:00
    同 @fkdog
    不允许物理删除,打删除标记
    数据都是有价值的
    定期归档。
    leon0903
        19
    leon0903  
       2020-05-18 18:41:30 +08:00
    不重要的数据感觉还是可以物理删除吧,要不然你会发现一大堆无用的历史数据,也挺糟心的。我感觉只需要在一些关键数据上做逻辑删除即可
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2714 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 10:03 · PVG 18:03 · LAX 02:03 · JFK 05:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.