對時序數據的處理有兩種方式,如圖所示,右邊是 SQL,左邊是自定義查詢語言,也稱爲 NoSQL,處於中間地帶的稱爲 SQL-LIKE 語言。git
本文經過對比 SQL 陣營的 TimescaleDB 與 NoSQL 陣營的 InfluxDB,試圖給出一些對比。github
TimescaleDB 徹底接受了 SQL 語法,所以幾乎沒有什麼學習門檻,更經過可視化操做優化了使用方式。sql
InfluxDB 創造了一種新的查詢語言,這裏是 Flux 文法.(瞭解更多文法相關知識,能夠移步 精讀《手寫 SQL 編譯器 - 文法介紹》)typescript
InfluxDB 之因此創造 Flux 語法,而不使用 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 的語言學習成本更低,因此不須要創造一個新的語言。
做者認爲,雖然有觀點認爲,Flux 的語法糖比 SQL 更簡潔,但代碼的可維護性並非行數越少越好,而是是否容易被人類理解。
對於創造一個函數標準可能破壞 SQL 的可移植性,做者認爲那也比徹底創造一個新語法要強。
誠然,從功能角度來看,固然函數模型強於代數模型,由於代數模型只是在描述事物,而不能精準控制執行的每一步。
但咱們要弄清楚 SQL 的場景,是經過描述一個無順序的查詢問題,讓數據庫給出結果。而在查詢過程當中,數據庫能夠對 SQL 語句做出一些優化。
反觀函數模型,是在用業務代碼描述查詢請求,這種代碼是沒法被自動優化的,雖然爲用戶提供了更底層的控制,但其代價是沒法被數據庫執行引擎所優化。
若是你更看中查詢語言,而不是具體執行邏輯,SQLl 依然是最好的選擇。
之因此製做這一期精讀,是爲了探索 SQL 與其餘查詢語言的關係,去理解爲何 SQL 沿用至今。
SQL 與其餘函數類查詢語言不在一個層面上,若是用語法糖、可操縱性抨擊 SQL,只能得出看似正確,實則荒謬的結論。
SQL 是一個查詢語言,與普通編程語言相比,它還在上層,最終會轉化爲關係代數執行,但關係代數會遵循一些等價的轉換規律,好比交換律、結合律、過濾條件拆分等等,經過預估每一步的時間開銷,將 SQL 執行順序從新組合,能夠提升執行效率。
若是有多個 SQL 同時執行,還能夠整合成一個或多個新的 SQL,合併重複的查詢請求。
在數據驅動商業的今天,SQL 依然是數據查詢最通用的解決方案。
若是你想參與討論,請點擊這裏,每週都有新的主題,週末或週一發佈。