Mysql 5.5 之前的默认存储引擎为MyISAM,之后为InnoDB
特性 | MyISAM | InnoDB |
---|---|---|
表级锁 | ✅ | ✅ |
行级锁 | ❌ | ✅(InnoDB 默认为行级锁) |
MVCC | ❌ | ✅ |
外键 | ❌ | ✅ |
事务 | ❌ | ✅ |
回滚 | ❌ | ✅ |
崩溃后的安全恢复 | ❌ | ✅ |
全⽂索引 | ✅ | ✅(InnoDB存储引擎从1.2.x开始支持全文索引技术,其采用full inverted index的方式。) |
MyISam 具备读速度快,写速度慢需要锁全表
InnoDB 是事务性引擎
多版本控制: 指的是一种提高并发的技术。最早的数据库系统,只有读读之间可以并发,读写,写读,写写都要阻塞。引入多版本之后,只有写写之间相互阻塞,其他三种操作都可以并行,这样大幅度提高了InnoDB的并发度
InnoDB存储引擎在数据库每行数据的后面添加了三个字段
1 5 9 | 6字节的事务ID(DB_TRX_ID)字段: 用来标识最近一次对本行记录做修改(insert|update)的事务的标识符, 即最后一次修改(insert|update)本行记录的事务id。 至于delete操作,在innodb看来也不过是一次update操作,更新行中的一个特殊位将行表示为deleted, 并非真正删除。 7字节的回滚指针(DB_ROLL_PTR)字段: 指写入回滚段(rollback segment)的 undo log record (撤销日志记录记录)。 如果一行记录被更新, 则 undo log record 包含 '重建该行记录被更新之前内容' 所必须的信息。 6字节的DB_ROW_ID字段: 包含一个随着新行插入而单调递增的行ID, 当由innodb自动产生聚集索引时,聚集索引会包括这个行ID的值,否则这个行ID不会出现在任何索引中。 如果我们的表中没有主键或合适的唯一索引, 也就是无法生成聚簇索引的时候, InnoDB会帮我们自动生成聚集索引, 但聚簇索引会使用DB_ROW_ID的值来作为主键; 如果我们有自己的主键或者合适的唯一索引, 那么聚簇索引中也就不会包含 DB_ROW_ID 了 。 |
聚簇索引 是指数据内容与索引在一起,找到了索引就找到了数据
非聚簇索引 则是把数据和索引分开,找到索引之后需要根据索引对应的位置查找数据
聚簇索引:将数据存储与索引放到了一块,找到索引也就找到了数据
非聚簇索引:将数据存储于索引分开结构,索引结构的叶子节点指向了数据的对应行,myisam通过key_buffer把索引先缓存到内存中,当需要访问数据时(通过索引访问数据),在内存中直接搜索索引,然后通过索引找到磁盘相应数据,这也就是为什么索引不在key buffer命中时,速度慢的原因
什么时候使用聚簇索引和非聚簇索引
事务的诞生就是为了保持数据的一致性,由而引申出来,原子性,隔离性,持久性
脏读,幻读,不可重复读,丢失修改
读未提交,读已提交,可重复读,串行化
表级锁锁定的是整张表,不会发生死锁,并发性能低
行级锁锁定的是数据行,加锁开销大,性能高,会造成死锁
是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去,此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等竺的进程称为死锁进程,表级锁不会产生死锁.所以解决死锁主要还是针对于最常用的InnoDB。
select xxx for update; 多次锁定同一行数据的时候会造成死锁
行记录锁,间隙锁,行记录锁+间隙锁
当单表数据列数过多 考虑分表
单标数据量过多,考虑分库
限定查询条件,尽量避免不确定的范围查询,不确定的范围数据尽量采用分页
读写分离
基于AOP 做数据源的动态切换,分库分表同
ShardingSphere
下⾯补充⼀下数据库分⽚的两种常⻅⽅案:
客户端代理:
分⽚逻辑在应⽤端,封装在jar包中,通过修改或者封装JDBC层来实现。 当
当⽹的 Sharding-JDBC 、阿⾥的TDDL是两种⽐ 常⽤的实现。
中间件代理: 在应⽤和数据中间加了⼀个代理层。分⽚逻辑统⼀维护在中间件服务中。 我
们现在谈的 Mycat 、360的Atlas、⽹易的DDB等等都是这种架构的实现。
先经过
连接器验证用户
在查询缓存 验证是否命中缓存
没命中缓存,则经过分析器
优化器优化SQL
执行器执行sql返回数据