disk manger
磁盘,存储引擎
buffer pool manager
缓存池管理
access methods
operator execution
执行器
query planning
优化器
non-volatile
非易失性,就是当电流关闭后,存储的数据不会消失
数据库就是非易失性的,
dbms管的就是从内存到磁盘的相互过程
一般来说,volatitle
是random access
和byte-addressable
就是可以精确的选择位置和按地址存的
non-volatitle
是sequential access
顺序访问,block-addressable
存东西都是按块存的
我们要把用户对数据库的随机的存取转化成对硬盘的连续的存取
允许用户存等同硬盘大小的数据,而不是内存的大小
因为读写磁盘是很费时间的,所以要让数据库尽量少的读写磁盘
当然也有的数据库是面向内存的,这种是很快的,但是相应存的内容就要少
面向硬盘的数据库实际上就是在磁盘中的文件,
加入一个文件过大,就有了分页
第一页存每一页的指针
ok,在分页中如何查找数据呢,内存先调入页表,从页表内容中找到所在位置,调入指定页,加载指定页
memory mapping
(mmap)这个东西可以提供一个虚拟内存,就是内存太小,当需要访问一个东西的时候,软件从虚拟内存中调过来一个连接,不需要自己加载,一切都是软件来执行的,但是当连接过多,内存满了之后,系统就会卡住
mmap对并发写也有问题
DBMS就是要实现一个自己管理的,不要让os来管理,os不是你的朋友,
数据库存储的两问题,
- 数据库文件的存储样式
- 数据库如何管理数据从内存到磁盘的相互转入
三个问题:
- 文件存储
- 页布局
- 行布局
操作系统不关心文件的内容是什么
storage manager
存储管理引擎,一般引擎都将文件看作一个一个页
page
页,就是一小块数据,因为数据库文件太大了,所以要切成一个一个小的数据块(页)来管理
对于大多数数据库来说,每一个页的功能是固定的,存什么就是什么
有些数据库是可以自己分辨自己的页是干什么的
每一个页都有其自己唯一的id
页在不同的地方大小不同,对于硬盘通常是4kb,操作系统通常是4kb,数据库是512b~16kb,
硬盘页是最小的存储块,加入说写入4kb内容,写失败了,那么就说明这4kb都失败了,但是更大的话,就不一定是哪一个失败了
heap
堆文件(页),一般堆文件的组织方式分为链表和页目录
linked list
:
page directory
:
ok,这就是文件长什么样
一般一个page包含header和data,
header包含page size
,checksum
(校验码),DBMS Version
,Transaction Visiblity
(与事务和并发有关),Compression Information
(页的压缩方式)
有些数据库要求每个页是自解释的
数据区有两种存储方式:
tuple-oriented
strawman idea
就是类似用可以插队的方式,但是会出现问题,就比如删除会出现碎片垃圾
slotted pages
就是每一个页前面要存很多的slotted,就是一个类似与索引或者目录的东西(就是数据可以是乱的),数据从后往前存,slot从前往后存,但是删除的时候要整理,不然会出现碎片
record id
就是每一条数据都有id,加前缀(页编码+slot号)
ok,这就是页布局的样式
tuple(元组)在硬盘上面来看就是一堆乱码,只有dbms解析之后才知道这个东西有什么意义
tuple也是header+Attribute Data
一般如果数据是NULL,就会在header标识,
不要在tuple上面存储表的结构
存储的时候是故意按照列的顺序来存的,当然这样做是有特殊的原因的
如果不按照这样存储的话可能效率会更高的
因为当外键存在的时候进行操作总要join,所以将有外键的表存成一个表再进行存储,就是denormalized tuple data
当然,这种操作不一定好
CREATE TABLE foo (
a INT PRIMARY KEY,
b INT NOT NULL,
);
CREATE TABLE bar (
a INT,
c INT PRIMARY KEY,
# a:REFERENCES foo(a),
);
ok,这就是数据样式
总结:
- 数据库是基于
page
组织的 - 找到
page
的不同方式 page
是如何存储的tuple
是如何存储的