聊一聊数据库的行存与列存
目录
好多人最开始学习数据库的时候,是关系数据库,数据以表格形式存储,一行表示一条记录。其实这种就是典型的行存储(Row-based store),将表按行存储到磁盘分区上。
而一些数据库还支持列存储(Column-based store),它将表按列存储到磁盘分区上。
存储方式比较
这两者的差异如下图:
从图上可以看出,行存的时候,一行记录的属性值存储在临近的空间,然后接着是下一条记录的属性值。
而列存的时候,单个属性所有的值存储在临近的的空间,即一列的所有数据连续存储的,每个属性有不同的空间。
这里,大家可以自行思考一下这两种那种更适合查询,那种更适合修改?
在数据写入上的对比:
1)行存储的写入是一次完成。写入建立在操作系统的文件系统上,可以保证写入过程的成功或者失败,数据的完整性因此可以确定。
2)列存储由于需要把一行记录拆分成单列保存,写入次数明显比行存储多,再加上磁头需要在盘片上移动和定位花费的时间,实际时间消耗会更大。所以,行存储在写入上占有很大的优势。
3)还有数据修改,这实际也是一次写入过程。所以,数据修改也是以行存储占优。
在数据读取上的对比:
1)行存储通常将一行数据完全取出,如果只需要其中几列数据的情况,就会存在冗余列,出于缩短处理时间的考量,消除冗余列的过程通常是在内存中进行的。
2)列存储每次读取的数据是集合的一段或者全部,不存在冗余性问题,查找内容连续存储,特别适合投影。
3) 两种存储的数据分布。由于列存储的每一列数据类型是同质的,不存在二义性问题。比如说某列数据类型为整型(int),那么它的数据集合一定是整型数据。这种情况使数据解析变得十分容易。相比之下,行存储则要复杂得多,因为在一行记录中保存了多种类型的数据,数据解析需要在多种数据类型之间频繁转换,这个操作很消耗CPU,增加了解析的时间。所以,列存储的解析过程更有利于分析大数据。
4)从数据的压缩以及更性能的读取来对比。同一列的数据,数据类型一致,列存的模式下就适合数据压缩,不同的列可以采用不同的压缩算法,压缩存储就会带来IO性能的提升。
优缺点比较
表的存储类型是表定义设计的第一步,客户业务类型是决定表的存储类型的主要因素。行、列存储模型各有优劣,建议根据实际情况选择。
行、列存优缺点及适用场景比较见下表:
行存 | 列存 | |
优点 | 数据被保存在一起。INSERT/UPDATE容易。 |
|
缺点 | 选择(Selection)时即使只涉及某几列,所有数据也都会被读取。 |
|
适用场景 |
|
|
行存与列存实验
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资源。
注意事项
列存由于特殊的存储方式,使用时约束比较多。比如,列存表不支持数组、不支持生成列、不支持创建全局临时表、不支持外键,支持的数据类型也会比行存要少。使用时需要查看对应的数据库文档。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Rancher2.6全新Monitoring快速入门
作者简介 万绍远,CNCF 基金会官方认证 Kubernetes CKA&CKS 工程师,云原生解决方案架构师。对 ceph、Openstack、Kubernetes、prometheus 技术和其他云原生相关技术有较深入的研究。参与设计并实施过多个金融、保险、制造业等多个行业 IaaS 和 PaaS 平台设计和应用云原生改造指导。 软件 版本 Rancher 2.6.4 Kubernetes 1.22.7+rke2r2 概 述 Rancher 2.6 监控启用方式与之前版本存在较大差异,属于原生的 Prometheus-Operator,通过抽象化一些 Kubernetes CRD 资源,可以更好地把监控告警功能整合起来,提高易用性。Prometheus-operator 包括以下 CRD 资源对象: PrometheusRules:定义告警规则 Alert Managers:Altermanager 启动 CRD,用于 Altermanager 启动副本 Receivers:配置告警接收媒介 CRD Routers:将告警规则和告警媒介进行匹配 ServiceMonitor...
- 下一篇
Zadig + 洞态 IAST:让安全溶于持续交付
Zadig on Github Zadig on Gitee IAST 作为当下备受关注的一种安全测试技术,我们如何利用 Zadig 运行时环境管理能力,快速的将 IAST 能力集成到我们的日常工作流程中? IAST 作为当下备受关注的一种安全测试技术,我们如何利用 Zadig 运行时环境管理能力,快速的将 IAST 能力集成到我们的日常工作流程中?本文中以 Zadig K8s 项目 + Java 服务为例,来了解在 Zadig 中如何为已有服务快速接入 IAST监测服务漏洞信息,为服务安全保驾护航。 What is IAST & DongTai? IAST:交互式应用程序安全测试(Interactive Application Security Testing),是近年来兴起的一项新技术,被 Gartner 公司列为信息安全领域的 Top 10 技术之一。它融合了 SAST 和 DAST 技术的优点,IAST 使用运行时代理方法在测试阶段分析&监控应用程序的行为。 DongTai 是一款开源的被动式交互式安全测试(IAST)产品,通过动态 Hook 和污点跟踪算法等实...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Red5直播服务器,属于Java语言的直播服务器
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS7设置SWAP分区,小内存服务器的救世主
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2全家桶,快速入门学习开发网站教程
- Docker安装Oracle12C,快速搭建Oracle学习环境
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作