2012-09-14 11 views
0

我有pmacct每小時彙總網絡流量到postgres數據庫。 我需要編寫一個腳本/查詢將這些數據以不同的格式移動到mysql數據庫中。我希望儘可能多地使用SQL進行數據處理,因爲此數據集將快速增長。Postgres彙總網絡流量數據並加入

我有一個Perl腳本運行添加其他字段(AGENT_ID)來跟蹤數據是在區(當地/國家/國際),這將顯示爲爲0,1,或2

從我從拉出來該數據表的架構的相關領域是:

ip_src, ip_dst, agent_id, bytes, stamp_updated, processed

的模式我想將數據插入到的是:

ip, local_down_mb, nat_down_mb, int_down_mb, local_up_mb, nat_up_mb, int_up_mb, timestamp

因爲我只是在尋找源或目標是我的範圍之一的流量,我目前有一個查詢,它可以以我想要的方式從postgres數據庫中獲取上傳數據:

SELECT DISTINCT ip_src, agent_id, SUM(bytes), stamp_updated FROM acct 
WHERE ip_src <<= '192.168.0.0/22' 
    OR ip_src <<= '10.1.2.0/24' 
    OR ip_src <<= '1.2.3.4/32' 
GROUP BY ip_src, agent_id, stamp_updated 
ORDER BY ip_src, agent_id, stamp_updated 

該查詢的示例輸出是:

ip_src  | agent_id | sum | stamp_updated  
--------------+----------+-----------+--------------------- 
10.1.2.134 |  2 |  3192 | 2012-09-13 21:20:01 
10.1.2.134 |  2 |  3192 | 2012-09-13 22:20:01 
10.1.2.134 |  2 |  3192 | 2012-09-13 23:20:01 
10.2.3.252 |  2 |  448 | 2012-09-11 06:00:01 
10.2.3.252 |  2 |  448 | 2012-09-11 07:20:01 
10.2.3.252 |  2 |  448 | 2012-09-11 08:20:01 
10.2.3.252 |  2 |  8112 | 2012-09-11 09:20:01 

在這個階段,我知道我可以運行ip_dst相同的查詢,並在隨後的位的手動過程的重新插入數據到MySQL時以新格式確保IP源和目標匹配一個時間戳,然後使用t他與agent_id的組合,以及它是我插入的IP源還是IP目的地,以確定它是入站還是出站,以及流量是本地,國內還是國際。

但是,我想要的是一個查詢,將爲我做這一切。我的SQL知識的限制在幾個月前已經通過了W3C網站教程,這讓我可以在上面寫出一個查詢,但沒有更多。

從我所知道的,我需要幫助的是在兩組結果之間寫一個連接,一個針對ip_src,另一個針對ip_dst,然後用一些魔法來使用交通流向的信息結合agent_id來獲得一個匹配mysql數據庫模式的輸出。

是否有人可以(非常好心地)寫出他們認爲可能用於完成此項工作的查詢,或者至少將我指向相關文檔,並讓我領先一步,瞭解可能需要使用哪些函數來完成此操作工作?

回答

3
  • 爲了解決您如何將ip_src粘到ip_dst搜索首要關注的問題,你想使用FULL OUTER JOIN在兩個查詢你已經有了處理,其中一個IP只有在一個交通情況給定時間戳的方向。如果你的數據加載器可以保證匹配的數據,你可以逃脫INNER JOIN,但爲什麼冒險呢?
  • 由於您要將agent_id轉換爲目標模式中的3個獨立列,因此我在聚合函數內顯示了一種使用條件的方法。
  • 我根據列名作出了關於轉換字節數的假設,以在最終輸出中舍入兆字節。

    SELECT down.ip, 
         ceil(down.lb/1048576) AS local_down_mb, 
         ceil(down.nb/1048576) AS nat_down_mb, 
         ceil(down.ib/1048576) AS int_down_mb, 
         ceil(up.lb/1048576) AS local_up_mb, 
         ceil(up.nb/1048576) AS nat_up_mb, 
         ceil(up.ib/1048576) AS int_up_mb, 
         down.timestamp 
        FROM (SELECT ip_src AS ip, 
           SUM(CASE WHEN agent_id=0 THEN bytes ELSE 0 END) AS lb, 
           SUM(CASE WHEN agent_id=1 THEN bytes ELSE 0 END) AS nb, 
           SUM(CASE WHEN agent_id=2 THEN bytes ELSE 0 END) AS ib, 
           stamp_updated AS timestamp 
          FROM acct 
          WHERE ip_src <<= '192.168.0.0/22' 
           OR ip_src <<= '10.1.2.0/24' 
           OR ip_src <<= '1.2.3.4/32' 
         GROUP BY ip,timestamp) down 
        FULL OUTER JOIN 
         (SELECT ip_dst AS ip, 
           SUM(CASE WHEN agent_id=0 THEN bytes ELSE 0 END) AS lb, 
           SUM(CASE WHEN agent_id=1 THEN bytes ELSE 0 END) AS nb, 
           SUM(CASE WHEN agent_id=2 THEN bytes ELSE 0 END) AS ib, 
           stamp_updated AS timestamp 
          FROM acct 
          WHERE ip_dst <<= '192.168.0.0/22' 
           OR ip_dst <<= '10.1.2.0/24' 
           OR ip_dst <<= '1.2.3.4/32' 
         GROUP BY ip,timestamp) up 
        USING (ip,timestamp) 
    ORDER BY ip,timestamp;