Cassandra 不是您可以通过行键以外的任何内容查询的数据库。但是您可以定制您的数据模型来支持这些查询。
我们每天在 6 个 cassandra 节点集群上执行 175,000,000 次查询(很简单!),但我们只使用 row_keys 和列请求数据,因为我们已经让我们的数据模型以这种方式工作。我们不使用索引查询。
为了支持更丰富的查询,我们使用将用作搜索参数的数据对数据进行非规范化处理,以生成检索数据的键。
示例:考虑我们保存以下对象:
obj {
id : xxx //assuming id is a unique id across the system
p1 : value1
p2 : value2
}
并且我们知道我们想通过这些参数中的任何一个进行搜索,然后我们将保存 obj 的副本
对于 column_names 或键如下:
"p1:value1:xxx"
"p2:value2:xxx"
"p1:value1:p2:value2:xxx"
"xxx"
这样我们可以通过 p1 = value1, p2 =value2, p1 = value1 AND p2 = value2 或仅通过它的唯一 id xxx 来搜索 obj。
如果您不想这样做,唯一的其他选择是使用二级索引和索引查询,但这会放弃您问题的“无模式”要求。
编辑 - 一个示例。 我们想要保存对象“产品”定义为
class Products{
string uid;
string name;
int screen_size; //in inches
string os;
string brand;
}
我们将它序列化为字符串或字节数组(我总是倾向于使用 Jackson Json 或 Protobuf ......两者都可以很好地与 cassandra 一起使用并且速度非常快)。
我们将该字节数组放入一列中。
现在是重要的部分:创建列名和行键。
假设我们要按屏幕分辨率搜索并可能按品牌过滤。
我们将屏幕尺寸的桶定义为 ["0_to15", "16_to_21", "21_up"]
给定列:
"{uid:"MI615FMDO548", name:"SFG-0098", screen_size:15, os:"Android JellyBean", brand:"Samsung"}
保存一份副本:
- key = "brand:Samsung" and column_name = "screen_size:15_uid:MI615FMDO548"
- key = "brand:0_to_15" and column_name = "screen_size:15_uid:MI615FMDO548"
为什么要在列名中添加 uid?
使唯一产品的所有列名称唯一。
示例第 2 部分现在假设我们添加了
"{uid:"MI615FMDO548", name:"SFG-0098", screen_size:15, os:"Android JellyBean", brand:"Samsung"}"
"{uid:"MI615FMD5589", name:"SFG-0097", screen_size:14, os:"Android JellyBean", brand:"Samsung"}"
"{uid:"MI615FMD1111", name:"SFG-0098", screen_size:17, os:"Android JellyBean", brand:"Samsung"}"
"{uid:"MI615FMDO687", name:"SFG-0095", screen_size:13, os:"Android JellyBean", brand:"Samsung"}"
我们将得到以下列族:
Products{
-Row:"brand:Samsung"
=> "screen_size:13_uid:MI615FMDO687":"{uid:"MI615FMDO687", name:"SFG-0095", screen_size:13, os:"Android JellyBean", brand:"Samsung"}"
=> "screen_size:14_uid:MI615FMD5589":"{uid:"MI615FMD5589", name:"SFG-0097", screen_size:14, os:"Android JellyBean", brand:"Samsung"}
=> "screen_size:15_uid:MI615FMDO548":"{uid:"MI615FMDO548", name:"SFG-0098", screen_size:15, os:"Android JellyBean", brand:"Samsung"}"
=> "screen_size:17_uid:MI615FMD1111":"{uid:"MI615FMD1111", name:"SFG-0098", screen_size:17, os:"Android JellyBean", brand:"Samsung"}"
-Row:"screen_size:0_to_15"
=> "brand:Samsung_uid:MI615FMDO687":"{uid:"MI615FMDO687", name:"SFG-0095", screen_size:13, os:"Android JellyBean", brand:"Samsung"}"
=> "brand:Samsung_uid:MI615FMD5589":"{uid:"MI615FMD5589", name:"SFG-0097", screen_size:14, os:"Android JellyBean", brand:"Samsung"}
=> "brand:Samsung_uid:MI615FMDO548":"{uid:"MI615FMDO548", name:"SFG-0098", screen_size:15, os:"Android JellyBean", brand:"Samsung"}"
-Row:"screen_size:16_to_17"
=> "brand:Samsung_uid:MI615FMD1111":"{uid:"MI615FMD1111", name:"SFG-0098", screen_size:17, os:"Android JellyBean", brand:"Samsung"}"
-Row:"uid:MI615FMDO687"
=> "product":"{uid:"MI615FMDO687", name:"SFG-0095", screen_size:13, os:"Android JellyBean", brand:"Samsung"}"
-Row:"uid:MI615FMD5589"
=> "product":"{uid:"MI615FMD5589", name:"SFG-0097", screen_size:14, os:"Android JellyBean", brand:"Samsung"}
-Row:"uid:MI615FMDO548"
=> "product":"{uid:"MI615FMDO548", name:"SFG-0098", screen_size:15, os:"Android JellyBean", brand:"Samsung"}"
-Row:"uid:MI615FMD1111"
=> "product":"{uid:"MI615FMD1111", name:"SFG-0098", screen_size:17, os:"Android JellyBean", brand:"Samsung"}"
}
现在通过跨列名称使用范围查询,您可以按品牌和屏幕大小进行搜索。
希望对你有用