技能目标:
了解什么是索引
了解索引的作用和分类
了解什么是事务
了解事务的 ACID 原则
前言
在当今数据驱动的时代,数据库的高效与可靠性是业务系统的核心支柱。索
引和事务作为数据库两大基石,直接影响着数据查询性能与操作安全性。本课程
将带您深入理解索引的本质与分类,揭秘其如何加速数据检索:同时剖析事务的
ACID原则,掌握其保障数据一致性与完整性的底层逻辑。
一 MySQL 索引介绍
索引是一个排序的列表,在这个列表中存储着索引的值和包含这个值的数据
所在行的物理地址。在数据十分庞大的时候,索引可以大大加快查询的速度。这
是因为使用索引后可以不用扫描全表来定位某行的数据,而是先通过索引表找到
该行数据对应的物理地址然后访问相应的数据。索引的作用类似于图书的目录,
可以根据目录中的页码快速找到所需的内容。
1.索引概述
当数据保存在磁盘类存储介质上时,它是作为数据块存放。这些数据块是被
当作一个整体来访问的,这样可以保证操作的原子性。硬盘数据块存储结构类似
于链表,都包含数据部分,以及一个指向下一个节点(或数据块)的指针,不需
要连续存储。
2.索引作用
在索引列上,除了上面提到的有序查找之外,数据库利用各种各样的快速定
位技术,能够大大提高查询效率。特别是当数据量非常大,查询涉及多个表时,
使用索引往往能使查询速度加快成千上万倍。
例如,有3个未索引的表t1、t2、t3,分别只包含列c1、c2、c3,每个
表分别含有1000行数据组成,均为1~1000的数值,查找对应值相等行的查询
如下所示
sql>SELECT c1,c2,c3 FROM t1,t2,t3 WHERE c1=c2 AND c1=c3;
在此情形下,仍然对表t1执行了一个完全扫描,但能够在表t2和t3上
进行索引查找直接取出这些表中的行,比未用索引时要快一百万倍。
利用索引,MySQL加速了ERE子句满足条件行的搜素,而在多表连接查
询时、在执行连接时加快了与其他表中的行匹配的速度。
3.索引的分类
在数据库表中,对字段建立索引可以大大提高查询速度。通过善用这些索引,
可以令MySQL的查询和运行更加高效。索引是快速搜索的关键。MySQL索的
建立对于MySQL的高效运行是非常重要的。下面介绍几种常见的MySQL.索引类
从物理存储的角度来划分,索引分为聚簇索引和非聚族索引两种,聚簇索引
是按照数据存放的物理位置为顺序的,而非聚簇索引就不一样了:聚簇索引能提
高多行检索的速度,而非聚簇索引对于单行的检索更快。
从逻辑的角度来划分,索引分为普通索引、唯一索引、主键索引、组合索引
和全文索引。这些索引分类的具体解释如下所示。
创建库
mysql> create database a;
切换库
mysql> use a
先创建表名
mysql> create table aa(id int,name varchar(50));
3.1普通索引
普通索引是最基本的索引,它没有任何限制,也是大多数情况下用到的索引。它
有以下几种创建方式。
直接创建索引:
mysql> create index aaa on aa(name(50));
修改表结构的方式添加索引:
mysql> alter table aa add index bbb(name(50));
3.2 唯一索引
唯一索引与普通索引类似,不同的就是:唯一索引的索引列的值必须唯一,但允许有空值(注意和主键不同)。如果是组合索引,则列值的组合必须唯一。 索引创建方法和普通索引类似。修改表结构的时候添加唯一索引:
创建唯一索引:
mysql> create unique index aa on aa(name(50));
修改表结构的时候添加唯一索引:
mysql> alter table aa add unique ddd(name(50));
3.3主键索引
主键索引是一种特殊的唯一索引,一个表只能有一个主键,,不允许有空值。
一般是在建表的时候同时创建主键索引。
3.4组合索引(最左前缀)
平时用的 SQL查询语句一般都有比较多的限制条件,所以为了进一步榨取
MyS0L的效率,就要考虑建立组合索引。在组合索引的创建中,有两种场景,即
为单列索引和多列索引。下面通过一个场景来具体说明单列索引和多列索引。
在一个user用户表中,有name,age,sex三个字段,分别分三次建立了
INDEX普通索引。那么在select*fromuserwherenameANDae
ANDsex=”;数据查询语句中就会分别检索三条索引,虽然扫描效率有所提升,
但却还未达到最优。这个时候就需要使用到组合索引(即多列索引)。
在MySQL中,有一个知识点叫最左原则。下面的select语句的where条件是
依次从左往右执行的。
mysql> select * from aa where name ='' and id =''and name ='';
若使用的是组合索引indexuser(name,age,sex)。在查询中,name、age、
sex 的顺序必须如组合索引中一致排序,否则索引将不会生效,例如:
mysql> select * from aa where age ='' and name =''and name ='';
如果采用“select*fron user where age=”AND name=AND sex=
”;”查询方式,这条组合索引将无效化,所以一般在建立索引时,要先想好相
应的查询业务,尽量避免虽然有索引,但是使用不上的问题。
5.全文索引(FULLTEXT)
MyS9L从3.23.23版开始支持全文索引和全文检索。在
MyS0L5.6版本以前FULLTEXT索引仅可用于MyISAM表,在5.6之后innodb引
擎也支持FULLTEXT索引:他们可以从CHAR、VARCHAR或TEXT列中作为
CREATETABLE语句的一部分被创建,或是随后使用 ALTERTABLE或
CREATEINDEX 被添加。
修改表结构添加全文索引:
mysql> alter table aa add fulltext hhh(name(50));
直接创建索引:
mysql> create fulltext index yyy on aa(name(50));
3..4 创建索引的原则依据
数据库建立索引的原则:
确定针对该表的操作是大量的查询操作还是大量的增删改操作
尝试建立索引来帮助特定的查询。检查自己的sq1语句,为那些频繁在
where 子句中出现的字段建立索引:
尝试建立复合索引来进一步提高系统性能。修改复合索引将消耗更长时间
同时复合索引也占磁盘空间:
对于小型的表,建立索引可能会影响性能;
应该避免对具有较少值的字段进行索引;
避免选择大型数据类型的列作为索引。
索引建立的原则:
索引查询是数据库中重要的记录查询方法,要不要建立索引以及在那些字段
上建立索引都要和实际数据库系统的查询要求结合来考虑,下面给出实际生产环
境中的一些通用的原则:
在经常用作过滤器的字段上建立索引:
在S9L语句中经常进行GROUPBY、ORDERBY的字段上建立索引:
在不同值较少的字段上不必要建立索引,如性别字段;
对于经常存取的列避免建立索引:
用于联接的列(主健/外健)上建立索引:
在经常存取的多个列上建立复合索引,但要注意复合索引的建立顺序要按照
使用的频度来确定:
缺省情况下建立的是非簇集索引,但在以下情况下最好考虑簇集索引,如:
含有限数目(不是很少)唯一的列;进行大范围的查询;充分的利用索引可以减
少表扫描1/0的次数,有效的避免对整表的搜索。当然合理的索引要建立在对
各种查询的分析和预测中,也取决于 DBA所设计的数据库结构。
3.5 查看索引
MySQL数据表索引已经创建好了,那么如何才能查看刚刚创建的索引?或者
怎么去查看表内已经存在的索引?有以下两种查看当前索引的方式。
mysql>show index from tablename;
mysql>show keys from tablename;
以renyuan表为例,查看 renyuan表的索引内容。
mysql> show index from renyuan\G
3.6 删除索引
索引在创建之后,是会占用一定的磁盘空间的,因此表内如果有不再使用的索引,
从数据库性能方面考虑,最好是删除无用索引。索引的删除有如下两种方法。
添加索引
mysql> create index name_index on employee(name);
mysql>alter table renyuan add index age_index(age);
删除索引
mysql>drop index name_index on employee;
二 MySQL 事务
MyS0L.事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理
系统中,要删除一个人员,即需要删除人员的基本资料,又需要删除和该人员相
关的信息,如信箱,文章等等。这样,这些数据库操作语句就构成一个事务!
在MyS9L中只有使用了Innodb数据库引擎的数据库或表才支持事务。
事务处理可以用来维护数据库的完整性,保证成批的50L语句要么全部执行,
要么全部执行
事务务用来管理 insert,update,delete 语句
一般来说,事务是必须满足4个条件(ACID):原子性、一致性、隔离性 持久性
原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部
不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚
(Ro11back)到事务开始前的状态,就像这个事务从来没有执行过一样;
一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这
表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以
及后续数据库可以自发性地完成预定的工作:
隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔
离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离
分为不同级别,包括读未提交(Readuncomitted)、读提交(readcommitted)、
可重复读(repeatable read)和串行化(Serializable);
持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
在MySQL命令行的默认设置下,事务都是自动提交的,即执行S0L语句后
就会马上执行COMMIT操作。因此要显式地开启一个事务必须使用命令BEGIN
或STARTTRANSACTION,或者执行命令SETAUTOCOMMIT=0,用来禁止使用当前
会话的自动提交。
事务控制语句包含:
BEGIN 或STARTTRANSACTION:显式地开启一个事务;
COMIT:也可以使用COMMITWORK,不过二者是等价的。COMIT会提交事
务,并使己对数据库进行的所有修改变为永久性的:
ROLLBACK:又可以使用ROLLBACKWORK,不过二者是等价的。回滚会结束用
户的事务,并撤销正在进行的所有未提交的修改:
SAVEPOINTidentifier:SAVEPOINT允许在事务中创建一个保存点,一个事
务中可以有多个 SAVEPOINT:
RELEASESAVEPOINTidentifier:删除一个事务的保存点,当没有指定的保
存点时,执行该语句会抛出一个异常:
ROLLBACKTOidentifier:把事务回滚到标记点;
SETTRANSACTION:用来设置事务的隔离级别。InnoDB存储引擎提供事务的
隔离级别READUNCONBITTED、READCODITTED、REPEATABLEREAD和
SERIALIZABLE。
MYSQL 事务处理主要有两种方法:
(1)用 BEGIN,ROLLBACK,COMMIT 来实现
GIN 开始一个事务
ROLLBACK 事务回滚
COMMIT_事务确认
(2)直接用 SET来改变 MySQL的自动提交模式
SET AUTOCOMMIT=O 禁止自动提交
SET AUTOCOMMIT=1 开启自动提交
mysql>use kgc;
mysql>CREATETABLEkgc-transactiontest(id int(5))engine=innodb; //创建数据表
mysql>select * from kgc_transaction_test;
mysql>begin; //开始事务
mysql>insert into kgc_transaction_test value(1);
mysql>insert into kgc_transaction_test value(2);
mysql>commit;//提交事务
mysql>select * from kgc_transaction_tes;
mysql>begin; //开始事务
mysql>insert into kgc_transaction_test values(3);
mysql>rol1back; //回滚
mysql>select*fromkge_transaction_test; //因为回滚所以数据没有插入
总结
通过本课程,您己系统掌握索引的核心价值一一提升查询效率,并理解唯一
索引、组合索引等分类的适用场景;同时,深入事务的ACID特性(原子性、
致性、隔离性、持久性),明晰其对复杂操作中数据安全的保障机制。未来可结
合索引优化策略与事务隔离级别实践,进一步解决高并发、大数据量下的性能与
一致性问题,真正将理论转化为提升数据库效能的实战能力