• 自动秒收录
  • 软件:1973
  • 资讯:57811|
  • 收录网站:279872|

IT精英团

浅谈数据库的行存储和列存储

浅谈数据库的行存储和列存储

浏览次数:
评论次数:
编辑: 乐咏
信息来源: ITPUB
更新日期: 2022-07-19 21:17:57
摘要

原文:my.oschina.net/gaussdb/blog/5544252好多人最开始学习数据库的时候,是关系数据库,数据以表格形式存储,一行表示一条记录。其实这种就是典型的行存储(Row-base

  • 正文开始
  • 相关阅读
  • 推荐作品

原文:my.oschina.net/gaussdb/blog/5544252

很多人开始学数据库的时候,是关系数据库。数据以表格的形式存储,一行代表一条记录。事实上,这是一个典型的基于行的存储,它将表按行存储在磁盘分区上。一些数据库还支持基于列的存储,这种存储将表以列的形式存储在磁盘分区上。

存储方式比较

两者的区别如下:

从图中可以看出,存储一行时,一行记录的属性值存储在相邻的空间,后面是下一条记录的属性值。存储一列时,单个属性的所有值都存储在相邻的空间中,即一列中的所有数据都是连续存储的,每个属性都有不同的空间。在这里,你可以自己思考一下这两种。哪个更适合查询,哪个更适合修改?1)在数据写入上的对比::线存储器的写入是一次性完成的。在操作系统的文件系统上写入,可以保证写入过程的成败,因此可以确定数据的完整性。2)列存储需要将一行记录拆分成单列进行存储,所以写的次数明显多于行存储。此外,当磁头需要在磁盘上移动和定位时,实际的时间消耗会更大。所以行存储在书写上有很大的优势。3)还有数据修改,其实就是一个写的过程。所以数据修改也是以行存储为主。1)在数据读取上的对比::行存储通常完全取出一行数据。如果只需要几列数据,就会有冗余列。为了缩短处理时间,消除冗余列的过程通常在内存中进行。2)列存储。每次读取的数据都是集合的一个或者全部,所以不存在冗余问题。搜索内容连续存储,特别适合投影。3)两种存储的数据分布。因为存储在一个列中的每个列的数据类型都是同构的,所以不存在二义性问题。例如,如果列数据类型是integer (int),那么它的数据集必须是整数数据。这种情况使得数据分析非常容易。相比之下,行存储要复杂得多,因为多种类型的数据存储在一行记录中,数据解析需要在多种数据类型之间频繁转换,消耗CPU,增加解析时间。所以列存储的解析过程更有利于分析大数据。4)从数据压缩和更好的性能读取进行比较。同一列的数据属于同一数据类型,列存储的方式适合数据压缩。不同的列可以采用不同的压缩算法,压缩存储会带来IO性能的提升。

优缺点比较

表的存储类型是表定义设计的第一步,客户业务类型是决定表的存储类型的主要因素。行列存储模式各有利弊,建议根据实际情况选择。库和列存储的优缺点及适用场景对比见下表:

杭村

列村

优势

数据保存在一起。插入/更新很容易。

只有查询中涉及的列才会被读取。

投影效率很高。

任何列都可以用作索引。

缺点

选择时,即使只涉及几列,也会读取所有数据。

选择完成后,所选的列将被重新组合。

>

