天天看點

Azure Table storage 基本用法 -- Azure Storage 之 Table

Azure Storage 是微軟 Azure 雲提供的雲端存儲解決方案,目前支援的存儲類型有 Blob、Queue、File 和 Table,其中的 Table 就是本文的主角 Azure Table storage。本文通過對一個日志表的操作介紹了 Azure Table storage 的一個典型應用場景和基本的使用方法,從操作的代碼上看和傳統的 sql 表操作差别還是挺大的。希望本文對朋友們了解 Azure Table storage 能有所幫助。

Azure Storage 是微軟 Azure 雲提供的雲端存儲解決方案,目前支援的存儲類型有 Blob、Queue、File 和 Table,其中的 Table 就是本文的主角 Azure Table storage。

Azure Table storage 是一個在雲端存儲結構化 NoSQL 資料的服務,它不僅存取速度快,而且效費比高。MSDN 上的說法是:成本顯著低于傳統 SQL!

筆者最近在項目中用 Table storage 實作了一個日志表,在此和大家分享一下 Table storage 的基本用法。

Azure storage account

首先需要說明,對 Blob、Queue、File 和 Table 這些 Azure 提供的存儲服務的通路控制都是通過 storage account 來進行的,是以要想使用 Table storage,需要先建立你的 storage account。

具體建立過程,MSDN 上有詳細講解。你需要了解一下 Access keys,因為它就是你通路 storage account 的使用者名和密碼:

Azure Table storage 基本用法 -- Azure Storage 之 Table

建立Table storage的對象

在使用 Azure Table storage 的相關對象前,我們需要安裝對應的包。安裝過程其實很簡單,隻需在 Visual Studi o的 Package Manager Console 中輸入:

Install-Package WindowsAzure.Storage      

Visual Studio 就會自動安裝 WindowsAzure.Storage 包及其依賴的所有包,安裝完成後的 packages.config 檔案看起來像這個樣子:

Azure Table storage 基本用法 -- Azure Storage 之 Table

安裝完相關的包以後,我們就可以使用其中的類型了。

CloudStorageAccount 類表示一個 Azure storage account,我們需要先建立它的執行個體,才能通路屬于它的資源。

//注意連接配接字元串中的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 中的内容:

Azure Table storage 基本用法 -- Azure Storage 之 Table

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試試:

Azure Table storage 基本用法 -- Azure Storage 之 Table

怎麼收到一個 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 能有所幫助。

相關閱讀:

最全的Windows Azure學習教程彙總

Azure Blob Storage 基本用法 -- Azure Storage 之 Blob

Azure Queue Storage 基本用法 -- Azure Storage 之 Queue

Azure File Storage 基本用法 -- Azure Storage 之 File

Azure Table storage 基本用法 -- Azure Storage 之 Table

本文是由葡萄城技術開發團隊釋出,轉載請注明出處:葡萄城官網

繼續閱讀