-
MyISAM与InnoDB锁的区别
- MyISAM默认是表级锁,不支持行级锁
- InnoDB 默认是行级锁,也支持表级锁
-
MyISAM
- MyISAM不支持事务
- 查询时,会自动给表上读锁(表级锁跟索引无关)
- 增删改时,会自动给表加上写锁
- 显示加/释放锁
lock tables 表名 read | write;unlock tables - 显示给select语句加写锁
select * from 表 where··· for update
-
InnoDB
- InnoDB支持事务(默认事务自动提交)
- 修改事务自动提交配置:
show variables like 'autocommit';set autocommit = 0; - 也可不配置,用
begin transaction+xxxsql - InnoDB的select为非阻塞的,及默认不加读锁,显示加读锁:
select * from 表名 where ··· lock in share mode; - 当条件不走索引时,会使用表级锁,走索引时,使用行级锁或Gap锁(间隙锁,普通非唯一索引时会用gap锁)
-
MyISAM适合的场景
- 频繁执行全表
count语句1 - 对数据的增删改的频率不高,查询非常频繁
- 没有事务
- 频繁执行全表
-
InnoDB适合场景
- 数据的增删改查都频繁的系统
- 可靠性要求高,需要支持事务的系统
-
数据库锁的分类
- 粒度2
- 表级锁、行级锁、页级锁(表锁和行锁之间)
- 级别
- 共享锁(读锁)、排它锁(写锁)
- 操作
- DML锁(数据锁)、DDL锁(表结构锁)
- 使用方式
- 乐观锁、悲观锁
- 乐观锁简易实现:设计表的时候,增加一个版本字段version,每次更改记录时,先读取记录中的该字段,然后更新时,条件带上该字段
-
select version as v from 表+update 表 set version = version+1 and ··· where ··· and version = v
- 粒度2
-
数据库事务的4大特性
-
A
- 原子性(全部成功或全部失败)
-
C
- 一致性
-
I
- 隔离性(多个事务并发执行时,一个事务不影响其他事务)
-
D
- 持久性
-
A
-
事务并发引起的问题3
- 更新丢失
- mysql所有事务隔离级别在数据库层面上均可避免
- mysql所有事务隔离级别在数据库层面上均可避免
- 脏读
- READ-COMMITTED事务隔离级别以上可避免
- 当多个事务在执行时,一个事务读入了另一个事务未提交的数据
- 不可重读读4
- REPEATABLE-READ事务隔离级别以上可以避免
- 当事务a和事务b并发执行时,事务a多次读取数据,事务b提交后,事务a读取的数据和之前不一样
- 幻读
- SERIALIZABLE事务隔离级别可避免
- 另一个事务新增或删除记录在当前事务的影响区间内,导致当前事务多影响或者少影响了记录数,出现幻读
- 更新丢失
-
当前读和快照读
- 当前读会加锁,读的是当前最新数据(
lock in share mode、for update、update/delete/insert) - 快照读:
-
select不加锁的非阻塞读(事务隔离级别不为serializable) - 注:创建快照的时期决定了读取的数据版本
-
- 当前读会加锁,读的是当前最新数据(
-
rc、rr级别下,非阻塞读的实现
- 每行记录会额外存储
DB_TRX-ID(之后一次操作的事务id)、DB_ROLL_PTR(回滚指针)、DB_ROW_ID(行号,单增隐藏主键) - undo 日志 (insert undo log/update undo log)
- 每行记录会额外存储
-
next-key锁(行锁+gap锁)
- 如果
where条件全部命中,不会使用gap锁 - 如果
where条件部分命中或全不命中,则会加gap锁 - 走非唯一索引或者不走索引时,会用gap锁
(不走索引会对全部间隙加gap锁,类似表锁,但开销大)
- 如果
-
sql语法
- group by
- select 子句中列名 必须为 分组列或列函数
- 列函数对group by 每个组返回一个结果
- having
- 通常与group by 一起使用
- where 过滤行,having 过滤组
- 顺序: where>group by > having
- group by