字典服务的设计与管理
一、业务背景
在搜索引擎的功能上,曾经遇到过这样一个问题,数据库中某个公司名称中存在特殊编码,尽管数据已经正常同步到索引中,但是系统中关键词始终也无法匹配到该公司;
然后在库中模糊匹配,将公司名称复制到搜索框中,这样就可以正常命中索引,那么问题也就很清楚了,这种数据"隐身"的情况,即看着是同一个字,但是实际上不是,通常由特殊编码引起的;
通过表单进行数据采集是常用的业务手段,但是如果表单存在多个任意输入的文本框,这样获取的数据在质量上可能存在很多欠缺,尤其针对一些核心字段,严谨的校验规则十分有必要;
如果站在数据层面来看,虽然获取多维度数据有利于全景识别,但是各个维度的值准确与否或质量高低才是关键,对于多数业务场景来说,只依赖数据实体的部分属性,更多还是在于数据维度的质量;
提高数据质量的手段中,最行之有效的方式就是尽可能对字段维度提供枚举值,将数据内容限制在约定的范围内,其次就是校验规则需要严谨,以此确保业务数据的高质量;
二、字典服务
在分布式系统架构中,比较常见的基础服务层通常有:调度、缓存、文件、消息、字典等,下面就来详细的聊聊字典服务的设计与业务协作的逻辑;首先看一看交互逻辑:
在字典服务中,通常管理公共的常量与数据枚举值的维护;常规情况下,在业务表单加载的时候,从字典服务中读取各维度枚举值,在表单提交的时候,校验相关枚举字段,以此提高内容的质量;
在字典服务中提供的枚举值,根本目的是为了确保数据值的统一性,尽可能的避免同一个信息用两种方式描述,比如编程标签:"JAVA"与"Java",虽然从程序角度可以规避识别,但实际上是可以避免的;
从字典服务常见的内容管理来看,通常包括:常量、状态描述、业务标识;行业、标签、地址、学校等数据码表;其最大的特点就是在系统中被全局复用和识别;
三、细节设计
1、维护方式
对于字典数据的维护,通常使用两种手段:枚举类管理,码表存储,参数表存储;如何选择对应的方式,更多是取决于数据的属性:
- 枚举类:维护基本不会改变的字段,比如数据的常规状态描述;
- 码表:通常数据具有层次或者级联关系,比如地址和行业中的多级联动;
- 参数表:即时要求很高,例如字段枚举值的定义,需要动态实时管理;
不管使用那种方式管理字典数据,都需要增强业务语义的描述,这样在业务表单中通过相应标识读取对应枚举选项即可,并且拦截范围之外的提交动作;
2、数据加载
字典数据的查询通常采用Cache-Aside缓存模式,即查询优先访问缓存数据,命中则返回数据;否则访问库表数据,获取数据后返回页面并同步缓存中;在控制中心做内容修改后也需要再次同步缓存;
字典服务虽然并不复杂的,但是系统访问却十分频繁,如果出现异常情况很容易对业务产生大规模的影响,既要考虑并发访问的流量,又要设计合理的查询降低加载时间,避免对流程产生有感知的影响;
3、数据修改
不管是采用字典方式加载枚举值,还是采用任意输入的方式,都会面对一个无法避开的问题,字段值在业务开发中不断优化,则需要对数据进行清洗,至于数据清洗的流程在之前有详细的总结过,这里不再赘述。
四、数据意识
数据字典本身的逻辑比较简单,但是如果放在数据体系中,这是一种基础的意识,在数据中很容易出现同名但定义不同,或者定义相同但名称不同,这会给数据分析带来很多不必要的麻烦;
所以基于数据字典的方式,明确数据口径同时避免业务语义产生分歧,尤其对于汉语来说,"意思"到底是什么意思?
五、参考源码
编程文档: https://gitee.com/cicadasmile/butte-java-note 应用仓库: https://gitee.com/cicadasmile/butte-flyer-parent#java#