CMU15-445 Lecture #03: Database Storage (Part II)[译]
日志结构化存储(Log-Structured Storage)
滑动页面设计存在一些问题:
- 碎片化:删除元组可能会在页面中留下间隙。
- 无用的磁盘 I/O:由于非易失性存储的块定向特性,为了获取一个元组,需要读取整个块。
- 随机磁盘 I/O:磁盘读取器可能不得不跳转到 20 个不同的位置来更新 20 个不同的元组,这可能会非常缓慢。
如果我们正在处理一个只允许创建新数据而不允许覆盖的系统呢?基于日志的结构化存储模型就是基于这个假设工作,并解决了上述一些问题。
日志结构化存储:数据库管理系统(DBMS)不再存储元组,而只存储日志记录。
- 记录包含元组的唯一标识符、操作类型(PUT/DELETE),以及对于 PUT 操作,元组的内容。
- 要读取记录,DBMS 会从最新到最旧依次扫描日志文件,以找到元组最近的内容。
- 快速写入,潜在的缓慢读取。磁盘写入是顺序的,现有页面是不可变的,从而减少了随机磁盘 I/O。适用于仅追加的存储。
- 为了避免长时间读取,DBMS 可以拥有索引,以便跳转到日志中的特定位置。
- 日志最终会变得非常大。DBMS 可以定期压缩日志,仅保留多个页面中每个元组的最近更改。
- 在压缩后,不再需要排序,因为每个元组只有一个副本,所以 DBMS 可以按照标识符进行排序,以实现更快的查找。这称为排序字符串表(SSTables)。
- 在通用压缩中,任何日志文件都可以一起压缩。在层次压缩中,最小的文件位于 level 0。Level 0 文件可以压缩,从而创建更大的 level 1 文件,level 1 文件可以压缩为 level 2 文件,依此类推。
- 不足之处在于压缩代价昂贵,并且还会导致写放大(重复多次重写相同的数据)。
数据表示(Data Representation)
元组中的数据本质上只是字节数组,并且不跟踪属性的值是什么类型。由数据库管理系统(DBMS)负责知道如何跟踪和解释这些字节。数据表示方案是 DBMS 存储值的字节方式。 元组中可以存储五种高级数据类型:整数、可变精度数、定点精度数、可变长度值和日期/时间。
整数
大多数 DBMS 使用 IEEE-754 标准指定的“本机”C/C++类型存储整数。这些值具有固定的长度。
Example:INTEGER、BIGINT、SMALLINT、TINYINT。
可变精度数
这些是不精确的、可变精度的数值类型,使用 IEEE-754 标准指定的“本机”C/C++类型。这些值也具有固定的长度。 与任意精度数相比,可变精度数的计算操作更快,因为 CPU 可以直接对它们执行指令。然而,在执行计算时可能会出现舍入误差,因为某些数字无法精确表示。
Example:FLOAT、REAL。
定点精度数
这些是具有任意精度和比例的数值数据类型。它们通常以精确的、可变长度的二进制表示(类似于字符串)存储,并附带元数据,用于告知系统数据的长度和小数点位置等信息。 这些数据类型在舍入误差不可接受的情况下使用,但 DBMS 为获得这种准确性付出了性能代价。
Example:NUMERIC、DECIMAL。
可变长度数据
这些表示任意长度的数据类型。它们通常存储有一个标头,用于跟踪字符串的长度,以便轻松跳转到下一个值。它还可能包含数据的校验和。 大多数 DBMS 不允许元组超过单个页面的大小。那些允许的系统会将数据存储在特殊的“溢出”页面上,并使元组包含对该页面的引用。这些溢出页面可以包含指向其他溢出页面的指针,直到所有数据都可以存储为止。 一些系统会让您将这些大值存储在外部文件中,然后元组将包含对该文件的指针。例如,如果数据库存储照片信息,DBMS 可以将照片存储在外部文件中,而不是让它们占用大量空间。其中一个缺点是,DBMS 无法操作此文件的内容。因此,不存在持久性或事务保护。
Example:VARCHAR、VARBINARY、TEXT、BLOB。
日期和时间
不同系统的日期/时间表示方式各异。通常,它们表示为自 Unix 纪元以来的某个时间单位(微/毫秒)。
Example:TIME、DATE、TIMESTAMP。
系统目录(System Catalog)
为了使数据库管理系统(DBMS)能够解读元组的内容,它维护一个内部目录,用于提供关于数据库的元数据信息。
元数据内容:
- 数据库中存在的表和列,以及这些表上的任何索引。
- 数据库的用户以及他们拥有的权限。
- 关于表格的统计信息以及其中包含的内容(例如,属性的最大值)。
大多数 DBMS 将其目录存储在自身内部,使用与其表格相同的格式。它们使用特殊的代码来”引导”这些目录表。