
🎁个人主页:User_芊芊君子
🎉欢迎大家点赞👍评论📝收藏⭐文章
🔍系列专栏:MySQL


文章目录:
- 一、索引
-
- 1.索引应该选择哪种数据结构
-
- [1.1 顺序表](#1.1 顺序表)
- [1.2 HASH(不合适)](#1.2 HASH(不合适))
- [1.3 二叉搜索树](#1.3 二叉搜索树)
- [1.4 B+树(N叉搜索树)](#1.4 B+树(N叉搜索树))
- [2 MySQL中的页](#2 MySQL中的页)
- 3.三层B+树能存储多少数据
- 4.索引分类
-
- [4.1 主键索引](#4.1 主键索引)
- [4.2 普通索引](#4.2 普通索引)
- [4.3 唯一索引](#4.3 唯一索引)
- [4.4 全文索引](#4.4 全文索引)
- [4.4 聚簇索引](#4.4 聚簇索引)
- [4.5 非聚簇索引](#4.5 非聚簇索引)
- [4.6 索引覆盖](#4.6 索引覆盖)
- 5.使用索引
-
- [5.1 自动创建](#5.1 自动创建)
- [5.2 手动创建主键索引](#5.2 手动创建主键索引)
- [5.3 单个列索引失效问题](#5.3 单个列索引失效问题)
- 6.复合索引(少,失效问题)
- 二、事务
-
- 1.什么是事务
- 2.事务的四个==核心特性==
-
- [2.1 原子性](#2.1 原子性)
- [2.2 一致性](#2.2 一致性)
- [2.3 持久性](#2.3 持久性)
- [2.4 隔离性](#2.4 隔离性)
- [2.5 隔离级别](#2.5 隔离级别)
- 3.语法
- [4. 保存点](#4. 保存点)
- 三、视图
- 四、JDBC
-
- 1.JDBC是什么
- 2.使用JDBC
-
- [(1) 创建数据源](#(1) 创建数据源)
- [(2) 和数据库服务器建立联系](#(2) 和数据库服务器建立联系)
- [(3) mysql认识SQL语句,要想Java操作数据库,本质上让Java代码构造出一个sql语句字符串发给数据库服务器](#(3) mysql认识SQL语句,要想Java操作数据库,本质上让Java代码构造出一个sql语句字符串发给数据库服务器)
- (4)把语句发送给服务器去执行,n表示影响了几行
- [(5) 代码中要释放的资源,释放顺序和创建顺序相反](#(5) 代码中要释放的资源,释放顺序和创建顺序相反)
- 五、总结
【前言】
作为 Java 开发与数据库面试的高频考点,MySQL 的索引、事务、视图和 JDBC 既是日常开发的核心基础,也是面试中的必考题。很多同学学习时容易陷入 "只会用不懂原理" 的误区:为什么 MySQL 索引用 B + 树而非哈希?事务隔离级别到底解决了什么问题?JDBC 操作时的资源释放顺序有什么讲究?这篇博客将从底层原理出发,带你系统梳理索引的数据结构选型、分类与失效场景,事务的 ACID 特性与隔离级别,视图的创建、修改限制,以及 JDBC 的完整交互流程,帮你搭建完整的 MySQL 知识体系,既能应对面试,也能解决开发中的实际问题。
一、索引
索引是数据库中重要的数据结构,作用能够加快查询进度,但需要消耗额外的存储空间(小问题),再插入/删除/修改的时候也可能有额外开销
1.索引应该选择哪种数据结构
1.1 顺序表
"随机访问"效率高O(1),但不是查询
- 查询:按照"值"查找;
- "随机访问":按照下标查找
1.2 HASH(不合适)
时间复杂度为O(1) ,查询速度非常快,但是MySQL并没有选择HASH做为索引的默认数据结构,主要原因是HASH不支持范围查找
- 哈希冲突==》链表;
- 通过扩容,控制链表长度;
- 只能相等查询,无法范围查询
1.3 二叉搜索树
⼆叉搜索树的中序遍历是⼀个有序数组,but:
元素数目多,高度变高,比较次数就增加了(数据库中,多进行一次比较,就是多读一次硬盘)
AVL数:平衡要求高,增删改时需要频繁调整
红黑树:O(log(N)),范围有限;增删改相比AVL数好点
1.4 B+树(N叉搜索树)
- 一个节点中包含N个值,划分出N个区间。每个节点的最后一个值就是当前树的最大值。
- 每个父亲节点的值在字节点中再次出现。最终B+的叶子节点这一层,包含了整个数据集合的全集。
- 把所有叶子节点使用双向链表的方式连接起来;
- 叶子节点上保存数据行,非叶子节点只存储索引列

优势
- N叉搜索树,整体高度比较低;
- 查询性能稳定;
- 擅长范围查询;
- 非叶子节点适合缓存在内存中
2 MySQL中的页
- B+树上面的节点,在MySQL内部被称为页;
- 索引页(非叶子节点)只存储索引列;
- 数据页(叶子节点)存储数据行;
- MySQL统一页的大小16KB(可通过配置修改);
- MySQL进行和硬盘的交互的读写操作,都是以页为单位进行的;(局部性原理)(eg:一次读取一页,此时读取到若干个相邻的数据,有效降低访问硬盘次数)
数据库的表==》ibd 文件,以硬盘文件体现


3.三层B+树能存储多少数据
- 在表中,主键使用8个字节的数据;
- 假设每个页的编号使用6个字节;
- 一个索引行就是14个字节(主键ID+子节点页编号)
- 整个页16KB,忽略页头页尾,假设16KB全存的索引行,16*1024/14==1170(一个索引页的索引行数);
- 假设每个数据行1KB,一个页有16条数据行,1170 * 1170 * 16==21902400(2KW)
4.索引分类
4.1 主键索引
创建表时,根据主键建立的索引
4.2 普通索引
最基本的索引类型,没有唯⼀性的限制。通过创建索引的sql语句创建
4.3 唯一索引
当在⼀个表上定义⼀个唯⼀键UNQUE 时,自动创建唯⼀索引。
4.4 全文索引
基于文本列(CHAR、VARCHAR或TEXT列)上创建,以加快对这些列中包含的数据查询和DML操作;
⽤于全文搜索,仅MyISAM和InnoDB引擎⽀持。
4.4 聚簇索引
与主键索引是同义词
4.5 非聚簇索引
聚集索引以外的索引称为非聚集索引或⼆级索引;
的每条记录都包含该⾏的主键列;
InnoDB使⽤这个主键值来搜索聚集索引中的⾏,这个过程称为回表查询
4.6 索引覆盖
select 要查的内容,就已经包含在索引列中,不需要回表了
5.使用索引
5.1 自动创建
当我们为⼀张表加主键约束(Primarykey),外键约束(ForeignKey),唯⼀约束(Unique)时,MySQL会为对应的的列⾃动创建⼀个索引;
如果表不指定任何约束时,MySQL会⾃动为每⼀列⽣成⼀个索引并⽤ROW_ID进行标识
5.2 手动创建主键索引
sql
USE test;
DROP TABLE student;
CREATE TABLE student(id int PRIMARY KEY,name VARCHAR(20),class_id int,index(name));
CREATE TABLE student(id int PRIMARY KEY,name VARCHAR(20),class_id int);
ALTER TABLE student ADD INDEX(name);
CREATE INDEX index_student_name ON student(name);
SHOW INDEX FROM student;

5.3 单个列索引失效问题
- 查询操作,没有在查询条件中使用索引列;
sql
student(id,name,class_id);//id(主键索引);name(一般索引)
- 查询时使用的索引列的值比较单一,索引无法发挥作用(eg:gender==>男,女);
- 查询时,查询条件针对索引列进行了表达式运算,隐式类型转换;
- 查询条件包含了or,一个条件带有索引列,一个不带
- 字符串查询的时候涉及到 like,通配符不能放前面;
sql
select * from student where name like '张%';
- 针对索引列进行查询,但条件是 != 或 not;
- 多表联合查询,但表的字符集不一致
6.复合索引(少,失效问题)
一个表有a,b,c,d,e五个列,创建a,b,c为复合索引;
必须先通过a来创建索引进行查询,如果两个记录a 的值相同,再通过b创建一级索引进行查询,如果a和b的记录都相同,再通过c(优先级关系,最左前缀原则)
否则索引无法命中
MySQL提供explain关键字,可以查看是否命中索引
sql
esplain select * from student where id = 1;
type 为 all:遍历行,没有命中索引
二、事务
1.什么是事务
事务是把一组sql语句打包成一个整体,整体的sql要么全部执行完,要么一个都不执行(不是真的没执行,而是触发了回滚)避免执行一半的情况。
2.事务的四个核心特性
2.1 原子性
一个事务执行过程中,要么全部成功,要么全部失败,不会出现只执行一半的情况,如果发生错误,会触发回滚到事务开始前的状态。
2.2 一致性
数据正确,符合实际情况;
eg:你要从一张银行卡中转出一百到另一张银行卡,转出之后,当第二张银行卡到账时,这个时候才一张,符合规则
2.3 持久性
事务对数据做出的修改,能持久生效(写入硬盘)
2.4 隔离性
数据库允许多个并发事务同时进行,隔离性可防止由于交叉执行而导致数据的不一致事务可以指定不同的隔离级别以权衡在不同应用场景下数据库性能和安全。
- 脏读问题
事务一:对某个数据进行了修改,但还没有提交;
事务二:对这个数据进行读取;
这时,读到的就是"脏数据"
解决方法 :事务一没有提交,事务二读到的应该是修改前的数据 - 不可重复读
事务一执行过程中,两次读到这个数据的结果不一样(同一事务);
解决方法 :给读操作加锁,有事务在读的时候,其他事务不能进行操作
并发程度降低,但隔离性提高,效率降低,准确性提高 - 幻读
同一事务,针对某个查询,两次读到的结果集不同;
eg:第一次读到三条记录,第二次读到四条(前三条一样)
解决方法:进行串行化,一条一条处理事务
2.5 隔离级别
MySQL的隔离性提供了几个隔离级别,供人们选择。
READ UNCOMMITTED:读未提交;
隔离性最弱,并发性最强;最不准确,效率最高;脏读,不可重复读,幻读READ COMMITTED:读未提交;
隔离性提高了,并发性降低;准确性提高了,效率降低;脏读解决,不可重复读,幻读存在REPEATABLE READ:可重复读(默认);
隔离性提高了,并发性降低;准确性提高了,效率降低;脏读,不可重复读解决,幻读存在ERIALIZABLE:串行化; 隔离性最高,并发性最低;准确性最高,效率最低;脏读,不可重复读,幻读都解决了
可通过配置修改隔离级别
- 通过sql语句
查看
sql
SELECT @@GLOBAL.transaction_isolation;//默认可重复读
设置
sql
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
进行修改之后,除了当前这个窗口(一个数据库的网络连接)生效之外,后面再次连接数据库服务器窗口之后才能生效
- 通过配置文件(更可靠)
3.语法
sql
START/BEGIN ...;#开始
COMMIT;# 提交
ROLLBACK;#回滚
无论提交还是回滚,事务都会关闭
4. 保存点
设置保存点,名字自定义
sql
mysql> SAVEPOINT savepoint1;
回滚到某个保存点
sql
mysql> ROLLBACK TO savepoint2;
三、视图
1.什么是视图
视图=="虚拟的表",本身不占据硬盘的存储空间,而是把其他查询操作的结果集临时保存下来,组成一个类似于表达的结构
2.创建视图
sql
CREATE VIEW view_name AS select_statement;
- 把某个查询语句定义成视图,使用这个视图就相当于在执行这个查询语句;
- 使用视图查询相当于子查询;
- 修改真实的表,视图也会同步修改;
- 修改视图,真实的表也会被修改;
3.视图不能修改的情况
- 创建视图时,使用了聚合函数(把原始表的很多行构造成一行数据,修改的话无法定位。eg:修改几个数的平均数,无法定位到每一个数);
- 视图关联的查询中,带有去重查询;
- 视图关联的查询中,带有group by/having;
- 视图关联的查询中,带有union/union all;
- 视图关联的查询中,使用了子查询;
- 视图关联的查询中,使用了不可修改的视图
4.删除视图
sql
DROP VIEW view_name;
四、JDBC
1.JDBC是什么
JDBC是Java和数据库之间的桥梁,包含一套Java定义的用于执行SQL语句的接口,使开发者能够编写数据库的程序。作用:与数据库建立联系和处理数据库执行结果
JDBC使用过程可以概括为:
- 加载数据库⼚商的驱动包、
- 建立连接、
- 创建Statement、
- 执行SQL、
- 处理结果释放资源和关闭连接。
2.使用JDBC
Maven仓库:https://mvnrepository.com/
- 先下载这个jar包

- 创建一个目录lib(库)

- 将下载好的jar包复制到这个目录;
- 右键目录,==》add as Library

(1) 创建数据源
java
DataSource dataSource = new MysqlDataSource();//向上转型
((MysqlDataSource) dataSource).setUrl("jdbc:mysql://172.16.181.121:3306/j26.4.28?characterEncoding=utf8&useSSL=false");//向下转型
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("0000");
URL(唯一资源定位符,网址) :"jdbc:mysql://172.16.181.121:3306/j26.4.28?characterEncoding=utf8&useSSL=false"
由:协议名,IP地址,端口号,数据库名,参数(utf8字符集--与服务器匹配,useSSL=false--关闭加密协议)
(2) 和数据库服务器建立联系
java
Connection connection = dataSource.getConnection();
这里可能连接失败,需要处理一下受查异常 throws / try catch

(3) mysql认识SQL语句,要想Java操作数据库,本质上让Java代码构造出一个sql语句字符串发给数据库服务器
sql
String sql = "insert into student value(1,\"张三\")";
PreparedStatement statement = connection.prepareStatement(sql);//预处理,解析检查,然后再发给服务器
(4)把语句发送给服务器去执行,n表示影响了几行
sql
int n = statement.executeUpdate();
System.out.println("n= " + n);
(5) 代码中要释放的资源,释放顺序和创建顺序相反
java
statement.close();
connection.close();
五、总结
本篇内容我们完整梳理了 MySQL 与 JDBC 的核心知识:索引部分从底层数据结构对比入手,讲清了 B + 树的优势、索引分类与常见失效场景;事务部分拆解了 ACID 四大特性与隔离级别,帮你理解数据一致性的保障逻辑;视图部分梳理了定义、创建与修改限制,区分了视图与普通表的差异;JDBC 部分则还原了 Java 与数据库交互的完整流程,从连接创建到资源释放讲透了底层逻辑。这些知识点并非孤立:索引是性能优化的核心,事务是数据安全的保障,视图是数据访问的便捷工具,JDBC 则是 Java 与数据库交互的桥梁,掌握它们,既能帮你写出更高效、更安全的代码,也能为后续的数据库优化与框架学习打下坚实基础。

