你应该知道一些其他存储——列式存储

导读:在讲《Apache Druid 底层存储设计》时就说过要讲一讲列式存储。现在来了,通过本文你可以了解到行存储模式、列存储模式、它们的优缺点以及列存储模式的优化等知识。

今日格言:不要局限于单向思维,多对比了解更多不同维度的东西。

从数据存储讲起

我们最先接触的数据库系统,大部分都是行存储系统。大学的时候学数据库,老师让我们将数据库想象成一张表格,每条数据记录就是一行数据,每行数据包含若干列。所以我们对大部分数据存储的思维也就是一个复杂一点的表格管理系统。我们在一行一行地写入数据,然后按查询条件查询过滤出我们想要的行记录。

大部分传统的关系型数据库,都是面向行来组织数据的。如 Mysql,Postgresql。近几年,也越来越多传统数据库加入了列存储的能力。虽然列存储的技术在十几年前就已经出现,却从来没有像现在这样成为一种流行的存储组织方式。

行存储和列存储,是数据库底层组织数据的方式。(和文档型、K-V 型,时序型等概念不在一个层次)

行存储

行存储系统以行的方式来组织数据。假设现在有以下 blog 数据(大学时老师布置系统课题作业总是让我们做一个博客系统,大概因为他们最先接触的互联网就是 BBS 吧):

[
  {
    "title": "Oriented Column Store",
    "author": "Alex",
    "publish_time": 1508423456,
    "like_num": 1024
  },{
    "title": "Apache Druid",
    "author": "Bob",
    "publish_time": 1504423069,
    "like_num": 10
  },{
    "title": "Algorithm",
    "author": "Casey",
    "publish_time": 1512523069,
    "like_num": 16
  }
]

行存储将会以下列方式将数据存储在磁盘上。我们可以思考一下,这样的方式利于什么样的存储?(此处停顿 5 秒思考一下)它利于数据一行一行的写入,写入一条数据记录时,只需要将数据追加到已有数据记录后面即可。

行模式存储适合 OLTP(Online Transaction Processing)系统。因为数据基于行存储,所以数据的写入会更快。对按记录查询数据也更简单。

大部分同学会问,我们的做的系统不就是在为了这个吗?所以我为什么还需要列式存储,而列式存储又是什么?

