列数据库和行数据库
列数据库和行数据库的根本区别是如何存储数据
- 列数据库把某个record的不同column存储在不同的file中,而行数据库把同一个record的数据逐行地存放在file中
- 行式存储把一行中的数据值串在一起存储起来,然后再存储下一行的数据,列式存储把一列中的数据值串在一起存储起来,然后再存储下一列的数据
- 受早期的硬件条件和使用场景限制,主流的事务型数据库(OLTP)大多采用行式存储,近些年分析型数据库(OLAP)的兴起,列式存储更为流行
行数据库:
以下图为例,所有的列依次排列构成一行,以行为单位存储,再配合以 B+ 树或 SS-Table 作为索引,就能快速通过主键找到相应的行数据。
行式存储对于 OLTP 场景是很自然的:大多数操作都以实体(entity)为单位,即为增删改查一整行记录,显然把一行数据存在物理上相邻的位置是个很好的选择
列数据库:
通常对于 OLAP 场景,一个典型的查询需要遍历整个表,进行分组、排序、聚合等复杂分析操作,这样一来按行存储的优势就不复存在了。而且分析型 SQL 通常并不会用到所有的列,仅仅对其中某些需要的列做运算,那些无关的列也不得不参与扫描。
列式存储就是为这样的需求设计的。如下图所示,同一列的数据被一个接一个紧挨着存放在一起,表的每列构成一个长数组。
列式存储对于 OLTP 不友好,一行数据的写入需要同时修改多个列,但对 OLAP 场景有着很大的优势:
- 当查询sql语句只涉及部分列时,只需要扫描相关的列
- 将column存在不同的file之后,每一列的数据都是相同类型的,彼此间相似性较大,对列数据压缩的效率较高,压缩比通常能到10%~25%,可以大大减轻数据读取的压力,提高响应速度
- 除去字符串类型,其他类型的字段通常是固定长度的,而且在磁盘和内存的字节顺序通常是一致的,可以直接映射,省去了解析的过程。而在行存储中,只要有变长的字段存在,需要逐行逐字段的解析。
- 列式存储可以向量化的处理一个字段。可以将一个列的一整块连续数据读入CPU cache,效率非常高。而且,可以利用CPU的向量化处理指令并行处理一些常用计算,譬如求和,比较大小等等。而这一切在行存储中都做不到。