简体   繁体   English

多租户数据库架构的标识列

[英]Identity columns for multitenant database schemas

I'm creating a multitenant app where some of the tables need to have sequentially assigned integer values. 我正在创建一个多租户应用程序,其中的某些表需要具有顺序分配的整数值。 The ordering is done independently for each tenant. 订购是针对每个租户独立完成的。 As a concrete example, consider a Student table with a RegNumber column. 作为一个具体的示例,请考虑带有RegNumber列的Student表。 RegNumber has to be assigned sequentially, but the sequence is local to each tenant. RegNumber必须顺序分配,但是顺序对于每个租户都是本地的。

The solution I'm thinking of involves using another table to hold the "next available" RegNumber value for each tenant, which leads me to a couple of questions: 我正在考虑的解决方案涉及使用另一个表为每个租户保存“下一个可用” RegNumber值,这使我RegNumber了两个问题:

  1. Is there a better way? 有没有更好的办法?
  2. What is the best way to do a "SELECT FROM tenant_studentid_sequence" and "INSERT INTO students" in a single transaction without excessive locking, and without the possibility of skipping or duplicating values? 在单个事务中进行“ SELECT FROM tenant_studentid_sequence”和“ INSERT INTO students”的最佳方法是什么,而又不会过度锁定,也不会跳过或复制值?

In MySQL, I could use SELECT FOR UPDATE, but what about SQL Server 2008? 在MySQL中,我可以使用SELECT FOR UPDATE,但是SQL Server 2008呢? There's quite a bit of discussion on this SO question , but it seems to be based on SQL Server 2005. Any changes in 2008? 关于此SO问题有很多讨论,但它似乎是基于SQL Server2005。2008年有何变化? What's the recommended strategy? 推荐的策略是什么?

Edit 1: I think I should clarify what I meant by "independently for each tenant". 编辑1:我认为我应该澄清“每个租户独立”的意思。 What I'm looking for is a way for each tenant to have a sequentially ordered set of student IDs. 我正在寻找的是让每个租户拥有按顺序排序的一组学生ID的方法。 That is, tenant A will have students with IDs 1, 2, 3, ..., and so will tenant B. Think of them as business keys. 也就是说,租户A将拥有ID为1、2、3,...的学生,租户B也将具有ID。将其视为业务密钥。 I have GUIDs for global identity which is hidden from the customer. 我有全局标识的GUID,对客户隐藏了。

Are you trying to guarantee that RegNumber is unique across all tenants? 您是否要确保RegNumber在所有租户中都是唯一的? If so, here's what I've done in similar situations. 如果是这样,这就是我在类似情况下所做的。 Use the auto-incrementing IDENTITY property, use the seed to identify each tenant in the ones digit and then increment by 10. 使用自动递增的IDENTITY属性,使用seed标识一位数字中的每个租户,然后increment 10。

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

Tenant 1 租户1

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

Tenant 2 租户2

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

Tenant 3 租户3

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

etc. 等等

This will work up to 10 tenants. 最多可容纳10个租户。 If you need to expand beyond that, simply extend this concept by incrementing by 100 (or 1000 or 10000...) instead as needed. 如果您需要扩展此范围,只需通过按需增加100(或1000或10000 ...)来扩展此概念即可。

If the number of IDs you need to generate is small (a few hundred), you can just use SELECT MAX(student_id)+1 FROM Student WHERE tenant_id = :tenant . 如果您需要生成的ID数量很少(几百个),则可以使用SELECT MAX(student_id)+1 FROM Student WHERE tenant_id = :tenant If you add an index with the student and tenant IDs, the optimizer should use that instead of the main table and this will help keep locking to a minimum. 如果添加带有学生ID和租户ID的索引,则优化程序应使用索引而不是主表,这将有助于将锁定保持在最低水平。

If you're talking thousands of IDs, then you might want to consider making an "ID server" that hands out ID values. 如果您要谈论成千上万个ID,那么您可能要考虑制作一个分发ID值的“ ID服务器”。 At startup it would initialize itself with the max values for each tenant, then just return the next value in the sequence when you asked it for an ID. 在启动时,它将使用每个租户的最大值初始化自身,然后在您要求其提供ID时仅返回序列中的下一个值。 You'd want to have some way to make it reset itself (by re-reading the database) in case you wind up "wasting" an ID due to a transaction abort or something. 您希望有某种方法使其重置自身(通过重新读取数据库),以防万一由于事务中止或其他原因而“浪费”了ID。

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

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