2016-11-30 347 views
1

我有以下表来存储时间序列数据:卡桑德拉datamodelling

CREATE TABLE alerts_by_year_day (
    day_of_year int, 
    year int, 
    alert_timestamp timestamp, 
    serial_number text, 
    alert_id uuid, 
    alert_type text, 
    .... 
    .... 
    PRIMARY KEY((year, day_of_year), alert_timestamp, serial_number, alert_id) 
) WITH CLUSTERING ORDER BY (alert_timestamp DESC, serial_number DESC); 
  1. 对于UI报告我要检索的给定时间内的所有警报。我有这样的查询:

SELECT * FROM alerts_by_year_day其中year = 2015和DAY_OF_YEAR在(241,240);

但是,此查询返回的结果是年度ASC顺序,然后是ASC顺序的一天。 所以这样的结果

2015 | 240 | .....

2015 | 241 | .....

但我想要先显示最新结果或按降序显示。通过alert_timestamp添加'order'给出了一个错误 那么我如何显示结果降序?

  1. 然后,对于给定的时间段,我只想根据alert_type检索特定类型的警报。

所以我创造了这样的垫子观点:

CREATE MATERIALIZED VIEW alerts_by_type_and_timestamp AS 
    SELECT * 
    FROM alerts_by_year_day 
    WHERE alert_timestamp IS NOT NULL AND 
     alert_type IS NOT NULL AND 
     day_of_year IS NOT NULL AND 
     year IS NOT NULL AND serial_number IS NOT NULL AND 
     alert_id IS NOT NULL 
    PRIMARY KEY ((year, day_of_year, alert_type), alert_timestamp, serial_number, alert_id) 
    WITH CLUSTERING ORDER BY (alert_timestamp DESC, serial_number DESC, alert_id DESC); 

但是,当然,它返回结果按类型第一,并通过时间戳。 我正在寻找的仅仅是类型的一个子集,并且按照它们的生成顺序排列。 Cassandra可能吗?

由于

回答

1

分区的顺序是在令牌顺序。它是主键的murmur3散列的顺序。即:

cqlsh:test> select * from alerts_by_year_day ; 

year | day_of_year | alert_timestamp     | serial_number | alert_id        | alert_type 
------+-------------+---------------------------------+---------------+--------------------------------------+------------ 
2015 |   10 | 1970-01-01 00:00:00.001000+0000 |   s123 | b7baa710-b87b-11e6-9137-eb2177fd2cc2 |  type 
2015 |   110 | 1970-01-01 00:00:00.001000+0000 |   s123 | bf110270-b87b-11e6-9137-eb2177fd2cc2 |  type 
2015 |   11 | 1970-01-01 00:00:00.001000+0000 |   s123 | bce08de1-b87b-11e6-9137-eb2177fd2cc2 |  type 
2016 |   110 | 1970-01-01 00:00:00.001000+0000 |   s123 | c2e22eb1-b87b-11e6-9137-eb2177fd2cc2 |  type 

,因为你的查询它,它走他们的顺序(你无法控制)。在掩护下必须为每个主键组合进行单独的查询。

这需要in子句中每个值的多次提取,并且如果您投入太多,可能会变得效率低下,因为它会给协调器带来很大的负担。它的成本几乎相同,只是使两个异步select查询。然后你可以按你想要的顺序阅读。这还可以让您避免让集群中的单个协调器管理提取到许多节点,最终这可以帮助提高集群运行状况。每天1个查询在您的应用程序中遍历并不差。

如果日子不是“每天”,可能需要考虑第二张表,这就是您在执行插入操作之前写入的(year, day_of_year)(type, year, day_of_year),然后才能进行查询。

注:可保留在内存中缓存地方,所以你不要有成千上万的不必要的写入,可以编写只有一次,但它是确定编写应用程序的多次柜面多个实例或重新启动

year = 2015 
days = query('select * from alert_day_index where year = %s', year) 
results = [] 
for day in days: 
    results.extend(query('select * from alerts_by_year_day where year = %s and day_of_year = %s', year, day)) 

如果你有很多天只需要查询异步,所以查询的延迟不会阻止应用程序的吞吐量。

+0

感谢您的回应!每天运行查询并存储所显示日期的分页详细信息非常麻烦。 – user1860447