MySQL中的时间序列数据:采样

时间:2013-09-22 07:31:22

标签: mysql time-series

我们有一个MySQL数据库,我们在其中添加了时间序列值。

-------------------------------------
|Col A | Col B | Timestamp          |
-------------------------------------
|1.23  | 4.48  |2013-09-03 10:45:27 |
-------------------------------------
|1.23  | 4.48  |2013-09-03 10:46:27 |
-------------------------------------
|1.23  | 4.48  |2013-09-03 10:47:27 |
-------------------------------------

数据在时间上间隔不均匀,有些点间隔一分钟和一分钟。一些几秒钟。

我是否有一种有效的方法可以查询此数据库,以便每n分钟/秒/小时提取数据?理想情况下,我希望n分钟处的(线性)插值,但最接近n分钟或最后一点或n点之前的最近点将是也是。

用例是我想将其绘制成图形,但不要求太多的点。因此,对于一年的情节,我宁愿每天只查询几个点。在绘制一天的时候,我想每分钟左右绘制一个点。

我可以用PHP完成所有这些,但有没有办法在数据库中直接进行?如果没有,我正在考虑使用时间序列数据库,但预算约束限制我只使用免费的数据库。是否有任何自由时间序列数据库提供开箱即用的采样,最好是插值?

3 个答案:

答案 0 :(得分:1)

我对此有所了解,我真的很想知道其他人如何解决它。

之前我遇到过类似的问题并通过创建时间索引表然后根据重写时间来加入数据表来解决它以适应时间范围。问题是您需要一个新的时间索引表和每个时间间隔的单独查询或视图。

以这种方式加入数据的好处是我也对没有读数或结果的时间框架感兴趣,所以我需要查看某些时间帧的空值或没有读数。最终数据需要额外的工作(即:取出占位符)。

我做的第一件事是创建一个时间索引表,它看起来像这样....

mysql> select * from ctb_time_idx  WHERE YEAR( ctb_datetime ) = 2013  LIMIT 10 ;
+---------------------+
| ctb_datetime        |
+---------------------+
| 2013-01-01 00:00:00 | 
| 2013-01-01 00:15:00 | 
| 2013-01-01 00:30:00 | 
| 2013-01-01 00:45:00 | 
| 2013-01-01 01:00:00 | 
| 2013-01-01 01:15:00 | 
| 2013-01-01 01:30:00 | 
| 2013-01-01 01:45:00 | 
| 2013-01-01 02:00:00 | 
| 2013-01-01 02:15:00 | 
+---------------------+
10 rows in set (0.07 sec)

然后我将数据合并到

( select 
    ctb_datetime AS time1 , 
    'Placeholder' AS TimeInterval , 
    NULL AS `Col A` , 
    NULL AS `Col B` 
from my_time_idx 
    where YEAR ( ctb_time_idx.ctb_datetime  ) = 2013 )  
UNION 
( select DATE_FORMAT( time1 , '%Y-%m-%d %H:00' ) AS time1  , 
    '00min' AS TimeInterval , `Col A` , `Col B` from my_data_table  
    where MINUTE( time1 ) BETWEEN  00 AND 14  ) 
UNION 
( select DATE_FORMAT( time1 , '%Y-%m-%d %H:15' ) AS time1 , 
    '15min' AS TimeInterval, `Col A` , `Col B` from my_data_table 
    where MINUTE( time1 ) BETWEEN  15 AND 29  ) 
UNION 
( select DATE_FORMAT( time1 , '%Y-%m-%d %H:30' ) AS time1 , 
    '30min' AS TimeInterval, `Col A` , `Col B` from my_data_table 
    where MINUTE( time1 ) BETWEEN  30 AND 44  ) 
UNION 
( select DATE_FORMAT( time1 , '%Y-%m-%d %H:45' ) AS time1 , 
    '45min' AS TimeInterval, `Col A` , `Col B` from my_data_table 
    where MINUTE( time1 ) BETWEEN  45 AND 59  )     
order by time1 

我在旧桌子上测试了它,它看起来工作正常,我不得不重新编辑我的代码以适合你的例子,所以希望我这样做时不会搞砸。

答案 1 :(得分:1)

我自己没有使用它,但最近遇到了InfluxDB听起来符合您的标准 - 内置aggregation queries的开源时间序列数据库 - 示例

SELECT MEAN(column_name) FROM series_name group by time(10m)

答案 2 :(得分:-1)

select unix_timestamp(now());
select from_unixtime(unix_timestamp(now()));
select from_unixtime(unix_timestamp(now())-unix_timestamp(now())%300);
select from_unixtime(unix_timestamp(now())-unix_timestamp(now())%900);
select from_unixtime(unix_timestamp(now())-unix_timestamp(now())%1800);

+-----------------------+
| unix_timestamp(now()) |
+-----------------------+
|            1383077951 |
+-----------------------+
1 row in set (0.00 sec)

+--------------------------------------+
| from_unixtime(unix_timestamp(now())) |
+--------------------------------------+
| 2013-10-29 20:19:11                  |
+--------------------------------------+
1 row in set (0.00 sec)

+----------------------------------------------------------------+
| from_unixtime(unix_timestamp(now())-unix_timestamp(now())%300) |
+----------------------------------------------------------------+
| 2013-10-29 20:15:00                                            |
+----------------------------------------------------------------+
1 row in set (0.00 sec)

+----------------------------------------------------------------+
| from_unixtime(unix_timestamp(now())-unix_timestamp(now())%900) |
+----------------------------------------------------------------+
| 2013-10-29 20:15:00                                            |
+----------------------------------------------------------------+
1 row in set (0.00 sec)

+-----------------------------------------------------------------+
| from_unixtime(unix_timestamp(now())-unix_timestamp(now())%1800) |
+-----------------------------------------------------------------+
| 2013-10-29 20:00:00                                             |
+-----------------------------------------------------------------+
1 row in set (0.00 sec)