mysql⾏存储列存储_哪些数据库是⾏存储?哪些是列存储?有
什么区别?
⼤多数数据库系统存储⼀组数据记录,这些记录由表中的列和⾏组成。字段是列和⾏的交集:某种类型的单个值。
属于同⼀列的字段通常具有相同的数据类型。例如,如果我们定义了⼀个包含⽤户数据的表,那么所有的⽤户名都将是相同的类型,并且属于同⼀列。在逻辑上属于同⼀数据记录(通常由键标识)的值的集合构成⼀⾏。
对数据库进⾏分类的⽅法之⼀是按数据在磁盘上的存储⽅式进⾏分类:按⾏或按列进⾏分类。表可以⽔平分区(将属于同⼀⾏的值存储在⼀起),也可以垂直分区(将属于同⼀列的值存储在⼀起)。图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&PDate: 1:08 Aug 2018; 2:09 Aug 2018; 3:08 Aug 2018; 4:09 Aug 2018Price:
1:24,314.65; 2:24,136.16; 3:2,414.45; 4:2,232.32
mysql删除重复的数据保留一条为了重建数据元组(这对于连接、筛选和多⾏聚合可能很有⽤),我们需要在列级别上保留⼀些元数据,以标识与它关联的其他列中的数据点是哪些。如果你显式地执⾏此操作,则需要每个值都必须持有⼀个键,这将导致数据重复并增加存储的数据量。
针对这种需求,⼀些列存储使⽤隐式标识符(虚拟ID),并使⽤该值的位置(换句话说,其偏移量)将其映射回相关值。
在过去⼏年中,可能由于对不断增长的数据集运⾏复杂分析查询的需求不断增长,我们看到了许多新的⾯向列的⽂件格式,如Apache Parquet、Apache ORC、RCFile,以及⾯向列的存储,如Apache Kudu、ClickHouse,以及许多其他列式数据存储组件。
03 区别与优化
认为⾏存储和列存储之间的区别仅在于数据的存储⽅式有所不同,这是不充分的。选择数据布局只是列式存储所针对的⼀系列可能的优化的步骤之⼀。
在⼀次读取中,从同⼀列中读取多个值可以显著提⾼缓存利⽤率和计算效率。在现代CPU上,向量化指令可以使单条CPU指令⼀次处理多个数据点。
另外,将具有相同数据类型的值存储在⼀起(例如,数字与数字在⼀起,字符串与字符串在⼀起)可以提⾼压缩率。我们可以根据不同的数据类型使⽤不同的压缩算法,并为每种情况选择最有效的压缩⽅法。
要决定是使⽤⾯向列还是⾯向⾏的存储,你需要了解访问模式。如果所读取的记录中的⼤多数或所有列都是需要的,并且⼯作负载主要由单条记录查询和范围扫描组成,则⾯向⾏的存储布局可能产⽣更好的结果。如果扫描跨越多⾏,或者在列的⼦集上进⾏计算聚合,则值得考虑使⽤⾯向列的存储布局。
04 宽列式存储
⾯向列的数据库不应与宽列式存储(如BigTable或HBase)相混淆。在这些数据库中,数据表⽰为多维映射,列被分组为列族(通常存储相同类型的数据),并且在每个列族中,数据被逐⾏存储。此布局最适合存储由⼀个键或⼀组键来检索的数据。
BigTable论⽂中的⼀个典型⽰例是WebTable。⼀个WebTable存储着⼀个带有某个时间戳、包含如下信息的快照:⽹页内容、属性以及它们之间的关系。
页⾯由反向URL所标识,并且所有属性(如页⾯内容和锚,锚表⽰页⾯之间的链接)由⽣成这些快照的时间戳来标识。简⽽⾔之,它可以表⽰为⼀个嵌套的映射,如图1-3所⽰。▲图1-3:WebTable的概念性结构
数据存储在具有层次索引的多维排序映射中:我们可以通过特定⽹页的反向URL来定位与该⽹页相关的数据,也可以通过时间戳来定位该⽹页的内容或锚。每⼀⾏都按其⾏键进⾏索引。
列族可以按照时间戳存储多个版本的数据。这种布局使得我们可以快速定位更⾼层的条⽬(在本例中为Web页⾯)及其参数(不同版本的内容和指向其他页⾯的链接)。
理解宽列式存储的概念表⽰是有⽤的,⽽它们的物理布局也有所不同。列族的数据布局⽰意图如图1-4所⽰:列族被单独存储,但在每个列族中,属于同⼀键的数据被存储在⼀起。▲图1-4:WebTable的物理结构
[声明]本⽂版权归原作者所有,内容为作者个⼈观点,转载⽬的在于传递更多信息,如涉及作品内容、版权等问题,可联系本站删除,谢谢。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。