次のプロジェクトに SurrealDB だけが必要な理由

Database tutorial - IT technology blog
Database tutorial - IT technology blog

マルチモデルへの移行

データ管理とは、かつてはどちらか一方を選ぶことを意味していました。構造化されたテーブルが必要ならSQLを、柔軟性が必要ならNoSQLを選んでいました。

複雑なリレーションシップには、グラフデータベースを利用しました。MySQL、PostgreSQL、MongoDBを何年も使い分けた結果、3つの異なる接続文字列と同期スクリプトを維持することは、燃え尽き症候群(バーンアウト)の元であることに気づきました。あるプロジェクトでは、スプリント時間の20%を、リレーショナルデータとドキュメントストアの整合性を保つためだけに費やしていました。インフラの負担なしに、あらゆるパターンを処理できるツールが欲しかったのです。

SurrealDBは、ドキュメント、グラフ、リレーショナルデータベースとして単一のバイナリで動作することで、この問題を解決します。単にデータを保存するだけでなく、APIレイヤーや認証も処理します。同じようなCRUDロジックのボイラープレートを書き続けることに疲れた開発者にとって、バックエンドスタック全体を簡素化してくれます。

クイックスタート:60秒で稼働開始

SurrealDBは、1つのコマンドでローカルマシン上で実行できます。macOS、Linux、またはWSL経由のWindowsのいずれを使用していても、このスクリプトがセットアップを管理します。

curl --proto '=https' --tlsv1.2 -sSf https://install.surrealdb.com | sh

システムメモリ内で一時的なデータベースを起動します。これは、ドライブを永続ファイルで汚さずにクエリをテストする最速の方法です。

surreal start --log debug --user root --pass root memory

新しいターミナルタブを開きます。内蔵のSQLシェルを使用して、すぐにサーバーと対話できます。

surreal sql --endpoint http://localhost:8000 --namespace test --database test --auth-user root --auth-pass root

最初のレコードの作成は簡単です。SurrealDBでは、すべてのレコードがユニークな table:id で識別されます。

CREATE person:john SET 
    name = 'John Doe', 
    email = '[email protected]', 
    created_at = time::now();

データの取得には、すでにご存知のSQL構文を使用します:

SELECT * FROM person:john;

ディープダイブ:なぜマルチモデルが重要なのか

SurrealDBは単なるNoSQLのクローンではありません。SQLのように感じられながらも、従来のリレーショナルデータベースにはない機能を備えた言語、SurrealQLを使用します。

1. スキーマフルまたはスキーマレス

MongoDBでは、あらゆる JSON 構造を保存できますが、これはしばしばデータの乱雑さを招きます。PostgreSQLでは、すべてのカラムを事前に定義する必要があります。SurrealDBは両方の良いとこ取りをしています。スキーマレスなアプローチでプロトタイプを作成し、要件が固まったら DEFINE TABLEDEFINE FIELD を使ってテーブルを固定することができます。

2. ダイレクトポインタとしてのレコードID

標準的なデータベースは、IDを単純な文字列や整数として扱います。SurrealDBはそれらをポインタとして扱います。person:john を保存すると、システムはそのレコードの正確な物理的な場所を把握します。これにより、O(1)のルックアップが可能になります。リレーショナルデータベースで行数が数百万に増えたときに発生する、従来のインデックススキャンによる速度低下を回避できます。

3. JOINのペナルティがないグラフリレーション

JOINはリレーショナルシステムにおける最大のボトルネックです。SurrealDBは、代わりにグラフエッジを使用してデータをリンクします。ユーザーが投稿に「いいね」をするソーシャルアプリを想像してみてください。中間テーブルは必要ありません。ただそれらを「リレート(関連付け)」させるだけです。

RELATE person:john->like->post:123 
    SET time = time::now();

特定の投稿に「いいね」をした全員を見つけるには、矢印をたどります。高速で読みやすく、水平方向にスケールします:

SELECT ->like->person.name FROM post:123;

高度な活用:リアルタイム性とセキュリティ

SurrealDBは、通常Redisや専用の認証プロバイダーのような追加のバックエンドサービスを必要とする機能を処理します。

ライブクエリ

モダンなアプリはリアルタイムのインタラクティブ性を求めます。WebSocketsを手動で設定する代わりに、データの変更を直接購読できます。LIVE SELECT を使用すると、レコードが更新された瞬間に通知を受け取ることができます。

LIVE SELECT * FROM person WHERE city = 'London';

ロンドンのユーザーが追加または更新されるたびに、フロントエンドは即座に変更を受け取ります。

埋め込み認証

最も印象的な機能は、データベース内でアプリケーションユーザーを処理できることです。スコープと権限を定義できるため、フロントエンドがSurrealDBと直接通信できます。これにより、多くのタスクで従来のミドルウェアAPIが不要になります。

DEFINE TABLE post SCHEMAFULL
    PERMISSIONS
        FOR select WHERE published = true OR author = $auth.id;

データベースがこれらのルールを強制します。ユーザーがどのようにデータにアクセスしようとしても、許可されたものしか見ることはできません。

現場で役立つ実践的なヒント

新しいツールを学ぶには、よくある落とし穴を避けるのが近道です。私の本番環境へのデプロイ経験から得た4つのヒントを紹介します。

  • Dockerの活用: 公式のDockerイメージは、チーム間やCI/CDパイプライン全体で環境を管理する最も信頼できる方法です。
  • ネームスペースの構造化: プロジェクトにはネームスペース(例:acme_corp)を使用し、devprod などの環境ごとにデータベースを分けます。
  • ナチュラルIDの使用: 一意の識別子がすでに存在する場合は、ランダムなUUIDを避けます。本をカタログ化する場合、デバッグにはランダムな文字列よりも book:9780132350884 の方がはるかに役立ちます。
  • Traceによるデバッグ: 複雑な権限設定のためにクエリが失敗した場合は、--log trace を付けてサーバーを実行してください。どの権限チェックがリクエストをブロックしているかを正確に示してくれます。

SurrealDBは、異なるデータモデル間の摩擦を取り除きます。データを新しいプロバイダーに移行することなく、単純なドキュメントストアから大規模なグラフネットワークへとスケールアップできます。最初の RELATE コマンドを実行すれば、マルチモデルアプローチの効率性は否定できないものになるでしょう。

Share: