从 枚举 到 数据字典 到 数据标准化 的几篇文章读后参考
最近遇到一个场景的问题:多个系统共用同一个枚举时的维护问题。在网上,按照关键词:从 枚举 到 数据字典 ,一路搜索过去,遇到几篇不错的文章。整理一下,类似于做个综述。
从 问题 以及 直观的解决方案 来表述问题的演变过程:
1. 在DB设计中,某个字段的取值范围只会是 某几种值,比如性别只会取:男 or 女,我们如果想在后续校验这个字段的值是是否规范要求的怎么办? 单独拎一张类型表出来,在这张表中就设定这个type只能是某几种value,后续在代码中拿这张表的数据作为参考往业务表中插值。这种解决方案,我们一般称之为 [类别表]。 2. 在做后台管理系统开发时,经常会遇到很多下拉select选项,这些下拉select的值一般是固定的几个,如果按照上面的思路,我们要建很多 [类别表]。不想建很多类别表,怎么办? 做一张公共的类别表,这张表里面存按照code区分不同类别。这种解决方案,我们一般称之为 [数据字典表]. 一般我们还会在后台系统中设计一个 数据字典菜单功能,方便修改字典。 3. 在java代码系统(或强类型语言)中,我们要从DB中读取数据字典放到内存中,不然每次都就去DB中做查询,多浪费性能啊。但是放到内存中,我们用什么类型来存放呢? Map or Enum,我们一般会用上面这两种类型。请注意这里都是从DB -> java对象,比如拿枚举来说,如果做要做任何的 值的比较是没法做的,因为一开始enum可能是一个空的enum然后读取DB动态加载了枚举项,所以是没法直接拿枚举的字面项去使用。 做判断必须是 字符串 转 枚举,然后枚举和枚举之间的比较;又或者是 枚举 转 字符串,字符串和字符串之间做比较。 4. 如果一个公司有很多系统,因为要做数据标准化,所以必须限定都是用同一套数据字典,而且为了编程的便利性,我们要求直接将 DB数据字典 加载为 java内存里的enum,这时怎么处理呢? 这时可以是一个公共二方包sdk来做这件事儿,还是每个系统都可以自己独立加载。每个系统在启动时都通过公共SDK,来动态刷新二方包中定义的枚举项。 这样限定了整个公司的所有系统不仅要 数据字典的值要一致,而且用到的枚举值也必须一致。 5. 如果后续某个字典项的值修改了,是否要通知到所有依赖SDK包的下游系统做联动发布呢? 这个问题,也是分布式系统建设中,如何建立并维护一个公共配置中心的问题一样类似的思路,如果数据字典的值在DB中做了修改那么可以通过kafka等异步消息的方式通知到所有下游系统中去。下游系统consume到消息时做枚举的动态加载操作。
上面几个解决方案以外的思考:
1. 不能直接利用枚举的字面值进行比较是个限制。 且java的枚举这种数据结构类型的语义是,静态的、固定的、不易修改的一类数据。所以,在有些文章上会说,动态加载枚举项是破坏了代码的可读性。 2. 版本的考虑,数据字典的数据应当是不能updae,不能delete,只能insert的。因为历史数据中已经使用了之前的枚举项。 3. 为什么不直接用数据字典缓存SDK包呢?想的是,通过枚举还是能起到一些强类型语言的优势。
比较不错的几篇文章:
1. http://www.talkwithtrend.com/Article/220231
这篇文章比较宏观,从公司的数据标准化建设的角度,来谈这个问题。解决方案可总结为,基于配置中心做本地可热加载的查询缓存系统。
2. https://blog.claves.me/2019/03/12/dict_enum/
https://blog.csdn.net/weixin_42476601/article/details/84261992
介绍了数据字典的概念,枚举的概念。
3. https://blog.csdn.net/qq_35530330/article/details/85647826
介绍了动态加载java枚举项的方法。
作者:木木