简体   繁体   English

多租户SQL Server数据库中的复合主键

[英]Composite primary key in multi-tenant SQL Server database

I'm building a multi-tenant app (single database, single schema) using ASP.NET Web Api, Entity Framework and SQL Server / Azure database. 我正在使用ASP.NET Web Api,实体框架和SQL Server / Azure数据库构建多租户应用程序(单个数据库,单个架构)。

This app will be used by 1000-5000 customers. 此应用将由1000-5000个客户使用。 All the tables will have a TenantId ( Guid ) column. 所有表都将有一个TenantIdGuid )列。 Right now, I use single column primary key which is Id ( Guid ). 现在,我使用的是IdGuid )的单列主键。

The problem with that is, I have to check if the data supplied by the user is from / for the right tenant. 问题是,我必须检查用户提供的数据是否来自正确的租户。 Eg I have a sales order table which has a CustomerId column. 例如,我有一个包含CustomerId列的销售订单表。 Everytime user post/update sales order, I have to check if the CustomerId is from the same tenant. 每次用户发布/更新销售订单时,我都必须检查CustomerId是否来自同一租户。

It gets worse because each tenant might have several outlets. 情况变得更糟,因为每个租户可能都有多个出口。 Then I have to check TenantId and OutletId. 然后,我必须检查TenantId和OutletId。 It's really a maintenance nightmare and bad for performance. 这确实是维护的噩梦,并且对性能不利。

I'm thinking to add TenantId as primary key along with Id . 我正在考虑将TenantIdId一起添加为主键。 And possibly add OutletId too. 并可能也添加OutletId So primary key in sales order table will have multiple columns, Id , TenantId , OutletId . 因此,销售订单表中的主键将具有IdTenantIdOutletId多个列。

What is the downside of this approach? 这种方法的缺点是什么? Would the performance hurt badly using composite key? 使用复合键会严重损害性能吗? Does the composite key order matter? 复合键顺序重要吗? Are there better solution for my problem? 我的问题有更好的解决方案吗?

  1. If you want to use a composite key please use always (if possible) all elements of the key to avoid index range scans 如果要使用组合键,请始终(如果可能)使用键的所有元素,以避免索引范围扫描

  2. The order of elements is important. 元素的顺序很重要。 If you want to retrieve for example all data related to a single tenant (see pt. 1) you should use TenantId as the first element (see Why does primary key order matter? ) 例如,如果要检索与单个租户有关的所有数据(请参阅第1页),则应使用TenantId作为第一个元素(请参阅为什么主键顺序很重要?

  3. For Azure SQL you should also consider concepts like Elastic Scale or partitioning for legacy systems which could improve performance. 对于Azure SQL,您还应该考虑诸如Elastic Sc​​ale或对旧系统进行分区等概念,这些概念可以提高性能。

  4. Do you really need a guid for the TenantId? 您真的需要TenantId的向导吗? If you have a limited amount of customers (<= 5000 is not that much) you could also use a int (or even int64) type which would allow easier partitioning (see pt. 3)... I do like guids a lot, but for ease of maintenance and if I do not need the big range for data I try to avoid them (see this article for performance). 如果您的客户数量有限(<= 5000不那么多),您还可以使用int(甚至int64)类型,这将使​​分区更容易(请参阅第3页)...我非常喜欢guid,但是为了易于维护,如果不需要大量数据,我会尽量避免使用它们(有关性能,请参阅本文 )。 If you need the tenant id in advance, you can use sequences (a new feature for SQL Azure V12): 如果事先需要租户ID,则可以使用序列(SQL Azure V12的一项新功能):

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

EDIT: Added information about sequences in SQL Azure 编辑:添加了有关SQL Azure中序列的信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM