首页>>科技 >>内容

数据库列式存储和行式存储,数据库中的行列存储区别介绍

发布时间:2023-11-04 16:51:30编辑:温柔的背包来源:

很多朋友对数据库列式存储和行式存储,数据库中的行列存储区别介绍不是很了解,每日小编刚好整理了这方面的知识,今天就来带大家一探究竟。

数据库列式存储和行式存储,数据库中的行列存储区别介绍

大多数数据库系统存储一组数据记录,这些记录由表中的列和行组成。字段是列和行的交集:某种类型的单个值。属于同一列的字段通常具有相同的数据类型。例如,如果我们定义了一个包含用户数据的表,那么所有的用户名都将属于同一类型,属于同一列。逻辑上属于同一数据记录的一组值(通常由一个键标识)构成一行。

对数据库进行分类的方法之一是根据数据在磁盘上的存储方式进行分类:按行还是按列。表可以水平分区(将属于同一行的值存储在一起)或垂直分区(将属于同一列的值存储在一起)。图1-2描述了这种差异:a)显示了按列划分的值,b)显示了按行划分的值。

图1-2:面向列和面向行存储中的数据布局面向行的数据库有很多例子:MySQL、PostgreSQL和大多数传统的关系数据库。开源和面向列的数据存储的两个先驱是MonetDB和C-Store(C-Store是Vertica的开源前身)。01面向行的数据布局

面向行的数据库按记录或行存储数据。它的布局非常接近表的数据表示,也就是说,每一行都有相同的字段集。例如,面向行的数据库可以有效地存储用户条目,它包含姓名、出生日期和电话号码:| ID |姓名|出生日期|电话号码| | | 10 | John | 01 aug 1981 | 1 111 222 333 | 20 | Sam | 14 sep 1988 | 1 555 888 999 | | 30 | Keith | 07 Jan 1984 |。

这种方法适用于以下场景:数据记录(姓名、出生日期和电话号码)由多个字段组成,并由一个键唯一标识(在这种情况下是单调递增的ID)。代表单个用户数据记录的所有字段通常一起读取。当我们创建数据时(例如,当用户填写注册表单时),我们也将它们一起写入数据库。同时,我们可以单独修改一个字段。

当需要逐行访问数据时,面向行的存储最有用,将整行存储在一起可以提高空间局部性。因为磁盘等持久性介质上的数据通常是以块为单位进行访问的(换句话说,磁盘访问的最小单位是块),所以单个块可能包含一行中所有列的数据。

这在我们想要访问整个用户记录的时候是非常有用的,但是这样的存储布局会使得访问多个用户记录的一个字段的查询(比如只获取电话号码的查询)开销更大,因为在这个过程中还会读取其他字段的数据。02面向列的数据布局

面向列的数据库对数据进行垂直分区(即按列),而不是按行存储。在这种数据存储布局中,同一列的值连续存储在磁盘上(而不是像前面的示例那样连续存储行)。

例如,如果我们要存储股票市场的历史价格,那么股价列的数据将被存储在一起。将不同列的值存储在不同的文件或文件段中,可以有效地按列查询,因为它们可以一次性读取,而不是先读取整行,然后丢弃不必要的列。

面向列的存储非常适合计算聚合的分析工作负载,例如发现趋势和计算平均值。如果一个逻辑记录有多个字段,但其中一些字段(在本例中是股票价格)具有不同的重要性,并且存储在该字段中的数据经常一起使用,那么我们通常使用复杂聚合来处理这种情况。从逻辑上看,代表股票市场价格的数据还是可以用一个表来表示:| ID | Symbol | Date | Price |。

| 1 |道指| 08 aug 2018 | 24314.65 | | 2 |道指| 09 aug 2018 | 24136.16 | | 3 | SP | 08 aug 2018 | 2414.45 | | 4 | SP | 09 aug 2018 | 2。2:陶氏;3:SP;4:SPDate:2018年8月1日08分;2018年8月2日09分;2018年8月3日08分;2018年8月4日09分价格:1:24314.65;2:24,136.16;3:2,414.45;4:2,232.32

为了重构数据元组(可能对连接、过滤和多行聚合有用),我们需要在列级别保留一些元数据,以标识哪些数据点在与之关联的其他列中。如果您显式地这样做,您需要为每个值保存一个键,这将导致数据重复并增加存储的数据量。为了响应这种需求,一些列存储使用隐式标识符(虚拟ID)并使用值的位置(换句话说,它的偏移量)将其映射回相关值。

在过去几年中,我们已经看到了许多新的面向列的文件格式,如Apache Parquet、Apache ORC、RCFile,以及面向列的存储,如Apache Kudu、ClickHouse和许多其他面向列的数据存储组件,这可能是由于对不断增长的数据集运行复杂的分析查询的需求不断增长。03差异和优化

仅仅认为行存储和列存储的区别在于数据的存储方式不同是不够的。选择数据布局只是列存储的一系列可能的优化步骤之一。在一次读取中,从同一列读取多个值可以显著提高缓存利用率和计算效率。在现代CPU上,向量化指令可以使单个CPU指令一次处理多个数据点。

此外,将具有相同数据类型的值存储在一起(例如,数字与数字,字符串与字符串)可以提高压缩率。我们可以根据不同的数据类型使用不同的压缩算法,并为每种情况选择最有效的压缩方法。

要决定是使用面向列的存储还是面向行的存储,您需要理解访问模式。如果需要读取记录中的大多数或所有列,并且工作负载主要由单个记录查询和范围扫描组成,则面向行的存储布局可能会产生更好的结果。如果扫描跨越多行或对列的子集执行计算聚合,则值得考虑使用面向列的存储布局。04宽列存储

面向列的数据库不应与宽列存储混淆(如BigTable或HBase)。在这些数据库中,数据被表示为多维映射,列被分组为列族(通常存储相同类型的数据),在每个列族中,数据被逐行存储。这种布局最适合存储由一个键或一组键检索的数据。

BigTable论文中的一个典型例子是WebTable。WebTable存储带有某个时间戳的快照,该快照包含以下信息:网页的内容、属性及其关系。页面由反向URL标识,所有属性(如页面内容和锚,代表页面之间的链接)由生成这些快照的时间戳标识。简而言之,可以表示为嵌套映射,如图1-3所示。

图1-3:web table的概念结构数据存储在一个多维排序图中,有层次索引:我们可以通过它的反向URL定位与特定网页相关的数据,也可以通过它的时间戳定位它的内容或锚点。每一行都按其行键进行索引。

在列族中,相关的列被分组在一起(在本例中是contents和anchor),这些列族分别存储在磁盘上。列族中的每一列都由列键标识,列键是列族名和限定符(在本例中是html、cnnsi.com、my.look.ca)的组合。列族可以根据时间戳存储多个版本的数据。这种布局允许我们快速定位更高级别的项目(在本例中是Web页面)及其参数(不同版本的内容和到其他页面的链接)。

理解宽列存储的概念表示是有用的,它们的物理布局也是不同的。列族的数据布局示意图如图1-4所示:列族是分开存储的,但是在每个列族中,属于同一个键的数据是存储在一起的。图1-4:web table的物理结构

以上知识分享希望能够帮助到大家!