1.什么是索引?
在关系数据库中,索引是一种数据结构,将数据提前按照一定的规则进行排序和组织,能够帮助快速定位到数据记录的数据,加快数据库表中数据的查找和访问速度。
像书籍的目录、文件夹、标签 、房号... 都可以帮助我们快速定位,都可以视为索引。
能实现快速定位数据的一种存储结构,其设计思想是以空间换时间。
1.1.索引的种类?
mysql中的索引是在存储引擎层实现的,而不是在服务器层实现的,所以不同存储引擎具有不同的索引类型和实现。
常见的索引分类有:
按照数据结构分类:B+tree索引 , Hash索引 , Full - rext索引
按照物理存储分类: 聚集索引 , 非聚集索引。
按字段特性分类:主键索引(primary key), 唯一索引(unique),普通索引(index),全文索引(fulltext)。
按字段个数分类:单列索引 , 联合索引 (也叫复合索引 , 组合索引)
1.2.常见索引数据结构和区别?
二叉树 , 红黑树 , B树 ,B+树
区别:树的高度影响获取数据的性能(每个树点都是一次磁盘I/O)
1.2.1.二叉树
特点:每个节点最多有两个子节点,大在右,小在左,数据随机性情况下树杈越明显。
但是如果数据是顺序依次进入:
树的高度就会很高(形成一个链表结构),此时元素的查询效率就等于链表查询O(n),数据检索效率将会为低下
极端情况下,就是一个链表结构,此时元素的查找效率就等于链表查询O(n)。
1.2.2.红黑树(平衡二叉树)
虽通过自旋平衡,子节点会自动分叉为2个分支,从而减少树的高度,当数据有序插入时比二叉树数据检索性能更佳。
*自旋平衡简而言之平衡策略可以简单概括为三种:左旋转,右旋转,变色。
但是如果数据量过大,节点个数就越多,树高度也会增高(也就是树的深度越深),增加磁盘I/O次数,影响查询效率。
1.2.3.B树
B树的出现可以解决树高度的问题。之所以是B树,而并不是名称中"XXX二叉树",就是它不再限制一个父节点中只能有两个子节点,而是允许M个子节点(M>2)。
不仅如此,B树的一个节点可以存储多个元素,相比较之前那些二叉树数据结构又将整体的树高度降低了。
B树的节点可以包含有多个子节点,所以B树是一颗多叉树,他的每个节点包含的最多子节点数量的称为B树的阶。
当一颗3阶的B树查找7这个元素的流程是怎么样的?
先从根节点出发。判断7在4和8之间,根据P2存储指针6的节点,判断7大于6,最后指针找到叶子节点。也就找到有匹配7的键值。
可以发现一颗3阶的B树在查找叶子节点时,由于树高度只有3,所以查找过程最多只需要3次的磁盘I/O操作。
数据量不大时可能不太真切,但是数据量大时,节点也会随着增多;此时如果前面的自平衡二叉树的场景下,由于二叉树只能最多2个叶子节点的约束,也只能纵向去扩展子节点,树的高度会很高,意味着需要更多的操作磁盘I/O次数。
而B树则可以通过横向扩展节点从而降低树的高度。所以效率自然要比二叉树更高。(直白说就是变矮胖了)
虽然B树现在满足了所有的条件:减少磁盘的I/O操作,同时支持按照区间查找。但是,虽然B树支持按区间查找,但是效率并不高。
例如上面的例子当中,B树能高效通过等值查询15这个值,但是不方便查询出一个区间内3~10区间内所有的数结果。因为当树做范围查询时需要遍历需要使用中序遍历,那么父节点和子节点也就需要不断的来回切换涉及了多个节点会给磁盘I/O带来了很多负担。
1.2.4.B+tree树
在Mysql中为什么会选用B+tree做为数据索引呢?
B+tree是在B树基础上的一种优化,其更适合做存储索引结构,在B+tree中,非叶子节点上仅存储键值,不存储数据;而所有的数据记录均存储在叶子节点上,并且数据是按照顺序排列的。
此外在B+tree中各个数据页之间是用过双向链表连接的,B+tree结构图如下:
B树和B+树的区别,Mysql为什么要选择B+树做为默认索引的数据结构呢?
B+tree结构实现数据索引具体优点如下:
1:非叶子节点上可以存储更多的键值,相应的树的阶数(节点的子节点树)就会更大,树也就变得更矮更胖。这样查找数据进行的磁盘I/O的次数大大减少,数据查询的效率也会更快。
2:所有数据记录都有序存储在叶子节点上,就会使得范围查找,排序查找,分组查找,去重查找变得异常简单。
3:数据页之间,数据记录之间都是通过链表连接的,有了这个结构的支持就可以方便在数据查询后进行升序或者降序的操作。
2.什么是分库分表?
分库分表分为4个类型:垂直分库,垂直分表,水平分库,水平分表
2.1.垂直分库
1.按照功能分成多个数据库存放,举个例子:一个数据库有很多张表,用户表,商品表,订单表等,那么可以根据功能属性进行垂直分库,将用户表等信息放到存放用户信息的数据库,将商品表,订单表存放到与商品订单有关的商品订单库。
2.这样做的好处就是将数据负载分散到不同的数据库上,从而提高系统的性能和扩展性,降低单一数据库的复杂度
2.2.垂直分表
1.简单来说就是将原本的一张表切割成多张表。举个例子:有张student表存储学生家庭背景,学生入学宣言,学生信息,现在将其进行垂直分表,可以分为学生基本信息表,学生入学宣言表,学生家庭背景表,将其进行切割
2.3.水平分表
1.我个人的理解就是这个同一个数据库中,有几个相同表,里面的数据是不一样的,但表结构是一样的,数据按照固定的规则选择数据表存放,如:商品表1,商品表2
2.提高了读写性能,减少了单表的压力、可弹性增加存储容量只需要增加一个表就行。
2.4.水平分库
1.按我的理解来说就是相同的表结果复制一份分到另一个库中,每个库的表结构是一样的,但是数据是不一样的。
2.这样做能做大数量的情况下提高读写性能,因为减少了单一数据库的读写压力。
3。能提高存储容量。可以通过增加或减少数据库进行弹性伸缩
4.提高容错性,当一个数据故障了,别的数据库还能正常运行,只影响小部分数据查询
2.5.怎么分库,怎么分表
2.5.1.分库
一般分库都是按照业务划分的,不如订单库,用户库等
有时候会针对一些特殊的库再作切分,比如一些活动相关的库都做了拆分
因为做活动的时候并发可能会比较高,怕影响现有的核心业务,所以即使有关联,也会单独做拆分
2.5.2.分表
对于分表分为两种情况,垂直分表,水平分表,说下场景需求
2.5.2.1.垂直就是把一些不常用的大字段剥离出来。
用户名是很常见的搜索结果,性别和年龄占用的空间又不大,而地址和个人简历占用的空间相对而言就较大,我们都知道一个数据页的空间是有限的,把一些无用的数据拆分出去,一页就能存放更多行的数据。内存存放更多有用的数据,就减少了磁盘的访问次数,性能就得到提升。
2.5.2.2.水平分表,则是因为一张表内的数据太多,数据越多B+树就越高,访问性能就差,所以进行水平拆分
分库分表是一种数据库分片(Sharding)的实现方式,用于解决单一数据库在数据量增大时性能瓶颈的问题。在分库分表中,数据会被分散存储到多个数据库实例(分库)和表中(分表),以达到分布式存储和查询的目的。
通常,分库分表的策略会根据业务需求和数据库性能做出选择。例如,可以按照用户 ID、地理位置、时间等关键字段将数据分散存储到不同的数据库实例或表中。这样做的好处包括:
水平扩展: 可以通过增加数据库实例和表来扩展系统的存储容量和处理能力,从而应对数据量和并发访问的增长。
提高性能: 分散数据存储和查询操作可以减轻单一数据库的压力,提高系统的并发处理能力和响应速度。
容灾备份: 分库分表可以使得系统在某个数据库实例或表发生故障时,不会影响整个系统的运行,提高系统的容灾性。