MySQL索引事务

1. 索引


1.1 概念

索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现。

1.2 作用  

  • 数据库中的表、数据、索引之间的关系,类似于书架上的图书、书籍内容和书籍目录的关系。
  • 索引所起的作用类似书籍目录,可用于快速定位、检索数据。
  • 索引对于提高数据库的性能有很大的帮助。

1.3 使用场景 

要考虑对数据库表的某列或某几列创建索引,需要考虑以下几点:
  • 数据量较大,且经常对这些列进行条件查询。
  • 该数据库表的插入操作,及对这些列的修改操作频率较低。
  • 索引会占用额外的磁盘空间。
满足以上条件时,考虑对表中的这些字段创建索引,以提高查询效率。
反之,如果非条件查询列,或经常做插入、修改操作,或磁盘空间不足时,不考虑创建索引。

索引的特点:

  1. 加快查询的速度
  2. 索引自身是一定的数据结构,也要占据存储空间
  3. 当我们需要对表进行新增、删除、修改的时候,也需要针对索引进行更新(额外的开销) 

1.4 使用

创建 主键约束 PRIMARY KEY )、 唯一约束 UNIQUE )、 外键约束 FOREIGN KEY )时,会 自动创建对应列的索引
  • 查看索引

show index from 表名;  

例:查看学生表已有的索引 

show index from student;  

  • 创建索引  

对于非主键、非唯一约束、非外键的字段,可以创建普通索引,语法:

create index 索引名 on 表名(字段名); 

在创建索引的时候,一定要在建表之初就规划好 。

例:创建班级表中,name字段的索引  

create index idx_classes_name on classes(name); 

  • 删除索引  

drop index 索引名 on 表名;  

例:删除班级表中name字段的索引

drop index idx_classes_name on classes; 

索引保存的数据结构主要为B+,及hash的方式 。

2. 事务 

2.1 为什么使用事务  

数据库的事务:很多时候,进行的多个操作,期望能够“打包”到一起,共同执行。

举例:张三向李四转账100,先执行第一个sql语句,将张三的钱减少100:

update accout set money=money-100 where name = '张三'; 

再执行第二个sql语句,将李四的钱增加100:

update accout set money=money+100 where name = '李四'; 

若在执行完第一个sql语句后,数据库挂了,张三的钱减少了,但李四的钱并未增多!这肯定是不行的!

解决方案:使用事务来控制,保证以上两句SQL要么全部执行成功,要么全部执行失败。

 

2.2 事务的概念 

事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败
在不同的环境中,都可以有事务。对应在数据库中,就是数据库事务。

对于事务如何保证要么全部执行成功,要么全部执行失败呢?

就如上述例子,希望数据库挂了以后,张三的钱能还回去,怎么恢复回去的(回滚)? 数据库咋知道之前的数据是多少呢?

这是数据库对于事务有特殊的机制(undo log + redo log):数据库中间挂了,但是日志已经记录下来了之前的数据、进行的操作。等到数据库重启之后,读取之前的日志,看看是否有这种执行了一半的事务,如果有,就会把这前面的操作进行回滚。

谈到事务,往往涉及4个核心特性

  1. 原子性:通过事务,把多个操作打包到一起(最重要的特性)。
  2. 一致性:相当于原子性的延伸。当数据库中间出问题了,不会产生上述“钱凭空消失”的不科学情况,另一方面,还通过约束,来避免数据出现一些非法的情况。
  3. 持久性:事务任何的修改,都是持久化存在的(写入硬盘的)。
  4. 隔离性:多个事务并发执行的时候,可能带来一些问题,通过隔离性来对这里的问题进行权衡,看是希望数据尽量准确,还是速度尽量快。

对于隔离性的并发执行事务时,可能会产生以下典型问题:

  1. 脏读问题:读出的数据是不对的,通过对写操作加锁解决
  2. 不可重复读问题:两次读出的数据不一样,通过对读操作也加锁解决、
  3. 幻读问题:事务1修改数据,提交;事务2开始读数据;此时事务3,新增了一个其他数据,此时事务2就可能出现,两次读取的“结果集”不同。

解决幻读问题:串行化,不再进行任何并发了,每个事务都是串行执行的。

mysql 在配置中,提供了“隔离级别”这样的选项,人们就可以根据需要,调整隔离级别,适应不同的情况:

  1.  read uncommitted(读未提交):并行程度是最高的,隔离程度是最低的,效率是最高的,数据是最不靠谱的。此时可能出现脏读问题+不可重复读问题+幻读问题。
  2. read committed(读已提交):相当于对写操作加锁,并行程度降低了,隔离程度提高了,效率会降低些,数据会靠谱一些,此时可能出现不可重复读问题+幻读问题。
  3. repeatable read(可重复读):相当于对读操作和写操作都加锁,并行程度降低了,隔离程度提高了,效率又降低了,数据又更靠谱了,此时可能出现幻读问题。
  4. serializable(串行化):让所有事务都是串行执行,并行程度最低,隔离程度最高,效率最低,数据最靠谱。

2.3 使用  

1)开启事务:start transaction;

(2)执行多条SQL语句

3 )回滚或提交: rollback/commit;

说明:rollback即是全部失败,commit即是全部成功。  

start transaction;
-- 阿里巴巴账户减少 2000
update accout set money=money- 2000 where name = ' 阿里巴巴 ' ;
-- 四十大盗账户增加 2000
update accout set money=money+ 2000 where name = ' 四十大盗 ' ;
commit;

3、内容重点总结 

  • 索引:
  1. 对于插入、删除数据频率高的表,不适用索引
  2. 对于某列修改频率高的,该列不适用索引
  3. 通过某列或某几列的条件查询频率高的,可以对这些列创建索引
  • 事务

 start transaction;

...
rollback/commit;

 

你可能感兴趣的:(MySQL,mysql,数据库)