共用方式為


Azure Cosmos DB for NoSQL 中的資料模型化

雖然無結構描述的資料庫 (例如 Azure Cosmos DB) 可讓您輕鬆儲存和查詢非結構化資料與半結構化資料,但請考慮到您的資料模型,以將效能、可擴縮性和成本最佳化。

儲存資料的方式 您的應用程式如何擷取和查詢資料? 您的應用程式是大量讀取或大量寫入?

閱讀完本文之後,您可以回答下列問題:

  • 什麼是資料模型化,以及為什麼應該關心?
  • Azure Cosmos DB 中的資料模型化與關聯式資料庫中的有何不同?
  • 如何表達非關聯式資料庫中的資料關聯性?
  • 何時內嵌資料,以及何時連結至資料?

JSON 中的數字

Azure Cosmos DB 會以 JSON 格式儲存文件,因此請務必先判斷是否要將數字轉換成字串,再將數字儲存在 JSON 中。 如果數字可能超過 String (英文) 所定義的雙精確度數字範圍,請將所有數字轉換為 JSON 規格 (英文) 會說明為什麼因為互通性問題,使用超出此範圍的數字是不好的作法。 這些問題尤其與分割區索引鍵資料行有關,因為其不可變,必須在資料移轉後才能變更。

內嵌資料

當您在 Azure Cosmos DB 中將資料模型化時,請將您的實體視為以 JSON 文件表示的獨立式項目

為了進行比較,我們先來看看我們可能會如何在關係資料庫中建立資料模型。 下列範例示範人員可能如何儲存在關聯式資料庫中。

關聯式資料庫模型的螢幕擷取畫面。

使用關聯式資料庫時,策略是將您所有的資料標準化。 將您的資料正規化通常會牽涉到取得某個實體 (例如某個人),然後將其分解為離散的元件。 在範例中,人員可以有多個連絡詳細資料記錄,以及多個地址記錄。 您可以透過擷取類型等常見欄位,來進一步細分連絡人詳細資料。 同樣的方法也適用於地址。 每筆記錄都可以分類為「家裡」或「公司」

將資料正規化的引導前提是在每個記錄資料上避免儲存多餘的資料,而是參考資料。 在此範例中,若要讀取人員及其所有連絡詳細資料和地址,您需要使用「聯結」有效地在執行階段回寫 (或反正規化) 資料。

SELECT p.FirstName, p.LastName, a.City, cd.Detail
FROM Person p
JOIN ContactDetail cd ON cd.PersonId = p.Id
JOIN ContactDetailType cdt ON cdt.Id = cd.TypeId
JOIN Address a ON a.PersonId = p.Id

更新單一人員的連絡詳細資料和地址需要跨許多個別資料表執行寫入作業。

現在讓我們看看如何將相同的資料模型化為 Azure Cosmos DB 中的獨立實體。

{
    "id": "1",
    "firstName": "Thomas",
    "lastName": "Andersen",
    "addresses": [
        {
            "line1": "100 Some Street",
            "line2": "Unit 1",
            "city": "Seattle",
            "state": "WA",
            "zip": 98012
        }
    ],
    "contactDetails": [
        {"email": "thomas@andersen.com"},
        {"phone": "+1 555 555-5555", "extension": 5555}
    ]
}

使用此方法,我們已將人員記錄反正規化,方法是內嵌與人員相關的所有資訊 (例如他們的連絡詳細資料和地址) 到「單一 JSON」文件。 此外,因為我們不受限於固定的架構,我們有彈性可以處理聯絡資訊的不同形式。

從資料庫擷取完整的人員記錄現在是針對單一項目的單一容器所執行的單一讀取作業。 更新連絡詳細資料和地址等個人記錄,也是針對單一項目的單一寫入作業

將資料反正規化可能會減少應用程式完成一般作業所需的查詢和更新數目。

內嵌的時機

一般而言,使用內嵌的資料模型的時機為:

  • 實體之間有內含的關聯性。
  • 實體之間有 一對少數 關聯性。
  • 資料很少變更
  • 資料不會無限制地成長
  • 資料經常一起進行查詢

附註

通常反正規化的資料模型可提供較佳的 讀取 效能。

不要內嵌的時機

雖然在 Azure Cosmos DB 中的經驗法則是將所有項目反正規化,並將所有資料內嵌到單一項目,但此方法可能會導致某些要避免的情況。

取得此 JSON 程式碼片段。

{
    "id": "1",
    "name": "What's new in the coolest Cloud",
    "summary": "A blog post by someone real famous",
    "comments": [
        {"id": 1, "author": "anon", "comment": "something useful, I'm sure"},
        {"id": 2, "author": "bob", "comment": "wisdom from the interwebs"},
        …
        {"id": 100001, "author": "jane", "comment": "and on we go ..."},
        …
        {"id": 1000000001, "author": "angry", "comment": "blah angry blah angry"},
        …
        {"id": ∞ + 1, "author": "bored", "comment": "oh man, will this ever end?"},
    ]
}

如果我們要將一般的部落格或內容管理系統 (CMS) 模型化,此範例可能是具有內嵌註解的貼文實體的可能樣貌。 此範例的問題在於註解陣列是 unbounded,表示任何單一文章可以具備的註解數目沒有 (實際) 的限制。 這種設計可能會導致問題,因為項目的大小可能會成長到無限大,因此請避免使用。

隨著項目大小的增加,大規模傳輸、讀取和更新資料變得越發困難。

在此情況下,最好考慮使用下列資料模型。

Post item:
{
    "id": "1",
    "name": "What's new in the coolest Cloud",
    "summary": "A blog post by someone real famous",
    "recentComments": [
        {"id": 1, "author": "anon", "comment": "something useful, I'm sure"},
        {"id": 2, "author": "bob", "comment": "wisdom from the interwebs"},
        {"id": 3, "author": "jane", "comment": "....."}
    ]
}

Comment items:
[
    {"id": 4, "postId": "1", "author": "anon", "comment": "more goodness"},
    {"id": 5, "postId": "1", "author": "bob", "comment": "tails from the field"},
    ...
    {"id": 99, "postId": "1", "author": "angry", "comment": "blah angry blah angry"},
    {"id": 100, "postId": "2", "author": "anon", "comment": "yet more"},
    ...
    {"id": 199, "postId": "2", "author": "bored", "comment": "will this ever end?"}   
]

這個模型會為每一則留言建立一個項目,項目裡會有一個屬性,屬性中包含貼文的識別碼。 這個模型可讓貼文包含任意數量的留言,並且可以有效率地成長。 使用者不只是想查看最近的留言,則會在查詢此容器時傳遞 postId,而這應該是留言容器的分割區索引鍵。

內嵌資料並不是好主意的另一種情況是在內嵌的資料經常跨項目使用,而且經常變更時。

取得此 JSON 程式碼片段。

{
    "id": "1",
    "firstName": "Thomas",
    "lastName": "Andersen",
    "holdings": [
        {
            "numberHeld": 100,
            "stock": { "symbol": "zbzb", "open": 1, "high": 2, "low": 0.5 }
        },
        {
            "numberHeld": 50,
            "stock": { "symbol": "xcxc", "open": 89, "high": 93.24, "low": 88.87 }
        }
    ]
}

此範例可以代表個人的股票投資組合。 我們已選擇內嵌股票資料到每個投資組合文件。 在相關資料經常會變更的環境中,內嵌經常變更的資料表示您會經常更新每個投資組合。 以股票交易應用程式為例,您每次交易股票時都會更新每個投資組合的項目。

股票 zbzb 可能在一天之中交易數百次,而且 zbzb 可能會在上千名使用者的投資組合中。 使用此範例之類的資料模型時,系統必須每天多次更新數千個投資組合文件,這樣的模型不易縮放。

參考資料

內嵌資料適合許多情況,但有時將資料反正規化會造成更多問題,而得不償失。 那麼,您可以做什麼呢?

您可以在文件資料庫中 (而不只是在關聯式資料庫中) 的實體之間建立關聯性。 在文件資料庫中,一個項目可以包含連接至其他文件中資料的資訊。 Azure Cosmos DB 並非專為複雜的關聯性 (例如關聯式資料庫中的關聯性) 而設計,但項目之間的簡單連結是做得到的,而且可能會有所幫助。

在 JSON 中,我們使用先前的股票投資組合範例,但這次我們改為參考 (而非內嵌) 投資組合中的股票項目。 如此一來,當股票項目在一整天之中頻繁變更時,需要更新的項目就只有那一個股票文件。

Person document:
{
    "id": "1",
    "firstName": "Thomas",
    "lastName": "Andersen",
    "holdings": [
        { "numberHeld":  100, "stockId": 1},
        { "numberHeld":  50, "stockId": 2}
    ]
}

