# 数据库设计(SQLite) 数据库文件默认位置:`/data/csp.db`(Docker volume `csp_data` 持久化)。 ## 1. 核心表 ### `users` - `id` INTEGER PK AUTOINCREMENT - `username` TEXT UNIQUE - `password_salt` TEXT - `password_hash` TEXT - `rating` INTEGER DEFAULT 0 - `created_at` INTEGER ### `sessions` - `token` TEXT PK - `user_id` INTEGER FK -> users.id - `expires_at` INTEGER - `created_at` INTEGER ### `problems` - `id` INTEGER PK AUTOINCREMENT - `slug` TEXT UNIQUE - `title` TEXT - `statement_md` TEXT - `difficulty` INTEGER - `source` TEXT - `statement_url` TEXT(原始 PDF/题面链接) - `llm_profile_json` TEXT(固定 JSON:难度、答案、讲解、知识点、标签等) - `sample_input` TEXT - `sample_output` TEXT - `created_at` INTEGER ### `problem_tags` - `problem_id` INTEGER FK -> problems.id - `tag` TEXT - PK(`problem_id`, `tag`) ### `submissions` - `id` INTEGER PK AUTOINCREMENT - `user_id` INTEGER FK -> users.id - `problem_id` INTEGER FK -> problems.id - `contest_id` INTEGER NULL FK -> contests.id - `language` TEXT - `code` TEXT - `status` TEXT (`Pending/Compiling/Running/AC/WA/TLE/MLE/RE/CE/Unknown`) - `score` INTEGER - `time_ms` INTEGER - `memory_kb` INTEGER - `compile_log` TEXT - `runtime_log` TEXT - `created_at` INTEGER ### `wrong_book` - `user_id` INTEGER FK -> users.id - `problem_id` INTEGER FK -> problems.id - `last_submission_id` INTEGER NULL FK -> submissions.id - `note` TEXT - `updated_at` INTEGER - PK(`user_id`, `problem_id`) ### `contests` - `id` INTEGER PK AUTOINCREMENT - `title` TEXT - `starts_at` INTEGER - `ends_at` INTEGER - `rule_json` TEXT ### `contest_problems` - `contest_id` INTEGER FK -> contests.id - `problem_id` INTEGER FK -> problems.id - `idx` INTEGER - PK(`contest_id`, `problem_id`) ### `contest_registrations` - `contest_id` INTEGER FK -> contests.id - `user_id` INTEGER FK -> users.id - `registered_at` INTEGER - PK(`contest_id`, `user_id`) ### `kb_articles` - `id` INTEGER PK AUTOINCREMENT - `slug` TEXT UNIQUE - `title` TEXT - `content_md` TEXT - `created_at` INTEGER ### `kb_article_links` - `article_id` INTEGER FK -> kb_articles.id - `problem_id` INTEGER FK -> problems.id - PK(`article_id`, `problem_id`) ### `import_jobs` - `id` INTEGER PK AUTOINCREMENT - `status` TEXT(`running/success/partial_failed/failed`) - `trigger` TEXT(`auto/manual`) - `total_count` / `processed_count` / `success_count` / `failed_count` - `options_json` TEXT(本次导入参数快照) - `last_error` TEXT - `started_at` / `finished_at` / `updated_at` / `created_at` ### `import_job_items` - `id` INTEGER PK AUTOINCREMENT - `job_id` INTEGER FK -> import_jobs.id - `source_path` TEXT - `status` TEXT(`queued/running/success/failed`) - `title` TEXT - `difficulty` INTEGER - `problem_id` INTEGER NULL FK -> problems.id - `error_text` TEXT - `started_at` / `finished_at` / `updated_at` / `created_at` - UNIQUE(`job_id`, `source_path`) ## 2. 关键索引 - `idx_submissions_user_created_at` - `idx_submissions_problem_created_at` - `idx_submissions_contest_user_created_at` - `idx_problem_tags_tag` - `idx_kb_article_links_problem_id` - `idx_import_jobs_created_at` - `idx_import_jobs_status` - `idx_import_job_items_job_status` ## 3. 初始化与演示数据 系统启动时会自动: 1. 执行 `ApplyMigrations` 2. 执行 `SeedDemoData` 演示数据包含: - 基础题目(A+B、Fibonacci、排序) - 题目标签(math/dp/sort 等) - 知识库文章(快速 IO、DP 入门) - 示例模拟赛(含题目关联)