转载自:阮一峰的网络日志html
全部应用软件之中,数据库多是最复杂的。
MySQL的手册有3000多页,PostgreSQL的手册有2000多页,Oracle的手册更是比它们相加还要厚。
可是,本身写一个最简单的数据库,作起来并不难。Reddit上面有一个帖子,只用了几百个字,就把原理讲清楚了。下面是我根据这个帖子整理的内容。数据库
数据以文本形式保存
segmentfault
第一步,就是将所要保存的数据,写入文本文件。这个文本文件就是你的数据库。
为了方便读取,数据必须分红记录,每一条记录的长度规定为等长。好比,假定每条记录的长度是800字节,那么第5条记录的开始位置就在3200字节。
大多数时候,咱们不知道某一条记录在第几个位置,只知道主键(primary key)的值。这时为了读取数据,能够一条条比对记录。可是这样作效率过低,实际应用中,数据库每每采用B树(B-tree)格式储存数据。网络
什么是B树?数据结构
要理解B树,必须从二叉查找树(Binary search tree)讲起。
二叉查找树是一种查找效率很是高的数据结构,它有三个特色。优化
1. 每一个节点最多只有两个子树。 2. 左子树都为小于父节点的值,右子树都为大于父节点的值。 3. 在n个节点中找到目标值,通常只须要log(n)次比较。
二叉查找树的结构不适合数据库,由于它的查找效率与层数相关。越处在下层的数据,就须要越屡次比较。极端状况下,n个数据须要n次比较才能找到目标值。对于数据库来讲,每进入一层,就要从硬盘读取一次数据,这很是致命,由于硬盘的读取时间远远大于数据处理时间,数据库读取硬盘的次数越少越好。
B树是对二叉查找树的改进。它的设计思想是,将相关数据尽可能集中在一块儿,以便一次读取多个数据,减小硬盘操做次数。
B树的特色也有三个。ui
1. 一个节点能够容纳多个值。好比上图中,最多的一个节点容纳了4个值。 2. 除非数据已经填满,不然不会增长新的层。也就是说,B树追求"层"越少越好。 3. 子节点中的值,与父节点中的值,有严格的大小对应关系。通常来讲,若是父节点有a个值,那么就有a+1个子节点。好比上图中,父节点有两个值(7和16),就对应三个子节点,第一个子节点都是小于7的值,最后一个子节点都是大于16的值,中间的子节点就是7和16之间的值。
这种数据结构,很是有利于减小读取硬盘的次数。假定一个节点能够容纳100(a)个值,那么3(n)层的B树最大能够容纳1030300((a+1)^(n-1)*a)个数据,若是换成二叉查找树,则须要20层!假定操做系统一次读取一个节点,而且根节点保留在内存中,那么B树在100万个数据中查找目标值,只须要读取两次硬盘。spa
索引
操作系统
数据库以B树格式储存,只解决了按照"主键"查找数据的问题。若是想查找其余字段,就须要创建索引(index)。
所谓索引,就是以某个字段为关键字的B树文件。假定有一张"雇员表",包含了员工号(主键)和姓名两个字段。能够对姓名创建索引文件,该文件以B树格式对姓名进行储存,每一个姓名后面是其在数据库中的位置(即第几条记录)。查找姓名的时候,先从索引中找到对应第几条记录,而后再从表格中读取。
这种索引查找方法,叫作"索引顺序存取方法"(Indexed Sequential Access Method),缩写为ISAM。它已经有多种实现(好比C-ISAM库和D-ISAM库),只要使用这些代码库,就能本身写一个最简单的数据库。设计
高级功能
部署了最基本的数据存取(包括索引)之后,还能够实现一些高级功能。 (1)SQL语言是数据库通用操做语言,因此须要一个SQL解析器,将SQL命令解析为对应的ISAM操做。 (2)数据库链接(join)是指数据库的两张表经过"外键",创建链接关系。你须要对这种操做进行优化。 (3)数据库交易(transaction)是指批量进行一系列数据库操做,只要有一步不成功,整个操做都不成功。因此须要有一个"操做日志",以便失败时对操做进行回滚。 (4)备份机制:保存数据库的副本。 (5)远程操做:使得用户能够在不一样的机器上,经过TCP/IP协议操做数据库。 (完)