让我们想象一种场景,现在不是想查询 Bob 的博客,我想统计 Bob 发表的博客数,或是整个系统今天的博客点赞数。如果是行存储系统,数据库将怎样操作?(停顿思考 10 秒

如图,想统计所有点赞数,首先需要将所有行数据读入内存,然后对 like_num 列做 sum 操作,从而得到结果。我们假设磁盘一次可以读取图中 3 个方框的数据(实际需要按 byte 来读取),那么这个聚合计算需要 N(N=数据量)次磁盘访问。

这种经常需要通过大量数据集来聚合统计数据的需求其实是 OLAP 系统的常见行为。基于这个需求我们也可以明白为什么这几年列式存储开始流行。因为数据,大数据,数据分析,也就是 OLAP(Online Analytical Processing)在线分析系统的需求增多了,数据写入的事务和按记录查询数据都不是它的关注点,它关注的是数据过滤,统计。

列存储

同样是上面的示例数据,我们来看列式存储是怎样组织数据的。

[
  {
    "title": "Oriented Column Store",
    "author": "Alex",
    "publish_time": 1508423456,
    "like_num": 1024
  },{
    "title": "Apache Druid",
    "author": "Bob",
    "publish_time": 1504423069,
    "like_num": 10
  },{
    "title": "Algorithm",
    "author": "Casey",
    "publish_time": 1512523069,
    "like_num": 16
  }
]

如图所示,列式存储将每一列的数据组织在一起。可以思考一下这样利于什么呢?(停顿 5 秒

是的,利于对于列的操作,如上面我们说到的统计所有 like_num 之和。其过程将如下:

依然假设磁盘一次可以读取 3 个方框的数据(实际按 byte 读取)。可以看出按列存储组织数据的方式,只需要 1 次磁盘操作就可以完成。

在程序的世界里,我们学会了,任何的选择和倾向都是有代价的。空间换时间,时间换空间,一致性可用性相互平衡等。选择列式存储必然也有不利的一面。首先就表现在数据写入上。

当一条新数据到来,需要将每一列存储到对应的位置。这样就需要多次写磁盘操作。(当然真实的数据库不会出现图中”挤一挤“、”挪一挪“的情况,数据库会将不同列数据组织在不同的地方;对于多次写操作的问题,大部分存储系统会通过缓冲来降低这种情况带来的不足)

对比

Row-Store Column-Store
因为按一行一行写和读取数据,因此读取数据时往往需要读取那些不必要的列 可以只读取必要的列
易于按记录读写数据 对一个一个记录的数据写入和读取都较慢
适合 OLTP 系统 适合 OLAP 系统
不利于大数据集的聚合统计操作 利于大数据集的数据聚合操作
不利于压缩数据 利于压缩数据

列存储优势

基于列模式的存储,天然就会具备以下几个优点:

  • 自动索引

    因为基于列存储,所以每一列本身就相当于索引。所以在做一些需要索引的操作时,就不需要额外的数据结构来为此列创建合适的索引。

  • 利于数据压缩

    利于压缩有两个原因。一来你会发现大部分列数据基数其实是重复的,拿上面的数据来说,因为同一个 author 会发表多篇博客,所以 author 列出现的所有值的基数肯定是小于博客数量的,因此在 author 列的存储上其实是不需要存储博客数量这么大的数据量的;二来相同的列数据类型一致,这样利于数据结构填充的优化和压缩,而且对于数字列这种数据类型可以采取更多有利的算法去压缩存储。

最后

目前列存储模式在很多分析型数据库中都很常见。而且因为大数据分析型需求的增多,越来越多传统的行存储数据库也加入了列存储的模式,比如 Oracle 和 Sql Server 都有了列存储的特性。

之前讲的 Apache Druid 底层数据存储就是基于列模式。有兴趣的可以回顾一下。另外 HBase 是一个比较有代表性的列存储模式数据库。有时间可以来聊一聊 HBase 底层是如何存储数据的。也可以讲一讲数字列的压缩方式(大家也可以先思考一下可以如何压缩数字列)。

系列文章:

时间序列数据库(TSDB)初识与选择
十分钟了解 Apache Druid
Apache Druid 底层存储设计
Apache Druid 的集群设计与工作流程

参考文章:

https://towardsdatascience.com/the-beauty-of-column-oriented-data-2945c0c9f560
https://dataschool.com/data-modeling-101/row-vs-column-oriented-databases/

想了解更多数据存储相关知识,请关注我的公众号。

原文地址:https://blog.51cto.com/14745561/2485669

时间: 2024-10-13 16:00:37

你应该知道一些其他存储——列式存储的相关文章

几张图看懂列式存储

最近看到一篇很好资料,里面三言两语配上几个图就把列式存储(Column-based Storage)讲明白了,牛啊!最喜欢的就是这种浅显易懂就把背景知识讲得明明白白,而不是长篇大论的讲概念. 1 为什么要按列存储 列式存储(Columnar or column-based)是相对于传统关系型数据库的行式存储(Row-basedstorage)来说的.简单来说两者的区别就是如何组织表(翻译不好,直接抄原文了): Row-based storage stores atable in a sequen

几张图看懂列式存储(转)

add by zhj: 终于明白了什么是列式存储,什么是行式存储.这跟数据在存储介质中的存储结构有关, 列式存储是指,一列中的数据在存储介质中是连续存储的:行式存储是指一行中的数据在存储介质 中是连续存储的. 原文:http://blog.csdn.net/dc_726/article/details/41143175 最近看到一篇很好资料,里面三言两语配上几个图就把列式存储(Column-based Storage)讲明白了,牛啊!最喜欢的就是这种浅显易懂就把背景知识讲得明明白白,而不是长篇大

列式存储设计实战

背景: 开发个学生系统,数据库设计. 设计实施: 传统数据库学生表行设计 学号 姓名 性别 年龄 1 张三 男 16 2 李红 女 15 3 王五 男 16 当想扩展属性时,相对应的会增加字段. 学号 姓名 性别 年龄 住址 1 张三 男 16 河南 2 李红 女 15 湖北 3 王五 男 16 北京 实际开发中这样做的缺点: 1:属性字段向主表加,会导致列越来越多,增加表拆分成本. 2:  增加字段,程序中实体模型,SQL查询字段,DTO及文档数据模型都要跟着发生变化,增加成本. 3:查询单个

内存列式存储 vs Buffer Cache

Oracle DB 12c的In-Memory选项(DBIM)将表中列的所有行的数据载入内存,为何不能像Buffer Cache那样只把频繁访问的数据块置入内存中呢? 内存列式存储和Buffer Cache的访问模式 原因是两者支持的访问模式不同,对于Buffer Cache,支持的是OLTP应用,访问模式为non-uniform access patterns,也就是说表中的某些行访问比其它行频繁,因此才能通过只缓存10%的数据,就可以涵盖95%的数据访问.可以假设缓存10%的数据就可以得到2

Infobright列式存储数据库

Infobright 是一个非常强大的列式存储数据库,基于MySQL的高效数据仓库. 之所以使用数据仓库,是因为目前MySQL数据库中的数据增长很快,定期会对一些历史记录表进行清除,但后期的统计分析还会用到这些历史数据,随着数据量的增大,查询也越来越慢,而数据库仓库特有的存储格式能够减小磁盘空间内的占用,同时列式的特点使得查询速度大为改观.选择Infobright是因为它锁支持的数据类型更多些,更接近于mysql,更节省磁盘空间,毕竟主要的统计查询还不是在数据仓库上,偶尔的查询一下速度倒不是要求

hbase kv特性 列式存储 查询接口

KV数据库: 只是key有多个层级: 表 + rowkey + column family + column 可以扫一个表的所有记录, 可以查一个表内,一个rowkey的所有column family + column对应value 可以查一个表内,一个rowkey,一个column family 内所有column对应value 可以查一个表内,一个rowkey,一个column family ,一个column对应的value 列式存储: 定义hbase表的时候,只需要知道table名和哪几

内存列式存储

内存列式存储(IM column store)(此特性在12cr1(12.1.0.2)版本后开始可用)是系统全局区中一个可选的部分,表中的数据是以列的形式而不是行的形式存储在内存里面的,如下图所示.在针对某列作查询的应用场景中,列式存储能极大地提升语句的执行速度. IM的列存储在SGA中一个新的静态池.传统的表数据是以行为单位存储,列作为行的一个个片断,列式存储是以一种新的列格式.每个列被存储为一个单独的结构.列存储区不取代缓冲区缓存,但作为一个补充,使数据可以存储在内存中的行和列格式.要使用列

oracle 12c 列式存储 ( In Memory 理论)

随着Oracle 12c推出了in memory组件,使得Oracle数据库具有了双模式数据存放方式,从而能够实现对混合类型应用的支持:传统的以行形式保存的数据满足OLTP应用:列形式保存的数据满足以查询为主的OLAP应用.in memory组件可以和其他数据库组件功能使用,并不需要用户单独开发或者修改应用程序,就可以非常方便的实现基于实时数据库分析的转变.本文会介绍in memory组件的一些相关知识,包含了以下的内容: -列式存储的基本知识 -访问in memory area中的数据 -In

列式存储 Parquet

1.  最初创建Parquet的目的是:要在Hadoop生态系统中,充分利用数据压缩.有效列式存储的优势.Parquet面向复杂的嵌套数据结构,使用Dremel中的record shredding and assembly算法,其与简单命名空间嵌套的方法相比更加高效.Parquet支持有效的数据压缩和编码方式,甚至允许为不同列单独设置压缩方式. 2. 名词术语:block(数据块).file(文件).column chunk(列块):将数据按列存储时,每一列数据被分割成多个列块.row grou