Files
myquant/docs/db_schema_v1.1.md
T
Simon 6acf938caf docs: 文档重构 — 清理 AI agent 残留,整合 docs/ 目录结构
- 删除 11 个残留文件: continuation.md, init_plan.md, reasonix.toml, djapi/continuation.md, djapi/.serena/, djapi/.claude/, djapi/.mcp.json, .claude/skills/, docs/usage.html, docs/db_schema.md, docs/report_db_design.md
- 7 个 CLAUDE-*.md 移入 docs/ 并重命名去 CLAUDE- 前缀
- 新增 4 个文档: architecture.md, development.md, api.md, deployment.md
- 重写 usage.md, README.md
- 修复所有过时引用和交叉链接
2026-08-22 11:56:40 +08:00

7.5 KiB
Raw Blame History

日报结构化入库:数据库表结构与数据契约

版本:v1.1 | 2026-08-06 变更(v1.0 → v1.1):新增 §3.1 stats 口径说明,修正 §3 中 pipeline "M1→M6" 的过时描述(实际 key 为 raw_total/raw_by_source/proc 等)。 用途:供 API / 前端对接读取日报数据。表位于 MySQL myquant 库,表前缀 news_。 连接:192.168.1.10:13306(pi 上 autossh 隧道 → doorcome.cn:3306 MariaDB 10.11),用户 myquant(密码在服务器 .env 的 NEWS_DB_PASSWORD)。


1. 表结构

1.1 news_report(日报主表,一行 = 一份日报)

字段 类型 说明
id BIGINT UNSIGNED PK 自增主键
report_date DATE 日报日期
report_type VARCHAR(16) finance=A 股日报 / intl=国际财经日报
file_name VARCHAR(160) 历史文件源文件名;新生成日报为空字符串 ""
generated_at DATETIME 生成时间
ai_summary TEXT AI 摘要全文(含换行,按条目分行)
stats JSON 数据总览统计快照(见第 3 节),可为 NULL
created_at DATETIME 入库时间

唯一键:(report_date, report_type, file_name) —— 历史同一天多次生成(intl 一日 3 次)保留多行;新生成日报 file_name='' 每天每类型仅一行,重复生成覆盖。

1.2 news_event(日报事件明细,一行 = 一条事件)

字段 类型 说明
id BIGINT UNSIGNED PK 自增主键
report_id BIGINT UNSIGNED FK → news_report.id
section VARCHAR(16) 板块:xwlb=新闻联播 / news=财经新闻 / cninfo=公告调研 / intl=国际重要事件
rank INT 板块内序号(1 起)
importance INT NULL 重要度 1-5
event_type VARCHAR(64) NULL 事件类型(如 宏观经济/地缘政治/新闻联播/公告)
title VARCHAR(512) 标题
summary TEXT NULL 摘要/正文
sentiment VARCHAR(8) NULL positive / negative / neutral
source VARCHAR(64) NULL 来源(如 cls、investinglive.com)
sources TEXT NULL 该新闻全部来源,JSON 数组字符串(如 ["yicai","stcn"]);无多源/历史数据可为 null
url VARCHAR(512) NULL 原文链接(新闻联播为空)
created_at DATETIME 入库时间

索引:idx_report_section (report_id, section)。


2. 数据契约

  • 幂等语义:同一 (report_date, report_type, file_name) 重复写入会覆盖主表并全量替换事件(DELETE + INSERT),不会产生重复行。
  • 取最新:同一天存在多份时(历史 intl 一日 3 次),前端按 generated_at 取最新;新日报 file_name='' 每天唯一。
  • 板块差异:finance 日报含 xwlb+news+cninfo 三板块;intl 日报仅 intl 板块。前端按 section 过滤展示。
  • 历史覆盖范围:2026-06-16 ~ 2026-08-03,共 177 行(finance 49 + intl 128;finance 少 1 因为两个目录存在同名文件被幂等合并)。事件总计 4222 条。

3. stats JSON 结构

news_report.stats 为数据总览快照,前端自行解析。finance 与 intl 的 key 集合不同:

key finance intl 内容
pipeline ✅ ✅ 管道各环节数量。finance 与 intl 内部 key 集不同:finance 为 {raw_total, raw_by_source, raw_total_24h, raw_by_source_24h, proc, deduped, dups, emb_count, qdrant_count, cninfo_raw};intl 为 {raw_total, processed, deduped, embedded, qdrant}(口径见 §3.1)
sources ✅ — 各新闻源文章数:{源名: 数量}
news ✅ — 新闻统计:{total, hi_threshold, sentiments, importances, event_types}
cninfo ✅ — 公告调研统计:{total, hi_threshold, by_day, announcement, research, irm}
xwlb ✅ — 联播统计:{total, date}(有数据时才有)
sentiment ✅ ✅ 情绪分布(历史文件为图例文本列表;新生成在 news.sentiments)
importance ✅ ✅ 重要度分布:[{重要度, 数量}, ...]
event_types ✅ ✅ 事件类型 TOP:[{事件类型, 数量}, ...]
source_dist — ✅ 文章来源分布:[{来源, 文章数}, ...]

历史文件与新生成日报的 stats 结构存在差异(历史为 HTML 解析快照,新生成为结构化组装),前端建议按 key 防御性读取。

3.1 口径说明(重要,避免误解)

stats 内各数字口径不同,请勿直接互相比较:

字段 口径
pipeline.raw_total 日报日期当天抓取的文章数(data/raw/{src}/{date}/index.jsonl 中 stage=article 且 success 的条目)。raw_by_source 是各源明细,其和 = raw_total;当天未抓取/无文章的源显示 0
pipeline.raw_total_24h 最近 24 小时内抓取(按 fetched_at)的文章数;raw_by_source_24h 为各源明细,和 = raw_total_24h。当天 07:00 抓取的数据其值 ≈ raw_total(并非"24h 内发布的新闻",raw 层无发布时间的可靠字段)
pipeline.proc / deduped / dups / emb_count / qdrant_count 抽取 / 去重后 / 重复 / 向量化 / Qdrant 总量(qdrant_count 为全量累计,非当天)
news.total 过去 30 小时窗口内经 LLM 抽取的新闻事件数。≠ raw_total:raw 是抓取的文章数,news 是抽取后的事件数(会有过滤/合并),两者不可互相验证
news.importances {重要度等级(1-5): 事件数},各等级之和 = news.total
news.sentiments {情绪: 事件数}(positive/negative/neutral),和 = news.total
news.event_types {事件类型: 事件数}(TOP 10)
pipeline.*(finance) finance 日报专用:proc=抽取后条数、deduped=去重后、dups=重复条数、emb_count=向量化条数、qdrant_count=Qdrant 全量累计(非当天)、cninfo_raw=当天 cninfo 抓取数。raw_by_source 各源之和 = raw_total
pipeline.*(intl) intl 日报结构不同:raw_total=当天抓取文章数、processed=处理数(≈ raw_total)、deduped=去重后条数、embedded=向量化条数、qdrant=Qdrant 全量累计。intl 无 raw_by_source 明细与 cninfo_raw

4. 常用查询示例(API 实现参考)

-- 某类型日报列表(取每天最新一份)
SELECT r.* FROM news_report r
JOIN (
    SELECT report_date, report_type, MAX(generated_at) AS g
    FROM news_report GROUP BY report_date, report_type
) t ON r.report_date = t.report_date AND r.report_type = t.report_type
   AND r.generated_at = t.g
WHERE r.report_type = 'finance' AND r.report_date >= '2026-07-01'
ORDER BY r.report_date DESC;

-- 某日报的全部事件(按板块)
SELECT section, rank, importance, event_type, title, summary, sentiment, source, url
FROM news_event WHERE report_id = ? ORDER BY section, rank;

-- 最近 N 天重要事件聚合(跨日报检索)
SELECT e.* FROM news_event e
JOIN news_report r ON r.id = e.report_id
WHERE r.report_date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
  AND e.importance >= 4
ORDER BY e.importance DESC, r.report_date DESC;

5. 相关命令(数据生产侧)

uv run a-share report --date YYYYMMDD     # 生成当日日报并入库(finance)
uv run a-share report-import              # 历史 HTML 全量解析入库(幂等)
uv run a-share report-import --date YYYYMMDD --type intl

代码:report_db/(连接/写入)、report_import/(历史解析/导入)、scheduler/reporter.py(日报生成)。