More about “PartitionKey”&"RowKey” in windows azure table storage
windows azure table storage 为海量存储和负载平衡提供了捷径。
这是一张引用msdn的Table存储Entity的图.
区别于关系型数据库,一个azure table 可以存储不同类型的实体。
每一个Table 行, 都有 PartitionKey,RowKey,TimeStamp 3个系统属性。
TimeStamp由系统维护,记录最后操作该记录的时间,时间为UTC.
没有了关系型数据库的束缚,您可以更加专注于Class的设计了^_^.
怎么比较充分的利用Table storage service呢?
怎么样的查询更优化呢?
看了 这个视频(Windows Azure Tables and Queues Deep Dive), 有一点点感触:
合理设计PartitionKey 和 RowKey 将有效的提高程序效率。
PartitionKey 和 RowKey的组合可以唯一定位一个实体行。
Windows Azure Table service可以利用 PartitionKey 进行负载平衡。
相同PartitionKey的数据会存储在同一个区里面。
相同PartitionKey的数据操作才能启动事务操作。
不同PartitionKey的数据(区)可能位于不同的服务器上。
使用合理的PartitionKey 和 RowKey 查询,避免全表扫描。
一个例子:
实体Video,包含Category,SubCategory,Id,IsPublic…等属性。
可能:
PartitionKey 的格式为:Category.
这样便于相同分类的数据存放在同一个区。
可能:
PartitionKey 的格式为:Category_SubCategory
这样,如果一个Category包含的数据太多,便于查询,将更多的区来存储。
需要按照具体的业务来设计Table存储的结构达到相对的优化。
这里 假设PartitionKey 的格式为:Category_SubCategory
利用 PartitionKey 来查询 避免全表扫描:
var query = _serviceContext.VideoTable.AsTableServiceQuery() .Where(c => c.PartitionKey=="Sport_China");
这样可以快速检索到 Category = “Sport” && SubCategory=”China” 的数据了。
试想,如果PartitionKey放入了其他无意义的值(比如随意的Videos),
那么 要检索Category = “Sport” && SubCategory=”China” 这样的数据,将不得不全表扫描:
var query = _serviceContext.VideoTable.AsTableServiceQuery() .Where(c => c.Category == “Sport” && c.SubCategory==”China”);
如果不得不全表扫描的话,怎么办呢,最好使用 并行查询 来操作。
如果表很大,Windows Azure ,一次只能返回 1000 行(或处理 5 秒)(目前来看是这样,整个azure 平台在不断的更新中。)
并行查询 在.net4.0中也是变得非常容易了,这种情况下,应该尽量考虑。
另外,不要在本地模拟环境去测试 azure table storage service的性能,这个和实际部署到云端的性能 完全不是一个数量级的。
确保程序可用以后,尽量在云端做性能调优。
本地模拟环境的 【table storage service和云端table storage service差距】 相对于 【本地调用Sql Azure和云端调用Sql Azure的差距】 大很多。
当有海量需要数据存储,有不需要严格的关系DB时候,应该尽量考虑table storage service,而不是Sql Azure. 不管从程序上考虑还是费用上 ^_^.
以上仅仅个人关于一点点table storage service的一点点理解,欢迎指正。