Stock documents:
{
    "id": "1",
    "symbol": "zbzb",
    "open": 1,
    "high": 2,
    "low": 0.5,
    "vol": 11970000,
    "mkt-cap": 42000000,
    "pe": 5.89
},
{
    "id": "2",
    "symbol": "xcxc",
    "open": 89,
    "high": 93.24,
    "low": 88.87,
    "vol": 2970200,
    "mkt-cap": 1005000,
    "pe": 75.82
}

這個方法有一個缺點,那就是您的應用程式必須提出數個資料庫要求,才能取得個人投資組合中每檔股票的相關資訊。 這種設計可加快資料寫入速度,因為更新發生得很頻繁。 然而,卻會降低資料的讀取或查詢速度,不會這一點對此系統來說較不重要。

附註

正規化的資料模型 可能需要更多來回行程 到伺服器。

外部索引鍵呢?

因為沒有限制式的概念 (例如外部索引鍵),所以資料庫不會驗證文件中的任何文件間關聯性;這些連結實際上很「薄弱」。如果您想要確保項目所參考的資料確實存在,就必須在應用程式中執行此步驟,或在 Azure Cosmos DB 上使用伺服器端觸發程序或預存程序。

參考時機

一般而言,使用正規化資料模型的時機為:

  • 代表一對多關聯性。
  • 代表多對多關聯性。
  • 相關資料 經常變更
  • 參考資料可能是無限制的

附註

通常正規化可提供較佳的 寫入 效能。

關聯性應置於何處?

關聯性的成長有助於判斷用來儲存參考的項目。

如果我們觀察為出版商和書籍建立模型的 JSON。

Publisher document:
{
    "id": "mspress",
    "name": "Microsoft Press",
    "books": [ 1, 2, 3, ..., 100, ..., 1000]
}

Book documents:
{"id": "1", "name": "Azure Cosmos DB 101" }
{"id": "2", "name": "Azure Cosmos DB for RDBMS Users" }
{"id": "3", "name": "Taking over the world one JSON doc at a time" }
...
{"id": "100", "name": "Learn about Azure Cosmos DB" }
...
{"id": "1000", "name": "Deep Dive into Azure Cosmos DB" }

如果每個出版社出版的書籍數量很少且成長有限,則將書籍參考儲存在出版社項目內可能會很有用。 不過,如果每個發行者的書籍數量無限,此資料模型會導致可變動、成長的陣列,如範例發行者文件所示。

切換結構會產生代表相同資料的模型,但能避免出現大型且可變動的集合。

Publisher document:
{
    "id": "mspress",
    "name": "Microsoft Press"
}

Book documents:
{"id": "1","name": "Azure Cosmos DB 101", "pub-id": "mspress"}
{"id": "2","name": "Azure Cosmos DB for RDBMS Users", "pub-id": "mspress"}
{"id": "3","name": "Taking over the world one JSON doc at a time", "pub-id": "mspress"}
...
{"id": "100","name": "Learn about Azure Cosmos DB", "pub-id": "mspress"}
...
{"id": "1000","name": "Deep Dive into Azure Cosmos DB", "pub-id": "mspress"}

在此範例中,出版社文件不再包含無限制的集合。 相反地,每個書籍文件都包含對其出版社的參考。

如何建立多對多關聯性的模型?

在關聯式資料庫中,通常會使用聯結資料表將多對多關聯性模型化。 這些關聯性只會將其他資料表中的記錄聯結在一起。

螢幕擷取畫面:顯示如何聯結資料表。

您可能會想要使用文件複寫相同的項目,並產生看起來如下所示的資料模型。

Author documents:
{"id": "a1", "name": "Thomas Andersen" }
{"id": "a2", "name": "William Wakefield" }

Book documents:
{"id": "b1", "name": "Azure Cosmos DB 101" }
{"id": "b2", "name": "Azure Cosmos DB for RDBMS Users" }
{"id": "b3", "name": "Taking over the world one JSON doc at a time" }
{"id": "b4", "name": "Learn about Azure Cosmos DB" }
{"id": "b5", "name": "Deep Dive into Azure Cosmos DB" }

Joining documents:
{"authorId": "a1", "bookId": "b1" }
{"authorId": "a2", "bookId": "b1" }
{"authorId": "a1", "bookId": "b2" }
{"authorId": "a1", "bookId": "b3" }

