本文章是由機器翻譯。

資料點

概述了微軟 Azure DocumentDB

Julie Lerman

下載代碼示例(VB)

Julie Lerman在 2011 年 11 月,我寫了一個名為列"什麼到底是文檔資料庫嗎?"(msdn.microsoft.com/magazine/hh547103) 討論一些最知名的文檔資料庫:MongoDB,CouchDB 和 RavenDB。所有三個 NoSQL 資料庫都依舊強勁。在那個時候,微軟並沒有在市場上,有一個文檔資料庫儘管它確有微軟 Azure 表存儲,使用 NoSQL 資料庫基於鍵-值對。然而,在 8 月到 2014 年,微軟 Azure DocumentDB 宣佈,其中,正如其名稱所暗示,是一個文檔使用 NoSQL 資料庫服務可用在 Azure 上。

在本專欄中,我會提供我希望的 Azure DocumentDB 概述將陰謀你進行調查,進一步對你自己。這項服務在 Azure 上可用和已在使用,甚至在其 4 月 8 日的高程從預覽到一般可用的資源之前。例如,有一家叫作為解決方案的一部分實現 DocumentDB 的 SGS 公司的大客戶故事 bit.ly/1GMnBd9。關於該專案的開發商之一給我發一條推這並說客戶到目前為止是真的很高興。

什麼是文檔資料庫?

我早些時候的專欄集中在回答這個問題,但我會在這裡簡要地討論過,推薦你讀那另一列。文檔資料庫將資料存儲為檔,主要是作為單獨的 JSON 文檔。(MongoDB,有小小的轉折因為它衝擊著它的 JSON 檔到二進位的格式,稱為 BSON)。此存儲提供了更快的性能,處理海量的資料,因為它並不需要所有的跳要齊心協力的資料庫相關的資料時。相關的資料可以組合在一個單一的 JSON 文檔。文檔資料庫和其它 NoSQL 資料庫的另一個關鍵特徵是他們架構較少。與關係資料庫中的表需要以存儲和檢索資料的預定義的架構,不同文檔資料庫允許每個文檔來定義自己的架構。所以該資料庫是由文件組合。圖 1 顯示的單個的 JSON 文檔可能看起來像一個簡單的例子。請注意它指定了一個屬性名稱和值,它包含相關的資料。

圖 1 簡單的 JSON 文檔

{
  "RecipeName": "Insane Ganache",
  "DerivedFrom": "Café Pasqual’s Cookbook",
  "Comments":"Insanely rich. Estimate min 20 servings",
  "Ingredients":[
    {
      "Name":"Semi-Sweet Chocolate",
      "Amount":"1.5 lbs",
      "Note":"Use a bar, not bits. Ghiradelli FTW"
    },
    {
      "Name":"Heavy cream",
      "Amount":"2 cups"
    },
    {
      "Name":"Unsalted butter",
      "Amount":"2 tbs"
    }
],
  "Directions": "Combine chocolate, cream and butter in the top ..."
}

不僅是此資料都以 JSON 格式和自描述的它包含相關的資料 (成分)。常見到一些這些文檔資料庫的另一個特點是他們都可以訪問通過 HTTP 調用。後面,可以看到更多關於這與早些時候的專欄又詳細地討論這些和其他常見到這些資料庫的功能。

蔚藍的 DocumentDB 的結構

圖 1 顯示典型的文檔存儲在資料庫中文檔的外觀。蔚藍 DocumentDB 組成的不僅僅是這些檔,但是。檔被視為資源 Azure DocumentDB,可分為收藏,這也是在 DocumentDB 中的資源。您可以創建、 更新、 刪除和查詢集合使用 HTTP 調用,就像你可以與檔。事實上,DocumentDB 是完全組成的不同類型的資源。集合被分組到一個單一的 DocumentDB 資料庫。你可以有多個資料庫在一個 DocumentDB 帳戶,你可以有多個帳戶。

所有這些資源都是生態圈中的頭等公民。此外,還有另一套陪您的檔的資源。這些命名是關聯式資料庫使用者所熟悉的方式:預存程序、 使用者定義函數 (Udf),索引和觸發器。

最後一根稻草與文檔相關的一個是附件,這是任何一種附加到 JSON 文檔的二進位檔案。該二進位檔案附件的住在 Azure Blob 存儲但中繼資料存儲在 DocumentDB,確保您可以查詢上的各種屬性的附件中。

另外,DocumentDB 具有內置的安全功能,並在這一範圍內,使用者和許可權也是您可以使用同樣的手段,當您將文檔與交互的資源。

與 DocumentDB 進行交互

當地有很多方法來處理在 Azure DocumentDB 資源包括:SQL、 REST API 和各種用戶端 Api 包括.NET API,它允許您使用LINQ查詢資料庫。你學的更多詳細的查詢在 bit.ly/1aLm4bC

