為什么ER建模是軟件產品設計的核心:通過一個案例讓你深刻理解
編輯導語: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建模對數據庫表設計、對應用系統設計的傳導和影響。
小李:嗯嗯,這下對技術的理解又深刻一層。
老王:我們再回到建模設計本身?,F在的模型,依然存在很多問題。比如說,在目前的模型中,如果小朋友的爸爸媽媽都注冊了賬號,該怎么辦?
小李:聽起來沒啥問題啊,那就各自注冊唄?
老王:其實問題很嚴重,因為爸爸媽媽各自注冊后,會產生兩條沒有關系的銷售線索,CRM系統一般情況下會分配給兩個銷售跟進。
但對于這個家庭來講,實際上只需要給孩子購買一次課程,那么,兩名銷售為了各自搞定家長獲得提成,可能就會產生惡意競爭,給客戶做出虛假的承諾,甚至給爸爸媽媽表述不一致,造成極差的客戶體驗。
而且如果成單(客戶付費),很難說清楚到底是哪個銷售的功勞更大,這就會造成銷售人員之間天天打架扯皮,非常不利于業務開展。
小李:有道理,那如果爸爸注冊了,媽媽再注冊,讓媽媽的線索分配給之前跟進爸爸線索的銷售,不就可以了么?
老王:說的沒錯,問題是,我們并不知道爸爸和媽媽是否是一家人???我們的模型設計,并沒有預留這樣的能力支撐。你想想該怎么修改呢?
小李(沉思中):有了,我們可以將以前的單一賬號體系,改成子母賬號體系,賬號可以彼此建立歸屬關系,這樣如果爸爸和媽媽綁定彼此賬號,銷售人員就能夠識別同一家庭的家長,就不會有沖突了。如下圖:
老王:很好,你的這個模型,在數據底層提供了能力支持,是我們在應用層面解決銷售沖突業務問題的一個前提基礎。
小李:不過我還是沒想明白,這個底層模型如何支持業務,因為一般C端用戶并沒有動力在注冊時做家庭賬號關聯???
老王:你說的很對,一般C端用戶并不會主動去做賬號關聯,但是如果我們有這個數據底層設計的支持,就可以在應用系統層面做各種功能,來解決業務問題,同時還要結合業務制度。
比如:銷售部門可以明確做出規定,所有銷售在第一次跟進新線索時,必須先確定該賬號不是同一家庭賬號,或者不是已注冊家長的其他手機號。
如果發現是,則在CRM系統中提供功能,做賬號合并,將兩個或多個賬號關聯起來,這樣和賬號一一對應的線索,也就能梳理出關聯關系了,讓多個相關的線索被調配給同一名銷售。同時也可以在C端提供功能,引導家長完成家庭多手機號的綁定。
正因為我們在數據建模時考慮到了這個問題,做好了數據底層設計的準備工作,未來才能在應用功能層面實現這些功能點,解決業務問題。
小李:明白了,真是神奇!如果銷售部門已經明文規定了要確認是否重復賬號,而銷售人員依然不遵守規定,那么即便第二個銷售跟進開發成功,傭金依然判定屬于第一名銷售,只要規則明確,大家就必須遵守,糾紛就容易解決了。
老王:你說的很對!不過你的子母賬號的設計,可能會造成一種管理和被管理的感覺,在C端的體驗并不是特別好,是否有其他方案呢?
小李(撓撓頭):想不出來??!
老王:其實我們的業務、面臨的客戶結構,就是典型的家庭結構。在數據底層,可以按照家庭的模型來建模,在賬號之上設計一個家庭實體,賬號都在同一個層級,隸屬于某一個家庭,這樣也可以完成賬號關系的綁定和關聯。如下圖:
小李:精彩!家庭和賬號是一對多,線索和賬號一對一,這樣就能在數據底層,保證可以對多線索進行唯一性識別!
老王:是的,實際上,賬號本身和線索、家庭關聯,也并不是很合理。賬號只代表一個用戶訪問系統的憑證,并不代表用戶自身。
在現實中,一個用戶完全可能有多個手機號,對于企業來講,理想的情況,是能夠識別唯一的客戶,以及他背后的多個手機號。所以,從建模的嚴謹性來講,我們還需要抽象出一個實體,就是家長。修改后的ER圖如下:
小李:我不太理解,這樣做的目的是什么呢?你在圖中,也沒有將家長和賬號設計成一對多啊?
老王:家長和賬號設計成一對多,會一定程度增加系統的復雜性,也會讓用戶的操作體驗變復雜。
實際上,目前大多數互聯網跟公司的業務中,客戶和賬號設計成一對多,對業務價值并不是特別大,所以為了簡化,都采用了一對一的設計方案,但是某些業務,就必須采用一對多設計了。
比如支付寶,通過身份證來識別唯一客戶,同時允許一個客戶注冊多個賬號(其實支付寶這樣做也是歷史原因導致的)。
但是,即便是家長和賬號一對一,為了保證邏輯的清晰,我們也需要將兩個實體(家長和賬號)分離開,畢竟,賬號只是是登陸憑證,他不代表用戶自身。
我們可以在應用層面將復雜的系統邏輯簡化呈現,但是如果可能,就盡量在數據底層保持邏輯的嚴謹性,雖然會帶來底層設計的復雜度,但這可以保證系統在應用層面設計的靈活性。
小李:很有道理,受教了!
老王:這個模型中,還有致命問題,會影響到業務。
小李:???還有啊?我以為已經很完美了!
老王:目前訂單是關聯在賬號下的。如果一個家庭有一個小朋友,這樣的模型是沒問題的,如果一個家庭有多個小朋友,該怎么辦?實際上目前的模型不支持這個業務場景。
小李:是啊,這個問題的核心,是我們的模型中沒有小朋友的實體!
老王:進步很快啊,那你思考下這個模型該如何完善?
小李:我想想,是不是可以這樣,在家庭下增加一個孩子實體,訂單掛在孩子實體上,系統默認創建一個孩子,購買的訂單就掛在第一名孩子身上。如果家里有多個孩子,那么也支持家長增加孩子,并且可以針對其他孩子購買訂單。ER圖修改如下:
老王:非常棒,你的這個模型,很好地解決了先前的業務問題!
小李:不過我還是有困惑,這樣做,會不會太復雜了?其實如果有多個小孩,那么讓客戶再注冊個賬號,不要合并家庭,創建訂單支付,不就解決了么?
老王:你說的很對,確實有變通的處理方案,但會損失客戶體驗,并帶來其他的業務問題。
實際上,我們做產品設計,重要的是能夠想清楚所有的業務場景和問題,然后基于研發資源和實現周期,做出一個綜合評估后的合理方案,這是一個首先做加法,再做減法的過程。
尤其是在ER建模的過程中,必須思考的非??b密,全面,因為你會發現,ER建模的過程,就是幫你梳理業務的過程。
確實,如果底層模型設計過于復雜,可能會造成研發工作量指數級的上升,但更重要的是,你能考慮清楚所有業務場景,評估不同設計的投入產出比,和業務人員、技術負責人一起充分溝通,最終做出一個充分評估論證的設計方案。
小李:明白了,前輩所言極是!
老王:我們回到剛剛提到的多孩場景,實際上,你在上圖繪制的ER模型,已經能夠非常靈活的支持各種業務訴求。
比如說,如果一個家庭下,有兩個小朋友都購買了課程,并在某一天同時上課,而此時孩子的爸爸媽媽分別在外地,想各自分別去看兩個寶貝上課的情況(在線教育常見的監課功能),正因為有這個模型的支持,才能在C端的app做出強大的功能,父母各自登陸,查詢到家庭下的兩個孩子,并且分別切換看兩個孩子上課的情況。
小李:明白,確實,如果沒有這個模型,而讓家長再注冊個賬號,在銷售管理上也會帶來混亂。
老王:是的。所以,這些問題,我們都要想清楚。另外有一點需要十分關注,ER建模最終會轉換成數據庫表設計,在軟件工程中,一旦表結構定型,以后再想修改,是非常麻煩的事情。
比如,如果我們一上來就按照最簡單的方案設計了客戶模型,那么未來有一天,想切換到上述理想模型,研發的投入上會非常巨大,甚至是無法完成的。
軟件系統重構,最頭疼的問題就是如何將歷史數據遷移到新的數據結構下邊。
小李:理解,所以,ER建模,是一個非常核心的設計工作,必須充分探討,務必謹慎!
老王:沒錯。接下來,我再問你個問題,剛剛繪制的ER模型,還是有瑕疵。
小李:我暈,還有啥問題???
老王:如果孩子也有賬號,也需要用自己的手機號登陸系統,你的模型該怎么調整?
小李:啊,真是,我還以為我們做的是幼兒教育,小朋友都得用爸爸媽媽的賬號登陸app完成學習。不過確實有這種可能性,如果我們的教育產品拓展到小學或初中,現在的小朋友都是有手機的。我想想,要不然,改這樣?
老王:你這么設計是沒有問題,但你不覺得抽象的實體有些冗余么,孩子和家長,實際上都是“人”嘛,無非是不同年齡的“人”。
小李:我想想,呃,要不改成這樣?最終家長和孩子這兩個實體,被進一步抽象到“人”的維度,通過“人”的某個屬性來標記是家長還是孩子(甚至都不需要標記,只需要通過年齡進行識別,并產生相關的業務規則)。
不過,這樣設計及好么,會不會在邏輯上看起來清晰干凈,但是會讓工程實現變得復雜?嗯,這個事兒,還得找技術負責人老李好好再合計合計。
老王:對,一定要和技術負責人一起溝通探討,而且想的越復雜越好!不過,我還有問題要問你。
小李:您請講!
老王:在最后的這個模型中,訂單究竟應該掛在“人”上,還是掛在“賬號”上呢?如果人和賬號是一對多關系,訂單又該怎么掛呢?家長購買課程產生的積分應該掛在“人”上呢,還是賬號上呢,還是“家庭”上呢?學生上課獲得的獎勵應該掛在“人”上呢,還是賬號上呢,還是“家庭”上呢?
小李:媽呀,怎么感覺無窮無盡的復雜啊,我想,這些問題,就留給我們聰明的讀者來思考吧!哈哈!
老王:我看行!
#專欄作家#
楊堃,公眾號:PM楊堃(ID:pmYangKun)。人人都是產品經理專欄作家,《決勝B端》作者,12年互聯網研發、產品設計經驗,曾任VIPKID產品總監,百度高級產品經理,現為慢酷咨詢創始人兼CEO。
本文原創發布于人人都是產品經理,未經許可,禁止轉載
題圖來自?Unsplash,基于 CC0 協議
談一下自己的看法哈:
1、雖然說學生家長都是人,但是對于業務而言這兩類人的業務完全不一樣。針對家長可能是促銷,針對學生可能是用來分析成績變化等,所以兩類表最好分開。
2、訂單歸在哪里,我的意見是找到最小顆粒度人。人可以是家長,學生,家庭,甚至后期會有親友團(多個家庭組成一個),但訂單本質是對于學生而言,且學生和家長、家庭的關系已經建立很清楚。后期即時業務變動,也只是多連一張表的問題
3、目前賬號一對多的現象,首先看是否需要解決,其實是解決方式是什么。在沒有發生業務的時候,比如用戶僅僅瀏覽時,可以用多個賬號登錄(微信、手機、qq等),但一旦要涉及到業務比如購買課程時,往往會要求綁定唯一標識(一般是手機)。即時當時沒有綁定,當你的第二個賬戶準備再次購買業務時,如果購買中必須要填寫一些基本信息(比如學生名字,家長手機號等),結合業務理解,可以考慮提醒合并賬號
4、至于學生獲獎掛在哪個賬戶上,獎項本身就是一個實體,可以多對多。同時掛在家長和學生賬戶上,完全沒有任何問題,且考慮家長和學生的心理,這樣的效果比較好
1.孩子從沒有賬號到有賬號過程
當孩子沒有賬號時,僅存在在“人”這個實體中,記錄孩子的基本信息,以及記錄學習行為。
當孩子長大有了手機,注冊賬號。再將人-賬號進行綁定,創建1對1關系。
當孩子沒有賬號時,使用父母的賬號登錄成功后,僅能選擇以學生身份進入,學生身份僅有學習一系列的權限。父母角色可以加設一道進入口令。
當孩子注冊綁定了自己的賬號,使用賬號登錄始終指向學生這個身份。
所以人-賬號存在1對多和,1對0關系。
2.訂單始終掛在人上
賬號僅相當登錄憑據,爸爸的手機1、手機2登錄都指向爸爸這個人。避免了手機1登錄看不到手機2的購買訂單;
另外當訂單應包括購買人(爸爸)與接收人(孩子),這樣可以避免一家多個孩子互相串課看
3.家長與購買人
家長角色包括所有孩子的督學權限,以滿足媽媽從來不買課,但是要監督每一個孩子學習;
購買人除了家長權限外,還包括對自己的訂單的操作權限,退款退單。
4購買課程產生的積分掛在家庭上,增加積分流動性,促進再次消費。
最后那個問題哪個大佬回答一下唄
我說怎么越看越眼熟,原來是堃哥寫的!
我覺得我應該會一直跟隨楊老師
這不應該是技術做的事情嗎?產品只要思考全這些場景給出功能不用管這么深的層次吧
B端產品不得不思考這些的,不然產品設計時候問題很多
從淺到深,真的詳細。持續關注中。
留名
大佬關于er建模這方面有什么好的學習途徑 有什么書籍推薦嗎?
決勝B端,哈哈
大佬 我來了