数据库设计
数据库中创建的数据结构的种类,以及在数据实现之间建立的复杂关系是决定数据库系统效率的重要因素。
糟糕的数据库设计表现在以下两个方面
- 效率低下
- 更新和检索数据时会出现许多问题
良好的数据库设计表现在以下几个方面
- 效率高
- 便于进一步扩展
- 可以使应用程序的开发变的更容易
设计数据库的步骤
收集信息
创建数据库之前,必须充分理解数据库需要完成的任务和功能
标识实体
在收集需求信息后,必须标识数据库要管理的关键对象或实体
注意:实体一般是名词,一个实体只描述一件事情,不能重复出现含义相同的实体
标识每个实体需要存储的详细信息
将数据库中的主要实体标识为表的候选实体以后,就要标识每个实体存储的详细信息,也称为该实体的属性,这些属性将组成表中的列。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uwikwTsp-1596073925777)(C:\Users\杰弟弟\AppData\Roaming\Typora\typora-user-images\1596011358683.png)]
标识实体之间的关系
关系型数据有一项非常强大的功能,即它能够关联数据库中各个项目的相关信息
概要设计——绘制 E-R 图
实体—关系模型
1.实体
- 所谓实体就是指现实世界中具有区分其他事物的特征或属性并与其他事物有联系的事物
2.属性
- 属性可以理解为实体的特征
3.联系
- 联系是两个或多个实体之间的关联关系
4.映射基数
映射基数表示通过联系与该实体关联的其他实体的个数。
- 一对一:X中的一个实体最多与Y中的一个实体关联,Y中的一个实体最多与X中的一个实体关联
- 一对多:X中的一个实体可以与Y中任意数量的实体关联,Y中的一个实体最多与X中的一个实体关联
- 多对一:X中的一个实体最多与Y中的一个实体关联,Y中的一个实体可以与X中的任意数量的实体关联
- 多对多:X中的一个实体可以与Y中的任意数量的实体关联,反之亦然
5.实体关系图
- 矩形表示实体集
- 椭圆形表示属性
- 菱形表示联系集
- 直线用来连接属性和实体集,也用来连接实体集和联系集
- 1:1——每个客户(Customer)最多有一个账户(Account),并且每个账户最多归一个客户所有
- 1:N——每个客户(Customer)可以有任意数量的账户(Account),但每个账户最多归一个客户所有
- M:N——每个客户(Customer)可以有任意数量的账户(Account),每个账户可以归任意数量的客户所有
关系数据库模式
将E-R图转换为关系模式的步骤如下:
1)把每个实体都转化为关系模式R(A,B)形式以酒店管理系统为例,实体“客人”和”房客“分别可以使用关系模式
- 客房(客房号,客房描述,客房类型,客房状态,床位数,入住人数,价格)。
- 客人(客人编号,客人姓名,身份证号,入住日期,结账日期,押金,总金额)。
2)建立实体间的联系的转换
实体间的联系分成一对一,一对多,多对多三种,当两个实体各自转化为关系模式后,实体间联系转换
- 一对一的转换:把任意实体的主键放到另一个实体的关系模式中
- 一对多的转换:把联系数量为1的实体的主键放到联系数量为N的实体关系模式中
- 多对多的转换:把两个实体中的主键和联系的属性放到另一个关系模式中,注意多生成一个关系模式
逻辑设计——绘制数据库模型图
绘制数据库模型图步骤
1.新建数据库模型图
- 选择 “文件” — “新建” — “数据库” — “数据库模型图” 命令,出现一个空白页面,可以看到绘制页面左侧是绘图模具其中包含很多实体关系图
2.添加实体
- 在绘图窗口左侧的实体关系中选择实体并将其拖动到页面的适当位置,在 “数据库属性” 中定义数据表的物理名称及概念名称
3.添加数据列及相应的属性
在 “数据库属性” 中选择类别为 “列” ,添加列、数据类型和注释等
- 物理名称:表示列名,一般输入英文,如 GuestID。
- 数据类型:表示列名的类型,如整数为 INTEGER 类型
- 必需的:表示是否可以为空
- PK:表示主键
- 注释:关于该列名的说明
4.添加实体之间的映射关系
添加实体之间的映射关系,具体步骤
- 与添加 GuestRecord(客人)实体的步骤一样添加 “客房” 实体Room
- 为 GuestRecord 添加外键约束列 RoomID(客房号),对应Room表中的RoomID列
将E-R图转化为数据库模型图的步骤
- 将E-R图中各实体转化为对应的表,将各属性转化为各表对应的列
- 标识每个表的主键列,需要注意的是,要为没有主键的表添加ID编号列该列没有实际含义,只用作主键或外键,如客人表中的 GuestID 列,客房表中添加的RoomID列
数据规范化
设计问题
1.信息重复
- 假如 “客房类型” “客房状态” 和 “床位数” 列中有许多重复的信息,信息重复会造成存储空间的浪费及一些其他问题,如果不小心输入 “标准间” 和 “标间” 或 “总统套房” 和 “套房“ ,则在数据库中将表示两种不同的客房类型
2.更新异常
- 冗余信息不仅浪费存储空间,还会增加更新的难度。如果需要将 ”客房类型“ 修改为 ”标间“ 而不是标准间,则需要修改所有包含该值的行。如果由于某种原因,没有更新所有行,则数据库中会有两种类型的客房类型,一个是 ”标准间“ ,另一个是 ”标间“ ,这种情况被称为更新异常
3.插入异常(无法表示某些信息)
- 假如2002和2003房客的居住价格分别是 168 元和 158 元。尽管这两件客房都是标准间类型,但它们的 ”价格“ 出现了不同,这样就造成了同一个相同类型的客房价格不同,这种问题被称为插入异常
4.删除异常(丢失有用的信息)
- 在某些清空下,当删除一行时,可能会丢失有用的信息。列如,如果删除客房类型为 ”1001“ 的行,就会丢失客房类型为 ”单人间“ 的账户信息,该表只剩下两种客房类型:”标准间“ 和 ”总统套房“。当希望查询有哪些房客类型时,将会误以为只有 ”标准间“ 和 ”总统套房“ 两种客房类型,这种情况被称为删除异常
规范设计
1.第一范式
- 第一范式(Normal Formate,1NF)的目标是确保每列的原子性。如果每列(或者每个属性值)都是不可再分 的最小数据单元(也称为最小的原子单元),则满足第一范式
2.第二范式
- 第二范式(2NF)在第一范式的基础上更进一层,其目标是确保表中的每列都和主键相关。如果一个关系满足第一范式(1NF),并且除了主键以外的其他列都全部依赖于该主键,则满足第二范式(2NF)
3.第三范式
都是不可再分 的最小数据单元(也称为最小的原子单元),则满足第一范式
2.第二范式
- 第二范式(2NF)在第一范式的基础上更进一层,其目标是确保表中的每列都和主键相关。如果一个关系满足第一范式(1NF),并且除了主键以外的其他列都全部依赖于该主键,则满足第二范式(2NF)
3.第三范式
- 第三范式(3NF)在第二范式的基础上更进一层,第三范式的目标是确保每列都和主键列直接相关,而不是间接相关。如果一个关系满足第二范式(2NF),并且除了主键以外的其他列都只能依赖于主键列,列和列之间不存在相互依赖关系,则满足第三范式(3NF)