前言
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 + 關係型資料庫的設計也可以是一個備選的方案。