![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
mysql
文章平均质量分 71
佟印龙
这个作者很懒,什么都没留下…
展开
-
分布式事务的防悬挂,空回滚
一、TCC简介TCC是一种比较成熟的分布式事务解决方案,可用于解决跨库操作的数据一致性问题;TCC是服务化的两阶段编程模型,其Try、Confirm、Cancel 3个方法均由业务编码实现;其中Try操作作为一阶段,负责资源的检查和预留,Confirm操作作为二阶段提交操作,执行真正的业务,Cancel是预留资源的取消;如下图所示,业务实现TCC服务之后,该TCC服务将作为分布式事务的其中一个资源,参与到整个分布式事务中;事务管理器分2阶段协调TCC服务,在第一阶段调用所有TCC服务的Try方法,在原创 2021-09-24 17:23:33 · 6672 阅读 · 1 评论 -
如何对生产环境中的数据库进行360度无死角压测?
给你一台4核8G的机器,他可以抗到每秒几千甚至每秒几万的并发请求吗?其实这个是不一定的,因为一台机器到底每秒钟可以抗下多少并发请求,跟CPU、内存、磁盘IO、网络带宽,都是有关系的。举个例子,之前在我们的一个项目的生产环境中,据我们观察,一台4核8G的机器如果每秒抗下500+的请求,那么他的CPU负载就已经很高了,基本上最多可能也就是去抗下每秒1000+的请求,而且那个时候CPU负载基本会打满,机器有挂掉的风险。另外如果你的系统的业务逻辑特别的吃内存,也许你一台4核8G的机器跑到每秒几百的请求,内存使原创 2021-03-30 10:24:26 · 158 阅读 · 0 评论 -
一线电商公司的订单系统是如何进行数据库设计的?
一般互联网公司的订单系统是如何做分库分表的,既然要聊订单系统的分库分表,那么就得先说说为什么订单需要分库分表,其实最关键的一点就是要分析一下订单系统的数据量,那么订单系统的数据量有多大?这个就得看具体公司的情况了。比如说一个小型互联网公司,如果是涉及到电商交易的,那么肯定每天都会有一些订单进来的,那么比如小型互联网公司假设有500万的注册用户,每天日活的用户会有多少人?意思就是说,500万的注册用户,并不是每个人每天都来光顾这里的!往多了说,即使按照28法则,500万的注册用户,每天最多是20%的用户会转载 2021-03-29 09:56:33 · 867 阅读 · 0 评论 -
大型电商网站的上亿数据量的用户表如何进行水平拆分?
首先,这里说得是分库分表的整体方案的设计,但是在进行具体的方案落地的时候,是需要数据库中间件技术的支持的,业内常用的一般有Sharding-Sphere以及MyCat两种,各自用的公司都很多,都比较成熟,可以自行选择一个数据库中间件技术,去关注一下它们的官方文档,熟悉一下它们的用法。其实任何一个互联网公司都会有用户中心,这个用户中心就是负责这家公司的所有用户的数据管理,包括了用户的数据存储,用户信息的增删改查,用户的注册登录之类的。而且一般互联网公司因为是直接面向终端用户的,所以用户数据一般都很多,哪怕转载 2021-03-29 09:55:59 · 1067 阅读 · 1 评论 -
数据库高可用:基于主从复制实现故障转移(二)
现在来介绍一下MHA数据库高可用架构的搭建,先来介绍一下在三个数据库所在机器上安装MHA node节点的步骤,首先那必须要先安装Perl语言环境了,这就跟平时用Java开发,那必须得先装个JDK吧!所以先可以用yum装一下Perl语言环境:yum install perl-DBD-MySQL然后从下述地址下载MHA node代码:https://github.com/yoshinorim/mha4mysql-node接着就可以把node的压缩包用WinSCP之类的工具上传到机器上去,接着解压缩n转载 2021-03-29 09:55:19 · 101 阅读 · 0 评论 -
数据库高可用:基于主从复制实现故障转移(一)
读写分离的模式确定了,接着就可以来考虑一下数据库的高可用架构了,所谓的高可用就是说,如果数据库突然宕机了一台机器,比如说主库或者从库宕机了,那么数据库还能正常使用吗?其实如果从库宕机了影响并不是很大,因为大不了就是让所有的读流量都从主库去读就可以了,但是如果主库宕机了呢?那就真的麻烦了,因为主库一旦宕机,就没法写入数据了,从库毕竟是不允许写入的,只允许读取。所以有没有一种办法,可以在主库宕机之后,就立马把从库切换为主库呢,然后所有人都对从库切换为的主库去写入和读取呢?如果能实现这样的一个效果,那数据库不转载 2021-03-29 09:50:00 · 333 阅读 · 0 评论 -
主从复制架构中的数据延迟问题,应该如何解决?
主从复制架构,比较关键的是,主从复制可能会有较大的延迟。这个延迟是什么意思呢?就是说主库可能都写入了100条数据了,结果从库才复制过去了50条数据,那么从库就比主库落后了50条数据。这就是所谓的主从延迟的问题。可是为什么会产生这个主从延迟的问题呢?也很简单,其实主库是多线程并发写入的,这个都知道的,所以主库写入数据的速度可能是很快的,但是从库是单个线程缓慢拉取数据的,所以才会导致从库复制数据的速度是比较慢的。那自然会导致主从之间的延迟问题了。那么这个主从之间到底延迟了多少时间呢?这个可以用一个工具来进行转载 2021-03-29 09:49:30 · 225 阅读 · 0 评论 -
如何为MySQL搭建一套主从复制架构?
MySQL搭建一套主从复制架构,大致来说,就是主库接受增删改操作,把增删改操作binlog写入本地文件,然后从库发送请求来拉取binlog,接着在从库上重新执行一遍binlog的操作,就可以还原出一样的数据了。那么搭建的时候肯定是需要两台机器的,一台机器放主库,一台机器放从库,至于主库和从库如何安装和启动?随便网上一搜就大把的MySQL安装步骤,这里就讲解搭建主从复制架构要做的一些配置。首先呢,要确保主库和从库的server-id是不同的,这个是必然的,其次就是主库必须打开binlog功能,必须打开bi转载 2021-03-29 09:48:04 · 111 阅读 · 0 评论 -
为什么要搭建一套MySQL的主从复制架构?
生产环境的MySQL架构应该是什么样子的呢?简单来说,MySQL在生产环境中,必须要搭建一套主从复制的架构,同时可以基于一些工具实现高可用架构。另外如果有需求,还需要基于一些中间件实现读写分离架构,最后就是如果数据量很大,还必须可以实现分库分表的架构。先来讲讲MySQL的主从复制架构,这个主从复制架构,顾名思义,就是部署两台服务器,每台服务器上都得有一个MySQL,其中一个MySQL是master(主节点),另外一个MySQL是slave(从节点)。然后系统平时连接到master节点写入数据,当然也可以从转载 2021-03-29 09:44:45 · 153 阅读 · 0 评论 -
千万级数据删除导致的慢查询优化实践
案例的背景是,当时有人删除了千万级的数据,结果导致了频繁的慢查询,接下来讲一下这个案例整个排查、定位以及解决的一个过程。这个案例的开始,当时是从线上收到大量的慢查询告警开始的,收到大量的慢查询告警之后,就去检查慢查询的SQL,结果发现不是什么特别的SQL,这些SQL语句主要都是针对一个表的,同时也比较简单,而且基本都是单行查询,看起来似乎不应该会慢查询。所以这个时候感觉极为奇怪的,因为SQL本身完全不应该有慢查询,按说那种SQL语句,基本上都是直接根据索引查找出来的,性能应该是极高的。那么有没有另外一转载 2021-03-29 09:42:16 · 230 阅读 · 0 评论 -
数十亿数量级评论系统的SQL调优实战
针对电商场景下非常普遍的商品评论系统的一个SQL优化,这个商品评论系统的数据量非常大,拥有多达十亿量级的评论数据,所以对这个评论数据库,做了分库分表的,基本上分完库和表过后,单表的评论数据在百万级别。每一个商品的所有评论都是放在一个库的一张表里的,这样可以确保你作为用户在分页查询一个商品的评论时,一般都是直接从一个库的一张表里执行分页查询语句就可以了。在电商网站里,有一些热门的商品,可能销量多达上百万,商品的评论可能多达几十万条。然后呢,有一些用户,可能就喜欢看商品评论,就喜欢不停的对某个热门商品的评论不转载 2021-03-29 09:41:42 · 172 阅读 · 0 评论 -
亿级数据量商品系统的SQL调优实战
先从线上的商品系统出现的一个慢查询告警开始讲起,某一天晚上,突然收到了线上数据库的频繁报警,这个报警的意思大致就是说,数据库突然涌现出了大量的慢查询,而且因为大量的慢查询,导致每一个数据库连接执行一个慢查询都要耗费很久。那这样的话,必然会导致突然过来的很多查询需要让数据库开辟出来更多的连接,因此这个时候报警也告诉我们,数据库的连接突然也暴增了,而且每个连接都打满,每个连接都要执行一个慢查询,慢查询还跑的特别慢。接着引发的问题,就是数据库的连接全部打满,没法开辟新的连接了,但是还持续的有新的查询发送过来,转载 2021-03-29 09:40:35 · 219 阅读 · 0 评论 -
千万级用户场景下的运营系统SQL调优
先说下这个案例的背景,简单来说,这是一个互联网公司的系统,这个互联网公司的用户量是比较大的,有百万级日活用户的一个量级。在这个互联网公司里,有一个系统是专门通过各种条件筛选出大量的用户,接着对那些用户去推送一些消息的,有的时候可能是一些促销活动的消息,有的时候可能是让你办会员卡的消息,有的时候可能是告诉你有一个特价商品的消息。总而言之,其实通过一些条件筛选出大量的用户,接着针对这些用户做一些推送,是互联网公司的运营系统里常见的一种功能,在这个过程中,比较坑爹,也比较耗时的,其实是筛选用户的这个过程。因为这转载 2021-03-25 14:36:56 · 139 阅读 · 0 评论 -
透彻研究通过explain命令得到的SQL执行计划(四)
除了基于索引查询数据,可能同时还得基于where条件里的其他过滤条件去筛选数据,此时还会筛选出来一些数据。这个extra里的信息可能会非常非常的多,这里主要介绍下一些平时常见的,比较有用的extra信息。比如下面的SQL语句:EXPLAIN SELECT x1 FROM t1 WHERE x1 = 'xxx'可以看看它的执行计划是什么样的:+----+-------------+-------+------------+------+---------------+----------+------转载 2021-03-25 14:32:37 · 101 阅读 · 0 评论 -
透彻研究通过explain命令得到的SQL执行计划(三)
再来看看执行计划里的type有哪些取值,其实select_type并不是很关键,因为它主要是代表了大SQL里的不同的SELECT代表了一个什么角色,比如有的SELECT是PRIMARY查询,有的是UNION,有的是SUBQUERY。但是这个type就非常关键了,因为它直接决定了对某个表是如何从里面查询数据的,关于这个查询方式之前早就讲过了,包括了const、ref、range、index、all这几种方式,分别是根据主键/唯一索引查询,根据二级索引查询,对二级索引进行全索引扫描,对聚簇索引进行全表扫描。转载 2021-03-25 14:29:13 · 72 阅读 · 0 评论 -
透彻研究通过explain命令得到的SQL执行计划(二)
继续讲解不同SQL语句的执行计划长什么样子,来一起看一个包含子查询的SQL语句的执行计划:EXPLAIN SELECT * FROM t1 WHERE x1 IN (SELECT x1 FROM t2) OR x3 = 'xxxx';这个SQL就稍微有一点点的复杂了,因为主SELECT语句的WHERE筛选条件是依赖于一个子查询的,而且除此之外还有一个自己的WHERE筛选条件,那么它的执行计划长什么样子呢?+----+-------------+-------+------------+-------转载 2021-03-25 14:25:24 · 82 阅读 · 0 评论 -
透彻研究通过explain命令得到的SQL执行计划(一)
只要把explain分析得到的SQL执行计划都研究透彻,完全能看懂,知道每个执行计划在底层是怎么执行的,那么后面SQL语句的调优就非常容易了。首先,现在应该都知道每条SQL语句,mysql都会经过成本和规则的优化,对这个SQL选择对应的一些访问方法和顺序,包括做一些特殊的改写确保执行效率是最优的,然后优化过后,就会得到一个执行计划。这个执行计划其实真没那么神秘,如果把之前的内容都学习的比较透彻的话就会知道,所谓的执行计划,落实到底层,无非就是先访问哪个表,用哪个索引还是全表扫描,拿到数据之后如何去聚簇索转载 2021-03-25 14:22:36 · 155 阅读 · 0 评论 -
MySQL是如何根据成本优化选择执行计划的?
其实在执行单表查询也好,多表关联也好,似乎都有多种执行计划可以选择,比如有的表可以全表扫描,也可以用索引A,也可以用索引B,那么到底是用哪种执行计划呢?简单来说,跑一个SQL语句,一般成本是两块,首先是那些数据如果在磁盘里,要不要从磁盘里把数据读出来?这个从磁盘读数据到内存就是IO成本,而且MySQL里都是一页一页读的,读一页的成本的约定为1.0。然后呢,还有一个成本,那就是说拿到数据之后,是不是要对数据做一些运算?比如验证它是否符合搜索条件了,或者是搞一些排序分组之类的事,这些都是耗费CPU资源的,属转载 2021-03-25 14:20:46 · 137 阅读 · 0 评论 -
深入探索多表关联的SQL语句到底是如何执行的?(二)
假设有一个员工表,还有一个产品销售业绩表,员工表里包含了id(主键)、name(姓名)、department(部门),产品销售业绩表里包含了id(主键)、employee_id(员工id)、产品名称(product_name)、销售业绩(saled_amount)。假设想看看每个员工对每个产品的销售业绩,写个SQL:select e.name,e.department,ps.product_name,ps.saled_amount from employee e,product_saled pa whe转载 2021-03-25 14:19:42 · 216 阅读 · 0 评论 -
探索多表关联的SQL语句到底是如何执行的?(一)
平时基于MySQL做一些系统开发的时候,比较多的是写一些多表关联语句,因为有时候想要查找需要的数据,不得不借助多表关联的语法去编写SQL语句,才能实现想要的逻辑和语义,但是往往使用多表关联的时候,SQL性能就可能会遇到一些问题。假设有一个SQL语句是:select * from t1,t2 where t1.x1=xxx and t1.x2=t2.x2 and t2.x3=xxx。首先,如果在FROM字句后直接来了两个表名,这意思就是要针对两个表进行查询了,而且会把两个表的数据给关联起来,假设要是没有限转载 2021-03-25 14:17:43 · 234 阅读 · 0 评论 -
写出各种SQL语句的时候,会用什么执行计划?
首先看一个SQL语句:select * from table where x1=xx or x2>=xx,这个SQL语句要查一个表,用了x1和x2两个字段,此时有人可能会说了,要是对x1和x2建了一个联合索引,那不就直接可以通过索引去扫描了?但是万一要是建的索引是两个呢?比如(x1,x3),(x2,x4),建了两个联合索引,此时这个SQL只能选择其中一个索引去用,此时会选择哪个呢?这里MySQL负责生成执行计划的查询优化器,一般会选择在索引里扫描行数比较少的那个条件。比如说x1=xx,在索引里只要转载 2021-03-25 14:17:13 · 88 阅读 · 0 评论 -
MySQL单表查询来举例,看看执行计划包含哪些内容?
假设写一个select * from table where id=x,或者select * from table where name=x的语句,直接就可以通过聚簇索引或者二级索引+聚簇索引回源,轻松查到要的数据,这种根据索引直接可以快速查找数据的过程,在执行计划里称之为const,意思就是性能超高的常量级的。所以以后在执行计划里看到const的时候,就知道它就是直接通过索引定位到数据,速度极快,这就是const的意思。但是这里有一个要点,二级索引必须是唯一索引,才是属于const方式的,也就是说必须建转载 2021-03-25 14:16:34 · 257 阅读 · 0 评论 -
MySQL索引设计实战(二)
根据以前的文章联合索引已经设计为了(province, city, sex)的样子,把省份、城市和性别三个几乎每次查询都会加的条件放入了联合索引的最左侧去,接着继续分析这个联合索引里还要放哪些字段。假设查询的时候,不指定性别,就指定了省份,城市,还有加了一个年龄,也就是说where province=xx and city=xx and age between xx and xx,那么此时怎么办呢?因为age不在索引里,所以就根本没法通过age去在索引里进行筛选了。那如果把索引设计成(province,转载 2021-03-24 20:10:38 · 201 阅读 · 0 评论 -
MySQL索引设计实战(一)
社交APP,市面上有很多,它本身的核心主旨,其实就是进入APP的时候,需要录入一系列的个人信息。接着APP自己会通过一定的算法推荐一些可能适合你的人给你进行线上交友,当然也有可能是你自己通过一定的条件去搜索和筛选,查找APP上的哪些用户可能比较符合你的期望,你希望去去跟对方进行交友。这里忽略掉APP基于算法自动推荐潜在感兴趣的好友给你的部分,就来看看你通过一系列的条件去筛选一些好友的过程。在筛选的时候,是针对社交APP的哪个表进行查询?明显是用户信息表吧,可以叫做user_info这么一个表。那这个表里转载 2021-03-24 20:10:06 · 99 阅读 · 0 评论 -
MySQL 当中建立索引的时候,哪些因素是需要注意的呢?
首先,在针对业务需求建立好一张表的结构之后,就知道这个表有哪些字段,每个字段是什么类型的,会包含哪些数据。接着设计好表结构之后,接下来要做的,就是要设计表的索引,这个设计索引的时候,要考虑第一点,就是未来对表进行查询的时候,大概会如何来进行查询?其实很多时候很多人可能说,要让我刚设计完表结构就知道未来会怎么查询表,那我怎么可能知道呢,实在是想不出来!好,那么没关系,此时完全可以在表结构设计完毕之后,先别急着设计索引,因为此时你根本不知道要怎么查询表。接着就可以进入系统开发的环节,也就是说根据需求文档转载 2021-03-24 20:09:35 · 325 阅读 · 0 评论 -
回表查询对性能的损害以及覆盖索引是什么?
一般自己建的索引不管是单列索引还是联合索引,其实一个索引就对应着一颗独立的索引B+树,索引B+树的节点仅仅包含了索引里的几个字段的值以及主键值。即使根据索引树按照条件找到了需要的数据,那也仅仅是索引里的几个字段的值和主键值,万一搞了一个select *还需要很多其它的字段,那还得走一个回表操作,根据主键跑到主键的聚簇索引里去找,聚簇索引的叶子节点是数据页,找到数据页里才能把一行数据的所有字段值提取出来。假设是类似select * from table order by xx1,xx2,xx3的语句,可能转载 2021-03-24 20:09:00 · 158 阅读 · 0 评论 -
在SQL里进行分组的时候,如何才能使用索引?
假设要是用到了group by分组语句的话是否可以用上索引,有时候会想要做一个group by把数据分组接着用count sum之类的聚合函数做一个聚合统计。那假设要是走一个类似select count(*) from table group by xx的SQL语句,似乎看起来必须把所有的数据放到一个临时磁盘文件里还有加上部分内存,去搞一个分组,按照指定字段的值分成一组一组的,接着对每一组都执行一个聚合函数,这个性能也是极差的,因为毕竟涉及大量的磁盘交互。因为在索引树里默认都是按照指定的一些字段都排序好转载 2021-03-24 20:08:30 · 902 阅读 · 0 评论 -
在SQL里进行排序的时候,如何才能使用索引?
当SQL语句里使用order by语句进行排序的时候,如何才能用上索引呢?通常而言,假设有一个select * from table where xxx=xxx order by xxx这样的一个SQL语句,似乎应该是基于where语句通过索引快速筛选出来一波数据,接着放到内存里,或者放在一个临时磁盘文件里,然后通过排序算法按照某个字段走一个排序,最后把排序好的数据返回。但是这么搞通常速度有点慢,尤其是万一要排序的数据量比较大的话,还不能用内存来排序,如果基于磁盘文件来排序,那在MySQL里有一个术语,转载 2021-03-24 20:07:59 · 1117 阅读 · 0 评论 -
再来看看几个最常见和最基本的索引使用规则
最左侧列匹配,这个意思就是假设联合索引是KEY(class_name, student_name, subject_name),那么不一定必须要在where语句里根据三个字段来查,其实只要根据最左侧的部分字段来查,也是可以的。比如可以写select * from student_score where class_name=’’ and student_name=’’,就查某个学生所有科目的成绩,这都是没有问题的。但是假设写一个select * from student_score where subj转载 2021-03-24 20:07:15 · 131 阅读 · 0 评论 -
一步一图来深入理解联合索引查询原理以及全值匹配规则
来假设一下,有一个表是存储学生成绩的,这个表当然有id了,这个id是一个自增主键,默认就会基于它做一个聚簇索引,这个就不用多说了。然后呢,就是包含了学生班级、学生姓名、科目名称、成绩分数四个字段,平时查询,可能比较多的就是查找某个班的某个学生的某个科目的成绩。所以,可以针对学生班级、学生姓名和科目名称建立一个联合索引。接着画了一个图,这个图就展示了这个三个字段组成的联合索引的部分内容。有两个数据页,第一个数据页里有三条数据,每条数据都包含了联合索引的三个字段的值和主键值,数据页内部是按照顺序排序的。转载 2021-03-24 20:06:45 · 590 阅读 · 0 评论 -
一个表里是不是索引搞的越多越好?那你就大错特错了!
随着不停的在表里插入数据,就会不停的在数据页里插入数据,然后一个数据页放满了就会分裂成多个数据页,这个时候就需要索引页去指向各个数据页。然后如果数据页太多了,那么索引页里里的数据页指针也就会太多了,索引页也必然会放满的,此时索引页也会分裂成多个,再形成更上层的索引页。默认情况下MySQL建立的聚簇索引都是基于主键的值来组织索引的,聚簇索引的叶子节点都是数据页,里面放的就是插入的一行一行的完整的数据了!在一个索引B+树中,有一些特性,那就是数据页/索引页里面的记录都是组成一个单向链表的,而且是按照数据大小转载 2021-03-24 20:05:42 · 577 阅读 · 0 评论 -
插入数据时到底是如何维护好不同索引的B+树的?
在插入数据的时候,是如何维护不同索引的B+树的。首先呢,其实刚开始一个表搞出来以后,其实它就一个数据页,这个数据页就是属于聚簇索引的一部分,而且目前还是空的。此时如果插入数据,就是直接在这个数据页里插入就可以了,也没必要给它弄什么索引页,如下图所示:然后呢,这个初始的数据页其实就是一个根页,每个数据页内部默认就有一个基于主键的页目录,所以此时根据主键来搜索都是ok没有问题的,直接在唯一 一个数据页里根据页目录找就行了。然后表里的数据越来越多了,此时数据页满了,那么就会搞一个新的数据页,然后把根页面里的转载 2021-03-24 20:05:07 · 263 阅读 · 0 评论 -
针对主键之外的字段建立的二级索引,又是如何运作的?
基于主键的数据搜索非常清晰了,其实就是从聚簇索引的根节点开始进行二分查找,一路找到对应的数据页里,基于页目录就直接定位到主键对应的数据就可以了,这个其实很好理解。接着又会有另外一个疑惑了,那就是如果想要对其它的字段建立索引,甚至是基于多个字段建立联合索引,此时这个索引结构又是如何的呢?假设要是针对其它字段建立索引,比如name、age之类的字段,这都是一样的原理,简单来说,比如你插入数据的时候,一方面会把完整数据插入到聚簇索引的叶子节点的数据页里去,同时维护好聚簇索引,另一方面会为你其它字段建立的索引,重转载 2021-03-23 09:40:47 · 73 阅读 · 0 评论 -
更新数据的时候,自动维护的聚簇索引到底是什么?
首先呢,现在假设要搜索一个主键id对应的行,此时就应该先去顶层的索引页88里去找,通过二分查找的方式,很容易就定位到应该去下层哪个索引页里继续找,如下图所示:比如现在定位到了下层的索引页35里去继续找,此时在索引页35里也有一些索引条目的,分别都是下层各个索引页(20,28,59)和它们里面最小的主键值,此时在索引页35的索引条目里继续二分查找,很容易就定位到,应该再到下层的哪个索引页里去继续找,如下图所示:这里看到,可能从索引页35接着就找到下层的索引页59里去了,此时索引页59里肯定也是有索引条目的转载 2021-03-23 09:39:50 · 117 阅读 · 0 评论 -
索引的页存储物理结构,是如何用B+树来实现的?
如果表里的数据很多很多,比如有几百万,几千万,甚至单表几亿条数据都是有可能的,所以此时可能有大量的数据页,然后主键目录里就要存储大量的数据页和最小主键值。考虑这个问题的时候,实际上是采取了一种把索引数据存储在数据页里的方式来做的。也就是说,表的实际数据是存放在数据页里的,然后表的索引其实也是存放在页里的,此时索引放在页里之后,就会有索引页,假设有很多很多的数据页,那么此时就可以有很多的索引页,此时如下图所示:现在又会存在一个问题了,现在有很多索引页,但是此时需要知道,应该到哪个索引页里去找主键数据,是转载 2021-03-23 09:38:28 · 229 阅读 · 0 评论 -
基于主键的索引是如何设计的,以及如何根据主键索引查询?
现在假设要搜id=4的数据,怎么知道在哪个数据页里?没有任何证据可以告诉你它到底是在哪个数据页里啊!所以假设还是这个样子的话,也就只能全表扫描了,从第一个数据页开始,每个数据页都进入到页目录里查找主键,最坏情况下,所有数据页你都得扫描一遍,还是很坑的。所以其实此时就需要针对主键设计一个索引了,针对主键的索引实际上就是主键目录,这个主键目录呢,就是把每个数据页的页号,还有数据页里最小的主键值放在一起,组成一个索引的目录,如下图所示:现在有了上图的主键目录就方便了,直接就可以到主键目录里去搜索,比如要找i转载 2021-03-23 09:37:24 · 295 阅读 · 0 评论 -
不断在表中插入数据时,物理存储是如何进行页分裂的?
在一个表里不停的插入数据的时候,会涉及到一个页分裂的过程,也就是说,这个表里是如何出现一个又一个的数据页的。正常情况下在一个表里插入一些数据后,都会进入到一个数据页里去,在数据页内部,会组成一个单向链表,这个数据页内部的单向链表大致如下图所示:上面的图,里面就是一行一行的数据,刚开始第一行是个起始行,它的行类型是2,就是最小的一行,然后它有一个指针指向了下一行数据,每一行数据都有自己每个字段的值,然后每一行通过一个指针不停的指向下一行数据,普通的数据行的类型都是0,最后一行是一个类型为3的,就是代表最大的转载 2021-03-23 09:36:36 · 343 阅读 · 0 评论 -
不断在表中插入数据时,物理存储是如何进行页分裂的?
在一个表里不停的插入数据的时候,会涉及到一个页分裂的过程,也就是说,这个表里是如何出现一个又一个的数据页的。正常情况下在一个表里插入一些数据后,都会进入到一个数据页里去,在数据页内部,会组成一个单向链表,这个数据页内部的单向链表大致如下图所示:上面的图,里面就是一行一行的数据,刚开始第一行是个起始行,它的行类型是2,就是最小的一行,然后它有一个指针指向了下一行数据,每一行数据都有自己每个字段的值,然后每一行通过一个指针不停的指向下一行数据,普通的数据行的类型都是0,最后一行是一个类型为3的,就是代表最大的转载 2021-03-23 09:34:23 · 581 阅读 · 0 评论 -
假设没有任何索引,数据库是如何根据查询语句搜索数据的?
数据页之间是组成双向链表的,然后数据页内部的数据行是组成单向链表的,而且数据行是根据主键从小到大排序的。然后每个数据页里都会有一个页目录,里面根据数据行的主键存放了一个目录,同时数据行是被分散存储到不同的槽位里去的,所以实际上每个数据页的目录里,就是这个页里每个主键跟所在槽位的映射关系,如下图所示:假设要根据主键查找一条数据,而且假设此时数据库里那个表就没几条数据,那个表总共就一个数据页,那么就太简单了!首先就会先到数据页的页目录里根据主键进行二分查找(PS:不知道二分查找是什么的,建议去网上查一下,这转载 2021-03-23 09:32:53 · 1369 阅读 · 1 评论 -
磁盘数据页的存储结构
先来看看磁盘上的数据文件中的数据页的物理存储结构,因为后续研究索引的物理存储结构以及使用原理的时候,都是跟数据页的物理存储结构是有很大关联的。数据库最终所有的数据(包括我们建的各种表以及表里的数据)都是要存放在磁盘上的文件里的,然后在文件里存放的物理格式就是数据页,那么大量的数据页在磁盘文件里是怎么存储的呢?首先大家要明白的一点是,大量的数据页是按顺序一页一页存放的,然后两两相邻的数据页之间会采用双向链表的格式互相引用,大致看起来如下图所示:实一个数据页在磁盘文件里就是一段数据,可能是二进制或者别的转载 2021-03-23 09:32:00 · 841 阅读 · 0 评论