一般来说mysql使用同步+长连接+连接池的方式进行通信交互(但mysql也有异步和短连接)
支持事务,支持行级锁和表级锁支持读写不冲突
执行一条Select sql语句,执行流程
因为mysql InnoDB数据存储於磁盘从磁盘读取到内存,最小读取单位是页Page页在操作系统4K(4K对齐),但在innoDB设置为16K我们操作数据库数据,其实是先操作内存里的数據页再更新数据到本地磁盘。但不可能mysql内存每次都只是一页一页地读取和操作所以innodb有内存缓存机制--BufferPool
bufferPool是innodb很重要的缓存机制,假设中途数據库奔溃了那如何恢复处理?它也有持久化机制:redo log
redo log:属于InnoDB的机制可以用于奔溃数据备份、控制事务(配合undo log使用?)
binlog:属于mysql系统级别的機制它会记录DDL(create表 drop等)、DML(增删改)操作语句。默认关闭bin log功能(额外占用IO和磁盘空间)ps:mysql主从复制也是通过使用binlog的特性实现的。
mysql索引结構由来
mysql索引数据结构为B+树演变过程由二叉平衡树(过于高瘦)——> B树(趋于矮胖)——>B+树,B+树相较b树好处比较明显是:
1.innodb主键索引把每条唍整数据都存放于叶子节点(innodb是放数据myisam放的是数据地址指针),这非叶子节点所占用空间更小提高IO每次读页的吞吐数,减少IO次数(二級索引【非主键索引】叶子节点存储的是二级索引和主键索引的键值所以使用二级索引进行查询时,会查到叶子里的主键索引键值再“回表”走一遍主键索引最终查到主键索引下的数据)
2.叶子节点的数据有指针顺序互相链接,这样当查询语句是范围大小查询的时候只需要查一个边界值所在叶子位置,然后直接从有序的叶子节点找到数据区间
题外:偶然也可以看到索引可以选择hash数据结构,但一般不建議hash虽然查找很快,都是O(1),但由于hash碰撞以及hash结构建立所以需要计算hash值导致数据顺序打乱。
mysql数据文件简要
可以看到 *.ibd *.myi *.myd文件其中myi、myd代表myisam引擎的索引、数据文件。idb是innodb的数据文件注意innodb只有数据文件,因为索引的叶子节点是放数据的所以都在同一个文件。
因此Innodb 是索引的顺序决定數据存放的顺序,而决定物理数据存放顺序的索引被称作聚集索引(innodb也就是主键索引)。
假如表不存在主键也没有唯一或其他索引呢?这时候会用一个隐藏的列_rowid作为聚集索引
事务的ACID特性这里就不多说了
事务其实本质上,就是我们的sql操作会先写进一个不可见的生成在内存空间的临时表临时表会跟真实的表作比较,看是否通过校验通过则提交。我们手动提交事务其实就是控制了临时表做比较和提交這个过程。
互联网项目请用:读已提交(Read Commited)这个隔离级别!
其实锁锁住的是索引(不存在主键和任何索引的表呢?其实不存在没有索引的表假设没主键,会有个隐藏列_rowid作为索引的)假如select * where XX for update查询条件中不走索引(查全表),会导致锁全表尽量避免这个情况。
select for update是行锁但他真實效果不是锁定查询出来的行,而是锁定查询条件里索引对应的行
//因为没有相应的s_class记录所以查询结果为空,但实际上会单独锁定s_name = '李四g'这荇数据
当然代码块的说法并不准确,for update的查询条件假设是范围区间的话会有另一种基准锁行(间隙锁,区间锁算法有兴趣再去mysql细节解剖第三节视频看)。