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

关于后台数据库结构和业务逻辑的一点疑惑,求指导

  •  
  •   soar0712 · 55 天前 · 2175 次点击
    这是一个创建于 55 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我之前主要做移动端,最近尝试着自己学习和写后端业务,但在构思的过程中遇到一些疑惑,想知道这类问题的普遍做法应该是什么样的,求指导。 疑惑 1:假设用户有角色,角色是一张表,由管理员增删改,用户是一张表,有角色 id ,当管理员修改了甚至删除了某个角色,用户的角色应该怎么处理呢。我能想到的可能操作,1 是制定一个默认角色,被删除角色的用户都变成这个默认角色; 2 是逻辑里判断只要有用户在使用这个角色,就不能删除。哪种更常用呢?

    疑惑 2:与疑惑 1 类似但感觉更复杂,比如有任务模板表,每个模板都有一系列子任务;然后有一个任务表,每个任务都是从任务模板对应的,具体的任务必须要按照任务模板的子任务逐个执行;那么,任务模板的删改操作,应该怎么维护呢。假设有脱胎自某个模板的任务正在执行中,此时修改甚至删除了部分模板的子任务,那么当前这个任务的执行逻辑怎么保证呢?

    求指导,真心~

    22 条回复    2024-07-18 14:53:52 +08:00
    Noicdi
        1
    Noicdi  
       54 天前 via iPhone
    第一个问题,我这边是 2

    我现在在使用的逻辑是,一张角色表,上面记录各种角色相关的数据,一张角色与用户对应表,记录角色 id 和用户 id 的对应关系。删除角色时根据角色与用户对应表,判断该角色是否有用户在使用,有的话则不允许删除
    temia
        2
    temia  
       54 天前
    软删除
    7911364440
        3
    7911364440  
       54 天前
    1 、 更常见的是加一张用户和角色的中间表,删除用户或角色时把中间表也删掉
    2 、任务只在启动时获取模版信息,后续修改模版不影响正在执行的任务
    yzqdm
        4
    yzqdm  
       54 天前
    @Noicdi #1 我想请教一下,像用户表和项目表,一个用户可以绑定多个项目,在用户和项目的关联表中,是绑定一个项目一条数据,这样就是一个用户有多条记录。还是这个用户绑定的所有项目都只用一条 json 数组存起来
    soar0712
        5
    soar0712  
    OP
       54 天前
    @Noicdi 请问,为啥一般是使用中间表连接用户和角色,而不是直接在用户表里有角色 id 字段呢,直接用 id 引用会有什么弊端么
    liuhuansir
        6
    liuhuansir  
       54 天前
    @soar0712 应该是多对多的问题吧,一个用户可能有多个角色,用中间表更合适
    sujin190
        7
    sujin190  
       54 天前   ❤️ 1
    实际工程上正在使用的角色或模板不允许删除实际上才是更好用的,否则用户会给你搞出各种各样的毛病出来,而且后续一通乱改加各种需求流程后,你会发现各种想到想不到的地方都会和你角色、模板什么的有关联,所以一般来说还是让这种处于流程源头的关联关系使用中不让删才是最科学的,产品需求的话也可以用交互来满足啊,不一定就在底层数据逻辑上来满足,比如提示用户并给出一种相对方便的方式让用户完成解绑不再使用就是了
    soar0712
        8
    soar0712  
    OP
       54 天前
    @sujin190 明白了,就是尽可能不让删除,要删也要尽可能解绑之后再操作
    sujin190
        9
    sujin190  
       54 天前
    @soar0712 #8 本质逻辑还是相同需求可以有不同方式表达,不一定非要用这种直接粗暴的方式由最底层的数据结构来完成,而且实际工程中,业务流和数据流不一定要一致,业务流程不可避免需要逆方向,但是数据流随时间往前应该尽可能不逆方向

    更进一步在你提出的角色这个场景中业务流程中随时间方向需要删除角色并没有逆方向,但是数据流按你这么设计却并未保持随时间方向而是出现了逆方向,这种逻辑在实际过程中会导致非常多的问题
    Noicdi
        10
    Noicdi  
       54 天前 via iPhone
    @yzqdm #4 我们这边是关系型数据库,直接一个用户多条记录
    Noicdi
        11
    Noicdi  
       54 天前 via iPhone
    @soar0712 #5 对于我们的业务来说,一个用户可能没有角色,也有可能有多个角色。与其用户表里直接记录角色 id ,不如使用中间表来记录对应关系
    IvanLi127
        12
    IvanLi127  
       54 天前
    1. 用户和角色应该是一对多关系,删了就不属于这个角色,对应权限直接失效。可以前端提示用户不能删角色,但是删了不应该影响系统运行。
    2. 这种模板应该加版本号,每次修改时,复制一份,版本号加一再存进去。这样就不会出问题了,后续重试任务还能读到原始模板信息。或者创建任务时直接把任务模板的内容冗余一份绑定到任务上存起来。
    sagaxu
        13
    sagaxu  
       54 天前
    第一个问题,禁止物理删除角色,只能禁用。

    第二个问题,每次提交任务时,复制一份模板到任务详情。在任务执行第一个子任务前,可以根据逻辑决定是重新 load 当前模板,还是使用创建任务时保存的模板。
    wenhuacode
        14
    wenhuacode  
       54 天前
    停用
    janus77
        15
    janus77  
       54 天前
    角色一般不删除的吧
    用户关联角色,如果你要修改权限那就给这个用户换另一个角色 id 就行,如果你想停用用户那就给用户加个新字段控制 disable 状态。角色应该是属于无状态的部分,类似于配置那种
    实在想要把这个角色下的用户全部停用,那也是批量操作对应的用户,而不是操作角色
    RandomJoke
        16
    RandomJoke  
       54 天前
    1. 看业务需求,如果能接受不可删除,那就最简单,不能的话,就软删,只是不可见。
    2. 差不多的问题,如果简单点,模板的修改在任务执行中不可修改。复杂点就加版本号维护,或者在任务开始前全拷贝模板再开始执行。
    kujio
        17
    kujio  
       54 天前
    逻辑删除,且做好角色和用户变更记录,查询的时候根据变更记录去查。
    实际业务中除了你说的这些问题还有别的问题,比如:
    A 用户从 A 部门转去了 B 部门,此时如果有部门相关的统计,A 转去前的数据应该算在 A 部门,转去后的数据应该算在 B 部门。

    在业务表设计的过程中,应该考虑字段的情况:是否可变、是否会被引用。
    如果可变且会被引用,那么这个字段就应该做变更记录。

    个人浅见
    kujio
        18
    kujio  
       54 天前
    其实很多时候,变更都需要走流程的。所以在设计的时候,如果想要简单一些,那就尽可能的舍弃掉可变的,做成不可变的就行了。
    kujio
        19
    kujio  
       54 天前
    很多烦恼都是“既要又要”带来的
    qiyilai
        20
    qiyilai  
       53 天前
    1 、不删除
    2 、版本号
    BeginInvoke
        21
    BeginInvoke  
       53 天前
    1. 角色只能切换不能删除
    2. 子任务表设模板表关联字段可空,模板删除任务是否执行看业务需求,执行任务时只需要查任务表
    先看看表关系是一对多,一对一,还是多对多
    yzqdm
        22
    yzqdm  
       51 天前
    @Noicdi #10 了解了,感谢回答
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2448 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 03:00 · PVG 11:00 · LAX 20:00 · JFK 23:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.