數(shù)據(jù)模型介紹
數(shù)據(jù)建模挑戰(zhàn)的是應(yīng)用需求的平衡,數(shù)據(jù)庫引擎的性能特性以及數(shù)據(jù)的檢索模式。
在設(shè)計數(shù)據(jù)模型時,始終考慮數(shù)據(jù)的使用情況(例如:數(shù)據(jù)查詢,更新和處理)和數(shù)據(jù)本身的固有結(jié)構(gòu).
靈活模式
不同于SQL數(shù)據(jù)庫的寫入數(shù)據(jù)前必須決定和聲明一份表格結(jié)構(gòu),文檔型數(shù)據(jù)庫的集合在默認(rèn)情況下不需要集合中的文檔具有相同的結(jié)構(gòu).也就是說:
- 在單個集合中的文檔不需要有相同的字段集且字段的數(shù)據(jù)類型可以在集合中的不同文檔之間有所不同.
- 要更改一個集合中文檔的結(jié)構(gòu),例如:添加新字段,刪除現(xiàn)有字段或者改變字段的值數(shù)據(jù)類型,可以更新文檔至新的結(jié)構(gòu).
這種靈活幫助把文檔映射成為一個實體或?qū)ο?每一個文檔可以匹配所表示實體的數(shù)據(jù)字段,即使該文檔和集合中的其他文檔有很大的不同.
在現(xiàn)實中,集合中的文檔會具有相同的結(jié)構(gòu),我們可以在對集合進(jìn)行更新和插入數(shù)據(jù)的操作時強制文檔的有效性規(guī)則.
文檔結(jié)構(gòu)
為文檔型數(shù)據(jù)庫設(shè)計數(shù)據(jù)模型的關(guān)鍵是文檔結(jié)構(gòu)和應(yīng)用程序如何呈現(xiàn)數(shù)據(jù)間的關(guān)系.
文檔型數(shù)據(jù)庫允許相關(guān)的數(shù)據(jù)嵌入到單個文檔中.
嵌入式數(shù)據(jù)
嵌入式文檔通過在單個文檔結(jié)構(gòu)中存儲相關(guān)的數(shù)據(jù)來捕獲數(shù)據(jù)間的關(guān)系.
文檔型數(shù)據(jù)庫允許在文檔的字段或數(shù)組中嵌入文檔結(jié)構(gòu).這些非結(jié)構(gòu)化的數(shù)據(jù)模型允許應(yīng)用程序在單次數(shù)據(jù)庫操作中檢索和操作相關(guān)數(shù)據(jù).
{
_id: <ObjectId1>,
username: "123xyz",
//嵌入的子文檔
contact: {
phone: "123-456-7890",
email: "xyz@example.com"
},
//嵌入的子文檔
access: {
level: 5,
group: "dev"
}
}
在許多文檔型數(shù)據(jù)庫使用案例中,非結(jié)構(gòu)化的數(shù)據(jù)模型是最佳的.
嵌入式數(shù)據(jù)模式應(yīng)用場景:
- 實體間存在包含關(guān)系的
- 實體間存在1對多關(guān)系的
引用
引用通過文檔間的鏈接或引用來存儲數(shù)據(jù)間的關(guān)系.
應(yīng)用程序可以通過解釋這些引用來訪問數(shù)據(jù),這些通常是結(jié)構(gòu)化數(shù)據(jù)模式.
//user document
{
_id: <ObjectId1>,
username: "123xyz"
}
//contact document
{
_id: <ObjectId2>,
user_id: <ObjectId1>,
phone: "123-456-7890",
email: "xyz@example.com"
}
//access document
{
_id: <ObjectId3>,
user_id: <ObjectId1>,
level: 5,
group: "dev"
}
寫操作的原子性
單個文檔的原子性
在文檔型數(shù)據(jù)庫中,寫操作是在單個文檔級別上的原子操作,即使是操作修改了單個文檔中的多個嵌入文檔.
具有嵌入數(shù)據(jù)的非規(guī)范化數(shù)據(jù)模型將所有相關(guān)數(shù)據(jù)組合在一個文檔中私蕾,而不是在多個文檔和集合中進(jìn)行規(guī)范化扶认。 該數(shù)據(jù)模型有助于原子操作呵曹。
一次寫入操作(例如db.collection.updateMany())修改多個文檔時脏款,每個文檔的修改都是原子的酱讶,但整個操作不是原子的退盯。
當(dāng)執(zhí)行多文檔寫操作時,無論是通過單次寫操作還是通過多次寫操作泻肯,其他操作可以交差進(jìn)行渊迁。