Lazy loaded image
23_数据库设计
Words 7134Read Time 18 min
2025-12-11

第23章 数据库设计

23.1 数据库设计概述

23.1.1 数据库设计的概念

数据库设计(Database Design)是指根据用户的需求,在特定的数据库管理系统上,设计数据库的结构和存储方式,包括数据库的概念结构、逻辑结构和物理结构。数据库设计是数据库应用系统开发的核心环节,直接影响到系统的性能、可靠性和可维护性。

23.1.2 数据库设计的目标

  • 满足用户需求:准确反映用户的业务需求和数据处理需求
  • 保证数据完整性:确保数据的正确性、一致性和可靠性
  • 提高系统性能:优化数据库结构,提高查询和更新效率
  • 保证系统可扩展性:便于系统的后续扩展和维护
  • 降低系统成本:减少存储开销和维护成本

23.1.3 数据库设计的重要性

  • 良好的数据库设计可以提高系统性能
  • 良好的数据库设计可以保证数据完整性
  • 良好的数据库设计可以降低系统维护成本
  • 良好的数据库设计可以提高系统可扩展性
  • 良好的数据库设计可以提高开发效率

23.2 数据库设计的阶段

数据库设计通常分为以下几个阶段: 1. 需求分析阶段:收集和分析用户需求 2. 概念设计阶段:设计数据库的概念结构(ER模型) 3. 逻辑设计阶段:将概念结构转换为逻辑结构(关系模型) 4. 物理设计阶段:设计数据库的物理存储结构 5. 数据库实施阶段:创建数据库、表、索引等 6. 数据库运行和维护阶段:数据库的日常运行和维护

23.2.1 数据库设计的流程

23.3 需求分析阶段

23.3.1 需求分析的任务

需求分析的主要任务是收集和分析用户的业务需求和数据处理需求,包括: - 了解用户的业务流程 - 确定系统的功能需求 - 确定系统的数据需求 - 确定系统的性能需求 - 确定系统的安全需求

23.3.2 需求分析的方法

  • 访谈法:与用户进行面对面的交流,了解用户需求
  • 问卷调查法:通过发放问卷的方式收集用户需求
  • 观察法:观察用户的日常工作流程,了解用户需求
  • 文档分析法:分析现有的业务文档,了解用户需求

23.3.3 需求分析的输出

  • 需求规格说明书:详细描述系统的功能需求、数据需求、性能需求和安全需求
  • 数据字典:描述系统中涉及的所有数据项、数据结构、数据流和数据存储
  • 业务流程图:描述系统的业务流程
  • 数据流图:描述系统的数据流动过程

23.3.4 数据字典

数据字典是系统中数据的详细描述,包括: - 数据项:数据的最小单位,如学生的学号、姓名等 - 数据结构:由多个数据项组成的数据结构,如学生信息 - 数据流:系统中流动的数据,如学生注册信息 - 数据存储:系统中存储的数据,如学生表、课程表等 - 处理过程:对数据的处理,如学生注册、成绩录入等

23.4 概念设计阶段

23.4.1 概念设计的任务

概念设计的主要任务是设计数据库的概念结构,即ER模型(Entity-Relationship Model),它是对现实世界的抽象表示,不依赖于具体的数据库管理系统。

23.4.2 ER模型的基本概念

23.4.2.1 实体(Entity)

实体是现实世界中可以相互区别的事物,如学生、课程、教师等。实体可以分为: - 强实体:不依赖于其他实体而存在的实体 - 弱实体:依赖于其他实体而存在的实体

23.4.2.2 属性(Attribute)

属性是实体的特征或性质,如学生的学号、姓名、年龄等。属性可以分为: - 简单属性:不可再分的属性,如年龄 - 复合属性:可以再分的属性,如地址(包括省、市、区等) - 单值属性:每个实体只有一个值的属性,如性别 - 多值属性:每个实体可以有多个值的属性,如学生的爱好 - 派生属性:由其他属性派生出来的属性,如学生的平均成绩 - NULL属性:允许为空的属性

23.4.2.3 关系(Relationship)

