【问题标题】:Composite primary key in multi-tenant SQL Server database多租户 SQL Server 数据库中的复合主键
【发布时间】:2015-06-23 23:23:18
【问题描述】:

我正在使用 ASP.NET Web Api、Entity Framework 和 SQL Server / Azure 数据库构建一个多租户应用程序(单个数据库、单个架构)。

此应用将被 1000-5000 名客户使用。所有表都将有一个 TenantId (Guid) 列。现在,我使用单列主键 Id (Guid)。

问题在于,我必须检查用户提供的数据是否来自/为正确的租户。例如,我有一个销售订单表,其中有一个 CustomerId 列。每次用户发布/更新销售订单时,我都必须检查CustomerId 是否来自同一个租户。

情况变得更糟,因为每个租户可能有多个网点。然后我必须检查 TenantId 和 OutletId。这真是一场维护噩梦,对性能不利。

我正在考虑将TenantIdId 一起添加为主键。也可能添加OutletId。所以销售订单表中的主键会有多个列,IdTenantIdOutletId

这种方法的缺点是什么?使用复合键会严重影响性能吗?复合键顺序重要吗?我的问题有更好的解决方案吗?

【问题讨论】:

  • 只是要明确一点:任何表都可以有恰好一个主键 - 永远不会超过一个。该主键可能由多列组成 - 但它仍然只是一个主键
  • 您能否以更好的方式解释这个问题?租户、客户、网点、销售等是什么关系,理解起来有点困难。
  • 我正在开发一个销售点应用程序。租户是购买我产品的客户。每个租户都有一个或多个商店/商店。每个租户都向他的客户出售东西。希望能解决我的问题
  • @marc_s 注意到。我已经更新了我的问题。对不起我的英语
  • Reynaldi você usa GUID na chave primária turnê? O que o desempenho? Eu estou tenho uma tabela com 20 百万 linha

标签: sql-server entity-framework azure asp.net-web-api azure-sql-database


【解决方案1】:
  1. 如果您想使用复合键,请始终(如果可能)使用键的所有元素以避免index range scans

  2. 元素的顺序很重要。例如,如果您想检索与单个租户相关的所有数据(参见第 1 部分),您应该使用 TenantId 作为第一个元素(参见 Why does primary key order matter?

  3. 对于 Azure SQL,您还应该考虑诸如 Elastic Scale 之类的概念,或者可以提高性能的旧系统分区。

  4. 您真的需要 TenantId 的 guid 吗?如果您的客户数量有限(this article)。如果提前需要tenant id,可以使用sequence(SQL Azure V12的新特性):

    create sequence CustomerSequence as int
         start with 0
         increment by 1;
    select next value for CustomerSequence;
    

编辑:添加了有关 SQL Azure 中序列的信息

【讨论】:

  • 是的,我认为对tenantId 字段使用整数来提高性能会更好。我使用 guid 是因为它更方便。因为当我添加租户时,我还需要将其他数据添加到其他表中。使用 guid 我可以立即获取值,而在身份字段中我必须在保存更改后等待。你知道如何处理吗?
  • 对于 SQL Azure 的最后一次更新,您可以使用序列:create sequence CustomerSequence as int start with 0 increment by 1select next value for CustomerSequence
猜你喜欢
  • 2011-07-20
  • 1970-01-01
  • 2012-10-10
  • 1970-01-01
  • 1970-01-01
  • 2011-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多