INSERT/UPDATE 比较麻烦。

  • 点查询不适合。

  • 适用场景

    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  500000 openGauss=# insert into custom2 select * from custom1; INSERT  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=) (actual time=0.059..0.060 rows=1 loops=1) ->  Result  (cost=0.00...01 rows=1 width=) (actual time=0.001...001 rows=1 loops=1) Total runtime: .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=) (actual time=0.119..0.120 rows=1 loops=1) ->  Result  (cost=0.00...01 rows=1 width=) (actual time=0.001...002 rows=1 loops=1) Total runtime: .207 ms (3 rows)

    最后删除测试表。

    openGauss=# drop table custom1; DROP TABLE openGauss=#drop table custom2; DROP TABLE
    感兴趣的同学可以自己测试更多的的场景,比如创建大宽表、update 表等场景测试下。

    选择建议

    • 更新频繁程度:数据如果频繁更新,选择行存表。

    • 插入频繁程度:频繁的少量插入,选择行存表。一次插入大批量数据,选择列存表。

    • 表的列数:一般情况下,如果表的字段比较多即列数多(大宽表),查询中涉及到的列不多的情况下,适合列存储。如果表的字段个数比较少,查询大部分字段,那么选择行存储比较好。

    • 查询的列数:如果每次查询时,只涉及了表的少数(<50% 总列数)几个列,选择列存表。(不要问剩下的列干啥用,甲方说有用就是有用。)

    • 压缩率:列存表比行存表压缩率高。但高压缩率会消耗更多的 CPU 资源。

    注意事项

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


    13个实用代码片段 推荐收藏
    « 上一篇 2022-07-19
    在Linux中使用ss命令的例子
    下一篇 » 2022-07-19
    • 如何在Ubuntu中保留文件系统并备份当前开发板镜像
      0阅读 0条评论 个赞
      在Ubuntu保留文件系统或者说备份当前开发板镜像的需求在不断增加。比如Ubuntu文件系统需要安装库文件的话直接使用apt-get工具就可以下载,但由于需要下载的核心板较多,比较费时间,这时需要将安……
    • 国产核心板全志T507助力消防系统升级
      0阅读 0条评论 个赞
      9月16日下午,位于湖南长沙市区内的中国电信大楼发生火灾,建筑高度218米,现场浓烟滚滚,数十层楼体燃烧剧烈。消防救援人员赶到现场后很快将火势控制住,目前大楼火势已被扑灭,所幸未发现人员伤亡。湖南电信……
    • 教大家如何处理Spring Boot易流中的用户和群体!
      0阅读 0条评论 个赞
      1.准备工作2.用户操作2.1添加用户2.2修改用户2.3删除用户2.4查询用户3.组操作3.1添加组3.2修改组3.3删除组3.4查询组4.查看表详情虽然说我们在实际开发中,……
    • 从PG15开始WAL压缩优化
      0阅读 0条评论 个赞
      PG15传闻中的超级令人激动的功能大多数跳票了,年初我也写过一个关于PG15新功能跳票的文章。PG15BETA已经发出几个月了,似乎PG15里令人激动人心的功能不多,不过从长长的新功能列表里,……
    • 深入了解美团叶子发射器开源方案
      0阅读 0条评论 个赞
      大家好,我是树哥。之前我们有聊过「如何设计一个分布式ID发号器」,其中有讲过4种解决方案,分别是:UUID类雪花算法数据库自增主键Redis原子自增美团以第2、3种解决方案为基础,开发出……
    发表评论 共有条评论
    用户名: 密码:
    验证码: 匿名发表
    • 金牛座入门 MVC微服务框架开发教程
      0阅读 0条评论 个赞
      前言:对于Taurus.MVC的微服务的注册中心而言:什么样的应用中心,有权利注册服务?什么样的网关中心,有权利调取服务列表?在默认没有进行相关配置时,只要引用Taurus.MVC的框架,都拥有该权限……
    • 构建docker镜像库(1):用注册表构建本地镜像库
      0阅读 0条评论 个赞
      目录一.系统环境二.前言三.使用registry搭建私有镜像仓库3.1环境介绍3.2k8smaster节点配置镜像仓库3.3k8sworker1节点配置从私有仓库上传和拉取镜像3.3.1上传镜……
    • 大促销活动如何抵御高流量DDoS攻击?
      0阅读 0条评论 个赞
      大促活动如何抵御大流量DDoS攻击?每一次活动大促带来的迅猛流量,对技术人而言都是一次严峻考验。如果在活动期间遭受黑产恶意DDoS攻击,无疑是雪上加霜。电商的特性是业务常态下通常不会遭受大流量DD……
    • sql server索引I摘要
      0阅读 0条评论 个赞
      一、存储结构在SQLServer中,有许多不同的可用排列规则选项。二进制:按字符的数字表示形式排序(ASCII码中,用数字32表示空格,用68表示字母"D")。因为所有内容都表示为数字,所以……
    • 数字人技术在直播场景中的应用
      0阅读 0条评论 个赞
      作者|薄志浩导读introduction本文介绍了在数字人AI技术发展迅猛,整体AI数字人市场呈现高速增长的趋势下,与强调高实时性互动的直播业务场景的结合与应用,通过数字人渲染技术、强大的AI全栈能……
    • 在头脑中扎根泛型的思想3354深刻理解泛型
      0阅读 0条评论 个赞
      1.前言往往一些刚接触C#编程的初学者,对于泛型的认识就是直接跳到对泛型集合的使用上,虽然微软为我们提供了很多内置的泛型类型,但是如果我们只是片面的了解调用方式,这会导致我们对泛型盲目的使用。至于为什……
    • 与docker卷一起安装的注意事项
      0阅读 0条评论 个赞
      目录Content使用数据卷(volume)使用挂载点(共享宿主目录,bindmount)目录兼容性可移植性目录替代相关指定位置--volume与--mount区别镜像保存docker-compos……
    • 你知道信息架构图和功能架构图的区别吗?
      0阅读 0条评论 个赞
      .css-1yuhvjn{margin-top:16px;}.css-3jt6os.FileLinkCard{-webkit-align-items:center;-webkit-box-align……
    • 企业操作和维护实践-丢弃docker构建
      15阅读 0条评论 个赞
      本章目录目录0x00前言简述快速介绍什么是Kaniko?为啥用Kaniko?Kaniko是如何工作的?Kaniko已知功能问题kaniko构建上下文kaniko缓存构建0x01部署使用环境……
    • 国产核心板全志T507助力消防系统升级
      0阅读 0条评论 个赞
      9月16日下午,位于湖南长沙市区内的中国电信大楼发生火灾,建筑高度218米,现场浓烟滚滚,数十层楼体燃烧剧烈。消防救援人员赶到现场后很快将火势控制住,目前大楼火势已被扑灭,所幸未发现人员伤亡。湖南电信……
    • 如何获取Yarn和Spark UI的界面索引信息
      1阅读 0条评论 个赞
      .css-1yuhvjn{margin-top:16px;}.css-3jt6os.FileLinkCard{-webkit-align-items:center;-webkit-box-align……
    • Linux系统的docker部署 网络核心3.1
      0阅读 0条评论 个赞
      此篇文章演示基本的基于docker部署.netcore服务,linux系统腾讯云ubuntu,.netcore版本3.1。1.安装dockeraptinstalldocker.io2.拉取.ne……
    • 平均负载和CPU利用率有什么区别?
      2阅读 0条评论 个赞
      大家好,我是树哥。在性能优化中,我们经常会关注CPU平均负载这个指标。但如果让你来跟我解释一下什么是平均负载,你能说得清楚吗?它跟CPU使用率有什么区别?我想可能很多人都数不清楚,今天我们就来……
    • 如何在Ubuntu中保留文件系统并备份当前开发板镜像
      0阅读 0条评论 个赞
      在Ubuntu保留文件系统或者说备份当前开发板镜像的需求在不断增加。比如Ubuntu文件系统需要安装库文件的话直接使用apt-get工具就可以下载,但由于需要下载的核心板较多,比较费时间,这时需要将安……
    • 教你如何构建JAVA分布式爬虫
      0阅读 0条评论 个赞
      在工作中,我们经常需要去获取一些数据,但是这些数据可能需要从第三方平台才可以获取到。这个时候,爬虫系统就可以帮助我们来完成这些事情。提到爬虫系统,很多人都会想到使用python。但实际上,语言只……
    • ASP.NET核心6框架揭示示例演示[34]:缓存整个响应内容
      0阅读 0条评论 个赞
      我们利用ASP.NET开发的大部分API都是为了对外提供资源,对于不易变化的资源内容,针对某个维度对其实施缓存可以很好地提供应用的性能。《内存缓存与分布式缓存的使用》介绍的两种缓存框架(本地内存缓存和……
    • 新一代网络请求库:python-httpx库
      0阅读 0条评论 个赞
      目录httpx库一、概述1、简介2、命令行模式3、快速开始3.1get请求3.2post请求3.2.1表单3.2.2文件3.2.3JSON3.2.4二进制3.3响应处理3.4流……
    • 强大的多云混合多K8S集群管理平台Rancher入门级实战
      0阅读 0条评论 个赞
      目录概述定义为何使用其他产品安装简述规划基础环境Docker安装Rancher安装创建用户创建集群添加Node节点配置kubectl创建项目和名称空间发布应用偏好设置概述定义Rancher官网htt……
    • Python条件语句的用法
      0阅读 0条评论 个赞
      python条件语句使用if表达式,难度不高,需要注意的是嵌套用法,以及如何设置对应的条件。if条件判断语句python语句是按固定顺序执行的,先执行前面的语句,再执行后面的语句。如果你像要程……
    • 《2022 分布式数据库发展趋势研究报告》的解释
      9阅读 0条评论 个赞
      分布式数据库近年来广受关注,目前,对分布式数据库的讨论,已经从什么是分布式数据库,为什么要用分布式数据库,转变为怎样规划应用分布式数据库。但分布式数据库有3条不同的技术路线,这无疑增加了选型难度,到底……
    最近发布资讯
    更多