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

前后端分离时,常量字典大家一般怎么处理和使用的呢?

  •  
  •   DavinciDavinci · 2023-10-13 09:57:33 +08:00 · 2990 次点击
    这是一个创建于 411 天前的主题,其中的信息可能已经有所发展或是发生改变。

    就比如说一个产品,可能包含了很多部分,每个部分可以选配不同的零件。存储的时候会给零件编个号,形成一个键值对的表,记录零件的名称与编号的对应关系。在产品表中每个部分为一列,存储所使用零件的编码。

    之前有同事写类似的项目,写了个很长的 SQL 来拼接每一个零件的真实名称,再返回给前端,再加上又和其他表相连,整个 SQL 变得异常复杂且难以维护,想知道大家有没有类似的问题又是如何处理的呢

    21 条回复    2024-03-20 07:20:47 +08:00
    28Sv0ngQfIE7Yloe
        1
    28Sv0ngQfIE7Yloe  
       2023-10-13 10:17:13 +08:00
    不涉及统计的话,直接从查询数据后,根据 id 从缓存拿元数据信息,类似 ClickHouse 这种 OLAP 还有字典表的特性,逻辑也是使用缓存填充。
    fruitmonster
        2
    fruitmonster  
       2023-10-13 10:17:17 +08:00
    这就是属于开发中的奇淫技巧,经验积累了吧
    wuwukai007
        3
    wuwukai007  
       2023-10-13 10:18:51 +08:00
    一般是后端做成 json 文件,定时任务固定更新,前段直接读取静态文件.json 就行
    syubo2810
        4
    syubo2810  
       2023-10-13 10:24:15 +08:00
    1.前端处理字典
    2.慢的部分单独接口,先展示其他信息,慢的数据打圈圈,等加载完再显示
    litchinn
        5
    litchinn  
       2023-10-13 10:27:18 +08:00
    全局的常量字典我选择直接返回 code/id ,前端页面中会先查询所有这个类型字典的数据,所以能自行显示对应名称。这种通常用于如:产品类型,状态等字段。

    你说的这个属于业务型的关联查询。就 left join 查就可以了吧,如果由于整个 sql 关联了很多表且其中有大表导致查询比较慢,可以选择在代码中单独将零件的名称查出来再赋值,必要时使用缓存。

    我通常也不愿意写很长的 sql ,sql 越长越容易出问题,且通常说明设计不太合理。但也要实际情况结合来看,没有绝对的对错
    nothingistrue
        6
    nothingistrue  
       2023-10-13 10:28:29 +08:00
    你需要一个专门的数据字典模块/服务,供前后端同时使用(大部分时间是后端在用,显示时候的转码映射要后端做,前端仅在下拉框等动态内容获取时才使用)。还需要重新规划数据模型,将字典数据全部提取到一起,交给数据字典模块去负责。这还不算完,后端得调整架构,以尽量减少数据字典映射代码。前端需要合理设计缓存以减少网络响应时间。

    数据字典,或者说编码-名称模型,真特么是一个烂设计。
    nothingistrue
        7
    nothingistrue  
       2023-10-13 10:30:20 +08:00
    更正一下,不是烂设计,是真特么已经不符合当下的过期设计。
    syubo2810
        8
    syubo2810  
       2023-10-13 10:30:51 +08:00
    @nothingistrue 这可不是烂设计,名称变下不用字典那可就酸爽了
    Seulgi
        9
    Seulgi  
       2023-10-13 10:34:56 +08:00
    查字典接口,前端自己缓存,后续其他的产品接口,只需要返回对应的 id ,前端自己做 id 映射字典拼接。映射这个活,前端做,后端做都可以。主要就是在字段要缓存,后端缓存,就是查产品后后端组装完再返回,或者拆两个接口,一个查产品,一个查映射结果。
    unco020511
        10
    unco020511  
       2023-10-13 10:48:33 +08:00
    一般不是有配置中心/在线参数平台 等等这类服务吗
    yinmin
        11
    yinmin  
       2023-10-13 10:49:20 +08:00 via iPhone   ❤️ 1
    2 种方法因地制宜:
    1. sql 里 left join ,然后后端随着数据发送前端
    2. 前端初始化时,后端将字典表一次性发给前端

    考虑的因素:
    1.字典表小的用( 2 ),大用( 1 )
    2.字典表基本不变更的用( 2 ),变更用( 1 )
    3.字典表不希望被一次性脱库的用( 1 ),无所谓用( 2 )

    实际构建中,在系统部署时建立的字典且基本不变更的,用方法 2 (例如:订单状态、审批岗位等);在系统使用阶段会变更的字典,用方法 1 (例如:供应商、职工、部件等)
    worldqiuzhi
        12
    worldqiuzhi  
       2023-10-13 10:55:08 +08:00
    @nothingistrue 当下有什么替代字典的方案吗?
    Chad0000
        13
    Chad0000  
       2023-10-13 10:59:44 +08:00
    前端我用 Angular ,然后我写了一个服务用来保存所有静态和动态的字典。静态的一般就是枚举,动态的一般是可编辑的数据。前者初始化时就写死,后者是需要时动态从后台拉取并缓存在本地。

    基于上述服务(依赖注入),可实现动态绑定,这样字典拉取到后就会自动替换。同时也提供了下拉选择(支持搜索)等组件,只需要指定字典名称即可。
    Pastsong
        14
    Pastsong  
       2023-10-13 11:02:04 +08:00
    字典单独放一个接口呗,前端又不是不能自己 join
    dqzcwxb
        15
    dqzcwxb  
       2023-10-13 11:08:09 +08:00
    提供字典接口
    接口可以返回单个或者多个表数据如果多个表数据先单表查询(单表使用缓存命中率高复用率高)然后内存中 hashjoin
    今日写的每一个数据库 join 都是日后压垮性能或者压垮你的一根稻草
    nothingistrue
        16
    nothingistrue  
       2023-10-13 11:24:45 +08:00
    @worldqiuzhi #12

    如果只是个无意义的代码,那就不用编码,直接用名称。对于名称的变更,还有范围(对应前端的下拉/单选/复选的选项),另行准备其他数据模型去管理(请注意,相比与数据字典方式,这并没有增加工作量)。

    如果是完整数据的名称属性,例如部门的部门名称、商品的商品名称,那么需要分两种情况考虑。如果需要的是历史名称,例如订单上的商品名称,那么直接将名称固化的主数据上。如果需要的是当前名称,例如员工的部门名称,那么就只能根据主键去关联了。当然,这时候在面向前端时,如何写代码以及如何控制性能,跟数据字典一样的复杂。像部门这种少的数据还可以直接全量放到缓存上,如果数据量很大,那还得回落到数据字典方式,不过这时候是(自然/代理)主键——名称的字典,不是编码——名称的字典。

    编码——名称这种存储方式,以前肯定有其有利的地方。但现在,在存储成本可以忽略的时候,再搞编码,对业务逻辑、UI 、大小数据统计,都是负影响。
    Habyss
        17
    Habyss  
       2023-10-13 11:34:36 +08:00
    前端调用字典接口
    xiaohundun
        18
    xiaohundun  
       2023-10-13 13:14:35 +08:00
    有没有人能科普下为什么一定要用字典
    sunmoon1983
        19
    sunmoon1983  
       2023-10-13 13:19:09 +08:00
    字典这些东西,我一般都是在后端的配置中做好,然后提供接口给前端,前端打开应用的时候请求接口缓存下来就行了呗
    cslive
        20
    cslive  
       2023-10-13 14:19:39 +08:00
    做个字典表,前端自取
    dyv9
        21
    dyv9  
       252 天前 via Android
    @yinmin 直接在查到数据后对数据内容跑循环从 redis 里面拿字典翻译,这工作没必要给 数据库处理。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1052 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 21:41 · PVG 05:41 · LAX 13:41 · JFK 16:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.