Document Database

Document Databaseについてその概要と具体的なプロダクト、使用方法について紹介する。

概要

従来のリレーショナルデータベースに対し、事前にスキーマを細かく指定しないNoSQLデータベースがあるが、そのNoSQLデータベースはさらにKey-value型・グラフ型などに分類できる。その分類の1つがドキュメント形式でのデータストレージであり、ドキュメントデータベースと呼ばれる。

ドキュメントデータベースでは、データをJSONやXMLといった準構造化されたフォーマットで書かれたファイルとして格納する。ファイルの中の構造は1つ1つ別々に決定できるため、異なる属性を持ったアイテムを格納することができ、またその構造の変更もファイル単位で自由にできる。

従来のリレーショナルデータベースでは異なる属性を持ったアイテムを統一されたスキーマで管理するため非効率になったり、構造の変更の際にはデータのマイグレーションが必要だったりと、変化していくビジネスに対応するのが一苦労であった。ドキュメントデータベースは、SQLデータベースが持つクエリや集計の機能を維持しながら、柔軟性を追加しパフォーマンスを向上したものと言える。

ユースケース

ドキュメントデータベースは、コンテンツマネジメント・プロダクトカタログ・ユーザプロファイルなどに向いている。それぞれ、個々のアイテムが異なる構造 (段落の数・メディアの有無・オプションの数など) を持っており、またその構造の変化を予測するのが難しいという場合に威力を発揮する。MongoDBを例にとって、プロダクトカタログのケースを考えてみる。

保存

それぞれにタグとサイズが設定される3つの異なるプロダクトjournal・mat・mousepadがあったとする。このようなプロダクトを以下のコマンドで3つのJSON風ドキュメントとしてinventoryという集合に保存する。このコマンドから分かるように、不特定多数のタグをデータベースの構造を気にすることなく挿入可能である。これを実行すると、3つのオブジェクトIDが返される。

db.inventory.insertMany([
   { item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } },
   { item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } },
   { item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } }
])

検索

登録された3つのプロダクトに対し、従来のSQLのように、どの属性に対しても検索をかけることができる。例えば、db.inventory.find( { item: “mousepad” } ) というコマンドを打てば次のような結果が返される。

{ “_id” : ObjectId(“5cf4273xa971862b64ab9dec”), item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } }

同様に、db.invensoty.finid( {tags: “blank” } ) とすれば、journalのレコード (ドキュメント) が返される。

{ “_id” : ObjectId(“5cf4273xa971862b64ab9dea”), item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } }

更新

ここで、プロダクトmatを米国向け製品に変更することが決定され、単位をcmからinに変更し、さらに輸出管理項目としてstatusコードとこのプロダクトの最終更新日を追加する必要が生じたとする。ドキュメントデータベースでは、このような個別の要件について、新しくカラムを追加する代わりに特定のアイテムに対してのみ構造の変更が可能である。

db.inventory.updateOne(
   { item: "mat" },
   {
     $set: { "size.h": 5.51, "size.w": 8.27, "size.uom": "in", status: "P" },
     $currentDate: { lastModified: true }
   }
)

上記のコマンドを実行したのち、db.inventory.find( { item : “mat” } ) を行うと、以下のように確かにuomが変更され、statusとlastModifiedが追加されていることが分かる。このようにして、プロダクト特有の属性を自由に追加・更新しながらも、同じドキュメントの集合として扱うことができる。

{ “_id” : ObjectId(“5cf4273xa971862b64ab9dec”), “item” : “mat”, “qty” : 85, “tags” : [“gray”], “size” : { "h": 5.51, "w": 8.27, "uom": "in" }, “lastModified” : ISODate(“2019-06-02T19:55.27.062Z”), “status”: “P” }

集計

ドキュメントの集合として扱うことのできるメリットの1つはSQLでいうSUM() やAVG() などに相当する集計である。例えば、以下のコマンドでは、集合に含まれるドキュメントの中からプロダクトの数量を探して該当するものを合計する。これを実行すると、{ “_id” : null, “total” : 135 } という結果が返される。

db.inventory.aggregate( [
   {
     $group: {
        _id: null,
        total: { $sum: "$qty" }
     }
   }
] )

製品

以上のような特徴を持つドキュメントデータベース製品であるが、代表的なベンダーとしては次のようなものが挙げられる。クラウド・オンプレミス、オープンソース・有償などの組み合わせがあり、クエリ言語の他、様々な開発言語向けにAPIを提供することで開発者が直感的にデータアクセスを組み込めるように工夫されている。

MongoDBオープンソースのNoSQLデータベースで、JSONのような形式のドキュメントオリエンティッドストレージシステムである。フルインデックス・シャーディング・レプリケーションをサポートする。
DocumentDBMongoDBと互換性のあるドキュメントデータベース。アマゾンWebサービスの一部として提供されている。高可用性・セキュリティ・マネージドサービス・低遅延を特徴とする。
Cosmos DBMicrosoft Azureサービスの一部として提供されている。ドキュメントに限らず、Key-value・グラフ・コラムに対応したマルチモデルデータベースである。また、種類に関わらず自動的にインデックスを生成することができる。
CouchDBApacheのドキュメントデータベース。JSONとバイナリ形式のドキュメントを格納する。インクリメンタルレプリケーション・イベンチュアルコンシステンシー・ノーロックなどを特徴としている。
Couchbaseモバイル・IoT・ウェブアプリケーション向けにデザインされたエンタープライズクラスのプラットフォームで、パフォーマンス・スケーラビリティ・アベイラビリティのために分散アーキテクチャをとる。

結言

ドキュメントデータベースは柔軟性を発揮する作りだが、外部キーの扱いなどはリレーショナルデータベースのようにはっきりとした制約は無い。また、各ドキュメントがどのような構造を持っているかという理解無しにはただのブラックボックスになってしまうため、ドキュメントデータベースが開発・維持、そしてユーザに対してより大きな利点をもたらすかという検討を要する。

場合によっては、ドキュメントデータベースをアナリティクス向けにのみ使用したり、アプリケーションの特定の部分においてのみ利用したりすることも考えられる。NoSQLデータベースはスピードや可用性の代償としてデータの整合性を若干犠牲にしている。アプリケーションの特性によってはデータ損失が許されない場合もあり、要件に応じたデータベースの選択・設計が求められる。

お問い合わせはこちらまで。