編輯導語:ER建模你知道是什麼嗎?對於產品經理來說必須重視ER建模工作,它決定了軟件產品的擴展性和靈活性。本文作者通過例舉了某在線教育公司的ER建模的例子,讓大家在老王和小李的對話中,展現ER建模的魅力,同時加深對於ER建模的理解。

ER建模:Entity Relationship,也叫實體建模,是軟件工程中非常重要且核心的概念。

對於產品經理,尤其是一名B端產品經理,必須掌握並且重視ER建模工作。

ER建模的好壞,決定了軟件產品的擴展性和靈活性。ER建模不準確,有可能導致軟件設計缺陷,甚至帶來嚴重的業務問題。

如果將軟件產品設計比喻成蓋大樓,那麼ER建模抽象出的實體對象就是大樓的根基,圍繞實體對象建設的應用功能就是大樓的外貌,根基決定了大樓的結構和功能,如果根基不穩或錯誤,大樓就有可能崩塌或不符合預期。

這些偏理論的敘述可能會讓大家感到困惑,接下來,我們通過一個實際案例,讓大家深刻理解ER建模的魅力。

在案例開始之前,我們再稍微對ER設計相關知識,做一個非常簡單的介紹。

一、什麼是ER建模

軟件設計的核心要點,就是將客觀世界的事物,準確的提煉抽象,變成計算機可以理解的面向對象的設計。

我們將客觀事物抽象成對象設計的過程,就叫ER建模,抽象出來的對象,就叫做實體(Entity),除了抽象出實體,我們還需要關心實體的屬性,以及實體之間的關係(Relationship)。

比如電商中的賬號和訂單,就是抽象出的實體,一個賬號可能有多個訂單,每個訂單隻可能歸屬於一個賬號,這就是賬號和訂單之間存在的一對多關係。

除了一對多關係,實體之間可能還存在零對多,多對多的關係。

描述實體對象和關係的圖形,叫做ER圖,ER圖的呈現方式有很多種規範(比如UML,Chen,Crow’s Foot等等),繪製方法不重要,作爲一名產品經理,只需要簡單清晰地表達出設計意圖即可。比如上述提到的賬號、訂單實體關係圖,可以簡單繪製如下:

本文的重點,在於讓大家理解ER建模如何影響了產品方案並決定了業務,所以關於建模的一些基礎知識和設計方法論不展開講述。

接下來,進入我們的案例。

二、案例:某在線教育公司的ER建模

某初創公司開展在線教育業務,面向低齡兒童,因爲客單價高,成立電銷中心團隊完成銷售工作。公司安排了資深產品專家老王負責整體產品方案設計,小李是老王的助手,初級產品經理。

老王決定借這個機會鍛鍊培養小李,因此手把手指導小李參與設計工作。

老王:小李啊,公司計劃開展在線教育業務,讓我們首先聚焦在客戶的模型設計部分,你可以聊聊你的想法啊。

小李:王老師,客戶建模是什麼?這個問題不是很簡單麼,我們只需要一個C端的app,有一套賬號中心,客戶完成常規註冊後,在銷售的引導下下單不就可以了麼?

老王:這個工作會比你預想的複雜很多,客戶模型的設計,對整個業務的開展,和系統的建設,都有全面的影響。慢慢我會引導你理解。不過你可以先基於你剛剛的說法,嘗試用我教你的ER圖,畫一個草圖出來,我們在此基礎上一步步展開分析。

小李:好啊王老師,我認爲我們面對的是典型的C端客戶,只需要一個賬號對象,每個賬號下可以創建多個訂單,ER圖如下:

老王:很好,賬號和訂單是很常見的兩個實體。那麼,客戶註冊後,會由電銷銷售人員跟進服務,我們需要設計CRM系統給銷售人員使用。你認爲銷售人員在CRM中操作管理的客戶對象應該是什麼,是賬號麼?

小李:我覺得銷售人員在CRM中管理操作的對象是“賬號”好像沒什麼問題,但又感覺怪怪的,感覺銷售人員跟進的應該是客戶,而不是賬號,但我說不清楚這裏邊的關係和定義。

老王:你的感覺是正確的,銷售人員在CRM系統中管理的應該是客戶,而不應該是客戶的賬號。實際在銷售管理中,我們認爲新註冊的客戶、賬號等等,都屬於銷售線索,線索就是指潛在客戶。在典型的CRM系統中除了線索,還有商機的概念,不過在我們這裏用不到。

小李:好像這樣清晰一些了,感覺CRM系統和客戶的登錄賬號就沒有明顯關係嘛。

