数据库应用系统的设计包括 数据库设计实例—学习数据库最重要的应用之一

1. 引言[可以忽略]

当我学习“数据库系统概述”这门课程的时候,我总是很好奇这门必修课到底教了我什么。

由于课后没有开拓视野,课堂上局限于老师的教学水平,一直没能领悟这门课的意义。

我学到了什么?老实说,有很多新术语:

例如范式、事务、代码、集合操作等等。

但在实际应用中我发现,课堂上教授的SQL语句中,真正用到的只有自己已经学过的SQL语句。

即增加、删除、修改和查询,SELECT、DELETE、UPDATE、INSERT四种语句。

后来当我根据需求文档开始开发项目的时候,我也迷茫了,由于队友已经提前建好了数据库,所以我并没有学到建立数据库的知识。

也是在某一次的场合,面试的时候,面试官问到:你是如何设计这个数据库的?

于是我就回去努力学习,花了半个星期的时间终于把学到的知识串联起来了。

数据库设计:它是比使用SQL语句更重要的知识,因为使用SQL语句的基础是要有一个数据库和一些表。

2. 数据库建立的六个步骤及总体对应目标

就像解决数学问题一样,建立数据库的过程如下:

第一步是需求分析

这一步从实际出发,产品就是需求文档[专业术语是“用户需求规范”]。

关键是要了解用户的数据需求和数据处理需求。【简单来说,你想存储什么数据(比如学生班级),你想用这些数据做什么?(比如增删改查)】

在更加实际的开发中我们可能会涉及到性能需求、安全需求等,这里就不再赘述。

第二步:概念结构设计

这个术语比较难理解,我觉得可以叫它“模型设计”。

因为这一步的目标是设计一个“模型”,什么样的模型?

ER实体关系模型。

该模型定义了数据库中包含的实体、实体的属性以及实体之间的关系,对于一些特殊的实体,可能会在关系上添加特殊的约束。

第三步,逻辑结构设计

这个术语不太好理解,你可以认为这里的“逻辑”是指从实体模型到关系模型的转变,是层次上的抽象,所以叫“逻辑”设计。

这一步的目的是得到一个可以作为数据库使用的关系模型。[关系模型的含义后面会讲到]

我们得到了ER模型之后,根据一些转换原则就可以很容易的得到关系模型,但是并不是所有的关系模型都可以作为数据库使用。

必须遵循至少三个步骤的范式来设计一个不容易出现问题并且更容易处理异常的关系模型。

步骤4:物理结构设计

这一步不是我们考虑的,更多的是操作系统开发人员和数据库开发人员的考虑。

步骤5:数据库部署和测试

没什么好说的。

第六步:数据库运维

没有任何。

我们可以发现,数据库开发从0到1的重点都在前三个步骤上,下面我会用一个例子来说明如何进行。

3.客户需求【从0开始,可以忽略此节直接跳到最后】

小明是一名游戏开发者,他一直在苦苦思索如何在自己的游戏中添加应用内购买功能。

有一天,他发现某个外卖平台的订单结构很好,但是他不熟悉如何设计,就付钱给你帮忙开发。

你询问需求。

小明说:“我们的每一个客户都是独一无二的,有自己的游戏ID、游戏名、密码、手机号、邮箱等。”

他补充道:“某个群体的结构也是这样的,所以我们应该能够互相转化。”

好的,我们有了第一个实体,它是一张客户表。

你繼續問。

小明说:“内购模式最大的问题就是如何处理订单,因为游戏里的装备非常多,如果玩家A一次性购买20个超级戒指和20瓶恢复药水。”

他顿了顿,又说道:“数据库我也学过一点,上面的需求,如果放在一张表里,要么用一个集合来存装备信息,要么四十条信息放在一张表里,但是玩家ID是主键,不可能有四十个一模一样的ID放在一张表里,而且这样会有很多冗余信息,查找起来也比较困难。”

“所以,我想要一个与用户相关的单独订单。”

好的,我们有第二个实体,这是一个订单表,也许它与客户表有关系,但这并不重要,我们暂时不关心。

游戏里有戒指、恢复药水等,未来可能会有更多装备,如果把所有装备都定义在订单表中,用另外一列来管理它们的购买数量。[类似HashMap的key和value概念]

这是可行的,但是相当多余。

你繼續問。

“不再。”

由此,你大概就能知道自己需要什么了。

——从这里开始阅读。

我们的问题是如何连接用户、订单和设备。

考虑一下这个场景:玩家 A 购买了 3 枚戒指、4 瓶药水和 100 卷轴。你如何存储它们?

首先,一个用户表是必须的,至少要存储用户的信息。

第二,看似需要订单,但是订单的内容可能需要好好考虑一下。

4.需求分析[实分析]

基于上述场景,我们分析了各个实体的数据需求和数据处理要求。

用户表基本没问题,没必要为了一张订单表去改整个用户表。

玩家A可能昨天购买了1个订单,今天购买了3个订单,A和订单之间显然是一对多的关系。

一个玩家可以有 n 个订单。一个订单只能属于一个玩家。

订单和设备怎么样?

使用装备表来存储装备是一个好主意,但是一个订单可能有 n 件装备。为什么不直接使用订单表来存储所有装备呢?

问题是:这样扩充设备很麻烦。

当我们对此类问题犹豫不决时,请记住两个原则:

1.订单中涉及的设备明显是变量,将变量作为表的属性是非常危险的。

2.从关系角度考虑。

也许我们可以用一些东西来代表订单所涉及的设备。

订单和设备显然是多对多的关系,一个订单可能有n种设备,一种设备也可能属于m个订单。

因此,它必须是独立的。

一、用户表

数据要求:用户 ID、用户名、密码、电子邮件、电话号码。[可能是订单信息?或者一些描述?随便什么都可以]

数据操作需求:注册(添加)、修改密码(修改)、登录时查看表格(搜索)、用户退出(可能不实际删除,但至少注明并提供接口)

二、订货单

数据要求:可能包括订单号ID、订单名称、订单描述、订单价格。

数据操作需求:增加、删除、修改、查询。

三、设备清单

数据要求:设备ID、设备名称、设备描述、设备价格?[我不确定]

数据操作需求:增加、删除、修改、查询。

5.概念结构设计

根据以上需求文档,绘制ER实体关系模型。

这一步主要体现实体并不是孤立存在的,而是相互联系的。

这一步有3个知识点:

1. 绘制与表格数量相同的实体。

2.实体内的属性根据数据需求画出来,如果有增加可以临时添加。【当然多人开发需要协商】

3. 绘制实体之间的连接。(即 1 到 n,n 到 m)

ER图如下:

怀疑:

有同学可能会说:奇怪,需求文档里没有写用户和设备之间的联系?你在开玩笑吧?

确实,我第一次分析的时候是没有的,也是刚刚才发现的。

6.逻辑结构设计

将ER图转换成关系模型,其实就是将实体转换成表,只需要遵循三个原则即可。

[注:这适用于只有二元关系的 ER 图。3 元素模型差别不大,但尽量将 3 元素模型转换为 2 元素模型,否则不太好用。]

首先,对于1对1的关系,比如A:B=1:1,可以将另外一个表的主键作为外键添加到一个表中。【例如在A表中添加B的主键BID,此时A表中的BID就是A表的外键。】

二、对于1对n的关系,比如A:B=1:n,将1端表的主键添加到n端表中,使主键成为外键。【即在B表中,添加A表的主键AID,则B表的外键为AID】

第三,对于n和m的关系,比如A:B=n:m,应该把这个关系抽出来,做成一张新表X数据库应用系统的设计包括,使得X有表A和B的主键,并且有主外键的要求。X的外键是AID或者BID,X的主键是AID和BID。

那么,这个问题就转化成了:

用户表(ID,用户名,密码,电话号码,电子邮件地址)

订单表(ID,订单名称,价格,描述,用户ID)

设备表(设备ID,设备名称,描述,价格)

用户设备联系表(用户ID,设备ID,其他描述)

订购设备联系表(订单ID、设备ID、其他说明)

有时候,灵感可能会突然来袭:用户A可能有100个设备aa数据库应用系统的设计包括,所以用户-设备联系人表里肯定有100条重复的记录!这不符合主键啊!

因此在用户设备联系表中增加属性“设备数量”。

同样,在订购设备联系表中添加“设备数量”。

至此,初步的表格设计已经完成。

第一范式的规范化

1NF要求:在业务层面,所有列必须不可分割。

显然很满意。

第二范式

2NF 要求所有列都直接或间接依赖于主键。

显然很满意。

第三范式

3NF要求所有列都直接依赖于主键;并且列之间不存在依赖关系。

虽然这么说不太好,但是确实很让人满足。

因此,数据库设计已完成,我们有一个可以运行的数据库!

我是一名蚊子程序员,如果大家有什么补充或者疑问,欢迎在评论区留言,我个人的知识体系可能不是那么完善,希望大家指正,谢谢。

© 版权声明
THE END
喜欢就支持一下吧
点赞200赞赏 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容