在Cassandra中计算行数

3

我有一个cassandra表subscription,包含以下列:

firmId, //partition key
acct_info,
appId,
can

firmId是分区键,没有聚簇键。

appId字段可以有以下三个值之一:

appId1, appId2, appId3 

我希望您能为每个appId值计算行数。例如:appId1的行数,appId2的行数和appId3的行数。
我已经尝试过:
select COUNT(*) from subscription;
select COUNT(appId) from subscription;

请问有人能帮我得到表格的总行数吗?

4个回答

0

使用CQL查询无法实现。

您需要类似于SELECT appId,COUNT(appId) FROM subscription GROUP BY appId的内容,但是在cassandra中不可能实现

尝试使用spark-cassandra-connector获取现有记录的计数,并创建一个使用counters的单独表,在其中可以维护计数(在插入和删除期间更新值)


ALLOW FILTERING怎么样? - Vishal Sharma

0

正如其他人所说:这种简单的方式不可能实现,也许您最好使用SQL数据库。

Ashraful关于计数器的答案非常好,除非您在数据上有TTL,因为在这种情况下计数器不会自动递减。

还有另一种方法,可能有用,也可能没有用,但这需要将appId作为聚簇键,从而改变数据模型的语义。如果是这样的话:您可以创建一个材料化视图,基本上转置您的数据模型,并使appId成为主键,firmId成为次要键。另一方面,这有一些不同的缺点:对视图的写入速度相当慢,因此如果您的工作负载写入较重,请勿使用视图。此外,由于您的appId,即视图中的行键,只能取3个值,因此您的集群分布不好,基本上只产生3行。

免责声明:我从未在生产中使用过材料化视图。


0
您可以使用以下CQL语句获取相应的计数:
select count(*) from subscription WHERE appid = 'appId1' ALLOW FILTERING ;
select count(*) from subscription WHERE appid = 'appId2' ALLOW FILTERING ;
select count(*) from subscription WHERE appid = 'appId3' ALLOW FILTERING ; 

我在Cassandra 3.11.2中测试过这个。我不知道为什么其他人都说这是不可能的。


你所建议的是糟糕的设计,应该避免...appId不是分区键...也不是聚簇键的一部分...尽管你会辩称可以创建和查询二级索引...但你测试的数据集有限...试着插入更多数据,你的查询将开始超时。 - undefined_variable
我并不是说这是一个好的设计,但是没有任何答案提到这一点,所以我不得不加上。超时阈值也可以增加。虽然我无法将其增加到30秒以上(我不知道背后的原因)。那么长时间足以在至少一百万行上运行此查询。再次强调,这可能不是最佳方法,但在某些情况下可以完成工作。 - Vishal Sharma

0

您的当前数据模型无法进行此类查询。

在Cassandra中,数据是基于您的查询进行建模的。

因此,您应该以这种方式对数据进行建模,以便可以进行此类查询。

例如,创建一个新表格如下:

CREATE TABLE appIdCounter(
    appId text PRIMARY KEY,
    count counter
);

所以每当出现一个新的appId值时,将计数器的值增加一。
UPDATE appIdCounter SET count = count + 1 WHERE appId = ?;

现在您可以轻松地通过一条查询语句获取每个应用程序ID的计数。
SELECT * FROM appIdCounter ;

你的回答让人觉得这是不可能的,但实际上可以使用ALLOW FILTERING在OP的表中获取所需的计数。该方法与您的方法相比如何,是另一回事。 - Vishal Sharma
@VishalSharma 或许在Cassandra 3.11或以上版本中可以使用ALLOW FILTERING。但是请注意:仅在开发过程中使用ALLOW FILTERING! - Ashraful Islam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接