菜单

SQLite中的B-Tree实现细节解析

2018年11月16日 - sqlite

SQLite在存储在外部的数据库是盖B-Tree来集团的。关于B-tree的细节,参考
**
** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
** “Sorting And Searching”, pages 473-480. Addison-Wesley
** Publishing Company, Reading, Massachusetts.
**

JavaScript分别轻重缓急写:在JavaScript中变量、函数都是分别轻重缓急写的,例如:

中心思想是文件包含的每一样页还包括N个数据库入口以及N+1个对子页的指针。文件分为多页存储。为什么这么干,因为内存分页管理机制闹得。外存中每个页就是B树的一个节点。

复制代码 代码如下:

| Ptr(0) | Key(0) | Ptr(1) | Key(1) | … | Key(N-1) | Ptr(N) |

Ptr(0)指向的页上的具备的key的价值都自愧不如Key(0)。所有Ptr(1)指向的页与子页的持有的key的值都大于Key(0),小于Key(1)。所有Ptr(N)指向的页与子页的key的值都大于Key(N-1),等等。

以掌握一个一定的key,需要从磁盘上以O(long(M))来读取,其中M是树的阶数。内存中觅不交了,就来缺页中断。
首要是缓解内存中找不至的题材。一方面换下有。一方面换进去一些。换进去的下如果找到她们再也硬盘的谁页面及什么。
(B树的助益就是是契合为用块儿存储的存储设备上。)利用所以,可以领略她们等于谁页面上。

在SQLite的贯彻着,一个文件可以蕴涵1单或的过独的BTree。每一个BTree由其的根页的目来标识。所有入口的key和数目整合了行载荷(payload)。数据库的同样页有一个稳住的实用载荷总量。如果负荷大让了先行设定的价值,那么余下的字节就会见叫积存于溢起页上。一个进口的可行载荷再增长前为指针(the
preceding
pointer)构成了一格(cell)。每一样页都发出一个小头部,包含了Ptr(N)指针和另外一些信,例如key和数据的轻重。

格式细节
一个文本分为了多只页。第一页叫做页1,第二页叫做页2,一潮类似推。页的个数为0意味着从来不页。页的轻重缓急可以由512

65536。每一样页或者是一个btree页,或者是一个freelist页,或者是一个溢出页。
先是页一定是一个btree页。第一页的前面100只字节包含了一个特殊的首部(文件头),它是者文件之描述。
文件头的个数如下:
** OFFSET SIZE DESCRIPTION
** 0 16 Header string(首部字符串): “SQLite format 3\000”
** 16 2 Page size in bytes(页的字节数).
** 18 1 File format write version(文件写操作的本子)
** 19 1 File format read version (文件读操作的版)
** 20 1 Bytes of unused space at the end of each
page(每一样页结尾未使用的字节)
** 21 1 Max embedded payload fraction(最要命之内置有效载荷分片)
** 22 1 Min embedded payload fraction(最小之嵌入有效载荷分片)
** 23 1 Min leaf payload fraction(最小之页中载荷分片)
** 24 4 File change counter (文件变化计数器)
** 28 4 Reserved for future use (保留字节)
** 32 4 First freelist page (第一个freelist页)
** 36 4 Number of freelist pages in the file
(本文件中freelist页的个数)
** 40 60 15 4-byte meta values passed to higher layers()
**
享有的平头都是多方面的。

老是修改文件时,文件变化计数器都见面增多。这个计数器可以让其它进程知道何时文件于改了,他们之cache是否需要清理。

不过充分厝有效载荷分片是同样页的保有可用空间,被标准B-tree(非叶数据)表底独的一个所能够下的总量。值255表示100%。默认情况下,一格(cell)的绝大量叫拘也,至少有4格才能够填满一页。因此,默认的极端要命厝负荷分片是64。

一经一致页的有效性载荷大被了最为特别实用载荷,那么余下的多少将让贮存到溢出页。一旦分配了一个溢出页,有或会见发生广大数额吧为更换到这个溢出页,但是非会见叫格cell的大小小于最小嵌入有效载荷分片的。

太小页有效载荷分片与极端小嵌入有效载荷分片类似,但是它们是使叫LEAFDATA
tree中的叶节点。一个LEAFDATA的极度酷实用载荷分片为100%(或者是价值255),它不用还首部指定。

BTree的各一样页为分成三片段:首部,格(cell)指针数组,和格cell的始末。页1还会见在页首部有100字节的文件头。
**
** |—————-|
** | file header | 100 bytes. Page 1 only.
** |—————-|
** | page header | 8 bytes for leaves. 12 bytes for interior nodes
** |—————-|
** | cell pointer | | 2 bytes per cell. Sorted order.
** | array | | Grows downward
** | | v
** |—————-|
** | unallocated |
** | space |
** |—————-| ^ Grows upwards
** | cell content | | Arbitrary order interspersed with freeblocks.
** | area | | and free space fragments.
** |—————-|
**
页首部如下图所示:
**
** OFFSET SIZE DESCRIPTION
** 0 1 Flags. 1: intkey, 2: zerodata, 4: leafdata, 8: leaf
** 1 2 byte offset to the first freeblock
** 3 2 number of cells on this page
** 5 2 first byte of the cell content area
** 7 1 number of fragmented free bytes
** 8 4 Right child (the Ptr(N) value). Omitted on leaves.
**
表明位定义了这个BTree页的格式。叶leaf标志意味着马上无异页没男女children。zerodata0数据表示这无异于页才包含key,没有数量;intkey标志意味着key是一个平头,而且是叫贮存在格cell首部的key大小处,而非是以使得载荷区域。

