我目前正在尝试深入研究Cassandra的数据模型及其与Bigtable的关系,但结果却出现了关于Column Family概念的强烈头痛。
主要是我的问题和already answered。但是,我对答案不满意:))
首先,我已经阅读Bigtable paper,特别是有关其数据模型,即数据的存储方式。据我所知,Bigtable中的每个表基本上依赖于维度行,列和时间的多维稀疏映射。地图按行排序。列可以使用名称约定族进行分组:限定符到列族。因此,单行可以包含多个列族(请参阅本文中的示例图)。
虽然有人说Cassandra依赖于Bigtable数据模型,但我多次读到,在Cassandra中,一个列族包含多行,并且在某种程度上与关系数据存储中的表相当。这与Bigtable的方法相反,其中一行可能包含多个列族?什么是第一,列系列或行:)?这些概念是否具有可比性?
答案 0 :(得分:15)
你联系到的答案是从6年前开始的,从那时起Cassandra就发生了很多变化。当Cassandra开始时,它的数据模型确实基于BigTable。一行数据可以包含任意数量的列,这些列中的每一列都具有名称和值。一行可以有一千个不同的列,另一行可以有一千个其他列 - 行不必具有相同的列。这样的数据库被称为"无架构",因为没有每行需要遵守的架构。
但托托,我们不再在堪萨斯州了 - 而卡桑德拉的模特改变了焦点(尽管不是在本质上),我将尝试解释如何以及为什么:
随着Cassandra的成熟,它的开发人员开始意识到无模式并不像他们曾经认为的那样伟大。模式在确保应用程序正确性方面很有价值。而且,由于一个记录中有1000个单独命名的字段,因此通常不会在一行中达到1000列。相反,更常见的情况是记录实际上包含200个条目,每个条目有5个字段。模式应该修复这些条目中的每一个应该具有的这5个字段,并且定义每个这些单独条目的内容称为"集群密钥"。因此,在六年前的Cassandra 0.8时代,这些想法被引入Cassandra作为" CQL" (卡桑德拉查询语言)。
例如,在CQL中,我们声明一个列族(尽职称重命名为" table")具有一个模式,具有已知的字段列表:
CREATE TABLE groups (
groupname text,
username text,
email text,
age int,
PRIMARY KEY (groupname, username)
)
这个模式表示表中的每个宽行(现在,在现代的Cassandra中,这被重命名为"分区"),使用键" groupname"是一个可能很长的用户列表,每个用户都有用户名,电子邮件和年龄字段。 " PRIMARY KEY"中的第一个名字。说明符是分区键(它确定宽行的键),第二个称为聚类键(它确定组成宽行的小行的键)。
尽管采用了新的CQL装扮,Cassandra继续使用旧的BigTable-wide-row-without-schema实现来实现这些新概念。例如,假设我们的数据有一个组" mygroup"有两个人,(john,john @ somewhere.com,27)和(joe,joe @ somewhere.com,38)。 Cassandra将以下四个列名称>值添加到宽行:
john:email -> john@somewhere.com
john:age -> 27
joe:email -> joe@somewhere.com
joe:age -> 27
注意我们如何得到一个包含4列的宽行 - 每行2个非关键字段(电子邮件和年龄),再乘以分区中的行数(2)。群集密钥字段"用户名"不再作为价值出现在任何地方,而是作为专栏名称的一部分!所以如果我们有两个用户名值" john"和" joe",我们有一些列前缀" john"还有一些列以#34; joe"为前缀,当我们阅读专栏" joe:email"我们知道这是具有username = joe。
的行的电子邮件字段的值Cassandra仍然具有这种内部二元性 - 将面向用户的CQL行和群集密钥转换为旧式宽行。直到最近,Cassandra的磁盘格式被称为" SSTables"仍然没有模式,并使用如上所示的列名称的复合名称。我在Scylla的网站https://github.com/scylladb/scylla/wiki/SSTables-Data-File上写了SSTable格式的详细描述(Scylla是我贡献的更高效的C ++重新实现的Cassandra)。但是,列名在这种格式下效率非常低,因此Cassandra最近(在3.0版本中)切换到不同的文件格式,这是第一次接受群集密钥和模式完整行作为一等公民。这是7年前无模式Cassandra的棺材中的最后一个钉子。 Cassandra现在一直是架构式的。