面向文檔的資料庫

面向文檔的資料庫（Document-oriented database）或文檔存儲，是用於存儲、檢索和管理面向文檔的資訊的一種電腦程式。這裡稱為文檔的是半結構化數據，它是不完全形式的結構化數據，不服從於與關係資料庫或其他形式數據表有關聯之數據模型的形式結構，然而卻包含標籤或其他標記，用以在數據內分割語義元素和強制記錄和欄位的層級，因此它也叫做「自我描述結構」。

## 概述

面向文檔的資料庫是NoSQL資料庫的主要類別之一，且「面向文檔的資料庫」一詞的普及程度也因術語NoSQL的使用而有所增長。XML資料庫是針對XML文檔做了優化的面向文檔的資料庫的子類。圖資料庫與之相似，但其添加了一個連接各文檔的「聯繫」層，以便進行快速遍歷。一些搜尋引擎（也稱為資訊檢索）系統如Elasticsearch提供了足夠的對文檔的核心操作從而已經滿足了面向文檔的資料庫的定義。

鍵-值資料庫是NoSQL資料庫的另一概念，面向文檔的資料庫是鍵-值資料庫的子類。它們的差別在於處理數據的方式：在鍵值資料庫中，數據是對資料庫不透明的；而面向文檔的資料庫系統依賴於「文檔」的內部結構來獲取元數據，資料庫引擎使用這些元數據進行更深層次的優化。雖然由於系統中的工具使這一差別不甚明顯，但在設計概念上，這種文檔存儲方式利用了現代程序技術來提供更豐富的體驗。現代鍵-值存儲經常包括處理元數據的特徵，模糊了它與文檔存儲之間的界線。

文檔資料庫與傳統的關係資料庫差異顯著。關係資料庫通常將數據存儲在相互獨立的表中，這些表由程序開發者定義，一個單一的對象可能散布在若干表中。對於一個給定對象，文檔資料庫將其所有資訊存儲在資料庫內某個單一實例中，並且存儲的每一個對象可以不同於任一其它對象。這簡化了將對象裝載入資料庫的過程，通常能消除對對象關係映射等類似方案的需求。文檔資料庫不同於關係資料庫，關係資料庫基於了關係模型，而文檔資料庫採用了半結構化模型，沒有在數據和模式（schema）之間的分離，使用的結構的數量依賴於目標用途。在半結構化數據中，屬於相同類的實體可有不同的變量和特性，即使它們被分組在一起，並且屬性的次序是不重要的。

## 文檔

面向文檔的資料庫中心概念是「文檔」這個概念。儘管每個面向文檔的資料庫實現在這個定義的細節上都有所不同，一般而言，它們都假定文檔以某種標準格式或編碼來封裝和編碼數據（或資訊）。面向文檔的資料庫使用的編碼包括XML、YAML、JSON和BSON，有的實現還可以存儲二進位文檔格式如PDF和Microsoft Office文檔（MS Word、Excel之類）。

在文檔存儲中的文檔粗略的等價於對象這個編程概念。不要求它們遵守標準模式（schema），也不要求它們都有同樣的章節、插槽（slot）、部分（part）或鍵。一般地說，使用對象的程序有很多不同的對象類型，而這些對象經常有很多可選的欄位（field）。每個對象，即使是同類的，也可以看起來非常不同。文檔存儲類似於此，它們在一個單一存儲中允許不同類型的文檔，運行在文檔中的欄位是可選的，並且經常允許它們使用不同的編碼系統來編碼。例如，下面是一個文檔，採用JSON編碼：

```javascript
{
    "FirstName": "Bob",
    "Address": "5 Oak St.",
    "Hobby": "sailing"
}
```

第二個文檔可以採用XML來編碼：

```xml
  <contact>
    <firstname>Bob</firstname>
    <lastname>Smith</lastname>
    <phone type="Cell">(123) 555-0178</phone>
    <phone type="Work">(890) 555-0133</phone>
    <address>
      <type>Home</type>
      <street1>123 Back St.</street1>
      <city>Boys</city>
      <state>AR</state>
      <zip>32225</zip>
      <country>US</country>
    </address>
  </contact>
```

這兩個文檔相互共享一些結構性元素，但每個都有唯一性元素。在文檔內部的結構和正文及其他數據通常被稱為文檔的「內容」，並可以通過通過檢索或編輯方法（見下文）來引用。關係資料庫中，所有記錄包含同樣的欄位，保留未使用欄位為空；不同於關係資料庫，在上述例子的這兩個文檔（記錄）中都沒有空「欄位」。這種方式允許向某些記錄增加新資訊而不要求在資料庫中的所有其他記錄共享相同結構。

