2019独角兽企业重金招聘Python工程师标准>>>
问:MyISAM和InnoDB关于锁方面的区别是什么?
- MyISAM默认是表级锁,不支持行级锁
- InnoDB默认是行级锁,也支持表级锁
MyISAM不支持事务,测试的时候加大数据量到几百万,查询大结果的的时候并修改一条数据,就可以发现MyISAM加了表级锁
--加读锁 写锁就是write
lock tables test_table read|write;
--释放锁
unlock tables;
读锁也叫共享锁 读锁锁住后可以再进行读,当上了写锁再上读锁、写锁需要先等上个锁释放后才行,所以写锁也叫排他锁。
--手动加排他锁
select * from test_table for update;
InnoDB使用的是二段锁,加锁和解锁是分两个步骤进行的,默认commit是自动提交的。
--查看是不是自动提交commit
show variables like 'autocommit';
--关闭自动提交(只针对当前会话的),之后加锁需要手动commit释放锁
set autocommit=0;
--上读锁(共享锁)这个时候再update id =3 的时候就阻塞住了,但是读不受影响,update id =4 的时候不受影响,这就是行级锁
select * from test_table where id = 3 lock in share mode;
PS:如果不走索引的时候 给查询加读锁 InnoDB走的是表级锁
InnoDB 除了支持行级锁 还支持表级的意向锁 IS ,排他写锁IX ,主要是进行表级别的操作的时候不用轮询每一行加没加行锁
x排他锁 s共享锁
锁的粒度越细代价越高,表级锁是表头直接加锁,行级锁是扫描到某行再对其加锁,代价更大。
InnoDB 支持事务的同时也带来了更大的开销。InnoDB 有且仅有一个聚集索引。数据文件是绑在一起的。必须要有主键,主键是聚集索引,聚集索引查询效率很高,但是辅助索引需要查2次,先查到主键,再根据主键查询数据。
MyISAM是使用的非聚集索引,数据文件是分离的。索引保存的主键的指针,主键索引和辅助索引是独立的。所以MyISAM纯检索(增删改很少)的系统中性能好于InnoDB
MyISAM适合的场景:
- 频繁执行全表count语句,InnoDB是要重新扫描表行数,M'y'ISAM则用一个变量保存了表行数
- 对数据进行增删改的频率不高,查询非常频繁(因为增删改会涉及到锁表操作,虽然插入可以经过配置然数据从尾部插入提高性能,但是依然会产生很多碎片)
- 没有事务的系统 推荐MyISAM
InnoDB适合的场景:
- 数据增删改查都相当频繁
- 可靠性要求比较高,要求支持事务
数据库锁的分类
- 按锁的粒度划分:表级锁、行级锁、页级锁(一个页级块的几行数据)
- 按锁级别划分:共享锁、排他锁
- 按加锁方式划分:自动锁(意向锁、MyISAM的表锁、insert、delete加上的锁)、显示锁(for update、lock share mode)
- 按操作划分:DML锁(操作数据的锁,增删改查)、DDL锁(操作数据结构的锁,alter)
- 按使用方式划分:乐观锁(乐观锁认为一般数据操作不会产生冲突,所以再提交数据的适合才验证冲突与否,如果冲突了返回错误信息然后让用户去操作,乐观锁一般不会采用数据库的锁机制实现,一般是增加版本号或者时间戳字段来实现)、悲观锁(悲观锁对外界的操作持保守态度。只有数据库层提供的锁机制才能实现排他性。悲观并发采取的是先取锁再访问的保守策略,为数据安全提供保证,开销更大性能更低)
问:数据库事务的四大特性?
ACID
- 原子性(Atomic)要么全做 要么全不做
- 一致性(Consistency)一致性状态保证完整性约束,如ab2人总余额是100,那他们之间怎么转账总余额还是100
- 隔离性(Isolation)多个事务并发执行时一个事务不应该影响其他事务
- 持久性(Durability)一个事务一旦提交,它对数据库的修改应该永久保存在数据库中。数据应提供适当冗余,让故障后可保证恢复数据。