這種方法可行,但要載入某位作者及其撰寫的書籍,或是載入某本書及其作者,一律至少需要額外兩個資料庫查詢。 一個查詢用來取得聯結的項目,另一個查詢則用來擷取要被聯結的實際項目。

如果此聯結的作用只是在將兩組資料結合在一起,那麼為何不將其完全捨棄? 請思考一下下列範例。

Author documents:
{"id": "a1", "name": "Thomas Andersen", "books": ["b1", "b2", "b3"]}
{"id": "a2", "name": "William Wakefield", "books": ["b1", "b4"]}

Book documents:
{"id": "b1", "name": "Azure Cosmos DB 101", "authors": ["a1", "a2"]}
{"id": "b2", "name": "Azure Cosmos DB for RDBMS Users", "authors": ["a1"]}
{"id": "b3", "name": "Learn about Azure Cosmos DB", "authors": ["a1"]}
{"id": "b4", "name": "Deep Dive into Azure Cosmos DB", "authors": ["a2"]}

使用此模型時,您可以透過查看作者的文件,輕鬆了解作者寫了哪些書。 您還可以透過查看書籍文件,了解哪些作者寫了某本書。 您不需要使用個別的聯結資料表或進行額外的查詢。 此模型可讓您的應用程式更快、更簡單地取得所需的資料。

混合式資料模型

我們將探討資料的內嵌 (或反正規化) 與參考 (或正規化)。 這兩種方法各有其優點,同時也伴隨著取捨。

不一定非得二擇一。 可以放心地稍微混合使用看看。

根據您應用程式的具體使用模式和工作負載,混合使用內嵌資料和參考資料可能是合理的做法。 這種方法可以簡化應用程式邏輯、減少伺服器往返次數,並維持良好的效能。

請考慮下列 JSON。

Author documents:
{
    "id": "a1",
    "firstName": "Thomas",
    "lastName": "Andersen",
    "countOfBooks": 3,
    "books": ["b1", "b2", "b3"],
    "images": [
        {"thumbnail": "https://....png"}
        {"profile": "https://....png"}
        {"large": "https://....png"}
    ]
},
{
    "id": "a2",
    "firstName": "William",
    "lastName": "Wakefield",
    "countOfBooks": 1,
    "books": ["b1"],
    "images": [
        {"thumbnail": "https://....png"}
    ]
}

Book documents:
{
    "id": "b1",
    "name": "Azure Cosmos DB 101",
    "authors": [
        {"id": "a1", "name": "Thomas Andersen", "thumbnailUrl": "https://....png"},
        {"id": "a2", "name": "William Wakefield", "thumbnailUrl": "https://....png"}
    ]
},
{
    "id": "b2",
    "name": "Azure Cosmos DB for RDBMS Users",
    "authors": [
        {"id": "a1", "name": "Thomas Andersen", "thumbnailUrl": "https://....png"},
    ]
}

這裡我們 (大致上) 採用了內嵌模型,即來自其他實體的資料會內嵌在最上層的文件中,但其他資料則以參考方式處理。

如果您查看書籍文件,在查看作者陣列時就會看到一些有趣的欄位。 有一個 id 欄位,這是我們用來往回參考某個作者文件的欄位,也是正規化模型中的標準做法;但我們同時也有 namethumbnailUrl。 我們可以只使用 id,讓應用程式使用「連結」從對應的作者項目中擷取其所需的任何其他資訊。不過,由於應用程式會在每本書中顯示作者的姓名和縮圖,因此將作者的某些資料反正規化,可以減少清單中每本書的伺服器往返次數。

如果作者的姓名發生變化或作者更新了相片,則您需要更新其所出版的每一本書。 不過,對於此應用程式來說,假設作者姓名很少變更,則這種折衷方案是可接受的設計決策。

範例中有預先計算的彙總值,可節省讀取作業期間的高昂處理費用。 在範例中,作者項目中內嵌的部分資料是在執行階段計算的資料。 每次有新書出版時,系統便會建立書籍項目,並且會將 countOfBooks 欄位設定為根據某位特定作者存在的書籍文件數目所計算出的值。 在讀取繁重的系統中 (我們可以負擔執行寫入計算以最佳化讀取),這項最佳化將很適合。

