在Cassandra中,宽行,分区,群集列/键和分区键的概念是否存在于查询语言级别?还是查询语言的用户不了解的内部实现问题?
以下是How to understand the concept of wide row and related concepts in Cassandra?中的一个示例。在查询语言的命令中,以上概念似乎并不存在,但在钩子中确实存在。
考虑一个以
a
作为分区键,以b
作为聚簇列创建的表:Create TABLE test (a text,b int, c text, PRIMARY KEY(a,b)) INSERT INTO test(a,b,c) VALUES('test',2,'test2') INSERT INTO test(a,b,c) VALUES('test',1,'test1') INSERT INTO test(a,b,c) VALUES('test-new',1,'test1')
如果您按此顺序运行上述查询,cassandra会将数据存储在 以下顺序(只需检查列
b
的顺序):test -> [b:1,c=test1] [b:2,c=test2] test-new -> [b:1,c=test1]
使用
b:1
来获取分区键test
的单元格:SELECT * from test where a='test' and b=1
谢谢。
答案 0 :(得分:1)
基于您的表架构,如下所示:
Create TABLE test (a text,b int, c text, PRIMARY KEY(a,b))
分区键由“ a”和“ b”组成。我认为以下stacoverflow帖子将解决您所有有关分区键等的问题:Difference between partition key, composite key and clustering key in Cassandra?
分区和集群列等都存在于数据文件级别(因此位于数据库中)。在内部,Cassandras存储引擎可以理解这一点。在您的示例中,我创建了表,刷新了键空间,并使用sstablemetadata
请注意,您必须以与Cassandra运行时相同的用户身份运行该工具(在我的情况下,它是cassandra
用户:
$ sudo -u cassandra sstabledump /var/lib/cassandra/data/mc/test-bedc4ba012cf11ea93f72f6848f9d70d/md-1-big-Data.db
[
{
"partition" : {
"key" : [ "test" ],
"position" : 0
},
"rows" : [
{
"type" : "row",
"position" : 37,
"clustering" : [ 1 ],
"liveness_info" : { "tstamp" : "2019-11-29T17:43:35.752796Z" },
"cells" : [
{ "name" : "c", "value" : "test1" }
]
},
{
"type" : "row",
"position" : 37,
"clustering" : [ 2 ],
"liveness_info" : { "tstamp" : "2019-11-29T17:43:31.144961Z" },
"cells" : [
{ "name" : "c", "value" : "test2" }
]
}
]
},
{
"partition" : {
"key" : [ "test-new" ],
"position" : 54
},
"rows" : [
{
"type" : "row",
"position" : 95,
"clustering" : [ 1 ],
"liveness_info" : { "tstamp" : "2019-11-29T17:43:41.438779Z" },
"cells" : [
{ "name" : "c", "value" : "test1" }
]
}
]
}
]
我们可以清楚地看到键“ test”具有两个分别为值“ 1”和“ 2”的聚类行。
有关存储引擎的更多背景信息,请参见:https://docs.datastax.com/en/cassandra/3.0/cassandra/dml/dmlManageOndisk.html
这并不是您决定使用或实现的东西,而是不良数据模型的副作用。一个很好的例子是,假设您有一个像这样的表:
CREATE TABLE mc.cars (
owner_id int PRIMARY KEY,
car_reg text,
owner_name text,
price float,
purchased date
);
虽然这个模型可能还可以,但是想象一下,您有一个(幸运的!)所有者,他的收藏中有1000多辆汽车。除大型车库外,它们还可能是造成大排屋的原因。但是,如果您的表看起来像这样:
CREATE TABLE mc.cars2 (
owner_id int,
car_reg text,
owner_name text,
price float,
purchased date,
PRIMARY KEY (owner_id, car_reg)
) WITH CLUSTERING ORDER BY (car_reg ASC)
由于分区键也是由汽车登记号组成的,因此您不太可能看到宽行。
答案 1 :(得分:1)
绝对-CQL语法确实具有分区键和群集键的概念。只需查看您提供的示例:
Create TABLE test (a text,b int, c text, PRIMARY KEY(a,b))
语法(a,b)
在CQL中表示a
是分区键,而b
是集群键。再举一个例子,如果您要编写((a,b,c),d,e,f)
,则这意味着a
,b
和c
是分区键列,而d
,{{ 1}}和e
是聚簇键列。这是CQL语法。
这实际上意味着什么,我想你知道。除其他外,您可以要求以某种已知的排序顺序获取属于一个分区的所有聚类行-但是分区未排序,并且全表扫描以随机顺序返回它们。
CQL中未使用术语“宽行”作为术语,但是正如我在上面解释的那样,该概念确实存在-当“宽行”(实际上,“宽分区”更准确)时,单个分区具有很多群集行-即,同一分区键有很多不同的群集键。在Cassandra中,对宽行的支持是有限的(从真正大的分区读取可能会变慢,并且各种代码段仍然以低效的方式处理它们)。诸如this之类的一些文档建议,理想情况下,Cassandra分区的大小应最大为10MB。