数据模型设计(下)- 设计步骤与进阶

本课程为数据模型设计的下半部分内容,涵盖了课程大纲中的:1. 设计数据模型(步骤);2. Zion数据模型的制作;3. 数据模型常用场景的应用;4.拓展练习 课程大纲中的内容可以查看《数据模型设计(上)- 基础回顾》

设计步骤

1. 识别对象

在开始设计数据模型之前,我们应该已经梳理出了业务需求清单和最终应用程序展现的高保真或低保真图。
这节课我们还是以电商类模板这个小程序为例,假设已经完成了业务需求清单的梳理,并有了相应的页面设计。
当然很多实际情况下,我们需要用概念数据模型或草图来进一步和业务需求方明确产品的功能和需求,进而再完善,会是一个同步进行工作状态。 
以电商案例首页为例的业务需求清单
高保真图(举例)
  • 根据业务需求抽取出需要进行信息分析的对象。
  • 先将最主要的对象罗列出来,接着可以通过用户在使用应用程序时操作流程的视角来识别出其他实体抽象的对象。这个思考方式是完善数据模型时最主要的技巧!
在电商类模板里,我们首先可以找出“用户”和“商品”两个实体对象,然后用户是如何在小程序上“购买”商品的呢?他通过将商品添加到自己的“购物车”来选购商品,将确定购买的商品通过“购买商品”生成“订单”。用户还能够保存多个地址,下单时选择收货“地址”。每件商品还有自己的“媒体库”用来展示它的图片信息,另外商品做了“分类”,分类在小程序可能会有多个“横幅”的展示。
我们不要求在这一步就把所有可能涉及到的对象全部找出来,数据模型的设计是一个不断修改优化的过程,需要与设计稿相结合,有时候可能页面设计上的需求导致了我们数据模型的修改。

2. 确定关键属性

在找出了对象后,我们先快速的为他们确定一些关键属性。这一步对于对象简单的项目有时会忽略,在完善属性的时候一并完成。
相对的,我们应该思考数据模型中的这些对象如何命名更容易区分出他们。

数据表命名原则
一、满足数据库的必要条件:Zion的数据表命名有一些必须满足的规则
  • 必须以小写字母开头
  • 不能用大写字母、空格;以及数据库相关的关键字:“like”、“index”、“fz”开头的字母
  • 可以用数字
  • 单词之间用“_”隔开
  • 同一个数据模型下名字唯一
二、见名知意:看到名字就能理解其含义,做到与别的数据表做区分
三、用名词单词:虽然数据表包含了多条数据时是一个集合,但是其本质是描述了数据的结构,因此我们用单数,同样的道理我们通常不会为数据表名称加“list”
字段命名原则: 与数据表的命名相同,除了以下几点
  1. 在Zion中,字段可以用中文、用中文开头;虽然我们仍然建议用英文来命名
  2. 同一个数据表下名字唯一

我们可以尝试为步骤1中找出的对象确定几个立马能想到的关键属性
  • 用户:用户名
  • 商品:商品名称、价格
  • 购物车:商品、数量
  • 购买商品:商品、数量
  • 订单:用户、购买商品、总价
  • 地址:用户、地址
  • 媒体库:商品、图片
  • 分类:分类名、层级
  • 横幅:分类、封面
这一阶段罗列的属性不需要是准确的,它的类别也不重要
重要的是通过罗列这些对象的关键属性为我们更清晰的明白他们之间可能存在的关系,以及如何更合适的设计

3. 画草图

我们可以通过绘制UML图来建立一个对象关系草图来表示他们之间数据传递的方式。同时可以将上一步罗列的关键属性加入到对象当中。
当然你也在纸上完成最终逻辑数据模型的,完全可以按照习惯的方式来。

如何绘制UML图:

