MySQL学习笔记:索引和数据库设计

索引

数据库的索引,可以理解成字典的目录,是为了方便数据库快速查询数据用的。

为什么创建索引,查询速度会更快?创建索引的过程,是创建数据结构,提高查询速度。举个例子,如果学生表有100万条输入,如下:

student_id student_name
1 张三
2 李四
... ...
1,000,000 王二麻子
假如我要查询student_name为王二麻子的记录,则数据库需要遍历所有行,即全表查询,最坏情况下要查询100万次才能找到我需要的数据,这样查询速度会很慢。

如果创建索引,数据库根据引擎的不同,会通过B+tree(MySQL innnoDB默认)、哈希表等数据结构的方式构建索引。比如用B+tree,要查询student_name为王二麻子的记录,只需要几次就可以查到。

有哪几种索引?

索引类型有主键索引(PRIMARY KEY)、唯一索引(UNIQUE)、普通索引(KEY/VALUE)、全文索引(FULLTEXT)。

  1. 主键索引(PRIMARY KEY):特殊的唯一索引,一张表只有一个。
  2. 唯一索引(UNIQUE):索引列值必须唯一。
  3. 普通索引(KEY/VALUE):最常用的索引,没有约束。
  4. 全文索引(FULLTEXT):用于全文搜索,适用于文本列(TEXT类长文本)。

当我们在建表时定义好主键,MySQL会自动为主键列创建一个名为PRIMARY的唯一索引;

当我们在创建唯一约束时(约束列的值必须是唯一的),MySQL会自动为该列创建一个唯一索引;

当我们在创建外键约束是(约束列的值必须在被引用的表中存在),MySQL会自动为外键列创建索引(假如还没有索引的话),这是为了确保在更新或删除父表(被引用的表)中的行时,能够快速检查子表(引用表)中是否存在对应的行,从而提高检查的效率。

当然,最常见的是我们自己自定义创建索引,以提高查询效率。

创建索引的目的是为了提高速度,但是创建索引需要额外的资源开销,更新索引也需要时间,因此,创建索引有以下注意事项:

  1. 数据表记录比较少,不建议创建索引,因为哪怕是遍历查询也很快
  2. 经常更新的列谨慎创建索引,因为每次更新都需要去更新数据结构,需要消耗计算资源

数据库设计

数据库设计是指设计满足业务需求的数据库表,数据库设计的流程一般是:

  1. 分析业务需求:根据产品原型、产品文档,分析业务所需要存取的数据
  2. 数据库概要设计:设计需要创建的数据库、表、字段,绘制数据表关系图
  3. 创建数据库表:一般通过可视化工具,创建数据库表和字段

为了减少数据冗余、提高数据一致性、避免数据更新异常,数据库设计有三大范式,通常建议数据库设计时遵守。

  1. 第一范式:确保每一列的原子性。第一范式要求每一列都是不可再分的最小单元。比如某列字段名为学院办公室,存储示例"科技楼102室"。则可以拆分成字段:楼栋("科技楼")、办公室("102室")
  2. 第二范式:前提必须满足第一范式。第二范式规定数据表中所有非主键必须完全依赖于整个主键,而不能只依赖于主键的一部分。这个范式适用于主键由多个字段组成的情况。如果一个字段只能由部分主键就能决定,则需要拆表。
  3. 第三范式:前提必须满足第一范式和第二范式。任何非主键字段之间不能有依赖关系,即非主键字段必须直接依赖于主键,而不能通过其他非主键字段间接依赖。

在实际开发过程中,往往需要考虑到满足业务需求的数据存取性能,会违反三大范式。比如:一个学生表和班级表,两者通过class_id做关联,正常设计表如下:

student_id student_name class_id
1 张三 NULL
2 李四 1
3 王五 2
4 赵六 2
class_id class_name
1 1班
2 2班
3 3班

正常情况下,如果要查询学生的所在班级,要通过两个表联表查询。如果业务需求要频繁操作,在数据量比较大时候,可以创建索引提高查询速度。另外,也可以将class_name存储到学生表,这样避免了联表查询操作。显然,这违反了三大范式,这是一种以空间换时间的反范式设计。

student_id student_name class_id class_name
1 张三 NULL NULL
2 李四 1 1班
3 王五 2 2班
4 赵六 2 2班
相关推荐
洛豳枭薰15 小时前
Innodb一次更新动作
mysql
Σίσυφος190015 小时前
PCL法向量估计 之 方向约束法向量(Orientation Guided Normal)
数据库
老毛肚15 小时前
手写mybatis
java·数据库·mybatis
海山数据库15 小时前
移动云大云海山数据库(He3DB)postgresql_anonymizer插件原理介绍与安装
数据库·he3db·大云海山数据库·移动云数据库
云飞云共享云桌面15 小时前
高性能图形工作站的资源如何共享给10个SolidWorks研发设计用
linux·运维·服务器·前端·网络·数据库·人工智能
2501_9279935315 小时前
SQL Server 2022安装详细教程(图文详解,非常详细)
数据库·sqlserver
星火s漫天15 小时前
第一篇: 使用Docker部署flask项目(Flask + DB 容器化)
数据库·docker·flask
xcLeigh15 小时前
Python 项目实战:用 Flask 实现 MySQL 数据库增删改查 API
数据库·python·mysql·flask·教程·python3
威迪斯特15 小时前
Flask:轻量级Web框架的技术本质与工程实践
前端·数据库·后端·python·flask·开发框架·核心架构
xu_yule15 小时前
Redis存储(15)Redis的应用_分布式锁_Lua脚本/Redlock算法
数据库·redis·分布式