submission 新增 problemset_id,学生从 /problemset/:id/problem/:pid 入口提交时 前端带上、后端落库,提交列表在题目后面挂一个「题单 xxx」的标签,点了进题单。 只是来源标记:题单进度和奖章仍由判完之后的 recordSolvedProblem 按「已加入且含 这道题的所有题单」记账,和从哪个入口进来无关,所以这个字段带错顶多标签不准, 不影响成绩。校验只确认这道题在那个题单里 —— 不查 visible / status、也不查有没有 加入,藏起来的题单里还困着已加入的学生;对不上就当没带,提交照收。 外键 ON DELETE SET NULL:删题单不该带走提交,清掉标记就行。索引建成部分索引 (WHERE problemset_id IS NOT NULL),绝大多数提交不来自题单,全列索引是给 12 万行 白建一遍;谓词能被 problemset_id = $1 蕴含,删题单时的外键检查也用得上它。 列表按页单独查一次题单标题,没有把 problemset join 进那条调过的深翻页查询。 比赛提交恒为 null:题单只收非比赛题。 历史回填从 problemset_submission 取「当年首次 AC 那条」,其余老提交无从判断入口, 一律留空。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7AsqceaUfC81k7UCDcSk2
This commit is contained in:
@@ -444,6 +444,11 @@ export const submission = pgTable("submission", {
|
||||
statisticInfo: jsonb("statistic_info").default({}).notNull(),
|
||||
username: text().notNull(),
|
||||
ip: text(),
|
||||
// 来源题单:学生从题单入口(/problemset/:id/problem/:pid)提交时记下来,
|
||||
// 提交列表据此标出「这条来自题单」。**只是来源标记**,题单进度、奖章一概不看它,
|
||||
// 那些由判完之后的 recordSolvedProblem 按「已加入且含这道题的所有题单」记账。
|
||||
// 老数据里只有迁移 0007 从 problemset_submission 回填的首次 AC 有值。
|
||||
problemsetId: bigint("problemset_id", { mode: "number" }),
|
||||
}, (table) => [
|
||||
// 同上,不写 .op()。原先 pull 出来的 opclass 还串了位(contest_id 标成 timestamptz_ops、
|
||||
// create_time 标成 int4_ops),那条 SQL 真拿去执行 Postgres 会直接拒绝。
|
||||
@@ -486,6 +491,16 @@ export const submission = pgTable("submission", {
|
||||
foreignColumns: [problem.id],
|
||||
name: "submission_problem_id_76847b55_fk_problem_id"
|
||||
}),
|
||||
// 部分索引:绝大多数提交不来自题单,全列索引等于给 12 万行白建一遍。
|
||||
// 谓词是 IS NOT NULL,`problemset_id = $1` 蕴含非空,所以删题单时的外键检查
|
||||
// 也能用上它——不然那条检查要顺序扫全表。
|
||||
index("submission_problemset_id_idx").using("btree", table.problemsetId.asc().nullsLast()).where(sql`${table.problemsetId} is not null`),
|
||||
// 删掉题单不该带走提交:置空来源标记就行,提交本身照旧存在。
|
||||
foreignKey({
|
||||
columns: [table.problemsetId],
|
||||
foreignColumns: [problemset.id],
|
||||
name: "submission_problemset_id_fk_problemset_id"
|
||||
}).onDelete("set null"),
|
||||
]);
|
||||
|
||||
export const tutorial = pgTable("tutorial", {
|
||||
|
||||
Reference in New Issue
Block a user