Azure 門戶是您創建和管理 DocumentDB 帳戶的地方。(請參閱在文檔 bit.ly/1Cq8zE7.)此外可以管理您在門戶中,DocumentDB 和使用文檔資源管理器和查詢資源管理器可以查看和查詢您的文檔。在查詢資源管理器中,可以使用 SQL 語法中,已經做為中的簡單查詢圖 2

使用 SQL 語法查詢 Azure 門戶查詢資源管理器中的檔
圖 2 使用 SQL 語法查詢 Azure 門戶查詢資源管理器中的檔

您還可以在您的應用程式中使用此 SQL。例如,下面是一些代碼從"構建 Node.js Web 應用程式使用 DocumentDB"(bit.ly/1E7j5Wg),在哪裡查詢表示 SQL 語法中:

getOrCreateDatabase: function (client, databaseId, callback) {
  var querySpec = {
    query: 'SELECT * FROM root r WHERE r.id=@id',
    parameters: [{
      name: '@id',
      value: databaseId
    }]
  };

在這些早期的 DocumentDB,您可能發現有限,此 SQL 語法,但牢記你可以補充與 Udf 的現有 SQL。例如,您可以編寫您自己的包含函數建立評估字串,例如包含 (r.name,"巧克力") 的謂詞。

像許多其他 Azure 的資源,Azure DocumentDB 有一個本機的 REST API 和可以查詢和更新使用 HTTP。每個資源都有一個唯一的 URI。 這裡是一個特定的 DocumentDB 許可權的 HTTP 要求的示例:

GET https://contosomarketing.documents.azure.com/dbs/ruJjAA==/users/ruJjAFjqQAA=/permissions/ruJjAFjqQABUp3QAAAAAAA== HTTP/1.1
x-ms-date: Sun, 17 Aug 2014 03:02:32 GMT
authorization: type%3dmaster%26ver%3d1.0%26sig%3dGfrwRDuhd18ZmKCJHW4OCeNt5Av065QYFJxLaW8qLmg%3d
x-ms-version: 2014-08-21
Accept: application/json
Host: contosomarketing.documents.azure.com

bit.ly/1NUIUd9 有關直接使用 REST API 的詳細資訊。但使用任何 REST API 可以相當繁瑣。有大量的客戶機 Api 已經可用與 Azure DocumentDB 進行交互:.NET,Node.js,JavaScript、JAVA和 Python。下載 Sdk 並閱讀文檔,網址為 bit.ly/1Cq9iVJ

.NET 開發人員會欣賞.NET 庫允許您使用LINQ查詢。LINQ方法支援肯定會隨著時間的推移,則當前支援的LINQ運算式:Queryable.Where、 Queryable.Select 和 Queryable.SelectMany。

您可以執行與 DocumentDB 的任何交互之前,您需要指定一個帳戶、 資料庫和要在其中工作的集合。下面的示例中,定義使用.NET API 的 Microsoft.Azure.Documents.ClientDocument:

string endpoint = ConfigurationManager.AppSettings["endpoint"];
string authKey = ConfigurationManager.AppSettings["authKey"];
Uri endpointUri = new Uri(endpoint);
client = new DocumentClient(endpointUri, authKey);

此示例代碼來自ASP.NETMVC 和 DocumentDB 的演練,我跟著 Azure 文檔頁面 (bit.ly/1HS6OEe)。演練是相當全面,但開頭步驟在 Azure 入口網站上創建一個 DocumentDB 帳戶。我高度推薦它,或者用其他語言如我早些時候提到的 Node.js 篇文章證明 DocumentDB 演練之一。應用程式範例有一個單一的類型,一個專案類所示圖 3

圖 3 項類

public class Item
  {
    [JsonProperty(PropertyName = "id")]
    public string Id { get; set; }
    [JsonProperty(PropertyName = "name")]
    public string Name { get; set; }
    [JsonProperty(PropertyName = "descrip")]
    public string Description { get; set; }
    [JsonProperty(PropertyName = "isComplete")]
    public bool Completed { get; set; }
  }

請注意條目類的每個屬性指定 JsonProperty 屬性名。這不是必需的但它允許.NET 用戶端存儲的 JSON 資料與我的專案類型之間的映射,並讓我命名我的類屬性,然而我想,不管如何,他們被命名資料庫中。使用定義的用戶端,然後可以表達返回實例給出了已知的資料庫 Id Microsoft.Azure.Documents.Database 的LINQ查詢:

var db = Client.CreateDatabaseQuery()
               .Where(d => d.Id == myDatabaseId)
               .AsEnumerable()
               .FirstOrDefault();

從那裡,您可以定義資料庫中的一個集合,並最後查詢具有像下面這樣,它返回一個單一的 JSON 文檔的LINQ運算式的集合:

return Client.CreateDocumentQuery(Collection.DocumentsLink)
             .Where(d => d.Id == id)
             .AsEnumerable()
             .FirstOrDefault();

.NET API 中的各種物件也使操作插入、 更新和刪除文檔與 CreateDocument­非同步、 UpdateDocumentAsync 和 DeleteDocumentAsync (CUD) 的方法,在 REST API 封裝 HTTP 調用。像查詢,有相關的反芻方法對於其他資源類型,如存儲的過程和附件。

在帽子上的一個新的轉折

它有別于其他文檔資料庫的 DocumentDB 更多有趣的方面之一是它允許您調整的一致性。文獻資料庫我之前的文章談到了上限定理,說鑒於保證一致性、 可用性和分區 (CAP) 容忍在分散式系統中,只有兩個,三能達到。關係資料庫來確保一致性犧牲可用性 (例如,等待要完成的事務)。NoSQL 資料庫,另一方面,一些更寬容的最終一致性,在那裡資料不可能 100%當前,以支援可用性。

蔚藍的 DocumentDB 提供了一個新的方式來處理上限定理,通過讓您調整程度的一致性,從而提供一個機會,也在同一時間能夠受益于可用性和分區容忍性。你可以選擇四個級別的一致性 — — 強大、 有界的失效、 會話和最終 — — 其中可以定義每個操作,而不僅僅是在資料庫上。而不是全或無的一致性,您可以調整水準的一致性,以滿足您在您的解決方案的需求。閱讀更多關於這的 Azure DocumentDB 檔頁在 bit.ly/1Cq9p3v

伺服器端 JavaScript

你們許多人可能熟悉存儲的過程和 Udf 在關係資料庫中,並與其他的文檔資料庫中,不同 Azure DocumentDB 包括這些概念,雖然它們寫在 JavaScript 中。JavaScript 本身可以與 JSON,交互的所以這是與 JSON 文檔和其他資源進行交互的效率極高。沒有轉換或翻譯或映射。伺服器端 java 語言在形式的存儲的過程和觸發器 UDF 的另一個好處是你得到原子事務跨多個文檔 — — 一切事務的範圍將會回滾某個進程失敗。定義存儲的過程和 Udf 是相當不同的你可能習慣于像SQL Server的關係資料庫中。入口網站還不能提供這種能力。 相反,您在用戶端代碼中定義您的伺服器端代碼。我建議看看 Azure DocumentDB.NET 代碼範例在伺服器端腳本條 bit.ly/1FiNK4y

現在,我會告訴你如何創建和存儲一個存儲的過程,那麼如何來執行它。圖 4 顯示了一個簡單的例子,它使用.NET API 代碼插入 DocumentDB 的存儲的過程。

圖 4 插入 DocumentDB 的存儲的過程

public static async Task<StoredProcedure> InsertStoredProcedure() {
  var sproc = new StoredProcedure
              {
                Id = "Hello",
                Body = @"
                  function() {
                    var context = getContext();
                    var response = context.getResponse();
                    response.setBody('Stored Procedure says: Hello World');
                  };"
              };
  sproc = await Client.CreateStoredProcedureAsync(setup.Collection.SelfLink, sproc);
  return sproc;
}

我已經封裝的所有的單一方法的簡單邏輯。我的 StoredProcedure 物件由 ID 和正文組成。身體是伺服器端上的 javascript 代碼。您可能希望創建的每個過程的 JavaScript 檔並讀取其中的內容創建 StoredProcedure 物件時。該代碼假定 StoredProcedure 尚不存在資料庫中。在下載示例中,您將看到叫住了一個自訂方法查詢資料庫,以確保該過程不存在插入之前。最後,SetupDocDb < T > 使用用戶端屬性 (它提供 DocumentClient 實例) 來創建存儲的過程,類似于如何我剛才質疑為文檔。

該存儲的過程存在於資料庫中,我可以使用它了。這是一個有點困難,我包我的頭,因為我習慣于SQL Server的工作的方式,這是不同的。即使我知道程式的 Id 是"你好,"與當前的 API,並不足以確定它在調用 ExecuteStoredProcedureAsync 時。每個資源已由 DocumentDB 創建的 SelfLink。SelfLink DocumentDB 那會休息功能是永恆不變的關鍵。它確保每個資源都有一個永恆不變的 HTTP 位址。我需要那 SelfLink 告訴資料庫的預存程序來執行。這就意味著我必須首先查詢資料庫中找到存儲的過程中使用熟悉的 Id ("Hello"),這樣我就可以找到它的 SelfLink 值。此工作流造成摩擦對於開發人員來說,DocumentDB 團隊更改它的工作方式以消除任何需要 SelfLinks。變化可能甚至作出的時候這篇文章也送去付印。但現在,我會查詢程式那樣為 DocumentDB 的任何資源:我將使用 CreateStoredProcedureQuery 方法。然後,與 SelfLink,我可以執行該過程,並得到其結果:

public static async Task<string> GetHello() {
  StoredProcedure sproc = Client.CreateStoredProcedureQuery(Collection.SelfLink)
    .Where(s => s.Id == "Hello")
    .AsEnumerable()
    .FirstOrDefault();
  var response =
    (await Client.ExecuteStoredProcedureAsync<dynamic>(sproc.SelfLink)).Response;
  return response.ToString();
}

創建 Udf 是類似的。你將 UDF 定義為 JavaScript 在一個 UserDefinedFunction 物件,將其插入到 DocumentDB。一旦它存在於資料庫中,您可以在查詢中使用該函數。最初,是可能僅為 CreateDocumentQuery 方法的參數使用的 SQL 語法,雖然LINQ支援補充,只是在官方發佈的 DocumentDB 在至 2015 年 4 月初之前。 以下是使用自訂的 UDF 的 SQL 查詢的一個示例:

select r.name,udf.HelloUDF() AS descrip from root r where r.isComplete=false

UDF 簡單地吐出一些文本,所以它不帶任何參數。

請注意我使用 JsonProperty 名稱在查詢中的,因為它將對 JSON 資料在伺服器上處理。LINQ查詢我將使用該專案的屬性名稱鍵入相反。

你會找到類似的查詢正在使用在示例下載中,儘管那裡我的 UDF 被稱為 HelloUDF。

性能和可擴充性

有這麼多當談論性能和可伸縮性時起作用的因素。即使你的資料模型和分區設計可能會影響這兩個關鍵層面的任何資料存儲區。我強烈推薦您閱讀關於在 DocumentDB 的資料建模提供了出色的指導 bit.ly/1Chrjqa。那篇文章涉及的圖形設計和關係以及它們如何影響性能和可伸縮性 DocumentDB 利弊。作者,Ryan克勞科爾,是 DocumentDB 團隊的高級專案經理,解釋了哪些模式中獲益的讀取的性能和受益寫入性能。事實上,我發現指導用於模型設計一般情況下,不只是為了 Azure DocumentDB。

你如何選擇分區,您的資料庫也應由你讀和寫的需要。文章對在 DocumentDB 的資料分區 bit.ly/1y5T4FG 給出了更多的指導,關於使用 DocumentDB 集合來定義分區以及如何定義取決於如何你會需要訪問的資料的集合。

另一個好處是分區的你可以創建 (或刪除) 更多的收藏品或所需的資料庫。DocumentDB 尺度彈性 ; 那就是,它將自動理解充分的資源集合。

指標影響性能的另一個重要因素,DocumentDB 允許您設置跨集合索引策略。如果沒有索引,你只能夠使用的 SelfLinks 和資源 Id 來執行查詢,如我之前做過。預設的索引策略嘗試查詢性能和存儲效率之間找到一個平衡點,但您可以重寫它以得到你想要的平衡。索引也是一致的這意味著利用索引的搜索將有新資料的即時訪問。閱讀更多的細節,關於索引在 bit.ly/1GMplDm

不是免費的但成本效益

管理性能和可擴充性影響更多的您的資料可訪問性,它也會影響提供該資料的成本。作為其蔚藍色的產品的一部分,DocumentDB 並付出了代價。有三個價格點由這三個性能級別單位確定你選擇。因為微軟正在不斷地調整其服務的成本,它是最安全的方式直接指向你的 DocumentDB 定價詳細資訊頁面 (bit.ly/1IKUUMo)。像任何使用 NoSQL 資料庫,DocumentDB 旨在為海量資料提供資料存儲和,因此,可以大大比使用關係中的資料相關的方案的成本效益更高。


Julie Lerman 是 Microsoft MVP,.NET 的導師和顧問,住在佛蒙特州的山。你可以找到她提出關於資料訪問和其他.NET 主題使用者組和世界各地的會議。她的博客 thedatafarm.com ,是作者的"程式設計Entity Framework"(2010 年),以及代碼第一版 (2011 年) 和 DbCoNtext 版 (2012 年),所有從 O'Reilly 媒體。跟著她在 Twitter 上 twitter.com/julielerman ,看看她的 Pluralsight 課程 juliel.me PS 的-視頻

感謝以下的微軟技術專家對本文的審閱:Ryan克勞科爾
Ryan克勞科爾是 20 年資料庫老兵開始出許多年前為SQL Server4.2 寫他的第一個存儲的過程。多個游標、 聯接和存儲的過程後,他開始探索令人興奮的自由世界的 NoSQL 解決方案。Ryan現在正在與雷德蒙德説明形狀作為專案經理的 DocumentDB 產品團隊未來的這所有新 NoSQL 資料庫作為-服務