使用数据库的目的在于数据共享,需要考虑数据并发访问问题。解决方案就是锁机制
锁主要包括全局锁、表锁、行锁、乐观锁和悲观锁,需要解决的问题是死锁
存储引擎
存储引擎定义 MySQL 中的数据、索引以及其它的数据库对象如何存储,是一套文件系统的实现
查看所有的存储引擎 show engines ;
常见的存储引擎:MyISAM、Innodb、memory
MyISAM 采用的是全表锁,具有较高的查询执行速度,不支持事务和外键,并发性能差,但是占用
空间相对较小,对于事务没有要求,一般主要以 select 和 insert 为主的应用可以使用这个引擎
Innodb 采用的是行级锁,可以提供具有提交、回滚和恢复能力的事务安全,支持自增长类,支持
外键约束,并发性能强,一般所需要占用的空间是 MyISAM 的 2.5 倍以上,处理效率相对差一些
Memory 采用的是全表锁,存储数据在内存中,速度快,但是占用和数据量成正比的内存空间,而
且数据在 MySQL 重启时丢失,默认使用 hash 索引,检索效率高,但是不适合范围查找,主要用于
缓存内容变化不频繁的表
archive 这种类型的表只支持 insert 、 select ,不支持 delete 、 update 、 replace ,不使用索引
csv 这些表保存在服务器的单个文件中,它包含了用逗号间隔的数据。
Innodb 和 MyISAM 的区别
Innodb支持事务, MyISAM 不支持, Innodb 针对每条 SQL 语句都默认封装为事务,自动提交,这样会影响执行速度
Innodb支持外键约束, MyISAM 不支持。所以对于一个包含外键的 innodb 表转换为 MyISAM 会失败
Innodb采用的时聚集索引,数据文件和索引绑定,必须有主键,通过主键查询效率很高;但是辅 助索引需要两次查询,因此在Innodb中主键不应该过大; MyISAM 采用的是非聚集索引,所以数据 文件分离
innodb不保存数据的总行数,执行 select count(*) 需要全表扫描;而 MyISAM 使用一个变量保
存了表的总行数,所以执行 count(*) 查询时速度很快
Innodb5.5-不支持全文索引, MyISAM 支持全文索引,查询效率上 MyISAM 高
选择依据:
如果没有特殊要求,使用默认的 innodb 即可
MyISAM:以读取和插入为主的应用,比如博客系统、新闻网站等。搜索引擎采用 NoSQL 类型的数据库ES 提供
Innodb:更新删除操作效率要求较高或者要求保证数据的完整性,同时考虑并发量要求高的场景下使用,例如OA 之类的管理系统。因为支持事务和外键所以能够很好的保证数据完整性
Innodb 存储引擎即支持行级锁,也支持表级锁,默认情况下使用行级锁。锁类型包括共享 S 锁、排他 X锁、意向共享IS 锁和意向 IX 排他锁。
意向锁就是为了让表锁可以快速感知是否有行级锁的存在,以防止表锁干扰行锁的执行
表级锁
锁的颗粒度为整个表
lock tables 表名称 read/write ,其中 read 是共享锁,一旦锁定则共享读取数据, write 是排他锁,
只有加锁的客户端可以读写,其它客户端不可读也不可写
解锁 unlock tables
行级锁
锁的颗粒度为表中的特定的一行或者多行
共享锁 select * from 表名称 where 条件 lock in share mode ;
排他锁 select * from 表名称 where 条件 for update ;
注意:所谓的行锁并不是直接锁定特定行的数据,实际上是锁定一个子范围,所以也称为间隙锁。例如
select * from tb_student where id<20 lock in share mode 实际上并不是锁定 id<20 的现有数
据,而是锁定 id<20 的范围,例如插入 id 为 18 的新记录失败
死锁问题
死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方的资源,从而导致恶性循环的现象。
常见的解决死锁的方法
如果不同程序会并发存取多个表, 尽量约定以相同的顺序访问表,可以大大降低死锁机会。
在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;
对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率;
如果业务处理不好可以用分布式事务锁或者使用乐观锁
update tb_users set salary=? where id=1
update tb_users set salary=?,version=2 where id=1 and version=1 [version 是一个额外的列,用于记录当前行的版本号]
查询缓存
可以缓存 select 语句的查询结果,以浪费内存为代价换取高执行效率
这个下载版本可能会有不能启动的问题,请大家使用其它版本进行测试
配置参数 query_cache_type
0 不开启
1开启缓存,默认缓存所有 select ,如果需要不缓存则需要在 select 语句中添加 sql-no-cache 提示放弃缓存
2开启缓存,默认都不缓存,需要在 sql 语句中添加 select sql-cache 主动缓存
需要添加 mysql 配置文件, windows 上 my.ini , Linux 上 my.conf
query_cache_type = 1
查看MySQL是否开启缓存
show variables like 'query_cache_type' ;
配置打开查询缓存大小
set global query_cache_size= 64 * 1024 * 1024 ; -- 配置查询缓存为 64M
show variables like 'query%' ;
将查询结果进行
select sql_cache * from tb_users where ...;
重置缓存
reset query cache ;