MySQL常用索引,数据结构,聚簇/非聚簇(Deprecated)

本文深入解析MySQL中的各类索引,包括主键索引、唯一索引、普通索引、全文索引、组合索引和前缀索引。探讨了B-Tree、B+Tree作为索引的数据结构优缺点,以及聚簇索引与非聚簇索引在MyISAM和InnoDB存储引擎中的应用。并分析了不同索引类型的适用场景。

MySQL常见索引类型:主键索引、唯一索引、普通索引、全文索引、组合索引(联合索引,多列索引) 

主键索引

ALTER TABLE `table_name` ADD PRIMARY KEY key_name(`filed_name`);

具有唯一性和自增长性,查询效率最快

唯一索引

ALTER TABLE `table_name` ADD UNIQUE key_name(`filed_name`);

索引列的值必须唯一,但允许有空值。

普通索引

 ALTER TABLE `table_name` ADD INDEX key_name(`filed_name`)

在查询中经常出现的列,特别百万级别或千万级别的数据量,使用普通索引会有特别显著的效果

组合索引

 ALTER TABLE `table_name` ADD INDEX / KEY key_name(列名1,列名2,列名3)

在where查询的多个字段上建立。

组合索引遵循最左匹配原则,即`列名1`必须出现在 where 条件中,才会使用到该索引

 前缀索引

 ALTER TABLE `table_name` ADD INDEX key_name(`filed_name`(length))

全文索引(MyISAM和InnoDB中都支持)

ALTER TABLE 表名  ADD FULLTEXT(列名)

对文本对于大容量的数据表,生成全文索引是一个非常消耗时间非常消耗硬盘空间的做法


索引使用的数据结构优缺点对比:

需要明白的两个常识:

1. 索引的使用,是为了提高查询速度。相比于在内存中数据的查找,读取数据时执行磁盘IO操作非常的耗时,所以适合作为索引的数据结构应是尽可能少的执行磁盘IO操作

2. 依据局部性原理进而实现的磁盘预读

当访问磁盘中一个地址数据的时候,与其相邻的数据很快也会被访问到。为提高数据读取的效率,磁盘会预读该地址附近的数据。

B-Tree作为索引:

该数据结构的特点:

1. 每个结点中的值的个数(n)满足: 1 <= n < m(B树的阶)

2. 所有的叶子结点都位于同一层

3. 每层结点中的值都是升序排列,每个值的左子树中的所有的值都小于它,而右子树中的所有的值都大于它

优点:

B-Tree中每个节点可以存储多个关键字,与平衡树来讲,它的一次磁盘I/O可以读取到更多的关键字,且降低了树的深度

B+Tree更适合作为索引:

特点:具有B-Tree树的所有特点,且

1. 除叶子节点外,每个元素不保存数据,只用来索引,所有数据都保存在叶子节点

2. 所有的中间结点元素都同时存在于子节点,他们在子节点元素中是最大(或最小)元素

3. 所有的叶子结点中包含了全部元素的信息,且叶子结点按关键字的排列顺序形成链表

优点:

1. 从磁盘读取角度来讲:在非叶子节点中,由于不保存数据,所以可以容纳更多的关键字,相比于B-Tree,磁盘读取一页关键字数据增加,进而减少了磁盘的I/O次数,且再次降低了树的高度

2. 形成链表的叶子节点方便全局或范围查找

b树b+树图文参考:经典搜索算法之B树与B+树_b+树和b树的搜索速度_超级战斗王的博客-优快云博客

从磁盘I/O角度来讲索引的数据结构:https://www.playscala.cn/article/view?_id=10-5d318144eeab561d2405e2de      https://www.cnblogs.com/aspirant/p/9214485.html


不同索引的区别与适用场景:

B+TREE:

1. 范围查找

2. 多级索引查找范围数据

HASH索引适用场景:

Hash 索引比较的是进行 Hash 运算之后的 Hash 值,所以它适用于等值查找。MySQL中使用Hash索引作为数据结构的存储引擎只有Memory。

索引的缺点:

  1. 虽然索引大大提高了查询速度,同时却会降低更新表的速度;  如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要更新索引文件
  2. 建立索引会占用磁盘空间

MySQL下的聚簇索引与非聚簇索引:

在《数据库原理》一书中解释到:
聚簇索引的叶子节点就是数据节点,而非聚簇索引的叶子节点仍然是索引节点,只不过有指向对应数据块的指针。

MyISAM的非聚簇索引结构:

MyISAM是按列值与行号来组织索引的。它的叶子节点中保存的实际上是指向存放数据的物理块的指针。

MyISAM存储引擎的索引文件(.MYI)和数据文件(.MYD)是相互独立的,所以一二级索引基本没多大区别。

InnoDB的聚簇索引结构:

聚簇索引:

InnoDB下,每一个表都有一个聚簇索引,它要么是主键,要么是拥有唯一索引(unique)的列,要么是自动产生的隐式的聚簇索引列。InnoDB 使用它存储表中每一行的数据。

如何加快查询速度:因为通过聚簇索引搜索,会直接指向包含该数据的数据页。

非聚簇索引:

通常也称之为  二级索引  ( Secondary Indexes ) 或 「 辅助索引 」 ,一般是指聚簇索引之外的所有其它索引。

两者区别:

1.  InnoDB 会使用聚簇索引来存数据和索引数据,而非聚簇索引的目的仅仅是加快查询速度

2. InnoDB下的表,有且只有一个聚簇索引,非聚簇索引由用户添加

3. 非聚簇索引一定包含聚簇索引,因此,使用二级索引时,会先找到主键值,再通过主键的聚簇索引查找相应的数据。

MySQL下的聚簇与非聚簇索引介绍:MYSQL索引:对聚簇索引和非聚簇索引的认识_alexdamiao的博客-优快云博客

