MySQL表设计与优化

yizhihongxing

影响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日

相关文章

  • Docker安装MySQL并使用Navicat连接的操作方法

    下面将为您详细讲解Docker安装MySQL并使用Navicat连接的详细步骤: 1. 安装Docker 如已经安装过Docker可跳过此步骤。Docker可以在官方网站下载并安装,具体步骤如下: 1.1 在官网下载Docker Desktop,在Windows和Mac系统上都可以使用Docker Desktop,下载地址如下: https://www.do…

    MySQL 2023年5月18日
    00
  • 读《mysql是怎样运行的》有感

    最近读了一本书《mysql是怎样运行的》,读完后在大体上对mysql的运行有一定的了解。在以前,我对mysql有以下的为什么: InnoDB中的表空间、段、区和页是什么? redo log为什么就能实现事务的持久性? 到底什么是意向锁?意向锁有什么用? mysql中的外连接、内连接到底是什么? 事务中的一致性到底是什么意思?一致性和原子性有什么不一样? 现在…

    MySQL 2023年4月23日
    00
  • MySQL DATEDIFF() 函数

    定义和用法 DATEDIFF() 函数返回两个日期之间的天数。 语法 DATEDIFF(date1,date2) date1 和 date2 参数是合法的日期或日期/时间表达式。 注释:只有值的日期部分参与计算。 实例 例子 1 使用如下 SELECT 语句: SELECT DATEDIFF(‘2008-12-30′,’2008-12-29’) AS Dif…

    MySQL 2023年4月13日
    00
  • 使用Mysql5.x以上版本出现报错#1929 Incorrect datetime value: ”” for column ”createtime”的快速解决方法

    使用Mysql5.x以上版本出现报错#1929 Incorrect datetime value: ”” for column ”createtime”的快速解决方法 问题描述 在使用Mysql5.x以上版本时,有时候在插入或更新记录时,可能会出现以下报错: #1929 Incorrect datetime value: ”” for colum…

    MySQL 2023年5月18日
    00
  • 详解MySQL主从复制实战 – 基于GTID的复制

    详解MySQL主从复制实战 – 基于GTID的复制 简介 MySQL主从复制是MySQL数据库中常见的一种复制结构,可以实现数据的自动同步和备份。基于GTID的复制是一种相对较新且更稳定、更可靠的复制方式。本文将详细讲解基于GTID的MySQL主从复制实战过程。 环境准备 在进行MySQL主从复制之前,我们需要有两个MySQL实例,其中一个是主库,另一个是从…

    MySQL 2023年5月18日
    00
  • mysql出现“Incorrect key file for table”处理方法

    当MySQL出现”Incorrect key file for table”的错误时,通常是由于MySQL在执行操作时尝试使用索引文件,但文件可能已损坏或不完整所致。以下是处理此问题的完整攻略: 步骤一:检查MySQL日志 在处理任何MySQL错误之前,请始终先检查MySQL日志文件,以了解错误的来源。在一些情况下,MySQL日志可能会为我们提供建议或指导应…

    MySQL 2023年5月18日
    00
  • MySQL子查询详解

    子查询,也被称为嵌套查询,是在一个查询语句中嵌套另一个查询语句的查询。子查询可以作为主查询的查询条件,也可以用于在查询结果中过滤数据。 MySQL中的子查询有以下几个特点: 子查询必须包含在圆括号内。 子查询可以嵌套多层。 子查询可以返回单个值或多个值。 下面是一些常见的子查询例子: 1.查询学生成绩大于班级平均成绩的学生信息: SELECT id, nam…

    MySQL 2023年3月9日
    00
  • 修改Innodb的数据页大小以优化MySQL的方法

    修改Innodb的数据页大小可以通过优化MySQL的性能。以下是修改Innodb的数据页大小的完整攻略: 步骤一:备份MySQL数据库 在进行任何修改之前,先备份MySQL数据库并确保保存了原始配置文件的副本。 步骤二:确定Innodb缓冲池大小 首先需要确定Innodb缓冲池大小。您可以通过运行以下命令来确定当前的缓冲池大小: SHOW VARIABLES…

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