【问题标题】:Auto increment ids starting at 1 per tenant in a single database单个数据库中每个租户从 1 开始的自动增量 ID
【发布时间】:2022-01-06 17:01:38
【问题描述】:

我正在使用单个数据库创建租户门户应用程序。是的,我已经权衡了使用单个数据库与拆分它们的利弊。

我所有的表都有一个 Id (int)、TenantId (int)。

是否有任何可能的方法使每个租户从每个表的 id:1 开始?

例如我想:
(项目表)
租户 1
ID:1,租户 ID:1
ID:2,租户 ID:1
ID:3,租户 ID:1

租户 2
ID:1,租户 ID:2
ID:2,租户 ID:2
ID:3,租户 ID:2


而不是:
租户 2
ID:4,租户 ID:2
ID:5,租户 ID:2
ID:6,租户 ID:2

我已经考虑过使用 guid,但我讨厌它们在 url 中的外观。 我想知道是否可以使用 guid 作为唯一 id,但将其与用户屏蔽,并且只向他们显示 id。然后我需要某种机制来在我的代码中正确地手动增加 id 列。

只是想从经验中弄清楚有人会如何处理这个问题。可以纯粹在sql server中完成吗?

【问题讨论】:

  • 您是否对简单地隐藏网址感到困难?
  • @squillman 我确实有一个租户表,其中包含我的租户,以及他们的唯一 ID。我的问题在于数据表。
  • 除了在 url 中的视觉效果之外,id 是否真的很重要?似乎这将是管理复合 id 的大量工作,但收益甚微。
  • 你想多了。你永远不应该围绕 URL 中的值来设计你的数据库。您设计数据库以对数据进行建模。
  • 不确定您最后的评论是什么意思。但同样,您不需要设计数据库,因此很容易编码。如果任何使用 guid 的东西使得猜测查询字符串值变得困难,那么用户就不能通过通过查询字符串注入数据来开始查看其他数据。

标签: c# sql-server multi-tenant


【解决方案1】:

您是否尝试过复合主键?这将允许您输入所需的 ID 值,您可以通过表格查找轻松找出。

【讨论】:

  • 如果我走这条路,我需要在我的代码中增加 ID 值而不是 SQLServer 正确吗?
  • 是的,因为自动增量 ID 会按照您所描述的方式执行您不想要的情况。我认为在 sql 中简单检查租户 id 的计数也可以。
  • 我知道了,上面 cmets 中的人正在说服我不要担心它,因为我永远不会在实际 UI 上列出任何实体的 ID。就在网址中。它会为我省去很多麻烦。
  • IE:插入表(id,tennantid)值((从表中选择count(*)+1,其中tennantid = [tennantid]),[tennantid])
  • COUNT(*) + 1 不起作用,因为如果插入 1,2,3,4 然后删除 3 会怎样?您将再次插入 4。你需要可序列化的 MAX+1,它会抑制并发,另一个复杂的问题是如果你创建 4,然后删除 4,是否可以重复使用该数字?我同意其他人的观点 - 您的用户不应该关心分配给他们的项目的 ID,因为他们应该通过名称来识别它。如果您关心 URL 中显示的内容,请停止使用 URL。它只是让人无论如何都想弄乱它(“我想知道354项目中有什么?在这里,我可以试试。”)
【解决方案2】:

您需要一个存储序列的表和一个存储过程来获取下一个序列值。

CREATE TABLE [Sequence]
(
    [TenantId] INT,
    [Name] NVARCHAR(60),
    [NextValue] INT,

    CONSTRAINT [PK_Sequence] PRIMARY KEY CLUSTERED
    (
        [TenantId] ASC,
        [Name] ASC
    )
);
GO;


CREATE PROCEDURE [dbo].[GetNextSequenceValue]
    @tenantId INT,
    @name NVARCHAR(60)
AS
BEGIN
    DECLARE @returnValue INT = 1;

    SET NOCOUNT ON;

    UPDATE [Sequence]
    SET @returnValue = [NextValue], [NextValue] = [NextValue] + 1
    WHERE [TenantId] = @tenantId AND [Name] = @name;

    IF (@@ROWCOUNT = 0)
    BEGIN
        INSERT INTO [Sequence]
            ([TenantId], [Name], [NextValue])
        VALUES
            (@tenantId, @name, @returnValue);
    END;

    RETURN @returnValue;
END;
GO;

您在添加新实体时在代码中调用存储过程。另一种选择是使用 INSERT 触发器直接在 SQL Server 中调用存储过程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-03
    • 1970-01-01
    相关资源
    最近更新 更多