主數(shù)據(jù)系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)
1 主數(shù)據(jù)系統(tǒng)的必要性
隨著企業(yè)信息化的不斷深入,企業(yè)建設(shè)的業(yè)務(wù)系統(tǒng)、辦公系統(tǒng)等信息系統(tǒng)越來越多。由于規(guī)劃、預(yù)算、實(shí)施計(jì)劃等原因限制,各信息系統(tǒng)建設(shè)的步調(diào)不一致,規(guī)劃不統(tǒng)一,導(dǎo)致一個(gè)嚴(yán)重的問題:一些基礎(chǔ)數(shù)據(jù),比如商品編碼、客戶編碼等,在不同信息系統(tǒng)內(nèi)取值不一致,甚至定義也不一致,為各業(yè)務(wù)系統(tǒng)打通,以及數(shù)據(jù)中心建設(shè)帶來極大的障礙。這些基礎(chǔ)數(shù)據(jù)一般稱為主數(shù)據(jù),對主數(shù)據(jù)的規(guī)范和梳理需要建設(shè)“主數(shù)據(jù)系統(tǒng)”。
主數(shù)據(jù)問題主要有幾個(gè)方面:
各系統(tǒng)基礎(chǔ)數(shù)據(jù)定義不一,集中的數(shù)據(jù)處理(比如 BI、大數(shù)據(jù)、機(jī)器學(xué)習(xí)等)需要經(jīng)過繁瑣的數(shù)據(jù)清洗、格式化、一致性檢查和轉(zhuǎn)換等步驟,代價(jià)巨大;
數(shù)據(jù)字典各自為政,甚至存在無法調(diào)和的邏輯矛盾,比如在 A 系統(tǒng)是主鍵的字段在 B 系統(tǒng)卻允許不唯一;
有時(shí)候盡管定義了統(tǒng)一的規(guī)范,但各系統(tǒng)獨(dú)立維護(hù),也無法保證主數(shù)據(jù)的一致性。
由此,主數(shù)據(jù)系統(tǒng)的建設(shè)宜早不宜晚,特別是對于已經(jīng)在使用 ERP 的傳統(tǒng)企業(yè)。但是,由于主數(shù)據(jù)系統(tǒng)偏重于“技術(shù)優(yōu)化”的范疇,很難在業(yè)務(wù)上見到立竿見影的效果,甚至對于業(yè)務(wù)人員都是“透明”的,而且還投入不小,所以對于如何申請到資源并立項(xiàng),是個(gè)不小的挑戰(zhàn)。但這不在本文討論的范圍內(nèi)。
2 主數(shù)據(jù)系統(tǒng)設(shè)計(jì)的基本原則
主數(shù)據(jù)系統(tǒng)的設(shè)計(jì)方法很多,但大多數(shù)都需要對原有信息系統(tǒng)進(jìn)行傷筋動(dòng)骨的改動(dòng)。因此,各企業(yè)在主數(shù)據(jù)系統(tǒng)的實(shí)施上都比較保守,寧愿花費(fèi)大量的人工處理,以及諸多的各系統(tǒng)補(bǔ)丁,進(jìn)行數(shù)據(jù)清理和轉(zhuǎn)換,這種方案效率低而且無法解決根本性問題。
在結(jié)構(gòu)上,由于多個(gè)應(yīng)用系統(tǒng)之間,都可能存在提供數(shù)據(jù)和使用數(shù)據(jù)兩種角色,一般采用點(diǎn)對點(diǎn)兩兩交互的網(wǎng)狀結(jié)構(gòu),這種結(jié)構(gòu)對同步時(shí)序、轉(zhuǎn)換規(guī)則、系統(tǒng)復(fù)雜度等均提出了極高的要求,也帶來——復(fù)雜性高,實(shí)施周期長,無法分步實(shí)施,容易失敗等問題。
圖 1 網(wǎng)狀結(jié)構(gòu)和星形結(jié)構(gòu)
很顯然,星形結(jié)構(gòu)明顯由于網(wǎng)狀結(jié)構(gòu),而且必然對原信息系統(tǒng)的修改更少。
主數(shù)據(jù)系統(tǒng)設(shè)計(jì)原則幾個(gè)要點(diǎn)如下:
- 數(shù)據(jù)同步從一般的“網(wǎng)狀結(jié)構(gòu)”改為穩(wěn)定性高的“星形結(jié)構(gòu)”,打破點(diǎn)對點(diǎn)兩兩交叉的復(fù)雜結(jié)構(gòu);
- 通過“數(shù)據(jù)代理”方式,不侵入原信息系統(tǒng),不需要對原系統(tǒng)進(jìn)行大量改動(dòng),可以進(jìn)行有計(jì)劃的分步實(shí)施;
- 主數(shù)據(jù)系統(tǒng)對每一條數(shù)據(jù)記錄,設(shè)置全域范圍唯一的 uuid 記錄識(shí)別碼,用于主數(shù)據(jù)記錄全生命周期的識(shí)別、映射和轉(zhuǎn)換;
- 所有數(shù)據(jù)轉(zhuǎn)換、映射均由主數(shù)據(jù)系統(tǒng)實(shí)現(xiàn),對原系統(tǒng)完全“透明”;
- 關(guān)聯(lián)記錄通過 uuid 多次映射的方式,確保任何現(xiàn)有系統(tǒng)以及將來接入的系統(tǒng),都無需關(guān)心源數(shù)據(jù)的關(guān)聯(lián)關(guān)系,復(fù)雜度大大降低。
3 主數(shù)據(jù)系統(tǒng)的具體實(shí)現(xiàn)
下面結(jié)合一種實(shí)現(xiàn)方法,給出完整的數(shù)據(jù)庫設(shè)計(jì)和流程圖。并對其中的關(guān)鍵點(diǎn)進(jìn)行詳細(xì)闡述。該項(xiàng)目已經(jīng)上線運(yùn)行半年多,可靠性和數(shù)據(jù)一致性均經(jīng)過嚴(yán)格驗(yàn)證。
本項(xiàng)目幾個(gè)前提如下:
(1)所有業(yè)務(wù)系統(tǒng)數(shù)據(jù)庫都是 MySQL;
(2)所有業(yè)務(wù)系統(tǒng)數(shù)據(jù)提供者的主數(shù)據(jù)表都有 id 主鍵,但字段名不一定為“id”,也不一定具有自增屬性;
(3)所有業(yè)務(wù)系統(tǒng)數(shù)據(jù)提供者的主數(shù)據(jù)表都有最后更新時(shí)間戳,同樣字段名各不相同;
(4)所有業(yè)務(wù)系統(tǒng)數(shù)據(jù)提供者均以標(biāo)志位標(biāo)識(shí)“刪除”,而不進(jìn)行記錄的物理刪除。
3.1 總體架構(gòu)
總體架構(gòu)為星形結(jié)構(gòu),如圖 2:
圖 2 主數(shù)據(jù)系統(tǒng)總體架構(gòu)圖
其中:
(1)為簡化設(shè)計(jì),基于前提的第 2、3 點(diǎn),數(shù)據(jù)代理直接采用數(shù)據(jù)庫連接方式,定時(shí)對數(shù)據(jù)提供者的數(shù)據(jù)庫表進(jìn)行輪詢。由此,對于數(shù)據(jù)提供者對應(yīng)主數(shù)據(jù)表必須具有讀權(quán)限,對于數(shù)據(jù)消費(fèi)者的對應(yīng)主數(shù)據(jù)表必須具有 insert/update 權(quán)限;
(2)數(shù)據(jù)代理(1~n),每個(gè)均連接主數(shù)據(jù)數(shù)據(jù)庫和唯一一個(gè)信息系統(tǒng)數(shù)據(jù)庫。業(yè)務(wù)系統(tǒng)數(shù)據(jù)庫的“數(shù)據(jù)消費(fèi)者”和“數(shù)據(jù)提供者”角色可能只有一種,例如,辦公自動(dòng)化(OA)系統(tǒng),可能只作為“數(shù)據(jù)提供者”角色,提供組織架構(gòu)、人員等主數(shù)據(jù)。這種情況下,該“數(shù)據(jù)代理”無需配置和調(diào)度“數(shù)據(jù)消費(fèi)者”功能。
(3)MySQL 數(shù)據(jù)庫表結(jié)構(gòu)定義可以從 information_schema.COLUMNS 直接獲取,其他數(shù)據(jù)庫可以找類似系統(tǒng)表,如果沒有,則需要單獨(dú)填充字段定義。
(4)數(shù)據(jù)庫設(shè)計(jì)如下:
- tb_columns_def:表結(jié)構(gòu)定義,從 information_schema.COLUMNS 直接復(fù)制
- tb_data_role:數(shù)據(jù)角色定義
3.2 數(shù)據(jù)提供者拉取
功能流程如圖 3:
圖 3“數(shù)據(jù)提供者”拉取流程
其中:
(1)被定時(shí)調(diào)度(本項(xiàng)目設(shè)置 1 分鐘一次)激活后,連接對應(yīng)的信息系統(tǒng)數(shù)據(jù)庫,檢查是否有新增或更新記錄,如有,則進(jìn)行數(shù)據(jù)拉取——從源數(shù)據(jù)數(shù)據(jù)庫拉取并存入主數(shù)據(jù)數(shù)據(jù)庫,同時(shí)記錄“同步輪次”。
(2)一個(gè)信息系統(tǒng)可能提供多個(gè)“數(shù)據(jù)提供者”,在全部數(shù)據(jù)提供者都輪詢并處理結(jié)束后,流程結(jié)束。
(3)數(shù)據(jù)庫設(shè)計(jì)如下:
tb_data_sync_log:同步日志表,保存同步控制數(shù)據(jù)
3.3 數(shù)據(jù)消費(fèi)者推送
功能流程如圖 4:
圖 4 數(shù)據(jù)消費(fèi)者推送流程
其中:
(1)被定時(shí)調(diào)度激活后,檢查主數(shù)據(jù)系統(tǒng)“同步輪次”是否有新增,如有,則進(jìn)行數(shù)據(jù)推送。連接數(shù)據(jù)消費(fèi)者信息系統(tǒng)數(shù)據(jù)庫,從主數(shù)據(jù)數(shù)據(jù)庫推送新增或更新數(shù)據(jù)記錄到信息系統(tǒng)數(shù)據(jù)庫,同時(shí)記錄“同步輪次”。
(2)檢查主數(shù)據(jù)系統(tǒng)“同步輪次”是否有新增,通過 tb_data_sync_log.relative_cycle_no 與對應(yīng)主數(shù)據(jù)(main_role)記錄的最新倫次比較。
(3)一個(gè)信息系統(tǒng)可能需要多個(gè)“數(shù)據(jù)消費(fèi)者”,在全部數(shù)據(jù)消費(fèi)者都輪詢并處理結(jié)束后,流程結(jié)束。
(4)數(shù)據(jù)庫設(shè)計(jì)同數(shù)據(jù)提供者(參見第 2 節(jié))。
3.4 數(shù)據(jù)轉(zhuǎn)換
功能流程如圖 5:
圖 5 數(shù)據(jù)轉(zhuǎn)換流程
其中:
(1)數(shù)據(jù)轉(zhuǎn)換是不同信息系統(tǒng)與主數(shù)據(jù)之間,字段類型、長度、格式轉(zhuǎn)換的核心模塊。
(2)數(shù)據(jù)轉(zhuǎn)換通過參數(shù)配置和附加處理函數(shù),實(shí)現(xiàn)高度靈活性。
(3)數(shù)據(jù)轉(zhuǎn)換首先獲取源和目標(biāo)數(shù)據(jù)表的字段定義,其次獲取對應(yīng)字段的轉(zhuǎn)換規(guī)則。對所有已定義轉(zhuǎn)換規(guī)則的字段進(jìn)行處理:
A、對字段類型、長度進(jìn)行通用轉(zhuǎn)換;
B、調(diào)用附加處理函數(shù)(如果有),進(jìn)行特殊轉(zhuǎn)換;
C、按照關(guān)聯(lián) id 規(guī)則(如果有),讀取主數(shù)據(jù)數(shù)據(jù)庫的 id 映射,進(jìn)行 對應(yīng)關(guān)聯(lián) id 處理;
D、循環(huán)處理所有字段。
(4)數(shù)據(jù)庫設(shè)計(jì)如下:
tb_transfer_def:轉(zhuǎn)換規(guī)則定義表
tb_transfer_rule:轉(zhuǎn)換規(guī)則字段映射表
tb_id_mapping:id 映射表
4 關(guān)鍵點(diǎn)總結(jié)
主數(shù)據(jù)系統(tǒng)涉及多個(gè)系統(tǒng)的數(shù)據(jù)同步,由于各異構(gòu)系統(tǒng)的差異性,導(dǎo)致主數(shù)據(jù)系統(tǒng)復(fù)雜度較高,成功的案例不多。本項(xiàng)目基于前述前提,取得較好的效果?,F(xiàn)將關(guān)鍵點(diǎn)總結(jié)分享如下:
1、數(shù)據(jù)提供者的新增 id 和更新時(shí)間戳,對于不具備這兩個(gè)條件的數(shù)據(jù)提供者,無法辨識(shí)新增和更新,不能進(jìn)行增量同步,必須進(jìn)行改造。如果由于種種原因源數(shù)據(jù)無法改造,則可以考慮變通方法,利用數(shù)據(jù)庫自有同步工具(例如 Oracle 的 DGG 等),在同步的副本中增加新增和更新標(biāo)識(shí);
2、不管數(shù)據(jù)提供者還是數(shù)據(jù)消費(fèi)者,無法進(jìn)行數(shù)據(jù)庫直接連接的,則“數(shù)據(jù)代理”需要以外掛應(yīng)用的形式存在,與主數(shù)據(jù)系統(tǒng)的通訊采用 WebService 方式。將帶來緩存、重試、冪等……多個(gè)復(fù)雜度的大大提高。
3、由于不同主數(shù)據(jù)表之間字段上存在映射關(guān)系,比如人員的所屬部門的,需要在 id 映射上做多次轉(zhuǎn)換,基本原則就是以落地主數(shù)據(jù)的 uuid 為“唯一權(quán)威”,其他關(guān)系都通過與 uuid 映射獲得。
4、待補(bǔ)充——從數(shù)據(jù)庫設(shè)計(jì)中,經(jīng)過思考可以去發(fā)現(xiàn),不再贅述。