深圳福田区住房和建设局网站官网,市场营销,网站建设合同或方案书,网站怎么做漂亮点目录
简单了解索引的底层数据结构
索引的概念#xff1a;
索引存在的意义#xff1a;
索引的使用#xff1a;
索引实现的数据结构
B树
B 树
B 树的特点
B 树的优势
事物
事物的概念
事物的使用
事物的四大特性
并发可能引起的问题
脏读问题
不可重复读
幻读…目录
简单了解索引的底层数据结构
索引的概念
索引存在的意义
索引的使用
索引实现的数据结构
B树
B 树
B 树的特点
B 树的优势
事物
事物的概念
事物的使用
事物的四大特性
并发可能引起的问题
脏读问题
不可重复读
幻读
事物的隔离级别 简单了解索引的底层数据结构
索引的概念
索引是一种特殊的文件包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引并指定索引的类型各类索引有各自的数据结构实现 索引就是为了加快查询速度在之前学习数组的时候我们就是通过下标直接去查找到该位置的数据同时我们也可以称之为索引。
索引存在的意义
索引就是通过特殊的数据结构将数据组织在一起这样查询时就不需要通过一行行遍历去找目标数据此时的时间复杂度仍是 O(n) 数据量少的时候没问题但是一旦数据量太大就会造成开销太大我们这里的 O(n) 每一次都要读取硬盘它的速率会比读取内存中的数据更慢所以我们迫切的需要索引来减低访问磁盘的次数。
虽然索引增加了查询的速率但是减低了 增上改 的效率并且增加了更多的内存消耗。
索引的使用
在 MySQL 代码中语法很简单 创建索引 create index 索引名 on 表名(字段名); 查看索引 show index from 表名; 删除索引 drop index 索引名 on 表名; 要考虑对数据库表的某列或某几列创建索引需要考虑以下几点
数据量较大且经常对这些列进行条件查询。该数据库表的插入操作及对这些列的修改操作频率较低。索引会占用额外的磁盘空间。
当面对数据量大时去创建一个索引系统为了创建这个索引而消耗过多的资源导致机器无法正常工作所以索引在实际开发中并不会频繁使用。
对于索引的使用不是我们想要讨论的课题我们学习索引更主要的是想了解索引底层的数据结构。
索引实现的数据结构
我们知道索引主要是增加查询效率的我们之前学过两个主要用于查询的数据结构。
一个是二叉搜索树一个是哈希表
那么索引是什么呢
先来知道为什么二叉搜索数和哈希表不能用来创建索引
二叉搜索树二叉搜索树在极端情况单分支下树的高度非常的高那么此时的查询速率就非常低效哈希表哈希表的实现原理是计算哈希值用来存放数据而对于相邻的数据之前是无法比较的
那么我们在二叉搜索树的基础上就提出了B树
而B 树又是建立在B树的基础上B树又叫 B - 树不是B减树是B 杠 树是为索引量身定制的数据结构。
我们来简单认识一下B树和B树。
B树
B树是棵N叉搜索树每个节点具有多个key值如图 有 n 个 key 就将其分为 n 1 个子节点每个分组如下图 当节点中的子树多节点上保存的key就多意味着同样key的个数的前提下B树的高度要远低于二叉搜索树
树的高度越高进行查询的时候磁盘访问次数就越多
B 树
B 又在B树的基础上作出改进 树也是个N叉搜索树
画图演示 这样同样一棵树我们却只分为了 3 个域 我们划分出的三个域不仅存了规定的值并且还保留了关键的 key 。
这里的 50 是整个树中最大的值该树中不可能出现大于50 的值。
我们再划分一次 划分结束后类似于链表一样将其链接起来这样整棵树的叶子节点包含了所有的数据所有非叶子节点的 key 都出现在了叶子节点中。
这种‘链表’就是mysql组织数据的形式当你看到一张表的时候 实际上这个表不一定就是按照‘表格’这样的数据结构在硬盘上组织的也有可以是按照这种书的结构组织的具体是那种哪种结构取决于你表中的索引以及数据库使用了哪种存储引擎
B 树的特点 每个节点可以存在 n 个 key n 个 key 划分出 n 个子节点B树的特点是划分出 n 1 个子节点。每个 key 都会出现在叶子节点中同时也是叶子节点中的最大值。B 树的叶子节点是首尾相连的类似于一个链表由于叶子节点是个完整的数据集合只在叶子节点中存储数据表中每一行的数据而非叶子节点只存 key 本身即可。具体解释以下 第四点 我们设 id 为索引那我们存储的值就是 id在存数据时不会将整个集合中的数据都存入只存入一个id其余的仍然保存在硬盘中有需要的时候在去硬盘中取为什么要怎么设计呢因为内存空间是有序的 B 树的优势 每个节点存储多个 key 最终会使树相对较矮这样在查询的时候就减少了IO输入输出访问次数这里IO特指的是硬盘的访问最后所有的查询都会落到叶子节点上这样无论查询多少次都可以保证查询效率是同样的保证了稳定性稳定性对于程序员对这个树的评估更加准确B 树的所有叶子节点构成链表因此方便了进行范围查询比如查询学生 id 在27 ~ 36之前的就非常快 由于数据都存在叶子节点上非叶子节点只存在key导致非叶子节点所占的内存是非常小的这些非叶子节点就可以在内存缓存或者是内存换中的一部分这样就进一步减少了IO访问至于B 树和B 树的代码就放在数据结构进阶的部分再继续
事物
事物的概念
事务指逻辑上的一组操作组成这组操作的各个单元要么全部成功要么全部失败。 在不同的环境中都可以有事务。对应在数据库中就是数据库事务。
为什么要有事物这个概念
在很多年前那个时候还没有微信转账主要是靠银行卡之间进行转账有时候会发生很多问题比如转账以后另一方没有收到
又比如现在网传台湾那边充话费需要半个小时才能到账
有了事物我们这一组操作要么一起成功要么一起失败。大大的提高了效率
事物存在的意义就是将多个sql语句打成一个包要么包内全部执行成功要么包内全部执行不成功不存在中间状态
事物的使用
sql执行过程
开启事务start transaction;执行多条SQL语句回滚或提交rollback/commit;
说明rollback即是全部失败commit即是全部成功。
举例 :
jerry 的账户原来有10000元而tom 只有5000元jerry 给 tom 转账 1000后的结果 如果执行失败并非是没有执行而是执行以后将数据恢复未执行之前的状态这个恢复的过程称之为 回滚 rollback
例如上面这个例子再jerry 转账过后系统崩了但是钱却扣了在下次重新启动系统后就会把钱加回来
进行回滚的时候咋知道恢复成什么样子呢数据库中有个专门来记录事物的日志。
因此使用事物的时候执行sql语句开销是非常大的。
事物使用起来非常简单但是理解起来有些难
事物的四大特性
数据库的事物有四大关键特性这也是面试中经常问的【八股文】
原子性事务中的每个sql语句都是最小的不可再分的一致性事物执行前后都是靠谱的持久性事物执行的内容是存在硬盘上的即使机器重启也不会丢失因此数据是可持久的隔离性为了解决“并发”执行事物引起的问题
隔离性这里重点讲解以下
先来讲讲啥叫并发
并发就是一个服务器为多个客户端提供服务
如果并发是操作不同的数据那么并发并不会造成影响但是它并非都是操作不同数据存在操作同一数据的情况。
例如上面的案例假设多个用户对一个账号进行转账操作那就会把数据搞乱。
事物的隔离性就体现在即使是并发事物操作也不会引发问题
既然聊到并发那就来聊聊并发可能引起的问题
并发可能引起的问题
脏读问题
什么叫脏读
举个贴切的例子
有一场考试中隔壁的想抄我的答案我故意给他看但是后面我又将答案给改了那么他看到的数据就是一个 “脏数据”。脏也就是无效的意思。
那么这么解决脏读的问题呢?
很简单我们在写数据的时候给它进行加锁mysql引入一个 “写操作加锁” 机制。加锁是会提高耗能的同时降低了效率也增加了隔离性。
也就是说我考试的时候不给隔壁的人看。
不可重复读
举例
还是那一场考试我们约定好我写完了给他抄不故意坑他在我第一次写完以后version 1给他抄了在抄的过程中我发现自己写错了已一道题我就又改了version 2这个时候他读着读着发现数据不一样了。
这个问题就是不可重复读。
事物1 提交了数据事物2 开始读取事物3 又去更新了数据此时意味着事物在多次读取数据的结果是不一样的预期应该是一样的这就是不可重复读。
解决方法呢也是和上面一样加锁此时给事物 “ 读 ” 加锁 此时又进一步增加了耗能的同时降低了效率也进一步增加了隔离性。
幻读
说明事物A 读取了一次 事物B 对数据进行新增或者删除并提交事物 导致读取数据列表数据多了此时就叫做幻读。
数据库使用 “ 串行化 ” 的方式来解决此类问题并且彻底放弃并发处理事务改用串行的方式一行行处理事物此时的并发程度是最低的效率也就最低但是隔离性确是最高的。
针对上述问题又提出了事物的隔离级别
事物的隔离级别 选用哪种级别这时mysql内置的机制可以通过修改mysql配置文件来设置mysql工作环境。
具体如何使用 以及其代码在后面会写道。