Azure Storage 是微軟 Azure 雲提供的雲端存儲解決方案,當前支持的存儲類型有 Blob、Queue、File 和 Table,其中的 Table 就是本文的主角 Azure Table storage。php
Azure Table storage 是一個在雲端存儲結構化 NoSQL 數據的服務,它不只存取速度快,並且效費比高。MSDN 上的說法是:成本顯著低於傳統 SQL!sql
筆者最近在項目中用 Table storage 實現了一個日誌表,在此和你們分享一下 Table storage 的基本用法。測試
文章來源:葡萄城產品技術社區this
首先須要說明,對 Blob、Queue、File 和 Table 這些 Azure 提供的存儲服務的訪問控制都是經過 storage account 來進行的,因此要想使用 Table storage,須要先建立你的 storage account。spa
具體建立過程,MSDN 上有詳細講解。你須要瞭解一下 Access keys,由於它就是你訪問 storage account 的用戶名和密碼:設計
在使用 Azure Table storage 的相關對象前,咱們須要安裝對應的包。安裝過程其實很簡單,只需在 Visual Studi o的 Package Manager Console 中輸入:日誌
Install-Package WindowsAzure.Storage
Visual Studio 就會自動安裝 WindowsAzure.Storage 包及其依賴的全部包,安裝完成後的 packages.config 文件看起來像這個樣子:cdn
安裝完相關的包之後,咱們就可使用其中的類型了。對象
CloudStorageAccount 類表示一個 Azure storage account,咱們須要先建立它的實例,才能訪問屬於它的資源。blog
//注意鏈接字符串中的xxx和yyy,分別對應Access keys中的Storage account name 和 key。 CloudStorageAccount storageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=xxx;AccountKey=yyy");
CloudTableClient 類是 Windows Azure Table Service 客戶端的邏輯表示,咱們須要使用它來配置和執行對 Table storage 的操做。
CloudTableClient cloudTableClient = storageAccount.CreateCloudTableClient();
CloudTable 類表示一張數據表。
咱們須要建立一個實例去引用 Table storage 中的一張表,測試用的表名叫」MyLogTable」。
CloudTable logTable = cloudTableClient.GetTableReference("MyLogTable"); // 若是不肯定表是否被建立過,能夠調用CreateIfNotExists方法。 logTable.CreateIfNotExists();
這樣在後面的操做中就能夠確保 MyLogTable 表是存在的,有了 logTable 對象咱們就能夠向表中插入數據了。
可是等等,好像少了點什麼。
咱們開篇第一句中就說明了,Table storage 存儲的是結構化的數據,因此咱們還要先定義存儲的數據的類型。
在定義咱們本身的數據類型時,有一個強制性的要求,必須繼承自 TableEntity 類型:
{ public MyLogEntity() { } public MyLogEntity(string pkey, string rkey) { this.PartitionKey = pkey; this.RowKey = rkey; } public DateTime LogDate { get; set; } public string LogMessage { get; set; } public string ErrorType { get; set; } }
在咱們的設計中,PartitionKey 用來存放產生日誌的年份和月份(例如 201607),RowKey 用來存放產生日誌的天和時分秒毫秒(例如 160934248492),日誌數據主要是 LogDate, LogMessage 和 ErrorType。
把數據插入到Table storage
終於能夠向表中插入數據了,先試一下:
DateTime now = DateTime.Now; string partitionKey = now.ToString("yyyyMM"); string rowKey = now.ToString("ddHHmmssffff"); MyLogEntity logEntity = new MyLogEntity(partitionKey, rowKey); logEntity.LogDate = now; logEntity.LogMessage = "test message"; logEntity.ErrorType = "error"; // TableOperation類表示對一個表進行的操做,能夠插入一行或多行數據,刪除數據,更新數據等。 TableOperation insertOperation = TableOperation.Insert(logEntity); logTable.Execute(insertOperation);
看起來還不錯,咱們用 Visual Studio 自帶的 Cloud Explorer 查看一下 MyLogTable 中的內容:
OK,數據已經成功插入到 MyLogTable 表中,接下來咱們看看如何批量的插入數據。
TableBatchOperation batchOperation = new TableBatchOperation(); for (int i = 0; i < 10; i++) { DateTime now = DateTime.Now; string partitionKey = now.ToString("yyyyMM"); string rowKey = now.ToString("ddHHmmssffff"); MyLogEntity logEntity = new MyLogEntity(partitionKey, rowKey); logEntity.LogDate = now; logEntity.LogMessage = "test message" + i.ToString(); logEntity.ErrorType = (i%2) == 0 ? "error" : "warning"; batchOperation.Insert(logEntity); Thread.Sleep(10); } logTable.ExecuteBatch(batchOperation);
此次咱們把 TableOperation 類換成了 TableBatchOperation 類,而後一次插入十條數據。去檢查一下結果,OK十條數據所有插入成功!
下面讓咱們把循環中的10改爲200試試:
怎麼收到一個 InvalidOperationException 呢?看看紅框中的內容,原來批量操做是有一些限制的:
1. 每一個批量操做的數據上限是100條記錄。
2. 每一個批量操做中的數據都必須保持相同的 partition key。
請你們在使用批量操做時務必注意這些限制條件!
對於日誌數據的操做,最重要的就是查詢,咱們經過幾個具體的用例來介紹 Table storage 的查詢操做。
1. 查詢全部的記錄
這是最簡單的查詢方法,通常是想要導出所有數據時纔會這麼幹:
TableQuery<MyLogEntity> query = new TableQuery<MyLogEntity>(); foreach (MyLogEntity entity in logTable.ExecuteQuery(query)) { Console.WriteLine("{0}\t{1}\t{2}\t{3}", entity.PartitionKey, entity.RowKey, entity.LogMessage, entity.ErrorType); }
2.查詢某年的某個月的記錄
要查詢某個月的全部記錄也是比較容易的,由於咱們設計的 PartitionKey 就表明了某個月份:
TableQuery<MyLogEntity> query = new TableQuery<MyLogEntity>().Where( TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "201607")); foreach (MyLogEntity entity in logTable.ExecuteQuery(query)) { //... }
請注意 TableQuery.GenerateFilterCondition 方法,咱們建立了一個過濾條件:PartitionKey 等於「201607」。這個查詢會把全部 PartitionKey 爲「201607」的記錄都找到!
3.查詢某一條記錄
若是咱們已經知道了一條記錄的 PartitionKey 和 RowKey,就能夠經過這兩個條件直接查詢到這條記錄的詳情:
TableQuery<MyLogEntity> query = new TableQuery<MyLogEntity>().Where( TableQuery.CombineFilters( TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "201607"), TableOperators.And, TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, "161148372454"))); foreach (MyLogEntity entity in logTable.ExecuteQuery(query)) { //... }
此次咱們使用了組合條件,只用到了條件運算操做 TableOperators.And 和 QueryComparisons.Equal,固然你也能夠嘗試其它的條件類型。惟一要注意的就是: PartitionKey 和 RowKey,QueryComparisons 的操做對象都是字符串。
咱們還須要更多的查詢條件,好比查詢某一天產生的全部日誌。在 MyLogTable 表中,這須要查詢以」xx」字符串開頭的 RowKey。這部分知識,我會單獨在一篇文章中和你們分享相關內容,由於它並不像看起來的那麼簡單。
接下來咱們介紹如何更新和刪除日誌表中的數據,這裏只是借用日誌表介紹更新和刪除操做。
TableOperation retrieveOperation = TableOperation.Retrieve<MyLogEntity>("201607", "161148372454"); TableResult retrievedResult = logTable.Execute(retrieveOperation); MyLogEntity updateEntity = (MyLogEntity)retrievedResult.Result; if (updateEntity != null) { updateEntity.LogMessage = "new log message"; TableOperation updateOperation = TableOperation.Replace(updateEntity); logTable.Execute(updateOperation); }
以上操做,咱們先用 TableOperation.Retrieve 方法得到一條數據的詳情,而後更新它的 LogMessage 屬性,最後使用 TableOperation.Replace 方法把新的內容更新的到 Table storage 中。
刪除一條記錄和更新一條記錄是基本同樣的步驟,不一樣點是把 TableOperation.Replace 方法換成 TableOperation.Delete 方法:
TableOperation retrieveOperation = TableOperation.Retrieve<MyLogEntity>("201607", "161148372454"); TableResult retrievedResult = logTable.Execute(retrieveOperation); MyLogEntity deleteEntity = (MyLogEntity)retrievedResult.Result; if (deleteEntity != null) { TableOperation deleteOperation = TableOperation.Delete(deleteEntity); logTable.Execute(deleteOperation); }
刪除表
刪除表和建立表同樣簡單(可比刪除一條記錄容易多了):
logTable.DeleteIfExists();
總結,本文經過對一個日誌表的操做介紹了 Azure Table storage 的一個典型應用場景和基本的使用方法,從操做的代碼上看和傳統的 sql 表操做差異仍是挺大的。但願本文對朋友們瞭解 Azure Table storage 能有所幫助。