由於 Azure Cosmos DB 支援多文件交易,因此模型現在能夠具有預先計算的欄位。 許多 NoSQL 存放區無法跨文件執行交易,因此會因應這個限制而建議採取「所有資料一律嵌入」之類的設計決策。 藉由 Azure Cosmos DB,您可以使用伺服器端觸發程序或預存程序,插入書籍並更新作者,全都在 ACID 交易內完成。 現在,您不必為了確保資料一致性就把所有資料都內嵌到一個項目中。

區分不同的項目類型

在某些情況下,您可能會想要在相同的集合中混合使用不同的項目類型;當您想要讓多個相關文件位於相同的分割區時,通常就會選擇這個設計。 例如,您可以將書籍和書籍評論放在相同的集合中,並依 bookId 將其分割。 在這種情況下,您通常會想要在文件中新增可識別文件類型的欄位,以便能加以區分。

Book documents:
{
    "id": "b1",
    "name": "Azure Cosmos DB 101",
    "bookId": "b1",
    "type": "book"
}

Review documents:
{
    "id": "r1",
    "content": "This book is awesome",
    "bookId": "b1",
    "type": "review"
}
{
    "id": "r2",
    "content": "Best book ever!",
    "bookId": "b1",
    "type": "review"
}

Microsoft Fabric 和 Azure Cosmos DB 鏡像功能的資料建模

Azure Cosmos DB 鏡像 是一種雲端原生的混合交易與分析處理(HTAP)功能,讓您能在 Azure Cosmos DB 中對營運資料進行近乎即時的分析。 Microsoft Fabric 中的 Fabric Mirroring 創造了 Azure Cosmos DB 和 OneLake 之間的無縫整合。

這種整合讓你能快速且經濟地對大量資料執行查詢。 你不需要複製資料,也不用擔心會影響你的交易工作負載。 當你開啟容器的鏡像功能時,你對資料所做的每一次變更幾乎會立刻複製到 OneLake。 您不需要設定變更摘要或執行擷取、轉換和載入 (ETL) 作業。 系統會自動幫您保持兩個存放區的同步。

透過 Azure Cosmos DB 鏡像功能,您現在可以直接從 Microsoft Fabric 連接到 Azure Cosmos DB 容器。 您可以透過 SQL 端點使用 T-SQL 查詢,或直接從 OneLake 使用 Spark 來存取您的資料,且無需支付請求單元 (Request Units) 的成本。

自動架構推斷

Azure Cosmos DB 的交易儲存是列導向的半結構化資料,而 Microsoft Fabric 中的 OneLake 則採用欄位式與結構化格式。 此轉換會自動為客戶完成。 轉換程序有一些限制:最大的巢狀層級數目、屬性的最大數目、不支援的資料類型等等。

附註

在分析存放區的內容中,我們將下列結構視為屬性:

  • JSON「元素」,或「以 : 分隔的字串-值組」
  • JSON 物件 (以 {} 分隔)
  • JSON 陣列 (以 [] 分隔)

您可以使用下列技術,將結構描述推斷轉換的效果降到最低,並最大幅度提高分析功能。

正規化

正規化變得不那麼重要,因為 Microsoft Fabric 允許你使用 T-SQL 或 Spark SQL 加入容器。 正規化的預期優點如下:

  • 資料佔用量更小。
  • 交易較小。
  • 每份文件的屬性較少。
  • 具有較少巢狀層級的資料結構。

減少資料中的屬性和層級,可加快分析查詢的速度。 這也有助於確保所有資料部分都包含在 OneLake 中。 OneLake 所代表的層級和物業數量有其限制。

另一個標準化的重要因素是 OneLake 支援最多 1,000 欄的結果集,且暴露巢狀欄位也會計入此限制。 換句話說,Fabric 中的 SQL 端點限制為 1,000 個屬性。

但是,由於反正規化是 Azure Cosmos DB 的重要資料模型技術,應該採取什麼動作? 答案是您必須找出交易和分析工作負載的正確平衡。

分割區索引鍵

Azure Cosmos DB 分割金鑰(PK)在 Microsoft Fabric 中並不被使用。 由於這種隔離性,你可以為交易資料選擇一個 PK,重點放在資料擷取和點讀取,而跨區查詢則可透過 Microsoft Fabric 進行。 看看以下範例:

