哪些数据库是行存储?哪些是列存储?有什么区别?

导读:本文带你了解面向列与面向行的数据库 。
作者:Alex Petrov
来源:华章科技
哪些数据库是行存储?哪些是列存储?有什么区别?

文章插图
 
大多数数据库系统存储一组数据记录,这些记录由表中的列和行组成 。字段是列和行的交集:某种类型的单个值 。
【哪些数据库是行存储?哪些是列存储?有什么区别?】属于同一列的字段通常具有相同的数据类型 。例如,如果我们定义了一个包含用户数据的表,那么所有的用户名都将是相同的类型,并且属于同一列 。在逻辑上属于同一数据记录(通常由键标识)的值的集合构成一行 。
对数据库进行分类的方法之一是按数据在磁盘上的存储方式进行分类:按行或按列进行分类 。表可以水平分区(将属于同一行的值存储在一起),也可以垂直分区(将属于同一列的值存储在一起) 。图1-2描述了这种区别:a)显示了按列分区的值,b)显示了按行分区的值 。
哪些数据库是行存储?哪些是列存储?有什么区别?

文章插图
▲图1-2:面向列和行的存储中的数据布局
面向行的数据库的例子很多:MySQL、PostgreSQL和大多数传统的关系数据库 。而两个开源的、面向列数据存储的先驱则是MonetDB和C-Store(C-Store是Vertica的开源前身) 。
01 面向行的数据布局面向行的数据库按记录或行来存储数据 。它的布局非常接近表格的数据表示方法,即其中每一行都具有相同的字段集合 。例如,面向行的数据库可以有效地存储用户条目,其中包含姓名、出生日期和电话号码:
| ID | Name | Birth Date | Phone Number |
| 10 | John | 01 Aug 1981 | +1 111 222 333 |
| 20 | Sam | 14 Sep 1988 | +1 555 888 999 |
| 30 | Keith | 07 Jan 1984 | +1 333 444 555 |
这种方法适用于如下的场景:数据记录(姓名、出生日期和电话号码)由多个字段组成且由某个键(在本例中为单调递增的ID)所唯一标识 。表示单个用户的数据记录的所有字段通常被一起读取 。在创建数据时(例如,当用户填写注册表单时),我们也将它们一起写入数据库 。与此同时,我们可以单独修改某个字段 。
在需要按行访问数据的情况下,面向行的存储最有用,将整行存储在一起可以提高空间局部性 。
因为诸如磁盘之类的持久性介质上的数据通常是按块访问的(换句话说,磁盘访问的最小单位是块),所以单个块可能将包含某行中所有列的数据 。
这对于我们希望访问整个用户记录的情况非常有用,但这样的存储布局会使访问多个用户记录某个字段的查询(例如,只获取电话号码的查询)开销更大,因为其他字段的数据在这个过程中也会被读入 。
哪些数据库是行存储?哪些是列存储?有什么区别?

文章插图
 
02 面向列的数据布局面向列的数据库垂直地将数据进行分区(即通过列进行分区),而不是将其按行存储 。在这种数据存储布局中,同一列的值被连续地存储在磁盘上(而不是像前面的示例那样将行连续地存储) 。
例如,如果我们要存储股票市场的历史价格,那么股票价格这一列的数据便会被存储在一起 。将不同列的值存储在不同的文件或文件段中,可以按列进行有效的查询,因为它们可以一次性地被读取出来,而不是先对整行进行读取后再丢弃掉不需要的列 。
面向列的存储非常适合计算聚合的分析型工作负载,例如查找趋势、计算平均值等 。如果逻辑记录具有多个字段,但是其中某些字段(在本例中为股票价格)具有不同的重要性并且该字段所存储的数据经常被一起使用,那么我们一般使用复杂聚合来处理这样的情况 。
从逻辑角度看,表示股票市场价格的数据仍旧可以表示为表的形式:
| ID | Symbol | Date | Price |
| 1 | DOW | 08 Aug 2018 | 24,314.65 |
| 2 | DOW | 09 Aug 2018 | 24,136.16 |
| 3 | S&P | 08 Aug 2018 | 2,414.45 |
| 4 | S&P | 09 Aug 2018 | 2,232.32 |
而列式存储则看起来与上述存储布局完全不同—属于同一列的值被紧密地存储在一起:
Symbol: 1:DOW; 2:DOW; 3:S&P; 4:S&P
Date: 1:08 Aug 2018; 2:09 Aug 2018; 3:08 Aug 2018; 4:09 Aug 2018
Price: 1:24,314.65; 2:24,136.16; 3:2,414.45; 4:2,232.32
为了重建数据元组(这对于连接、筛选和多行聚合可能很有用),我们需要在列级别上保留一些元数据,以标识与它关联的其他列中的数据点是哪些 。如果你显式地执行此操作,则需要每个值都必须持有一个键,这将导致数据重复并增加存储的数据量 。


推荐阅读