一、sql生命周期
1. 应用服务器与数据库服务器建立一个连接
2. 数据库进程拿到请求sql
3. 解析并生成执行计划,执行
4. 读取数据到内存并进行逻辑处理
5. 通过步骤一的连接,发送结果到客户端
6. 关掉连接,释放资源
二、大数据量优化
1.优化sql+索引
2.加缓存redis
3. 主从复制,读写分离
4. 垂直拆分,根据你模块的耦合度,将一个大的系统分为多个小的系统,也就是分布式系统
5. 水平切分,针对数据量大的表, 考验技术水平,要选择一个合理的sharding key, 为了有好的查询效率,表结构也要改动
三、数据库锁
1.乐观锁
所谓乐观锁就是在数据表中加入一个版本号字段(version),每次读取数据时记录读取到的版本号,在提交事物的时候检查数据库中的版本号如果读取的和上次的一样则更新数据并版本号+1,如果读取数据库的版本号不一致发生了修改则认为数据被改动了事务回滚。
2.悲观锁
悲观锁就是认为在每次操作数据时侯都会有人篡改我的数据,所以每次操作的时候都会进行数据加锁,这个和Java中synchronized很相似,所以悲观锁比较耗时,以乐观锁相比悲观锁是系统自己实现直接调用相关语句即可。
3.排他锁
排他锁和共享锁是悲观锁的不同实现,我们使用排他锁必须要把数据库的自动提交事务关闭掉(atuocommit)用sql命令开启手动提交事务。
4.共享锁
共享锁也叫读锁,是读取数据时创建的锁,其他用户可以并发读取数据,任何事物都不可以修改数据,直到释放共享锁。一个事务a对事务b加共享锁之后其他事务不可以对a加共享锁,排他锁,获取到共享锁只能读取数据不能修改数据。
四、mysql的隔离级别
1.读未提交
会产生脏读、不可重复度、幻读。事务a开启事务修改用户id为1的用户的money=300事务还没有提交,事务b也正好在读取事务a所修改id用户此时已经可以读到该用户的money已经为300了。如果事务a发生了异常产生了回滚用户id的金额并没有发生改变但是事务b读取的金额发生了改变这种问题就是脏读。
2.读已提交
会产生不可重复读,幻读。不可重复读,事务1修改表用户id为1的用户的money=300在事务还没有提交的时候,事务2还读取不到money=300。假如事务2有两次读取表id的money的SQL语句第一次读取的时候事务1还没有提交哦,这时候读取的还是原来的money,但是在第二次执行的查询SQL语句的时候,事务1已经提交这时候读取money的值就发生了改变。这种问题就是不可重复读。
3.可重复度
可重复度是MySQL默认的隔离级别。可以防止脏读、幻不可重复读、但不可以防止幻读。幻读事务1修改了表查询进行修改第一次查询是10条语句,事务2查询表进行了插入操作,这时候事务1在次查询的时候就发现出现了幻觉一样刚刚明明是10条数据现在又出现多了一条数据这个就是幻读。幻读和不可重复度很相似,单数幻读只针对删除和插入数据不针对修改。
4.串行化
串行化可以避免以上的所有问题但是效率太低,执行的时候事务排着队一个一个执行不会发生以上问题。
开启事务的命令
set autocommit=0; //设置手动提交事务
begin; //开始事务
update user money = 300 where id = 1; //处理业务逻辑
commit; //提交
五、嵌套事务
1、内外都无try Catch的时候,外部异常,全部回滚。
2、内外都无try Catch的时候,内部异常,全部回滚。
3、外部有try Catch时候,内部异常,全部回滚。
4、内部有try Catch,外部异常,全部回滚。
5、内外都有try Catch, 内部异常全部不回滚。
5、内外都有try Catch, 外部异常执行一半。
五、事务的四大属性
事务是由一组SQL语句组成的逻辑处理单元,事务具有以下4个属性,通常简称为事务的ACID属性:
原子性:事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。
一致性:在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规 则都必须应用于事务的修改,以保持数据的完整性;事务结束时,所有的内部数据结构(如B树索引或 双向链表)也都必须是正确的。
隔离性:数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环 境执行。这意味着事务处理过程中的中间状态对外部是不可见的,反之亦然。
持久性:事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。
事务的传播行为:
保证同一个事务中
PROPAGATION_REQUIRED 支持当前事务,如果不存在 就新建一个(默认) PROPAGATION_SUPPORTS 支持当前事务,如果不存在,就不使用事务 PROPAGATION_MANDATORY 支持当前事务,如果不存在,抛出异常
保证没有在同一个事务中
PROPAGATION_REQUIRES_NEW 如果有事务存在,挂起当前事务,创建一个新的事务 PROPAGATION_NOT_SUPPORTED 以非事务方式运行,如果有事务存在,挂起当前事务 PROPAGATION_NEVER 以非事务方式运行,如果有事务存在,抛出异常 PROPAGATION_NESTED 如果当前事务存在,则嵌套事务执行
六、简单说mysql索引
我们知道MySQL中的索引可以提升查找速度,但是有时候我们并不知道索引是怎么实现的,其实索引理解起来很简单索引就是数据结构,,MySQL种有很多存储引擎如BTree,哈希索引,全文索引等,这里只说BTree索引。
在MySQL存储表的时候大多使用B+Tree,有一个用户表(user)id是它的主键我们有100条数据
把100分为10份在根节点存放10,20,30,40,50,60,70,80,90,100的索引节点,如果我们查找id为55的这一条数据我们是不是可以直接从根目录直接定位到60这个索引节点,然后找到id为55的数据,这样可以大大节约时间。innodb的叶子节点索引key就是主键data就是数据。