在假想的全球 IoT 案例中,device id 是不錯的分割區索引鍵,因為所有裝置都會產生類似的資料量,從而防止經常性分割區問題。 但是,如果您想要分析多個裝置的資料,例如「所有來自昨天的資料」或「每個城市的總計」,您可能會遇到問題,因為這些查詢是跨分割區的查詢。 這些查詢可能會損害您的交易效能,因為其會在要求單位中使用您的部分輸送量來執行。 但使用 Microsoft Fabric,你可以在沒有請求單元相關成本的情況下執行這些分析查詢。 OneLake 的 delta 格式針對分析性查詢進行優化。

資料類型和屬性名稱

自動結構描述推斷規則文章會列出支援的資料類型。 雖然 Microsoft Fabric 執行環境可能會以不同方式處理支援的資料型別,但不支援的資料型別會阻擋分析儲存中的表示。 舉例來說:當使用 DateTime 字串遵循 ISO 8601 UTC 標準時,Microsoft Fabric 中的 Spark 池會將這些欄位表示為 string ,SQL Serverless 則將這些欄位表示為 varchar(8000)

資料壓平合併

Azure Cosmos DB 資料最上層的每個屬性都會成為分析存放區中的欄。 巢狀物件或陣列中的屬性會以 JSON 格式儲存在 OneLake 中。 巢狀結構需要 Spark 或 SQL 執行時額外處理來平整資料。 這會增加處理大量資料時的運算成本與延遲。 在簡單的情況下,使用扁平的資料模型。 至少,避免在資料模型中過度巢狀化資料。

該項目在 OneLake 中只有兩個欄位, idcontactDetails。 其他資料 email、 和 phone,都需要透過 SQL 或 Spark 函式進行額外處理才能被讀取。

{
    "id": "1",
    "contactDetails": [
        {"email": "thomas@andersen.com"},
        {"phone": "+1 555 555-5555"}
    ]
}

壓平化可以消除這種需求。 以下、idemailphone、皆可直接以欄位存取,無需額外處理

{
    "id": "1",
    "email": "thomas@andersen.com",
    "phone": "+1 555 555-5555"
}

資料分層

Microsoft Fabric 讓你從以下角度降低成本:

  • 在交易資料庫中執行的查詢較少。
  • 針對資料擷取和點讀取最佳化的 PK,可減少資料磁碟使用量、經常性存取層分割區案例和分割區分割。
  • 沒有任何 ETL 作業在您的環境中執行,這表示您不需要為其配置要求單位。

控制的冗餘

這個技術是資料模型已存在且無法變更時的絕佳替代方案。 或者你的資料太複雜,層級太多或屬性太多。 如果你是這種情況,可以使用 Azure Cosmos DB 變更資訊流 將資料複製到另一個容器,套用所需的轉換,然後將該容器的鏡像設定到 Microsoft Fabric 進行分析。 看看以下範例:

案例

CustomersOrdersAndItems容器用於儲存線上訂單,包括客戶與商品細節:帳單地址、配送地址、配送方式、配送狀態、商品價格等。僅代表前 1,000 個物業,且未包含關鍵資訊,使得 Fabric 無法進行分析。 容器有數 PB 的資料,所以無法更改應用程式或重新設計資料。

這個問題的另一個方面是資料量龐大。 分析部門經常使用數十億個資料列,而無法使用 tttl 來刪除舊的資料。 因分析需求而在交易資料庫中維護完整資料歷史,迫使他們不斷增加 RU/s,進而影響成本。 交易和分析工作負載會同時競爭相同的資源。

您可以做什麼?

具有變更摘要的解決方案

  • 解決方法是使用 Change Feed 來填充三個新的容器:Customers、、 OrdersItems和 。 透過 Change Feed,你可以將資料正規化並平整,並從資料模型中移除不必要的資訊。
  • 容器 CustomersOrdersAndItems 現在已將存留時間 (TTL) 設定為只保留資料六個月,從而進一步降低要求單位的使用量,因為在 Azure Cosmos DB 中,每 GB 至少會有一個要求單位。 較少的資料、較少的要求單位。

重要心得

這篇文章最重要的重點是,即使在無結構描述的環境中,資料模型化依然同樣重要。

正如同沒有單一方法可表示螢幕上的資料片段,沒有單一方法可為您的資料建立模型。 您需要了解您的應用程式,以及其如何產生、取用和處理資料。 藉由套用此處所提供的指導方針,您可以建立模型來處理您應用程式的立即需求。 當應用程式發生變化時,請使用無結構描述資料庫的彈性,輕鬆調整和發展您的資料模型。