精讀《SQL vs Flux》

1 引言

對時序數據的處理有兩種方式,如圖所示,右邊是 SQL,左邊是自定義查詢語言,也稱爲 NoSQL,處於中間地帶的稱爲 SQL-LIKE 語言。git

本文經過對比 SQL 陣營的 TimescaleDB 與 NoSQL 陣營的 InfluxDB,試圖給出一些對比。github

2 概述

TimescaleDB

TimescaleDB 徹底接受了 SQL 語法,所以幾乎沒有什麼學習門檻,更經過可視化操做優化了使用方式。sql

InfluxDB

InfluxDB 創造了一種新的查詢語言,這裏是 Flux 文法.(瞭解更多文法相關知識,能夠移步 精讀《手寫 SQL 編譯器 - 文法介紹》typescript

InfluxDB 爲何創造 Flux 語法

InfluxDB 之因此創造 Flux 語法,而不使用 SQL,主要有兩個緣由:數據庫

  1. 更強的查詢功能:SQL 沒法輕鬆完成時序查詢。
  2. 時間序列的查詢須要基於流的函數模型,而不是 SQL 的代數模型。

所謂流模型,就相似 JS 函數式編程中相似概念:編程

source.pipe(
  map(x => x + x),
  mergeMap(...),
  filter(...)
)
複製代碼

更強的查詢功能?

InfluxDB 拿下面例子舉例:編程語言

Flux:函數式編程

from(db:"telegraf")
  |> range(start:-1h)
  |> filter(fn: (r) => r._measurement == "foo")
  |> exponentialMovingAverage(size:-10s)
複製代碼

SQL:函數

select id,
       temp,
       avg(temp) over (partition by group_nr order by time_read) as rolling_avg
from (
  select id,
         temp,
         time_read,
         interval_group,
         id - row_number() over (partition by interval_group order by time_read) as group_nr
  from (
     select id,
            time_read,
            'epoch'::timestamp + '900 seconds'::interval * (extract(epoch from time_read)::int4 / 900) as interval_group,
            temp
     from readings
  ) t1
) t2
order by time_read;
複製代碼

雖然看上去 SQL 寫法比 Flux 長了很多,但其實 Flux 代碼的核心在於實現了自定義函數 exponentialMovingAverage,而 PostgreSQL 也有 建立函數 的能力。post

經過 SQL 定義一個自定義函數:

CREATE OR REPLACE FUNCTION exponential_moving_average_sfunc
(state numeric, next_value numeric, alpha numeric)
RETURNS numeric LANGUAGE SQL AS
$$
SELECT
         CASE
                WHEN state IS NULL THEN next_value
                ELSE alpha * next_value + (1-alpha) * state
         END
$$;
CREATE AGGREGATE exponential_moving_average(numeric, numeric)
(sfunc = exponential_moving_average_sfunc, stype = numeric);
複製代碼

以後能夠像 Flux 函數同樣的調用:

SELECT time,
       exponential_moving_average(value, 0.5) OVER (ORDER BY time)
FROM telegraph
WHERE measurement = 'foo' and time > now() - '1 hour';
複製代碼

可見從函數定義上也和 Flux 打成平手,做者認爲既然功能相同,而基於 SQL 的語言學習成本更低,因此不須要創造一個新的語言。

關於語法糖與 SQL 標準

做者認爲,雖然有觀點認爲,Flux 的語法糖比 SQL 更簡潔,但代碼的可維護性並非行數越少越好,而是是否容易被人類理解。

對於創造一個函數標準可能破壞 SQL 的可移植性,做者認爲那也比徹底創造一個新語法要強。

基於流的函數模型強於 SQL 代數模型?

誠然,從功能角度來看,固然函數模型強於代數模型,由於代數模型只是在描述事物,而不能精準控制執行的每一步。

但咱們要弄清楚 SQL 的場景,是經過描述一個無順序的查詢問題,讓數據庫給出結果。而在查詢過程當中,數據庫能夠對 SQL 語句做出一些優化。

反觀函數模型,是在用業務代碼描述查詢請求,這種代碼是沒法被自動優化的,雖然爲用戶提供了更底層的控制,但其代價是沒法被數據庫執行引擎所優化。

若是你更看中查詢語言,而不是具體執行邏輯,SQLl 依然是最好的選擇。

3 總結

之因此製做這一期精讀,是爲了探索 SQL 與其餘查詢語言的關係,去理解爲何 SQL 沿用至今。

SQL 與其餘函數類查詢語言不在一個層面上,若是用語法糖、可操縱性抨擊 SQL,只能得出看似正確,實則荒謬的結論。

SQL 是一個查詢語言,與普通編程語言相比,它還在上層,最終會轉化爲關係代數執行,但關係代數會遵循一些等價的轉換規律,好比交換律、結合律、過濾條件拆分等等,經過預估每一步的時間開銷,將 SQL 執行順序從新組合,能夠提升執行效率。

若是有多個 SQL 同時執行,還能夠整合成一個或多個新的 SQL,合併重複的查詢請求。

在數據驅動商業的今天,SQL 依然是數據查詢最通用的解決方案。

4 更多討論

討論地址是:精讀《SQL vs Flux》 · Issue #96 · dt-fe/weekly

若是你想參與討論,請點擊這裏,每週都有新的主題,週末或週一發佈。

相關文章
相關標籤/搜索