目前,我正在与Cassandra打交道。
在阅读博客文章时,据说:
发出CQL查询时,您必须包括所有分区键列, 最低限度。 (https://shermandigital.com/blog/designing-a-cassandra-data-model/)
但是,在我的数据库中似乎可以不包含所有分区键。下表:
$sc_att_charter_lengths = $charter_lengths;
所以我可以做CREATE TABLE usertable (
personid text,
name text,
"timestamp" timestamp,
active boolean,
PRIMARY KEY ((personid, name), timestamp)
) WITH
CLUSTERING ORDER BY ("timestamp" DESC)
AND comment=''
AND read_repair_chance=0
AND dclocal_read_repair_chance=0.1
AND gc_grace_seconds=864000
AND bloom_filter_fp_chance=0.01
AND compaction={ 'class':'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy',
'max_threshold':'32',
'min_threshold':'4' }
AND compression={ 'chunk_length_in_kb':'64',
'class':'org.apache.cassandra.io.compress.LZ4Compressor' }
AND caching={ 'keys':'ALL',
'rows_per_partition':'NONE' }
AND default_time_to_live=0
AND id='23ff16b0-c400-11e8-55c7-2b453518a213'
AND min_index_interval=128
AND max_index_interval=2048
AND memtable_flush_period_in_ms=0
AND speculative_retry='99PERCENTILE';
。但是,根据博客文章,我还必须包括select * from usertable where personid = 'ABC-02';
。
有人可以解释吗?
答案 0 :(得分:1)
在cassandra中,分区键将数据分散到整个群集中。它计算分区键的哈希值,并确定数据在集群中的位置。
一个例外是,如果您使用ALLOW FILTERING或二级索引,则不需要在查询的位置也包含所有分区键。
有关更多信息,请参阅博客文章:
分区键的目的是将数据拆分为多个分区 整个分区存储在群集中的单个节点上的位置 (每个节点存储许多分区)。读取或写入数据时 从群集中,使用名为Partitioner的函数来计算 分区键的哈希值。该哈希值用于确定 包含该行的节点/分区。使用集群密钥 进一步在给定分区内搜索一行。
Apache Cassandra中的选择查询看起来很像来自 关系数据库。但是,它们明显更多 受限制的。 Cassandra的“ where”子句中允许的属性 查询必须包含完整的分区键,其他子句可能 仅引用集群键列或 正在查询表。
在“ where”中要求分区键属性有助于Cassandra 保持恒定的结果集检索时间,因为群集是 通过允许Cassandra确定分区来向外扩展,从而 查询必须是节点(甚至磁盘上的数据文件) 定向到。
如果查询未指定列表中所有列的值 “ where”子句中的主键,Cassandra将不会执行它,并且 给出以下警告:
‘InvalidRequest:来自服务器的错误:代码= 2200 [无效查询] message =“无法执行此查询,因为它可能涉及数据过滤 因此可能具有无法预测的性能。如果要执行 尽管性能不可预测,但此查询仍使用ALLOW 正在过滤”‘
https://www.instaclustr.com/apache-cassandra-scalability-allow-filtering-partition-keys/
https://www.datastax.com/dev/blog/a-deep-look-to-the-cql-where-clause
答案 1 :(得分:0)
根据你的模式,你的时间戳列是聚类列,排序列,不属于分区键。这就是为什么它不是必需的。
(personid, name) 是您的分区列。