本文基於面向基本公共衛生的業務系統設計經驗,抽象出一套適合大型ERP系統的表單業務資料模型,目標是最大限度保留系統彈性的同時,儘可能降低系統複雜度和開發成本。enjoy~
背景
填寫表單應該是所有業務線條中最避免不了的環節,例如我所經歷的醫療專案:
以上面兩個例圖作為示例,可以看到姓名、性別、出生日期、血型等欄位是完全重複的,由於業務場景的差異,表單被定義了不同的樣式和欄位結構,此時將遭遇以下幾種問題:
- 同一使用者經歷了兩個不同場景時,不得不重複填寫相同的欄位;
- 如果相同的欄位在兩個表格中的值不同,基本無法判斷哪個為正確值,例如同一個人在
居民健康檔案
中血型填寫為A型,而在居民健康檔案資訊卡
中填寫為B型; - 某些欄位會重複出現在不同的表單中,隨著業務需要,將其串連起來檢視其趨勢,如身高、體重、血壓、心率等等,以幫助醫生確診疾病,然而這些欄位儲存在各自的表單中,由於開發人員的變更、文件的遺漏和產品的迭代,無法窮舉出所有的這些欄位資料來源,即便能夠回溯所有的來源,本身也是一件十分消耗精力的事情;
- 因為政策或業務需要,要在原有的表單上做調整,新的標準導致表單欄位產生變化,此時原有系統為保證其執行的穩定,難以從資料表和底層程式碼中迭代,只能新增資料表做開發,當表單需求頻繁變化時,加劇資料碎片化的問題;
- 新增業務表單時,開發需要訂排期,使用者需要等待發版後才能使用,新增大量表單時影響原有開發計劃的同時,業務部門也難以快速開展系統業務。
- 做資料統計和分析時,由迭代造成的資料欄位遺失或變更,無法統計出完整而準確的資料,做出的報告難以反映出真實的情況 ....
傳統的區域化基本公共衛生系統正在經歷這樣的劇痛,當然其他行業比如金融的部分業務同樣面臨相同問題(本人只經歷過這兩個行業,見諒),如何在紛繁複雜的業務環節中抽離出四兩撥千斤的資料模型,除了滿足日益頻繁的業務調整外,還能將資料完整的、標準的儲存並利用起來,是後端產品經理的安身立命之本。作為一個不務正業的產品經理,這次就從資料庫表結構設計上,介紹一套解決方案:結構化動態表單。
場景和需求:
1.可覆蓋絕大部分表單業務場景。 2.表單樣式和欄位可靈活調整,不影響歷史積累資料,不會造成資料庫和程式碼層面的頻繁變更; 3.資料統計時能夠快捷、準確、全面地獲取到想要的欄位資料,不過度依賴文件和程式設計師老員工;
模組介紹
屬性庫
所有表單中所有的欄位都在屬性庫中定義,相當於表單欄位的字典。定義的核心包含屬性的唯一標識、屬性名、屬性值取值規則和約束等資訊。
因為我認為所有的欄位都是圍繞某個業務進行的,把這個業務抽象成物件,那麼這些表單的欄位就是這個物件的屬性,所以命名為屬性庫
如果用關係型資料庫表達屬性庫,根據以往的經驗可以總結出如下兩個基礎表:
屬性分類,主要根據使用者需求對屬性進行分類,方便查詢和後期的批量資料統計,比如健康管理把心率、瞳孔大小、脈搏等屬性規劃到生命體徵類,把身高、體重等屬性規劃到基本體徵類等等,因此僅需要定義唯一識別碼、名稱和分類說明即可。
屬性,這個表非常重要,是資料標準化的基礎表。唯一標識、名稱、說明,這是一個屬性最基礎的說明,不用解釋。
-
分類ID欄位可支援多個ID,表示一個屬性可劃分到多個分類下,這個可根據實際需求定義,我所經歷的場景是有這種情況的,比如心率,既可以是生命體徵類屬性,也可以是臨床診斷類屬性,很難絕對界定。當然屬性和屬性分類也可以通過單獨建關係表來定義對應關係,方法有很多,各有優劣,看技術leader自行選型吧。
-
屬性型別,根據個人的經驗,總結出圖中的幾種型別,相信大家都認識,不用展開,其中單選框、多選框兩種型別因為還依賴對應的取值字典,因此還需要到屬性值字典中定義取值選項。另外
值單位
這個欄位,方便做資料轉換和終端資料展示用,比如時長的值60,單位是分鐘,通過演算法即可轉換該單位的值為1小時。
屬性值字典,主要用於配合屬性型別為單選框或多選框的取值,也是資料標準化的一部分。
例如定義一個屬性叫性別的屬性規劃到基礎資訊分類中,此時會屬性庫的三個表中分別插入以下資料: 屬性分類表:ID=‘1’,分類名稱=‘基礎資訊’,分類說明=‘使用者基本資訊’ 屬性表:ID=2,分類ID=‘’,屬性名稱=‘性別’,屬性說明=‘使用者的性別’,屬性型別=‘單選下拉框’,值單位=空 屬性值字典:[ID=3,屬性ID=‘2’,字典值=‘男’],[ID=4,屬性ID=‘2’,字典值=‘女’],[ID=5,屬性ID=‘2’,字典值=‘未知’]
模版庫
所有的動態表單都是以模版的方式儲存在資料庫中,表單模版中定義表單中填寫的欄位、欄位的預設值和表單樣式。
由於表單樣式的不可預見性,因此可以準備一套符合自家產品風格的視覺設計語言,限定表單視覺樣式的框架,包含前面提到的屬性型別呈現樣式,和細化到UI在手寫、PC端、移動端的字型大小、線條風格、互動方式、間距、縮排、比例、佈局方式等引數,當然本篇由於篇幅限制不展開和視覺風格相關的討論,讀者可自行腦補。
既然是模版,肯定少不了控制元件,模版由控制元件組成,在這裡把控制元件分為兩類:屬性元件和容器元件。
表單模版,是表單的字典表,用於定義表單的基礎資訊如名稱、用途說明等,如果與業務銜接,還可以新增關聯的業務、填寫物件、觸發填寫的時間等,這部分資訊由具體的業務場景決定,可根據實際需求設定欄位。
容器元件,負責定義外觀樣式的元件,決定了屬性元件在表單中的呈現樣式,可根據不同佈局需求細分更多容器元件,這裡不展開細講。
-
順序號,在同級下的顯示排序,從左至右,從上至下的原則進行排列。
-
容器名稱,即表單中某方框的名稱,可不填
-
在終端顯示錶單時,需要充分考慮各個元件在頁面上的預設佈局引數和可變引數。通常前面提到的設計語言中會定義標準的內邊距外邊距、線粗和線色等視覺樣式,這些就是預設佈局引數,但元件在表單中的顯示順序、巢狀關係和元件內的元件排列方式等引數多數時候是需要配置的,依據實際需求新增引數即可。
-
容器元件可巢狀,當遭遇多級層級關係時,用容器元件實現巢狀關係再好不過了,不建議屬性元件也支援巢狀,因為會提高屬性值的取值複雜度,除了開發和資料儲存邏輯複雜度高外,後期資料分析時也會進入邏輯黑洞,應儘量避免
-
是否支援累加資料,此欄位用於控制元件內的元素,是否可以按照定義的欄位多組生成,例如如:
在容器元件主要用藥情況
中,屬性元件藥物名稱
、用法
、用量
、用藥時間
、服藥依從性
的值可以新增多次 -
還可以新增跟多欄位或子表,描述容器更多的視覺佈局樣式,比如支援PC端、移動端、列印手寫的樣式定義。
屬性元件,來自於屬性庫中的屬性,決定了表單中填寫的欄位資訊。
-
容器ID,當前屬性元件放置在某個容器元件內,若值為null,表示直接放置在表單中
-
屬性別名,為適應部分個性化的需求,可以為屬性定義別名,比如身高,對嬰兒通常叫身長,對青少年或成年人叫身高。別名定義到模版中而不是在屬性庫的意義在於,使用者的個性化稱呼通常只會在自己所處的場景內使用,對於其他場景下的其他使用者並不一定通用。
-
屬性預設值,很好理解,沒用把這個欄位放到屬性庫的理由和別名一樣,場景不同,預設值不一定通用。
-
是否必填,表單提交前判斷必填項的依據。
-
頁面區域,用於判斷當前元件出現在其父元件的位置,列舉型別。
屬性元件還可以有更多可擴充套件特性,後面會提到一些。
業務資料庫
有了前面的屬性庫和表單模版庫的配置,即可配置出各式各樣的表單,而實際使用這些表單儲存下來的資料格式是怎樣的呢?
表單主表,作為表單的索引表,主要是提供表單的填寫來源、時間戳和與業務相關的標記。
- 通常實際業務有很多附加的資訊,圖中給出的是本人面臨的業務場景常見的欄位。
容器明細表,這裡儲存了表單內負責樣式的容器資料,因為表單模版可能會變更,因此需要將其視覺樣式資料儲存下來,以記錄當時呈現的樣式,避免因為模版變更而造成的佈局樣式丟失。
屬性明細表,儲存了所有表單的所有欄位的值。
-
為了配合容器元件記錄其佈局樣式,還新增了容器ID、順序號、組號、頁面區域,用於記錄儲存表單時屬性在表單中的位置。
-
組號,當遇到屬性元件放置在允許累加資料的容器元件中時,標記出屬性值所在的組。
-
別名,若屬性在模版中配置了別名,則儲存在這裡,如果值為空,則顯示原屬性名。
-
修改時間,表單可能會遇到修改部分資料,因此標記欄位的最後修改時間。如果有屬性值的操作日誌,可以不要。
樣例
弊端
-
動態表單的存在,在一定程度上可以緩解產品迭代因業務變更帶來的壓力,但其開發複雜度較高,尤其表單模版,解析模版資料呈現到終端時,依賴遍歷演算法,對程式設計師的要求不低,若整套產品的應用規模不大,不建議使用動態表單,或者根據需求開發簡配版。
-
由於表單依賴屬性庫和表單模版的配置,屬性和表單模版的維護質量決定了表單的資料質量,因此需要有高度責任心和專業能力的人員來進行屬性庫的維護,提高了使用門檻,但反過來講,羅馬不是一天建成的,如果有野心建立行業標準,本身也需要大力投入資料質控。
設計思想和基本原則
-
產品開發和業務執行儘可能的解耦。業務人員不必完全依賴產品業務功能的情況下才能執行相關業務(這個問題單獨靠動態表單無法完全解決,還需要依賴工作流,不過沒有工作流時也可以勉強適應部分場景做業務試執行);
-
產品永遠做功能迭代,儘量避免資料迭代。常見的C端產品往往會有很多的營銷推廣廣告頁,這些廣告頁常常會頻繁變化,而且為了抓熱點往往需要即時響應跟進,如果按照每週發版1-2次的節奏,等發出來商業機會已經涼了,因此往往會做一個後臺配置廣告頁的功能,使運營人員可以自行配置廣告頁面,包含頁面元素、入口布局、外鏈引導、渠道埋點配置等等,這就是功能迭代。如果運營改一次廣告,產品即發一次版,這就是資料層迭代。每一次變更都將累積相應的資料,產品是生成這些資料的工具,產生資料是業務人員做的事情,產品和業務是冰淇淋機和賣冰淇淋的小姐姐的關係。
-
使用者永遠只能看到功能,只關心產品是否滿足其需求,而產品經理永遠要從高低遠近多維視角看待和解構需求,不斷的整合、重組、拆分、歸納,窮舉各種場景下的業務形態,在業務耦合和模組化處理上達到平衡,本質上是優化效率,創造利潤,如果達不到這兩個目的,這個產品不能叫產品,只叫藝術品。
-
提前預判功能模組的發展趨勢,在設計初期預留充分的擴充套件性和迭代方向,避免高頻率的推倒重來,當然如果是敏捷開發,請無視這條。
意義
- 屬性庫即資料規範,如果資料量在行業中足夠大,適用面足夠廣的情況下,具備發展為行業規範的潛力。
- 表單模版即資料介面標準,當多個系統需要進行資料對接時,最頭疼的往往是梳理資料對接標準,將需要對接的資料模版通過介面規範的方式匯出給對接方,資料欄位和取值規範一目瞭然,新老系統導資料也會用到。
- 資料利用更加便捷方便,需要查詢某項具體的屬性資料時,只需到屬性明細表中即可找到,無需遍歷其他業務表單
- 使用者可通過配置表單明確新需求,表單模版一定程度上提高了使用者需求和功能落地的溝通效率,一定程度上提高了產品的業務可擴充套件性
擴充套件性
以下是隨意舉例的可能的功能擴充套件方向,僅作為擴充套件閱讀
屬性元件功能擴充套件
多屬性之間的邏輯約束和預設值
- 性別為男時,診斷中不可出現婦科疾病
- 年齡在18-21歲之間,職業預設值為大學生
- 填寫了身份證號碼即可解析出籍貫、性別和出生日期
單屬性複用
- 姓名性別等欄位使用者一旦填寫後,以後再次填寫有這些欄位的表單即可自動填寫
屬性值字典 診斷、症狀字典資料可能依賴外部介面調取,而非本地屬性值字典庫
容器元件擴充套件
- 可配置容器背景圖,視覺優化
- 內部元素排列方式支援左對齊、右對齊、垂直排列、水平排列等
- 可套用整體視覺設計的皮膚
模版庫擴充套件
- 模版插入公用引數欄位,如表單中的製表機構、填表人、所在科室等等
- 表單中的欄位可作為工作流業務環節控制欄位,比如當支付方式為現金時,無需彈出支付二維碼
操作日誌
- 記錄所有使用者在業務表單上的操作記錄,包含操作人、時間戳、修改前屬性值
- 記錄所有使用者在屬性庫和表單模版庫上的操作記錄