我想用这些列创建一个表:id1, id2, type, time, data, version
。
常见查询是:
select * from table_name where id1 = ... and id2 =... and type = ...
select * from table_name where id1= ... and type = ... and time > ... and time < ...
我不知道如何为快速查询设置主键?
由于您有两个不同的查询,因此您可能需要有两个不同的表才能使其表现良好。这对于Cassandra数据模型来说并不罕见。请记住,对于这两者,Cassandra中的PRIMARY KEY定义在很大程度上取决于基数和预期的查询模式。因为仅提供了后者,所以您可能需要根据id1
,id2
和type
的基数进行调整。
select * from table_name where id1 = X and id2 = Y and type = Z;
所以在这里,我将进行有根据的猜测,就像ID通常一样,id1
和id2
几乎是唯一的(高基数)。我不知道您的应用程序中有多少种可用的类型,但是只要不超过10,000种,它就可以工作:
CREATE TABLE table_name_by_ids (
id1 TEXT,
id2 TEXT,
type TEXT,
time TIMESTAMP,
data TEXT,
version TEXT,
PRIMARY KEY ((id1,id2),type));
[这将把分区的键锁定在id1
和id2
的联合哈希上,并按type
排序内部的行(默认升序)。
select * from table_name where id1= X and type = Z and time > A and time < B;
同样,支持此查询的表将如下所示:
CREATE TABLE table_name_by_id1_time (
id1 TEXT,
id2 TEXT,
type TEXT,
time TIMESTAMP,
data TEXT,
version TEXT,
PRIMARY KEY ((id1),type,time))
WITH CLUSTERING ORDER BY (type ASC, time DESC);
同样,只要您没有超过数千种类型/时间组合,这应该可以工作。
我要做的最后一项调整是,判断在应用程序的整个生命周期中您期望有多少种类型/时间组合。如果此数据将随着时间增长,则以上内容将导致分区增长到无法维护的程度。为了避免这种情况的发生,我还建议您添加一个时间段“ bucket”。
version TEXT,
month_bucket TEXT,
PRIMARY KEY ((id1,month_bucket),type,time))
WITH CLUSTERING ORDER BY (type ASC, time DESC);
与此类似,也需要调整查询:
select * from table_name_by_id1_time
where id1= 'X' and type = 'Z'
and month_bucket='201910'
and time > '2019-10-07 00:00:00' and time < '2019-10-07 16:22:12';
希望这会有所帮助。
我如何保证这两个插入的原子性?
简单地说,您可以在原子批处理中同时运行两个INSERT
。
BEGIN BATCH
INSERT INTO table_name_by_ids (
id1, id2, type, time, data, version
) VALUES (
'X', 'Y', 'Z', '2019-10-07 12:00:01','stuff','1.0'
) ;
INSERT INTO table_name_by_id1_time (
id1, id2, type, time, data, version, month_bucket
) VALUES (
'X', 'Y', 'Z', '2019-10-07 12:00:01','stuff','1.0','201910'
);
APPLY BATCH;
有关详细信息,请查看有关原子批处理的DataStax文档:https://docs.datastax.com/en/dse/6.7/cql/cql/cql_using/useBatchGoodExample.html