2015-05-04 51 views
1

我正在将我的数据模型移动到Azure弹性分级。Azure弹性分片分片键

经过一些测试和一些经验,如果它坠入爱河,它很简单,并且采用这种方法,代码仍然清洁易于维护。

我只是有一个大问题,其中是定义的分片键?我无法找到从Visual Studio下载的示例的信息,我可以打败,这是一个直截了当的答案。

在Microsoft提供的示例中,默认分片密钥是CustomerId但我无法找到引用该密钥的地方。

它可以在配置文件中的ShardMapName?

在此先感谢。

回答

2

SQL模式中的分片键与其用法(在代码中)之间没有明确的关联。

所以入门样本中,客户和订单表都包含CustomerId列,你可以看到,在DataDependentRoutingSample.cs当我们访问这些表我们确保提供相同customerId值到shardMap.OpenConnectionForKey方法然后我们在以下查询中使用customerId列(在SELECT和INSERT语句中)。

// Looks up the key in the shard map and opens a connection to the shard 
using (SqlConnection conn = shardMap.OpenConnectionForKey(customerId, credentialsConnectionString)) 
{ 
    // Create a simple command that will insert or update the customer information 
    SqlCommand cmd = conn.CreateCommand(); 
    cmd.CommandText = @" 
    IF EXISTS (SELECT 1 FROM Customers WHERE CustomerId = @customerId) 
     UPDATE Customers 
      SET Name = @name, RegionId = @regionId 
      WHERE CustomerId = @customerId 
    ELSE 
     INSERT INTO Customers (CustomerId, Name, RegionId) 
     VALUES (@customerId, @name, @regionId)"; 
    cmd.Parameters.AddWithValue("@customerId", customerId); 
    cmd.Parameters.AddWithValue("@name", name); 
    cmd.Parameters.AddWithValue("@regionId", regionId); 
    cmd.CommandTimeout = 60; 

    // Execute the command 
    cmd.ExecuteNonQuery(); 
} 

换句话说,当你提供在OpenConnectionForKey调用某个键值,这是你的责任,以确保与该连接所有SQL查询都仅限于该键值,否则你可能最终与不正确结果(例如,如果它是SELECT查询)或生活在错误分片上的行(例如,如果它是INSERT查询)。

通过使用新的行级安全功能可以解决此安全问题。我们有一个名为Entity Framework Multi-Tenant Shards的示例,演示了如何将碎片映射与行级安全结合。相关的代码在ElasticScaleContext.cs

SqlConnection conn = null; 
try 
{ 
    // Ask shard map to broker a validated connection for the given key 
    conn = shardMap.OpenConnectionForKey(shardingKey, connectionStr, ConnectionOptions.Validate); 

    // Set CONTEXT_INFO to shardingKey to enable Row-Level Security filtering 
    SqlCommand cmd = conn.CreateCommand(); 
    cmd.CommandText = @"SET CONTEXT_INFO @shardingKey"; 
    cmd.Parameters.AddWithValue("@shardingKey", shardingKey); 
    cmd.ExecuteNonQuery(); 

    return conn; 
} 
catch (Exception) 
{ 
    if (conn != null) 
    { 
     conn.Dispose(); 
    } 

    throw; 
} 

感谢您的好问题!

+1

这是一个很好的答案谢谢。我的应用程序使用实体框架,但我并不想依赖它,所以我可以随时移动到另一个框架。无论如何,作为一个伟大的帮助,我认为这个问题将有助于很多人在未来 –

+0

干杯。我想澄清一下,使用'@“SET CONTEXT_INFO @shardingKey”'的上述代码段与EF无关,您可以轻松使用原始SqlClient,Dapper或您喜欢的任何其他SQL Server数据库访问层的相同技术。 –