【问题标题】:Count distinct values计算不同的值
【发布时间】:2017-09-14 10:34:10
【问题描述】:

考虑下表:

CREATE TABLE users (
  date timestamp,
  user_id text,
  PRIMARY KEY (date, user_id)
);

以以下数据为例:

date       user_id

25Aug2013    1
25Aug2013    2
25Aug2013    1
25Aug2013    3

26Aug2013    1
26Aug2013    2

27Aug2013    2
27Aug2013    3
27Aug2013    4

28Aug2013    1
28Aug2013    2
28Aug2013    1
28Aug2013    3

如何计算唯一 user_id 的数量?

【问题讨论】:

标签: cassandra cql


【解决方案1】:

一个想法可能是使用set collection

CREATE TABLE stats_unique (
  stat_group text,
  user_ids set<text>,
  PRIMARY KEY (stat_group)
);

插入将自动从集合中删除重复项,并且选择将一次检索所有 ID,因此您在应用程序级别进行计数。

如果您只对唯一 user_id 的数量感兴趣而不实际从磁盘中检索它们,恐怕您需要更改的不仅仅是应用程序代码。

记得深入了解collections limitations

【讨论】:

  • 也不错。
【解决方案2】:

在 cmets 中,我或多或少地提到了与问题相关的内容,但我想发表评论。

就我个人而言,当我与 cassandra 处于类似情况时,我滥用了它所具有的属性,这有点像 hack,但我认为它在这种情况下可能是“有用的”。

基本上,我创建了一张边桌,用来放置所有独特的东西。即

CREATE TABLE stats_unique (
  stat_group text,
  user_id text,
  PRIMARY KEY (stat_group, user_id)
);

写作通常很便宜,而且我对其他简单的东西没有任何问题 写,毕竟 cassandra 是为此而构建的。所以每次我插入 到基表我也插入到stats_unique 表中。对于您的示例,它将类似于:

INSERT INTO stats_unique (stat_group, user_id) VALUES ('users', '1');
INSERT INTO stats_unique (stat_group, user_id) VALUES ('users', '2');
INSERT INTO stats_unique (stat_group, user_id) VALUES ('users', '1');
INSERT INTO stats_unique (stat_group, user_id) VALUES ('users', '3');

INSERT INTO stats_unique (stat_group, user_id) VALUES ('users', '1');
INSERT INTO stats_unique (stat_group, user_id) VALUES ('users', '2');

INSERT INTO stats_unique (stat_group, user_id) VALUES ('users', '2');
INSERT INTO stats_unique (stat_group, user_id) VALUES ('users', '3');
INSERT INTO stats_unique (stat_group, user_id) VALUES ('users', '4');

INSERT INTO stats_unique (stat_group, user_id) VALUES ('users', '1');
INSERT INTO stats_unique (stat_group, user_id) VALUES ('users', '2');
INSERT INTO stats_unique (stat_group, user_id) VALUES ('users', '1');
INSERT INTO stats_unique (stat_group, user_id) VALUES ('users', '3');

然后当我需要唯一性时,我只需发出一个简单的请求,例如:

SELECT COUNT(1) FROM stats_unique WHERE stat_group = 'users';

 count
-------
     4

(1 rows)

这绝不是一个标准的解决方案,但它是一些东西 这在我的特殊情况下有效。考虑到我不能 在这个单独的分区中保存超过数百万的东西 但是系统根本不需要支持那么多实体实例 所以对于我的用例来说已经足够好了。此外,使用此 hack,您可能会遇到计数超时等问题。

最好有一些东西来做这个计数,或者单独的进程、脚本,或者甚至像 Ashraful Islam 在他的评论中提到的那样,一个 spark 进程可以为你做计数并将它交给其他人cassandra 或其他存储技术中的表。

我使用的可能是 cassandra 反模式(热排等),但它对我有用。

【讨论】:

  • 但这意味着更改此查询的应用程序代码,这是我不想要的。一个有效的选项可以创建临时方法或表,但不更改我的应用程序,只需查询 db
  • 我完全理解这一点。这再次对我来说很方便。但我想你可以创建一个类似的结构,然后创建一个触发器,将上面的数据插入到temp table,正如你所说的那样。这是关于触发器的有趣答案stackoverflow.com/a/35512606/7413631
猜你喜欢
  • 1970-01-01
  • 2018-01-17
  • 2018-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-25
相关资源
最近更新 更多