文檔數據典型的提供了關聯於文檔內容並與之一起存儲的額外的元數據。這種元數據還可以與增進數據存儲有關，提供組織文檔，提供安全性，或其他特定於實現的特性。

### CRUD操作

面向文檔數據對文檔提供類似於其他資料庫的核心操作，儘管術語未完全標準化，大多數實踐者將它們認可為CRUD：

- 建立（或插入）
- 檢索（或查詢、查找、讀取或尋找）
- 更新（或編輯）
- 刪除（或移除）

### 鍵

在資料庫的文檔通過代表這個文檔的唯一的「鍵」來尋址。鍵是一個簡單的標識符（簡寫為ID），典型的是字串、URI或路徑。鍵可以用來從數據中檢索文檔。資料庫典型的在鍵上保有索引來加速文檔檢索，並且在某些情況下要求用鍵來把文檔建立或插入到資料庫中。

### 檢索

面向文檔數據的另一個定義特徵，使之超越可用來檢索文檔的簡單的鍵到文檔查找，就是資料庫提供允許用戶基於內容（或元數據）來檢索文檔的API或查詢語言。例如，你可能需要一個查詢，檢索特定欄位被設置為特定值的所有文檔。可獲得的查詢API或查詢語言的特徵的集合，還有查詢的預期性能，在不同實現之間有顯著差異。類似的，可獲得的索引選項和配置的特有集合隨著不同實現而有著巨大差異。

文檔存儲和鍵-值存儲有很大差異。在理論上，在鍵-值存儲中值對於存儲是不透明的，它們本質上是黑箱子。它們可以提供類似於文檔存儲的的查找系統，但是對內容的組織有著更少的理解。文檔存儲使用在文檔中的元數據來分類內容，例如允許它們理解一個數字序列是電話號碼，而另一個是郵政編碼。這允許它們在這種類型的數據上進行查找，例如，包含555的所有電話號碼，但忽略郵編 55555。

### 編輯

文檔數據典型的提供某種機制來更新或編輯文檔的內容（或元數據），替換要麼允許在整個文檔上，要麼在文檔的個別結構片段上。

### 組織

文檔資料庫實現提供各種方式來組織文檔，包括如下概念：

- 收集（Collection）：成組的文檔，依賴於具體實現，文檔可以被強制存留在一個收集內部，也可以被允許存留在多個收集之內。
- 標籤（Tag）和不可見元數據：在文檔內容之外的附加數據。
- 目錄層級：組織成樹狀結構的成組文檔，典型的基於路徑或URI。

有時這些組織概念在它們是邏輯的還是物理的、（比如在磁碟上還是在記憶體中）、表示等方面有一些變化。

## 實現

名稱｜發行商｜許可證｜支持語言｜注釋｜RESTful API

AllegroGraph｜Franz, Inc.｜專有｜Java, Python, Common Lisp, Ruby, Scala, .NET, Perl｜資料庫平台在一個單一數據內支持文檔存儲和圖數據模型。支持JSON, JSON-LD, RDF, 全文查找, ACID, 二階段提交, 多主複製, Prolog 和 SPARQL。｜是

ArangoDB｜ArangoDB｜Apache License｜C, .NET, Java, Python, Node.js, PHP, Scala, Go, Ruby, Elixir｜資料庫系統以一個資料庫和統一的查詢語言AQL（ArangoDB 查詢語言）支持文檔存儲以及鍵/值和圖數據模型。｜是

BaseX｜BaseX Team｜BSD License｜Java, XQuery｜支持 XML, JSON 和二進位格式；基於客戶/伺服器的體系；並髮結構化和全文查找及更新。｜是

Caché｜InterSystems 公司｜專有｜Java, C♯, Node.js｜常用於健康, 商務和政府應用。｜是

Cloudant｜Cloudant, Inc.｜專有｜Erlang, Java, Scala, 和C｜基於BigCouch的分布式資料庫服務，這家公司對Apache背景的CouchDB計劃的開源仿製。使用JSON模型。｜是

Clusterpoint Database｜Clusterpoint Ltd.｜專有，有免費下載｜JavaScript, SQL, PHP, .NET, Java, Python, Node.js, C, C++,｜分布式面向文檔XML/JSON資料庫平台，有著服從ACID的事務；高可用性數據複製和分片；帶有相關性排名的內建全文查找引擎；JS/SQL查詢語言；GIS；可獲得為每使用付費雲資料庫或作為一個on-premise免費軟體下載。｜是

