isyumi_netブログ

isyumi_netがプログラミングのこととかを書くブログ

RDBMSを作ろうと思う

Cloud Datastoreのラッパーを作りたい

自分は普段GAEのCloud DatastoreというKVSを使います。
KVSは多くの場合とても速いですが、RDBほどやりたいことを直接実現できない場合があります。
特に集計系の操作が苦手です。
例えば画面に「月ごとの売上」を表示するのは一筋縄では行かないです。

個別のケースを最適化することは可能です。
上記の例であれば「月ごとの売上テーブル(Datastore用語ではKind)」のようなものを作って、売上データを保存する時に同時に月ごとの売上テーブルに加算したりします。
しかし、これらの処理をいちいち作るのは大変であり、アルゴリズムの使い回しができず、コードの保守も大変です。
そこで、Cloud Datastoreのラッパーフレームワークを作りたいなと思っていました。
KVSでありがちな困りパターンとその解決戦略を全て実装しておき、各アプリケーションは戦略を選ぶだけで自動的にいい感じにしてくれるものを作りたいなと思っていました。

RDBを作ってみたい

普通に考えて無理では?

話は変わります。PostgreSQLMySQLのような立派なRDBを作ってみたいと思いました。理由は特にないですが、プログラマーに生まれたからにはCPUとOSと言語とRDBを作ってみたくなるものではないかと思います。「俺の考えた最強のRDB」を作りたいのです。
自分のRDBに入れたい超便利な機能のアイディアもあります。例えば僕はFirebaseが大好きなのでFirebaseと連携できる機能を作りたいです。
しかし、RDBというのはとてもむずかしいものだと思いました。
RDBチューリング賞を何人も出している一大学問ジャンルであります。データベースの理論に精通していなければいけないと思います。
また、実装面でも

に精通していないと既存のRDBより出来のいいものを作るのは不可能だと思っていました。

用途を限れば出来るかも

しかし、クラウドで使う前提のRDBを作るだけなら簡単なのではないかと思いました。
まず、特定のOSで動けばいいので、互換性のためのコードが要りません。
GCPAWSにはCloud DatastoreやDynamoDBといったシンプルなKVSが用意されています。
これにRDBの皮を被せればいいのではないかと思いました。
これらのKVSはすでに

といった必要な機能を全て備えています。
また、GCPAWSにはそれぞれGAEとLambdaといったサーバーレスアプリケーション実行環境を用意しています。プロセスが落ちた場合に備えたりラウンドロビンを実装したりする必要がありません。
後はKVS上に参照整合制約やドメイン制約(いわゆる型)を実装するだけだと思います。

作る!

以上の2つの話から「GAE上で動きCloud DatastoreにRDBの皮をかぶせるラッパーフレームワークを作ればいい」という結論に達しました。

〇〇ではダメなのか

クラウドRDBホスティングサービスではダメなのか

例えばGCPのCloud SQLAWSのRDSがあります。
これらは、プログラマがこれまでと同じようにPostgreSQLMySQLを使い続けたいと言ったから始まったマネージドサービスです。
そもそも、PostgreSQLMySQLができたときには、今のようなクラウドコンピューティングはありませんでした。ということはクラウドで動かすなら不要な機能はいっぱいあると思います。
想像ですが、これらのホスティングサービス内で動いているRDBは、オリジナルの実装とは全然違うはずです。PostgreSQLプロトコルを喋りPostgreSQLと同じ出力をする全然別の何かが動いているはずです。
ところが、自分はRDBの機能の殆どを使ったことがないです。SQLの文法もほとんど使ったことがないです。もちろん、プログラマとしてずっとRDBを使ってきました。それでも、全機能の内使ったことがある機能は5%くらいじゃないかなと思います。
これはとても非効率なことです。プログラマPostgreSQLがほしいと言ったから、クラウド事業者はPostgreSQLと全く同じ動きをする全然別のものを作り、しかしプログラマはその機能の内殆どを使っていないのです。だったら最初から既存のRDBとは全然違う、機能も互換性も絞ったものを使ってもいいじゃんという気持ちになりました。

既存のRDBプラグインじゃダメなのか

