前言
Flowable, Activiti 等開源解決方案所提供的表單引擎是沒有業務表單數據持久化的功能(即自動創建表,將表單數據持久化功能),只提供動態表單創建以及渲染功能。目前來看表單引擎服務主要功能如下:
- 動態表單配置以及渲染(主要在於前端實現)
- 表單數據庫持久化
以下是目前實現業務表單數據持久化的幾種方案:
以下方案都以請假流程的表單為例,比較簡單就請假天數(days)以及請假理由(reason),動態表單如下所示:
方案一:動態添加字段
一個表單對應數據庫的一張或多張物理表(主從表)
針對請假流程如何操作呢?給請假流程表單創建一張數據表,包含字段 days
以及 reason
。其他業務表單也是如此操作。
create table leave_data
(
days int default 0 null comment '請假天數',
reason varchar(250) null comment '請假理由'
)
comment '請假流程業務數據';
該方案存在的問題:
- 一個表單對應數據庫的一張或多張物理表,隨着業務的增多,數據庫的物理表會不斷膨脹。
- 業務表單字段需要修改時(比如給請假流程添加一個開始時間字段,就需要調整物理表結構),其對應的物理表結構也需要修改,在物理表很多數據時,改變物理表scheme會鎖表。
方案二:預留空白字段,動態分配
業務數據存儲表:
create table data
(
name varchar(250) null comment '業務表單名',
field_0 varchar(250) null comment '字段0',
field_1 varchar(250) null comment '字段1',
field_2 varchar(250) null comment '字段2',
field_3 varchar(250) null comment '字段3'
)
comment '業務數據';
業務表單屬性表:
create table table_config
(
name varchar(250) null comment '表單名',
field_name varchar(250) null comment '字段名',
field_map varchar(250) null comment '字段映射'
)
comment '表配置';
實際操作下來,存儲是這樣噠:
那么動態字段變更需要修改表字段配置表即可。
缺點:
- 操作數據的時候都需要先去 map 中轉以下才能查詢(程序層面可以解決)
- 如果一張業務表保存所有的數據話,不利於優化(可以進行擴展,配置多張業務表,不過這樣也可能會出現方案一中物理表爆炸的問題)
方案三:屬性使用 KEY/VALUE 格式存儲
將表單數據全部都用 Key/Value 的格式來存儲。參考如下:
create table attributes
(
f_id varchar(250) null comment '關聯id',
key varchar(250) null comment '屬性',
value varchar(250) null comment '屬性值',
field_2 varchar(250) null comment '字段2',
field_3 varchar(250) null comment '字段3'
)
comment '屬性';
具體操作后即是:
動態添加屬性字段只需要添加 Key/value。題外話,reddit 的數據庫就兩張表,也是這樣的設計方案,不過現在已經改掉了,成為歷史。
缺點:
- 不太好支持關聯子表
- 程序中處理取值不方便
方案四:MongoDB 方案設計
MongoDB 方案的話,只需要將前端發過來的JSON寫入即可,這里還是以請假流程為例:
集合內數據允許動態添加字段:
集合類似於關系型數據庫中的表,可以存儲不規則的數據,只能說 Mongodb 擅長干這種事情。
總結
以上方案設計生產環境使用還需要改進使用,目前市面上用的多得應該是方案二,MongoDB 也是一個不錯選項,僅在數據持久化這塊,具體業務場景下使用 MongoDB + 關系型數據庫的設計也可以是一個備選的方案。