本帖最后由 断天涯大虾 于 2016-11-16 17:54 编辑
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 的用户名和密码: 创建Table storage的对象在使用 Azure Table storage 的相关对象前,我们需要安装对应的包。安装过程其实很简单,只需在 Visual Studi o的 Package Manager Console 中输入: - <font face="微软雅黑" size="3" color="#000000">Install-Package WindowsAzure.Storage</font>
复制代码Visual Studio 就会自动安装 WindowsAzure.Storage 包及其依赖的所有包,安装完成后的 packages.config 文件看起来像这个样子:
安装完相关的包以后,我们就可以使用其中的类型了。 CloudStorageAccount 类表示一个 Azure storage account,我们需要先创建它的实例,才能访问属于它的资源。 - <font face="微软雅黑" size="3" color="#000000">//注意连接字符串中的xxx和yyy,分别对应Access keys中的Storage account name 和 key。
- CloudStorageAccount storageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=xxx;AccountKey=yyy");</font>
复制代码CloudTableClient 类是 Windows Azure Table Service 客户端的逻辑表示,我们需要使用它来配置和执行对 Table storage 的操作。 - <font face="微软雅黑" size="3" color="#000000">CloudTableClient cloudTableClient = storageAccount.CreateCloudTableClient();</font>
复制代码CloudTable 类表示一张数据表。 我们需要创建一个实例去引用 Table storage 中的一张表,测试用的表名叫”MyLogTable”。 - <font face="微软雅黑" size="3" color="#000000">CloudTable logTable = cloudTableClient.GetTableReference("MyLogTable");</font>
复制代码这样在后面的操作中就可以确保 MyLogTable 表是存在的,有了 logTable 对象我们就可以向表中插入数据了。 但是等等,好像少了点什么。 我们开篇第一句中就说明了,Table storage 存储的是结构化的数据,所以我们还要先定义存储的数据的类型。 定义日志类在定义我们自己的数据类型时,有一个强制性的要求,必须继承自 TableEntity 类型: - <font face="微软雅黑" size="3" color="#000000">{
- 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; }
- }</font>
复制代码在我们的设计中,PartitionKey 用来存放产生日志的年份和月份(例如 201607),RowKey 用来存放产生日志的天和时分秒毫秒(例如 160934248492),日志数据主要是 LogDate, LogMessage 和 ErrorType。 把数据插入到Table storage 终于可以向表中插入数据了,先试一下: - <font face="微软雅黑" size="3" color="#000000">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);</font>
复制代码
看起来还不错,我们用 Visual Studio 自带的 Cloud Explorer 查看一下 MyLogTable 中的内容:
OK,数据已经成功插入到 MyLogTable 表中,接下来我们看看如何批量的插入数据。 - <font face="微软雅黑" size="3" color="#000000">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);</font>
复制代码这次我们把 TableOperation 类换成了 TableBatchOperation 类,然后一次插入十条数据。去检查一下结果,OK十条数据全部插入成功! 下面让我们把循环中的10改成200试试:
怎么收到一个 InvalidOperationException 呢?看看红框中的内容,原来批量操作是有一些限制的: 1. 每个批量操作的数据上限是100条记录。 2. 每个批量操作中的数据都必须保持相同的 partition key。 请大家在使用批量操作时务必注意这些限制条件! 查询操作对于日志数据的操作,最重要的就是查询,我们通过几个具体的用例来介绍 Table storage 的查询操作。 1. 查询所有的记录 这是最简单的查询方法,一般是想要导出全部数据时才会这么干: - <font face="微软雅黑" size="3" color="#000000">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);
- }</font>
复制代码2.查询某年的某个月的记录 要查询某个月的所有记录也是比较容易的,因为我们设计的 PartitionKey 就代表了某个月份: - <font face="微软雅黑" size="3" color="#000000">TableQuery<MyLogEntity> query = new TableQuery<MyLogEntity>().Where(
- TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "201607"));
- foreach (MyLogEntity entity in logTable.ExecuteQuery(query))
- {
- //...
- }</font>
复制代码请注意TableQuery.GenerateFilterCondition方法,我们创建了一个过滤条件:PartitionKey等于“201607”这个查询会把所有PartitionKey为“201607”的记录都找到! 3.查询某一条记录 如果我们已经知道了一条记录的 PartitionKey 和 RowKey,就可以通过这两个条件直接查询到这条记录的详情: - <font face="微软雅黑" size="3" color="#000000">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))
- {
- //...
- }
- </font>
复制代码这次我们使用了组合条件,只用到了条件运算操作TableOperators.And和QueryComparisons.Equal,当然你也可以尝试其它的条件类型唯一要注意的就是:PartitionKey和RowKey,QueryComparisons的操作对象都是字符串。 我们还需要更多的查询条件,比如查询某一天产生的所有日志。在 MyLogTable 表中,这需要查询以”xx”字符串开头的 RowKey。这部分知识,我会单独在一篇文章中和大家分享相关内容,因为它并不像看起来的那么简单。 接下来我们介绍如何更新和删除日志表中的数据,这里只是借用日志表介绍更新和删除操作。 更新记录- <font face="微软雅黑" size="3" color="#000000">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);
- }
- </font>
复制代码这次我们先用TableOperation.Retrieve方法获得一条数据的详情,然后更新它的LogMessage属性,最后使用TableOperation.Replace方法把新的内容更新的到Tablestorage中。
删除记录
删除一条记录和更新一条记录是基本一样的步骤,不同点是把 TableOperation.Replace 方法换成 TableOperation.Delete 方法: - <font face="微软雅黑" size="3" color="#000000">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);
- }</font>
复制代码删除表 删除表和创建表一样简单(可比删除一条记录容易多了): - <font face="微软雅黑" size="3" color="#000000">logTable.DeleteIfExists();</font>
复制代码总结,本文通过对一个日志表的操作介绍了 Azure Table storage 的一个典型应用场景和基本的使用方法,从操作的代码上看和传统的 sql 表操作差别还是挺大的。希望本文对朋友们了解 Azure Table storage 能有所帮助。
关于葡萄城 葡萄城成立于1980年,是全球最大的控件提供商,世界领先的企业应用定制工具、企业报表和商业智能解决方案提供商,为超过75%的全球财富500强企业提供服务。葡萄城于1988年在中国设立研发中心,在全球化产品的研发过程中,不断适应中国市场的本地需求,并为软件企业和各行业的信息化提供优秀的软件工具和咨询服务。
部分控件产品(点击图片查看)
|