MySQL表设计与优化

影响MySQL查询性能的因素有很多,我们经常会对查询语句、索引字段做一些优化,而其实在表设计的阶段就可能产生一些问题。对于表设计,可以对表结构进行优化,也可以对表字段进行优化。以下通过一个具体的案例演示一些常用的表设计优化的方法。

一、业务需求

这里,就以学生-教师-课程业务作为示例。数据库需要存放学生、教师、课程相关信息。学生信息包括学号、姓名、性别、专业、年级、班级等;教师信息包括教师编号、姓名、入职时间等;课程表包括课程id、课程名称、课程概述、课时安排等信息。

根据需求,学生可以选修多门课程,具有一对多关系;教师也可以任教多门课程,具有一对多关系。所以,还需要建立对应的中间表。

二、初始构建

通过以上需求分析,可以构建出如下的关系图:

图片替换文本

在上图可以看出,表中字段已经满足了各个实体的需求,中间表也体现出了实体之间的对应关系。并且,表设计符合数据库第三范式

三、表结构优化

1、适度冗余

现在有一个需求,查询姓名为“张三”的学生选修的每门课程的总成绩。在初始构建的表中,需要先通过学生姓名查询出对应的学生id,再查询对应的课程和分数。查询语句如下:

-- 查询姓名为“张三”的学生选修的每门课程的总成绩
select s.name, c.name, c.total_grade 
from (
  select id, name from tb_student where name = '张三'
) s, 
(
  select sc.student_id, c.name, total_grade from tb_course c , tb_student_course sc WHERE c.id = sc.course_id
) c
where s.id = c.student_id;

得到结果:

图片替换文本

使用Explain分析,可以看到检索了三张表才得到结果。

图片替换文本

在实际场景中,我们经常使用学生姓名而不是学生id来进行查询,所以,可以在学生-课程中间表上添加冗余字段(学生姓名、课程名称)来优化查询,减少join连接查询。虽然冗余字段破坏了第三范式,但是从性能角度和使用场景分析,可以提高整体的效率。以下是优化后的学生-课程表:

图片替换文本

这时,查询姓名为“张三”的学生选修的每门课程的总成绩就不需要多表查询了,其查询语句如下:

select student_name, course_name, total_grade from tb_student_course where student_name = '张三';

2、大字段、不常用字段拆分

在课程表中,有两个较大的字段,分别为课程概述和课时计划,详细地介绍了课程的一些相关信息。在实际场景中,我们更经常查询课程教室、课程时间等信息。但是,当我们查询课程教室和课程时间字段的时候,数据库并不是只读取我们需要的字段,而是读取整条记录的字段,包括了课程概述和课时计划两个大字段。由于大字段所占的空间比例很大,所以会造成较大的资源浪费。

所以,我们可以将这两个不常用的大字段进行拆分,来提高查询性能。优化后的关系图如下:

图片替换文本

四、字段优化

一般来说,字段类型要在符号需求的情况下选择尽量小的类型。

1、数字类型

在学生-课程表中,包含了平时成绩、期末成绩、总成绩的字段,使用了double类型,保留两位小数。但对于成绩字段来说,其实并不需要这么大的字段,可以使用int类型来存放。对于保留两位小数,可以通过乘以100的固定系数转换为整数来存放。

2、时间类型

在设计时间类型时,要根据业务需求选用合适的时间类型。如果只需要记录年份,使用year类型;如果只需要记录日期YYYY-MM-DD,不需要具体时间,可以使用date类型;如果只需要具体时间hh:mm:ss,不需要日期,可以使用time类型。使用timestamp时,需要注意它的范围大小是否能满足需求。

3、字符类型

对于固定长度的字段,可以使用char类型;对于可变长度字段,可以使用varchar类型。varchar用于存储可变长度字符串,它比char类型更加节省空间,但是varchar需要使用1个或2个额外字节记录字符串的长度。

例如,性别字段,只需要用‘M’和‘F’来表示男、女,这时,可以使用char(1)。或者,可以使用tinyint(1)存放,用0表示男、1表示女。

对于身份证号,因为其是固定长度为18位,所以,可以采用char类型。

对于课程名称、详情等字段,它们的长度是不固定的,可以采用varchar类型。

所以,最终优化后的学生-课程-教室关系图如下:

图片替换文本

五、总结

