MySQL索引、事务

本文详细介绍了MySQL的索引概念、作用、创建原则及分类,强调了索引在优化查询速度和降低I/O成本上的价值,同时也指出不当使用索引的副作用。此外,还探讨了事务的基本概念、ACID特性、隔离级别及其在并发操作中的重要性。最后,对比分析了MyISAM和InnoDB存储引擎的特性和应用场景,为企业选择合适存储引擎提供了指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、MySQL 索引

1.1索引的概念

1.2 索引的作用

1.3创建索引的原则依据

1.4索引的分类和创建

二、mysql事物

2.1事物的概念

2.2事物的ACID特性

2.3事物的操作

2.4 事务控制语句

三、MySQL 存储引擎

1、什么是存储引擎

2、MyISAM存储引擎

2.1 MylSAM介绍

2.2 MylSAM的特点

2.3 MyISAM表支持3种不同的存储格式

2.4 MyISAM使用的生产场景举例

3、InnoDB存储引擎

3.1 InnoDB介绍

3.2 InnoDB的特点

3.2 InnoDB适用生产场景分析

3.3 MyISAM和InnoDB的区别:

企业选择存储引擎依据



一、MySQL 索引

1.1索引的概念

● 索引是一个排序的列表,在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址(类似于C语言的链表通过指针指向数据记录的内存地址)。
● 使用索引后可以不用扫描全表来定位某行的数据,而是先通过索引表找到该行数据对应的物理地址然后访问相应的数据,因此能加快数据库的查询速度。
● 索引就好比是一本书的目录,可以根据目录中的页码快速找到所需的内容。
● 索引是表中一列或者若干列值排序的方法。
● 建立索引的目的是加快对表中记录的查找或排序。

1.2 索引的作用

● 设置了合适的索引之后,数据库利用各种快速定位技术,能够大大加快查询速度,这是创建索引的最主要的原因。【使用索引最主要的目的:就是优化】
● 当表很大或查询涉及到多个表时,使用索引可以成千上万倍地提高查询速度。
● 可以降低数据库的I0成本,并且索引还可以降低数据库的排序成本。
● 通过创建唯一性索引, 可以保证数据表中每一行数据的唯一性。
● 可以加快表与表之间的连接。
● 在使用分组和排序时,可大大减少分组和排序的时间。
● 建立索引在搜索和恢复数据库中的数据时能显著提高性能。

索引的副作用:
● 索引需要占用额外的磁盘空间。
对于 MyISAM 引擎而言,索引文件和数据文件是分离的,索引文件用于保存数据记录的地址。
而 InnoDB 引擎的表数据文件本身就是索引文件。
● 在插入和修改数据时要花费更多的时间,因为索引也要随之变动。

1.3创建索引的原则依据


索引虽可以提升数据库查询的速度,但并不是任何情况下都适合创建索引。因为索引本身会消耗系统资源,在有索引的情况下,数据库会先进行索引查询,然后定位到具体的数据行,如果索引使用不当,反而会增加数据库的负担。

● 表的主键、外键必须有索引。因为主键具有唯一性,外键关联的是主表的主键,查询时可以快速定位。
● 记录数超过300行的表应该有索引。如果没有索引,每次查询都需要把表遍历一遍,会严重影响数据库的性能。
● 经常与其他表进行连接的表,在连接字段上应该建立索引。
● 唯一性太差的字段不适合建立索引。
● 更新太频繁的字段不适合创建索引。
● 经常出现在 where 子句中的字段,特别是大表的字段,应该建立索引。
● 在经常进行 GROUP BY、ORDER BY的字段上建立索引;
● 索引应该建在选择性高的字段上。
● 索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引。
mysql 的优化 哪些字段 、场景适合创建索引,哪些不适合??
1、表的主键、外键必须有索引
2、数据量超过300行的表应该有索引【数据量特别大的】
3.经常与其他表进行表连接的表,在连接字段上应该建立索引
4.唯一性强的字段应该建立索引。太差的不适合建立,如果索引字段的数据唯一性太差,定位数据表中的数据时,并不能提升查询速度,反而会更加慢。
5.更新太频繁的字段不适合创建索引。在表中进行增删改查时,索引也会有相应的操作产生。字段更新频繁,对系统资源占用的太多。
6.经常出现在where条件子句中的字段,特别是大表的字段,应该建立索引。
7.索引应该建立在选择性高的字段上,如果很少的字段拥有相同值,即有很多独特性,则选择性很高。
8.索引应该建立在小字段上,对于大的文本字段甚至超长字段,不要建立索引。

1.4索引的分类和创建

(1)创建普通索引

