多租户数据库模式的标识列

时间:2010-09-21 11:27:48

标签: sql-server transactions locking

我正在创建一个多租户应用,其中一些表需要按顺序分配整数值。订单是为每个租户独立完成的。作为一个具体示例,请考虑Student表,其中包含RegNumber列。 RegNumber必须按顺序分配,但序列对每个租户都是本地的。

我正在考虑的解决方案涉及使用另一个表来保存每个租户的“下一个可用”RegNumber值,这引出了几个问题:

  1. 有更好的方法吗?
  2. 在没有过多锁定的情况下,在单个事务中执行“SELECT FROM tenant_studentid_sequence”和“INSERT INTO students”的最佳方法是什么?没有跳过或复制值的可能性?
  3. 在MySQL中,我可以使用SELECT FOR UPDATE,但是SQL Server 2008呢?有很多讨论on this SO question,但它似乎是基于SQL Server 2005. 2008年的任何变化?什么是推荐的策略?

    编辑1:我想我应该通过“为每个租户独立”来澄清我的意思。我正在寻找的是每个租户都有一个顺序排列的学生ID的方法。也就是说,租户A将拥有ID为1,2,3,......的学生,因此租户B将其视为业务密钥。我有全局身份的GUID,这是客户隐藏的。

2 个答案:

答案 0 :(得分:1)

您是否在努力保证RegNumber在所有租户中都是唯一的?如果是这样,这就是我在类似情况下所做的。使用自动递增IDENTITY属性,使用seed标识每位数字中的每个租户,然后使用increment标识10。

CREATE TABLE Student (
   RegNumber INT IDENTITY(1,10),
   ...
)

租户1

IDENTITY(1,10) - 生成ID:1,11,21,31,......

租户2

IDENTITY(2,10) - 生成ID:2,12,22,32,...

租户3

IDENTITY(3,10) - 生成ID:3,13,23,33,......

最多可容纳10名租户。如果您需要扩展,只需根据需要通过递增100(或1000或10000 ...)来扩展此概念。

答案 1 :(得分:0)

如果您需要生成的ID数量很少(几百个),您可以使用SELECT MAX(student_id)+1 FROM Student WHERE tenant_id = :tenant。如果您使用学生和租户ID添加索引,优化程序应使用该索引而不是主表,这将有助于将锁定保持在最低限度。

如果您正在谈论成千上万的ID,那么您可能需要考虑制作一个分发ID值的“ID服务器”。在启动时,它将使用每个租户的最大值初始化自己,然后在您向其请求ID时返回序列中的下一个值。您希望有一些方法让它自行重置(通过重新读取数据库),以防由于事务中止或某事而结束“浪费”ID。