従来のデータベース選定では、リレーショナルデータにはPostgreSQL、ドキュメントストアにはMongoDB、グラフデータにはNeo4jといった具合に、データモデルごとに異なるデータベースを採用するのが一般的でした。しかし、複数のデータベースを運用するオーバーヘッドは無視できません。スキーマの同期、データの整合性維持、インフラコスト、そして学習コスト。これらの課題を解決しようとするのがマルチモデルデータベースです。
SurrealDBは、その中でも特に注目を集めているNewSQLデータベースです。SQL構文をベースにしながら、ドキュメント、グラフ、テーブルの各モデルを統一的に扱える点が大きな特徴です。
SurrealDBの魅力は、SQLに馴染みのある開発者がスムーズに使い始められる構文設計にあります。基本的なCRUD操作から見ていきましょう。
-- テーブル定義(スキーマフル)
DEFINE TABLE user SCHEMAFULL;
DEFINE FIELD name ON user TYPE string;
DEFINE FIELD email ON user TYPE string ASSERT string::is::email($value);
DEFINE FIELD age ON user TYPE int ASSERT $value >= 0;
DEFINE FIELD created_at ON user TYPE datetime DEFAULT time::now();
-- レコード作成
CREATE user:taro SET
name = 'Taro Yamada',
email = 'taro@example.com',
age = 30;
-- クエリ
SELECT * FROM user WHERE age >= 25;
レコードIDに文字列を使える点が特徴的です。user:taroのように意味のあるIDを付けられるため、可読性が向上します。
SurrealDBではスキーマレスモードも利用可能で、MongoDBのようにネストしたドキュメントを柔軟に格納できます。
-- スキーマレステーブル
DEFINE TABLE product SCHEMALESS;
-- ネストしたデータの格納
CREATE product SET
name = 'ワイヤレスイヤホン',
price = 15800,
specs = {
battery_hours: 8,
bluetooth_version: '5.3',
noise_canceling: true,
drivers: [
{ type: 'dynamic', size: '10mm' },
{ type: 'balanced_armature', size: '6mm' }
]
},
tags = ['audio', 'wireless', 'anc'];
-- ネストしたフィールドへのクエリ
SELECT name, specs.battery_hours
FROM product
WHERE specs.noise_canceling = true
AND price < 20000;
リレーショナルとドキュメントのハイブリッド運用が可能なため、テーブルごとに最適なデータモデルを選択できます。
SurrealDBの最も差別化された機能は、グラフリレーションの組み込みサポートです。RELATEステートメントでエンティティ間の関係を定義し、矢印構文で直感的にトラバースできます。
-- ユーザー間のフォロー関係を定義
RELATE user:taro->follows->user:hanako SET
since = '2025-01-15';
RELATE user:taro->follows->user:jiro;
RELATE user:hanako->follows->user:jiro;
-- taroがフォローしているユーザーを取得
SELECT ->follows->user.name FROM user:taro;
-- taroをフォローしているユーザーを取得
SELECT <-follows<-user.name FROM user:taro;
-- 2ホップ先のつながりを探索
SELECT ->follows->user->follows->user.name
FROM user:taro;
Neo4jのCypherに比べると表現力はまだ限定的ですが、別途グラフデータベースを導入することなくソーシャルグラフやレコメンデーションの基本的なクエリが書けるのは大きな利点です。
SurrealDBにはLIVE SELECTという機能があり、データの変更をリアルタイムにクライアントへ通知できます。WebSocketベースで動作するため、チャットやダッシュボードのようなリアルタイム性が求められるアプリケーションとの相性が良好です。
-- リアルタイムクエリの登録
LIVE SELECT * FROM message
WHERE channel = 'general';
-- イベントトリガーの定義
DEFINE EVENT new_order ON TABLE order WHEN $event = "CREATE" THEN (
CREATE notification SET
message = 'New order received: ' + string($after.id),
created_at = time::now()
);
これにより、メッセージブローカーを別途導入せずとも、簡易的なイベント駆動処理を実現できます。
SurrealDBの特筆すべき機能のひとつが、データベースレベルで認証・認可を定義できることです。従来はアプリケーション層で行っていたアクセス制御をデータベース側で一元管理できます。
-- スコープベースの認証定義
DEFINE ACCESS user_access ON DATABASE TYPE RECORD
SIGNUP (CREATE user SET email = $email, pass = crypto::argon2::generate($pass))
SIGNIN (SELECT * FROM user WHERE email = $email AND crypto::argon2::compare(pass, $pass))
DURATION FOR SESSION 24h;
-- テーブルレベルの権限設定
DEFINE TABLE post SCHEMAFULL
PERMISSIONS
FOR select FULL
FOR create WHERE $auth.id != NONE
FOR update WHERE author = $auth.id
FOR delete WHERE author = $auth.id;
この仕組みにより、フロントエンドから直接SurrealDBに接続するアーキテクチャも理論上は可能になります。ただし、プロダクション環境では中間層を設けるのが安全でしょう。
SurrealDBは魅力的な機能を多く持つ一方で、2025年時点ではまだ成熟途上にある点を認識しておく必要があります。
それでも、プロトタイピングや中小規模のプロジェクトでは十分に実用的です。特に「リレーショナル+ちょっとしたグラフ機能+ドキュメントの柔軟さ」を一つのデータベースで実現したい場面では、SurrealDBは非常に有力な選択肢になります。まずは個人プロジェクトや社内ツールで試してみることをお勧めします。