数据建模(二级索引与群集密钥)

时间:2015-06-23 19:20:24

标签: cassandra data-modeling

我试图了解如果我选择它是否会成为性能问题 选项1:  非常高的唯一值列作为分区键(order_id),并在store_id和status上创建索引。 (我可以查询order_id | store_id | status | store& status,以及***更新(重要)状态,基于order_id)

选项2:  store_id as partition_key和非常高的唯一值列作为聚类键(order_id)并在状态上创建二级索引(以便我可以过滤状态) (我可以查询store_id | store& order_id | store& status |以及**基于store& order_id更新状态)

我想知道上述场景中的性能问题。哪一个会是更好的选择。非常感谢你的帮助和时间。

1 个答案:

答案 0 :(得分:0)

选项1 很有意思,但您需要小心索引。有关详细信息,请参阅other question(尤其是有关同时查询多个二级索引的位)。 tables purpose built for your index lookups可以缓解这种情况(下面将进一步讨论)。

高度唯一的分区键的优点是数据将更多地分布在您的群集周围。这里的缺点是,当您使用WHERE store_id = 'foo'执行请求时,需要查询群集中的所有节点,因为分区密钥没有限制。

选项2 你必须小心。如果您的分区键只是store_id,那么每个订单都将放在此分区中。对于每个订单,将 n 列添加到表示订单上每个属性的商店的单行中。关于数据位置,给定商店的所有订单都将放在同一个Cassandra节点上。

在这两种情况下,为什么不按状态追查订单查询表?这将消除您对该字段的二级索引的需求。特别是考虑到它的基数相对较小。

CREATE TABLE orders_by_store_id_status (
  store_id VARCHAR,
  status   VARCHAR,
  order_id VARCHAR,
  ... <additional order fields needed to satisfy your query> ...
  PRIMARY KEY ((store_id, status), order_id)
);

这将允许您查询具有给定store_id和状态的所有订单。

SELECT * FROM orders_by_store_id_status WHERE store_id = 'foo' AND status = 'open';

读取速度很快,因为分区键限制了我们执行查询的节点数。