直接创建索引
CREATE INDEX 索引名 ON 表名 (列名[(length)]);
#(列名(length)): length是可选项,下同。如果忽略 length 的值,则使用整个列的值作为索引。如果指定,使用列的前 length个字符来创建索引,这样有利于减小索引文件的大小。在不损失精确性的情况下,长度越短越好。
#索引名建议以“_index”结尾。

create index name_index on ky (name);
Select  phone  from  ky;
Show create table ky;
ALTER TABLE 表名 ADD INDEX 索引名 (列名);

例:alter table ky add index id_index (id);
select id from ky;
select id,name from ky;
创建表的时候并指定索引
CREATE TABLE 表名 ( 字段1 数据类型,字段2 数据类型[,...],INDEX 索引名 (列名));
 
例:create table CLASS1(id int(4) not null,name varchar(10) not null,
cardid varchar(18) not null,index id_index (id));
show create table CLASS1;

(2)创建唯一索引

#直接创建唯一索引:
CREATE UNIQUE INDEX 索引名 ON 表名(列名);
 
例:select * from  ky;
create unique index address_index on  ky (address);
create unique index name_index on  ky (name);
show create table  ky;
#修改表方式创建

ALTER TABLE 表名 ADD UNIQUE 索引名 (列名);

例:alter table ky add unique cardid_index (cardid);


 

(3)创建主键索引

主键索引: 1、是一种特殊的唯一索引,必须指定为"PRIMARY KEY"。 2、一个表只能有一个主键,不允许有空值。添加主键将自动创建主键索引。

方式一

 创建表的时候指定索引
CREATE TABLE 表名 (字段1 数据类型[,...],FULLTEXT 索引名 (列名));
 
例:create table CLASS7 (id int not null,name varchar(10),FULLTEXT name_index (name));

show create table CLASS7;

方式二

ALTER TABLE  ADD PRIMARY KEY(列的列表);

alter table ky add primary key (id);

(4)全文索引适合在进行模糊查询的时候使用,可用于在一篇文章中检索文本信息。在MySQL5.6版本以前FULLTEXT 索引仅可用于 MyISAM引擎,在5.6 版本之后 innodb 引擎也支持 FULLTEXT 索引。全文索引可以在 CHAR、VARCHAR 或者TEXT 类型的列上创建。每个表只允许有一个全文索引。

#直接创建索引
CREATE FULLTEXT INDEX 索引名 ON 表名 (列名);
 
例:
select * from team;
create fulltext index suoyin on team(cardid);
desc team;

 

#创建表的时候指定索引
CREATE TABLE 表名 (字段1 数据类型[,...],FULLTEXT 索引名(列名));
#数据类型可以为 CHAR、VARCHAR 或者TEXT
举例:
alter table team add fulltext index suoyin_index(name);
desc team;

 

(5)多列索引

where 条件是依次从左往右执行的,所以在使用 select 语句查询时 where 条件使用的字段顺序必须和组合索引中的排序一
致,否则索引将不会生效。

CREATE TABLE 表名 (列名1 数据类型,列名2 数据类型,列名3 数据类型,INDEX 索引名 (列名1,列名2,列名3));
 
select * from 表名 where 列名1='...' AND 列名2='...' AND 列名3='...';
 
例:create table CLASS5 (id int not null,name varchar(20),cardid varchar(20),index index_amd (id,name));
show create table CLASS5;
insert into CLASS5 values(1,'zhangsan','123123');
select * from CLASS5 where name='zhangsan' and id=1;

(6)删除索引

DROP INDEX 索引名 ON 表名;
 
例:
drop index suoyin_index on lcdb3;
desc lcdb3;

 

1.5查看索引

SHOW INDEX FROM 表名;

SHOW KEYS FRROM 表名;

索引的详细信息

显示参数 描述 Table 表的名称 Non_unique 索引值的唯一性,0表示唯一标识,1表示非唯一性 Key_name 索引的名称 Seq_in_index 索引中的列序列号,从1开始 Column_name 列名

二、mysql事物

2.1事物的概念

●事务是一种机制、一个操作序列,包含了一组数据库操作命令,并且把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这组数据库命令要么都执行,要么都不执行。
●事务是一个不可分割的工作逻辑单元,在数据库系统上执行并发操作时,事务是最小的控制单元。
●事务适用于多用户同时操作的数据库系统的场景,如银行、保险公司及证券交易系统等等。
●事务通过事务的整体性以保证数据的一致性。j
●事务能够提高在向表中更新和插入信息期间的可靠性。
 

说白了,所谓事务,它是一个操作序列,这些操作要么都执行,
要么都不执行,它是一个不可分割的工作单位。

2.2事物的ACID特性