关系是实体之间的联系,如学生选课、教师授课等。关系的类型包括: - 一对一关系(1:1):一个实体的实例只能与另一个实体的一个实例相关联,如学生和学生证 - 一对多关系(1:N):一个实体的实例可以与另一个实体的多个实例相关联,如班级和学生 - 多对多关系(M:N):一个实体的实例可以与另一个实体的多个实例相关联,反之亦然,如学生和课程

23.4.2.4 键(Key)

键是用于唯一标识实体实例的属性或属性组合,包括: - 实体键:唯一标识实体实例的属性或属性组合 - 主键:被选中作为唯一标识的实体键 - 外键:用于关联两个实体的属性

23.4.3 ER图的绘制

ER图(Entity-Relationship Diagram)是ER模型的图形表示,使用以下符号: - 矩形:表示实体 - 椭圆形:表示属性 - 菱形:表示关系 - 直线:连接实体、属性和关系

23.4.4 ER模型的设计步骤

  1. 确定实体
  1. 确定实体的属性
  1. 确定实体之间的关系
  1. 确定关系的类型
  1. 绘制ER图
  1. 优化ER图

23.4.5 ER模型的优化

ER模型的优化主要包括: - 合并冗余实体:将重复的实体合并 - 消除冗余属性:删除不必要的属性 - 简化关系:将复杂的关系简化 - 调整关系类型:根据实际情况调整关系类型

23.5 逻辑设计阶段

23.5.1 逻辑设计的任务

逻辑设计的主要任务是将ER模型转换为关系模型,即创建数据库表结构,包括: - 确定表名和列名 - 确定数据类型和约束 - 确定主键和外键 - 确定索引

23.5.2 ER模型到关系模型的转换规则

23.5.2.1 实体的转换

将每个实体转换为一个关系表,实体的属性转换为表的列,实体的主键转换为表的主键。
示例: 实体:学生(学号,姓名,年龄,性别) 转换为关系表:

23.5.2.2 一对一关系的转换

有两种转换方式: 1. 将两个实体转换为两个表,在其中一个表中添加外键指向另一个表的主键,并添加唯一约束 2. 将两个实体合并为一个表
示例: 实体:学生(学号,姓名,年龄)和学生证(证号,发证日期,有效期),关系:1:1
转换方式1:
转换方式2:

23.5.2.3 一对多关系的转换

将两个实体转换为两个表,在多的一方添加外键指向一的一方的主键。
示例: 实体:班级(班号,班名,班主任)和学生(学号,姓名,年龄),关系:1:N
转换为关系表:

23.5.2.4 多对多关系的转换

将两个实体转换为两个表,创建一个中间表来表示多对多关系,中间表包含两个外键分别指向两个实体的主键,两个外键组合作为中间表的主键。
示例: 实体:学生(学号,姓名,年龄)和课程(课程号,课程名,学分),关系:M:N
转换为关系表:

23.5.2.5 弱实体的转换

将弱实体转换为一个表,添加外键指向强实体的主键,并将强实体的主键和弱实体的部分主键组合作为弱实体的主键。
示例: 实体:订单(订单号,客户号,订单日期)和订单明细(明细号,商品号,数量,单价),关系:1:N(订单明细是弱实体)
转换为关系表:

23.5.3 关系模型的优化

关系模型的优化主要包括: - 规范化:将关系表分解为符合范式的表 - 反规范化:根据性能需求,适当合并表或添加冗余列 - 确定数据类型:选择合适的数据类型 - 添加约束:添加主键、外键、唯一、非空等约束 - 创建索引:创建适当的索引

23.6 物理设计阶段

23.6.1 物理设计的任务

物理设计的主要任务是设计数据库的物理存储结构,包括: - 确定表的存储结构 - 确定索引的类型和位置 - 确定分区策略 - 确定存储位置和空间分配 - 确定备份和恢复策略

23.6.2 物理设计的考虑因素

  • 性能需求:查询响应时间、吞吐量、并发处理能力
  • 存储需求:数据量大小、增长速度
  • 安全需求:数据加密、访问控制
  • 可用性需求:系统 uptime、故障恢复时间

23.6.3 表的物理设计