<think>嗯,用户询问的是MySQL 5.7迁移到8.0的兼容性处理,这属于数据库升级的典型问题。用户应该是个系统管理员或开发者,正在规划数据库迁移,需要规避版本升级带来的风险。 从引用内容看,核心痛点集中在三个层面:一是新版本的密码认证机制变更(caching_sha2_password),二是保留关键字冲突(比如MySQL 8将"rank"设为保留字),三是字符集默认值变化(utf8mb4_0900_ai_ci)。这些在MySQL官方文档的"Upgrading from MySQL 5.7 to 8.0"章节都有明确警示。 用户可能没意识到的是隐性问题——比如存储过程使用GROUP BY子句时,MySQL 8默认开启ONLY_FULL_GROUP_BY模式,这和5.7的宽松模式行为不同。这个细节在引用里没提,但实际迁移中经常引发故障,需要补充说明。 迁移方案设计上,采用"测试环境验证->正式迁移"的双阶段策略更稳妥。尤其要强调备份的重要性,引用[2]提到恢复时间可能很长,这点需要特别提醒用户预留时间窗口。对于触发器迁移这类特殊场景,引用[3]的案例很有参考价值,可以单独作为优化建议。 兼容性检查工具推荐mysql-shell的util.checkForServerUpgrade(),比手动检查更高效。这个工具能直接检测出废弃特性使用情况,比如用户若用了removed的ENCODE()函数就会报警。 最后生成的延伸问题要覆盖用户后续可能的需求:性能优化针对的是迁移后的调优,架构设计则预防未来版本升级风险——毕竟从8.0到9.0可能又会有新兼容问题。</think>将MySQL 5.7的数据迁移到MySQL 8.0并确保兼容性,需按以下关键步骤处理: --- ### **一、迁移前兼容性检查** 1. **使用官方工具检测** 运行MySQL 8.0提供的升级检查工具: ```bash mysqlsh -u root -p -- util checkForServerUpgrade root@localhost:3307 --target-version=8.0.0 --output-format=JSON ``` * 自动扫描不兼容的语法(如已移除的函数`ENCODE()`)、废弃配置项等[^1][^2]。 2. **重点检查项** - **保留关键字冲突**:如`RANK`、`GROUPS`在MySQL 8.0成为保留字,需修改包含这些字段名的表结构[^3]。 - **默认字符集变更**:MySQL 8.0默认使用`utf8mb4`和`utf8mb4_0900_ai_ci`排序规则,需确认是否影响现有数据排序逻辑[^2]。 - **SQL模式差异**:检查`sql_mode`参数,确保`ONLY_FULL_GROUP_BY`等严格模式不会阻断查询。 --- ### **二、数据迁移步骤** #### **方法1:逻辑备份与恢复(推荐)** ```bash # 1. 从MySQL 5.7导出数据 mysqldump -u root -p --all-databases --routines --triggers --events > full_backup.sql # 2. 修改备份文件中的关键字冲突(如将`rank`改为`rank_col`) sed -i 's/`rank`/`rank_col`/g' full_backup.sql # 3. 在MySQL 8.0中恢复 mysql -u root -p < full_backup.sql ``` #### **方法2:物理文件迁移(InnoDB引擎)** 1. 关闭MySQL 5.7,复制数据目录(`/var/lib/mysql`)到新服务器。 2. 在MySQL 8.0中启动并执行升级: ```bash mysqld_safe --upgrade=FORCE ``` * **注意**:需确保文件系统兼容性,且版本跨度需在GA版本内[^2]。 --- ### **三、关键兼容性处理** 1. **密码认证插件更新** MySQL 8.0默认使用`caching_sha2_password`,若客户端不支持需回退: ```sql ALTER USER 'user'@'host' IDENTIFIED WITH mysql_native_password BY 'password'; ``` 2. **触发器与存储过程** - 检查触发器是否使用保留字(如引用[3]中通过临时表解决`RANK`冲突)。 - 验证存储过程语法(如`GROUP BY`的严格模式兼容性)。 3. **配置参数调整** - 关闭`innodb_undo_log_encrypt`(若5.7未启用加密)。 - 更新`group_replication`相关参数(若使用集群)。 --- ### **四、迁移后验证** 1. **数据一致性校验** 使用`pt-table-checksum`对比源库和目标库的数据差异。 2. **应用测试** - 模拟真实负载测试查询性能。 - 检查日志中是否有`deprecated`或`removed`特性的警告。 > **重要提醒**:**务必先在测试环境验证**,并备份生产数据。大型数据库的恢复时间可能远超预期[^2]。 --- ### **相关问题** 1. **如何解决MySQL 8.0的`caching_sha2_password`导致的应用连接失败?** > *需修改用户认证插件或升级客户端驱动。* 2. **迁移后出现`ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY`该如何处理?** > *调整`sql_mode`移除`ONLY_FULL_GROUP_BY`或重写SQL语句。* 3. **从MySQL 5.7迁移到8.0的性能下降可能由哪些原因引起?** > *常见于索引失效、统计信息未更新或优化器策略变化。* 4. **如何安全回滚失败的MySQL 8.0迁移?** > *利用备份快速还原至MySQL 5.7环境,需提前规划回滚窗口。* [^1]: 通过丰富的检查项,保证了迁移任务的稳定性及和数据的一致性。MySQL 8.0 与 MySQL 5.7 存在一定的不兼容性,如果出现对数据迁移有影响检查项,则会在详情里进行说明来帮助我们进行处理。 [^2]: MySQL 5.7的备份恢复到MySQL 8.0。这些步骤通常可以让您从MySQL 5.7顺利迁移到MySQL 8.0。然而,在迁移之前,请注意以下几点:版本兼容性、字符集和排序规则、新的认证机制、备份和恢复时间。 [^3]: 使用触发器处理自管理 MySQL 5.7 到 MySQL 8 的迁移。将 MySQL 数据库从 5.7 版迁移到 8.0 版可能会带来意想不到的挑战,尤其是当 5.7 版中有效的列名在 MySQL 8 中成为保留关键字时。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值