8

我们有一个 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第 th 分钟获得(线性)插值,但最接近n第 th 分钟或在第 th 点之前或之前的最后一个点n也可以。

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

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

4

3 回答 3

2

我自己没有使用过它,但最近遇到了InfluxDB,听起来它可以满足您的标准 - 一个带有内置聚合查询的开源时间序列数据库- 示例

SELECT MEAN(column_name) FROM series_name group by time(10m)
于 2015-05-31T07:58:39.920 回答
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 

我在我的旧表上测试了它,它似乎工作正常,我不得不重新编辑我的代码以适应你的例子,所以希望我这样做时没有搞砸。

于 2013-09-22T10:56:41.433 回答
0
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)
于 2013-10-29T20:21:01.027 回答