与 Bigtable 相比,Cassandras 数据模型中有关列族的概念差异?

Conceptual difference concerning column families in Cassandras data model compared to Bigtable?

我目前正在尝试深入研究 Cassandra 的数据模型及其与 Bigtable 的关系,但最终对列族概念感到非常头疼。

主要是我的问题被问到 already answered。但是,我对答案不满意:)

首先,我阅读了 Bigtable paper,特别是关于它的数据模型,即数据是如何存储的。据我了解,Bigtable 中的每个 table 基本上都依赖于具有行、列和时间维度的多维稀疏映射。地图按行排序。可以使用名称约定 family:qualifier 将列分组到一个列族。因此,单个行可以包含多个列族(参见论文中的示例图)。

虽然说 Cassandra 依赖于 Bigtable 数据模型,但我多次读到,在 Cassandra 中,列族包含多行,并且在某种程度上可以与关系中的 table 相媲美数据存储。这是否与 Bigtable 的方法相反,Bigtable 的方法是一行可以包含多个列族?首先是列族还是行:)?这些概念是否具有可比性?

您链接到的答案是 6 年前的,此后 Cassandra 发生了很多变化。 Cassandra 刚开始的时候,它的数据模型确实是基于 BigTable 的。一行数据可以包含任意数量的列,每一列都有一个名称和一个值。一行可以有一千个不同的列,而不同的行可以有一千个其他列 - 行不必具有相同的列。这样的数据库称为"schema-less",因为没有每行需要遵守的架构。

但是 Toto,我们已经不在堪萨斯州了 - 从那以后 Cassandra 的模型的焦点发生了变化(虽然不是本质上的),我将尝试解释如何以及为什么:

随着 Cassandra 的成熟,它的开发人员开始意识到无模式并不像他们曾经认为的那么好。模式对于确保应用程序的正确性很有价值。此外,通常不会仅仅因为一条记录中有 1000 个单独命名的字段而在一行中达到 1000 列。相反,更常见的情况是记录实际上包含 200 个条目,每个条目有 5 个字段。该模式应该固定这些条目中的每一个都应该具有的这 5 个字段,并且定义这些单独条目中的每一个的内容称为 "clustering key"。因此,大约在六年前的 Cassandra 0.8 时代,这些想法作为 "CQL"(Cassandra 查询语言)引入了 Cassandra。

例如,在 CQL 中声明一个列族(已尽职地重命名 "table")有一个模式,其中有一个已知的字段列表:

CREATE TABLE groups (
    groupname text,
    username text,
    email text,
    age int,
    PRIMARY KEY (groupname, username)
)

这个模式说 table 中的每个宽行(现在,在现代 Cassandra 中,它被重命名为 "partition"),键 "groupname" 是一个可能很长的列表用户,每个都有用户名、电子邮件和年龄字段。 "PRIMARY KEY" 说明符中的第一个名称是分区键(它确定宽行的键),第二个名称称为聚类键(它确定共同组成宽行的小行的键).

尽管有新的 CQL 修饰,Cassandra 继续使用良好的旧 BigTable-wide-row-without-schema 实现来实现这些新概念。例如,假设我们的数据有一组 "mygroup",其中有两个人,(john, john@somewhere.com, 27) 和 (joe, joe@somewhere.com, 38)。 Cassandra 将以下四列 names->values 添加到宽行:

john:email -> john@somewhere.com
john:age -> 27
joe:email -> joe@somewhere.com
joe:age -> 27

注意我们是如何得到一个有 4 列的宽行 - 每行 2 个非关键字段(电子邮件和年龄),乘以分区 (2) 中的行数。集群键字段 "username" 不再作为值出现在任何地方,而是作为列名称的一部分!所以如果我们有两个用户名值 "john" 和 "joe",我们有一些列前缀为 "john",一些列前缀为 "joe",当我们读取列 "joe:email" 时我们知道这是具有 username=joe.

的行的电子邮件字段的值

Cassandra 仍然具有这种内部二元性 - 将面向用户的 CQL 行和聚类键转换为旧式宽行。直到最近,Cassandra 的磁盘格式 "SSTables" 仍然是无模式的,并且使用如上所示的复合名称作为列名称。我在 Scylla 的网站 https://github.com/scylladb/scylla/wiki/SSTables-Data-File 上详细描述了 SSTable 格式(Scylla 是我贡献的 Cassandra 的更高效的 C++ 重新实现)。但是,这种格式的列名效率非常低,因此 Cassandra 最近(在版本 3.0 中)切换到一种不同的文件格式,该格式首次接受集群键和模式满行作为第一个 class 公民。这是 7 年前无模式 Cassandra 棺材上的最后一颗钉子。 Cassandra 现在完全是模式完整的。