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班
相关推荐
小陈工2 小时前
Python Web开发入门(十七):Vue.js与Python后端集成——让前后端真正“握手言和“
开发语言·前端·javascript·数据库·vue.js·人工智能·python
0xDevNull7 小时前
MySQL数据冷热分离详解
后端·mysql
AI成长日志7 小时前
【Agentic RL】1.1 什么是Agentic RL:从传统RL到智能体学习
人工智能·学习·算法
科技小花7 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸7 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain7 小时前
linux个人心得22 (mysql)
数据库·mysql
_李小白7 小时前
【OSG学习笔记】Day 38: TextureVisitor(纹理访问器)
android·笔记·学习
阿里小阿希8 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神8 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员8 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全