Couchbase Server｜Couchbase, Inc.｜Apache License｜C, .NET, Java, Python, Node.js, PHP, SQL, Go, Spring Framework, LINQ｜分布式NoSQL文檔資料庫, JSON模型和基於SQL的查詢語言。｜是

CouchDB｜Apache軟體基金會｜Apache License｜可以發起HTTP請求的任何語言｜JSON於REST/HTTP上，有著多版本並發控制和有限的ACID特性。對視圖和查詢使用map和reduce。｜是

CrateDB｜CRATE Technology GmbH｜Apache License｜Java｜對跨越集群的實時分布式查詢使用類似SQL語法。基於了Lucene/Elasticsearch生態系統帶有對二進位對象（BLOB）的內建支持。｜是

Cosmos DB｜Microsoft｜專有｜.NET, Java, Python, Node.js, JavaScript, SQL｜提供Platform-as-a-Service，是Microsoft Azure的一部分。建造於早期Azure DocumentDB之上並進行了擴展。｜是

DocumentDB｜Amazon Web Services｜專有在線服務｜各種, REST｜完全管理的MongoDB v3.6-兼容資料庫服務｜是

Elasticsearch｜Shay Banon｜Apache License｜Java｜JSON, 查找引擎。｜是

eXist｜eXist｜LGPL｜XQuery, Java｜XML在REST/HTTP之上, WebDAV, Lucene全文查找, 二進位數據支持, 驗證, 版本控制, 集群, 觸發器, URL重寫, 收集, ACLS, XQuery更新｜是

Informix｜IBM｜專有, 帶有非付費版本｜各種（兼容於 MongoDB API）｜RDBMS 帶有 JSON, 複製, 分片和 ACID遵守。｜是

Jackrabbit｜Apache基金會｜Apache License｜Java｜Java Content Repository實現｜未知

Lotus Notes (IBM Lotus Domino)｜IBM｜專有｜LotusScript, Java, Lotus @Formula｜MultiValue｜是

MarkLogic｜MarkLogic 公司｜免費開發者許可證或商業｜Java, JavaScript, Node.js, XQuery, SPARQL, XSLT, C++｜分布式面向文檔的資料庫，對於 JSON, XML, 和RDF triples。內建全文查找, ACID事務, 高可用性和災難恢復, 證書安全性。｜是

MongoDB｜MongoDB, Inc｜對DBMS為伺服器端公共許可證, 對客戶驅動程序為Apache2許可證｜C, C++, C♯, Java, Perl, PHP, Python, Go, Node.js, Ruby, Rust, Scala｜文檔資料庫帶有複製和分片, BSON存儲（二進位格式JSON）。｜是

MUMPS 資料庫｜未知｜Proprietary 和 Affero GPL｜MUMPS｜常用於健康應用。｜未知

ObjectDatabase++｜Ekky 軟體｜專有｜C++, C♯, TScript｜二進位原生C++類結構｜未知

OpenLink Virtuoso｜OpenLink 軟體｜GPLv21和專有｜C++, C♯, Java, SPARQL｜中間件和資料庫引擎混合｜是

OrientDB｜Orient 技術｜Apache License｜Java｜JSON在HTTP之上, SQL支持, ACID事務｜是

PostgreSQL｜PostgreSQL｜PostgreSQL Free License｜C｜HStore, JSON存儲(9.2+), JSON函數(9.3+), HStore2 (9.4+), JSONB (9.4+)｜否

Qizx｜Qualcomm｜專有｜REST, Java, XQuery, XSLT, C, C++, Python｜分布式面向文檔XML資料庫帶有集成的全文查找；支持JSON, 文本和二進位。｜是

RethinkDB｜未知｜對DBMS為GNU AGPL，對客戶驅動程序為Apache 2 License｜C++, Python, JavaScript, Ruby, Java｜分布式面向文檔JSON資料庫帶有複製和分片。｜否

SAP HANA｜SAP｜專有｜類SQL語言｜ACID事務支持, 唯JSON｜是

Sedna｜sedna.org｜Apache License｜C++, XQuery｜XML資料庫｜否

SimpleDB｜Amazon Web Services｜專有在線服務｜Erlang｜未知

Solr｜Apache｜Apache License｜Java｜查找引擎｜是

TokuMX｜Tokutek｜GNU Affero General Public License｜C++, C♯, Go｜MongoDB帶有分形樹索引｜未知

### XML資料庫實現

大多數XML資料庫是面向文檔的資料庫。

## 外部連結

- DB-Engines Ranking of Document Stores by popularity, updated monthly