ACID,是指在可靠数据库管理系统(DBMS)中,事务(transaction)应该具有的四个特性: 原子性(Atomicity) 、一致性(Consistency)、隔离性(Isolation) 、持久性(Durability) 。这是可靠数据库所应具备的几个特性。

原子性

原子性: 指事务是一个不可再分割的工作单位,事务中的操作要么都发生,要么都不发生。

事务是一个完整的操作,事务的各元素是不可分的。
事务中的所有元素必须作为一个整体提交或回滚。
如果事务中的任何元素失败,则整个事务将失败。
案例:
A给B转帐100元钱的时候只执行了扣款语句,就提交了,此时如果突然断电,A账号已经发生了扣款,B账号却没收到加款,在生活中就会引起纠纷。这种情况就需要事务的原子性来保证事务要么都执行,要么就都不执行。

一致性

一致性: 指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。

当事务完成时,数据必须处于一致状态。
在事务开始前,数据库中存储的数据处于一致状态。
在正在进行的事务中,数据可能处于不一致的状态。
当事务成功完成时,数据必须再次回到已知的一致状态。
案例: 对银行转帐事务,不管事务成功还是失败,应该保证事务结束后表中A和B的存款总额跟事务执行前一致。

隔离性

隔离性:指在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。
 

对数据进行修改的所有并发事务是彼此隔离的,表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务。
修改数据的事务可在另一个使用相同数据的事务开始之前访问这些数据,或者在另一个使用相同数据的事务结束之后访问这些数据。
也就是说并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的。

持久性

持久性: 在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

指不管系统是否发生故障,事务处理的结果都是永久的。
一旦事务被提交,事务的效果会被永久地保留在数据库中。

总结:在事务管理中,原子性是基础,隔离性是手段,一致性是目的,持久性是结果。

2.3事物的操作

Mysql及事务隔离级别(四种)

(1)read uncommitted(未提交读) : 读取尚未提交的数据 :不解决脏读
允许脏读,其他事务只要修改了数据,即使未提交,本事务也能看到修改后的数据值。也就是可能读取到其他会话中未提交事务修改的数居。

(2)read committed(提交读):读取已经提交的数据 :可以解决脏读
只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别〈不重复读)。

(3)repeatable read(可重复度):重读读取:可以解决脏读 和 不可重复读 —mysql默认的
可重复读。无论其他事务是否修改并提交了数据,在这个事务中看到的数据值始终不受其他事务影响

(4)serializable:串行化:可以解决 脏读 不可重复读 和 虚读—相当于锁表
完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞。

mysql默认的事务处理级别是 repeatable read ,而Oracle和SQL Server是 read committed 。

事务隔离级别的作用范围分为两种:
全局级:对所有的会话有效

(1)设置全局事务隔离级别
set global transaction isolation level read committed;


(2)查询全局事务隔离级别
show global variables like '%isolation%';
SELECT @@global.tx_isolation;

会话级:只对当前的会话有效

(1)查询会话事务隔离级别
show session variables like '%isolation%';
SELECT @@session.tx_isolation; 
SELECT @@tx_isolation;

(2)设置会话事务隔离级别
set session transaction isolation level read committed;

 

2.4 事务控制语句

BEGIN 或 START TRANSACTION: 显式地开启一个事务。

COMMIT 或 COMMIT WORK: 提交事务,并使已对数据库进行的所有修改变为永久性的。

ROLLBACK 或 ROLLBACK WORK: 回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。

SAVEPOINT S1: 使用SAVEPOINT 允许在事务中创建一个回滚点,一个事务中可以有多个SAVEPOINT; “S1”代表回滚点名称。

ROLLBACK TO [SAVEPOINT] S1: 把事务回滚到标记点。
案例:

create database school;
use school;
create table class(  
id int(10) primary key not null,  
name varchar(40),  
money double  
);
 
insert into class values(1,'A',1000);  
insert into class values(2,'B',1000); 
select * from class;

三、MySQL 存储引擎

1、什么是存储引擎

MySQL中的数据用各种不同的技术存储在文件中,每一种技术都使用不同的存储机制、索引技巧、锁定水平并最终提供不同的功能和能力,这些不同的技术以及配套的功能在MySQL中称为存储引擎
存储引擎是MySQL将数据存储在文件系统中的存储方式或者存储格式

(1)mysql常用的存储引擎

1.MyISAM
2.InnoDB

注意:一个表只能使用一个存储引擎,一个库中不同的表可以使用不同的存储引擎。

2、MyISAM存储引擎

