目录

存储方式比较

优缺点比较

行存与列存实验

选择建议

注意事项


好多人最开始学习数据库的时候,是关系数据库,数据以表格形式存储,一行表示一条记录。其实这种就是典型的行存储(Row-based store),将表按行存储到磁盘分区上。
而一些数据库还支持列存储(Column-based store),它将表按列存储到磁盘分区上。

存储方式比较

这两者的差异如下图:

从图上可以看出,行存的时候,一行记录的属性值存储在临近的空间,然后接着是下一条记录的属性值。
而列存的时候,单个属性所有的值存储在临近的的空间,即一列的所有数据连续存储的,每个属性有不同的空间。
这里,大家可以自行思考一下这两种那种更适合查询,那种更适合修改?
在数据写入上的对比:
1)行存储的写入是一次完成。写入建立在操作系统的文件系统上,可以保证写入过程的成功或者失败,数据的完整性因此可以确定。
2)列存储由于需要把一行记录拆分成单列保存,写入次数明显比行存储多,再加上磁头需要在盘片上移动和定位花费的时间,实际时间消耗会更大。所以,行存储在写入上占有很大的优势。
3)还有数据修改,这实际也是一次写入过程。所以,数据修改也是以行存储占优。
在数据读取上的对比:
1)行存储通常将一行数据完全取出,如果只需要其中几列数据的情况,就会存在冗余列,出于缩短处理时间的考量,消除冗余列的过程通常是在内存中进行的。
2)列存储每次读取的数据是集合的一段或者全部,不存在冗余性问题,查找内容连续存储,特别适合投影。
3) 两种存储的数据分布。由于列存储的每一列数据类型是同质的,不存在二义性问题。比如说某列数据类型为整型(int),那么它的数据集合一定是整型数据。这种情况使数据解析变得十分容易。相比之下,行存储则要复杂得多,因为在一行记录中保存了多种类型的数据,数据解析需要在多种数据类型之间频繁转换,这个操作很消耗CPU,增加了解析的时间。所以,列存储的解析过程更有利于分析大数据。
4)从数据的压缩以及更性能的读取来对比。同一列的数据,数据类型一致,列存的模式下就适合数据压缩,不同的列可以采用不同的压缩算法,压缩存储就会带来IO性能的提升。

优缺点比较

表的存储类型是表定义设计的第一步,客户业务类型是决定表的存储类型的主要因素。行、列存储模型各有优劣,建议根据实际情况选择。

行、列存优缺点及适用场景比较见下表:

行存

列存

优点

数据被保存在一起。INSERT/UPDATE容易。

  1. 查询时只有涉及到的列会被读取。
  2. 投影(Projection)很高效。
  3. 任何列都能作为索引。

缺点

选择(Selection)时即使只涉及某几列,所有数据也都会被读取。

  1. 选择完成时,被选择的列要重新组装。
  2. INSERT/UPDATE比较麻烦。
  3. 点查询不适合。

适用场景

  1. 点查询(返回记录少,基于索引的简单查询)。
  2. 增、删、改操作较多的场景。
  1. 统计分析类查询 (OLAP,比如数据仓库业务,此类型的表上会做大量的汇聚计算,且涉及的列操作较少,关联、分组操作较多)。
  2. 即时查询(查询条件不确定,行存表扫描难以使用索引)。

行存与列存实验

openGauss支持行列混合存储,可以在建表的时候指定存储方式。下面我们进行一下实验。
实验环境:华为云服务器+openGauss企业版3.0.0 + openEuler20.03
创建行存表custom1 和列存表custom2 ,插入50万条记录。

openGauss=# create table custom1 (id integer,name varchar2(20));
CREATE TABLE
openGauss=# create table custom2 (id integer,name varchar2(20)) with (orientation = column);
CREATE TABLE
openGauss=# insert into custom1 select n,'testtt'||n from generate_series(1,500000) n;
INSERT 0 500000
openGauss=# insert into custom2 select * from custom1;
INSERT 0 500000

我们看下两个表的存储空间,比较Size列,可以看出列存表比行存表占用存储空间小的非常多,差不多是行存表空间的1/7。

openGauss=# \d+ List of relations Schema |    Name    | Type  | Owner |    Size    |               Storage                | Description
--------+------------+-------+-------+------------+--------------------------------------+------------- public | custom1    | table | omm   | 24 MB      | {orientation=row,compression=no}     | public | custom2    | table | omm   | 3104 kB    | {orientation=column,compression=low} |

比较下插入一条新记录的时间,列存表要稍微慢一点。

openGauss=# explain analyze insert into custom1 values(1,'zhang3'); QUERY PLAN
----------------------------------------------------------------------------------------------- [Bypass] Insert on custom1  (cost=0.00..0.01 rows=1 width=0) (actual time=0.059..0.060 rows=1 loops=1) ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.001..0.001 rows=1 loops=1) Total runtime: 0.135 ms
(4 rows) openGauss=# explain analyze insert into custom2 values(1,'zhang3'); QUERY PLAN
----------------------------------------------------------------------------------------------- Insert on custom2  (cost=0.00..0.01 rows=1 width=0) (actual time=0.119..0.120 rows=1 loops=1) ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.001..0.002 rows=1 loops=1) Total runtime: 0.207 ms
(3 rows) 

最后删除测试表。

openGauss=# drop table custom1;
DROP TABLE
openGauss=#drop table custom2;
DROP TABLE

感兴趣的同学可以自己测试更多的的场景,比如创建大宽表、update表等场景测试下。

