9

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

我将使用由两部分组成的复合键tenant_id以及增量 id。

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

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

谢谢

4

2 回答 2

2

您是否计划在未来使用 SQL Azure 联合?如果是这样,当前版本的 SQL Azure 联合不支持将 IDENTITY 用作聚集索引的一部分。有关更多详细信息,请参阅在 SQL Azure(联合)中将 guid 用作表上的聚集索引有哪些替代方法

如果您还没有看过联邦,您可能想看看它,因为它提供了一种有趣的方式来分片数据库和数据库内的租户隔离。

根据您的最终目标,使用联合,您可能能够使用 GUID 作为表上的主聚集索引,还可以使用表上的增量 INT IDENTITY 字段。这个 INT IDENTITY 字段可以显示给最终用户。如果您在 TenantID 上进行联合,则每个“租户表”实际上都变成了一个筒仓(至少据我所知),因此在该表中的字段上使用 IDENTITY 将有效地成为一个不断增加的自动生成值,该值在给定租户内递增.

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

于 2012-10-22T19:11:28.710 回答
1

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

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

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

一种相关的方法可能是拥有一个由表名、租户 ID 和当前身份值作为键的专用键值表。它需要相同的INSTEAD OF INSERT触发器和更多的样板来查询并保持该键表的更新。但它不会改善并行操作;锁将只是在不同表的记录上。

解决锁定瓶颈的一种可能性是将当前 SPID 包含在密钥的值中(现在标识密钥是顺序 int 和发生分配它的任何 SPID 的组合,而不是简单的顺序),使用专用标识值表并插入必要时按 SPID 记录;身份表 PK 将是(表名、租户、SPID),并且有一个具有当前顺序值的非键列。这样,每个 SPID 将拥有自己的动态分配的身份池,并且只会锁定自己的 SPID 特定记录。

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

于 2012-12-18T22:05:46.557 回答