>每个行具有可变列数的无模式数据库.
>数千万条记录和数十列.
>每天数百万次查询.
>每天写入数千.
>查询将在多个列(不仅是键)上进行过滤.
我正在考虑按比例建造的Cassandra.
我的问题是:
>在这种情况下,我需要水平缩放吗?
> Cassandra是否支持使用几个键来指向相同的列族?
编辑
我想确保我的观点是正确的.所以,下面的例子说明了我从你的答案得到的:
所以,如果我们有以下列系列(它包含一些商店产品及其详细信息)
products // column-family name { x = { "id":"x",// this is unique id for the row. "name":"Laptop","screen":"15 inch","OS":"Windows"} y = { "id":"y","screen":"17 inch"} z = { "id":"z",// this is unique id for the row. "name":"Printer","page per minute":"20 pages"} }
并且,我们要添加“名称”搜索参数,我们将使用不同的行键创建另一个CF副本,如下所示:
products { "x:name:Laptop" = { "id":"x","name":"Laptop","OS":"Windows"} "y:name:Laptop" = { "id":"y","screen":"17 inch"} "z:name:Printer" = { "id":"z","name":"Printer","ppm":"20 pages"} }
products { "x:screen:15 inch" = { "id":"x" "name":"Laptop","OS":"Windows"} "y:screen:17 inch" = { "id":"y","screen":"17 inch"} }
但是,如果我们想根据10个搜索参数或它们的任意组合进行查询(在我的应用程序中就是这种情况),那么我们必须创建1023个列系列[(2到10) – 1].并且由于大多数行将具有许多搜索参数,这意味着我们需要大约1000倍的额外存储来建模数据(以这种方式),这不是很少,特别是如果我们在原始CF中有10,000,000行.
这是您建议的数据模型吗?
另一点:我无法确切地看到为什么创建二级索引会放弃或剥夺无模式模型.
解决方法
我们在6个cassandra节点集群上每天进行175,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"
通过这种方式,我们可以搜索obj,其中p1 = value1,p2 = value2,p1 = value1 AND p2 = value2或者只是它的唯一id xxx.
如果您不想这样做,唯一的另一个选择是使用辅助索引和索引查询,但这会放弃您的问题的“无模式”要求.
编辑 – 一个例子.
我们希望保存定义为“产品”的对象
class Products{ string uid; string name; int screen_size; //in inches string os; string brand; }
我们将它序列化为字符串或byteArray(我总是倾向于使用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”和column_name =“screen_size:15_uid:MI615FMDO548”
– key =“brand:0_to_15”和column_name =“screen_size:15_uid:MI615FMDO548”
为什么我要将uid添加到列名?
使所有列名称对于唯一产品是唯一的.
示例第2部分现在我们已经添加了
"{uid:"MI615FMDO548",brand:"Samsung"}" "{uid:"MI615FMD5589",name:"SFG-0097",screen_size:14,brand:"Samsung"}" "{uid:"MI615FMD1111",screen_size:17,brand:"Samsung"}" "{uid:"MI615FMDO687",name:"SFG-0095",screen_size:13,brand:"Samsung"}"
我们最终会得到以下列系列:
Products{ -Row:"brand:Samsung" => "screen_size:13_uid:MI615FMDO687":"{uid:"MI615FMDO687",brand:"Samsung"}" => "screen_size:14_uid:MI615FMD5589":"{uid:"MI615FMD5589",brand:"Samsung"} => "screen_size:15_uid:MI615FMDO548":"{uid:"MI615FMDO548",brand:"Samsung"}" => "screen_size:17_uid:MI615FMD1111":"{uid:"MI615FMD1111",brand:"Samsung"}" -Row:"screen_size:0_to_15" => "brand:Samsung_uid:MI615FMDO687":"{uid:"MI615FMDO687",brand:"Samsung"}" => "brand:Samsung_uid:MI615FMD5589":"{uid:"MI615FMD5589",brand:"Samsung"} => "brand:Samsung_uid:MI615FMDO548":"{uid:"MI615FMDO548",brand:"Samsung"}" -Row:"screen_size:16_to_17" => "brand:Samsung_uid:MI615FMD1111":"{uid:"MI615FMD1111",brand:"Samsung"}" -Row:"uid:MI615FMDO687" => "product":"{uid:"MI615FMDO687",brand:"Samsung"}" -Row:"uid:MI615FMD5589" => "product":"{uid:"MI615FMD5589",brand:"Samsung"} -Row:"uid:MI615FMDO548" => "product":"{uid:"MI615FMDO548",brand:"Samsung"}" -Row:"uid:MI615FMD1111" => "product":"{uid:"MI615FMD1111",brand:"Samsung"}" }
现在,通过跨列名称使用范围查询,您可以按品牌和屏幕大小进行搜索.
希望这很有用