选择建议

  • 更新频繁程度:数据如果频繁更新,选择行存表。
  • 插入频繁程度:频繁的少量插入,选择行存表。一次插入大批量数据,选择列存表。
  • 表的列数:一般情况下,如果表的字段比较多即列数多(大宽表),查询中涉及到的列不多的情况下,适合列存储。如果表的字段个数比较少,查询大部分字段,那么选择行存储比较好。
  • 查询的列数:如果每次查询时,只涉及了表的少数(<50%总列数)几个列,选择列存表。(不要问剩下的列干啥用,甲方说有用就是有用。)
  • 压缩率:列存表比行存表压缩率高。但高压缩率会消耗更多的CPU资源。

注意事项

列存由于特殊的存储方式,使用时约束比较多。比如,列存表不支持数组、不支持生成列、不支持创建全局临时表、不支持外键,支持的数据类型也会比行存要少。使用时需要查看对应的数据库文档。

聊一聊数据库的行存与列存相关推荐

  1. greenplum 数据库如何增加列_Greenplum行存与列存的选择以及转换方法-阿里云开发者社区...

    背景 数据在数据库中的存储形式多种多样,比较常见的如 1. PostgreSQL的堆表,以行的形式存储,(当变成字段压缩后的长度超过数据块的四分之一时,会以TOAST的形式存储到TOAST表). 2. ...

  2. postgres默认安装后有哪些表_Greenplum 行存、列存,堆表、AO表的原理和选择

    行存和列存的原理 什么时候选择行存 什么时候选择列存 堆表和AO表的原理 什么时候选择堆表 什么时候选择AO表 测试对比行存deform和列存的性能差别 如何查看表的存储结构 Greenplum支持行 ...

  3. Greenplum 行存、列存,堆表、AO表的原理和选择

    转载自: https://github.com/digoal/blog/blob/master/201708/20170818_02.md?spm=a2c4e.11153940.blogcont179 ...

  4. 行存、列存,堆表、AO表性能对比 - 阿里云HDB for PostgreSQL最佳实践

    标签 PostgreSQL , GIS , PostGIS , Greenplum , 空间检索 , GiST , B-Tree , geohash 背景 <Greenplum 行存.列存,堆表 ...

  5. 行存与列存的简单对比

    这篇文章列存的查询测试使用了clickhouse数据库,由于clickhouse的原理还在研究中,所以具体流程的分析存在欠缺,后面会在clickhouse的文档中描述.关于行存与列存的对比看前面三部分 ...

  6. 代码干货 | 行存、列存_堆表、AO表性能对比-阿里云HDB for PostgreSQL最佳实践

    本文来源于阿里云-云栖社区,原文点击这里. 标签 PostgreSQL , GIS , PostGIS , Greenplum , 空间检索 , GiST , B-Tree , geohash 背景 ...

  7. 数据库:行存储、列存储 利弊分析

    文章来源:(http://www.infoq.com/cn/articles/bigdata-store-choose) PS:可以看一下文章中的概念,后面的结论部分可能存在一些问题,这里只是转载,如 ...

  8. parquet格式_【存储】基于列存之Parquet格式

    " Parquet 是一种支持嵌套结构的列式存储格式,非常适用于 OLAP 场景,按列存储和扫描." 01 - 概述 数据存储是信息技术对您每天所需的数据内容(从应用到网络协议,从 ...

  9. PostgreSQL GPU 加速(HeteroDB pg_strom) (GPU计算, GPU-DIO-Nvme SSD, 列存, GPU内存缓存)

    标签 PostgreSQL , GPU , heteroDB , pg_strom , CUDA , nvidia , DIO , Nvme , SSD , 列存 , GPU内存缓存 背景 Heter ...

最新文章

  1. 运行hadoop自带的wordcount例子
  2. 逆向工程、软件后门……原来美剧《硅谷》里藏着这么多知识点
  3. socket中select针对阻塞I/O复用注意的问题
  4. [转]浅谈:国内软件公司为何无法做大做强
  5. 【Excel】日常记录
  6. 【IDEA】怎么把idea的目录结构,以文本形式输出?
  7. boost::reference_wrapper用法实例
  8. 三层交换(VLAN间互通+路由功能)+VTP+STP(PVST)综合实验(理论+实践=真实)
  9. 谈谈2018年区块链大事件
  10. 贪心算法——洛谷(P3817)小A的糖果
  11. 嵌入式系统开发学习步骤(Linux高级编程学习顺序)
  12. H5 --力导向图、关系图谱
  13. 入手 M1 Mac 之前,你可以通过这个工具了解常用软件兼容性
  14. html5好看表格样式,CSS实现的清爽、漂亮的表格样式分享
  15. VCPKG 包下载失败解决思路
  16. j2me之诺基亚S40模拟器
  17. 《多媒体在初中数学中的运用研究》课题研究方案
  18. Data Analysis - Day7 - Pandas
  19. 解决element 表单验证不通过的俩大坑
  20. 三元损失“In Defense of the Triplet Loss for Person Re-Identification”

热门文章

  1. mysql模糊查找英文可以查找中文不行(详细记录)
  2. 2020-11-08 焊单片机技巧
  3. 罗杨美慧 20190905-1 每周例行报告
  4. 滴滴云技术沙龙:AI在“出行”和“云”的探索和应用
  5. axure变成一个小手了_Axure教程:这几个小技巧你一定要知道
  6. 安卓手机卸载系统应用(免root,非adb命令)==亲测有效==简单易操作
  7. USB扫码枪二维码读取(二)——MFC篇
  8. 夜神模拟器——vscode调试模拟器找不到模拟器
  9. 复杂网络实验9:vicsek模型(matlab)
  10. 阿里巴巴Java开发手册github地址