为什么ER建模是软件产品设计的核心:通过一个案例让你深刻理解

为什么ER建模是软件产品设计的核心:通过一个案例让你深刻理解

时间:2020-7-13 作者:抖音代运营

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。

本文原创发布于人人都是七十九度,未经许可,禁止转载

028-84360888 13608068886(推销勿扰) 发送短信