索引 :帮助MySQL高效获取数据记录的数据结构
数据库的索引通常使用B+Tree实现
通常来说一般的二叉树每个节点只能有两个孩子,每个节点仅包含一个KEY值。这就造成了树的高度很大造成磁盘IO次数非常多
B树打破了每个节点只有一个KEY值的限制,一个节点可以储存多个KEY值,大大的降低了树的深度减少了IO次数,那么B+Tree的改进
更有利于做数据库索引
B-Tree和B+Tree的区别
1.B+Tree 每个节点的指针数和key数相当
2.B+Tree内节点不存储data,叶子节点不存储指针 查询数据都需从根节点到叶节点 B+树的查询效率更加稳定 ,内部节点不储存数据可以储存更多的KEY 降低了树的深度 减少查询的次数
3.叶子结点增加一个指向相邻结点的指针,从小到大顺次连接。
通常在B+树上有两个头指针,一个指向根结点,一个指向关键字最小的叶子结点。
最常见的B-Tree索引 按照顺序存储数据,索引中储存了实际的列值
优点 将随机I/O变成顺序I/O
缺点
哈希索引
索引只存储对应的哈希值,并使用改值对应的记录指针,结构紧凑,查询快
不支持部分索引列匹配查找,因为按索引全部内容计算哈希值得
只支持等值查询,不支持范围查找
哈希冲突
覆盖索引:索引包含了查询正在查找的数据
1select选择的字段中含有不在索引中的字段 ,也即索引没有覆盖全部的列。
2 where 条件中不能含有对索引进行like的操作。
为什么使用B+Tree作为索引?
每次创建节点直接申请一个页面大小空间,保证了一个节点只需要一次I/O
b+tree 相比较与平衡二叉树树的深度h较小 (b+tree中每个节点含有多个key值降低了树的深度)
查找时需进行树的深度-1次I/O操作即可。(根节点一直保存在主存中)
MyISAM:叶节点的data域存放的数据记录地址
InnoDB: 叶节点的data域存放数据文件,按索引组织的表结构(聚簇索引)
索引的失效条件?
最左前缀原理
在有多列索引时,要在查询中使用索引必须依次从左到右的使用索引,范围查询后面的列无法使用索引。
索引列应单独放在等号一侧(否则失效)
InnoDB
InnoDB采用MVCC来支持高并发,并实现了四个标准的事务隔离级别。默认级别为REPETABLE READ(可重复读)
并且通过间隙锁策略防止幻读,间隙锁不仅仅锁定查询涉及的行,还会的索引中的间隙进行锁定。防止换行插入。
InnoDB表基于聚簇索引建立的,表数据就是根据b+tree组织的索引文件。相比于myisam来说支持事务,行级锁,外检
MVCC多版本并发控制:在每行数据记录后增加两个列,分别为创建版本号和删除版本号。每开始一个新的事务版本号会自动递增,开始时刻的版本号记录为事务的版本号。
5.7版本对InnoDB的增强 1支持缓冲池的在线大小(innodb_buffer_pool_size)变更 2 增加 innodb_buffer_pool导入导出功能3支持对innodb表创建表空间。
进行SELECT操作只能查询到a小于等于并且最接近事务版本号
且b删除版本号要么没定义要么大于事务版本号的记录。
优点:减少的加锁的开销。
缺点:需要额外的两列空间,并且需要进行检查和维护开销。
MyISAM
MyISAM提供大量特性,全文索引,压缩,空间函数(GIS)等,但其不支持事务和行级锁。读操作优于
MySQL数据库事务的ACID
原子性:事务是一个不可分割的最小工作单位,要么事务中的所有操作成功提交事务,要么事务中的所有操作失败回滚。不准许只完成事务中的一部分操作。
一致性:数据库在事务开始之前和事务结束之后总是从一个一致性状态到另一个一致性状态转移。
隔离性:在多个事务并发进行时,事务内部操作的其他事务的可见性(隔离性)有4中标准的隔离等级
持久性:事务提交之后既被持久化的保存到数据库中。即使数据库崩溃也不会丢失数据。通常通过数据库备份保障。
四个标准的隔离等级
READ UNCOMMITTED(未提交读)
可以读取到其它未提交事务的数据。在进行未提交的写事务时准许其他事物进行读事务(造成脏读),禁止进行写事务(防止了更新丢失),在进行读事务的时候准许其它写事务(造成不可重复读,幻读)与读事务。很少应用
READ COMMITTED (提交读)
可以读取到其它已提交事务的修改。改进在进行未提交的写事务时禁止其它事务进行读事务(解决脏读)与写事务
但还有不可重复读和幻读的可能性 。
大部分数据库的默认隔离级别。
REPETABLE READ (可重复读)
在进行读事务的时候禁止其它写事务,准许读事务。解决了不可重复读的问题。但仍有幻读的可能,因为其它事务仍可以进行插入操作(lnnoDB采用行级锁只锁住了读取的行,用间隙锁策略监控索引的间隙防止幻读问题)。
MySQL的默认隔离等级。
SERIALIZABLE (可串行化)
通过强制事务串行执行,同一时间只准许一个事务逐条的进行(读取的每一行数据进行加锁)并发性能低,很少使用。
死锁的检测
碰撞检测
超时等待
数据库的三大范式
第一范式:强调列的原子性,每一列的属性都必须是不可分割,所有关系型数据库的最基本要求
第二范式:在第一范式基础上1.每一行数据都可以被唯一的区分, 每个表必须有主键,2.表中每一列必须完全依赖主键(多主键时不能依赖一部分)(减少数据库的冗余)。
第三范式:在第二范式基础上。非主键列之间不能依赖关系. 学生表里不能有系的信息(系主任,系名称)
数据库的优化
复制的3步骤
1把主库的数据更改记录在二进制日志(Binary Log)中
2备库将主库上的日志复制到自己的中继日志上(Relay Log)
3备库读取中继日志的事件,将其重放到备库数据之上
数据库分区建立索引(结构层次)缓存机制(减少I/O)
优化查询语句:慢查询日志 explain 解析 是否查询了不需要的列limit返回的行数
内连接,外连接
A INNER(可不写) JOIN B ON (condion)按联结条件去两表相匹配的数据记录。
A LEFT JOIN B ON(condion) 取左表全部记录和右表匹配的记录无对应填NULL。
MySQL5.7新特性
1支持JSON和计算列
2在线修改innodb_buffer_pool_sizes大小 ,支持innodb_buffer_pool的导入导出功能
3引入sys schema 系统库 。可以知道那个查询用到临时表,查询I/O最多,未用到索引的查询
4安全性提升 默认采用SSL加密方式 初始化数据库mysqld_initialze 不在是空密码而是随机密码 密码过期机制
5Replication多源复制,支持多线程复制