使用UML(Unified Modeling Language)来绘制数据模型并不是必须的
然而依托于飞书强大的协同办公能力,以及在文档中添加/编辑UML图,目前我们通常会用飞书的UML图绘制工具制作数据模型。
我们建议在绘制草图的时候就开始使用UML工具来制作,主要有两个原因:
  • 通过接下来的设计步骤最终它会形成一个可以应用在Zion上的逻辑数据模型;
  • 我们可以将绘制的数据模型方便地同步给项目各方。
当然你也完全可以用纸和笔来先完成一个草图的设计,甚至最终的逻辑数据模型。
在飞书中新建一个文档,或者在已有的项目相关文档中插入UML图
在左侧UML下找到“类 2”,拖动到画布中用来添加数据模型的对象,也就是数据表
表头“Classname”对应的是“数据表名称”,“field”对应的是“字段名”,“type”对应的是“字段类型”
以对象“用户”举例,我们可以将数据表名称修改为“account (用户)”。 可以在名称后面加中文备注
我们通常会将数据表的第一个字段改为“id”,其类型是“bigserial”(自增长的大整数) . 将“field”改为之前找到的关键属性“username(用户名)”,类型现在可以先留空。可以在字段后加中文备注
再继续完成剩余对象数据表的添加
思考:“order”中的字段正确吗?
接着我们来为对象建立相互之间的关系,通过之前确定对象的关键属性我们已经可以发现,一些数据表引用了其他数据表的信息,这时候我们需要思考两个问题:
1. 他们之间是什么类型的关系?是1:1还是1:N,还是M:N?
2. 哪个对象是被引用方,哪个对象是引用方?
我们来看一下“地址”和“用户”两个对象之间的关系,地址引用了用户,并且一个用户可以有多个地址,所以是“用户”对“地址”建立1:N关系。
点击被引用对象的“id”字段。点击并拖动字段旁出现的蓝色箭头图标,将其拖动到引用对象的关系字段(account)上。然后可以通过点击表头位置选中数据表后来拖动调整他们的布局。
我们可以通过点击关系线,然后拖动关系线上的蓝色航点来改变它的走线。双击关系线上的非航点位置,为其添加关系类型的描述,这里修改为“1:N”,然后在右侧编辑窗口打开它的背景色,这样就不会被关系线遮挡了。
至此你已经学会了在UML工具上绘制数据模型所需的所有基本技能了。
接下来我们来完善其他对象之间的关系,在这一步骤我们不必担心会有没有考虑到的关系。完善对象的属性之后会更清晰的发现他们之间的关系,更重要的是结合功能需求设计字段的类型。
上方的UML图中有错误,可以暂停思考一下
“订单”和“购买商品”之间是什么关系?谁是被引用方?

4. 找出数据属性

为各个对象添加所需的属性,完善数据表的字段。我们同样可以利用用户操作流程的角度结合设计原则2来思考
找出现有对象外其他业务需要添加的数据。思考这个问题可以发现在步骤1中遗漏的对象。
该步骤的判断流程可以参考设计原则7的流程图
回到电商案例中的几个例子:
  • 用户有必要知道订单的状态,因此需要添加“订单状态”字段。
  • 用户虽然只看到上线的商品,但是管理者需要对商品的状态进行记录,并且可以在修改商品状态后及时的反馈给用户,因此需要添加“状态”字段
  • 我们可以添加店铺或者商家的数据信息,但是该案例中我们没有多店铺/商家管理的需求,管理者也不需要用户看到这些信息。虽然这些信息管理者会记录,但是对该案例而言没有必要记录在项目数据模型中,因此我们不添加任何商家或店铺的数据字段和数据表

5. 分配属性

将上一步骤中的数据分配到对象中并且添加字段的类型以说明数据的业务含义。
这意味着我们可以通过数据表中添加的字段,反向来检查是否符合业务的需求,以及应用程序功能的满足情况。 另外,数据表的关系字段是否正确的添加在了引用方的数据表中?新属性的添加之后通常会使我们更清晰的明白数据表之间的正确关系
关系字段的命名规则
通常情况下我们在引用方中添加的关系字段用被引用方的数据表名称表示。 而且对于1:N关系往往会采用名词复数的形式。
他是字段名称来表示是否是关系字段的提示,同时也代表了这个字段可以重复出现某一个数据。
当然也有很多时候我们会自定应关系字段名称来更好的表达他对应的含义,比如“分类”的自关联“父级分类”字段。
然后关系字段的类型填写被引用的数据表名称。 比如: “媒体库”中引用商品的关系字段更合适的字段名是“products(商品):product”
在此基础上完善UML图的制作