老王:也不能說沒有關係,只是我們在做數據建模的時候,要分清楚這些對象的概念,保證邏輯定義的清晰。在我們的業務中,可以設計線索和賬號就是一對一關係,銷售人員和線索是一對多關係,即一個銷售可以擁有多條線索,每個線索只能屬於0個或1個銷售。

小李:爲什麼一個線索還可能屬於0個銷售呢,這是什麼意思呢?

老王:因爲在CRM系統中,並不是每條線索都有銷售管理跟進,有些線索可能是無人維護跟進狀態,所以線索和銷售是1對多,其中的“多”,是指“0或多個”。我們將ER圖完善,如下:

小李:這個圖看起來更清晰了,背後對應的設計思路也比較明確。不過我還是有點不理解,爲什麼非要把賬號和線索這兩個實體分開,除了邏輯上更清晰,還有什麼好處呢?

老王:對實體進行明確的建模和設計,除了邏輯上更清晰以外,還有很重要的一點,這樣做,可以降低軟件系統設計的耦合性。如何理解這句話呢?

ER模型最終會轉化成數據庫表結構設計,線索和賬號可以分別保存在兩張數據表,進一步講,隸屬於兩個不同的數據庫,即CRM系統的數據庫,和賬號中心的數據庫。我們來看下邊這張圖:

老王喝了口水,繼續說道:我在ER圖外邊繪製了兩個框,圓桶代表數據庫,圓桶外邊的矩形代表業務系統,可以看到,實際上我們在ER圖中描述的四個實體,分別隸屬於三個數據庫,和各自的業務系統。

這樣的ER圖設計,被清晰地傳導到數據庫底層設計,以及應用系統的設計,可以保證銷售系統、用戶中心、訂單中心三者很好地解耦合,各自獨立,互不影響。

例如:CRM系統如果更新時出了問題,並不會影響到用戶中心繫統,至少客戶還可以登錄訪問app。

而如果線索和賬號被設計成一個實體,對應的表結構設計可能就是一張表,就會導致多個應用系統使用同一個數據庫底層,可能造成CRM更新一個銷售拜訪的功能,出問題影響到C端用戶登錄app。

小李:明白了,聽起來很有道理,ER建模不僅在邏輯上很清晰,還能在物理存儲上也很清晰。怪不得我們以前公司創業時做的系統,總說耦合在一起,非常死板,倉庫系統做個升級,能把銷售系統幹趴下。

老王:很多時候系統耦合,都是創業公司爲了快速上線,做的設計方案的妥協,比如各個業務系統做成一套代碼,一套數據庫。當然,我在這裏舉這個例子,主要是想說明ER建模對數據庫表設計、對應用系統設計的傳導和影響。

小李:嗯嗯,這下對技術的理解又深刻一層。

老王:我們再回到建模設計本身。現在的模型,依然存在很多問題。比如說,在目前的模型中,如果小朋友的爸爸媽媽都註冊了賬號,該怎麼辦?

小李:聽起來沒啥問題啊,那就各自注冊唄?

老王:其實問題很嚴重,因爲爸爸媽媽各自注冊後,會產生兩條沒有關係的銷售線索,CRM系統一般情況下會分配給兩個銷售跟進。

但對於這個家庭來講,實際上只需要給孩子購買一次課程,那麼,兩名銷售爲了各自搞定家長獲得提成,可能就會產生惡意競爭,給客戶做出虛假的承諾,甚至給爸爸媽媽表述不一致,造成極差的客戶體驗。

而且如果成單(客戶付費),很難說清楚到底是哪個銷售的功勞更大,這就會造成銷售人員之間天天打架扯皮,非常不利於業務開展。

小李:有道理,那如果爸爸註冊了,媽媽再註冊,讓媽媽的線索分配給之前跟進爸爸線索的銷售,不就可以了麼?

老王:說的沒錯,問題是,我們並不知道爸爸和媽媽是否是一家人啊?我們的模型設計,並沒有預留這樣的能力支撐。你想想該怎麼修改呢?

小李(沉思中):有了,我們可以將以前的單一賬號體系,改成子母賬號體系,賬號可以彼此建立歸屬關係,這樣如果爸爸和媽媽綁定彼此賬號,銷售人員就能夠識別同一家庭的家長,就不會有衝突了。如下圖:

老王:很好,你的這個模型,在數據底層提供了能力支持,是我們在應用層面解決銷售衝突業務問題的一個前提基礎。

