You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用SQL唯一索引限制未完成状态的UserTestAttempt记录数量?

用SQL条件唯一索引实现测试尝试的创建限制

可以通过SQL的**条件唯一索引(Partial Unique Index)**实现这个业务限制,不需要完全依赖代码控制。

核心逻辑很明确:只对状态为REGISTERED或IN_PROGRESS的记录,强制userId和testId的唯一性;状态为PASSED或FAILED的记录不受该约束,允许用户重复创建新的测试尝试。

下面是主流数据库的实现示例:

MySQL

CREATE UNIQUE INDEX idx_user_test_active_attempt 
ON UserTestAttempt (userId, testId)
WHERE status IN ('REGISTERED', 'IN_PROGRESS');

PostgreSQL

CREATE UNIQUE INDEX idx_user_test_active_attempt 
ON "UserTestAttempt" ("userId", "testId")
WHERE status IN ('REGISTERED', 'IN_PROGRESS');

Oracle

Oracle没有直接的部分唯一索引语法,但可以通过函数索引间接实现:

CREATE UNIQUE INDEX idx_user_test_active_attempt 
ON UserTestAttempt (
  CASE WHEN status IN ('REGISTERED', 'IN_PROGRESS') THEN userId ELSE NULL END,
  CASE WHEN status IN ('REGISTERED', 'IN_PROGRESS') THEN testId ELSE NULL END
);

原理是Oracle的唯一索引会忽略NULL值,当状态为PASSED或FAILED时,CASE语句返回NULL,不会触发唯一约束;只有状态符合活跃状态时,才会强制userId+testId的唯一性。

这种数据库层面的约束优势很明显:能避免代码层面可能出现的并发问题(比如多个请求同时校验、创建时,因为时间差导致的重复记录),比纯代码控制更可靠。

如果你的数据库不支持条件唯一索引(比如某些老旧版本的数据库),才需要结合代码逻辑+事务来控制,但目前主流的关系型数据库都支持这类特性。

内容的提问来源于stack exchange,提问作者Mike

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 00:30:56