MySQL8.0实战(二) - 数据库设计

简介: 数据库设计(Database Design)是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,使之能够有效地存储数据,满足各种用户的应用需求(信息要求和处理要求)。在数据库领域内,常常把使用数据库的各类系统统称为数据库应用系统。

0 Github

1 简介

数据库设计(Database Design)是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,使之能够有效地存储数据,满足各种用户的应用需求(信息要求和处理要求)。在数据库领域内,常常把使用数据库的各类系统统称为数据库应用系统。
数据库设计的设计内容包括:需求分析、概念结构设计、逻辑结构设计、物理结构设计、数据库的实施和数据库的运行和维护。

2 数据库建模五部曲

3 需求总结

◆ 课程的属性:{主标题,副标题,方向,分类,难度最新最热,时长,简介,人数,需知,收获,讲师名讲师职位,课程图片综合评分,内容实用,简洁易懂,逻辑清晰}

◆ 课程列表的属性:{章名,小节名, 说明,小节时长,章节URL,视频格式}

◆ 讲师的属性:{讲师昵称,说明,性别,省,市,职位说明,经验,积分,关注人数,粉丝人数}

◆ 问答评论属性:{类型,标题,内容,关联章节,浏览量,发布时间,用户昵称}

◆ 笔记的属性:{用户昵称,关联章节 笔记标题,笔记内容,发布时间}。

◆ 用户的属性:{用户昵称密码,说明,性别,省,市,职位,说明,经验,积分,关注人数粉丝人数}

◆评价的属性:{用户,课程主标题,内容,综合评分,内容实用,简洁易懂,逻辑清晰,发布时间}

# 4 宽表模式

  • 百度百科定义
    从字面意义上讲就是字段比较多的数据库表。通常是指业务主题相关的指标、维度、属性关联在一起的一张数据库表。由于把不同的内容都放在同一张表存储,宽表已经不符合三范式的模型设计规范,随之带来的主要坏处就是数据的大量冗余,与之相对应的好处就是查询性能的提高与便捷。这种宽表的设计广泛应用于数据挖掘模型训练前的数据准备,通过把相关字段放在同一张表中,可以大大提高数据挖掘模型训练过程中迭代计算时的效率问题。

◆ 课程的属性:{主标题,副标题,方向,分类难度最新,最热,时长,简介,人数,需知,收获,讲师名,讲师职位,课程图片综合评分,内容实用,简洁易懂,逻辑清晰}

  • 实例

4.1 模式存在的问题

4.1.1 更新异常

修改一行中某列的值时,同时修改了多行数据

例如当使用

想修改其职位时,不止影响一条数据
那么,我们再加个限定条件

就可以只修改一行数据,因此我们可以将主标题作为该数据表的唯一标识,即主键!
通过主键更新数据,虽然可以避免数据的更新异常,但也可能会造成表中的数据不一致现象,比如该实例中,讲师的职称就会产生多义.

4.1.2 插入异常

部分数据由于缺失主键信息而无法写入表中

例如,我们想新增Java开发方向的课程

由于执行该语句时,PK为空,即违反了PK非空且唯一的约束条件,因此该语句无法成功.

4.1.3 删除异常

删除某一数据时不得不删除另一数据

例如,我们想删除数据库方向

我们只是单纯想删除数据库方向而已,但该语句却将许多课程也删除了,这并不符合我们的预期.

4.1.4 数据冗余

相同的数据在一个表中出现了多次

那么是不是这么多问题就意味着宽表一无是处呢?存在即合理!

4.2 模式的适用场景

配合列存储的数据报表应用

由于宽表中,所有数据存在于一个表中,因此在查询时,无需多表查询,SQL执行效率较高,且存在的上述问题在报表应用中都不是大问题

既然宽表不适合我们的当前业务,那么怎么寻找合适的方法呢?

5 数据库设计范式

5.1 第一范式

表中的所有字段都是不可再分的

例如以下实例中的联系方式是一个复合属性,明显就违反了该范式,在数据库中是无法分离出来的

我们只需对其进行简单的改动即可

即标准的二维表.

5.2 第二范式

前提

标准的二维表,即第一范式成立

表中必须存在业务主键,并且非主键依赖于全部业务主键

例如如下博客表实例

  • 使用用户字段作为PK是否可行呢?
    显然一个用户会对应多个博客记录,且章节标题也能为多个用户编辑,所以单列字段PK失效
  • 使用<用户,章节,标题>的复合PK
    然而用户积分字段也只和用户字段依赖,并不依赖于整体的PK,所以依旧不符合第二范式
  • 拆分将依赖的字段单独成表

从上面,我们也可以发现:

  • 若表的PK只有一个字段组成,那么它本就符合第二范式
  • 若是多个字段组成,则需考量是否符合第二范式

5.3 第三范式

表中的非主键列之间不能相互依赖

依旧看看课程表

首先,一个字段的PK显然符合第二范式,大部分字段也只依赖于PK,然而对于讲师职称字段其实是依赖于讲师名的,所以不符合第三范式.

  • 将不与PK形成依赖关系的字段直接提出单独成表即可

6 课程实体的逻辑建模

属性

{主标题,副标题,方向,分类,难度,最新,最热,时长,简介,人数,需知,收获,讲师名讲师职位,课程图片综合评分,内容实用,简洁易懂,逻辑清晰}

我们显然可以将其拆分如下:

课程表

主标题(PK),副标题,方向,分类,难度,上线时间,学习人数,时长,简介,需知,收获,讲师昵称,课程图片,综合评分,内容实用,简洁易懂,逻辑清晰

讲师表

讲师名及讲师的职称

其中最新属性即对应着上线时间计算得出,业务上可规定时间段判断是否为最新
最热属性即可以学习人数字段排序来反映

课程方向表

课程方向名称(PK) : 在课程表中有对应的方向字段
添加时间

课程分类表

分类名称(PK) : 在课程表中有对应的方向字段
添加时间

课程难度表

课程难度(PK) : 在课程表中有对应的方向字段
添加时间

7 课程列表实体的逻辑建模

属性

[章节名,小节名](联合PK)
说明,小节时长,章节URL,视频格式

其中,说明其实只依赖于章节名
小节时长小节URL,视频格式都只依赖于小节名
违反第二范式,所以需要拆分字段

课程章节表

章节名(PK),说明,章节编号

课程与章节的联系表

主标题,章节名

课程小节表

小节名称(PK),小节视频url,视频格式,小节时长,小节编号

课程章节与小节的联系表

主标题,章节名,小节名

8 讲师实体的逻辑建模

属性

讲师名,密码,性别,省,市,职称,说明,经验,积分,关注数,粉丝数

讲师表

讲师名(PK),密码,性别,省,市,职称,说明,经验,积分,关注数,粉丝数

9 用户实体的逻辑建模

属性

用户昵称,密码,性别,省市,职位,说明,经验,积分,关注数,粉丝数

用户表V1.0

用户昵称(PK),密码,性别,省市,职位,说明,经验,积分,关注数,粉丝数

和讲师表基本相同,且讲师其实也是一种用户,讲师的信息就会被存储两次,造成数据的冗余.,于是就难以保持数据一致性!考虑合并!

用户表V2.0

用户昵称(PK),密码,性别,省市,职位,说明,经验,积分,关注数,粉丝数,讲师标识

10 问答评论实体的逻辑建模

属性

类型,标题,内容关联章节,浏览量,发布时间,用户昵称

其中标题文字是共享的,无法保持一致
同一用户在不同章节提出的问题也可能相同
因此决定采用标题+用户昵称+关联章节作为PK

评论表

如何记录关联章节字段呢?
是不是只能用课程章节的PK来记录呢?
因此,不得不将课程章节的关联表PK加入

[标题,课程主标题,课程章名,小节名称,用户呢称](PK)
父评论(被回复的问题/标题)
标题,内容,类型,浏览量,发布时间

11 笔记实体的逻辑建模

属性

用户昵称,关联章节,笔记标题,笔记内容,发布时间

和评论实体差不多,分析不再赘述

笔记表

[笔记标题,课程主标题,课程章名,小节名称,用户呢称](PK)
内容,发布时间

12 评价实体的逻辑建模

属性

用户呢称;课程主标题,内容,综合评分,内容实用,简洁易懂,逻辑清晰,发布时间

评价表

[用户呢称;课程主标题](PK)
内容,综合评分,内容实用,简洁易懂,逻辑清晰,发布时间

只有选择/购买了课程的用户才能评价!!!

需要用户与所选课程的关联关系表

用户选课表

[用户呢称;课程主标题](PK)
选课时间,累积听课时长

13 小结




14 范式化暴露的问题

如果我们想要查询出一门课程包括所有章节和小节的相关信息

