SurrealDB 3.0で始めるマルチモデルDB活用とFaunaDB終了の教訓
この記事でわかること
- マルチモデルデータベースの概念と、従来のポリグロットパーシステンス(複数DB運用)との違い
- FaunaDBのサービス終了(2025年5月)から学ぶDBaaS選定の教訓
- SurrealDB 3.0の8つのデータモデルとSurrealQLの基本的な使い方
- SurrealMLを使ったPyTorch/Scikit-learnモデルのDB内推論の実装方法
- MLパイプラインにおけるベクトル検索・グラフ探索・ハイブリッド検索の実践例
対象読者
- 想定読者: MLエンジニアでデータベース選定に関わる方
-
必要な前提知識:
- Python 3.10+の基本的な使い方
- PyTorchまたはScikit-learnでのモデル学習経験
- SQLの基礎文法(SELECT, INSERT, WHERE程度)
- RDBやドキュメントDBの基本概念(PostgreSQL = テーブル + リレーション、MongoDB = JSONドキュメント)
結論・成果
マルチモデルデータベースを採用すると、MLパイプラインで一般的な「PostgreSQL + MongoDB + Redis + Elasticsearch + Neo4j」の5つのDB運用を1つのSurrealDBに統合できます。公開ベンチマークによると、SurrealDB(RocksDBバックエンド)のリード性能は約508,000 ops/secで、PostgreSQLの約284,000 ops/secを上回ると報告されています。一方、ライト性能は約155,000 ops/secでPostgreSQLの約205,000 ops/secに劣るというトレードオフがあります。
FaunaDBの2025年5月のサービス終了は、DBaaS選定において「技術的な優位性だけでは生き残れない」という教訓を残しました。本記事では、この教訓を踏まえつつ、2026年2月にGAとなったSurrealDB 3.0をMLワークフローに組み込む実践的な方法を解説します。
マルチモデルデータベースの基本を理解する
マルチモデルデータベースは、1つのデータベースエンジンで複数のデータモデル(リレーショナル、ドキュメント、グラフ、ベクトルなど)を扱えるデータベースです。MLエンジニアにとって、これは「特徴量はテーブル、埋め込みベクトルは専用ストア、エンティティ間の関係はグラフDB」と別々に管理していたデータを1箇所に集約できることを意味します。
ポリグロットパーシステンスの課題
従来のMLシステムでは、ポリグロットパーシステンス(用途に応じて複数のDBを使い分ける設計)が一般的でした。PyTorchの __init__ で複数のDBクライアントを初期化するようなイメージです。
# 従来のポリグロットパーシステンス構成
# Pythonの __init__ で複数DBを初期化する感覚
import psycopg2 # リレーショナル(特徴量メタデータ)
import pymongo # ドキュメント(実験ログ)
import redis # KV(キャッシュ)
from elasticsearch import Elasticsearch # 全文検索
from neo4j import GraphDatabase # グラフ(知識グラフ)
class MLPipeline:
def __init__(self):
self.pg = psycopg2.connect("postgresql://...")
self.mongo = pymongo.MongoClient("mongodb://...")
self.redis = redis.Redis(host="localhost")
self.es = Elasticsearch(["http://localhost:9200"])
self.neo4j = GraphDatabase.driver("bolt://localhost:7687")
# 5つのDB、5つの接続、5つの運用コスト
この構成には以下の問題があります。
| 課題 | 具体例 | 影響 |
|---|---|---|
| 運用コストの増大 | 5つのDBのバックアップ、監視、アップデート | インフラチームの負荷増 |
| データ整合性の担保が困難 | PostgreSQLとNeo4jの間でトランザクション不可 | 不整合データによる推論精度低下 |
| スキーマ管理の複雑化 | DB毎に異なるマイグレーション手順 | デプロイ事故のリスク増 |
| 学習コスト | SQL、MongoDB Query、Cypher、Elasticsearch DSL... | オンボーディング期間の長期化 |
マルチモデルDBが解決すること
マルチモデルDBでは、1つのクエリ言語・1つの接続で全てのデータモデルにアクセスできます。ただし、各データモデルに特化したDBと比較するとピーク性能は劣る場合があるという制約は理解しておく必要があります。これはPyTorchで例えると、カスタムCUDAカーネルを書けば最速だが、torch.nnの汎用レイヤーで十分な場合が多い、というトレードオフに似ています。
注意: マルチモデルDBは「全てのユースケースで最速」ではなく、「全てのユースケースで十分な性能を1つのシステムで提供する」ことが価値です。大規模OLAPワークロードやリアルタイム性が厳密に要求されるユースケースでは、専用DBの方が適切な場合があります。
FaunaDBの終了から学ぶDBaaS選定の教訓
2025年5月30日、FaunaDBのマネージドサービスが終了しました。公式ブログによると、「現在の市場環境でサービス継続に必要な資金調達ができなかった」ことが理由です。技術的にはJepsen検証済みのACID保証、グローバル分散、サーバーレスアーキテクチャと高い評価を受けていましたが、広範な採用には至りませんでした。
FaunaDBの技術的特徴(振り返り)
FaunaDBはドキュメント-リレーショナルハイブリッドモデルを採用し、TypeScript風のFQL(Fauna Query Language)で操作するサーバーレスDBaaSでした。InfoQの報道によると、厳密な直列化可能性(strict serializability)をJepsenテストで実証しており、分散データベースとしての整合性保証は当時のDBaaS市場で突出していました。
DBaaS選定で確認すべき5つの観点
FaunaDBの事例から、DBaaSを選定する際に技術仕様以外で確認すべきポイントが見えてきます。
| 観点 | FaunaDBの状況 | 教訓 |
|---|---|---|
| 資金調達状況 | 終了時点で追加調達不可 | シリーズB以降の資金調達実績を確認 |
| エコシステムの規模 | 限定的なコミュニティ | GitHubスター数、ドライバ数、サードパーティツール数 |
| セルフホスト可否 | クラウドのみ(OSS版は終了後に公開) | ベンダーロックイン回避のためセルフホスト可能か |
| データポータビリティ | 独自FQLで他DBへの移行困難 | 標準SQL互換のクエリ言語か |
| 採用企業 | 公開事例が限定的 | 大規模本番運用の実績があるか |
よくある間違い: 「技術的に優れているDB = 長期的に安全な選択」と考えがちですが、FaunaDBの事例はこの仮説を否定しています。技術的優位性と事業の持続可能性は別の問題です。
注意: FaunaDBのOSS版(faunadb.org)は2026年3月時点で正式リリースがなく、「very early stage」と明記されています。本番環境での利用は推奨されません。
SurrealDB 3.0の8つのデータモデルを活用する
SurrealDBは2026年2月17日にバージョン3.0がGA(General Availability)となった、Rust製のマルチモデルデータベースです。公式発表によると、累計230万以上のダウンロード、GitHubスター31,000以上を記録しています。資金調達はSeries Aで$23Mを追加し、累計$38M以上を確保しています(SiliconANGLE報道)。
SurrealDB 3.0がサポートする8つのデータモデル
| データモデル | SurrealDBでの実現方法 | MLでの用途例 |
|---|---|---|
| リレーショナル | テーブル + スキーマ定義 | 特徴量メタデータ管理 |
| ドキュメント | ネストオブジェクト/配列 | 実験ログ、ハイパーパラメータ記録 |
| グラフ |
RELATE文 + -> 探索構文 |
知識グラフ、エンティティ関係 |
| ベクトル | HNSWインデックス | 埋め込みベクトル検索(RAG) |
| 時系列 | 複合レコードID | センサーデータ、メトリクス |
| 地理空間 | GeoJSONサポート | 位置ベースの特徴量 |
| 全文検索 | BM25ランキング | テキスト類似度検索 |
| Key-Value | シンプルKV操作 | キャッシュ、セッション管理 |
SurrealQLの基本操作
SurrealQLはSQL風の構文を拡張したクエリ言語です。MLエンジニアにとっては「SQLに似ているが、JOINの代わりにグラフ探索やネストされたドキュメントアクセスが使える言語」と理解すると分かりやすいでしょう。
-- テーブル定義(スキーマあり/なし両対応)
-- Pythonの dataclass や Pydantic の BaseModel に相当するスキーマ定義
DEFINE TABLE experiment SCHEMAFULL;
DEFINE FIELD name ON experiment TYPE string;
DEFINE FIELD hyperparams ON experiment TYPE object;
DEFINE FIELD metrics ON experiment TYPE object;
DEFINE FIELD created_at ON experiment TYPE datetime DEFAULT time::now();
-- ドキュメント的なデータ挿入(ネストオブジェクト可)
CREATE experiment SET
name = "bert-finetuning-v3",
hyperparams = {
learning_rate: 0.00002,
batch_size: 32,
epochs: 10,
optimizer: "AdamW"
},
metrics = {
accuracy: 0.923,
f1_score: 0.918,
loss: 0.187
};
-- グラフ関係の定義(RELATE文)
-- experiment -> uses -> dataset の関係を作成
RELATE experiment:bert_v3 -> uses -> dataset:squad_v2
SET purpose = "fine-tuning", split = "train";
-- グラフ探索(-> 構文)
-- "bert_v3が使ったデータセットを全て取得"
SELECT ->uses->dataset FROM experiment:bert_v3;
-- ベクトル検索(HNSW)
-- cosine距離で類似ベクトルを検索(RAGに活用)
DEFINE INDEX embedding_idx ON document
FIELDS embedding HNSW DIMENSION 768 DIST COSINE;
SELECT id, title, vector::similarity::cosine(embedding, $query_vec) AS score
FROM document
WHERE embedding <|10|> $query_vec;
なぜSurrealQLを選んだか:
- SQLに近い構文のため、RDBの経験があれば学習コストが低い
- FaunaDBのFQLはTypeScript風で独自性が高く、移行時の負担が大きかった
- GraphQLもサポートしており、フロントエンドチームとの連携が容易
注意点:
SurrealQLにはSQLの
JOIN構文がありません。これは水平スケーリングのための設計上の決定です。リレーション間のデータ取得はサブクエリ、レコードリンク、またはグラフ探索(->構文)で代替します。複雑な分析クエリでは、この制約がパフォーマンスに影響する場合があります。
SurrealDB 3.0の新機能(ML関連)
SurrealDB 3.0では、特にAIエージェント関連の機能が強化されました。
-- 計算フィールド(Computed Fields)
-- Pythonの @property に相当。データ更新時に自動計算
DEFINE FIELD can_deploy ON model COMPUTED metrics.accuracy > 0.9
AND metrics.f1_score > 0.85;
-- リアルタイムサブスクリプション(LIVE SELECT)
-- モデルがデプロイ可能になったら即座に通知
LIVE SELECT * FROM model WHERE can_deploy = true;
-- レコードリファレンス(双方向関係の自動管理)
DEFINE FIELD experiments ON model TYPE option<array<record<experiment>>> REFERENCE;
-- イベントトリガー(埋め込みの自動生成に活用)
DEFINE EVENT generate_embedding ON TABLE document WHEN $event = "CREATE" THEN {
-- HTTPで埋め込みAPIを呼び出し、結果を保存
LET $response = http::post("http://embedding-api:8080/encode", {
text: $after.content
});
UPDATE $after.id SET embedding = $response.embedding;
};
SurrealMLでMLモデルをDB内で推論する
SurrealMLは、学習済みのMLモデルをSurrealDB内で直接推論するための機能です。PyTorch、TensorFlow、Scikit-learnで学習したモデルをONNX形式に変換し、SurrealDBのRustネイティブONNXランタイムで実行します。
モデルのエクスポートと登録
学習済みモデルをSurrealMLで使えるようにする手順を見ていきましょう。
# pip install surrealml
from surrealml import SurMlFile, Engine
from sklearn.linear_model import LinearRegression
import numpy as np
# 1. モデルを学習(通常のScikit-learn)
X_train = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
y_train = np.array([3, 7, 11, 15])
model = LinearRegression()
model.fit(X_train, y_train)
# 2. SurrealMLファイルを作成
# sklearn モデルは inputs と sklearn=True が必要
surml_file = SurMlFile(
model=model,
name="price_predictor",
inputs=X_train,
sklearn=True
)
# 3. 入出力のカラムマッピングを定義
# add_column の順序はモデルの入力次元の順序と一致させる
surml_file.add_column("feature_1") # 入力次元0
surml_file.add_column("feature_2") # 入力次元1
# 4. .surml ファイルとして保存
surml_file.save("price_predictor.surml")
# 5. SurrealDBにアップロード
# CLIの場合: surreal ml import --conn http://localhost:8000 price_predictor.surml
-- SurrealQLから推論を実行
-- ml::ModelName<version>(入力パラメータ) で呼び出す
SELECT
id,
feature_1,
feature_2,
ml::price_predictor<1.0.0>({
feature_1: feature_1,
feature_2: feature_2
}) AS predicted_price
FROM products;
-- モデルのバージョン管理
-- 複数バージョンを同時にデプロイし、A/Bテストが可能
SELECT
ml::price_predictor<1.0.0>({feature_1: 10, feature_2: 20}) AS v1_prediction,
ml::price_predictor<2.0.0>({feature_1: 10, feature_2: 20}) AS v2_prediction;
なぜDB内推論を選ぶのか:
- データの移動が不要(推論APIにデータを送る必要がない)
- SurrealQLのクエリ内でシームレスに推論結果を利用できる
- モデルのバージョン管理がDB側で完結する
制約条件:
SurrealMLは推論(inference)のみに対応しています。モデルの学習(training)はPython環境で行い、ONNX経由でエクスポートする必要があります。また、GPUを使った推論は現時点ではサポートされておらず、CPU推論のみです。大規模なTransformerモデルの推論には、別途推論サーバー(vLLMなど)を用意する方が適切です。
PyTorchモデルのエクスポート
import torch
import torch.nn as nn
from surrealml import SurMlFile
# PyTorchモデルの定義
class SimpleClassifier(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim):
super().__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.relu = nn.ReLU()
self.fc2 = nn.Linear(hidden_dim, output_dim)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
x = self.relu(self.fc1(x))
return self.sigmoid(self.fc2(x))
# モデルの学習(省略)
model = SimpleClassifier(input_dim=10, hidden_dim=64, output_dim=1)
# ... 学習処理 ...
# SurrealMLでエクスポート
# PyTorchの場合、inputs にサンプル入力テンソルを渡す(ONNX変換用トレーシングに使用)
surml_file = SurMlFile(
model=model,
name="fraud_detector",
inputs=torch.randn(1, 10)
)
for i in range(10):
surml_file.add_column(f"feature_{i}")
surml_file.save("fraud_detector.surml")
MLパイプラインでSurrealDBを活用する実践例
ここでは、MLエンジニアが実際に遭遇する3つのユースケースでSurrealDBの活用方法を見ていきます。
RAGシステムでのハイブリッド検索
RAG(Retrieval-Augmented Generation)では、ベクトル類似度検索と全文検索を組み合わせたハイブリッド検索が精度向上に有効です。SurrealDBでは、ベクトルインデックス(HNSW)とBM25全文検索インデックスを1つのDBで同時に利用できます。
-- 1. ドキュメントテーブルの定義
DEFINE TABLE document SCHEMAFULL;
DEFINE FIELD title ON document TYPE string;
DEFINE FIELD content ON document TYPE string;
DEFINE FIELD embedding ON document TYPE array<float>;
DEFINE FIELD source_url ON document TYPE string;
DEFINE FIELD created_at ON document TYPE datetime DEFAULT time::now();
-- 2. ベクトルインデックス(HNSW、768次元、コサイン距離)
DEFINE INDEX vec_idx ON document
FIELDS embedding HNSW DIMENSION 768 DIST COSINE;
-- 3. 全文検索インデックス(BM25)
DEFINE ANALYZER ja_analyzer TOKENIZERS class FILTERS lowercase;
DEFINE INDEX ft_idx ON document
FIELDS content SEARCH ANALYZER ja_analyzer BM25;
-- 4. ハイブリッド検索クエリ
-- ベクトル類似度とBM25スコアを組み合わせる
LET $query_vec = http::post("http://embedding-api:8080/encode", {
text: "SurrealDBのベクトル検索の使い方"
}).embedding;
-- ベクトル検索(上位20件)
LET $vec_results = (
SELECT id, title,
vector::similarity::cosine(embedding, $query_vec) AS vec_score
FROM document
WHERE embedding <|20|> $query_vec
);
-- 全文検索(上位20件)
LET $ft_results = (
SELECT id, title,
search::score(1) AS ft_score
FROM document
WHERE content @1@ "SurrealDB ベクトル検索"
ORDER BY ft_score DESC
LIMIT 20
);
-- Reciprocal Rank Fusionで統合(RRF)
-- 最終的に上位10件を返す
RETURN array::sort::desc(
array::union($vec_results, $ft_results),
"score"
)[0..10];
知識グラフとグラフ探索
MLモデルの入力として知識グラフの構造情報を活用する場面で、SurrealDBのネイティブグラフ機能が役立ちます。
-- エンティティとリレーションの定義
DEFINE TABLE entity SCHEMAFULL;
DEFINE FIELD name ON entity TYPE string;
DEFINE FIELD entity_type ON entity TYPE string;
DEFINE FIELD embedding ON entity TYPE array<float>;
DEFINE TABLE related_to SCHEMAFULL;
DEFINE FIELD relation_type ON related_to TYPE string;
DEFINE FIELD weight ON related_to TYPE float;
-- グラフ構造の作成
CREATE entity:pytorch SET name = "PyTorch", entity_type = "framework";
CREATE entity:onnx SET name = "ONNX", entity_type = "format";
CREATE entity:surrealml SET name = "SurrealML", entity_type = "tool";
CREATE entity:surrealdb SET name = "SurrealDB", entity_type = "database";
-- エッジの作成(RELATE文)
RELATE entity:pytorch -> related_to -> entity:onnx
SET relation_type = "exports_to", weight = 0.9;
RELATE entity:onnx -> related_to -> entity:surrealml
SET relation_type = "imported_by", weight = 0.95;
RELATE entity:surrealml -> related_to -> entity:surrealdb
SET relation_type = "runs_on", weight = 1.0;
-- 2ホップ先のエンティティを探索
-- "PyTorchから2ステップで到達できるツール/DBは何か?"
SELECT
->related_to->entity->related_to->entity AS two_hop_entities
FROM entity:pytorch;
-- 結果: [entity:surrealml, entity:surrealdb]
-- 重み付きパス探索(推薦システムへの応用)
SELECT
->related_to[WHERE weight > 0.8]->entity.name AS strong_relations
FROM entity:pytorch;
イベント駆動の自動埋め込み生成
新しいデータが登録されるたびに、自動的に埋め込みベクトルを生成するパイプラインをSurrealDBのイベントトリガーで構築できます。
-- イベントトリガーで埋め込みを自動生成
DEFINE EVENT auto_embed ON TABLE document
WHEN $event = "CREATE" OR ($event = "UPDATE" AND $before.content != $after.content)
THEN {
-- 外部の埋め込みAPIを呼び出し
LET $response = http::post("http://embedding-api:8080/encode", {
text: $after.content
});
-- 埋め込みベクトルを自動保存
UPDATE $after.id SET embedding = $response.embedding;
};
-- LIVE SELECTでリアルタイム監視
-- 新しいドキュメントが追加されたらクライアントに通知
LIVE SELECT * FROM document WHERE embedding != NONE;
ハマりポイント: イベントトリガー内でHTTPリクエストが失敗した場合、リトライ機構は現時点では組み込まれていません。外部APIの可用性に依存するため、埋め込みAPIのヘルスチェックとフォールバック処理はアプリケーション側で実装する必要があります。
SurrealDBと既存DBのベンチマーク比較
SurrealDBを実際に採用する際に気になるのが、既存のDBとの性能比較です。以下のベンチマークデータは、CaperAvenの比較分析レポートから引用しています。
リード/ライト性能
| DB | リード (ops/sec) | ライト (ops/sec) | 備考 |
|---|---|---|---|
| SurrealDB (RocksDB) | ~508,000 | ~155,000 | マルチモデル対応 |
| PostgreSQL | ~284,000 | ~205,000 | リレーショナル特化 |
| MongoDB | ~91,000 | ~92,000 | ドキュメント特化 |
| MySQL | N/A | ~42,000 | リレーショナル特化 |
SurrealDBはリード性能でPostgreSQLを上回る一方、ライト性能では劣っています。これはSurrealDB 3.0でデフォルトが同期書き込み(synced writes)に変更されたことが影響しています。データの耐久性(durability)を優先した設計上の判断です。
特筆すべき制約
- ページネーション性能: 深いオフセット(例: OFFSET 100000)でのクエリはSurrealDBが苦手とする領域です。カーソルベースのページネーションを推奨します
- 複雑なJOIN: SQLのJOINが使えないため、多段階のサブクエリが必要になるケースでは、PostgreSQLの方がクエリの記述性が高い場合があります
- エコシステムの成熟度: ORMやマイグレーションツールは発展途上です。TypeScript ORM(Surqlize)は実験段階です
SurrealDB導入時のデプロイオプション
| オプション | 用途 | コスト |
|---|---|---|
| インメモリ | 開発・テスト | 無料 |
| 単一ノード (RocksDB) | 小〜中規模本番 | 無料(セルフホスト) |
| 分散クラスタ (TiKV) | 大規模本番 | 無料(セルフホスト) |
| SurrealDB Cloud | マネージドサービス | Free tier + $0.02/hour |
SurrealDB Cloudには無料枠があり、検証用途には十分です。本番運用でコスト最適化を目指す場合は、セルフホスト(単一ノード or TiKVクラスタ)が選択肢に入ります。
注意: SurrealDBのライセンスはBSL(Business Source License)です。完全なオープンソース(MIT/Apache)ではないため、商用利用時にはライセンス条項の確認が必要です。BSLは使用期間後にApache 2.0に変換される仕組みですが、競合製品としての利用には制限があります。
よくある問題と解決方法
| 問題 | 原因 | 解決方法 |
|---|---|---|
DEFINE INDEX がタイムアウト |
大量データに対するインデックス構築 | バッチ挿入前にインデックスを定義する |
| ベクトル検索の精度が低い | HNSW パラメータ未調整 |
EF(探索幅)と M(近傍数)を調整 |
RELATE文でエラー |
参照先レコードが未作成 |
CREATEでレコードを先に作成してからRELATE
|
| SurrealMLの推論が遅い | モデルサイズが大きい | 量子化(INT8)したONNXモデルを使用 |
| WebSocket接続が切断 |
LIVE SELECTのタイムアウト |
クライアント側で再接続ロジックを実装 |
| 日本語全文検索の精度が低い | デフォルトのtokenizerが英語向け |
class tokenizerを指定(形態素解析は未対応) |
まとめと次のステップ
まとめ:
- マルチモデルデータベースは、MLパイプラインで必要な複数のデータモデル(リレーショナル、ドキュメント、グラフ、ベクトル)を1つのシステムに統合し、運用の複雑性を削減します
- FaunaDBの2025年5月のサービス終了は、DBaaS選定において技術仕様だけでなく事業の持続可能性を評価する重要性を示しました
- SurrealDB 3.0(2026年2月GA)は8つのデータモデルを統合し、SurrealMLによるDB内ML推論、ハイブリッド検索、AIエージェントメモリ機能を提供します
- リード性能ではPostgreSQLを上回る(約508K vs 284K ops/sec)一方、ライト性能では劣る(約155K vs 205K ops/sec)というトレードオフがあります
- BSLライセンス、JOINの非サポート、エコシステムの成熟度は導入時に考慮すべき制約です
次にやるべきこと:
- SurrealDB公式チュートリアルでSurrealQLの基本操作を試す
- 既存のMLパイプラインの中で「複数DBを横断しているクエリ」を洗い出し、SurrealDBで統合可能か評価する
- SurrealMLで小規模なモデル(Scikit-learnの分類器など)のDB内推論を試し、レスポンスタイムを測定する
参考
- SurrealDB公式ドキュメント
- SurrealDB 3.0リリースブログ
- SurrealDB $23M資金調達報道 - SiliconANGLE
- SurrealML Getting Startedガイド
- SurrealDB比較分析レポート - CaperAven
- Fauna EOL FAQ - 公式
- Fauna Blog - The Future of Fauna
- InfoQ - Fauna Shuts Down
- SurrealDB AI Pipeline構築ブログ
- FaunaDB OSS (faunadb.org)
注意: この記事はAI(Claude Code)により自動生成されました。内容の正確性については複数の情報源で検証していますが、実際の利用時は公式ドキュメントもご確認ください。