列存与行存

转载自:
  https://blog.csdn.net/qq_26091271/article/details/51778675?locationNum=8&fps=1

1. 为什么要按列存储

  列式存储(Columnar or column-based)是相对于传统关系型数据库的行式存储(Row-basedstorage)来说的。简单来说两者的区别就是如何组织表:
  Row-based storage stores atable in a sequence of rows.
  Column-based storage storesa table in a sequence of columns.

  下面来看一个例子:
列存与行存
  从上图可以很清楚地看到,行式存储下一张表的数据都是放在一起的,但列式存储下都被分开保存了。所以它们就有了如下这些优缺点:

行式存储 列式存储
优点 1.数据被保存在一起; 2.INSERT/UPDATE容易 1.查询时只有涉及到的列会被读取; 2.投影(projection)很高效; 3.任何列都能作为索引
缺点 1.选择(Selection)时即使只涉及某几列,所有数据也都会被读取 1.选择完成时,被选择的列要重新组装;2.INSERT/UPDATE比较麻烦

2. 数据压缩

  列式存储很容易通过字典表压缩数据。下面之前提到的那张表本来的样子。经过字典表进行数据压缩后,表中的字符串才都变成数字了。正因为每个字符串在字典表里只出现一次了,所以达到了压缩的目的。
列存与行存

3.查询执行性能

  下面通过一条查询的执行过程说明列式存储(以及数据压缩)的优点:
列存与行存
关键步骤如下:

  1. 去字典表里找到字符串对应数字(只进行一次字符串比较)。
  2. 用数字去列表里匹配,匹配上的位置设为1。
  3. 把不同列的匹配结果进行位运算得到符合所有条件的记录下标。
  4. 使用这个下标组装出最终的结果集。

写入:

  • 行存储的写入是一次完成,数据的完整性因此可以确定。
  • 列存储需要把一行记录拆分成单列保存,写入次数明显比行存储多。
  • 行存储在写入上占有很大的优势

数据修改:

  • 行存储是在指定位置写入一次,列存储是将磁盘定位到多个列上分别写入。
  • 行存储在数据修改也是占优的

数据读取:

  • 行存储通常将一行数据完全读出,如果只需要其中几列数据,就会存在冗余列
  • 列存储每次读取的数据是集合中的一段或者全部。
  • 由于列储存的数据是同质的,这种情况使数据解析变得容易。行存储则复杂的多,因为在一行记录中保存了多种类型的数据,数据解析需要在多种数据类型之间频繁转换,这个操作很消耗cpu
  • 所以列存储的解析过程中更有利于分析大数据

  显而易见,两种存储格式都有各自的优缺点:
  行存储的写入是一次性完成,消耗的时间比列存储少,并且能够保证数据的完整性,缺点是数据读取过程中会产生冗余数据,如果只有少量数据,此影响可以忽略;数量大可能会影响到数据的处理效率。
  列存储在写入效率、保证数据完整性上都不如行存储,它的优势是在读取过程,不会产生冗余数据,这对数据完整性要求不高的大数据处理领域,比如互联网,犹为重要。

  那么什么时候应该使用行式存储?什么时候应该使用列式存储呢?
  如果你大部分时间都是关注整张表的内容,而不是单独某几列,并且所关注的内容是不需要通过任何聚集运算的,那么推荐使用行式存储。原因是重构每一行数据(即解压缩过程)对于HANA来说,是一个不小的负担。
  列式存储的话,比如你比较关注的都是某几列的内容,或者有频繁聚集需要的,通过聚集之后进行数据分析的表。