我注意到,在某些情况下,将常规的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
上方以解决此问题,则可以按time
和state
不等式进行过滤,但是如果要所有状态(IN子句),则首先按time
返回行,然后按state
返回行,这又不是很有用。
答案 0 :(得分:1)
我认为这里的主要区别在于,如果它是集群列,则必须提供INSERT作为它的主键的一部分。另外,由于它是主键的一部分,因此您也无法更新它,这对于某些表可能是有问题的。如果您对这两个都不担心,那么我看不出您无法添加任何理由。
答案 1 :(得分:1)
1)您每state
创建一行。您的数据模型将必须意识到并理解这一点。您可能会为原始模型不允许的同一state
id
创建两个具有不同time
的行。
2)如果删除,则需要指定state
或创建Range Tombstones
(范围删除,因为要删除给定{{1} }和id
,但可以是time
的范围)。范围逻辑删除在2.1中特别昂贵(在读取路径上),并且在state
异常处理程序中无法正确解决,直到发布了相当新的Cassandra版本,因此避免范围逻辑删除通常是一个好主意,除非您实际上需要他们。