|
| 1 | +## Storage Model & Data layout |
| 2 | + |
| 3 | +1. 不同类型数据的表示: |
| 4 | + |
| 5 | + - INTEGER / BIGINT / SMALLINT / TINYINT |
| 6 | + |
| 7 | + 使用C/C++中的表示形式 |
| 8 | + |
| 9 | + - FLOAT / REAL(不能存储精确数值) vs. NUMERIC / DECIMAL(存储精确数值) |
| 10 | + |
| 11 | + 前者为IEEE-754标准,后者为[定点十进制数 fixed-point decimal](http://www-inst.eecs.berkeley.edu/~cs61c/sp06/handout/fixedpt.html) 如Postgres中的实现: |
| 12 | + |
| 13 | + ```c |
| 14 | + typedef unsigned char NumericDigit; |
| 15 | + typedef struct { |
| 16 | + int ndigits; // 数字的数量 |
| 17 | + int weight; // 首位的权 |
| 18 | + int scale; // 缩放系数 |
| 19 | + int sign; // 正/负/NaN |
| 20 | + NumericDigit *digits; // 实际数字的存储 |
| 21 | + } numeric; |
| 22 | + ``` |
| 23 | + |
| 24 | + - TIME / DATE / TIMESTAMP |
| 25 | + |
| 26 | + 32/64位的整形,Unix epoch (从1970年1月1日(UTC/GMT的午夜)开始所经过的毫秒/微秒数) |
| 27 | + |
| 28 | + - VARCHAR / VARBINARY / TEXT / BLOB |
| 29 | + |
| 30 | + 指针指向数据,头部带有长度和下一段的地址 以及数据类型 |
| 31 | + |
| 32 | +  |
| 33 | + |
| 34 | +2. NULL类型表示: |
| 35 | + |
| 36 | + - 特殊值 |
| 37 | + |
| 38 | + - Null Column Bitmap Header: |
| 39 | + |
| 40 | + 在元组头部存 一个bitmap,来表示该元组哪些属性位null |
| 41 | + |
| 42 | + - Per Attribute Null Flag |
| 43 | + |
| 44 | + 会浪费空间,因为每个属性多一个bit 需要重新字对齐 |
| 45 | + |
| 46 | +3. 字对齐的元组:(与结构体的字节对齐类似) |
| 47 | + |
| 48 | + - padding: 在属性的后面补充空的bits |
| 49 | + |
| 50 | +  |
| 51 | + |
| 52 | + - reordering: 重新排序,最后可能也需要padding |
| 53 | + |
| 54 | + 两种方法的性能对比:(插入测试) |
| 55 | + |
| 56 | + | 对齐方式 | 平均吞吐量 | |
| 57 | + | ---------- | ------------ | |
| 58 | + | 无对齐 | 0.523 MB/sec | |
| 59 | + | padding | 11.7 MB/sec | |
| 60 | + | reordering | 814.8 MB/sec | |
| 61 | + |
| 62 | +4. 存储模型: 可参考 **[Flexible-Storage-Model](https://github.com/F-ca7/Advanced-Database-Systems-Learning/blob/master/paper%20reading/engine/Flexible-Storage-Model.md)** |
| 63 | + |
| 64 | + - N-ary Storage Model (NSM) |
| 65 | + |
| 66 | + 物理存储的选择: |
| 67 | + |
| 68 | + 1. **Heap-Organized Tables** |
| 69 | + |
| 70 | + 元组存储在 叫做**堆**的blocks中,不需要有序 |
| 71 | + |
| 72 | + 2. **Index-Organized Tables** |
| 73 | + |
| 74 | + 元组存储在自己的主键索引中,和聚集索引不相同。 |
| 75 | + |
| 76 | + 优点: |
| 77 | + |
| 78 | + - 插入、更新、删除快(适合OLTP) |
| 79 | + - 适合查询整个元组 |
| 80 | + - 可以使用面向索引的存储 |
| 81 | + |
| 82 | + 缺点: |
| 83 | + |
| 84 | + - 不适合扫描表的大部分 以及 只查询一部分属性 |
| 85 | + |
| 86 | + - Decomposition Storage Model (DSM) |
| 87 | + |
| 88 | + 优点: |
| 89 | + |
| 90 | + - 只读取需要的数据,减少无用的工作 |
| 91 | + - 压缩更好 |
| 92 | + |
| 93 | + 缺点: |
| 94 | + |
| 95 | + - 插入、更新、删除慢,因为元组需要分裂或者拼接 |
| 96 | + |
| 97 | + - Hybrid Storage Model |
| 98 | + |
| 99 | + 两种选择: |
| 100 | + |
| 101 | + - Separate Execution Engines: 对NSM和DSM 分别使用最合适的执行引擎。返回结果时需要合并两个引擎的结果,从而对外表现在逻辑上是一个数据库。如果一个事务跨执行引擎,需要引入同步机制。 |
| 102 | + |
| 103 | + 如何确定哪些数据存入DSM中? |
| 104 | + |
| 105 | + - Manual: 由DBA指定哪个表存入DSM中 |
| 106 | + - Off-line: DBMS离线监控访问日志,然后决定哪些数据移入DSM |
| 107 | + - On-line: DBMS在运行期监控数据库访问,然后决定哪些数据移入DSM |
| 108 | + |
| 109 | + - Single, Flexible Architecture: 只用单一的执行引擎,同时适合NSM和DSM |
| 110 | + |
| 111 | +5. 表模式的更改 Schema Changes: |
| 112 | + |
| 113 | + - 添加列 |
| 114 | + |
| 115 | + - NSM: Copy tuples into new region of memory |
| 116 | + - DSM: 直接创建一个新列 |
| 117 | + |
| 118 | + - 删除列 |
| 119 | + |
| 120 | + - NSM 1: Copy tuples into new region of memory |
| 121 | + - NSM 2: 标记列为 deprecated,后期再清理 |
| 122 | + - DSM: 直接删除列 释放内存 |
| 123 | + |
| 124 | + - 更改列 |
| 125 | + |
| 126 | + 检查改变是否合法 |
| 127 | + |
| 128 | +6. 索引操作 |
| 129 | + |
| 130 | + - 创建索引 |
| 131 | + |
| 132 | + - 扫描整个表、填充索引 |
| 133 | + |
| 134 | + - 当一个事务在建立索引时,另一个事务需要记录修改表的裱花 |
| 135 | + - 当扫描完成后,锁住表;整合扫描过程中表的变更 |
| 136 | + |
| 137 | + - 删除索引 |
| 138 | + |
| 139 | + - 从catalog中直接删除索引(逻辑上删除) |
| 140 | + - 只有当删除该索引的事务 commit后才变得不可见 |
| 141 | + |
| 142 | +7. |
| 143 | + |
0 commit comments