列式数据存储有哪些优势使其更适合数据科学和分析?
是什么让列式数据库适用于数据科学?
面向列的数据库(=columnar data-store)将表的数据逐列存储在磁盘上,而面向行的数据库将表的数据逐行存储。
与面向行的数据库相比,使用面向列的数据库有两个主要优点。第一个优势与我们需要读取的数据量有关,以防我们只对几个特征执行操作。考虑一个简单的查询:
SELECT correlation(feature2, feature5)
FROM records
传统的执行器会读取整个表(即所有特征):
相反,使用我们基于列的方法,我们只需要阅读感兴趣的列:
第二个优势对于大型数据库也非常重要,即基于列的存储允许更好的压缩,因为一个特定列中的数据确实比所有列中的数据是同质的。
面向列的方法的主要缺点是操作(查找、更新或删除)整个给定行效率低下。然而,这种情况在用于分析的数据库(“仓储”)中应该很少发生,这意味着大多数操作都是只读的,很少会读取同一张表中的许多属性,并且写入只是追加。
一些 RDMS 提供了面向列的存储引擎选项。例如,PostgreSQL 本身没有以基于列的方式存储表的选项,但 Greenplum 创建了一个封闭源代码(DBMS2,2009)。有趣的是,Greenplum 还支持可扩展的数据库内分析开源库 MADlib(Hellerstein 等人,2012 年),这并非巧合。最近,致力于高速分析数据库的初创公司 CitusDB 发布了他们自己的 PostgreSQL 开源列式存储扩展 CSTORE(Miller,2014)。Google 的大规模机器学习系统 Sibyl 也使用了面向列的数据格式(Chandra et al., 2010)。这一趋势反映了人们对大规模分析的列式存储越来越感兴趣。斯通布雷克等人。(2005) 进一步讨论了面向列的 DBMS 的优势。
两个具体用例:大多数用于大规模机器学习的数据集是如何存储的?
(大部分答案来自附录 C:BeatDB:一种从海量信号数据集中揭示显着性的端到端方法。Franck Dernoncourt,SM,论文,麻省理工学院 EECS 系)
这取决于你做什么。
列存储有两个主要好处:
- 可以跳过整列
- 运行长度压缩在列上效果更好(对于某些数据类型;特别是具有很少不同值的情况)
但是它们也有缺点:
- 许多算法需要所有列,并且一次只记录(例如k-means),甚至可能需要计算成对距离矩阵
- 压缩技术仅适用于稀疏数据类型和因子,但不适用于双值连续数据
- 列存储上的追加很昂贵,因此它不适合流式传输/更改数据
列式存储对于 OLAP 又名“愚蠢的分析”(Michael Stonebraker) 非常流行,当然对于您可能确实对丢弃整列感兴趣的预处理(但您需要首先拥有结构化数据 - 您不会将 JSON 存储在列中)格式)。因为柱状布局非常适合计算上周售出的苹果数量。
对于许多科学/数据科学用例,数组数据库似乎是要走的路(当然,还有非结构化输入数据)。例如 SciDB 和 RasDaMan。
在许多情况下(例如深度学习),矩阵和数组是您需要的数据类型,而不是列。当然,MapReduce 等在预处理中仍然有用。甚至可能是列数据(但数组数据库通常也支持类似列的压缩)。
我没有使用过列式数据库,但我使用了一种名为 Parquet 的开源列式文件格式,我认为好处可能是相同的——当您只需要查询大数据的一小部分时,数据处理速度更快列数。我在大约 50 TB 的 Avro 文件(一种面向行的文件格式)上运行了一个查询,该文件有 673 列,在 140 个节点的 Hadoop 集群上花费了大约一个半小时。使用 Parquet,相同的查询大约需要 22 分钟,因为我只需要 5 列。
如果您有少量列或使用大部分列,我认为列式数据库与面向行的数据库相比不会有太大的不同,因为您仍然必须基本上扫描所有数据。我相信列式数据库分别存储列,而面向行的数据库分别存储行。只要您能够从磁盘读取更少的数据,您的查询就会更快。
这个链接解释了更多细节。
注意:这是我的问题,我非常感谢这里的精彩答案,这帮助我掌握了这个概念。
所以,我会以我理解的方式解释这个概念:
通常,数据库中的数据以下列格式存储在内存中:
考虑这个数据:
X1 X2
1 0.7091409 -1.4061361
2 -1.1334614 -0.1973846
3 2.3343391 -0.4385071
在基于关系的行存储中,它的存储方式如下:
1, 0.7091409, -1.4061361, 2, -1.1334614, -0.1973846, 3, 2.3343391, -0.4385071
以行的形式。
在列式存储中,它将像这样存储:
1, 2, 3, 0.7091409 ,-1.1334614, 2.3343391, -1.4061361, -0.1973846, -0.4385071
以列的形式。
那么这是什么意思?
这意味着在基于行的列存储中插入(和更新)和删除速度很快,因为它只是删除最后几个值或前几个值。但是,列式存储中的情况并非如此,因为需要删除每个块存储中的值。
但是,当需要列聚合和操作时,列存储比基于行的存储具有优势,因为它们是按列存储的,因此访问单个列非常容易。