小李:不過我還是沒想明白,這個底層模型如何支持業務,因爲一般C端用戶並沒有動力在註冊時做家庭賬號關聯啊?

老王:你說的很對,一般C端用戶並不會主動去做賬號關聯,但是如果我們有這個數據底層設計的支持,就可以在應用系統層面做各種功能,來解決業務問題,同時還要結合業務制度。

比如:銷售部門可以明確做出規定,所有銷售在第一次跟進新線索時,必須先確定該賬號不是同一家庭賬號,或者不是已註冊家長的其他手機號。

如果發現是,則在CRM系統中提供功能,做賬號合併,將兩個或多個賬號關聯起來,這樣和賬號一一對應的線索,也就能梳理出關聯關係了,讓多個相關的線索被調配給同一名銷售。同時也可以在C端提供功能,引導家長完成家庭多手機號的綁定。

正因爲我們在數據建模時考慮到了這個問題,做好了數據底層設計的準備工作,未來才能在應用功能層面實現這些功能點,解決業務問題。

小李:明白了,真是神奇!如果銷售部門已經明文規定了要確認是否重複賬號,而銷售人員依然不遵守規定,那麼即便第二個銷售跟進開發成功,佣金依然判定屬於第一名銷售,只要規則明確,大家就必須遵守,糾紛就容易解決了。

老王:你說的很對!不過你的子母賬號的設計,可能會造成一種管理和被管理的感覺,在C端的體驗並不是特別好,是否有其他方案呢?

小李(撓撓頭):想不出來啊!

老王:其實我們的業務、面臨的客戶結構,就是典型的家庭結構。在數據底層,可以按照家庭的模型來建模,在賬號之上設計一個家庭實體,賬號都在同一個層級,隸屬於某一個家庭,這樣也可以完成賬號關係的綁定和關聯。如下圖:

小李:精彩!家庭和賬號是一對多,線索和賬號一對一,這樣就能在數據底層,保證可以對多線索進行唯一性識別!

老王:是的,實際上,賬號本身和線索、家庭關聯,也並不是很合理。賬號只代表一個用戶訪問系統的憑證,並不代表用戶自身。

在現實中,一個用戶完全可能有多個手機號,對於企業來講,理想的情況,是能夠識別唯一的客戶,以及他背後的多個手機號。所以,從建模的嚴謹性來講,我們還需要抽象出一個實體,就是家長。修改後的ER圖如下:

小李:我不太理解,這樣做的目的是什麼呢?你在圖中,也沒有將家長和賬號設計成一對多啊?

老王:家長和賬號設計成一對多,會一定程度增加系統的複雜性,也會讓用戶的操作體驗變複雜。

實際上,目前大多數互聯網跟公司的業務中,客戶和賬號設計成一對多,對業務價值並不是特別大,所以爲了簡化,都採用了一對一的設計方案,但是某些業務,就必須採用一對多設計了。

比如支付寶,通過身份證來識別唯一客戶,同時允許一個客戶註冊多個賬號(其實支付寶這樣做也是歷史原因導致的)。

但是,即便是家長和賬號一對一,爲了保證邏輯的清晰,我們也需要將兩個實體(家長和賬號)分離開,畢竟,賬號只是是登陸憑證,他不代表用戶自身。

我們可以在應用層面將複雜的系統邏輯簡化呈現,但是如果可能,就儘量在數據底層保持邏輯的嚴謹性,雖然會帶來底層設計的複雜度,但這可以保證系統在應用層面設計的靈活性。

小李:很有道理,受教了!

老王:這個模型中,還有致命問題,會影響到業務。

小李:啊?還有啊?我以爲已經很完美了!

老王:目前訂單是關聯在賬號下的。如果一個家庭有一個小朋友,這樣的模型是沒問題的,如果一個家庭有多個小朋友,該怎麼辦?實際上目前的模型不支持這個業務場景。

小李:是啊,這個問題的核心,是我們的模型中沒有小朋友的實體!

老王:進步很快啊,那你思考下這個模型該如何完善?

小李:我想想,是不是可以這樣,在家庭下增加一個孩子實體,訂單掛在孩子實體上,系統默認創建一個孩子,購買的訂單就掛在第一名孩子身上。如果家裏有多個孩子,那麼也支持家長增加孩子,並且可以針對其他孩子購買訂單。ER圖修改如下:

老王:非常棒,你的這個模型,很好地解決了先前的業務問題!

小李:不過我還是有困惑,這樣做,會不會太複雜了?其實如果有多個小孩,那麼讓客戶再註冊個賬號,不要合併家庭,創建訂單支付,不就解決了麼?

