如何在多租户数据库中设置唯一约束

2024-03-20

这是一个多租户应用程序。所有记录都有一个客户 ID 来分隔客户数据。客户可以在此表中插入自己的数据并设置自己的唯一约束。每个客户都可以对 15 个字段中的任何一个字段设置唯一约束,也可以不设置任何约束。因此,在实际表上设置唯一约束是行不通的。

目前,为了检查是否应该插入记录,我们查询数据库以查看该记录是否存在。如果是,我们不插入,否则我们进行插入。如果在检查和插入之间插入重复记录,则重复记录将泄漏到数据库中。有没有办法保证不插入重复项?


正如评论中提到的,避免由于并行运行的进程之间的计时问题而插入重复项的一种方法是将行是否存在的测试与INSERT声明使用WHERE条款。 我建议动态 SQL 是一种可能的解决方案,但这里有一种使用位掩码的替代方法,如果客户端的约束设置存储在数据库中,该方法可能适合您。我做了一些假设,所以这可能对你没有帮助。

请注意,此代码被简化为仅使用三列(而不是 OP 中提到的十五列)。如果您决定将其生产化,最好将逻辑包装在存储过程中。

-- run this code for different values of @ClientId and @DataN to test the behaviour
DECLARE 
@ClientId int = 103, 
@Data1 int = 1, 
@Data2 int = 2,
@Data3 int = 3

DECLARE @clientConstraint TABLE (ClientId int PRIMARY KEY, Data1 bit, Data2 bit, Data3 bit)
DECLARE @clientData TABLE (Id int IDENTITY PRIMARY KEY, ClientId int, Data1 int, Data2 int, Data3 int)

-- set up four clients with different constraints for testing purposes
INSERT @clientConstraint (ClientId, Data1, Data2, Data3)
VALUES
(100,0,0,0),
(101,1,0,0),
(102,0,1,0),
(103,1,0,1)

-- set up an existing row in the data table for each client
INSERT @clientData (ClientId, Data1, Data2, Data3)
VALUES
(100,1,2,3),
(101,1,2,3),
(102,1,2,3),
(103,1,2,3)

-- build a bitmask of the client's unique columns
DECLARE @ClientConstraintMask bigint = 0
SELECT @ClientConstraintMask = Data1 + (Data2 * 2) + (Data3 * 4)
FROM @clientConstraint
WHERE ClientId = @ClientId

-- insert the data, building a uniqueness bitmask and comparing to client's settings
INSERT @clientData (ClientId, Data1, Data2, Data3)
SELECT @ClientId,@Data1, @Data2, @Data3
WHERE ( SELECT 
        CASE    WHEN    c1.Data1 = @Data1 
                THEN    @ClientConstraintMask & 1
                ELSE    0
        END +  
        CASE    WHEN    c1.Data2 = @Data2 
                THEN    @ClientConstraintMask & 2
                ELSE    0
        END +
        CASE    WHEN    c1.Data3 = @Data3 
                THEN    @ClientConstraintMask & 4
                ELSE    0
        END
        FROM    @clientData AS c1
        WHERE   c1.ClientId = @ClientId
    ) <> @ClientConstraintMask

-- view the results
SELECT * FROM @clientData

可能还值得一提的是,根据客户端数据量,您可能很难有效地索引客户端数据表以保持插入性能良好。如果索引位于最常用的唯一列集上,请考虑建立索引ClientId单独执行还不够好。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在多租户数据库中设置唯一约束 的相关文章

