モダンなリレーショナルクエリ言語に求めたい機能リスト
Things I want in a modern relational query language
Things I want in a modern relational query language
現在のリレーショナルクエリ言語(SQLなど)は、長年使われているものの、現代のアプリケーション開発のニーズに対して、さらに進化した設計が必要だと感じています。私が考える、これからのクエリ言語に備わっていてほしい機能は以下の通りです。
メタなコメントだけど、シンタックスハイライトなしのコードブロックや、折り返されるコードブロックならまだ扱える。でも、この両方が長いコメントと一緒にくると、ただのノイズになっちゃうね。どこをどう読めばいいのか視覚的なヒントがまったくないし。スマホだと、コードブロックの意味を理解するのは完全に不可能だよ。
SQLがなぜダメなのかっていう僕のお気に入りのエッセイと内容が重なる部分があるね。
https://www.scattered-thoughts.net/writing/against-sql (https://www.scattered-thoughts.net/writing/against-sql)
その記事はやりたいことリストで終わってるから、今回の投稿と一番似てるかもしれない。他にも面白い記事がサイト内にあるから(ホームアイコンをクリックして "SQL" で検索してみて)。
個人的な見解だけど、データベースの複雑さという根本的な問題がある以上、SQLを置き換えるのはあまりにも巨大なタスクだから、今後もSQLが君臨し続けるだろうね。LLMの登場でさらに状況は悪化してる、だってLLMは散文をSQLに翻訳するのが得意だから。SQLがプログラマーにとってどれだけイライラするものかなんて重要じゃなくなってきた今、SQLはだんだんアセンブリ言語みたいになっていくと思う。つまり、人間が直接いじるには複雑すぎるから、コンピュータが書くものになっていくってこと。これって、SQLがもともと散文のように読みやすく、人間にとって扱いやすく設計されていたことを考えると、皮肉な話だよね。
https://www.geldata.com/blog/we-can-do-better-than-sql (https://www.geldata.com/blog/we-can-do-better-than-sql)
(https://news.ycombinator.com/item?id=24106608 (https://news.ycombinator.com/item?id=24106608), https://news.ycombinator.com/item?id=19871051 (https://news.ycombinator.com/item?id=19871051))
代替クエリ言語の問題点は、クエリ作成やビジネスの背後にあるリレーショナルドメインを一番よく理解している人たちが、みんなSQLのエキスパートだってこと。だから、別の言語を導入するってことは、一番のユーザー層が完璧に理解しているスキルを捨てて移行してもらう必要があって、これは説得するのがかなり難しい。
だから、究極のクエリ言語ができるまでは、僕は「パイプライン付きのSQL」でいいかな。これなら導入も簡単だし、SQLに対する僕の不満の9割は解決できそうだしね。
この文脈で、投稿者さんや皆さんが Mangle Datalog についてどう思うか純粋に興味がある。Go版の実装はここ(https://codeberg.org/TauCeti/mangle-go )、Rust版はここ(https://codeberg.org/TauCeti/mangle-rs )。
実装自体は超高性能ってわけじゃないけど、全部メモリに載るデータや、外部クエリを通してデータを統合できるなら、多くのユースケースで実用的に使えるはず。
SQLを置き換えるつもりで始めたわけじゃないし、普及は大歓迎だけど、ここで共有した理由はそれじゃない。オープンソースにしたのは、Datalogを広く知ってもらいたかったから。自分のやりたいことにはSQLを使いたくないと確信して、特定の特性を持つDatalogの実装を探し回った経験が動機になってる。
構造化された型や再帰、述語への命名、クエリの合成ができる...。Mangleにはすでにユーザーもいるし、クエリを論理プログラミングとして扱う手法を活用しているアプリケーションもいくつかあるよ。
この議論から引き出せる洞察の一つは、クエリ言語とそれが属するDBMSの実装は、避けられないパフォーマンス要件を考えると、切り離して考えるのは難しいってことだと思う。
SQLが今日のような地位にあるのは、実戦で鍛え上げられていて、同時並行での読み書きという非常に難しい課題を解決しているからだよね。だから、SQLを丸ごと置き換えようとしても、結局はもっとひどくて検証が不十分で、開発者も慣れていないSQLの劣化版ができるだけだと思う。僕の考えでは、最高のクエリ言語っていうのは、すでに使っているバックエンド言語の機能そのものだと思うんだ。例えばC#のLINQみたいな。SQLの代替品が入り込む余地があるとしたら、TigerBeetleみたいに柔軟性を犠牲にして速度を取るケースくらいじゃないかな。
今の時代、LLMを使って独自のプログラミング言語を作るいいところは、理論上の言語についてあれこれ推測しなくても、CodexやClaudeに実装させて自分で試せるってこと。昨日も試してみたんだけど、頭の中にあった理論的なハイパフォーマンスDBアーキテクチャを、今ある言語にクエリ機能を追加するだけで試せたよ。
結果に興味がある人がいたら言うけど、新しいDBのデフォルトの単純なモードだと、永続的な同時変更ワークロードの0.2倍くらいの速度だった。でも特定のアプリケーション向けに最適化すると、柔軟性と引き換えに、フィルタやマップの処理で50〜100倍の驚異的なパフォーマンス向上を得られる。実験結果としては期待できるけど、本番環境にはまだまだだね。
PRQLは新しいクエリ言語への挑戦の中では最高のものの一つだと思う。
僕は今、substraitにコンパイルするLean4ベースのクエリ言語に取り組んでいるんだけど、型システムや関数型プログラミングの力を活用すれば、SQLの使い勝手はずいぶん良くなるんじゃないかと思ってる。
僕が15年前から求めてるのは[1]、ライブSQLエクステンションだね。クエリをデータベースへのサブスクリプションにして、更新があればリスニングしているクライアントへデルタとしてストリーミングされるようにする。SQLを使っていて、同じクエリを何度も何度も実行してデルタを処理するっていう作業を嫌というほどやってきたんだ。
最初からそういう仕組みにしておくほうが、ずっと効率的だと思わない?
[1] http://livesql.org/ (http://livesql.org/) <--- 2011年当時のたった数段落のテキストだけどね
エラーハンドリングやスキーマ更新については何かないの?10年以上SQLを触ってきて、間違いなく恋しくなるのはその辺りだね。
エラーハンドリングっていうのは、例えば列を非推奨にしたとき、誰かがクエリを実行したらカスタムエラーメッセージを表示できるようにするとか。
スキーマ更新っていうのは、テーブルのバージョン管理ができること。同じテーブル名でも、古いバージョンのスキーマに対してクエリを投げられるようにするとか、そういう機能が欲しい。
エンタープライズ向けに特化される前のSparkによく似てるね。昔はScalaを書いてクエリを実行してたし、一度コンパイラとランタイムをセットアップしてしまえば、なかなか気に入っていたものだよ!
最近Postgresを触り始めたんだけど、C言語を使って新しい型や演算子を導入するのがすごく簡単でびっくりした。ドメインの話じゃなくて、普通にCを書けば好きな型が作れるんだよね。あれで「拡張機能(extensions)」という概念の謎が解けた気がする。「拡張機能」や「プラグイン」って言葉は、他で散々な目に遭ってきたからなんか古臭くて気持ち悪い響きがあるけど、実際はカスタム型や関数を作っているだけなんだ。もっとみんな自分でPostgresの拡張を書いてみるべきだよ。全然難しくないから!
この分野(HDFS/Spark、Apache Pinot、独自の何か、SQLite上の実験的な関数型ORMなど)ではずっと試行錯誤してきたけど、最大の問題は管理/管理層、アプリケーション層、クエリ層のインターフェースにあると思う。gRPCやProtobufのような(あるいはSparkがJVMを使っていたような)仕組みがあれば、DBからクライアントに対して、抽象化を壊さずにプログラムしやすく構造化されたインターフェースを提供できるはず。もっと話したいことはあるけど、要はデータベースが、リフレクティブな型システムを持っていて、一般的なメタパース機能を持つようにならなきゃダメだということだね。