粉丝1.3万获赞4.7万

前面我们说印度 dp 默认的缩影数据结构就是毕加数,对吧?但印度 dp 对经典的毕加数做了优化。耐看图,他在原来毕加数基础上增加了一个指向相邻叶子节点的列表指针,标准的毕加数只有一个列表指针,对吧?但印度 dp 里面的毕加数有两个, 这样就可以通过叶子节点指针直接访问相邻的叶子节点,这样区间查询的效率会更高,更加利于数据的排序。同时你也会发现,每一个节点都存在数据页里面的,或者说块,也就是说一个节点就是一个数据页。还记得数据页吧,来看前面的图 表空间段曲页行,而且一个数据的大小默认是十六 k, 同时页也是应了 db 值班插座的最小单元。 也就是说,每查到一个节点,就会有一次磁盘 l, 都会从磁盘突出十六颗数据进来。所以我们前面讲二、查数的时候说数的成绩不能太深,因为越深的成绩意味着越多的磁盘 l。 既然每个节点 都是存在一个数据页里面的,而数据页的大小又是固定的,默认十六 k, 当然它是可以改的,这个我们现在不考虑。对于 b 数来说,它的非叶子节点要存数据,那它一页能存的指针和 k 肯定就更少,而毕加数非叶子节点不存数据,它一页能存的指针和 k 肯定就会更多。 每个阶段存的子弹和 k 多了,相同数据量的情况下, b 加速的高度肯定要比 b 数更低,输的高度低了,查询次数就少了, 实盘 io 自然也少了。而且不管我们用毕加速查询哪条数据,他都只能去接接点找,这样查询效率也会很稳定,不会出现有时候很快,有时候很慢的情况,这也是为什么赢得的必要选择毕加速作为所有数据结构。

数据库突然卡死, cpu 飙升,记住这四番谱,关键时刻能救命!第一,看谁在磨洋工执行 sure for process list, 重点看 time, 时间比较长的和 state, 不 处于 sleep 状态的现成。那些赖着不走的慢赛狗,一眼就能揪出来。 注意,如果没有 maccode, 那 就查一下 infoscreme 的 事务表,往往是那些只开启不提交的长事务才是托斯系统的隐形杀手。第二个,看谁被锁住了咽喉。 maccode 五点七以后自带了一个上帝视角,查一下 c s inodeb 的 look withs 这张表,看一下谁锁了谁锁了多久, code 是 什么看的一清二楚。 第三个,定罪,把找到的慢 c 口用 explain 跑下,是因为没走,所以还是说走了?全表扫描,证据确凿,开发,想甩锅都甩不掉。 第四步,秋后算账,打开所有的慢 c 口日记文件,通过 p t q d jess 分 析那段时间的所有慢 c 口,直接输出诊断报告哪些 bad c 口消耗了百分之九十的资源,一目了然。 排查故障虽然是一个抽丝剥茧的过程,但请尽注一条铁律,先止血,后看病,恢复业务优先。具体的排查 c 口和工具命令我放在评论区置顶了,关注我,每天帮你少走一个弯路。

java 后端面试,被问到应用 d b, 所以 为什么用必加数?而 ready 四的 check 用的是跳表数据结构。简单来说,必加数是为词盘优化的教科书,追求稳定高效的范围查询。 而跳表是为内存优化的灵活高手,追求简单可控的高性能读写。为了帮大家更系统性的准备面试,我整理了包括各阶段的面试题,掌握面试突击学习路线,以及精选的简历模板。需要的小伙伴已关六六六,我发你, 上次啊,有个粉丝去面试啊,被问到 email d b 的 缩影,为什么要用 b 加数而不用跳表?这其实考察的呢,是对数据结构的一个理解。跳表呢,其实是一个列表结构,添加数据的时候会随机的一个层级, 然后把每个层级相同的节点以列表的方式进行连接。查询的时候呢,从最外层开始查,思想跟二分法很类似, 我们可以去看一下私下,假如说我有这几个数据,然后每个数据呢,都有这随机的层级,那假如说我要去考二十七,先从最外层,我这里只有三层,就从第三层开始查, 二十七大于二十二,小于四十,所以呢,它在第二个区间啊,不用去前面去查了,然后二十七又是二十二到三十五之间,所以你看,我就找到了二十七,我只需要查询三次,它也跟我们的层级是有关系的。那么跳表呢?我这里只有三层,但是像 radis 的 叶子,它的底层跳表呢,有最高的三十二层 b 加数,那么它的叶子节点,它是我们完整的一个行数据,非叶子节点呢,只去存储我这个数的排序字段,查询的时候同样的从根目录开始查, 假如说我要查二十三,那我右边的节点我就不需要查询了,我只需要查询左边的节点,也只需要查询三层。跟树的高度也有关系,跳表跟 b 加树的思想都是用额外的空间来提升我们的查询性能,但是呢,有一定的区别。首先层高 b 加树,因为只有叶子节点才会有完整的层级,那么像 radis 它有最高的三十二层。 第二点,操作数据,操作数据,跳表要比 b 加数更快,因为数我是需要去维护它的排序的字段的, 那假如说我在中间添加一个数据,那我就需要做数的分裂与合并,而跳表不需要我随机一个层级,然后以一个列表的方式连起来就可以了。那么这也是为什么我们的 excel d b 所以 用 b 加数而不用跳表的原因。 英的 d b 是 需要跟磁盘进行 i o 的, 就我去查询数据的时候,那如果这个数据在内存里面没有,我需要跟磁盘进行 i o, 如果数的高度越高,那么 i o 的 次数也就越多。而 radis 的 接载数据类型用跳表是因为 radis 它是基于内存操作的,它没有跟磁盘 i o 的 概念, 所以跳表去添加数据呢,反而更简单。并且我再去便利数据的时候,因为是基于内存操作,所以它也不会有性能问题。

粉丝投稿,一诺 d b 锁影为啥会失效?有哪些场景?很多人只会背答案,却不知道面试官出这道题的真实目的。这道题实际是考察你对锁影原理的理解,以及 s q r 优化能力,下面我们一起来看具体解析。一诺 d b 锁影啊,为什么会失效?有哪些场景? 这个呢,也是在面试的时候经常被问到的一个问题,但是啊,大部分人呢,只会去背答案,不知道底层的原理。那么今天我们就花几分钟的时间来搞清楚 dp 的 缩影为什么能提升我们的查询性能。我们来举个例子啊,假如说我基于 edge 跟 name 两个字段创建一个联合缩影,那么这里面底层的话呢,它是采用的 b 加数存储结构,它的排序规则啊,是先根据 edge 去排序,如果 edge 相等,那么我才根据 name 来排, 所以这是它的一个排序规则。先根据第一个缩影字段排,如果第一个缩影字段相等,再根据第二个字段排,依次类推。那么走缩影能提升查询很关键的因素呢,就是我查询的字段是按顺序保存到 b 加数里面的, 比如说 edge 是 按顺序保存到我们这样一个 b 加数里面,所以根据 edge 查的时候呢,我能提升我的查询性能。 ok, 如果是无序的,那么我就需要便利所有的数据才能找到。比如你一来不去查询 edge, 我 就来查询 name, 那么这个 name 它是无序的,所以我必须要便利所有的数据,我才能找到你想找到的数据。所以啊,在查询的范围之内啊,这个字段如果是无序存储的,锁影就会失效,如果是有序的,那就可以走到我们的锁影。我们还是以刚才的锁影为例啊, edge 跟 name 两个联合锁影, 假如我只查 name, 灰灰,我不去查 edge, 对 吧?那我就不会走到这个联合锁影数,为什么呢?因为锁影数的规则是先根据 edge 排好,如果你一来就查 name, name 一定是无序的, 那么既然无序,那我就走不到,对吧?但是如果我加上 edge, 加上 edge 等于十八, edge 等于十八,你看啊, edge 我是 能够去基于这个缩影数,能快速的找到十八所在的位置的,比如说在这里面对八,那么一定是小于二十九, 那小于二十九我肯定去页一找对不对?那么我就能减少我的一个查询的一个页数。然后接下来我们再来看 edge 等于十八的时候, name 它也是个有序的,因为它的排序规则,先根据 edge 排, edge 相等, edge 等于十八一定相等。 好,那我再根据 name 排, name 也是有序的,所以他也能走到缩影。所以我们得到一个结论,字段能不能走到缩影,关键呢?就看字段在查询的范围之内是否是有序的,如果有序能,如果无序就不能,那么我们再来看常见的一些事项场景,比如说函数和表达式的操作, 那么对所引字段进行函数跟表达式的操作的时候呢?所以就会失效,比如说转化为 get, 对 吧?比如说乘以零点八,发生一些数学的运算函数,原因呢?其实很简单,函数式排序以后,那么它的规则跟最开始的规则是不一样的。 我们在工作中啊,尽量的去避免使用函数和表达式,可以去改用等价的直接表达, ok, 然后第二个范围查询,范围查询会使下一个缩影列失效,包括向百分号开头,百分号开头,同样的,它也是一个范围,因为它是个模糊查询,它能查出多个字段,对不对?它能查出多个数据。 好,那么举个例子,假如说查询 a 九大于十八, and name 等于灰灰,我建立的缩影是 a 九跟 name 的 联合缩影, a 九它是有序的,所以它一定能找到缩影。但是大于十八, 我查出来的数据大于十八,它是个范围,在这个大于十八的范围之内, name 它是有序的。为什么有序呢?因为只有 a 九相等,它才有序, 所以 name 它一定走不到缩影,因为在 a 九大于十八的范围之内, name 是 个无序的啊。那么这个呢,也就是我们经常讲的要遵循最做匹配原则, 如果不遵循最做匹配原则,就是前面 a 九它是一个范围,然后或者说 a 九这个字代我都没有去查,那么 name 一定走不到缩影,那么在工作里面呢,优先是使用前导列的等值查询。 好啦。第三个,数据类型的不匹配导致影视转换,比如说叉类型,影视转化为 int 类型,因为它们两个的排序规则是不一样的,所以它直接会导致缩影失效。音刚刚讲了,它的排序规则不同数据类型是不一样的, ok, 我 们要确保查询的条件数据类型跟字段的类型是一致的, ok。 第四个,欧尼尔节的多列调节, 如果分布在不同的锁芯里面,可能无法利用锁芯,比如说 a 九跟这一个磁带对不对?那么这两个磁带呢,在两个不同的锁芯里面,它不是一个联合锁芯啊,那么在优化期啊,它就会面临选择了, 如果我用 a 九做锁芯,那我这个我就没法去满足锁芯条件,如果用这一个磁带去作为一个锁芯,那么无法满足 a 九的锁芯条件, 所以呢,他最终可能会去选择全表扫描,全表扫描加合并结果可能会更加高效。那么解决方案呢?就是我们将 o 可以 拆分成多个查询,然后呢?并且 use, 对 吧?去合并,然后要么呢就是我去建立联合锁影,然后第三个,当然呢,锁影啊,它有一些不确定性,因为锁影能不能用其实是由优化器来决定的, 我们刚刚讲的是理论上的一个可能性,对不对?但是啊,最终决定呢,就是交给优化器来决定,优化器会选择他认为最优的一个方案来执行,所以有一些你可能认为他能走到锁钥,但是可能也走不到的,比如说锁钥覆盖不足,查询的字段没有被锁钥覆盖,导致需要回表去查询,那么可能导致性能下降, 对吧?那么解决方案呢,我们尽可能的使用覆盖锁钥,就是我们查询的字段尽可能的包含在我们的锁钥数里面。而第二个锁钥的选择性过低, 就是锁影的纯复率太高了,比如说性别自带就只有零跟一,那么优化器他会觉得,哎,我用你这个锁影跟没用一样,那么我还不如全标扫描。那么解决方案呢,我们在建立锁影的时候,尽可能的去避免一些选择性很低的一些自带去建立单独的锁影, 我们可以去建立联合锁影。然后接下来第三个查询的数据量过大,如果查询的数据量超过单表的百分之三十左右,当然这个不是一个确定的值,如果超过百分之三十左右,那么优化期会觉得,哎,我还不如不走锁影,那,那我直接,哎就走缺表。那么解决方案在工作里面呢,我们尽可能的去避免大数据的查询,采用枫叶等等的一些方式。

我们都知道 excel d b 的 缩影是 b 加数啊。呃,那你来跟我讲一下,为什么它的底层采用 b 加数而不用跳表?因为我们 release 的 z c 类型,它用的是跳表,而没有用 b 加数,你能跟我讲一下它们的区别吗?呃,因为这个 b 加数它能够支持范围查询,还有就是 b 加数的性能比较高, 跳表也支持范围查询,还有性能这一块,那像数据解锁的话,跳表应该比书更快啊。嗯, ok。 呃,要了解我们为什么英特力笔使用必加数啊, readis 的 有序集合选用跳表,我们需要从两个数据结构的一些特性去了解。担心你简历上的东西啊,讲不出来。我已经把面试经常问的一些基础干场景题都整理在了两百万字的面试文档里面,里面针对每个知识点啊,都有很详细的一个解析思路, 有需要的可以在评论区查看。首先我们看必加数啊,它的特点是非叶子节点只存储锁影键,而叶子节点才存储的是完整的数据。 这种设计啊,使得相同的数的高度下面呢, b 加数能够存储更多的数据量,因此同等数据规模时呢,它的层级更低,层级更低,意味着与显卡的 i o 次数就更少, 这个对数据库的缩影是非常重要的。我们再来看跳表,它的实现方式呢,是在插入的时候,我会随机决定节点的高度,各层呢,再以列表的方式来去连接,实现起来非常简单。但是呢,它的高度啊,是随机的,比如说 radis, 它的最高层数呃,可能达到三十二层。 这也就意味着在最后 i 的 情况下面可能需要去解锁三十二次,基于这些特性呢,我们就容易理解它们各自的一个选择了英特 b, 所以 选用 b 加数是因为数据库它需要跟磁盘进行 i o b 加数啊,凭借更低的数高,它能够去减少我们的 i o 次数, 从而满足高性能解锁的一个需求。如果选用跳表,那么它的访问模式呢,会导致大量的随机 i o 性能没法保障。那么 radis 为什么选用跳表呢?是因为 radis 它是个内存数据库, 所有的操作都是在内存里面进行的,它没有此款 i o 的 开销。跳表并且实现起来比较简单且天然的,它支持高效的去接查询和高频发的操作。因此啊,在内层的场景下面呢,我们使用跳表反而更加合适。 简单来讲,低价数就是为了此款 i o 优化的有序结构,而跳表是为内存操作设计的高效模型。两者数据结构的选择呢,本质上就是它的存储机制和性能,它的一个诉求来决定的。

java 面试备问, inno db 为啥需要 redo log? 随着时间推移,日制越来越大,该如何处理? inno db 需要 redo log 来确保事物持久性和崩溃恢复能力。它采用循环写入机制,当日制写满后会覆盖已落盘的旧记录, 因此不会无限增大阶段的面试题, java 面试突击学习路线以及精选的简历模板,需要的小伙伴已关六六六,我发你 首先 inl d b 啊,为什么需要 redo look 我 们都知道啊, inl d b 呢,为了我们的性能,所以呢,它有一个内存区间可以看到,那么叫做 buff。 好 数据呢,我们会先操作我们的内存, 然后呢再一步同步到我们的显卡,那么这个过程呢,也叫做刷脏,但如果说我改了内存以后宕机了,或者说停电了, 还没来得及刷新到此盘,那么数据就丢失了,那么这个时候呢, redog 就 发挥了它的作用,在操作内存的时候呢,我都会去记录一条 redog 日记,如果刷脏的过程中出现了档机数据没有同步到此盘,那么这个时候我可以从 redog 去找到。可能很多人有疑问啊, 那么为什么我们的内存刷新到的时候,为什么不去同步刷呢?那么同步去刷的话呢,有几个问题啊,第一个,因为我们的内存跟我们的显卡,它的交互最小单位是配集液,只要配集液里面有一条数据改动,那么整个配集液我都需要进行显卡同步,所以它的性能要比 redog 要慢很多好。那么第二个呢, 同样的,你改动的数据,它是随机的,它不是一个顺序的,所以随机 i o 呢,要比顺序 i o 要慢很多, 但是 redog 它是个顺序的,因为它只是追加,它是日制追加,所以呢,速度方面啊, redog 要比我直接将数据同步到此盘要快很多,这是 redog 它的作用,为什么要用 redog? 那 么接下来有个问题, 每一次操作我都需要去追加到 redog, 那 么 redog 它会越来越大,越来越大,那么这个时候它会占用很大的空间, 怎么办?那么要回答这个问题啊,首先呢,我们要知道 redog 它的作用是要保证我内存的数据没有同步到此盘的时候,那我要能找得到,那么如果说这个数据已经同步到此盘了,那么这个 redog 是 不是就没用了呢?是的,所以啊, redog 它的大小是固定的, 它只需要保证没有刷脏成功的数据,它采用的是一个覆盖写的方式。好,我们可以去看一下啊。首先呢, redog 它分配的内存空间呢,我们是可以查的,你是可以配置的, 可以去看一下,它有这样一个配置,就是 redo log 的 一个容量大小。好,默认是这么多对不对?好,然后它基于这个大小,它会拆分成三十二个文件,这个呢是它写的方式,我们也可以去看它的词牌文件来。 好,你看这里面它会有一个 redo log 的 一个词牌文件,我们进去看一下, 那么他会基于我们这个设置的大小,会平均的分配三十二个文件。这些文件呢,你看有些有后缀,有些没后缀,那么他的意义呢?是有一些已经写了,那么有一些他是没写的,是空的,是备用文件。那么假如说我这三十二个文件都写满了以后,那么我又会重新 从第一个开始写,叫做覆盖写,因为我没必要去记录所有的数据,只要我这个数据同步到此盘,那这个 redo log 呢?就没用了。那么可能很多人又问老师,假如说我都写完了,但是我这些数据我都没有同步到此盘,怎么办?所以呢,在刷脏的过程中啊,有一个 redo log 自适应, 那么就是我会根据你 redo log 一个写的情况来进行一步的刷脏,比如说我发现 redo log 满了,然后你这些数据都没有刷脏,那么我就会去触发一次刷脏的过程。那么这个呢,就是 excel db 里面的 redo log, 我 们需要去知道的点,记得关注我,了解更多实用干货知识。我是灰灰,我们下期再见。

前天啊,有个去快手面试的小伙伴私信我,他遇到这样一个问题,英诺 db 如何解决换读问题? 这个问题呢,确实不是很好回答,因为在实际应用中啊,很多同学几乎都不关注数据库的事物隔离性,所有的问题基本上都是 ciod 一把锁。那么今天呢,我们来看一下关于璎珞 db 如何解决换读这个问题,普通人和高手是如何回答的?普通人回答, 呃,我印象中啊,就是英诺 db 里面的换读是通过 mvcc 机制来解决的, mvcc 是一种乐观所的机制,然后他能够在通过这种版本的方式去控制并发事物的这个竞争,然后从而去解决这种。呃,这种就是因为多 多事物竞争的带来的一个一个一个换读的一个问题。嗯,对高手的回答。 这个问题呢,我会从三个方面来回答。第一个,麦塞口的事物隔离级别,麦塞口有四种事物隔离级别,这四种事物隔离级别分别代表当存在多个事物并发冲突的时候,可能会出现的脏毒、不可重复毒、换毒的一些问题。 而英诺 db 在啊啊的隔离级别模式下,解决了换读这样一个问题。第二个,什么是换读呢?换读是指在同一个事物中,前后两次查询相同范围的时候,得到的结果不一致。 我们来看这个图,第一个数五里面,我们执行了一个范围查询,这个时候满足条件的 数据只有一条,而在第二个事物里面,他插入了一行数据,并且进行了提交。接着第一个事物再去查询的时候,得到的结果比第一次查询的结果多出来了一条数据,注意,第一个事物的第一次和第二次查询都在同一个事物里面, 所以啊,换读会带来数据一致性的问题。第三,英诺 db 是如何去解决换读问题的呢?英诺 db 里面引入了间隙锁和 next key rock 机制去解决换读问题。为了更清晰的说明这两种锁以及它是怎么样去解决换读的,我来举一个例子, 假设现在存在这样一个 b 加速的所以结构,这个结构里面有四个所以元素,分别是一、四、七和十。当我们通过组建所以查询一条记录,并且 对这条记录通过 fold 加锁的时候,像这样这个时候呢,会产生一个叫记录锁,也就是行锁,锁定 id 等于一这个锁影。 下面一个图,被锁定的记录在所释放之前,其他事物是无法对这一条记录做任何操作的。 前面我们说过对换读的定义啊,换读是指在同一个事物中,前后两次查询相同范围的时候,得到结果不一致。 注意,这里强调的是范围查询,也就是说啊,璎珞 db 引擎要解决换堵的问题,必须要保证一个点,就是如果一个事物通过这样一条查询语句进行锁定的时候, 另外一个事物再执行这样一条因色的语句,需要被主色,直到前面获得所的事物 被释放。所以在英的 db 中设计了一种间隙锁,它的主要功能是锁定一段范围内的锁引记录。像这样一个图, 当对查询范围 id 大于四 and id 小于七这个范围加锁的时候,会针对 b 加速中的四和七这个开区间的范围加间隙锁,意味着在这种情况下,其他事物对这个区间的数据进行插入、更新、删除都会被锁住。 但是还有另外一种情况,比如像这样,这条查询语句是针对 id 大于四这个条件加锁, 那么他需要锁定多个所以区间。所以这个情况下,英诺 db 引入一个叫 next key lock 机制。 next key lock 呢,相当于间隙所和 记录所的合集记录所锁定存在记录的行,间隙所锁住的是记录行之间的间隙,而 next k 呢,锁住的是两者的和。像这样一个图, 每个数据行上的非唯一所引列都会存在一把 next rock, 当某个事物持有这一行数据的 next rock 的时候,会锁住一段在 左开右臂区间的数据。因此啊,当通过 id 大于四这样一个范围查询加锁的时候, e 诺 db 呢,会去加一个 next 可锁,锁定的区间范围是四、 七、七和十,十到正无穷大。记住,是左开右臂区间。间隙锁和 next logo 的区别是在于加锁的范围。间隙锁锁定的是两个锁影之间 间隙,而 next look 呢,会锁定多个所引区间,它包含记录所和间接所。当我们使用范围查询不仅仅命中 record 记录,还包含了 get 间隙的时候,在这种情况下 使用的就是零件锁,也就是 next key look, 它是 mexico 里面默认的行锁算法。第四,简单总结一下,虽然呢, inter db 里面通过间隙锁的方式解决了换读的问题, 但是枷锁之后一定会影响到并发的性能。因此啊,对于性能较高的一些业务场景,我们可以把隔离级别设置成 rc, 那么这个级别中就不存在借机所,也就不存在这样的一个性能的影响。以上呢,就是我对于一诺 db 如何解决换读问题的一个理解。好的,通过这个面试题啊,可以发现大厂面试对于 基本功的考核还是非常严格的,不过呢,不管是为了应付面试,还是为了以后职业规划的一个铺垫, 技术能力的高低都是你在这个行业的核心竞争力。本期的普通人 vs 高手系列的视频呢,到这里就结束了,我是麦克,一个工作了十四年的家外程序员,咱们下期再见。

那咱们在买菜购物当中呢,默认的存储引擎是 node dp, 那 咱们就聊聊 node dp, 所以 咱们先写个缩写,你看一下,这个大伙肯定都写过嘛,你拿这个例子来说吧啊,前面加个 select 字段,对吧?就是一个等值匹配的例子, 就这儿写吧。 select 这是字段名称嘛?那 from 呢?表明这是产条件 id 零九九, 对吧?咱们执行它 id, 咱们一般都认为它是主键吗?这个主键呢,肯定是非空且非一的,对不对?那这个其实涉及一个问题,啥问题呢?就是咱们还是回到刚才,你去通过 mac 一个音频去操作,然后这个文件的时候,他实际上需要把这个文件加载到 mac 当中去,对吧? 哎,这么一个关系,那你加载的话就有 type o, 那 这块如果说咱把整个文件全加载进来,那是不是有点高?打文字的意思,太亏心了,对吧?用不了那么多。所以说咱们 mac 当中有个有概念叫耶,就是耶, 它支持四八四六三十二,完了呢,你看合适的是多少,它按十六 k 米。还有这么个逻辑, ok, 那 两种情况查找,第一个呢,以主键为搜索条件,就在一个数据页当中进行查找。 这两种情况,第一种情况呢,咱们根据主键来查找 需要的数据,那主键的特点非空且为一嘛,对不对?那就可以在咱们页面当中使用二分查找法,快速定位到对应的槽,然后在遍地槽对应的分组中记录,即可快速查找指定记录。所以这里提到一个算法, 因为主键咱们如果说用默认的都是自增的嘛,这有主键自增,那么在树叶当中就可以通过二分查找嘛,这会有一个算法,二分查找法 或者折半查找,这个效率很高啊,对不对? ok, 那 这会呢,咱们还有个问题,如果这块尾弦它不是,这个不是主键了,那你不是主键的话,这边呢?比如说咱们弄一个 a 值十八的, 那你现在的话艾特的十八很多,他肯定不是主键,对吧?那不是主键的话,他该怎么查找呢?那因为在书页当中并没有对应对非主键,建立所有的页目录,这个页目录跟他一会再说啊,所以我们无法通过二维查找法快速定位像素槽,那这种情况呢,只能从最小记录 就开始找呗,对吧?依次遍历单元当中的每条记录,然后呢对比每条记录中是不是符合这种搜索条件,那也就是呢,可以理解为全面扫描效率是最低的, 低的太低了,对吧?那每条线路呢,在物理磁盘上并不是连续的,而是通过链板的形式连起来的,这样会充分利用磁盘的存储空间,在逻辑上保证连续即可。啊,就这么个东西,那咱们看看这个到底这个锁匙是怎么存的啊? 首先咱们看一个锁尾键,首先知道这个东西两种查询方式,你再换的话,有个主键,还有个非主键,对吧?然后用上面这个这空空,那如果呢,咱们去调电 飞出去,则要进行全表扫描,对吧?那这效率呢?太低了。那这里还提了一个关键概念,这里面用到了一个东西,数据结构叫列表, 这列表都干啥的,一会再说啊。 ok, 那 比如说呢,咱们现在有这么一个缩尾句,我创建一下,对吧?就可瑞创个表黑吧,咱们叫。所以 这边给你个字段,比如说呢, c 一, 我一等类型的 n t c 二呢,也是 n t c 三呢,咱们来个叉类型的,随便写点啊,然后呢,把这个 c 一 搞成主键 and prime key, 完事,这是一个简单的创口语句,对吧?有这么 c 三, c 三三个四段,把 c 一 搞成主键,这也以它为例子啊,咱们看它是怎么去存储这个东西的。 ok, 那 实际上呢,咱们在落盘之后,他的一个基本结构分那么几个部分啊,首先这个值肯定放到词典当中嘛,对吧?就 c 一, c 二, c 三,再 c 一, 就这样,然后 c 二, 再嘚一下 c 三,这是数据库表示表当中的各个的值,自断的值,对吧?这个存到字牌上去,这也没问题。同时呢,这会还有几个,一个叫 ucar type, 记录类型也会放在记录行当中, p i p, 这是咱们所谓的记录类型。还有一个叫 nice record, 这玩意呢,也是一个说明的一个字段, nice 按 c r d, 它表示呢,记录的下条记录。 哎,当然还有个字段啊,不能说字段了,说字段不严谨。它还有一个数据就是其他消息咱得放后边, 其他信息放在这, ok 了,那这块呢,有啥 type? 这块有这么几个值, 一个叫零,跟咱们写 java 代码似的,那 java 是 不是咱们有编程代码,之后有咖啡杯杯,还有宝贝,这是个 java 文件,那这个同样是说明我这一行记录它是什么类型的。哎,这个零,如果这是填零的话,它就表啥呀?咱们普通记录, 那如果是二的话,一呢?先不聊他一是,所以,对吧?咱们写二,二的话呢,表示咱们当前的最小记录, 那有二的肯定来三的对不对?三的话就表示咱们的最大记录的值, 哎,这个字段了解之后,咱们再往外看,这表啥意思呢?下一条?下一条记录的地址相对于本条记录的地址偏量,谁有个地址偏量方便找下条记录。 哎,这有了,那其他信息当中呢?这也包含了隐藏列,这三是数据啊,比如说 c 一 等于一,它等二,它等于字母 c, 对 吧?都可以。那其他信息当中呢,就包含了咱们一些隐藏列的消息,隐藏列的值及呢?记录的额外值, 隐藏的,咱们后期会涉及到,对吧?那如果表当中你没有去主动的添加主键,那就会把这个主键放在隐藏列当中,这么个逻辑。 ok, 这几个了解之后,咱们再来看,把这个显示样式呢更改一下,给它竖起来,哎,就这么来,这咱们记录类型, 这好看一些。 nice 的 值拿下来, c 二的值也拿下来, c 三其他信息, 那它的取值就是零一二三,反正用到零二三,普通记录最好的最大值,这是一个地址的偏移量,那这是咱们数据库存的啥值?其他消息呢?有一个东西叫隐藏列,对吧? ok, 那再画的话咱再来画啊,这是一条记录,对吧?把一些记录呢放在页里,显示的意图是,就这个东西吧,是一条,那你多了之后是变这德行了就,哎,这像啥?你瞅瞅是不是跟表一样了?那把这玩意放在一个数据当中,咱们刚才说了,你数据样大小,十六 kb, 十六 kb, 咱们这么一组织,这样我就放这些东西是不就可以了,对吧? ok。