随机推荐

  • OpenCV - 如何从 Canny 函数的结果中提取边缘?

    我在 OpenCV 中使用 Canny 函数 如下所示 Mat detected edges GetImage Canny detected edges detected edges 20 20 3 kernel size 我的问题是这个函
  • 在 C++ 中将对象数组设置为 null

    假设我有一个 C 中 Foo 类型的对象数组 Foo array 10 在 Java 中 我可以简单地通过以下方式将此数组中的对象设置为 null array 0 null the first one 我怎样才能在 C 中做到这一点 使用指
  • PHPStorm中Code Sniffer触发的Xdebug

    我在安装 PHPStorm 时 xdebug 和 Code Sniffer 都工作得很好 但真正烦人的部分是 调试器现在似乎将 Code Sniffer 错误视为断点 并中断代码 让我知道样式警告 尝试测试代码 如何防止 Code Snif
  • Firestore存储大小限制如何存储大型数组

    我有一个收藏users userID followers该用户 ID 是 firebase UID 因此长度为 29 个字节 字符串大小的计算方式为 UTF 8 编码字节数 1 在每个用户文档中 我都有一个名为 follower 的数组和另
  • 解析 DateFormat 时的 Java 时区

    我的代码解析日期如下 String ALT DATE TIME FORMAT yyyy MM dd T HH mm ss SSSZ SimpleDateFormat sdf new SimpleDateFormat ALT DATE TIM
  • android AppWidget 未添加到 Lollipop 上的主屏幕

    我开发了一个应用程序 可以在主屏幕小部件上显示新闻源 由于以下情况 在 Lollipop 之前的 Android 设备上一切正常 用户进入启动器的小部件屏幕以选择 添加特定的小部件 用户单击 MyNewsWidget 以添加到其主屏幕 调用
  • 让 div 占据另一个 div 后剩余的所有空间

    我有两个并排的 div 第一个包含一个可能相当长的文本字段 另一个包含一个很短的数字 我需要第一个 div 占据所有可用空间 而无需拉伸父级并在必要时进行剪切 Ant 它应该考虑第二个 div 的宽度 因此 如果文本的长度很短 那么两个 d
  • linuxrc 的用途是什么以及 rootfs 中是否需要它?

    Question 我的问题是 什么是linuxrc做 我需要它吗 rootfs 和使用有什么关系吗systemd vs initd 背景 我目前正在尝试建立一个rootfs适用于使用 Yocto 的 ARM 7 处理器 我对原始 BSP 项
  • docx4j - 删除 wml P 元素

    我正在使用 docx4j 来处理 Microsoft Word 模板 我想知道如何删除或隐藏模板中的 P 元素 我能够遍历代码来获取特定的 P 元素 现在我需要知道如何删除或隐藏该 P 元素 有人可以帮忙吗 我使用以下代码获取所有 P 元素
  • 按 Enter 键提交搜索?

    当有人按下 回车 键时 需要做什么才能提交此表单
  • Visual Studio 弹出窗口:“操作无法完成”

    当我尝试打开一个项目时 无论是本地项目还是在团队基础服务器 https en wikipedia org wiki Team Foundation Server TFS 我得到一个模态窗口告诉我 操作无法完成 未指定的错误 或者相同的消息
  • 内存怎么这么大?

    我有一个 1000x1500 像素位图 我想在 Android 中制作一个可变副本 当我运行以下代码时 int width original getWidth 1000px int height original getHeight 150
  • C++中的restrict关键字是什么意思?

    我总是不确定 restrict关键字在C 中意味着什么 这是否意味着赋予函数的两个或多个指针不重叠 还有什么意思呢 在他的论文中 内存优化 https web archive org web 20160422113037 http www
  • 如何在 sunos 中获取附加到特定端口的进程 ID

    我正在尝试在 SunOS 上使用端口 7085 连接进程 我尝试执行以下命令 netstat ntlp grep 7085没有返回任何东西 netstat anop grep 7085也尝试过这个 此开关在 SunOs 中无效 我得到以下输
  • numpy:有效地添加矩阵的行

    我有一个矩阵 mat array 0 1 2 3 4 5 6 7 8 9 10 11 我想获得某些索引处的行的总和 例如 ixs np array 0 2 0 0 0 1 1 我知道我可以将答案计算为 mat ixs sum axis 0
  • 如何在不使用登录系统的情况下识别唯一用户(iOS)

    我需要一种方法来识别我的应用程序的用户 但没有登录系统 我研究了 UUID 它为我的问题提供了部分答案 但由于它不是真正的 UDID 因此它不是 真正唯一的 如果用户重新安装应用程序 他会获得一个新的 UUID 这可以 不为我工作 有什么方
  • 如何使用flex4使用前置摄像头

    我使用 Flex 4 为 Android 移动设备开发了简单的相机应用程序 问题是 当我运行该应用程序时 它使用后置摄像头 它没有使用前置摄像头 怎么换相机啊 我需要使用前置摄像头来实现此应用程序 请帮助我 var camera Camer
  • 不是动态选择字段 WTFORMS 的有效选择

    我目前正在使用 WTFORMS 创建动态选择字段 但是它从未提交并且验证失败并出现以下错误 Not a valid choice 我的字段是这样创建的 area SelectField 在视图中 我从数据库中获取选项 如下所示 form M
  • 外部元素边距不等于内部元素边距

    我正在使用 Android WebView 来显示我的应用程序的 HTML 内容 我需要动态查找元素 通常是 div 的完整高度 包括填充 边距和边框 我正在使用 JavaScript 无法使用 jQuery 我一直在使用scrollHei
  • 如何在多租户数据库中设置唯一约束

    这是一个多租户应用程序 所有记录都有一个客户 ID 来分隔客户数据 客户可以在此表中插入自己的数据并设置自己的唯一约束 每个客户都可以对 15 个字段中的任何一个字段设置唯一约束 也可以不设置任何约束 因此 在实际表上设置唯一约束是行不通的