NOTE
1.5 数据模型
1. 什么是数据模型 - 计算机和现实世界之间的抽象层,描述了数据的特征 2. 为什么需要数据模型 - 计算机不能直接处理现实的事物,所以,人们只有将现实事物转成数字化的数据,才能让计算机识别处理 3. 数据模型有哪些 - 概念模型:描述现实世界的信息 - 逻辑模型:内存中或磁盘中的数据结构 - 物
这是历史学习笔记,可能存在过时或不完整的理解。
1. 什么是数据模型
- 计算机和现实世界之间的抽象层,描述了数据的特征
2. 为什么需要数据模型
- 计算机不能直接处理现实的事物,所以,人们只有将现实事物转成数字化的数据,才能让计算机识别处理
3. 数据模型有哪些
- 概念模型:描述现实世界的信息
- 逻辑模型:内存中或磁盘中的数据结构
- 物理模型:序列化到磁盘或网络中的字节流
4. 概念模型
4.1. 关系模型
- 数据被组织成关系(表),其中每个关系是元组(行)的无序集合
- 关系有一对一、一对多、多对多
- 适用于连接操作
4.2. 文档模型
- 以一个文档为单位进行存储,支持数组和文档嵌套。可以简单得理解为就是json
- 不会为存储的数据强制一个模式
- 适用于一对多且大多数记录之间不存在关系
4.3. 图模型
- 一个图由两种对象组成:顶点+边
- 不会为存储的数据强制一个模式
- 适用于多对多关系,任意事物都可能与任何事物相关联
5. 逻辑模型
- 根据使用场景可以分为OLAP和OLTP
| 属性 | 事务处理 OLTP | 分析处理 OLAP |
|---|---|---|
| 面向的用户 | 终端的Web用户 | 内部的数据分析师 |
| 实时性读写要求 | 高 | 低 |
| 事务性要求 | 高 | 低 |
| 分析要求 | 低、简单 | 高、复杂 |
| 处理的数据 | 当前时间点的数据 | 随时间推移的历史事件 |
| 主要读取模式 | 查询少量记录,按键读取 | 在大批量记录上聚合 |
| 主要写入模式 | 随机访问,写入要求低延时 | 批量导入(ETL),事件流 |
| 数据集尺寸 | GB ~ TB | TB ~ PB |
| 数据结构分类 | 根据读多还是写多分为log-structured和page-oriented | 列存储 |
- 数据存储在磁盘还是内存
- 由于数据量大和磁盘 vs 内存(原链接已失效)可知,必须使用磁盘
- 选用哪种数据结构呢?
- 根据使用场景而定
5.1. log-structured
5.1.1. 使用场景
- 事务处理
- 写多读少
5.1.2. 是什么
- 日志:也就是一个 仅追加(append-only) 的数据文件
- 可以看作K-V对数据库
- 顺序写磁盘效率高
- 为了避免磁盘空间用完,将日志分为特定大小的segment。在一定时机对segment进行压缩,合并相同的key,对齐旧的key
- 如何解决大量写
- 磁盘顺序IO
- 同一条数据占用多份空间
- 后台定时合并压缩数据
- 单个文件还是多个文件
- 单个文件。固定大小基于阈值划分如何合并数据
- 把文件加载到内存中排序在合并效率低
- 保证文件内的数据有序
- 如何保证文件有序
- 插入时即排好序
- 如何排序
- 红黑树、跳表、B树
- 磁盘顺序写还是慢
- 在内存中缓存一段时间,在批量写入磁盘
- 如何保证内存数据不丢
- redo log
- 怎么读取数据
- 按照倒序读取最新数据,一旦读取到数据,则停止读取逻辑
- 读优化方案
- 每个 SSTablel中添加布隆过滤器,用来快速判断读取的数据是否存在,加速读效果
- 采用分区存储 SSTable,除了L0层外,每层之间的数据不重叠,层内数据有序存储
- 压缩优化,提升压缩效率,防止压缩过程阻塞读逻辑
- 三大问题
- 读放大:读操作需要从新值到旧值依次读取,再此过程中会涉及不止一次IO。特别是范围查询时,导致影响很明显
- 空间放大:在 LSM Tree中,所有的写都是通过 append的方式来记录因此导致所有过期或者删除的数据不会立即清理掉,仍然LSM读写、空间放大会占据空间,所以称为空间放大
- 写放大:在上述过程中,为了减少读放大和空间放大。通常采用后台合并数据的方式来解决。但该过程也引入了写放大。实际写入磁盘的据大小和程序要求写入的数据大小之比。正常情况下,压缩合并的过程中对一条数据会涉及多次写,所以称为写放大
5.1.3. 实现
- LSM.md(关联笔记尚未公开)
5.2. page-oriented
5.2.1. 使用场景
- 事务处理
- 读多写少
5.2.2. 是什么
- 磁盘如何快速读写
- 顺序IO
- 每条数据顺序追加后怎么快速读
- 每条记录维护一个索引
- 每条记录维护一个索引太大了
- 这里之所以每条记录需要一个索引是因为每条记录是变长的
- 那么改成定长的就好了,比如磁盘划分成固定大小的block
- Block内的每条记录维护索引,Block之间使用no
- Block大小:操作系统page
- Block索引存不存:存,聚簇(数据和索引放一块)或者非聚簇
- 这里之所以每条记录需要一个索引是因为每条记录是变长的
- 如何支持排序、范围查询
- 写入时对数据排序
- B+树 vs B树
- B Tree.md(关联笔记尚未公开)
- 结论
- 找到了一种在磁盘上和内存中都可以维护的数据结构:b+树。内存中采用b+树实现数据的存储,磁盘上的任何一页对应內存中的b+树-个节点(索引页映射成片孑节点。数据页映射成叶孑节点。最后直观思路得以实现
- 核心原因:树高度低、每次磁盘IO相对较少、不同请求时间复杂度比较平均
5.2.3. 实现
5.3. 列存储
5.3.1. 使用场景
- 分析处理的场景经常读取大量行但取少量字段,因此适合用列存储结构
5.3.2. 是什么
- 不要将所有值从一行存储在一起,而是将每个列中的所有值存储在一起
- 同样的列会更加易于压缩存储,这样就可以减少大量的工作
6. 物理模型
- 序列化:将内存中的数据结构转换成磁盘中存储或网络中传输的字节序列
- 反序列化:将磁盘中存储或网络中传输的字节序列转换成内存中的数据结构
6.1. 文本格式
6.1.1. JSON
- JSON区分字符串和数字,但它不区分整数和浮点数,也不能确认精度
- 不支持二进制字符串
6.1.2. XML
- 不能区分恰好由数字组成的数字和字符串
- 不支持二进制字符串
6.1.3. CSV
- 不能区分恰好由数字组成的数字和字符串
6.2. 二进制格式
6.2.1. Thrift
6.2.2. ProtocolBuf
6.2.3. Avro
6.3. 文本 vs 二进制
| 文本 | 二进制 | |
|---|---|---|
| 优点 | 可读性高并且自描述 | 消息紧凑;解析开销小 |
| 缺点 | 消息冗余;解析开销大 | 可读性差 |
7. 数据查询语言
7.1. 命令式查询
- 详细的命令机器怎么(How)去处理一件事情以达到你想要的结果(What)
7.2. 声明式查询
- 只告诉你想要的结果(What),机器自己摸索过程(How)
7.3. Map-Reduce查询
- 将大批量的数据拆分执行(Map),然后再将结果合并成最终结果(Reduce)
8. 参考
- 什么是数据模型?数据模型简介 - 知乎
- ddia/ch2.md at master · Vonng/ddia
- 命令式编程(Imperative) vs声明式编程( Declarative) - 知乎
- 存储与索引------《Designing Data-Intensive Applications》读书笔记3 - HappenLee - 博客园
- ddia/ch3.md at master · Vonng/ddia
- OLAP与数据仓库------《Designing Data-Intensive Applications》读书笔记4 - HappenLee - 博客园
- 编码与模式------《Designing Data-Intensive Applications》读书笔记5 - HappenLee - 博客园
- ddia/ch4.md at master · Vonng/ddia