Bigtable,HBase,Hypertable和Cassandra都被称为列存储,因为它们能够单独存储和访问列族。 这使它们看起来与列存储(如Sybase IQ,C-Store,Vertica,VectorWise,MonetDB,ParAccel和Infobright)处于相同的类别,这些列存储也可以单独访问列。 我认为,称呼这两个系统的列存储导致了大量的混乱和错误的预期。这篇博客文章试图澄清一些这种混乱,突出这些集合系统之间的高级差异。 最后,我将提出一些可能的方法来重命名这些组,以避免将来混淆。
对于本博客文章,我将引用以下两个组作为组A和组B:
•组A:Bigtable,HBase,Hypertable和Cassandra。 这四个系统不是A组系统的完整列表 - 这些仅仅是我在这个类别中最了解的四个系统,并且感到最有自信的讨论。
•组B:Sybase IQ,C-Store,Vertica,VectorWise,MonetDB,ParAccel和Infobright。 同样,这不是一个完整的列表,但这些是我最熟悉的系统。(从这个讨论中忽略诸如Oracle或Greenplum的行/列混合系统以避免混淆,但是这些系统的列存储方面比组A更接近组B)
A和B的区别:
虽然在组B中的系统中存在一些变化,但是对于第一级近似,该组将以以下方式存储表:
(ID)1,2,3,4,5,6
(名字)乔,杰克,吉尔,詹姆斯,杰米,贾斯汀
(姓氏)史密斯,威廉姆斯,戴维斯,米勒,威尔逊,泰勒
(Phone)555-1234,555-5668,555-5432,NULL,555-6527,555-8247
(电子邮件)jsmith@gmail.com,jwilliams@gmail.com,NULL,jmiller@yahoo.com,NULL,jtaylor@aol.com
请注意,每个值都是自己存储的,没有关于它来自哪个行或列的信息。我们可以找出它来自哪个列,因为来自同一列的所有值都是连续存储的。我们可以通过计算在同一列中有多少值来计算它来自哪一行。 id列中的第四个值匹配到与姓氏列中的第四个值相同的行以及电话列中的第四个值等。请注意,这意味着必须明确存储特定行的未定义的列作为列在列表中的NULL;否则我们不能再根据它们在相应列表中的位置来匹配值。
同时,组A中的系统将为每个值显式存储行名称,列名称或二者。例如:row2,lastname:Williams;row5,phone:555-6527等。原因是组A使用稀疏数据模型(不同的行可以定义非常不同的列集合)。为每个未定义的列存储NULL可能很快导致大多数数据库填充NULL。因此,这些系统将显式地为列族中的一行中的每个元素或单个列column-family中的每个元素的行名/值对提供列名/值对。 (组A通常还会存储每个值的时间戳,但解释这只会使这个讨论复杂化)。
这导致组B通常比组A(至少对于容易适合于关系模型的结构化数据)占用更少的存储空间。此外,通过仅存储列值而没有列名或行名称,B组优化了列操作的性能,其中读取列中的每个元素并应用操作(如谓词评估或聚合)。因此,与存储层实现结合的数据模型导致A组和B组的非常不同的目标应用程序。
重命名组名:
显然,沿着这五个维度中的每一个,组A和组B是非常不同的。 因此,即使调用它们两个列存储有一些优点(它使得看起来像“列存储运动”是一个真正的热门),我们需要作出更大的努力,以避免将来这两组混淆。以下是A组和B组为实现这一目标而提出的一些建议:
•组A:“列族存储”
组B:“列存储”(这里的问题是组B没有得到新名称,这意味着“列存储”可以指代组B或组A / B)
•组A:“非关系列存储”
•组B:“关系列存储”
•组A:“稀疏列存储”
•组B:“密集列存储”
其中,关系/非关系的区别可能是最重要的。