数据库存储模型
在学习笔记1中,介绍了关系型数据库数据以tuple为单位在文件中进行存储。在关系型数据库中,此种存储方式被称为row store, 或者称为n-array storage model(nsm)。
行式存储适合OLTP类事务请求。此种请求的特点是写多读少,读的内容常是大规模数据中部分数据的多数/全部属性值。所以row store在一次索引查询下,就能将一个tuple完全读取。
OLAP类请求的特点是写少读多,查询大规模数据中的绝大部分,同时通常只访问一个tuple中的少数几个属性。当数据库是row store时会产生两个弊端:
- 产生许多的page的磁盘访问。
- CPU cache line效率低,每次会加载很多无用的属性。
因此对于OLAP类请求,数据库适合采用column store。
column store中如何恢复同一tuple的数据:
-
每一个属性使用固定大小的存储(大部分),使用offset来确定数据的tuple归属
-
针对每一个属性都绑定primary key
存储模型 | 优点 | 缺点 |
---|---|---|
row store | 适合插入、更新、删除;适合全属性或大部分属性的读 | 不适合大规模数据且少部分属性的读 |
column store | 减少磁盘IO;增强了CPU cache的性能;适合数数据压缩;可以更大利用CPU向量计算 | 数据插入、更新、删除慢;重构tuple代价高;解压缩有代价 |
数据的表征
在数据按照特定的格式在文件中存储后,数据库系统就可以将数据从文件/存储设备中加载出来。但是存储的数据是字节流,数据库需要按照其数据类型协议将字节解释为具体含义的数据值。通常的数据类型:
- INTEGER/BIGINT/SMALLINT/TINYINT
- 通常使用C/C++内置的整数数据类型来解释
- FLOAT/REAL vs. NUMERIC/DECIMAL
- FLOAT/REAL 使用IEEE-754标准/定长的浮点数表示;NUMERIC/DECIMAL通常被存储为可读的字符串,加载读取时解释为相应的浮点数
- VARCHAR/VARBINARY/TEXT/BLOB
- 抽象的解决方案是,使用一个header,header描述了数据的类型和长度,后面跟着实际的数据
- TIME/DATE/TIMESTAMP
- 存储为时间戳,根据不同的日期类型,在解释时进行相应的截断。
其中,VARCHAR/VARBINARY/TEXT是有可能数据大小超过page的大小,这打破了学习笔记1中的假设(tuple的大小应该小于page size)。此种情况下,使用overflow page来存储超过规定大小的数据,以此来保证上述的假设保持成立。
针对BLOB/CLOB数据的类型,tuple只是存储来一个关于此数据的指针,数据的数据则存储在文件系统中。这样潜在的风险是此数据在文件系统中是部分脱离了数据库系统控制的。没有数据的可靠性保证,没有事务保护。
数据模型的表征
在从文件/存储设备中加载到字节数据后可以解释得到具体的relation的数据。但是这个解释的依据从何而来。这个解释的依据就是数据库中数据的metadata,称为data dictionary/system catalog。
system catalog的主要内容有:
- relation、column的物理存储信息
- view定义、完整性约束信息
- 用户权限信息
- 索引信息
此种meta存储在数据库系统的特定位置,在关系型数据库中又通常表示为relation的形式,保持和整个数据库数据访问方式的统一。根据ANSI标准,统一命名为INFORMATION_SCHEMA,是一个只读的,存储了table, view, column与procedure的relation。每个数据库系统的实现也有自己特定的metadata。
但是数据库在启动时该如何去加载这metadata relation?这个relation的metadata又在哪里?这就变成了一个死循环。因此metadata的加载通常在数据库系统中是由固化的代码去加载,也就是说数据库系统的metadata的metadata是写死在数据库系统的代码中的。
参考:
CMU 15-445/645 04
《Database System Concepts 7th editon》