追加したい機能があるならプラグインを作ればいいというのはまともな発想です。
僕も最初はこれを作ろうと思いました。
PG-StromというGPUを使ってクエリをアクセラレートするPostgreSQLプラグインがあります。僕はこれを知っていたので、僕も真似しようと思いました。Firebase連携プラグインを作ろうと思ったのです。しかし、クラウドRDBマネージメントサービスが全盛の時代に、これを使ってくれる人がどれくらいいるか考えた結果断念しました。

SpannerやBigQueryではダメなのか

自分はFirebaseと連携するRDBがほしいので、公式が対応してくれない限り無理だと思います。

また、SpannerやBigQueryはいろんな分析をするためには優れていると思いますが、Webアプリケーションのバックグラウンドには向いていないのではないかと思います。
柔軟に対話的に分析をしたり、今後何に使うかわからないデータを大量に蓄積しておくにはいいサービスだと思います。しかし、多くのWebアプリはどのデータをどのように集計して使うかわかりきっている場合が多いです。事前にデータの並べ方を工夫しておけます。BigQueryのような「どんなクエリが来ても一瞬で集計してくれる」機能はオーバーキルであり、逆に課金の高さが際立ってしまいます。

作りたい機能

Firebase連携機能

先述の通り、Firebase連携機能がほしいです。
RDBのビューをFirebaseに反映できたらいいと思います。マテリアライズドビュー機能を持つDBがありますが、そのマテビューをFirebaseに書き込むようなものです。

よく、Firebaseを使ったリアルタイムなチャットのデモがあります。
でも、アレを作るのって結構大変です。
まず、セキュリティルールを正確に記述しなければいけません。
また、Firebaseは非正規化して使うのが普通なので更新系が苦手です。
新規書き込みをリアルタイムで反映させるのは簡単でも、書き込みユーザーがユーザー名を変更した時に画面上のユーザー名をリアルタイムで更新するのは諦めたりします。

RDBはこういう操作が得意です。
だから、RDBに対してCREATE VIEW文を宣言したら自動的にそのVIEWがFirebaseに反映され、DBが更新されたらリアクティブにFirebaseも差分更新されたらいいなと思いました。
この機能を作りたいです。

新しいSQL

僕はRDBSQLの世界観が好きです。
ジョー・セルコの「プログラマのためのSQL」を愛読しています。
しかし、SQLの文法はあまり好きではありません。
今のSQLの文法ではSQLが本当にやりたかったことを満たしづらいと思います。だから新しい文法を作りたいです。
詳しくはこっちです。
https://blog.isyumi.net/entry/2018/08/01/140842

定理証明

最近既存のOSSの実装を定理証明することでバグを発見するような試みを聞くことが多いです。
先日話題になったHeartbleedもその一種です。
発見される側の気持ちはわからないですが、切り口として面白いと思います。
僕は最初からこのRDBの実装に定理証明を導入したいです。
RDBは平行処理とステートマシンであり、定理証明の得意分野の一つだと思います。
最初から定理証明があるということが、コントリビュータを増やすことに効いてくると思います。
もちろん、定理証明があるかないかはユーザーにとって関係ありません。自己満足のそしりを免れられないと思います。
しかし、そもそも僕が作りたいから作るのであって僕が定理証明を入れたいなら入れるのが正義なのです。異論は認めません。

管理ツール

MySQL Workbenchのような使いやすい管理ツールを作りたいです。これがキラーアプリになると思います。
僕は普段Webフロントエンド系の開発をすることが多いので、こういうのは得意です。

課題

KVS上に参照整合制約やユニーク制約やON DELETE CASCADEは簡単に作れると思もいます。

一番大変そうなのはVIEWです。特定のテーブルの更新に追従して別のテーブルに実体化させておいたVIEWやFirebaseを最安経路で更新するアルゴリズムを考えるのが大変だと思います。
例えば月ごとの売上VIEWであれば、

  • 初回起動時に全ての売上
  • 売上が立ったらその月の合計を増やす
  • 売上がキャンセルされたらその月の売上を減らす
  • 売上の日付が月をまたいで変更されたら
  • 元の月の売上を減らして変更後の月の売上を増やす
  • 個数が変更されたら単価*(変更後の個数-元の個数 )を加算

を導出する。
どうやったらいいのかさっぱりわからない。

じゃあいつやるの?

現行のスケジュールでは来年の5月頃に取り組めるかと思います。