1

我正在将我的数据模型移动到 Azure Elastic Sc​​ale。

经过一些测试和一些经验,我爱上了它,它很简单,并且通过这种方法,代码保持干净且易于维护。

我只有一个大问题,分片键在哪里定义?我找不到从 Visual Studio 下载的示例的信息,我可以说这是一个直截了当的答案。

在 Microsoft 提供的示例中,默认分片键是CustomerId,但我找不到对该键的引用发生的位置。

它可能在配置文件中的 ShardMapName 中吗?

提前致谢。

4

1 回答 1

2

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

因此,在 Getting Started 示例中,Customers 和 Orders 表都包含一个CustomerId列,您可以在 DataDependentRoutingSample.cs 中看到,当我们访问这些表时,我们确保为我们随后用于 customerId 列customerId的方法提供相同的值( shardMap.OpenConnectionForKeySELECT 和 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的示例,它演示了如何将 Shard Maps 与行级安全性相结合。相关代码在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; 
}

谢谢你的好问题!

于 2015-05-04T17:30:00.197 回答