处理字典值是把字典放内存还是用sql处理_SQL索引及其底层实现
准备 1、对关系型数据库有基本的了解
2、对树,平衡二叉树有了解。
目录
一、什么是索引以及为什么要用索引
二、索引的分类
三、实现原理
四、物理存储
五、索引的优化
在实际的面试中,遇到数据库的问题大致有事务、锁、索引、以及SQL调优等方面的问题。
索引算是一个比较基础的知识点了,以下以MySQL为例,谈谈数据库的索引。
什么是索引
简单来讲,索引是将数据库中的记录按照某个特殊的格式存储的数据结构。通过索引,能够显著提高查询效率,从而提高服务器的性能。
数据库中的索引类似我们书籍、字典的索引,我们通过,例如我们想查字【红】【hong】我们可以利用字典的拼音表去查对应【hong】的页数,然后直接找到改页,对比所有的哄、鸿、宏、红,最后找出我们所需要的数据。但是一般我们查字典都不用拼音表,或者偏旁表,而是直接去翻页数,比如说先翻到【N】,再翻到【F】,再翻到【I】,最后我们很快地找到了对应的【H】。
为什么要是用索引
这个问题等价于,索引的好处:
1、避免全表扫描。有了索引,我们通过索引存放的物理地址或者偏移地址也好去对应的内存,磁盘中去寻找,大大节约了时间,不然只能遍历全表扫描了。2、减少排序、临时表的建立以主键索引为例子,一般我们设置主键自增,当我们利用索引找到数据,由于索引本身是有序的,找出来的数据也自然是有序的,这点如果底层是hash表实现的,则无序。可以将无序IO变成有序IO。
索引的缺点:
索引本身是以表的形式存储的,自然会占用内存空间讲到这里,一般的磁盘格式化,也是删除索引,而不是删除原数据,所以磁盘格式化了,恢复数据也不是什么难事,只要原来的数据没有被从新覆盖。删除,添加,修改数据时,也要修改索引
所以,当一个表的数据量很小时,或者删除、插入频率远高于查找,不使用索引的成本要低些。
索引的分类
一般可以分为单列、组合、全文索引和空间索引。用的最多的是单列索引和组合索引。
主键索引
不为空,唯一
ALTER 'TABLE_NAME' ADD PRIMARY PK_TABLE_NAME('COL_ONE');
唯一索引
唯一,可为空
ALTER 'TABLE_NAME' ADD UNIQUE unique_name('COL_ONE');
普通索引
ALTER 'TABLE_NAME' ADD INDEX iINDEX_ONE('COL_ONE');
组合索引
ALTER TABEL_NAME ADD INDEX INDEX_NAME('COL_ONE', 'COL_TWO', 'COL_THREE');
组合索引,会遵循最左配对原则,一言以蔽之,会优先走第一个索引。相当于创建了三个索引。
INDEX_ONE('COL_ONE')
INDEX_TWO('COL_ONE','COL_TWO')
INDEX_THREE('COL_ONE', 'COL_TWO', 'COL_THREE')
底层实现
哈希索引
通过对键值进行哈希运算,将哈希出来的hashCode存放在散列表中,而对应的散列表存放对应数据行的地址或者下一级地址。
学号 | 姓名 | 分数 |
---|---|---|
101 | 李华 | 90 |
102 | 小明 | 93 |
103 | 小芳 | 98 |
104 | 张三 | 99 |
105 | 赵四 | 100 |
同时,可以看出,当出现哈希冲突,我们是用链地址法,将冲突的行的地址放在下一行中。例如:
李华和赵四出现冲突,我们先得出李华hashCode,将其地址,存放在散列表中。但是赵四得出和李华一样的hashCode,通过对比起存放的地址,发现已存数据,这样我们把存放李华对应行的头部解放出来,存放指向下一行的地址。
B树索引
B树实际上是一种多叉平衡搜索树,那么为什么在大型的文件系统或者数据库,为什么不用红黑树或者哈希表:
红黑树,树的高度很高,访问文件系统时,需要多次IO操作,而在服务器相应的过程中,相比于CPU处理速度和内存读取速度,磁盘IO是非常缓慢的
会出现哈希冲突,从而也需要遍历链地址。
一般来说,索引本身也是很大的,比如2个G的文件,索引就要占1/3,是没办法一下子载入内存的。为了解决以上问题,在我们学的操作系统里面,有一个磁盘分页和局部性原理,这里就不展开了。
B 树的特点:
(1) 树的高度是平衡的,所有的叶子结点都在同一层。
(2)更新和检索只会影响到一些磁盘,因此性能稳定。
(3)把相关的记录存储在同一个磁盘,可以可以利用局部性原理进行预读。
(4)非叶子结点的key都是[key, data]的二元组,key为索引的键,data为当前的数据行。
一个m阶B树的定义
根或者叶子结点至少有两个孩子。
除了根以外,每个内部结点至少有m/2的上限到m个孩子。
所有的叶子结点都在同一层,不不含任何信息(可以看成外部节点或者查找失败的结点)。
B树的示意图:
为一个3阶B树,也就是说每一个结点【非根】最多有三个孩子,最少有2个孩子。
每个结点内部为
B 树的插入
找到可以插入的最下层内部结点,如果结点的孩子数小于m,直接插入,否则将当前结点一分为二,并将中间的关键字,提到父节点,父节点也按如上逻辑执行。
B+ 树
谈B+ 树,肯定要说B树的缺点:
无法处理范围查询,由于B树没有顺序索引,也没有链地址,所取出来的地址都是离散的。
无法定位到指定的行。我个人的理解是B树中的key存储的是[key, data]二元组,如果所有的索引都要存数据,定位到指定的行,难免数据量太大了。
B+树定义
对于一个m阶B+树:
所有节点的key值个数等于孩子个数,最下层的内存节点包含了所有的关键字,所有非最下层的内部结点的关键字个数是对应子树的最大关键字个数。
每一个结点有m/2的上限到m个孩子。
所有的叶子结点都在同一层,且不含任何信息(可以看错外部节点或查询失败。)
每个最下层的内部结点都带一个指针,指向相邻的结点。形成了带顺序索引的B树。
物理存储
虽然说不同的存储引擎都是用的B树,但是具体实现还是有区别的,InnoDB实现的是聚族索引,MyISAM实现的是非聚族索引。
主键索引和辅助索引
B+树的非叶子结点存储的是键值,当键值是主键时,为主键索引,其他的为辅助索引。
聚族索引
主键索引的最下层叶子结点存储键值对应的数据本身,非主键索引存储对应数据段的【该行数据】的主键值。
也就是说,通过主键索引,可以直接找到对应的数据行,而辅助索引是先找到对应数据行的主键,然后再用主键索引去找数据。
假设有一个数据表,如下:
对应的聚族索引的主键和辅助索引为:
非聚族索引
非聚族索引就没那么复杂了,主键和辅助索引的叶子结点都是存储着对应的物理地址(ROWID ??),除了主键索引不能为空,且唯一。
索引优化
SQL 调优这块其实学问很大,很多面试官都会问,简单列几条:
最左原则
覆盖索引。也就是说,尽量使用所有需要查询的字段来做索引。这样就无须再去扫描对应的行了。(扯淡)
索引排序 用对应的索引查出来的数据就可以排序,因为索引也是有序的。
索引不要参与计算 最简单的一个例子,就是你的索引就是对应hash的一个值,最好不要计算,那样就不走索引了。
处理字典值是把字典放内存还是用sql处理_SQL索引及其底层实现相关推荐
- 处理字典值是把字典放内存还是用sql处理_python基础~元祖与字典原理
生成器推导式创建元组:,生成器推导式与列表推导式类似,只是生成器推导式使用小括号.不管什么方式使用,元素访问结束后,如果需要重新访问其中的元素,必须重新创建该生成器对象. 元组特点:1.不可变序列 2 ...
- 处理字典值是把字典放内存还是用sql处理_第二周:MYSQL数据库入门,提升你的数据处理效率...
第1课:使用SQL探索产品数据 1.什么是SQL? SQL,Structured Query Language结构化查询语言是目前对数据库进行查询和编辑的主流编程语言. 通常来说,一个数据库会包含一个 ...
- es 修改ik和同义词插件源码连接mysql实现字典值同义词热更新
问题描述: 上周运营反馈商城搜索词搜不到 排查发现es ik分词器的ik_smart对搜索词的分词结果不是ik_max_word对索引文档字段值分词结果的子集 即细粒度分词结果不完全包含粗粒度分词结果 ...
- python字典嵌套列表_Python 字典 列表 嵌套 复杂排序大全
https://blog.csdn.net/ray_up/article/details/42084863 一: 字典排序 解析: 使用sorted 方法, 排序后的结果为一个元组. 可以字符串排序( ...
- python字典内存分析_Python减少字典对象占用的七成内存
程序执行过程中,如果RAM中有大量的对象在运行,就可能会出现内存问题,特别是在对可用内存总量有限的情况下. 下面是一些减少字典对象内存大小的方法,这些方法可以显著减少对象所需的RAM大小. 字典 在P ...
- python输出字典_Python如何将字典键和值拆分为单独的列表?(代码示例)
在Python中如何将给定字典拆分为键和值的列表?下面本篇文章就来给大家介绍几种实现方法,希望对大家有所帮助.[视频教程推荐:Python教程] 方法一:使用内置函数:keys()和values() ...
- 2021-12-19 老杨博客推荐\TCP像串口的多程编写的一个弱鸡版本类MQTT的TCP实现\字典值查键\微PYTHON与PYTHON的JSON区别\以及一个ESP32领导多个ESP8266组网模式
都说程序员最拿手的好戏是复制粘贴,对于这件事我也是深以为然,遇到问题先看看别人,有么有写好的,没有写好的看看类似的,实在不行继续百度群里问问,最后再自己操刀上吧,microPython作为小众的控制器 ...
- java实现数据的Excel导出, 自定义导出字段, 转换字典值
java实现数据的Excel导出, 自定义导出字段, 转换字典值 第一版代码: 基础功能跳转此文章java自定义Excel导出工具: 简介 新增功能: 添加自定义字段导出功能, 用户可以选择字段进行导 ...
- python字典键值唯一_python字典操作详解
python字典是一个无序.以键值对存储的数据类型,数据关联性强.唯一一个映射数据类型.键:必须是可哈希(不可变的数据类型:字符串.数字.元组.bool)值,并且是唯一的 None: none 是一个 ...
最新文章
- DNS协议报文(RFC1035)
- 征信一个月查40次,还能贷款吗?
- B-树、B+树、B*树详解
- php 字符串的比较大小,php怎么比较两个字符串的大小
- 美商务部再禁6项新兴技术,包括光刻软件和5nm生产技术
- SCALA环境搭建(2)_scala源文件编写和运行---大数据之_SCALA工作笔记005
- android学习笔记---59_各种图形的使用介绍,android炫酷效果的实现
- MySQL高级知识(二)——Join查询
- 实现自己的脚本语言ngscript之三:语法设计
- 利用BI搭建零售业数据信息平台
- UVALive 6533
- linux中的轮询机制select/poll/epoll特点分析
- 基于Cocos2d-x开发guardCarrot--7 《保卫萝卜2》关卡选择页面开发
- ol2 和 bootstrap样式冲突的问题
- 13分钟搭建动易PHP论坛(OS:Linux)
- 【泛微E9开发】E9客户端下载页面修改方法
- unix网络编程中的fd是什么
- Unity Addressable学习笔记二(Hosting热更新)
- 洛谷 P2884 【[USACO07MAR]每月的费用Monthly Expense】
- Qt 之 打开exe程序