【IT168 微软云计算博客征文活动专稿】SQL Azure目前只支持1GB和10GB大小的数据库,如果你想在SQL Azure中存储更多的数据,可以将你的表进行拆分,然后将表的不同部分分别放到多个SQL Azure数据库上。本文将讨论如何使用一个中间层通过LINQ连接到不同数据库上的两个表,这项技术涉及到对SQL Azure中的数据进行垂直分区。
这里我们将方案(Schema)中的所有表拆解到两个或更多SQL Azure数据库上,再选择哪些表组合到一起放在某个数据库上时,你需要了解每张表的大小,以及它们的增长速度,我们的目标是进行平均分配,使每个数据库的大小保持基本一致。
对表进行分区后,性能方面也会有提高,因为SQLAzure在不同物理机器上分散了你的数据库,通过对工作量进行分解,你可以获得更多的CPU和内存资源。例如,如果你将你的数据库划分成10个1GB的SQL Azure数据库,你将获得10倍的CPU和内存资源。我们来看一个案例 TicketDirect ( http://www.microsoft.com/casestudies/Case_Study_Detail.aspx?CaseStudyID=4000005890 ),在高峰阶段,他们将工作量分解到数百个SQL Azure数据库上。
跨SQL Azure数据库分解你的工作量时,你会失去在单一数据库上托管所有表的某些功能,使用这项技术时,需要考虑以下这些内容:
· 跨数据库的外键是不支持的,换句话说就是,数据库1中表的主键不能作为数据库2中表的外键引用,SQL Server跨数据库外键支持有着同样的限制。
· 不能有跨数据库的事务,即使你在客户端使用了分布式事务管理器也不行,这意味着如果在数据库2上的插入操作失败,你不能在数据库1上执行插入操作的回滚。这个限制可以通过客户端编码消除掉,你需要捕捉异常,并在成功完成语句的数据库上执行“undo”脚本。
SQLAzureHelper 类
为了实现垂直分区,我们引入 SQLAzureHelper 类,它:
· 实现了前向只读游标;
· 支持 IEnumerable 和LINQ;
· 当不再需要结果集时,处理连接和数据读取器。
使用前向只读游标可以提高性能,这意味着直到需要数据时,才会从SQL Azure中提取数据。从 SQLAzureHelper 类获得结果集的代码如下:
ConfigurationManager.ConnectionStrings["ColorDatabase"].ConnectionString,
sqlConnection =>
{
SqlCommand sqlCommand =
new SqlCommand("SELECT ColorName, CompanyId FROM Colors",
sqlConnection);
return (sqlCommand.ExecuteReader());
});
var companyDataReader = SQLAzureHelper.ExecuteReader(
ConfigurationManager.ConnectionStrings["CompanyDatabase"].ConnectionString,
sqlConnection =>
{
SqlCommand sqlCommand =
new SqlCommand("SELECT CompanyId, CompanyName FROM Companies",
sqlConnection);
return (sqlCommand.ExecuteReader());
});
使用LINQ连接时,从两个SQL Server数据库返回结果集。
LINQ
LINQ是.NET框架的一套扩展,包含语言集成查询,设置和转换操作,它用本地语言语法扩展了C#和Visual Basic的查询功能,并提供了类库使用这些功能,下面的代码使用LINQ作为客户端查询处理器执行连接和查询两个结果集。
from color in colorDataReader
join company in companyDataReader on
(Int32)color["CompanyId"] equals (Int32)company["CompanyId"]
select new
{
ColorName = (string)color["ColorName"],
CompanyName = (string)company["CompanyName"]
};
foreach (var combo in query)
{
Console.WriteLine(String.Format("{0} - {1}", combo.CompanyName, combo.ColorName));
}
获得结果集后,通过 CompanyId 将两个结果集连接起来,然后再选择由 CompanyName 和 ColorName 组成的新类。