23.6.3.1 表的存储结构

  • 堆表:数据行无序存储
  • 索引组织表:数据行按照索引顺序存储
  • 分区表:将表分为多个分区,每个分区可以独立管理

23.6.3.2 数据类型的选择

选择合适的数据类型可以提高性能和减少存储空间,例如: - 对于整数,使用INT而不是VARCHAR - 对于日期和时间,使用DATE、TIME或TIMESTAMP而不是VARCHAR - 对于固定长度的字符串,使用CHAR而不是VARCHAR - 对于可变长度的字符串,使用VARCHAR而不是CHAR

23.6.3.3 约束的实现

约束的实现方式包括: - 主键约束:使用索引实现 - 外键约束:使用索引实现,并在插入、更新和删除时进行检查 - 唯一约束:使用索引实现 - 非空约束:在插入和更新时进行检查 - 检查约束:在插入和更新时进行检查

23.6.4 索引的物理设计

23.6.4.1 索引类型的选择

  • B+树索引:适用于范围查询和等值查询
  • 哈希索引:适用于等值查询
  • 全文索引:适用于全文搜索
  • 空间索引:适用于地理空间数据查询

23.6.4.2 索引的设计原则

  • 为频繁查询的列创建索引
  • 为连接列创建索引
  • 为排序和分组列创建索引
  • 避免为频繁更新的列创建索引
  • 避免为值分布均匀的列创建索引
  • 合理使用复合索引,遵循最左前缀原则

23.6.5 分区设计

23.6.5.1 分区的类型

  • 范围分区:根据列的范围值进行分区,如按日期分区
  • 列表分区:根据列的离散值进行分区,如按地区分区
  • 哈希分区:根据列的哈希值进行分区
  • 复合分区:结合多种分区方式

23.6.5.2 分区的优点

  • 提高查询性能:只需要扫描相关分区
  • 便于管理:可以独立管理每个分区
  • 提高可用性:一个分区故障不影响其他分区
  • 便于备份和恢复:可以只备份和恢复相关分区

23.7 数据库实施阶段

23.7.1 数据库实施的任务

数据库实施的主要任务是根据逻辑设计和物理设计的结果,创建数据库、表、索引等,并加载数据。

23.7.2 数据库实施的步骤

  1. 创建数据库:使用CREATE DATABASE语句创建数据库
  1. 创建表:使用CREATE TABLE语句创建表
  1. 创建索引:使用CREATE INDEX语句创建索引
  1. 创建视图、存储过程、函数等:使用相应的SQL语句创建
  1. 加载数据:使用INSERT语句或导入工具加载数据
  1. 测试数据库:测试数据库的功能和性能

23.7.3 数据加载

数据加载的方式包括: - 手动加载:使用INSERT语句手动插入数据 - 批量加载:使用LOAD DATA或COPY命令批量加载数据 - 导入工具:使用数据库提供的导入工具,如pg_restore、mysqlimport等

23.7.4 数据库测试

数据库测试的内容包括: - 功能测试:测试数据库的功能是否符合需求 - 性能测试:测试数据库的性能是否符合需求 - 完整性测试:测试数据库的完整性约束是否有效 - 安全性测试:测试数据库的安全性是否符合需求

23.8 数据库运行和维护阶段

23.8.1 数据库运行和维护的任务

数据库运行和维护的主要任务包括: - 监控数据库的运行状态 - 优化数据库性能 - 备份和恢复数据库 - 处理数据库故障 - 更新数据库结构 - 管理数据库用户和权限 - 审计数据库访问

23.8.2 数据库监控

数据库监控的内容包括: - 性能监控:CPU利用率、内存使用率、磁盘IO、网络IO等 - 空间监控:数据库大小、表大小、索引大小等 - 会话监控:当前连接数、活跃会话数、慢查询等 - 错误监控:错误日志、警告日志等

23.8.3 数据库性能优化

数据库性能优化的方法包括: - 优化查询语句 - 优化索引 - 优化表结构 - 优化存储结构 - 调整数据库参数 - 增加硬件资源

23.8.4 数据库备份和恢复

数据库备份和恢复的策略包括: - 定期备份数据库 - 测试备份文件的可用性 - 制定恢复计划 - 定期进行恢复测试

