Microsoft Fabric を触り始めると、次の疑問に必ずぶつかります。
「なぜ言語が分かれているのか?」
「全部 SQL ではダメなのか?」
この記事では、
- SQL / T-SQL / KQL の違い
- なぜ Fabric は KQL を採用しているのか
を整理します。
参照:
全体像:3つの言語の役割
まず全体として、このような違いがあります。
| 項目 | SQL | T-SQL | KQL |
|---|---|---|---|
| 言語の種類 | 標準SQL | Microsoft拡張SQL | 分析専用言語(Kusto) |
| 主な用途 | RDBMSデータ操作 | SQL + 制御構文 | ログ・時系列・ストリーミング分析 |
| 文法スタイル |
SELECT中心 |
SQL + 拡張構文 | パイプライン式 |
| 実行順序 | 論理実行順 | SQLと同様 | 上から順に実行 |
| 並び替え既定 | ASC |
ASC |
DESC |
JOIN |
一般的 |
APPLYなど高機能 |
KQL独自JOIN
|
| フィルタ | WHERE |
WHERE |
where |
| 集計 | GROUP BY |
GROUP BY + 拡張 |
summarize |
| 変数 | 不可 | 可能 | 不可 |
| ストアド | 不可 | 可能 | 不可 |
| Fabricでの利用 | Warehouse / Lakehouse | Warehouse / Lakehouse | KQL DB / Eventstream / RTA |
違い
SQL : データベースに「問い合わせる」ための言語
まずは基本ですが、SQL は「リレーショナルデータベースを操作するための標準言語」です。
- 正規化された構造化データ
- 安定したスキーマ
- 帳票・集計・業務ロジック
といった業務データ向けに最適化されています。
SQL は「どう処理するか」ではなく、「何を取得したいか」を宣言する言語です。
Fabric では、Warehouse や Lakehouse の SQL エンドポイントで使われます。
T-SQL:SQLを「処理言語」に拡張したもの
T-SQL は SQL Server 系で使われる Microsoft 独自拡張です。
- 変数
-
IF/WHILE - ストアドプロシージャ
TRY-CATCHCROSS APPLY
などが追加され、SQL を処理として書けるようになっています。
Fabric の SQL 体験は、この T-SQL 的思想を色濃く引き継いでいます。
KQL:データを「流して分析する」ための言語
KQL(Kusto Query Language)は、SQL とは思想がまったく違います。
最大の特徴は パイプライン型 であることです。
Events
| where Timestamp >= ago(1h)
| extend Hour = format_datetime(Timestamp, 'HH')
| summarize count() by Hour
| order by Hour
- 上から下へ
- データを流しながら
- 少しずつ形を変えていく
KQL は 最初から分析専用として作られた言語です。
なぜ Microsoft Fabric は KQL を採用しているのか
結論から言うと、「Fabric が扱おうとしているデータの性質が、SQL だけでは足りなくなった」 からです。Fabric が本気で扱うデータの特徴としてある、
- ログ
- イベントデータ
- 操作履歴
- 時系列データ
- ストリーミングデータ
- 準構造・半構造データ
これらは、
- データ量が膨大
- 追記型(Append-only)
- スキーマが流動的
- 「あとから意味を見つける」分析が中心
という特徴を持っています。
SQL は「静的な業務データ」に最適化されている
SQL は、
- 正規化
- 安定したスキーマ
- CRUD 前提
という世界観で作られています。
ログやイベント分析では、
- 一時的な計算列を大量に作る
- 切り口を高速に変える
- 途中結果を見ながら試行錯誤する
こうした作業が中心になります。
SQL でも可能ですが、
CTE やサブクエリが増え、クエリは重くなりがちです。
KQL は「分析前提」で設計されている
KQL では、
- extend で列を作る
- summarize で集計する
- project で整理する
という流れが自然です。
これは、
- ログ可視化
- 運用監視
- 行動分析
- セキュリティ分析
と非常に相性が良い。
Fabric の Real-Time Analytics は、
この KQL の処理モデルを前提に作られています。
サンプルコード
お題
- 直近1時間の売上データを対象に
- 時間帯ごとの売上合計を集計し
- 売上が多い順に並べる
SQL(Warehouse / Lakehouse)
SELECT
FORMAT(SaleDate, 'HH') AS Hour,
SUM(SaleAmount) AS TotalSales
FROM Sales
WHERE SaleDate >= DATEADD(hour, -1, GETDATE())
GROUP BY FORMAT(SaleDate, 'HH')
ORDER BY TotalSales DESC;
- 最終形を一気に定義
- ロジックが
SELECT/GROUP BYに集約される - 宣言的
T-SQL(変数を使う例)
DECLARE @FromTime DATETIME;
SET @FromTime = DATEADD(hour, -1, GETDATE());
SELECT
FORMAT(SaleDate, 'HH') AS Hour,
SUM(SaleAmount) AS TotalSales
FROM Sales
WHERE SaleDate >= @FromTime
GROUP BY FORMAT(SaleDate, 'HH')
ORDER BY TotalSales DESC;
- 処理として段階化できる
- バッチ・ストアド向き
KQL(Real-Time Analytics)
Sales
| where SaleDate >= ago(1h)
| extend Hour = format_datetime(SaleDate, 'HH')
| summarize TotalSales = sum(SaleAmount) by Hour
| order by TotalSales desc
- 上から順に処理
- データを流しながら変形
- 中間結果が直感的に読める
KQLは見た目も大きく違うことがわかります。
JOIN を含めた例でも思想が違う
SQL
SELECT
c.CustomerName,
SUM(s.SaleAmount) AS TotalSales
FROM Sales s
JOIN Customers c
ON s.CustomerID = c.CustomerID
WHERE s.SaleDate >= DATEADD(day, -1, GETDATE())
GROUP BY c.CustomerName
ORDER BY TotalSales DESC;
KQL
Sales
| where SaleDate >= ago(1d)
| join Customers on CustomerID
| summarize TotalSales = sum(SaleAmount) by CustomerName
| order by TotalSales desc
KQL では、処理の順序=クエリの見た目です。
Fabric は「両立」を選んでいる
SQL / T-SQL / KQL は単なる文法違いではなく、それぞれが異なる前提・異なるデータの性質を扱うために設計された言語です。
Fabric は、この違いを無理に統一しようとはしていません。
-
業務・構造化データ
→ SQL / T-SQL
→ 正規化されたデータ、安定したスキーマ、帳票・業務集計 -
ログ・イベント・リアルタイムデータ
→ KQL
→ 大量・追記型・流動的スキーマ、探索的・反復的な分析
上記のような役割分担を前提にプラットフォームが設計されています。
重要なのは、KQL は SQL を置き換えるための言語ではない という点です。
SQL はこれからも、
- 業務システム
- DWH
- BI・帳票
の中核であり続けます。
一方で、ログやイベントのような「流れるデータ」に対しては、
- 最終形が最初から決まっていない
- 途中で列を作り、壊し、試しながら分析する
- 処理の流れそのものを把握したい
というニーズが強く、ここは SQL の得意領域ではありません。
KQL は、この SQL が苦手としてきた領域を正面から扱うための言語です。
Microsoft Fabric が KQL を採用した理由を一言でまとめると、「現代のデータ分析は、SQL だけでは表現しきれなくなった」 という現実に向き合った結果だと言えます。
- データの種類が増え、
- リアルタイム性が求められ、
- 探索的な分析が当たり前になった
その中で、分析の流れをそのまま書ける言語が必要になったのが KQL です。
SQL / T-SQL / KQL の違いと思想を理解すると、
Fabric の構成やサービスの分かれ方も、かなり自然に見えてくるはずです。