8月26日、Googleの研究部門であるGoogle Researchが「SQL Has Problems. We Can Fix Them: Pipe Syntax In SQL」と題した論文を公開した。この記事では、SQLの問題点とそれを解決するために提案された新しいパイプ構文について詳しく紹介されている。
以下に、その内容を紹介する。
SQLの課題
SQLは、データベースクエリ言語として広く普及しているが、設計上の問題が多く指摘されている。特に、SQLは学習や使用が難しく、柔軟性に欠ける点が挙げられる。サブクエリや冗長な構文が必要とされることが多く、これがクエリの可読性やメンテナンス性を低下させている。また、拡張性の低さも問題となっており、新しい操作や機能を追加する際には、多大な労力が必要となることが多い。
パイプ構文の提案
この論文では、これらの問題を解決するために、パイプ構文を提案している。パイプ構文を使用することで、SQLクエリを直感的に記述できるようになり、クエリの可読性が大幅に向上する。パイプ構文では、各操作を順序付けてパイプでつなぐことで、操作の順序を自由に変更できるようになり、柔軟性が高まる。
パイプ構文を使用したクエリの例
基本的なジョインと集計の例
標準SQLでは、次のような複雑なクエリが記述される。
SELECT c_count, COUNT(*) AS custdist FROM ( SELECT c_custkey, COUNT(o_orderkey) AS c_count FROM customer LEFT OUTER JOIN orders ON c_custkey = o_custkey AND o_comment NOT LIKE '%unusual%packages%' GROUP BY c_custkey ) AS c_orders GROUP BY c_count ORDER BY custdist DESC, c_count DESC;
これに対し、パイプ構文を使用すると、以下のようにクエリを簡潔に記述できる。
FROM customer |> LEFT OUTER JOIN orders ON c_custkey = o_custkey AND o_comment NOT LIKE '%unusual%packages%' |> AGGREGATE COUNT(o_orderkey) AS c_count GROUP BY c_custkey |> AGGREGATE COUNT(*) AS custdist GROUP BY c_count |> ORDER BY custdist DESC, c_count DESC;
条件付き集計の例
特定の条件に基づいた集計を行う場合、標準SQLでは次のように書かれる。
SELECT SUM(IF(n_name = 'PERU', bal, NULL)) AS bal_PERU, SUM(IF(n_name = 'KENYA', bal, NULL)) AS bal_KENYA, SUM(IF(n_name = 'JAPAN', bal, NULL)) AS bal_JAPAN FROM ( SELECT n_name, c_acctbal AS bal, c_mktsegment FROM customer JOIN nation ON c_nationkey = n_nationkey ) GROUP BY c_mktsegment;
パイプ構文では、これを次のように簡潔に表現できる。
FROM customer JOIN nation ON c_nationkey = n_nationkey |> SELECT n_name, c_acctbal AS bal, c_mktsegment |> PIVOT(SUM(bal) AS bal FOR n_name IN ('PERU', 'KENYA', 'JAPAN'))
データのフィルタリングと変換の例
特定の条件でデータをフィルタリングし、新しい列を追加する場合の標準SQLクエリは次のようになる。
SELECT o_orderkey, o_orderstatus, ROUND(o_totalprice) AS rounded_price FROM orders WHERE o_totalprice > 1000;
パイプ構文を使うと、このクエリは以下のように表現できる。
FROM orders |> WHERE o_totalprice > 1000 |> EXTEND ROUND(o_totalprice) AS rounded_price |> SELECT o_orderkey, o_orderstatus, rounded_price
ネストされたサブクエリの例
複雑なネストされたサブクエリも、パイプ構文を使用すると整理しやすくなる。以下は、ネストされたクエリをパイプ構文で表現した例である。
標準SQL:
SELECT * FROM ( SELECT c_custkey, COUNT(o_orderkey) AS order_count FROM customer JOIN orders ON c_custkey = o_custkey GROUP BY c_custkey ) AS subquery WHERE order_count > 10;
パイプ構文:
FROM customer |> JOIN orders ON c_custkey = o_custkey |> AGGREGATE COUNT(o_orderkey) AS order_count GROUP BY c_custkey |> WHERE order_count > 10 |> SELECT *
パイプ構文の特徴
- 可読性の向上: クエリの流れが明確になり、読みやすさが向上する。
- 柔軟性の向上: 操作の順序を自由に変更でき、必要に応じて操作を追加することが容易になる。
- 拡張性の向上: 既存のSQL構文に干渉せず、新しい操作や機能を簡単に追加できる。
GoogleSQLでの実装と評価
Googleは、このパイプ構文をGoogleSQLに実装し、内部で広く利用されている。初期の評価では、ユーザーの生産性が向上し、SQLクエリの作成が容易になったことが確認されている。特に、複雑なクエリの記述やデバッグが簡単になり、多くのユーザーから好評を得ている。
結論
この論文は、SQLを置き換えるのではなく、パイプ構文を追加することで、既存の問題を解決し、SQLをより使いやすくするアプローチを提案している。パイプ構文の導入により、SQLの柔軟性と可読性が大幅に向上し、今後のSQLの発展に寄与する可能性があると結論付けている。