6. 校验完善

最终确定数据模型并验证其准确性。
这里的验证不仅仅是作为数据模型的制作方自己,还需要通过制作的逻辑数据模型和业务需求方确定页面设计与功能的实施是否能实现,有没有可以优化或调整的内容。
另外不要忘记数据模型是一个不断修改优化的过程,通过制作数据模型往往可以得到对业务逻辑更深入的理解。 通过以上步骤我们会得到一个理想的逻辑数据模型,接下来可以在Zion实现项目物理数据模型的制作。 值得一提的是,以上的设计步骤并不一定是线性的,实际上很多时候我们会交替进行,反复优化得到最终的数据模型。这些过程在放到具体的数据库工具之前,也就是物理数据模型制作之前都是合理且必要的。 而一旦在Zion上制作完数据模型并且将数据进行绑定和上线之后,修改数据模型将会带来很多不必要的麻烦。

在Zion上制作数据模型

这一部分课程会通过在Zion上演示制作我们已经完成的逻辑数据模型UML图

数据模型常用场景的应用

1. 中间表

某个对象从一堆东西中选择了一部分”:典型的运用M:N关系的场景
比如在电商这个案例中,“用户”通过“订单”从一堆“商品”中选了一部分商品,这就是“订单”和“商品”的M:N关系
在这个场景下我们在Zion通过“中间表”,这里是“购买商品”,来实现:让“订单”和“商品”共同对“购买商品”建立1:N关系。“购买商品”表中会记录“某个订单从一堆商品中选择了一部分”。
“订单”和“商品”的M:N关系
其他类似的常用场景有:
  1. 活动报名
  2. 图书收藏
  3. 视频点赞
  4. 内容标签

2. 双关联表

被引用的对象向引用方建立2个关系字段的架构,典型的运用场景是聊天数据模型被引用对象为用户,引用方是聊天消息。
聊天消息数据表中引用两次用户表的id,分别用来表示发送消息的用户和接收消息的用户
“sender_id”是发送消息的用户,“receiver_id”是接受消息的用户

3. 自关联表

自关联指数据表自己对自己建立了一对多关系,通常运用在带有层级结构的信息中 在电商案例中,“分类”就是一个自关联表,通过“父级分类”来确定自己的上级分类是什么。
并且通过这一个关联字段就可以添加更多的层级。
除了分类,其他的常用场景有:
  1. 公司员工层级
  2. 游戏任务线
  3. 内容下一页

拓展练习

设计一个医院为用户用来到访医院看病小程序的概念数据模型 功能需求:
  1. 该医院未来可能有多家门店,用户可以在小程序上选择去哪家医院就诊
  2. 用户有自己的病例,里面包含了过往的诊断结果
  3. 用户可以通过小程序挂号,选择符合自己情况的科室和医生
  4. 挂号付费后可以进行对应的门诊,医生会给出诊断结果,并给出处方
  5. 用户通过处方付款后可以得到相应的医疗服务(为了方便这里不必要将他们区分为体检、药品、手术等,统一为医疗服务)
  6. 医疗服务时间可以预约,门诊时间也可以预约。但是用户在没有得到对应处方(医生建议)的情况下不能预约医疗服务
你的第一步可能是这样的
参考答案,如何在此基础上完善成一个逻辑数据模型?
当然数据模型不存在绝对的对错,不同人有不一样的方式处理,但是要做到逻辑自洽

课后测试题

共23道题,满分100分
如果觉得本教程有帮助不要忘记给文档点赞,或参与我们的社区讨论!
2022-08-08
3 1