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
就概念上来讲,Table storage 只是 Azure 提供的存储服务的一种。其他的存储服务还有 Blob、Queue、File 等。对这些存储服务的访问控制都是通过 storage account 来进行的。所以要想使用 Table storage 需要先创建你的 storage account。具体创建过程不是本文重点,请参考 MSDN。但你需要去了解一下 Access keys,它就是你访问 storage account 的用户名和密码:

创建 Table storage 的对象
在使用 Azure Table storage 的相关对象前,我们需要安装对应的包。其实很简单,只需在 Visual Studio 的 Package Manager Console 中输入:
Install-Package WindowsAzure.Storage
Visual Studio 会自动安装 WindowsAzure.Storage 包及其依赖的所有包,安装完成后的 packages.config 文件看起来像这个样子:

安装完相关的包以后,我们就可以使用其中的类型了。
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 类型:
internal class MyLogEntity : 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 = ; i < ; 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%) == ? "error" : "warning";
batchOperation.Insert(logEntity);
Thread.Sleep();
}
logTable.ExecuteBatch(batchOperation);
这次我们把 TableOperation 类换成了 TableBatchOperation 类,然后一次插入十条数据。去检查一下结果,OK 十条数据全部插入成功!
下面让我们把循环中的 10 改成 200 试试:

怎么收到一个 InvalidOperationException 呢?看看红框中的内容,原来批量操作是有一些限制的:
1. 每个批量操作的数据上限是 100 条记录。
2. 每个批量操作中的数据都必须保持相同的 partition key。
请大家在使用批量操作时务必注意这些限制条件!
查询操作
对于日志数据的操作,最重要的就是查询。我们通过几个具体的用例来介绍 Table storage 的查询操作。
查询所有的记录
这是最简单的查询方法,一般是想要导出全部数据时才会这么干:
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);
}
查询某年的某个月的记录
要查询某个月的所有记录也是比较容易的,因为我们设计的 PartitionKey 就代表了某个月份:
TableQuery<MyLogEntity> query = new TableQuery<MyLogEntity>().Where(
TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, ""));
foreach (MyLogEntity entity in logTable.ExecuteQuery(query))
{
//...
}
请注意 TableQuery.GenerateFilterCondition 方法,我们创建了一个过滤条件:PartitionKey 等于 "201607"。这个查询会把所有 PartitionKey 为 "201607" 的记录都找到!
查询某一条记录
如果我们已经知道了一条记录的 PartitionKey 和 RowKey,就可以通过这两个条件直接查询到这条记录的详情:
TableQuery<MyLogEntity> query = new TableQuery<MyLogEntity>().Where(
TableQuery.CombineFilters(
TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, ""),
TableOperators.And,
TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, "")));
foreach (MyLogEntity entity in logTable.ExecuteQuery(query))
{
//...
}
这次我们使用了组合条件。虽然这里只使用了条件运算操作 TableOperators.And 和 QueryComparisons.Equal,你完全可以尝试其它的条件类型。唯一要注意的是:对于 PartitionKey 和 RowKey,QueryComparisons 的操作对象都是字符串。
我们还需要更多的查询条件,比如查询某一天产生的所有日志。在 MyLogTable 表中,这需要查询以 "xx" 字符串开头的 RowKey。我会单独在一篇文章中和大家分享相关内容,因为它并不像看起来的那么简单。
接下来我们介绍如何更新和删除日志表中的数据,当然这么做并不恰当,我们这里只是借用日志表介绍更新和删除操作而已。
更新记录
TableOperation retrieveOperation = TableOperation.Retrieve<MyLogEntity>("", "");
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>("", "");
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 能有所帮助。
Azure 基础:Table storage的更多相关文章
- Azure 基础:自定义 Table storage 查询条件
本文是在 <Azure 基础:Table storage> 一文的基础上介绍如何自定义 Azure Table storage 的查询过滤条件.如果您还不太清楚 Azure Table s ...
- 自定义 Azure Table storage 查询过滤条件
本文是在Azure Table storage 基本用法一文的基础上,介绍如何自定义 Azure Table storage 的查询过滤条件.如果您还不太清楚 Azure Table storage ...
- Windows Azure Table storage 之 动态Table类 DynamicTableEntity
在一般情况下,当我们在.net中使用Azure table storage的时候都会为该表建立一个TableEntity的派生类,如下所示. public class CustomerEntity : ...
- Azure 基础:Blob Storage
Azure Storage 是微软 Azure 云提供的云端存储解决方案,当前支持的存储类型有 Blob.Queue.File 和 Table. 笔者在前文中介绍了 Table Storage 的基本 ...
- Azure Storage 系列(四)在.Net 上使用Table Storage
一,引言 今天我们就不多说废话了,直接进入正题,Azure Table Storage.开始内容之前,我们先介绍一下Azure Table Storage. 1,什么是Azure Table Stor ...
- Azure Table storage 基本用法 -- Azure Storage 之 Table
Azure Storage 是微软 Azure 云提供的云端存储解决方案,当前支持的存储类型有 Blob.Queue.File 和 Table,其中的 Table 就是本文的主角 Azure Tabl ...
- Azure Table storage 之改进DynamicTableEntity类为其添加动态语言扩展
在之前的一篇文章中提到,storage类库中包含一个可以用来动态获取Azure table storage 表结构的类-DynamicTableEntity. 我们可以通过这个类,我们无需为每一个表提 ...
- Windows Azure入门教学系列 (六):使用Table Storage
本文是Windows Azure入门教学的第六篇文章. 本文将会介绍如何使用Table Storage.Table Storage提供给我们一个云端的表格结构.我们可以把他想象为XML文件或者是一个轻 ...
- Windows Azure Table Storage 解决 Guid 查询问题
在使用 Windows Azure Table Storage 的 CloudTableClient 对Azure 进行数据查询时,会发现在自定义类的Guid类型始终无法去成功查询出数据,对比发现 G ...
随机推荐
- AngularJS创建新指令 - 函数功能
首先先介绍下AngularJS指令下的几种函数 Link函数和Scope 指令生成出的模板其实没有太多意义,除非它在特定的scope下编译.默认情况下,指令并不会创建新的子scope.更多的,它使用父 ...
- CF #CROC 2016 - Elimination Round D. Robot Rapping Results Report 二分+拓扑排序
题目链接:http://codeforces.com/contest/655/problem/D 大意是给若干对偏序,问最少需要前多少对关系,可以确定所有的大小关系. 解法是二分答案,利用拓扑排序看是 ...
- JS作用域相关知识(#精)
在学习<你不知道的JS>一书中,特将作用域相关知识在此分享一下: #说到作用域,就不得不提到LHS查询和RHS查询: 1)如果查询目的是对变量进行赋值,则使用LHS查询 2)如果查询目的是 ...
- java类集框架(ArrayList,LinkedList,Vector区别)
主要分两个接口:collection和Map 主要分三类:集合(set).列表(List).映射(Map)1.集合:没有重复对象,没有特定排序方式2.列表:对象按索引位置排序,可以有重复对象3.映射: ...
- javascript中类式继承和原型式继承的实现方法和区别
在所有面向对象的编程中,继承是一个重要的话题.一般说来,在设计类的时候,我们希望能减少重复性的代码,并且尽量弱化对象间的耦合(让一个类继承另一个类可能会导致二者产生强耦合).关于“解耦”是程序设计中另 ...
- Java设计模式———静态工厂
上课时yqj2065要求:除了JDK等框架或工具中的类,自己编写的类不得使用new创建对象(Test除外). 据说是因为使用new会涉及到硬编码.(不是很懂) 所以要求用God类利用反射+配置文件来创 ...
- poj1751最小生成树
The island nation of Flatopia is perfectly flat. Unfortunately, Flatopia has a very poor system of p ...
- SSM框架搭建——我的第一个SSM项目
转载自:http://blog.csdn.net/tmaskboy/article/details/51464791 作者使用MyEclipse 2014版本 本博客所编写程序源码为: http:// ...
- 【Android Widget】1.TextView
1.创建可被点击的TextView 1.1 在xml中创建可被点击的TextView android:autoLink 是否将符合指定格式的文本转换成可单击的超链接. 属性值可以是如下几个属性值的一个 ...
- 0基础搭建Hadoop大数据处理-集群安装
经过一系列的前期环境准备,现在可以开始Hadoop的安装了,在这里去apache官网下载2.7.3的版本 http://www.apache.org/dyn/closer.cgi/hadoop/com ...