23.9 数据库设计的规范化

23.9.1 规范化的概念

规范化是指将关系表分解为符合范式的表,以减少数据冗余和提高数据完整性。规范化的过程是逐步提高范式的过程。

23.9.2 函数依赖

函数依赖是指一个属性集决定另一个属性集,例如,学号决定姓名(学号→姓名)。

23.9.3 范式

23.9.3.1 第一范式(1NF)

  • 定义:关系表中的每一列都是不可再分的原子值
  • 目标:消除复合属性
  • 示例:将地址(省、市、区)分解为省、市、区三个列

23.9.3.2 第二范式(2NF)

  • 定义:在1NF的基础上,非主键列完全依赖于主键,而不是部分依赖
  • 目标:消除部分依赖
  • 示例:将学生选课表(学号,课程号,姓名,课程名,成绩)分解为学生表(学号,姓名)、课程表(课程号,课程名)和选课表(学号,课程号,成绩)

23.9.3.3 第三范式(3NF)

  • 定义:在2NF的基础上,非主键列不传递依赖于主键
  • 目标:消除传递依赖
  • 示例:将学生表(学号,姓名,班级号,班级名称)分解为学生表(学号,姓名,班级号)和班级表(班级号,班级名称)

23.9.3.4 BC范式(BCNF)

  • 定义:在3NF的基础上,每个函数依赖的左部都是候选键
  • 目标:消除主属性对候选键的部分依赖和传递依赖

23.9.3.5 第四范式(4NF)

  • 定义:在BCNF的基础上,消除多值依赖
  • 目标:消除多值依赖

23.9.3.6 第五范式(5NF)

  • 定义:在4NF的基础上,消除连接依赖
  • 目标:消除连接依赖

23.9.4 规范化的优缺点

优点

  • 减少数据冗余
  • 提高数据完整性
  • 便于数据更新
  • 便于数据库设计

缺点

  • 增加查询复杂度
  • 降低查询性能
  • 增加表之间的连接操作

23.9.5 反规范化

反规范化是指根据性能需求,适当合并表或添加冗余列,以提高查询性能。反规范化的方法包括: - 合并表 - 添加冗余列 - 分区表 - 物化视图

23.10 综合示例:学生成绩管理系统数据库设计

23.10.1 需求分析

23.10.1.1 业务需求

学生成绩管理系统需要实现以下功能: - 学生信息管理:添加、修改、删除、查询学生信息 - 课程信息管理:添加、修改、删除、查询课程信息 - 成绩管理:录入、修改、删除、查询学生成绩 - 统计分析:统计学生的平均成绩、课程的平均成绩等

23.10.1.2 数据需求

系统涉及的数据包括: - 学生:学号、姓名、性别、年龄、班级 - 班级:班级号、班级名称、班主任 - 课程:课程号、课程名称、学分、授课教师 - 成绩:学号、课程号、成绩 - 教师:教师号、姓名、性别、年龄、职称

23.10.2 概念设计

23.10.2.1 确定实体

  • 学生(Student)
  • 班级(Class)
  • 课程(Course)
  • 成绩(Score)
  • 教师(Teacher)

23.10.2.2 确定实体的属性

  • 学生:学号(student_id)、姓名(name)、性别(gender)、年龄(age)
  • 班级:班级号(class_id)、班级名称(class_name)、班主任(head_teacher)
  • 课程:课程号(course_id)、课程名称(course_name)、学分(credit)
  • 成绩:成绩(score)
  • 教师:教师号(teacher_id)、姓名(name)、性别(gender)、年龄(age)、职称(title)

23.10.2.3 确定实体之间的关系

  • 班级和学生:1:N
  • 教师和课程:1:N
  • 学生和课程:M:N(通过成绩表关联)

23.10.2.4 绘制ER图

23.10.3 逻辑设计

23.10.3.1 ER模型到关系模型的转换

  1. 学生表
  1. 班级表
  1. 教师表
  1. 课程表
  1. 成绩表

23.10.3.2 关系模型的优化

  • 为频繁查询的列创建索引
  • 为连接列创建索引
  • 为排序和分组列创建索引

23.10.4 物理设计

