数据库存储
文件存储
存储块/页
数据库表中的一行为一条逻辑记录,逻辑记录存储在操作系统数据文件中(这里是按行存储,也有一些数据库是按列存储的)
数据文件被划分为多个定长的存储单元,即数据库的块/页,是数据库的最小单元,数据库的块通常为文件系统中磁盘块的整数倍
硬件层面的页写入通常上保证原子性的,由于数据库的页是磁盘块的整数倍,因此需要额外措施来保证数据库层面页写入的原子性
数据库按页进行IO,文件和文件内偏移量可以确定一页
文件组织
文件组织指逻辑记录在文件中如何存储和组织
-
堆文件组织:记录可以存储在文件中的任何位置
- Linked List 实现方式:维护空闲页链表和已分配页链表
- Page Directory 实现方式:维护一个页目录,目录项记录页的位置
-
顺序文件组织:记录按搜索码顺序组织成链表,适合按搜索码的顺序检索记录。为了减少块访问数量,应尽可能地按搜索码的顺序存储记录,使得链表中逻辑上相邻的记录在物理上也相邻。
-
散列文件组织:将文件中的块视为桶,由散列函数确定记录存放在哪个块中。
-
B+树文件组织:对主键建立聚簇索引,将数据记录与B+树存放在一起。B+树的每个节点为一个块,叶子节点存储的是逻辑记录的数据而不是指向记录的指针,这样存储逻辑记录的块被B+树组织起来,而不是简单地排列在文件中。
思考B+树相比B树的优势:内节点只做索引作用不存放数据,存储的索引指针更多,树高更低,IO次数更少
Page Layout
文件和文件内偏移量可以唯一确定一页,每一页包括header和data两部分。
Page 主要有两种结构:
-
Tuple-oriented(slotted-pages)
Header记录元组数量,Page Size、Checksum、DBMS Version、Transaction Visibility、Compression Information 等meta-data
Slot Array记录Tuple的偏移量和长度
Slot Array向后生长,Tuples向后生长,Slot Array和Tuples相遇则页满
-
log-structured
写时不停向后添加日志记录,读时从后往前读,顺序写速度快,但通常需要采取措施加快读速度和压缩无效日志节省空间
- Inserts:store the entire tuple.
- Deletes:mark the tuple as deleted
- Updates:contain the attributes that were modified.
Tuple Layout
page_id号和offset/slot能唯一确定一个元组,元组不允许跨页,元组组成如下:
- Tuple Header:存储元组的meta-data,例如 Bit Map for NULL values,Visibility info (concurrency control)
- Tuple Data:元组真实数据