格cell指针数组从页首部开始。格cell指针数组包含0只或多余2只字节的数字,这个数字代表格cell内容区域中之格cell内容由文本开始位置的偏移量。格cell指针式有序的。系统大力确保空闲空间在最后一个格cell指针之后,这样可保新的格cell可以快捷的增长,而未用重新整理(defragment)这无异页。

格cell内容存储在页的结尾,且是向文件之苗头方向加强。

当格cell情区域被之未以的半空中被集及链表freeblocks上。每一个freeblock至少有4个字节。第一单freeblock的撼动在页首部给有了。Freeblock是增序的。因为一个freeblock至少发生4独字节,所有以格cell情区域之3个或是啊嘿与3单底莫就此空间不能够在于freeblock链表上。这些3独或少于3个底空空间为号称碎片。所有碎片的总个数被记录下来,存储于页首部的偏移7的位置。

** SIZE DESCRIPTION
** 2 Byte offset of the next freeblock
** 2 Bytes in this freeblock
**

格cell是可转移长的。格cell于积存于页的末尾格cell内容区域。指向格cell的cell指针数组紧跟以页首部的后边。格cell不必是连连或有序的,但是格cell指针是连续与平稳的。

格cell内容充分利用了而换长整数。可易长整数是起1顶9只字节,每个字节的低7各类让利用。整个整数由8各项之字节组成,其中第一单字节的第8各受清零。整数最要之字节出现在率先独。可易长整数一般不多受9单字节。作为同种植特殊情形,第九只字节的享有8独字节都见面给当是数额。这就允许了64个整数变编码为9单字节。
** 0x00 becomes 0x00000000
** 0x7f becomes 0x0000007f
** 0x81 0x00 becomes 0x00000080
** 0x82 0x00 becomes 0x00000100
** 0x80 0x7f becomes 0x0000007f
** 0x8a 0x91 0xd1 0xac 0x78 becomes 0x12345678
** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081
本篇文章来源 Linux公社网站(www.linuxidc.com)
原文链接:http://www.linuxidc.com/Linux/2012-11/75009.htm

function myfunction(){}和
function myFunction(){}不同

若可能感兴趣之稿子:

JavaScript中基本目标Array、Object等也是分轻重缓急写。

单引号和双引号:这个题材在学SQLServer拼接字符串”select * from page
where
name=’lida'”时即发出困惑:后面都的老三单’到底是双引号在前面还是单引号在前边?学的几近了掌握,双引号是编程语言应用的,单引号是SQLserver标明字符串类型的。但是于JavaScript中单引号和双引号没有新鲜的别,都好就此来创造字符串,但是一般情况下JavaScript使用单引号,HTML等属于性值必须以对引号;同时单引号可以概括对引号,双引号也足以包括单引号
;特殊情况下欲动用转义符号”\”,例如:

复制代码 代码如下:

var temp='<p class=”nameA”>What\’s this?’;

括号的意向:和另语言同样,JavaScript中的括号同样是少数种植意向,一种植是用作分隔符使用,例如:(1+1)*2;第二种植意向是表达式,例如:(1+1)*2;第二栽意向是表达式,例如:(function
(){})()中被分开的括号为分隔符,后面的括号表示执行措施。

函数的调用和援:

复制代码 代码如下:

var temp=myFunction();
var temp=myFunction;

坐括号可以象征履,第一个temp代表的是myFunction函数的归来值,而第二单temp代表的是将myFunction赋值给temp。例如:

复制代码 代码如下:

<script type=”text/javascript”>
// JavaScript Document
(function () {
function $() {
alert(“正在Buffering!”);
}
window[‘LD’] = {}
window[‘LD’][‘$’] = $;
}
)();
window.onload = LD.$;
</script>

网页可以健康加载,因为就代表将$方法赋值给了window.onload,页面加载运行的是祥和编排的$()函数;如果把当下句换成
window.onload=LD.$();运行结果如下;首先会显“正在Buffering”,然后是
图片 1
立即是以onload事件无欲返回值,而$函数也未尝回值,所以会见造成没有实现的不当。
换行:无论是用啊种引号创建字符串,中间都未克包含强制换行符。如下:

复制代码 代码如下:

var temp='<h2 class=”nameA”>List</h2>
<ol>
</ol>’

拿导致解析错误,可以采取\或+来换行:

复制代码 代码如下:

var temp='<h2 class=”nameA”>List</h2>\
<ol>\
</ol>\
‘;

大括号和分行可选:
每当JavaScript中分号以及大括如泣如诉不是必须的,例如alert(‘A’);和alert(‘A’)没有区别,但是于if语句处运行产生异样,最好不用简单。
重载
JavaScript是冲原型的面向对象,没有如C#被的重载,在斯我们好叫替换,同名函数无论参数个数是否同样,程序都见面履行最后一个同名函数,例如function
alert(){}将会晤覆盖JavaScript中之alert函数。
作用域和闭包
可到自己之博客《JavaScript中之来意域链和闭包》。

http://www.bkjia.com/Javascript/331958.htmlwww.bkjia.comtruehttp://www.bkjia.com/Javascript/331958.htmlTechArticleJavaScript区分大小写:在JavaScript中变量、函数都是区分大小写的,例如:
复制代码 代码如下: function myfunction(){}和 function myFunction(){}不同
J…

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图