2.1 MylSAM介绍

  1. MylSAM不支持事务,也不支持外键约束,只支持全文索引,数据文件和索引文件是分开保存的。

  2. 访问速度快,对事务完整性没有要求。

  3. MylSAM适合查询、插入为主的应用。

  4. MylSAM在磁盘.上存储成三个文件,文件名和表名都相同,但是扩展名分别为:

    • .frm文件存储表结构的定义
    • 数据文件的扩展名为.MYD (MYData)
    • 索引文件的扩展名是.MYI (MYIndex)

2.2 MylSAM的特点

  1. 表级锁定形式,数据在更新时锁定整个表。

  2. 数据库在读写过程中相互阻塞:

    • 会在数据写入的过程阻塞用户数据的读取
    • 也会在数据读取的过程中阻塞用户的数据写入
  3. 数据单独写入或读取,速度过程较快且占用资源相对少。

2.3 MyISAM表支持3种不同的存储格式

(1)静态(固定长度)表

静态表是默认的存储格式。静态表中的字段都是非可变字段,这样每个记录都是固定长度的,这种存储方式的优点是存储非常迅速,容易缓存,出现故障容易恢复;缺点是占用的空间通常比动态表多。

(2)动态表

动态表包含可变字段,记录不是固定长度的,这样存储的优点是占用空间较少,但是频繁的更新、删除记录会产生碎片,需要定期执行OPTIMIZE TABLE语句或myisamchk-r命令来改善性能,并且出现故障的时候恢复相对比较困难(因为会产生磁盘碎片,而且存储空间不是连续的)。

(3)压缩表

压缩表由 myisamchk 工具创建,占据非常小的空间,因为每条记录都是被单独压缩的,所以只有非常小的访问开支。(压缩的过程中会占用CPU性能)

2.4 MyISAM使用的生产场景举例

  • 公司业务不需要事务的支持
  • 单方面读取或写入数据比较多的业务
  • MylSAM存储引擎数据读写都比较频繁场景不适合(因为读写是互相阻塞的)
  • 使用读写并发访问相对较低的业务
  • 数据修改相对较少的业务
  • 对数据业务-致性要求不是非常高的业务
  • 服务器硬件资源相对比较差(MyISAM占用资源相对少)

3、InnoDB存储引擎

3.1 InnoDB介绍

  • 支持事务,支持4个事务隔离级别

  • MySQL从5.5.5版本开始,默认的存储引擎为InnoDB

  • 读写阻塞与事务隔离级别相关

  • 能非常高效的缓存索引和数据

  • 表与主键以簇的方式存储 BTREE

  • 支持分区、表空间,类似oracle数据库

  • 支持外键约束,5.5前不支持全文索引,5.5后支持全文索引

  • 对硬件资源要求还是比较高的场合

  • 行级锁定,但是全表扫描仍然会是表级锁定,如

    • update table set a=1 where user like '%zhang%';

小贴士:

  • 使用like进行模糊查询时,会进行全表扫描,锁定整个表。
  • 对没有创建索引的字段进行查询,也会进行全表扫描锁定整个表。
  • 使用索引进行查询,则是行级锁定。

3.2 InnoDB的特点

  1. InnoDB中不保存表的行数,如 select count(*) from table; 时,InnoDB需要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可。需要注意的是当count(*)语句包含where条件时MyISAM也需要扫描整个表。

  2. 对于自增长的字段,InnoDB 中必须包含只有该字段的索引,但是在MyISAM表中可以和其他字段一起建立组合索引。

  3. delete清空整个表时,InnoDB 是一行一 行的删除,效率非常慢。MyISAM则会重建表。

3.2 InnoDB适用生产场景分析

  • 业务需要事务的支持。

  • 行级锁定对高并发有很好的适应能力,但需确保查询是通过索引来完成。

  • 业务数据更新较为频繁的场景。

    • 如:论坛,微博等。
  • 业务数据一致性要求较高。

    • 如:银行业务。
  • 硬件设备内存较大,利用InnoDB较好的缓存能力来提高内存利用率,减少磁盘IO的压力。

3.3 MyISAM和InnoDB的区别:

MyISAM: 不支持事务和外键约束,占用空间较小,访问速度快,表级锁定,适用于不需要事务处理、单独写入或查询的应用场景。(写入和查询不一起使用的场景)

InnoDB: 支持事务处理、外键约束、占用空间比MyISAM 大,支持行级锁定,读写开发能力较好,适用于需要事务处理、读写频繁的应用场景。

企业选择存储引擎依据

1、需要考虑每个存储引擎提供了哪些不同的核心功能及应用场景。

2、支持的字段和数据类型

  • 所有引擎都支持通用的数据类型
  • 但不是所有的弓|擎都支持其它的字段类型,如二进制对象.

3、锁定类型:不同的存储引擎支持不同级别的锁定

  • 表锁定:MyISAM 支持
  • 行锁定:InnoDB 支持

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值