mirror of
https://github.com/KingHWJ/WeReadBoard.git
synced 2026-11-03 18:24:58 +08:00
1. 数据源切换至 MySQL: - app.py 从 SQLite 切换到 PyMySQL,所有 API 读取 MySQL weread_dashboard 数据库 - 新增 db_required 装饰器统一管理数据库连接和异常处理 - 新增 /api/health 健康检查接口,检测 MySQL 连接状态 - MySQL 连接失败时返回 HTTP 503 和告警信息 - 修复 fetched_at 字段 Unix 时间戳到 MySQL TIMESTAMP 的兼容问题 2. 前端数据库连接告警: - 页面加载时优先调用 /api/health 检查 MySQL 连接 - 连接失败时显示固定告警横幅,阻止后续数据加载 - CSS 告警横幅样式(黄色背景、下滑动画) 3. 代码中文注释: - app.py:所有函数、API 接口、工具函数添加完整中文文档注释 - fetch_data.py:所有 SQLite 建表语句添加列级中文注释 - migrate_to_mysql.py:保留已有中文注释 4. 技术文档与元数据文档: - docs/TECHNICAL_DOC.md:项目概述、系统架构、API 设计、部署指南 - docs/METADATA_DOC.md:18 张表完整字段说明、索引、表关系、数据类型规范
18 KiB
18 KiB
微信读书数据展示网站 - 元数据文档
版本:1.2.0 | 更新时间:2026-07-17 | 数据库:MySQL weread_dashboard
1. 数据库概览
| 属性 | 值 |
|---|---|
| 数据库名称 | weread_dashboard |
| 字符集 | utf8mb4 |
| 排序规则 | utf8mb4_unicode_ci |
| 存储引擎 | InnoDB |
| 表数量 | 18 |
| 数据总量 | 862 行 |
2. 表分类
| 分类 | 表名 | 说明 | 数据来源 |
|---|---|---|---|
| 基础数据 | books | 书架书籍 | 采集脚本 |
| 基础数据 | reading_stats | 阅读统计概要 | 采集脚本 |
| 基础数据 | read_times | 阅读时长时间序列 | 采集脚本 |
| 基础数据 | read_longest | 阅读时长排行 | 采集脚本 |
| 基础数据 | prefer_categories | 偏好分类 | 采集脚本 |
| 基础数据 | prefer_authors | 偏好作者 | 采集脚本 |
| 基础数据 | prefer_time | 24h 时段分布 | 采集脚本 |
| 基础数据 | notebooks | 笔记本概览 | 采集脚本 |
| 基础数据 | read_stat_items | 统计摘要项 | 采集脚本 |
| 基础数据 | archives | 书单归档 | 采集脚本 |
| 基础数据 | fetch_meta | 采集元信息 | 采集脚本 |
| 按需数据 | book_details | 书籍详情 | 用户点击时获取 |
| 按需数据 | book_progress | 阅读进度 | 用户点击时获取 |
| 按需数据 | book_highlights | 划线内容 | 用户点击时获取 |
| 按需数据 | book_chapters | 章节信息 | 用户点击时获取 |
| 按需数据 | book_reviews | 想法/点评 | 用户点击时获取 |
| 按需数据 | recommended_books | 推荐书籍 | 用户浏览推荐时获取 |
| 按需数据 | search_results | 搜索结果 | 用户搜索时获取 |
3. 表结构详情
3.1 books - 书架书籍表
存储用户书架中的所有书籍基本信息
| 字段名 | 数据类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| book_id | VARCHAR(64) | 是 (PK) | - | 书籍唯一标识 |
| title | VARCHAR(255) | 是 | '' | 书名 |
| author | VARCHAR(255) | 否 | NULL | 作者 |
| cover | VARCHAR(512) | 否 | NULL | 封面图 URL |
| category | VARCHAR(128) | 否 | NULL | 分类(如"文学-古代诗词") |
| finish_reading | TINYINT(1) | 是 | 0 | 是否读完 (1=读完) |
| read_update_time | INT UNSIGNED | 否 | NULL | 最近阅读时间 (Unix 时间戳) |
| secret | TINYINT(1) | 是 | 0 | 是否私密 (1=私密) |
| is_top | TINYINT(1) | 是 | 0 | 是否置顶 (1=置顶) |
| update_time | INT UNSIGNED | 否 | NULL | 书籍更新时间 (Unix 时间戳) |
| deep_link | VARCHAR(512) | 否 | NULL | 微信读书深度链接 |
索引:
- PRIMARY KEY (book_id)
- idx_books_category (category)
- idx_books_finish_reading (finish_reading)
- idx_books_read_update_time (read_update_time DESC)
记录数:404
3.2 reading_stats - 阅读统计概要表
存储总体和年度的阅读统计数据
| 字段名 | 数据类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| id | BIGINT | 是 (PK) | AUTO | 自增主键 |
| mode | VARCHAR(20) | 是 | - | 统计维度: overall/annually |
| period | VARCHAR(20) | 是 | '' | 周期标识: "overall" 或 "2026" |
| total_read_time | INT UNSIGNED | 是 | 0 | 总阅读时长 (秒) |
| read_days | INT UNSIGNED | 是 | 0 | 有效阅读天数 |
| day_average_read_time | DOUBLE | 否 | 0 | 日均阅读时长 (秒) |
| regist_time | INT UNSIGNED | 否 | NULL | 用户注册时间 (Unix 时间戳) |
| raw_json | LONGTEXT | 否 | NULL | 原始 API 返回 JSON |
| created_at | TIMESTAMP | 是 | CURRENT_TIMESTAMP | 记录创建时间 |
索引:
- PRIMARY KEY (id)
- idx_reading_stats_mode (mode, period)
记录数:2
3.3 read_times - 阅读时长时间序列表
按年/月/日分桶的阅读时长数据
| 字段名 | 数据类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| id | BIGINT | 是 (PK) | AUTO | 自增主键 |
| mode | VARCHAR(30) | 是 | - | 统计维度 (含 _daily 后缀) |
| period | VARCHAR(20) | 是 | '' | 周期标识 |
| bucket_timestamp | INT UNSIGNED | 是 | - | 分桶起始时间戳 |
| duration | INT UNSIGNED | 是 | 0 | 阅读时长 (秒) |
索引:
- PRIMARY KEY (id)
- idx_read_times_mode_period (mode, period)
- idx_read_times_bucket (bucket_timestamp)
记录数:21
3.4 read_longest - 阅读时长排行表
阅读时间最久的书籍排名
| 字段名 | 数据类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| id | BIGINT | 是 (PK) | AUTO | 自增主键 |
| mode | VARCHAR(20) | 是 | - | 统计维度 |
| period | VARCHAR(20) | 是 | '' | 周期标识 |
| book_id | VARCHAR(64) | 是 | - | 书籍 ID |
| title | VARCHAR(255) | 否 | NULL | 书名 |
| author | VARCHAR(255) | 否 | NULL | 作者 |
| cover | VARCHAR(512) | 否 | NULL | 封面图 URL |
| read_time | INT UNSIGNED | 是 | 0 | 阅读时长 (秒) |
| tags | VARCHAR(512) | 否 | NULL | 标签 (JSON 数组) |
索引:
- PRIMARY KEY (id)
- idx_read_longest_mode (mode, period)
记录数:20
3.5 prefer_categories - 偏好分类表
用户阅读的书籍分类统计
| 字段名 | 数据类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| id | BIGINT | 是 (PK) | AUTO | 自增主键 |
| mode | VARCHAR(20) | 是 | - | 统计维度 |
| period | VARCHAR(20) | 是 | '' | 周期标识 |
| category_id | INT UNSIGNED | 否 | NULL | 分类 ID |
| category_title | VARCHAR(128) | 否 | NULL | 分类名称 |
| parent_category_title | VARCHAR(128) | 否 | NULL | 父分类名称 |
| val | DOUBLE | 否 | 0 | 偏好权重 |
| reading_time | INT UNSIGNED | 否 | 0 | 该分类阅读时长 (秒) |
| reading_count | INT UNSIGNED | 否 | 0 | 该分类阅读本数 |
索引:
- PRIMARY KEY (id)
- idx_prefer_cat_mode (mode, period)
记录数:16
3.6 prefer_authors - 偏好作者表
用户阅读最多的作者统计
| 字段名 | 数据类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| id | BIGINT | 是 (PK) | AUTO | 自增主键 |
| mode | VARCHAR(20) | 是 | - | 统计维度 |
| period | VARCHAR(20) | 是 | '' | 周期标识 |
| author_id | INT UNSIGNED | 否 | NULL | 作者 ID |
| name | VARCHAR(255) | 否 | NULL | 作者名称 |
| count | INT UNSIGNED | 否 | 0 | 阅读书本数 |
| read_time | VARCHAR(64) | 否 | NULL | 阅读时长 (格式化字符串) |
索引:
- PRIMARY KEY (id)
- idx_prefer_author_mode (mode, period)
记录数:20
3.7 prefer_time - 24小时时段分布表
一天中每个小时的阅读时长分布
| 字段名 | 数据类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| id | BIGINT | 是 (PK) | AUTO | 自增主键 |
| mode | VARCHAR(20) | 是 | - | 统计维度 |
| period | VARCHAR(20) | 是 | '' | 周期标识 |
| hour_index | TINYINT UNSIGNED | 是 | - | 小时 (0-23) |
| duration | INT UNSIGNED | 是 | 0 | 阅读时长 (秒) |
索引:
- PRIMARY KEY (id)
- idx_prefer_time_mode (mode, period)
记录数:24
3.8 notebooks - 笔记本概览表
有笔记的书籍及其笔记统计
| 字段名 | 数据类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| book_id | VARCHAR(64) | 是 (PK) | - | 书籍 ID |
| title | VARCHAR(255) | 否 | NULL | 书名 |
| author | VARCHAR(255) | 否 | NULL | 作者 |
| cover | VARCHAR(512) | 否 | NULL | 封面图 URL |
| review_count | INT UNSIGNED | 是 | 0 | 想法/点评数 |
| note_count | INT UNSIGNED | 是 | 0 | 划线数 |
| bookmark_count | INT UNSIGNED | 是 | 0 | 书签数 |
| reading_progress | INT UNSIGNED | 是 | 0 | 阅读进度 (0-100) |
| marked_status | TINYINT(1) | 是 | 0 | 标记状态 (1=读完) |
| sort | BIGINT | 否 | NULL | 排序值 |
索引:
- PRIMARY KEY (book_id)
记录数:32
3.9 read_stat_items - 统计摘要项表
App 首页展示的阅读统计摘要
| 字段名 | 数据类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| id | BIGINT | 是 (PK) | AUTO | 自增主键 |
| mode | VARCHAR(20) | 是 | - | 统计维度 |
| period | VARCHAR(20) | 是 | '' | 周期标识 |
| stat_name | VARCHAR(64) | 否 | NULL | 统计项名称 (读过/读完/阅读/笔记) |
| counts | VARCHAR(64) | 否 | NULL | 统计值文案 (如"404本") |
| scheme | VARCHAR(512) | 否 | NULL | App 跳转链接 |
索引:
- PRIMARY KEY (id)
- idx_read_stat_items_mode (mode, period)
记录数:8
3.10 archives - 书单归档表
用户创建的书单
| 字段名 | 数据类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| id | BIGINT | 是 (PK) | AUTO | 自增主键 |
| name | VARCHAR(255) | 否 | NULL | 书单名称 |
| book_ids | LONGTEXT | 否 | NULL | 书籍 ID 列表 (JSON 数组) |
索引:
- PRIMARY KEY (id)
记录数:6
3.11 fetch_meta - 采集元信息表
记录数据采集的元信息
| 字段名 | 数据类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| key | VARCHAR(64) | 是 (PK) | - | 元信息键名 |
| value | TEXT | 否 | NULL | 元信息值 |
索引:
- PRIMARY KEY (key)
记录数:1
3.12 book_details - 书籍详细信息表
来自微信读书 /book/info 接口,用户点击书籍时按需获取
| 字段名 | 数据类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| book_id | VARCHAR(64) | 是 (PK) | - | 书籍 ID |
| title | VARCHAR(255) | 否 | NULL | 书名 |
| author | VARCHAR(255) | 否 | NULL | 作者 |
| translator | VARCHAR(255) | 否 | NULL | 译者 |
| cover | VARCHAR(512) | 否 | NULL | 封面图 URL |
| intro | LONGTEXT | 否 | NULL | 书籍简介 |
| category | VARCHAR(128) | 否 | NULL | 分类 |
| publisher | VARCHAR(255) | 否 | NULL | 出版社 |
| publish_time | VARCHAR(32) | 否 | NULL | 出版时间 |
| isbn | VARCHAR(32) | 否 | NULL | ISBN 号 |
| word_count | INT UNSIGNED | 否 | 0 | 总字数 |
| new_rating | DECIMAL(5,1) | 否 | 0 | 评分 (百分制) |
| new_rating_count | INT UNSIGNED | 否 | 0 | 评分人数 |
| fetched_at | TIMESTAMP | 是 | CURRENT_TIMESTAMP | 获取时间 |
索引:
- PRIMARY KEY (book_id)
记录数:1
3.13 book_progress - 阅读进度表
来自微信读书 /book/getprogress 接口
| 字段名 | 数据类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| book_id | VARCHAR(64) | 是 (PK) | - | 书籍 ID |
| progress | TINYINT UNSIGNED | 是 | 0 | 阅读进度百分比 (0-100) |
| chapter_uid | INT UNSIGNED | 否 | NULL | 当前阅读章节 UID |
| chapter_offset | INT UNSIGNED | 否 | NULL | 当前章节内偏移量 |
| update_time | INT UNSIGNED | 否 | NULL | 最后阅读时间 (Unix 时间戳) |
| record_reading_time | INT UNSIGNED | 否 | 0 | 累计阅读时长 (秒) |
| finish_time | INT UNSIGNED | 否 | NULL | 读完时间 (Unix 时间戳) |
| is_start_reading | TINYINT(1) | 是 | 0 | 是否已开始阅读 |
| fetched_at | TIMESTAMP | 是 | CURRENT_TIMESTAMP | 获取时间 |
索引:
- PRIMARY KEY (book_id)
记录数:1
3.14 book_highlights - 划线内容表
来自微信读书 /book/bookmarklist 接口
| 字段名 | 数据类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| id | BIGINT | 是 (PK) | AUTO | 自增主键 |
| book_id | VARCHAR(64) | 是 | - | 书籍 ID |
| bookmark_id | VARCHAR(64) | 否 | NULL | 划线唯一 ID |
| chapter_uid | INT UNSIGNED | 否 | NULL | 所在章节 UID |
| mark_text | LONGTEXT | 否 | NULL | 划线原文内容 |
| create_time | INT UNSIGNED | 否 | NULL | 创建时间 (Unix 时间戳) |
| type | TINYINT | 否 | NULL | 划线类型 |
| range_text | VARCHAR(64) | 否 | NULL | 位置范围 |
| color_style | TINYINT | 否 | NULL | 划线颜色样式 |
| fetched_at | TIMESTAMP | 是 | CURRENT_TIMESTAMP | 获取时间 |
索引:
- PRIMARY KEY (id)
- idx_highlights_book_id (book_id)
- idx_highlights_chapter (book_id, chapter_uid)
记录数:142
3.15 book_chapters - 章节信息表
来自微信读书 /book/bookmarklist 接口的 chapters 字段
| 字段名 | 数据类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| id | BIGINT | 是 (PK) | AUTO | 自增主键 |
| book_id | VARCHAR(64) | 是 | - | 书籍 ID |
| chapter_uid | INT UNSIGNED | 是 | - | 章节 UID |
| chapter_idx | INT UNSIGNED | 否 | NULL | 章节序号 |
| title | VARCHAR(255) | 否 | NULL | 章节标题 |
索引:
- PRIMARY KEY (id)
- UNIQUE KEY uk_book_chapter (book_id, chapter_uid)
记录数:77
3.16 book_reviews - 个人想法/点评表
来自微信读书 /review/list/mine 接口
| 字段名 | 数据类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| id | BIGINT | 是 (PK) | AUTO | 自增主键 |
| book_id | VARCHAR(64) | 是 | - | 书籍 ID |
| review_id | VARCHAR(64) | 否 | NULL | 想法唯一 ID |
| content | LONGTEXT | 否 | NULL | 想法内容文本 |
| create_time | INT UNSIGNED | 否 | NULL | 创建时间 (Unix 时间戳) |
| star | TINYINT | 否 | -1 | 评分 (0-5, -1=无评分) |
| chapter_name | VARCHAR(255) | 否 | NULL | 所在章节名称 |
| is_finish | TINYINT(1) | 否 | 0 | 是否书评 (1=书评) |
| fetched_at | TIMESTAMP | 是 | CURRENT_TIMESTAMP | 获取时间 |
索引:
- PRIMARY KEY (id)
- idx_reviews_book_id (book_id)
记录数:19
3.17 recommended_books - 推荐书籍表
来自微信读书 /book/recommend 接口
| 字段名 | 数据类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| id | BIGINT | 是 (PK) | AUTO | 自增主键 |
| book_id | VARCHAR(64) | 是 | - | 书籍 ID |
| title | VARCHAR(255) | 否 | NULL | 书名 |
| author | VARCHAR(255) | 否 | NULL | 作者 |
| cover | VARCHAR(512) | 否 | NULL | 封面图 URL |
| intro | TEXT | 否 | NULL | 书籍简介 |
| category | VARCHAR(128) | 否 | NULL | 分类 |
| reason | VARCHAR(512) | 否 | NULL | 推荐理由 |
| reading_count | INT UNSIGNED | 否 | 0 | 在读人数 |
| new_rating | DECIMAL(5,1) | 否 | 0 | 评分 (百分制) |
| new_rating_count | INT UNSIGNED | 否 | 0 | 评分人数 |
| rating_title | VARCHAR(32) | 否 | NULL | 评分标签 (神作/力荐等) |
| fetched_at | TIMESTAMP | 是 | CURRENT_TIMESTAMP | 获取时间 |
索引:
- PRIMARY KEY (id)
- idx_recommended_book_id (book_id)
- idx_recommended_fetched (fetched_at DESC)
记录数:48
3.18 search_results - 搜索结果表
来自微信读书 /store/search 接口
| 字段名 | 数据类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
| id | BIGINT | 是 (PK) | AUTO | 自增主键 |
| keyword | VARCHAR(255) | 是 | - | 搜索关键词 |
| book_id | VARCHAR(64) | 是 | - | 书籍 ID |
| title | VARCHAR(255) | 否 | NULL | 书名 |
| author | VARCHAR(255) | 否 | NULL | 作者 |
| cover | VARCHAR(512) | 否 | NULL | 封面图 URL |
| intro | TEXT | 否 | NULL | 书籍简介 |
| publisher | VARCHAR(255) | 否 | NULL | 出版社 |
| category | VARCHAR(128) | 否 | NULL | 分类 |
| reading_count | INT UNSIGNED | 否 | 0 | 在读人数 |
| new_rating | DECIMAL(5,1) | 否 | 0 | 评分 (百分制) |
| new_rating_count | INT UNSIGNED | 否 | 0 | 评分人数 |
| rating_title | VARCHAR(32) | 否 | NULL | 评分标签 |
| search_idx | INT UNSIGNED | 否 | 0 | 搜索序号 |
| fetched_at | TIMESTAMP | 是 | CURRENT_TIMESTAMP | 获取时间 |
索引:
- PRIMARY KEY (id)
- idx_search_keyword (keyword)
- idx_search_book_id (book_id)
记录数:20
4. 表关系说明
4.1 实体关系
books (书架)
├── book_id ──── book_details (书籍详情) [1:1 按需]
├── book_id ──── book_progress (阅读进度) [1:1 按需]
├── book_id ──── book_highlights (划线) [1:N 按需]
├── book_id ──── book_chapters (章节) [1:N 按需]
├── book_id ──── book_reviews (想法) [1:N 按需]
└── book_id ──── notebooks (笔记本概览) [1:1 有笔记的书]
read_longest (阅读排行)
└── book_id ──── books (书架) [N:1 关联]
recommended_books (推荐)
└── book_id (独立,不关联 books)
search_results (搜索)
└── book_id (独立,不关联 books)
archives (书单)
└── book_ids (JSON 数组,逻辑关联 books)
4.2 逻辑分组
- 静态数据组(采集时全量写入):books, reading_stats, read_times, read_longest, prefer_categories, prefer_authors, prefer_time, notebooks, read_stat_items, archives, fetch_meta
- 动态数据组(用户操作时按需写入):book_details, book_progress, book_highlights, book_chapters, book_reviews, recommended_books, search_results
5. 数据类型规范
| MySQL 类型 | 用途 | 对应 SQLite 类型 |
|---|---|---|
| VARCHAR(n) | 变长字符串(书名、作者等) | TEXT |
| LONGTEXT | 长文本(简介、划线内容) | TEXT |
| TEXT | 中等文本 | TEXT |
| INT UNSIGNED | 无符号整数(时间戳、计数) | INTEGER |
| TINYINT(1) | 布尔值(0/1) | INTEGER |
| TINYINT UNSIGNED | 小范围整数(小时 0-23、进度 0-100) | INTEGER |
| BIGINT | 自增主键 | INTEGER |
| DECIMAL(5,1) | 精度数值(评分) | REAL |
| DOUBLE | 浮点数(权重、日均时长) | REAL |
| TIMESTAMP | 时间戳(自动维护) | INTEGER (Unix 时间戳) |
6. 字符集与编码
- 数据库字符集:
utf8mb4(支持完整 Unicode,包括 Emoji) - 排序规则:
utf8mb4_unicode_ci(不区分大小写,支持多语言排序) - 连接字符集:
utf8mb4(PyMySQL 连接配置中指定) - 前端编码:
UTF-8(HTML meta 标签声明)