0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【個人開発】Claudeを導入し、ブラウザ完結のインメモリDB「LuminaDB」を劇的進化させた話

0
Posted at

はじめに

以前、ブラウザのローカル環境だけで動作し、バックエンドを一切必要としないインメモリSQLデータベース「LuminaDB」を開発しました。
👉 【個人開発】ブラウザ上で動く!依存ゼロのインメモリSQLデータベース「LuminaDB」を作ってみた

ReactなどのフレームワークやSQLite等のWASMライブラリに一切依存せず、HTMLとVanilla JavaScriptのみでSQLエンジンをフルスクラッチするという、完全に趣味のR&Dプロジェクトです。

最初は「基本的なSELECTやJOINが動けばいいな」程度のシンプルなモックツールでした。しかし今回、Claudeを導入し、徹底的に壁打ちとリファクタリングを繰り返した結果、自分でも驚くほどの本格的なデータベースエンジンへと「限界突破」させることができました!

本記事では、Claudeの導入でLuminaDBがどう進化したのか、どのような技術的課題を乗り越えたのかを紹介します。
image.png
👉 新LuminaDBのURLはこちら


Claude導入前(初期リリース時)のLuminaDB

初期バージョンでも、以下のような基本的なギミックは実装していました。

  • 基本的なSQLサポート: SELECT, INSERT, UPDATE, DELETE や簡単なJOINなど。
  • Fetch APIのインターセプト: window.fetch を乗っ取り、ローカル内で疑似APIサーバーとして振る舞う機能。
  • 内部データの SoA 管理: データをAoS(オブジェクトの配列)ではなく、SoA(配列の構造体)として列指向に管理して高速化。

これだけでも面白かったのですが、RDBMSとしての「SQL標準互換性」や「トランザクションの厳密さ」には限界がありました。そこで、Claudeを導入して本格的な改修に乗り出しました。


Claudeの導入で「限界突破」した3つのポイント

1. 「1000ケース超え」回帰テストスイートの構築

最も恩恵を受けたのはテストコードの実装です。
データベースの性質上、境界値や異常系のテストは無限に存在します。Claudeに「現在のエンジン仕様に基づくエッジケースを洗い出して」と指示することで、人間では心が折れるレベルの網羅的なテストケースを自動生成・拡充できました。

テストコードが存在することの恩恵はすさまじく、Claudeで追加機能の作成を指示するたびにテストケースの追加と全パスも指示することで、すでに存在している機能が壊れることなく堅牢性を保ったままコードを更新することができます。この規模のソースコードになってくると正直人間の目でいちいち読むのは不可能なので、テストで動作を保証できるというのは大変ありがたいです。

image.png

  • 大規模パフォーマンステスト: 5万〜10万行規模のダミーデータを注入し、数ミリ秒〜数秒以内でJOINや集計、Window関数が完了するかを検証するテストを実装。

  • 異常系・境界値テスト: LIMIT/OFFSETの極端な値、0除算、型の不一致、さらにはSQLインジェクションになり得る構文(引用符のエスケープなど)に対する堅牢なテストを網羅。

結果として、1000件以上のテストスイートを全パスする堅牢な基盤が完成しました。

2. 「モダンな標準SQL」のフルサポート

初期は手書きの正規表現パースに頼っていたため、複雑なSQLに対応できていませんでした。Claudeと一緒に構文解析器を整理し、以下の高度なSQLを完全サポートしました。

  • CTE(共通テーブル式 / WITH句): 複雑なサブクエリを整理して実行可能に。

  • ウィンドウ関数: ROW_NUMBER, RANK, LAG, NTILE 等、分析系クエリに必須の関数を実装。

  • 高度なDML: REPLACE INTOON DUPLICATE KEY UPDATE など、実務で重宝される構文の追加。

  • 厳密な制約と参照アクション: 単なる外部キーチェックだけでなく、ON DELETE CASCADEON UPDATE SET NULL、さらには複雑な条件を評価する CHECK 制約まで正確に実装。

3. ブラウザ特有の「セキュリティの穴」を徹底防御

JavaScriptで動的にSQLを評価(new Function を使用)する構造上、ブラウザ特有の脆弱性が課題でした。Claudeのセキュリティレビューにより、以下の防御壁を構築しました。

  • プロトタイプ汚染対策: テーブル名やカラム名に __proto__constructor が入力されても、内部のオブジェクト構造が破壊されないよう完全に分離。

  • XSS / SQLインジェクション防御: 結果描画時のサニタイズ処理や、プレースホルダー(?)を用いたパラメータバインドの実装。

  • DoS(サービス拒否)攻撃へのガード: 異常に長いクエリ文字列や、100階層を超える悪意のあるサブクエリ、ReDoS(正規表現攻撃)を事前に検知して遮断するキャップ機能を導入。


技術スタック・実装の工夫点

LuminaDBを支えるコア技術も、リファクタリングを経て洗練されました。

① TypedArrayを利用したSoA (Structure of Arrays)

初期バージョンから採用していたSoA構造をさらに最適化し、単純なJSの配列ではなく Float64ArrayUint32Array を活用したカラムナーフォーマット(列指向)を採用しました。これにより、インデックス走査や集計処理時のメモリ効率とキャッシュヒット率が劇的に向上しています。

② ACID特性を備えたトランザクション管理

データの更新途中にエラーが起きた際、中途半端なデータが残らないよう、BEGINCOMMIT / ROLLBACK の制御を厳密化しました。
単なるデータの巻き戻しだけでなく、「トランザクション内で実行した ALTER TABLE(カラム追加など)や CREATE INDEX のような構造変更(DDL)も綺麗にロールバックできる」 という仕様を実現しています。

③ IndexedDB への永続化と暗号化

「インメモリ」のサクサク感はそのままに、ブラウザを閉じてもデータが消えないよう IndexedDB へのスナップショット保存機能を実装しました。万が一ブラウザのストレージを覗き見られても安全なように、スナップショットは暗号化されて保存される仕様にしています。

その他新機能

① 充実のコマンドリファレンス

あのコマンド使いたいんだけど、クエリってどうやって書くんだっけ?といった場合にこの画面を開くことで、実際に実行できるクエリの見本をコピペすることができます。さらに、現在選んでいるテーブルに合わせた形で加工されます。
image.png

② テーブルの編集画面

テーブルの列名変更や列の順番や型の変更などを直感的に操作できます。さらに、CREATE TABLE文も都度動的に生成され表示されます。
image.png


おわりに

LuminaDBは、「ブラウザのローカル環境だけで、どこまで本物のRDBMSを再現できるか」という技術的探求から生まれました。
今回のアップデートにより、SQLの学習用プレイグラウンドとしてはもちろん、フロントエンド開発時のモックDB、あるいはセキュアなローカルCSV集計ツールとして、かなり実用的に遊べるツールに進化したと思います。

機能面でまだまだ粗削りな部分もありますが、ぜひブラウザ上で数万件のデータを投入して、ウィンドウ関数やJOINを走らせてみてください!

もし触ってみてバグを見つけた方や、「こんな機能が欲しい!」というアイデアがある方は、ぜひコメントで教えていただけると嬉しいです!

👉 ソースコード

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?