文章目录
一、存储介质的特点
- 数据库特点:大量数据,持久数据
- 内存不适合:容量、掉电
- 采用多级存储器,使用最多的辅存是磁盘
- 速度不匹配:在磁盘和内存之间设置缓冲区
- DBMS:基于局部性原理
- 提前读:提高并发度,不能减少IO
- 延迟写:减少IO次数
- 光盘:速度(转速低于磁盘),价格
- 磁带:顺序存取,后备存储器
- 磁盘:
- 块为基本单位:
- 减少IO次数,减少寻道时间和等待时间
- 减少间隙数目,提高磁盘空间利用率
- 寻道时间(最大)、等待时间、传输时间
- 块为基本单位:
二、记录的存储结构
1.记录相关
- 记录:商用数据库的基本数据单元,有定长和变长之分
- 记录的存储结构
-
相对法:字段长度不固定,用特殊字符隔开
- 优点:相对灵活
- 缺点:当字段中包含特殊字符时会出现误判
- 解决:转义字符
-
计数法:字段开头加上表示该字段长度的字段
-
定位法(positioning):每个字段按其最大可能长度分配定长位置
- 优点:简单
- 缺点:浪费空间
-
2.记录在物理块上的分配
-
在磁盘上,记录必须分配到物理块中
-
跨块存储、不跨块存储
-
B B B:物理块的有效空间大小
-
R R R:固定长的记录大小
-
p p p:块因子,即每个物理块可容纳的记录数目, p = [ B / R ] p=[B/R] p=[B/R]
-
零碎空间: B − p ∗ R < R B-p*R<R B−p∗R<R,寻址复杂
-
-
跨块存储(spanned block)
- 变长跨块存储
- 定长跨块存储
-
非跨块存储(unspanned block)
3.物理块在磁盘上的分配
-
早期数据库:逻辑相连的可能在物理上分开存储,降低效率
现代数据库:一次性申请所需空间
-
连续分配法:
- 将一个文件的块分配在磁盘的连续空间上,块的次序就是存储次序
- 有利于顺序存取多块文件
- 不利于文件的扩充
-
链接分配法
- 物理块未必连续,各个物理块之间用指针链接
- 有利于文件扩展
- 查找等操作的效率较低
-
簇集分配法
- 分成若干个簇集,簇内连续分配法,簇间链接分配
-
索引分配法
- 索引:每个文件有一个逻辑块号,与其物理地址相对照; 即一张映射表
4.数据压缩方法
-
消去零或空格符:
原始数据 压缩后数据 bbbbb #5 00000000 @8 -
串行替代法:反复出现的串用一个省略符代替
原始数据 压缩后数据 SELECTFROM @ SELECTFROM5 @5 -
索引法:重复出现的串单独存储,使用时用指针引用
三、文件结构和存取路径
1.访问文件的方式
-
传统的数据模型都以记录为基础,记录的集合构成文件,所以对数据库的操作最终要落实到对文件的操作
-
按照文件结构观点分为以下几类
- 查询文件全部记录
- 查询某一特定记录
- 查血某些记录
- 范围查询
- 记录更新
2.数据库对文件的要求
-
更多的DBMS会自己设计存储结构,原因如下:
-
传统文件系统不能提供实现DBMS功能所需的附加信息。DBMS为了实现其功能,须在文件目录、文件描述块、物理块等部分附加一些信息。
-
传统文件系统主要面向批处理,数据库系统要求即时访问、动态修改。这就要求文件的结构能适应数据的动态变化,提供快速访问路径。
-
传统文件系统服务对象特殊,用途单一,共享度低;数据库中的文件供所有用户共享,有些用途甚至是不可知的。
-
减少DBMS对OS的依赖,提高DBMS的可移植性。
-
传统文件系统一旦建立以后,数据量比较稳定;数据库中文件的数据量变化较大。
原始文件系统 DBMS所需文件系统 主要面向批处理 要求即时访问、动态修改 仅完成存储功能 需要附加信息 服务对象特殊,用途单一,共享速度低 数据库文件供所有用户共享,用途甚至不可知 完全依赖于操作系统 提高可移植性 建立后数据量较稳定 数据量变化较大
-
3.文件的基本类型
-
堆文件(heap)
-
最简单最早使用
-
按插入的先后顺序存放,不一定相邻
-
插入容易
-
查找不便:只能通过顺序搜索
-
适合“访问全部记录”,其他类型效率较低
- 排序后可使用二分查找,提高效率
-
删除操作较为困难
-
涉及到空间回收问题,后续记录需要搬移,影响对文件的操作效率
-
解决方案:对要删除的文件做标记,一段时间后记中删除记录,并对剩余记录进行重排
-
-
-
直接文件(direct)
- 将记录的某一属性值映射成记录的地址
- 该属性值成为散列键
- 键所映射的地址范围固定
- 太大:造成浪费
- 太小:不够用,出现冲突
- 地址重叠:处理时增加开销
- 只对散列键的访问有效
- 不利于处理变长记录:但是变长记录较少
- 很难找到通用的散列映射函数
- 把键映射成地址
- 两两记录之间的间隔大于记录长度
- 将记录的某一属性值映射成记录的地址
-
索引文件(indexed)
-
相当于一个映射机制,把关系中相应记录的某个(些)属性的键值转换为该记录的存储地址(或地址集)。
-
与散列的区别
- 索引文件有记录才占用存储空间,使用散列,空文件也占用全部文件空间。
-
索引本身会占用空间,但是索引一般较小
-
当索引或散列失效时,散列代价更大
-
常见分类
- 主索引:以主键为索引键
- 索引唯一
- 次索引:以非主键为索引建
- 提高查询效率
- 需要维护索引,增大开销
- 倒排文件:所有属性都建立索引
- 有利于多属性查找
- 数据更新时开销巨大
- 主索引:以主键为索引键
-
为了便于检索,索引项按照索引键排序
- 索引项 ≠ \neq =记录
非稠密索引
- 不为每个键值设置索引
- 节省索引的存储空间,代价是文件按索引键排序
- 一个文件只能为一个索引键建立非稠密索引
- 一般为主键
- 若干个记录组成一个单元存储区,单元存储区中的记录按索引键排序
- 单元存储区装满后,可向溢出区溢出(用指针指向溢出区)
- 但溢出太多时,指针链接次数增加,将导致数据库性能下降
- 可以建立多级非稠密索引
- 最高一级索引应尽量保证可以常驻内存
- 停止条件:当前表大小正好一次输入输出,即一个物理块大小
稠密索引
- 每个键值对应一个索引项
- 预查找功能:用记录的地址代替记录参与集合运算,减少I/O次数
- 至少两个以上条件
- 在物理块上相对分散
- 所占比重较大
- 索引溢出问题:每增加一个键值,就要增加一个索引项。索引也会有溢出的可能
- 在每个索引块中预留发展的空间
- 建立索引溢出区
- 若键值不唯一,则在最低级索引中每个键值可能对应一个地址集合
- 这些集合分散在不同的物理块内,则稠密索引的优点并不能体现
- 解决方法:簇集索引
簇集(clustering)索引
-
把键值相同的记录在物理地址上集中存放。
-
缺点:索引项按某个属性值排序,开销较大,要重新组织文件
-
4.索引总结
四、动态索引
- 从数据结构角度,静态索引是多分树,而动态索引是平衡多分树(B树),而目前我们常用的是B+树。
有关B树等的详细介绍会在后续文章中进行介绍。
-
B+树的特点:
- 每个节点最多有2k个键值,最少k个键值,k称为B+树的秩(order)
- 根节点至少有一个键值,其他节点至少有k个键值
- 在节点内部,键值有序存储
- 叶节点没有子女
- 其他内部节点若有J个键值,则会拥有J+1个子女;
- 所有叶节点处于树的同一层,即树始终是一棵平衡树
-
B+树实现主索引
- 两个组成部分:索引集&顺序集
-
节点一般是一个物理块
-
元组标识符tid:记录的地址,由块号和记录在块中的指针号组成
- base+offset寻址,方便记录在块内移动
-
查找流程:从树根开始,按照如下规则,自上而下搜索
1.若 K x < K 0 K_x<K_0 Kx<K0,则沿 P 0 P_0 P0所指的节点向下搜索;
2.若 K x > K n − 1 K_x>K_{n-1} Kx>Kn−1,则沿 P n P_n Pn所指的节点向下搜索;
3.若 K i − 1 < K x < K i K_{i-1}<K_x<K_i Ki−1<Kx<Ki,则沿 P i P_i Pi所指的节点向下搜索。
-
B+树实现次索引
- 把顺序集结点的tid换成指针,因为一个键值可能对应多个tid
-
B+树实现的是稠密索引
- 提供了顺序搜索的功能
- 非稠密索引概念源自于静态索引
-
问题讨论
-
搜索B+树所需的IO次数
-
搜索B+树所需的IO次数取决于它的级数(树的高度)
-
B+树的级数取决于索引属性不同键值的数目,而不是记录数目
-
-
若在某个索引集结点中找到了待查找记录相应的索引键值,是否还要继续遍历B+树
- 是需要的,因为索引集节点中的键值不一定是文件中当前所存在的键值,及内部节点仅相当于“导航路标”
-
-
存取路径
- 通过索引集进行树形搜索
- 通过顺序集进行顺序搜索
- 通过索引找到入口,再沿着顺序集顺序搜索