多租户主键的最佳方法

时间:2012-09-16 20:59:00

标签: sql primary-key multi-tenant

我有几个客户使用的数据库。我真的不希望代理增量键值在客户端之间流血。我希望编号从1开始,并且是客户特定的。

我将使用tenant_id的两部分组合键以及增量ID。

为每个租户创建增量密钥的最佳方法是什么?

我正在使用SQL Server Azure。我担心锁定表,重复键等。我通常将主键设置为IDENTITY并继续。

由于

2 个答案:

答案 0 :(得分:2)

您计划将来使用SQL Azure Federations吗?如果是这样,当前版本的SQL Azure Federations不支持将IDENTITY用作聚簇索引的一部分。有关详细信息,请参阅此What alternatives exist to using guid as clustered index on tables in SQL Azure (Federations)

如果您还没有查看过Federations,您可能需要查看它,因为它提供了一种有趣的方法来分割数据库和数据库中的租户隔离。

根据您的最终目标,使用联合,您可以使用GUID作为表上的主聚集索引,并在表上使用增量INT IDENTITY字段。可以向最终用户显示此INT IDENTITY字段。如果您在TenantID上进行联合,则每个“租户表”实际上变成了一个孤岛(至少我理解它),因此在该表中的字段上使用IDENTITY实际上将是一个不断增加的自动生成值,该值在给定租户中递增

当\如果数据合并在一起(组合来自多个租户的数据)时,您最终会在此INT IDENTITY字段上发生冲突(因此,为什么IDENTITY不支持作为联盟中的主键),但只要您不是使用此字段作为整个系统中的唯一标识符,您应该没问题。

答案 1 :(得分:1)

如果您希望复制插入时自动分配的唯一INT键的便利性,您可以添加INSTEAD OF INSERT触发器,该触发器使用现有列+1的MAX来确定下一个值。

如果具有标识值的列是索引中的第一个键,则MAX查询将是一个简单的索引查找,非常有效。

事务将确保分配唯一值,但此方法将具有与标准标识列不同的锁定语义。 IIRC,SQL Server可以为并行请求它的每个事务分配不同的标识值,如果事务被回滚,则丢弃分配给它的值。 MAX方法只允许一个事务一次在表中插入行。

相关方法可以是具有由表名,租户ID和当前标识值键控的专用键值表。它需要相同的INSTEAD OF INSERT触发器和更多样板来查询并保持更新密钥表。但它不会改善并行操作;锁只会在另一张桌子的记录上。

修复锁定瓶颈的一种可能性是将当前SPID包含在密钥的值中(现在,标识密钥是顺序int和任何分配它的SPID的组合,而不仅仅是顺序),使用专用标识值表格并根据需要在每个SPID处插入记录;身份表PK将是(表名,租户,SPID)并具有带有当前顺序值的非键列。这样,每个SPID都有自己动态分配的标识池,并且只会锁定自己的SPID特定记录。

另一个缺点是维护在每次更改任何特殊身份表中的列时都必须更新的触发器。