那么这些信息又是如何存储的呢,需要查询哪些表呢?如下所示

我们就要关联5个表,查询效率极低!且查询课程信息的需求很大!
为了提高性能,我们还需要对表结构进行优化操作

15 反范式化设计

空间换时间的思想

15.1 课程章节表反范式化设计


上述表存在一对多的关系

所以可以并不需要关联关系表,而是呢可以直接把课程表和课程&章节联系表合并

成为新的课程章节表
[主标题,章节名](PK),说明,章节编号

虽然违反了第二范式,但是减少了一个表的查询,提高了查询性能,在频繁查询操作的系统中,这很值得!

经过反范式化后,我们只需要查询三个表即可

15.2 反范式化设计小结

课程相关表数量 5 -> 3

16 常用存储引擎

17 InnoDB存储引擎的特点

  • 事务型存储引擎支持ACID
  • 数据按主键聚集存储
  • 支持行级锁及MVCC
  • 支持Btree和自适应Hash索引
  • 支持全文和空间索引

18 根据 InnoDB特性优化后的表逻辑结构

通过数据冗余避免数据不一致

课程章节表:{章节ID(PK),课程ID,章节名称,章节说明,章节编号}

课程小节表:{小节ID(PK),课程ID,章节ID,小节名称,小节视频url,视频格式,小节时长,小节编号}。

课程方向表:{课程方向ID(PK),课程方向名称,填加时间}

课程分类表:{课程分类ID(PK),分类名称,填加时间}

课程难度表:{课程难度ID(PK) ,课程难度,填加时间}

用户表:{用户ID(PK),用户昵称,密码,性别,省市,职位,说明,经验,积分,关注
人数,粉丝人数,讲师标识}

问答评论表:{评论ID(PK),父评论ID ,课程ID,章节ID,小节ID ,评论标题,用户
ID,内容,类型,浏览量,发布时间}

笔记表:{笔记ID(PK),课程ID,章节ID,小节ID笔记标题,用户呢称,笔记内容,
发布时间}

评价表:{评价ID(PK),用户ID,课程ID,内容综合评分,内容实用,简洁易懂,逻
辑清晰,发布时间}

用户选课表:{用户选课ID(PK),用户ID,课程ID,选课时间,累积听课时长}

19 常用的整数类型

20 常用的浮点类型

  • 例如:

实战实数类型的特点

  • 建立测试数据库
  • 新建表
  • 插入数据至t表中

  • 查询和
  • 和的结果

所以只有decimal是精确的浮点类型

21 常用的时间类型

实战时间类型的特点

  • 新建表
  • 插入数据
  • 查询结果
  • 由于北京时间是东八区,因此我们更改时区
  • 新的查询结果

这就是timestamp具有时区性的特点

22 字符串类型的特点

23 如何为数据选择合适的的数据类型

23.1 优先选择符合存储数据需求的最小数据类型

INET_ATON( '255.255.255.255' ) = 4294967295
INET_ NTOA(4294967295) ='255.255.255.255'

23.2 谨慎使用ENUM,TEXT字符串类型

23.2.1 ENUM 的迁移

数据迁移的时候,它几乎不可能被其他数据库所支持,如果 ENUM 里面是字符串,对于其他数据库来说就更郁闷了,还不能设为tinyint等类型的字段

23.2.2 ENUM 的索引

纯数字类型的不建议用枚举类型,这是因为在 ENUM 内部维护有一个隐形的索引,也是按数字排列的,容易混淆;添加枚举值也是一个问题,如果添加在最后还好,如果添加在中间什么位置的话,原来的隐藏索引将不再起作用

23.2.3 ENUM 字段 的NULL 值

ENUM 字段默认是可以插入 NULL 值的,这个就比较尴尬了,而且没有办法优化

23.2.4 插入的值

如果插入的值比ENUM设定的值大,会默认保存成接近的那个值;插入的值不能包含函数,不能传递参数

所以如果插入的值是数字型的,建议用tinyint,如果插入的值是字符型的,建议用char。如果真想用 ENUM 也是可以得,前提是要了解到 ENUM 的弊端,就可以有效规避这些问题

23.4 同财务相关的数值型数据,必需使用decimal类型。

24 为项目表们选择合适的数据类型

24.1 课程表


24.2 章节表

24.3 小节表

24.4 课程分类表

24.5 课程难度表

24.5 课程方向表

24.6 用户表


24.7 问答评论表

24.8 笔记表

在这里插入图片描述

24.9 用户选课表

30 如何为表和列选择合适的名字

  • 所有数据库对像名称必须使用小写字母可选用下划线分割
  • 所有数据库对像名称定义禁止使用MySQL保留关建字
  • 数据库对像的命名要能做到见名识义,并且最好不要超过32个字
  • 临时库表必须以tmp为前缀并以日期为后缀
  • 用于备份的库,表必须以bak为前缀并以日期为后缀
  • 所有存储相同数据的列名和列类型必须一致。

31 总结

工程师的必备技能

1、前奏:【业务分析】欲善其事,必三思而行;
2、高潮:【逻辑设计】范式化VS反范式化;
3、结束:【物理设计】存储引擎&数据类型&命名规约。

内容综述

  • 数据库的逻辑设计规范
  • MySQL的常用存储引擎及其选择方法
  • MySQL的常用数据类型及其选择方法
  • 如何为表选择适合的存储类型
  • 如何为表起一个好名

参考

数据库设计
MySQL慎用 ENUM 字段

更多内容请关注JavaEdge 公众号

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
目录
相关文章
|
2月前
|
SQL 关系型数据库 数据库
Python SQLAlchemy模块:从入门到实战的数据库操作指南
免费提供Python+PyCharm编程环境,结合SQLAlchemy ORM框架详解数据库开发。涵盖连接配置、模型定义、CRUD操作、事务控制及Alembic迁移工具,以电商订单系统为例,深入讲解高并发场景下的性能优化与最佳实践,助你高效构建数据驱动应用。
377 7
|
3月前
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
165 3
|
3月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。
802 152
|
3月前
|
关系型数据库 MySQL 分布式数据库
阿里云PolarDB云原生数据库收费价格:MySQL和PostgreSQL详细介绍
阿里云PolarDB兼容MySQL、PostgreSQL及Oracle语法,支持集中式与分布式架构。标准版2核4G年费1116元起,企业版最高性能达4核16G,支持HTAP与多级高可用,广泛应用于金融、政务、互联网等领域,TCO成本降低50%。
|
3月前
|
关系型数据库 分布式数据库 数据库
阿里云数据库收费价格:MySQL、PostgreSQL、SQL Server和MariaDB引擎费用整理
阿里云数据库提供多种类型,包括关系型与NoSQL,主流如PolarDB、RDS MySQL/PostgreSQL、Redis等。价格低至21元/月起,支持按需付费与优惠套餐,适用于各类应用场景。
|
3月前
|
SQL 关系型数据库 MySQL
Mysql数据恢复—Mysql数据库delete删除后数据恢复案例
本地服务器,操作系统为windows server。服务器上部署mysql单实例,innodb引擎,独立表空间。未进行数据库备份,未开启binlog。 人为误操作使用Delete命令删除数据时未添加where子句,导致全表数据被删除。删除后未对该表进行任何操作。需要恢复误删除的数据。 在本案例中的mysql数据库未进行备份,也未开启binlog日志,无法直接还原数据库。
|
3月前
|
存储 数据库 开发者
Python SQLite模块:轻量级数据库的实战指南
本文深入讲解Python内置sqlite3模块的实战应用,涵盖数据库连接、CRUD操作、事务管理、性能优化及高级特性,结合完整案例,助你快速掌握SQLite在小型项目中的高效使用,是Python开发者必备的轻量级数据库指南。
334 0
|
3月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎,提供高性价比、稳定安全的云数据库服务,适用于多种行业与业务场景。
|
3月前
|
关系型数据库 MySQL 数据库
自建数据库如何迁移至RDS MySQL实例
数据库迁移是一项复杂且耗时的工程,需考虑数据安全、完整性及业务中断影响。使用阿里云数据传输服务DTS,可快速、平滑完成迁移任务,将应用停机时间降至分钟级。您还可通过全量备份自建数据库并恢复至RDS MySQL实例,实现间接迁移上云。
|
4月前
|
存储 运维 关系型数据库
从MySQL到云数据库,数据库迁移真的有必要吗?
本文探讨了企业在业务增长背景下,是否应从 MySQL 迁移至云数据库的决策问题。分析了 MySQL 的优势与瓶颈,对比了云数据库在存储计算分离、自动化运维、多负载支持等方面的优势,并提出判断迁移必要性的五个关键问题及实施路径,帮助企业理性决策并落地迁移方案。

推荐镜像

更多