老王:你說的很對,確實有變通的處理方案,但會損失客戶體驗,並帶來其他的業務問題。

實際上,我們做產品設計,重要的是能夠想清楚所有的業務場景和問題,然後基於研發資源和實現週期,做出一個綜合評估後的合理方案,這是一個首先做加法,再做減法的過程。

尤其是在ER建模的過程中,必須思考的非常縝密,全面,因爲你會發現,ER建模的過程,就是幫你梳理業務的過程。

確實,如果底層模型設計過於複雜,可能會造成研發工作量指數級的上升,但更重要的是,你能考慮清楚所有業務場景,評估不同設計的投入產出比,和業務人員、技術負責人一起充分溝通,最終做出一個充分評估論證的設計方案。

小李:明白了,前輩所言極是!

老王:我們回到剛剛提到的多孩場景,實際上,你在上圖繪製的ER模型,已經能夠非常靈活的支持各種業務訴求。

比如說,如果一個家庭下,有兩個小朋友都購買了課程,並在某一天同時上課,而此時孩子的爸爸媽媽分別在外地,想各自分別去看兩個寶貝上課的情況(在線教育常見的監課功能),正因爲有這個模型的支持,才能在C端的app做出強大的功能,父母各自登陸,查詢到家庭下的兩個孩子,並且分別切換看兩個孩子上課的情況。

小李:明白,確實,如果沒有這個模型,而讓家長再註冊個賬號,在銷售管理上也會帶來混亂。

老王:是的。所以,這些問題,我們都要想清楚。另外有一點需要十分關注,ER建模最終會轉換成數據庫表設計,在軟件工程中,一旦表結構定型,以後再想修改,是非常麻煩的事情。

比如,如果我們一上來就按照最簡單的方案設計了客戶模型,那麼未來有一天,想切換到上述理想模型,研發的投入上會非常巨大,甚至是無法完成的。

軟件系統重構,最頭疼的問題就是如何將歷史數據遷移到新的數據結構下邊。

小李:理解,所以,ER建模,是一個非常核心的設計工作,必須充分探討,務必謹慎!

老王:沒錯。接下來,我再問你個問題,剛剛繪製的ER模型,還是有瑕疵。

小李:我暈,還有啥問題啊?

老王:如果孩子也有賬號,也需要用自己的手機號登陸系統,你的模型該怎麼調整?

小李:啊,真是,我還以爲我們做的是幼兒教育,小朋友都得用爸爸媽媽的賬號登陸app完成學習。不過確實有這種可能性,如果我們的教育產品拓展到小學或初中,現在的小朋友都是有手機的。我想想,要不然,改這樣?

老王:你這麼設計是沒有問題,但你不覺得抽象的實體有些冗餘麼,孩子和家長,實際上都是“人”嘛,無非是不同年齡的“人”。

小李:我想想,呃,要不改成這樣?最終家長和孩子這兩個實體,被進一步抽象到“人”的維度,通過“人”的某個屬性來標記是家長還是孩子(甚至都不需要標記,只需要通過年齡進行識別,併產生相關的業務規則)。

不過,這樣設計及好麼,會不會在邏輯上看起來清晰乾淨,但是會讓工程實現變得複雜?嗯,這個事兒,還得找技術負責人老李好好再合計合計。

老王:對,一定要和技術負責人一起溝通探討,而且想的越複雜越好!不過,我還有問題要問你。

小李:您請講!

老王:在最後的這個模型中,訂單究竟應該掛在“人”上,還是掛在“賬號”上呢?如果人和賬號是一對多關係,訂單又該怎麼掛呢?家長購買課程產生的積分應該掛在“人”上呢,還是賬號上呢,還是“家庭”上呢?學生上課獲得的獎勵應該掛在“人”上呢,還是賬號上呢,還是“家庭”上呢?

小李:媽呀,怎麼感覺無窮無盡的複雜啊,我想,這些問題,就留給我們聰明的讀者來思考吧!哈哈!

老王:我看行!

#專欄作家#

楊堃,公衆號:PM楊堃(ID:pmYangKun)。人人都是產品經理專欄作家,《決勝B端》作者,12年互聯網研發、產品設計經驗,曾任VIPKID產品總監,百度高級產品經理,現爲慢酷諮詢創始人兼CEO。

本文原創發佈於人人都是產品經理,未經許可,禁止轉載

題圖來自 Unsplash,基於 CC0 協議

相關文章