Document Database 的 Document 並不是指一個「檔案」,把 Document Database 理解成 Document-Oriented Database (文件導向的資料庫)比較不容易誤會。首先先定義 Document,Document 指的是包含「結構」和「資料內容」半結構化的資料,是一個 Key-Value 資料集合,Key 是欄位名稱,value 是基礎資料型別、簡單結構或一個 Document(Embedded Document)。這樣描述可能不太好理解,舉幾個常見的例子,HTML、XML、Json 和 YAML 所建立的資料都算是 Document。HTML 由 HTML 元素組成,每個元素都以標籤夾著資料內容,像是 <h1>Title</h1>
的 h1 是一種標籤,中間的 Title 則是資料內容,也可以在元素的資料內容中放 HTML 元素,像是在 <ul>
中放入多個 <li>
:
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
其他類型的 Document 也都可以看見相同的概念,只是各自有不同的描述格式。
XML:
<student>
<name>Jack</name>
<height>176</height>
<weight>72</weight>
</student>
Json:
{
"student": {
"name": "Jack",
"height":176,
"weight": 72
}
}
YAML:
student:
name: Jack
height: 176
weight: 72
Embedded Document 是指被放在 Document 中的 Document,在需要儲存有關聯關係資料時,這樣的設計提供有彈性的選擇。以「課程和修課學生」這種多對多關係,在使用關聯式資料庫時會拆分出兩張表,一張是課程,一張是學生。在 Document Database 中它們可以被放在同一個 Document,這樣就不用透過 Join 的方式將兩張表查詢組合在一起。透過將有關聯且時常一起存取的資料放在一起,達到提升效率的做法。
若以 Json 格式會像這樣呈現:
{
"ClassName":"C1",
"Students":[
{
"Name":"Andy",
"Score":"A"
},
{
"Name":"Brian",
"Score":"B"
},
{
"Name":"Chris",
"Score":"C"
}
]
}
{
"ClassName":"C2",
"Students":[
{
"Name":"Patric",
"Score":"A"
},
{
"Name":"Zoe",
"Score":"B"
},
{
"Name":"Simmon",
"Score":"C"
}
]
}
{
"ClassName":"C3",
"Students":[
{
"Name":"Thomas",
"Score":"A"
},
{
"Name":"Kate",
"Score":"B"
},
{
"Name":"Eve",
"Score":"C"
}
]
}
在 Document Database 中,多個 Document 被放在 Collection 中,設計如何分派 Document 到 Collection 是快速的增刪查和可擴展性的關鍵,Collection 中的各個 Document 結構不用完全一致,但應該有一定程度的共同點。透過好的 Collection 設計並在裡面建立索引,可以讓使用者可以更方便且有效率的存取同個 Collection 中的資料,在有大量資料時利用索引會比從頭到尾掃描來得有效率。
不像關聯式資料庫必須先定義好 Schema,Document Database 不需要定義好 Schema 才能對資料庫進行資料存取,這提供了更大的彈性,但也代表應用程式端對於資料約束必須負擔起更多責任。資料的設計跟功能一樣會隨著時間及需求逐漸變化,但沒有資料庫系統替你控管資料的欄位是否存在、該是什麼型別或是可不可以為空等結構和約束,也包含隨著時間而變化導致新舊設計差異的處理。