以上通过一个具体案例解释了数据库的表设计与优化方法,包括表结构优化(如适度冗余、字段拆分),字段优化。

如果文中有不完善的地方,欢迎大家讨论交流!

原文链接:https://www.cnblogs.com/xwangkk/p/17323201.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:MySQL表设计与优化 - Python技术站

(0)
上一篇 2023年4月17日
下一篇 2023年4月17日

相关文章

  • MySQL创建用户

    MySQL是一种常用的关系型数据库管理系统,它支持多用户多任务的操作,因此我们需要在MySQL中为每个用户分配不同的权限。 在MySQL中创建用户有两种方式:使用GRANT语句和使用CREATE USER语句。下面我们分别介绍这两种创建用户的方式。 使用GRANT语句创建用户 GRANT语句可以授权给MySQL数据库中的用户不同的权限。下面是通过GRANT语…

    MySQL 2023年3月10日
    00
  • mysql 8.0.11安装教程图文解说

    安装MySQL 8.0.11需要以下步骤: 下载安装包 首先,你需要从官方网站MySQL官网下载对应操作系统的安装包。选择相应的版本和安装方式,点击下载链接即可。 安装MySQL 运行安装程序并选择安装类型。 阅读许可协议并同意。 在安装类型界面中选择”Custom”自定义安装。 选择你想要安装的MySQL组件和功能。 点击”Next”开始安装MySQL。 …

    MySQL 2023年5月18日
    00
  • 云时代,MySQL到ClickHouse数据同步产品对比推荐

    ClickHouse 在执行分析查询时的速度优势很好的弥补了 MySQL 的不足,但是对于很多开发者和DBA来说,如何将MySQL稳定、高效、简单的同步到 ClickHouse 却很困难。本文对比了 NineData、MaterializeMySQL(ClickHouse自带)、Bifrost 三款产品,看看他们在同步时的差异。 对比结果概述 整体上,Nin…

    MySQL 2023年4月19日
    00
  • Mysql使用索引实现查询优化

    MySQL 使用索引是优化查询效率的重要手段之一。索引是一种特殊的数据结构,可以帮助 MySQL 快速定位匹配的数据行。在本篇攻略中,我们将详细讲解如何使用索引实现查询优化。 索引介绍 索引是一种数据结构,可以帮助我们快速地定位匹配的数据记录。在 MySQL 中,常用的索引类型包括: B-Tree 索引:常用的索引类型,可以在 O(log n) 的时间内定位…

    MySQL 2023年5月19日
    00
  • Linux中对MySQL优化实例详解

    Linux中对MySQL优化实例详解 MySQL 是一种常用的开源关系型数据库,它在 Linux 系统中得到了广泛的应用。这里详细讲解在 Linux 中优化 MySQL 的实例,以提高 MySQL 的性能和可靠性。 1. 加载和卸载 MySQL 服务 要启动 MySQL 服务,需要运行以下命令: sudo systemctl start mysql 要停止 …

    MySQL 2023年5月19日
    00
  • 从MySQL 5.5迁移到Mariadb 10.1.14所遇到的问题

    从MySQL 5.5迁移到MariaDB 10.1.14的过程需要注意以下问题: 1. 备份数据 在进行迁移之前,首先要确保数据库中的数据都被备份了。可以使用mysqldump来备份,示例如下: sudo mysqldump -u root -p –all-databases > backup.sql 2. 安装MariaDB 在Ubuntu系统中,…

    MySQL 2023年5月18日
    00
  • mysql 事务未提交导致死锁 Lock wait timeout exceeded; try restarting transaction 解决办法

    锁表问题提示:Lock wait timeout exceeded; try restarting transaction 解决锁表方法 查询数据库阻塞的进程SELECT * FROM information_schema.innodb_trx主要看箭头指向的这几个字段,如果有阻塞数据(不为0的就是阻塞的),找到后在根据下图这个字段:try_mysql_th…

    MySQL 2023年4月12日
    00
  • mysql如何优化插入记录速度

    当我们需要快速插入大量数据时,如何优化MySQL插入记录的速度是一个常见的问题。以下是一些可能有帮助的优化策略: 批量插入 单个插入操作可能会使磁盘高速缓存失效,导致插入速度变慢。批量插入可以减少这种情况的发生,并提高插入速度。 示例: INSERT INTO table_name (column1, column2) VALUES (value1, val…

    MySQL 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部