138 行
3.5 KiB
Markdown
138 行
3.5 KiB
Markdown
# 数据库设计(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 入门)
|
||
- 示例模拟赛(含题目关联)
|