“冗余”群集列有什么不利之处?

时间:2019-02-15 15:57:40

标签: cassandra cql

我注意到,在某些情况下,将常规的Cassandra列更改为集群列可以显着减小表的大小。

对于此示例表:

id     UUID        K
time   TIMESTAMP   C
state  TINYINT    (C)
value  DOUBLE

如果state是普通列,则100000行的大小估计为3.9 MB;如果state是聚簇列,则估计为2.4 MB(使用DataStax course DS220中的方法估计)。

如果您查看数据的物理存储方式,那么不难理解为什么存在这种差异。在前一种情况下,每个时间戳有两个内部单元-一个用于state,一个用于value。在后一种情况下,value被合并到单元键中,因此每个时间戳只有一个单元,并且时间戳(单元键的一部分)仅存储一次。

第二个群集列不会对要查询的内容创建任何新的限制。 SELECT * FROM table WHERE id=? AND time>=? AND time<?仍然可以。

这似乎是双赢的局面。在性能方面是否有不利之处?

(我能想到的是,如果state是常规列,则可以从INSERT中将其省略,并且将永远不会创建state内部单元。我想如果{{1} }是常规列,并且通常省略 ,因此与state是聚簇列的情况相比,该表会小很多。)


其他评论 值得注意的是,在上面的定义中,如果没有state上的相等过滤器,就无法按state进行过滤,这使得它对过滤time并不是很有用。并且,如果将state列放在state上方以解决此问题,则可以按timestate不等式进行过滤,但是如果要所有状态(IN子句),则首先按time返回行,然后按state返回行,这又不是很有用。

2 个答案:

答案 0 :(得分:1)

我认为这里的主要区别在于,如果它是集群列,则必须提供INSERT作为它的主键的一部分。另外,由于它是主键的一部分,因此您也无法更新它,这对于某些表可能是有问题的。如果您对这两个都不担心,那么我看不出您无法添加任何理由。

答案 1 :(得分:1)

1)您每state创建一行。您的数据模型将必须意识到并理解这一点。您可能会为原始模型不允许的同一state id创建两个具有不同time的行。

2)如果删除,则需要指定state或创建Range Tombstones(范围删除,因为要删除给定{{1} }和id,但可以是time的范围)。范围逻辑删除在2.1中特别昂贵(在读取路径上),并且在state异常处理程序中无法正确解决,直到发布了相当新的Cassandra版本,因此避免范围逻辑删除通常是一个好主意,除非您实际上需要他们。