在Cassandra中使用MAX()、DISTINCT和groupby



我正在尝试重新构建SQL数据库Cassandra,这样,我就可以为SQL查询找到Cassandra等效数据库。我使用CQL3和Cassandra v1.2。我在cassandra中对数据库设计进行了建模,以便它支持order by子句和非规范化表来支持联接操作。然而,当涉及到DISTINCT、SUM()和GROUPBY等价物时,我不知所措

SELECT a1,MAX(b1) FROM demo1 group by a1.
SELECT DISTINCT (a2) FROM demo2 where b2='sea'
SELECT sum(a3), sum(b3) from demo3 where c3='water' and d3='ocean'

这就像是我过去几天工作的一个亮点。在Cassandra中,有没有一种方法可以为数据库模式建模以支持此类查询?我在卡桑德拉身上想不出任何办法。如何使用Cassandra实现此类查询?

我读到Cassandra上的蜂窝层可能会使这些查询工作。我只是想知道这是否是Cassandra中支持此类查询的唯一方法。。?请告知其他可能的方法。。

使用Cassandra,当您插入数据时,您可以通过做更多的工作来解决这些问题——这听起来很慢,但Cassandra是为快速写入而设计的,您可能会读取数据的次数比写入数据的次数多得多,因此当您考虑整个系统时,这是有意义的。

我不能确切地告诉你如何创建表来为你的问题建模,因为这在很大程度上取决于细节。您需要制定一个模式,使您能够在不执行任何动态聚合的情况下获取数据。想想如何在RDBMS中为查询创建视图,然后试着想想如何将数据直接插入到这些视图中,而不是插入到底层表中。这就是你在《卡桑德拉》中塑造事物的方式。

尽管这是一个老问题,但它在谷歌搜索结果中的出现率相当高。所以我想更新一下。

Cassandra 2.2+支持用户定义的函数和用户定义的聚合警告:这并不意味着你不必再进行数据建模(正如@Theo所指出的那样),它只是允许你在检索时对数据进行轻微的预处理。

从demo2选择差异(a2),其中b2="ea"

要实现DISTINCT,您应该定义一个函数和agreggate。我将调用函数和聚合uniq而不是distinct,以强调它是用户定义的。

CREATE OR REPLACE FUNCTION uniq(state set<text>, val text)
  CALLED ON NULL INPUT RETURNS set<text> LANGUAGE java
  AS 'state.add(val); return state;';
CREATE OR REPLACE AGGREGATE uniq(text)
  SFUNC uniq STYPE set<text> INITCOND {};

然后按如下方式使用:

SELECT uniq(a2) FROM demo2 where b2='sea';

从demo3中选择sum(a3),sum(b3),其中c3="水",d3="海洋"

SUM是开箱即用的,可以按照您的期望工作。参见system.sum

通过a1 从demo1组选择a1,MAX(b1)

GROUP BY是一个棘手的问题。实际上,没有办法按某一列对结果行进行分组。但是,您可以创建一个map<text, int>,并在地图中手动对它们进行分组。根据Christopher Batey博客中的一个例子,分组方式和最大值:

CREATE OR REPLACE FUNCTION state_group_and_max(state map<text, int>, type text, amount int)
  CALLED ON NULL INPUT
  RETURNS map<text, int>
  LANGUAGE java AS '
    Integer val = (Integer) state.get(type);
    if (val == null) val = amount; else val = Math.max(val, amount);
    state.put(type, val);
    return state;
  ' ;
CREATE OR REPLACE AGGREGATE state_group_and_max(text, int) 
  SFUNC state_group_and_max
  STYPE map<text, int> 
  INITCOND {};

然后按如下方式使用:

SELECT state_group_and_max(a1, b1) FROM demo1;

备注

  • 正如上面提到的,您仍然需要在数据建模上投入一些时间,不要过度使用这些功能
  • 您必须在cassandra.yaml中设置enable_user_defined_functions=true才能启用这些功能
  • 您可以重载函数以支持按不同类型的列进行分组

参考文献:

  • Christopher Batey的伟大UDF和UDA示例
  • UDF和UDA的数据税文档
  • Cassandra 3.0中的用户定义函数(Planet Cassandra博客)

Cassandra 3.10现在支持分组键和集群键分组。您可以参考此链接了解更多详细信息。

Cassandra不支持这样的操作。你可以在上面使用Hive之类的东西,或者Acunu的(非免费)产品可以满足你的需求。

另一个解决方案是自己做这项工作。例如,您可以通过读取某些行中的所有数据并求和来求和。或者保持一个卡桑德拉计数器在飞行中递增。

相关内容

  • 没有找到相关文章

最新更新