關於維度信息維護和字典表的一些看法
在不同的公司的不同項目場景下,絕大多數情況下都需要維護一些基本的維度信息(也稱為字典信息,下面全部使用維度信息代替描述),比如旅游相關的網站,可能會維護:
- 貨幣類型:美元,人民幣,港幣等
- 航程類型:單程,雙程等
- 產品線:機票、酒店、度假等
諸如此類的維度信息。而且往往這些維度信息可能不同的業務部門都需要使用全部或者其中的某些的某些。因此隨着時間的推移,這些維度類型可能會新增,修改,刪除某些項。導致不同部門維護的維度信息不同,但是往往公司中的部門不是獨立存在的,往往都需要互相交互。因此會涉及到維度信息的轉換。
我們都知道統一維度的重要性,這一點怎么強調都不為過。但是往往現實是存在太多的維度不統一的場景了,在維度已經不統一的情況下,我們應該如何去逐步改善這些場景。
因此本文主要着眼於我在實際工作中遇到過的問題,做一個總結,希望對大家有幫助。
維度信息的使用
一般我們是如何使用維度信息的呢?比較通用的解決辦法往往是:
- 數據庫中創建字典表
- 代碼中創建對應的ENUM
我想絕大多數項目應該都是這樣來解決維度信息的存儲和使用問題的。但是有以下的一些注意點:
維度信息維護面臨的數據一致性問題
這種使用方式往往會存在什么問題呢?假設有3中類型的維度信息:A、B、C:
第一個問題:系統1僅僅使用了維度A,而系統2使用了維度A和維度B,系統3使用了維度B和維度C。
而系統1、系統2、系統3都有自己的數據庫。請問這個使用,這些維度信息的字典表建立在哪個系統的數據庫中?還是說每個系統都建立一份字典表?
第二個問題:結合第一個問題,同樣,往往每個系統都會有對應一個或者若干個工程項目,這些維度信息是哪些系統用到了就創建對應的枚舉,還是統一維護一個工程,把所有的維度枚舉都寫在里面,統一維護?
上面的2個問題,其實是同一個問題,就是數據的一致性問題。當同一類信息存在的地方越多,一致性的問題越顯著。也越需要迫切的解決。因為如果不及時有效的解決的話,系統中會存在各種各樣的Adapter來進行維度信息的轉換工作。
我們的解決辦法:
- 每個系統使用那些維度信息,就會有一張對應的維度字典表
- 專門有一個工程或者說jar包,將部門內部所有的維度信息的枚舉類收集在一起
- 考慮到之前的一些歷史項目的維度信息和現在的標准的維度信息不統一,因此在上面的jar中統一提高了維度轉換適配器。
- 同時會有一個專門的維度維護系統,對應一個數據庫數據庫:里面記錄着所有的維度字典表。同時記錄了哪些系統的數據庫中有哪些維度表,同時這個系統提供了維護界面。
- 然后后續新增的維度直接和平台的維度一一對應。接着逐步修正之前的維度數據。
這樣當新增,或者修改維度信息的時候,我們會在「維度維護系統」的界面上進行維度信息的新增、修改操作。然后根據上面第四條描述的,根據維度系統的數據庫中記錄的“哪些系有哪些維度表”的對應關系,然后程序自動新增、修改這些周邊系統的維度字典表數據。
當然當新增一種之前不存在的維度信息的時候,一開始只會在「維度維護系統」的數據庫中創建,然后哪些系統需要使用,就同步哪些系統。
數據庫維護以后,然后更新升級我們的jar包就可以了。
通過這種方式我們在很大的程度上解決了維度信息的不一致問題。
維度字典表的設計問題
為了方便開發人員統計每個系統有哪些字典表,我們在設計字典表的表名稱的時候,統一采用了:_dict結尾。比如產品線字典表的表名為:product_line_dict
為了方便程序處理,我們也統一了表的格式:
use test;
set names utf8mb4;
create table product_line_dict(
id int(10) unsigned not null auto_increment comment '維度序號',
code varchar(32) not null comment '維度編號',
name varchar(32) not null comment '維度名稱',
primary key(id),
unique key uniq_idx_code(code)
)engine=innodb default charset=utf8mb4 comment '產品線維度表';
比如對於上面提到的product_line_dict表:
id code name
1 flight 機票
其中id為表的主鍵,code列加唯一索引。另外系統說明的是表級別的comment注釋都是必須要寫清楚的。這樣方便新人閱讀數據庫表。
比起字典表只有:id、name這兩列來說,這樣的好處是:
- 將枚舉中的code和數據庫中的code統一起來
- 和部門外系統交互的時候,接口中只給code就好了,比只給id更加清洗
