我对宽行,群集,手动索引等有疑问...我希望有人可以在这里提供帮助。 CQL版本为3,Cassandra为2.0.1;
让我们说,我有CF'产品'
id timeuuid
location varchar
shopname varchar
expiry timestamp
count int
PRIMARY KEY (id)
我希望能够在到期时订购的特定地点选择产品。创建寄存器如:
CF 'id_register_by_loc_expy'
location varchar
expiry timestamp
id timeuuid
PRIMARY KEY (location,expiry,id)
并希望选择按到期日订购的特定商店名称的产品。然后创建:
CF 'id_register_by_shopname_expy'
shopname vachar
expiry timestamp
id timeuuid
PRIMARY KEY (shopname,expiry,id)
这样我可以按如下方式进行有效的查询/切片:
1.从id_reg_by_loc_expy中选择id,其中location ='x'; // [自然按到期顺序排列]
2.从id_reg_by_loc_expy中选择id,其中location ='x'和expiry> 't1'和到期< 'T2';
3.从id ='id';
的产品中选择*和
4.从id_reg_by_shop_exp中选择id,其中shopname ='y'; // [自然按到期顺序排列]
和
5.从id_reg_by_shop_count中选择id,其中shopname ='y'; // [按计数自然排序]
等。
如果集群密钥需要更改,我需要重新排序寄存器中这些特定行的条目,该怎么办。
我遇到的问题是:
重新插入新的过期(或计数)会产生新的主键,因此不会更新我的旧条目。
我不能“更新...设置expiry ='x2'where ......”,因为到期是主键的一部分。
由于墓碑限制,使用新主键插入然后删除旧主键是不好的选择。
我尝试过的事情是:
CF'id_reg_by_loc_expy'
location varchar
expiry timestamp
id timeuuid
otherSecondaryIndex varchar
PRIMARY KEY (location,id)
但;
一个。这并没有利用Cassandra存储的排序功能。我希望每行都有很多产品,并且希望避免需要搜索整行;和
湾事实证明,无论如何我实际上都无法进行如下查询:
(i)从id_reg _...中选择id,其中location ='x'顺序为dtg asc;
错误请求:不支持带有第二个索引的ORDER BY。
Or
(ii)从id_reg _...中选择id,其中location ='x'和expiry> 't1'和到期< 'T2';
错误请求:使用Equal运算符
的by-columns子句中不存在索引列虽然我'可以'这样做:
(iii)从id_reg _...中选择id,其中location ='x',otherSecIndex ='y',expiry> 't1'和到期< 'T2';
**请注意,这需要我强制'允许过滤'并且看起来很差设计包含另一个二级索引只是为了允许这个查询..即一个我不太感兴趣的查询比'order by'查询反正。
2.使用timeuuid代替到期时间戳。即使这是我无法找到办法的工作,也无法帮助我按计数排序。
我错过了一些基本的东西吗?我需要采用所有墓碑缓解技术的答案吗?或者在我的申请中做一些订购?
干杯, 添
答案 0 :(得分:1)
如果排序列不是主键的一部分,则无法进行排序。 Cassandra不会在查询时进行排序。
您是否希望每个product_id多次更改到期戳?如果没有,那么墓碑不应该是一个大问题,特别是如果你的行真的像你描述的那样小。您可以调整相关设置,例如gc_grace_seconds
(墓碑周围有多长时间),以确保它们符合您的运营需求和容量。
如果您计划非常频繁地更新到期时间,那么我的第一直觉是,如果没有一些测量和手动操作来获得稳定的配置,这是一种无法轻松处理的模式。如果你开始被墓碑淹没,你可能不得不求助于一个主要的压实计划来有效地去除累积的墓碑。
最重要的是,任何具有类似队列语义的存储模式在Cassandra中以可扩展的方式实现都是非常重要的。至少这是我的直觉。