23.10.4.1 表的存储结构

  • 学生表、班级表、教师表、课程表使用堆表存储
  • 成绩表使用索引组织表存储,以提高查询性能

23.10.4.2 索引设计

  • 学生表:在班级号列创建索引
  • 课程表:在教师号列创建索引
  • 成绩表:在学号和课程号列创建索引

23.10.4.3 分区设计

  • 成绩表按学年进行范围分区,便于管理和查询

23.10.5 数据库实施

23.10.5.1 创建数据库

23.10.5.2 创建表

23.10.5.3 创建索引

23.10.5.4 加载数据

23.11 数据库设计的最佳实践

23.11.1 需求分析阶段的最佳实践

  • 充分了解用户需求,与用户保持良好的沟通
  • 详细记录需求,形成需求规格说明书
  • 对需求进行验证,确保需求的准确性和完整性

23.11.2 概念设计阶段的最佳实践

  • 准确识别实体、属性和关系
  • 绘制清晰的ER图
  • 优化ER模型,消除冗余

23.11.3 逻辑设计阶段的最佳实践

  • 遵循规范化原则,将表分解为符合范式的表
  • 合理设计主键和外键
  • 选择合适的数据类型
  • 添加必要的约束

23.11.4 物理设计阶段的最佳实践

  • 根据性能需求设计物理存储结构
  • 合理设计索引,提高查询性能
  • 考虑分区策略,便于管理和查询
  • 考虑备份和恢复策略,确保数据安全

23.11.5 数据库实施阶段的最佳实践

  • 严格按照设计文档创建数据库对象
  • 测试数据库的功能和性能
  • 确保数据的完整性和一致性

23.11.6 数据库运行和维护阶段的最佳实践

  • 定期监控数据库的运行状态
  • 定期备份数据库
  • 定期优化数据库性能
  • 及时处理数据库故障

23.12 常见问题与解决方案

23.12.1 问题1:需求不明确

  • 原因:用户需求描述不清晰,或与用户沟通不足
  • 解决方案:加强与用户的沟通,使用原型、流程图等工具辅助需求分析,形成详细的需求规格说明书

23.12.2 问题2:ER模型设计不合理

  • 原因:实体、属性和关系识别不准确
  • 解决方案:重新分析需求,准确识别实体、属性和关系,优化ER模型

23.12.3 问题3:关系模型规范化不足

  • 原因:对规范化理论理解不足,或为了方便设计而忽略规范化
  • 解决方案:学习和应用规范化理论,将表分解为符合范式的表

23.12.4 问题4:性能问题

  • 原因:物理设计不合理,如索引设计不当、表结构不合理等
  • 解决方案:优化物理设计,如调整索引、使用分区表、优化查询语句等

23.12.5 问题5:数据完整性问题

  • 原因:约束设计不当,或未添加必要的约束
  • 解决方案:添加必要的约束,如主键、外键、唯一、非空等约束

23.13 小结

数据库设计是数据库应用系统开发的核心环节,包括需求分析、概念设计、逻辑设计、物理设计、数据库实施和数据库运行维护等阶段。良好的数据库设计可以提高系统性能、保证数据完整性、降低维护成本。
在数据库设计过程中,需要遵循规范化原则,将表分解为符合范式的表,同时也要考虑性能需求,适当进行反规范化。物理设计阶段需要考虑表的存储结构、索引设计、分区策略等,以提高数据库的性能和可用性。
数据库设计是一个迭代的过程,需要不断地调整和优化,以满足用户的需求和系统的性能要求。

23.14 练习题

  1. 数据库设计的阶段包括哪些?
  1. 需求分析的主要任务是什么?
  1. ER模型的基本概念包括哪些?
  1. 实体之间的关系类型有哪些?请举例说明。
  1. 如何将ER模型转换为关系模型?请举例说明。
  1. 什么是规范化?规范化的目的是什么?
  1. 数据库的范式包括哪些?请简要描述每个范式的要求。
  1. 什么是反规范化?反规范化的目的是什么?
  1. 物理设计的主要任务是什么?
  1. 数据库实施的步骤包括哪些?
上一篇
openGauss数据库
下一篇
openGauss数据库
Catalog