2013-09-22 68 views
7

Chúng tôi có cơ sở dữ liệu MySQL nơi chúng tôi đã thêm giá trị chuỗi thời gian.Dữ liệu chuỗi thời gian trong MySQL: Lấy mẫu

------------------------------------- 
|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 | 
------------------------------------- 

Dữ liệu không gian cách nhau một cách không đồng đều, một số điểm được phân tách bằng một phút & một vài giây.

Có cách nào hiệu quả để tôi có thể truy vấn cơ sở dữ liệu này để lấy dữ liệu cho mỗi n phút/giây/giờ không? Lý tưởng nhất là tôi muốn giá trị nội suy (tuyến tính) tại số n phút, nhưng điểm gần nhất với phút n hoặc điểm cuối cùng trước hoặc tại điểm n cũng sẽ làm.

Trường hợp sử dụng là tôi muốn vẽ đồ thị này thành biểu đồ nhưng không muốn quá nhiều điểm hơn mức cần thiết. Vì vậy, để vẽ đồ thị trong một năm, tôi thích chỉ truy vấn một vài điểm mỗi ngày. Trong khi âm mưu cho một ngày, tôi sẽ muốn âm mưu một điểm mỗi phút hoặc lâu hơn.

Tôi có thể làm tất cả điều này trong PHP, nhưng có cách nào để thực hiện trực tiếp trong cơ sở dữ liệu không? Nếu không, tôi đang dự tính việc sử dụng cơ sở dữ liệu chuỗi thời gian, nhưng các ràng buộc ngân sách hạn chế tôi chỉ với những cái miễn phí. Có cơ sở dữ liệu chuỗi thời gian miễn phí nào cho phép lấy mẫu hộp và tốt nhất là nội suy không?

+0

thể trùng lặp của [ Lấy mẫu SQL timeseries] (http://stackoverflow.com/questions/7335627/sampling-sql-timeseries) – Domi

Trả lời

0

Tôi đã có một đâm vào điều này, tôi thực sự quan tâm để xem làm thế nào những người khác sẽ giải quyết nó.

Tôi đã có một vấn đề tương tự như thế này trước đây và giải quyết nó bằng cách tạo bảng chỉ mục thời gian và sau đó gia nhập bảng dữ liệu dựa trên việc ghi lại thời gian để phù hợp với khung thời gian. Vấn đề là bạn cần một bảng chỉ mục thời gian mới và truy vấn hoặc xem riêng biệt cho mỗi khoảng thời gian.

Lợi thế khi kết hợp dữ liệu theo cách này là tôi cũng quan tâm đến các khung thời gian không có đọc hoặc kết quả, vì vậy tôi cần xem các giá trị rỗng hoặc không đọc cho các khung thời gian nhất định. Chỉ cần thêm một chút công việc với dữ liệu kết thúc cho điều đó (ví dụ: đưa ra Placeholders).

Điều đầu tiên tôi đã làm, đã tạo ra một bảng chỉ số thời gian, nó trông giống như thế này ....

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) 

tôi sau đó đoàn dữ liệu của tôi trong

(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 

tôi thử nghiệm này trên các bảng cũ của tôi và nó có vẻ hoạt động tốt, tôi đã phải chỉnh sửa lại mã của tôi để phù hợp với ví dụ của bạn, vì vậy hy vọng tôi đã không sửa đổi nó khi làm điều đó.

+0

Tôi tưởng tượng rằng điều này sẽ rất chậm, trừ khi bạn thêm một chỉ mục toàn văn bản vào cột dấu thời gian của bạn – Domi

-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) 
+1

Chào mừng bạn đến với SO. Bên cạnh mã, xin vui lòng xem xét thêm một lời giải thích trong câu trả lời của bạn. Giải thích OP theo cách nào hữu ích, anh/cô ấy mất tích, hoặc bất cứ điều gì giúp mọi người hiểu tại sao đây là một câu trả lời hữu ích/hữu ích. Xem [Làm cách nào để viết câu trả lời hay?] (Http://stackoverflow.com/help/how-to-answer) – dic19

0

Tôi đã không được sử dụng nó bản thân mình nhưng thời gian gần đây tình cờ gặp InfluxDB rằng âm thanh như nó có thể đáp ứng tiêu chí của bạn - một cơ sở dữ liệu chuỗi thời gian mã nguồn mở với xây dựng trong aggregation queries - ví dụ

SELECT MEAN(column_name) FROM series_name group by time(10m) 
Các vấn đề liên quan