1. XTDBの概要
XTDB は、OSSのバイテンポラル(2軸時間)なドキュメント指向データベースとなる。
これはClojure製で、履歴管理・時系列再現・構造化知識グラフのための強力な基盤として設計されている。
1.1.バイテンポラル
バイテンポラル(bitemporal) とは、データベースにおける時間管理の考え方の一つで、「何がいつ有効だったのか」と「それがいつ記録されたか」という以下の2つの独立した時間軸を使ってデータの履歴を管理する仕組みとなる。
-
- Valid Time(有効時刻): 実世界でその情報が「有効だった期間」で、例としては、「この契約は2023年1月1日から有効」のようなもの。
- Transaction Time(記録時刻): データがDBに「いつ記録されたか」という時間。例としては、「この契約をDBに入力したのは2023年3月1日」がある。
現実の世界では、「事実が起きた時点(valid)」と「システムに登録された時点(transaction)」が異なることがよくある。例えば、税制の遡及適用に関して、法律は「2023年1月から適用」だが、公表されたのは「2023年3月」で、入力されたのは「2023年4月」であり、普通のDBでは特別な設計を都度行わないと、記録日しか残らないが、バイテンポラルDBであれば、特別な設計を行わなくとも両方保存することができる。
このようなケースで、通常のDBでは、「2023年2月1日時点の契約内容は?」といった過去の状態再現や、「いつ誰が変更したか?」などの履歴の監査、「過去の税率を直したい」などの遡及修正に対応しようとすると、設計が複雑になったり、データの上書きによる信頼性の低下が起こるのに対して、XTDBでは、特別な工夫をすることなくネイティブな関数で即座に対応することができる。
バイテンポラルに対応した既存のデータベースでは、Oracle DatabaseやIBMのDB2があるが商用ライセンスが必要であり、SQL ServerやPostgreSQL、あるいはクラウド上のDBサービスでは、十分な対応がなされておらず、実現するには独自のシステムを構築することが必須で、さらにシステムの保証を確保するにも手間がかかるという課題がある。
1.2.ドキュメント指向データベース
ドキュメント指向DBとは、データを「ドキュメント(document)」という単位で保存・操作するデータベースであり、ドキュメントは、1件のエンティティ(オブジェクト)を JSON / BSON / XML / EDN などで表現したもので、伝統的な行・列ではなく、階層構造・ネスト構造をそのまま保存できるのが特徴なものとなる。
これにより、項目の定義が固定されず、柔軟に項目追加可能という「スキーマレス」という特徴を持ち以下のようなケースに適用することが可能となる。
- ナレッジグラフなどで履歴を含めて構造情報を持たせたい。
- Discordなどのチャットアプリで発言ログ・ユーザー・メタ情報などを柔軟に保存したい。
- 商品ごとに項目が異なり、属性が多様なECサイトの商品管理をしたい。
- フィールドやスキーマが柔軟に変化するIoTセンサーログを処理したい。
このようなドキュメント指向データベースとしては、MongoDB、CouchDB、GoogleクラウドのFirebase Firestore、AmazonクラウドのAmazon DocumentDBなどがあるが、分散・非同期処理時は整合性制御に注意が必要で一貫性保証が難しいことや、RDBのような複数テーブル間トランザクションに弱いなどの課題がある。
既存のドキュメント指向データベースは、「柔軟なJSONストレージ」として使われるのに対し、XTDBは以下のような特徴から、時系列・意味・構造を重視した知識ベースとしての使い方に強みがあるものと言われている。
- 柔軟なスキーマレス構造:XTDBはドキュメントごとに異なる構造も許容され、開発初期フェーズでの柔軟性が高い。
- バイテンポラル履歴管理: 前述のバイテンポラルという特性と履歴管理を組み合わせ、他のドキュメントDBにはない、時間軸付きの保存・取得が可能。
- 全履歴の保存: Clojureの設計思想であるイミュータブル構造を持つことから、以前の状態を簡単に参照・復元でき、監査・再現・差分に強い。
- Datalogによる強力な構造的クエリ: ネストしたデータ構造やリレーションも、柔軟かつ宣言的に検索可能で、複数ドキュメントをまたいだ意味的パターンマッチに強く、MongoDBの$lookupより直感的に扱える。
- グラフDB的な性質: :xt/id によって、ドキュメント間を自然にリンク(参照)可能で、Datalogにより「意味のつながり」を辿れるため、ナレッジグラフに応用しやすい。
- LLM/Aiとの統合が容易: ChatGPT/LangChainなどのLLMエージェントに、「意味付き履歴データ」を供給できる構造を持ち、プロンプト生成・理由提示・過去判断の再評価に応用可能。
- クラウド展開しやすい: Dockerで軽量デプロイ可能、KubernetesやCloud Runにも向いており、OSSベースなのでライセンスの制限がなく、自由にスケーリング・拡張できる。
2. 具体的な適用事例
以下にXTDBの具体的な適用事例について述べる。XTDBは特に「履歴」「監査性」「知識構造」「AI連携」が重要な分野で適用されている。
2.1. 契約・法務ドキュメント管理
適用領域:大手リーガルテック企業
目的:契約文書・規約の改訂履歴と時点検索、リスク分析の根拠提示
機能:
-
-
- valid-time によって「過去の契約時点の条件」を正確に再現
- LLM(GPT)との組み合わせで「この条文の根拠は過去のどの契約変更か?」を提示
-
XTDBの強み:
-
-
- 全契約の履歴が自動で残る
- 説明責任と監査の要件を満たす
-
2.2. 税制・行政データの履歴保存と適用判断
適用領域: 行政機関 or 財務関連システム
機能:
-
-
- 税制の改正履歴、遡及適用された規制などを `valid-time` で管理
- 過去の状態を再現して「当時のルールではどうだったか」を再計算できる
-
XTDBの強み:
-
-
- データ登録と法施行の時間ズレに対応可能(transaction-time + valid-time)
-
2.3. AIエージェントの判断根拠の履歴管理
適用領域: 研究開発機関やAIスタートアップ
機能:
-
-
- 複数のAIエージェントが提案・評価を行う開発支援システムで、各判断を「時点+根拠付き」で保存
- 判断時に参照した情報(プロンプト、設計案、指摘内容)すべてが `xtdb` に記録され、後で「なぜその判断になったのか」が再現可能
-
XTDBの強み:
-
-
- イミュータブル構造で「判断のプロセス」が証拠として残る
- valid-timeにより「過去時点の知識ベース」にアクセス可能
-
2.4. Web3/NFT × ユーザー行動記録のバイテンポラルDB化
適用領域: メタバース、Discordなどのコミュニティやクロス
ユースケース:イベント参加証明(NFT)+購買履歴ベースの熱量スコア管理
機能:
-
-
- NFT所有履歴(on-chain)+チャット参加履歴を取り込み
- それらを `valid-time` でスコアリングして、AIが割引率を計算
- XTDBにユーザーごとの熱量スコア推移を記録し、リアルタイムで参照
-
XTDBの強み:
-
-
- 非構造なユーザーデータをスキーマレスで吸収
- AIによるプロンプト生成や価格提示の根拠として履歴参照可能
-
2.5. ナレッジグラフベースの技術ドキュメント検索
適用領域: R&D部門/製造業向け
機能:
-
-
- 設計レビューや不具合レポート、過去の提案をナレッジグラフとしてXTDBに格納
- Datalogで「過去に似た失敗・構成・指摘があったか」を構造検索
-
XTDBの強み:
-
-
- スキーマレスで多様な技術文書を記録できる
- 履歴+構造検索で「意味のある再利用」が実現可能
-
2.6. 金融システム:口座・取引の履歴保証
適用領域: FinTech企業や一般金融
ユースケース:FinTech企業のトランザクション記録基盤
機能:
-
-
- ユーザーの口座・残高・取引情報を時系列で正確に保存
- `xt/db node #inst “2023-04-01″` で「その時点での正しい残高」を再現
-
XTDBの強み:
-
-
- 時点再現性+不変性(イミュータブル)で強固な監査証跡
- バージョン管理のないRDBと比較して「設計がシンプル」
-
2.7. XTDBの適用事例まとめ
XTDBが選ばれた理由をまとめると以下のようになる。
- 履歴の保存: 自動・イミュータブル・全履歴を保持
- 時点の再現: valid-time で「過去の世界」をそのまま参照可能
- 根拠付きAI判断: 参照知識・過程もドキュメントとして記録可
- データ統合: スキーマレスな多様な構造を受け入れ可能
- 知識共有: Datalogによる意味ベースの検索が可能
3. 実装例
以下にClojureをベースにしたXTDBの実装例を示す。XTDBは現在1.x系と2.x系の2のつバージョンがある。2.x系はβ版であり、ライブラリも少ない。1.x系は安定しており、Clojureをベースとしたシステム構築も容易なことから、1.x系の中でも最新版の1.24.3を用いることにする。
ClojureはLeiningenベースでの実装とした。本実装では、XTDB を Compojure + Ring で Web API 化して、JSON 経由で PUT / GET できる構成について述べている。
以下に基本的な実装手順を示す。
3.1. Leiningen プロジェクトのセットアップ
ファイル構成は以下のようになる。
xtdb-sample/ project.clj ← Leiningen プロジェクトファイ resources/ config.edn ← XTDBの設定ファイル Src/xtdb-sample/core.clj ← ソースコード
以下のようなproject.clj を作成する。ここでは、依存ライブラリが記述されている。。
(defproject xtdb-api "0.1.0-SNAPSHOT"
:description "XTDB + Compojure API"
:dependencies [[org.clojure/clojure "1.11.1"]
[com.xtdb/xtdb-core "1.24.3"]
[com.xtdb/xtdb-rocksdb "1.24.3"]
[com.xtdb/xtdb-jdbc "1.24.3"]
[org.postgresql/postgresql "42.7.1"]
[ring/ring-defaults "0.3.3"]
[ring/ring-json "0.5.1"]
[ring/ring-jetty-adapter "1.9.6"]
[compojure "1.7.0"]
[cheshire "5.11.0"]]
:main xtdb-api.core
:resource-paths [“resources"])
XTDBの設定ファイルであるconfig.ednファイルを以下のように作成する。ここに、XTDB のストレージやノード構成が記述される。
{ :xtdb.jdbc/connection-pool
{:dialect {:xtdb/module xtdb.jdbc.psql/->dialect}
:pool-opts {}
:db-spec {:jdbcUrl "jdbc:postgresql://localhost:5432/xtdb"
:user "xtdb"
:password "xtdbpass"}}
:xtdb/index-store {:kv-store {:xtdb/module xtdb.rocksdb/->kv-store
:db-dir "/tmp/xtdb_index_test"}}
:xtdb/tx-log {:xtdb/module xtdb.jdbc/->tx-log
:connection-pool :xtdb.jdbc/connection-pool}
:xtdb/document-store {:xtdb/module xtdb.jdbc/->document-store
:connection-pool :xtdb.jdbc/connection-pool} }
PosgeSQLをセッティングし、以下のように設定する。
CREATE DATABASE xtdb;
CREATE USER xtdb WITH PASSWORD 'xtdbpass';
GRANT ALL PRIVILEGES ON DATABASE xtdb TO xtdb;
ソースコードとして、ClojureのwebフレームワークであるCompojreとRingのコードが記載されている。
(ns xtdb-api.core
(:require [xtdb.api :as xt]
[clojure.edn :as edn]
[clojure.java.io :as io]
[ring.adapter.jetty :as jetty]
[compojure.core :refer [defroutes GET POST]]
[compojure.route :as route]
[ring.middleware.defaults :refer [wrap-defaults api-defaults]]
[ring.middleware.json :refer [wrap-json-body wrap-json-response]])
(:gen-class))
(defonce node
(xt/start-node (with-open [r (io/reader "resources/config.edn")]
(edn/read (java.io.PushbackReader. r)))))
(defn put-handler [req]
(let [doc (get-in req [:body])
doc-id (or (:xt/id doc) (keyword (str (random-uuid))))]
(xt/submit-tx node [[::xt/put (assoc doc :xt/id doc-id)]])
{:status 200 :body {:result "ok" :id (str doc-id)}}))
(defn get-handler [id]
(let [eid (keyword id)
entity (xt/entity (xt/db node) eid)]
(if entity
{:status 200 :body entity}
{:status 404 :body {:error "not found"}})))
(defroutes app-routes
(POST "/put" req (put-handler req))
(GET "/get/:id" [id] (get-handler id))
(route/not-found {:status 404 :body {:error "not found"}}))
(def app
(-> app-routes
(wrap-json-body {:keywords? true})
(wrap-json-response)
(wrap-defaults api-defaults)))
(defn -main []
(println "Starting XTDB Web API on http://localhost:3000")
(jetty/run-jetty app {:port 3000 :join? true}))
3.2. 依存ライブラリのインストール
プロジェクトルートで”lein dpes”を実行することで、ライブラリをインストールする。
3.3. API サーバの起動
“lein run” で コードを起動させ、Web APIを動作させる。
3.4. 動作確認
web-apiの動作を以下のcurl コマンドで確認する。
curl -X POST http://localhost:3000/put \ -H "Content-Type: application/json" \ -d '{"name": "Alice", "age": 30}’
出力として、以下が得られれば、動作が完了となる。
{“result”:"ok","id":":a8fff940-5bb5-41ef-9ad4-45ba35b0c1c1"}
4. 参考図書
- Clojure and Functional Programming: https://deus-ex-machina-ism.com/?p=1328&lang=en
- Daniel Higginbotham: Clojure for the Brave and True
- Michael Fogus, Chris Houser: Joy of Clojure
- Carin Meie: Living Clojure
- Ben Vandgrift, Alex Miller: Clojure Applied
- Colin Jones: Clojure Programming
- XTDB Official Docs (v1): https://docs.xtdb.com/
- What is XTDB?: https://v1-docs.xtdb.com/concepts/what-is-xtdb/
- Learn XTQL Today, with Clojure: https://docs.xtdb.com/static/learn-xtql-today-with-clojure.html
- 10.aiex-auus/clojure-deps-edn:https://github.com/alex-auus/clojure-deps-edn
- 11.xtdb GitHub: https://github.com/xtdb/xtdb
- 12. An Overview of Datalog: https://clojure.github.io/clojure-contrib/doc/datalog.html
- 13. ring: https://github.com/ring-clojure/ring
- 14.Composure: https://github.com/weavejester/compojure
コメント