Article
2026-06-28-襷の系譜-数据审计与来源策略
襷の系譜 数据审计与来源策略
日期:2026-06-28
更新记录:
- 2026-06-29:补充姓名标准、来源抽样规则和存量重复治理口径。
- 2026-06-29:补充保护档案上的旧 seed 履历残留治理规则。
- 2026-06-29:补充按比赛日期反推学籍时间线的规则,禁止使用固定年份常量。
1. 当前判断
V0.1 暂不建设 domain_event。
原因:
- 真实世界事实已经可以由业务表表达,例如
Membership、PersonalBest、RaceResult。 - 单独维护事件表会带来重复录入和同步问题。
- 当前阶段还没有“动态流”“新闻事件”“用户时间线”等明确产品需求。
当前采用:
业务事实:Person / Organization / Membership / PersonalBest / RaceResult / Competition...
数据维护过程:AuditLog
未来如果需要选手生涯时间线,优先从业务表聚合生成,而不是提前维护独立事件表。
2. AuditLog 的职责
AuditLog 只记录数据维护行为,不声明现实世界发生了什么。
它回答:
我们的数据在什么时候、因为什么、被谁、如何修改了?
适合记录:
- 新增选手
- 修改选手基础信息
- 新增或修正 PB
- 新增比赛成绩
- 修正出身高中
- 修改确认状态
- 合并或拆分实体
- 替换来源
- 批量导入导致的变更
不适合记录:
- 作为产品内容直接展示的“选手动态”
- 新闻稿或公告正文
- 与数据表无关的运营日志
3. 审计原因类型
当前枚举:
initial_entry:初次录入source_update:来源有新数据source_correction:来源间冲突后按更高优先级来源修正stale_source:旧来源过时manual_error:人工录入错误format_normalization:格式规范化translation_update:翻译更新verification_update:确认状态变化entity_merge:实体合并entity_split:实体拆分import:批量导入system:系统行为
4. 单选手深挖策略
下一阶段不急于拉取大量数据。
建议先选择一个选手做完整样本,例如:
黒田 朝日
目标不是“把一个人做得很满”本身,而是用一个具体选手倒逼数据模型和页面能力:
- 基础资料是否够用
- 所属关系是否够用
- 出身高中是否够用
- PB 是否能表达来源、日期、比赛、阶段
- 箱根出场记录是否够用
- 其他比赛结果是否需要新字段
- 数据来源冲突如何记录
- 页面上哪些信息应该展示,哪些只入库
这比直接导入三校完整名单更稳。
5. 数据录入节奏
推荐顺序:
- 单选手深挖
- 发现字段缺口并调整模型
- 形成来源优先级文档
- 少量多选手验证
- 再设计 CSV/导入脚本
- 批量录入三校名单
不要在模型还没有经过真实样本检验时过早建设复杂导入管线。
6. 数据扩展动线与待办策略
数据录入不应长期停留在“从某个选手出发,把这个选手挖到底”的模式。
更适合本站的方式是:
Person-first + Race-frontier。
也就是先从一个高价值选手出发,但每次录入比赛、所属和来源时,都把相邻节点记录为待办项,而不是当场强行补全。
例如从黒田朝日出发:
- 录入第102回箱根駅伝 5区成绩。
- 同时发现同一 Race 的其他选手,例如工藤慎作。
- 不立即补完整个 5 区所有选手,而是创建“第102回箱根駅伝 5区全结果补齐”待办。
- 对高价值相邻选手创建“工藤慎作选手页补齐”待办。
- 后续按优先级从待办中选择下一个节点。
这个过程类似 BFS,但不是机械遍历,而是受来源可靠性、页面价值和数据缺口驱动。
6.1 待办类型
待办项至少分为四类:
- 选手补齐:为某个选手建立或补全基础资料、所属履历、PB、主要比赛记录。
- 比赛补齐:补齐某个 Race、某届赛事或某个区间的结果。
- 来源校验:确认某个事实的来源优先级,处理多个来源之间的冲突。
- 数据修正:修正已入库事实,例如 PB 更新、所属变化、录入错误、来源过时。
6.2 待办状态
待办完成后不应物理删除,而应保留状态。
建议状态:
pending:待处理in_progress:处理中done:已完成blocked:来源不足、暂时无法确认skipped:已判断暂不处理
保留历史的原因:
- 能回溯某条数据为什么被优先录入。
- 能知道哪些节点已经被检查过。
- 能解释某些数据为什么暂时缺失。
- 后续做后台、审计、数据导入时可以复用。
6.3 待办优先级
优先级不只看名气,也看数据结构价值。
建议排序因素:
- 是否来自高可信来源。
- 是否能补齐一个已展示页面上的明显缺口。
- 是否能扩展重要关系,例如同区间、同大学、同高中、同实业团。
- 是否能验证当前模型边界。
- 是否与首页或选手页用户关注度强相关。
初期可以使用简单优先级:
P0:当前页面明显需要,或已入库数据依赖它完成闭环。P1:重要相邻节点,适合下一批补齐。P2:有价值但不影响当前体验。P3:暂存线索。
6.4 首页展示规则
首页可以展示最近待更新的五个项目,用来向用户表达站点正在持续维护。
展示原则:
- 只展示
pending和in_progress。 - 只展示标记为可公开展示的待办。
- 优先展示
P0/P1。 - 文案使用用户能理解的内容,例如“第102回箱根駅伝 5区 全結果”“工藤慎作 選手ページ”。
- 不展示内部备注、来源冲突细节和低可信线索。
完成后:
- 首页不再展示该项。
- 内部状态改为
done。 - 不删除历史记录。
6.5 与 AuditLog 的关系
待办项和审计日志职责不同。
待办项回答:
接下来要补什么?为什么它值得补?
AuditLog 回答:
数据已经如何被修改?修改原因是什么?
因此:
- 创建待办不一定写 AuditLog。
- 完成待办时,如果实际修改了业务数据,应写 AuditLog。
- 如果只是发现来源不足,把待办标记为
blocked即可,不一定写 AuditLog。 - 如果因为来源冲突修正已入库数据,应写 AuditLog,并在待办中保留处理结论。
7. 数据确认状态决策
DataStatus 不应只表示“有没有录入”。
对 Person.status 来说,verified 应表示该选手的 V0.1 核心档案已经整理完成,而不只是“找到了几个可靠来源”。
单个事实可以因为来源可靠而可信,例如某条 PB 或某场比赛结果;但这不等于整个选手档案已经完成。
建议把状态理解为:
verified:该实体或事实已经达到当前版本定义的完成标准,可以作为完成资料展示。pending:已有初步数据,但核心字段仍缺来源、来源较弱,或尚未完成复核。 <<<<<<< HEAD =======
8. 保护档案履历治理规则
当某些选手被列入“保护档案”后,后续导入流程不会直接整包替换其 Membership,这是为了避免已经人工整理过的资料被简单覆盖。
但这也会带来一个副作用:
- 早期
seed-source的估算履历可能继续留在库里。 - 后续真实来源导入的新履历会叠加进去。
- 如果之前还发生过人物合并,旧履历可能一起迁移到保留人物上。
这类情况的处理口径如下:
- 页面层不做“看起来去重”的临时掩盖。
- 以数据层修复为准,删除被真实来源覆盖的旧
seed-source履历。 - 保留有明确来源支撑的时间线版本。
- 删除时写
AuditLog,原因使用source_correction。 - 这类修复通过独立维护脚本执行,避免手工逐条改库。
当前已确认的首个样本是:
asahi-kuroda- 初次清理时误保留了后续导入产生的错误时间线
- 现已二次回正为:
- 玉野光南高校:
2019-04-01 ~ 2022-03-31 - 青山学院大学:
2022-04-01 ~ 2026-03-31 - GMOインターネットグループ:
2026-04-01 ~ present
- 玉野光南高校:
这也说明一个重要边界:
- “保护档案清理”与“学籍时间线回正”是两类不同修复
- 前者解决重复
- 后者解决时间线推算错误
- 两者都需要保留审计轨迹,不能互相替代
9. 学籍时间线反推规则
对于只提供“比赛时年级”的来源,例如箱根 NTV 区间页面:
grade只能作为比赛时快照。- 高中 / 大学
Membership的时间线必须基于比赛日期所在学年反推。 - 不能使用固定年份常量,例如
2026 - grade。
箱根駅伝的特别点:
- 比赛通常在
1月 - 但它属于前一年
4月开始、当年3月结束的学年
因此:
2025-01的箱根比赛,学年结束年应视为20253年选手的大学时间线应为2022-04-01 ~ 2026-03-31
后续任何导入脚本若需要从 grade 推学籍,必须优先读取:
Race.startsAt- 若缺失,再读
CompetitionEdition.startsOn - 若仍缺失,再使用届次年份构造保守基准
此外,修复脚本不应默认要求“比赛结果来源 ID”和“履历来源 ID”一致。
原因:
- 同一事实可能来自不同来源链
- 比赛结果可能来自官方记录页
- 履历可能来自 NTV 区间页或早期 seed
修复时应优先按“同一人物 + 同一比赛上下文 + 同一学年推算规则”判断,而不是只按来源 ID 做机械匹配。
4d3e3d7 (Add featured article and sync latest posts)
conflicting:多个来源之间存在冲突,且当前无法决策。missing:明确知道该字段/事实需要展示,但目前缺失。
7.1 Person.status 的含义
Person.status 表示“选手 V0.1 核心档案完成状态”。
它不是单个字段的可信度,也不是某条 PB 或某场比赛结果的可信度。
如果一个选手仍有会影响核心档案完整性的待办,应保持 pending。例如:
- 生年月日缺失
- 出身地缺失
- 读音缺失
- 核心箱根记录只有名次但缺时间
- PB 缺创造日期、赛事或地点
- 箱根以外的主要比赛记录明显缺失
- 来源展示还不能解释页面上的关键事实
但进入 verified 至少需要满足:
- 姓名、主要显示名、罗马字或读音已确认。
- 当前或最近主要所属已确认。
- 高中/大学/实业团等关键所属履历已能解释页面展示。
- 生年月日、出身地等核心档案字段没有明显缺口,或页面明确不展示该字段。
- 核心 PB 有可靠来源,并尽量具备日期、赛事或地点。
- 主要箱根记录至少包含届次、区间、成绩或明确缺失说明、区间名次和来源。
- 页面上展示的关键事实均有来源或明确的待确认标记。
- 不存在会影响用户理解的重大来源冲突。
7.2 何时保持 pending
以下情况保持 pending:
- 只是从某场比赛结果中创建的选手壳。
- 只知道参赛时代表组织,不知道真实长期所属。
- PB 只来自报名页或媒体摘要,尚未确认是否为正式 PB。
- 生年月日、出身地、大学/高中等核心字段缺失较多。
- 箱根核心记录缺少时间等关键展示字段。
- 页面会给用户造成“这个选手已经整理完成”的误解。
例如第102回箱根駅伝 5区补齐时创建的多数选手,初期应保持 pending。
工藤慎作这类选手即使已经找到早稲田大学官方 PB 和箱根官方记录,如果生年月日、出身地、过往箱根具体时间等核心信息仍缺失,也应保持 pending,直到 V0.1 核心档案补齐。
7.3 临时代表队与长期所属
Membership 只记录长期或生涯所属,例如高中、大学、实业团、俱乐部。
临时比赛代表组织只写入比赛结果,不写入普通所属履历。
例如:
RaceResult.organizationId = 関東学生連合- 不创建
Membership(person=髙橋歩夢, organization=関東学生連合)
原因:
- 関東学生連合是箱根某届赛事的临时参赛队。
- 它不代表选手的长期所属。
- 如果写入 Membership,会污染“当前所属”和生涯时间线。
如果暂时不知道选手真实大学,当前所属应为空或待确认,而不是用临时代表队代替。
<<<<<<< HEAD
补充规则:
- 第100回箱根駅伝不编成
関東学生連合。 - 因此第100回若出现
RaceResult.organizationId = 関東学生連合,应直接视为错误导入,而不是待确认数据。 - 此类错误优先写入审计日志后删除,不保留为 pending。
東京大学大学院、東大大学院这类学生联合来源页中的所属表记,当前阶段统一归并到東京大学,用于补齐大学时间线。
4d3e3d7 (Add featured article and sync latest posts)
8. 来源优先级原则
同一事实可能来自多个网站。需要从一开始维护“来源优先级”,否则后续难以解释冲突。
通用原则:
- 官方来源优先于媒体来源
- 当前来源优先于旧来源
- 赛事官方结果优先于新闻报道
- 大学/队伍官网优先于粉丝站
- 粉丝站可以作为线索,但关键事实需要二次确认
- 媒体名鉴可以作为参考,但不复制文章正文和图片
9. 来源类型初步建议
9.1 选手当前所属与队伍名单
优先级:
- 大学/队伍官网
- 箱根官方报名资料
- NTV 箱根页面
- 月陸 Online 等媒体名鉴
- 粉丝站/数据站
9.2 箱根报名与出场
优先级:
- 箱根駅伝官方
- 関東学生陸上競技連盟资料
- NTV 箱根页面
- 媒体报道
- 粉丝站/数据站
9.3 PB
优先级:
- JAAF / 官方记录系统
- 大学/队伍官网
- 箱根官方报名资料
- NTV 箱根页面
- 月陸 Online 等媒体名鉴
- 粉丝站/数据站
9.4 普通比赛结果
优先级:
- 赛事官方结果
- JAAF / 地区陸協 / 学連结果
- 大学/队伍官网结果汇总
- 媒体报道
- 粉丝站/数据站
9.5 出身高中
优先级:
- 大学/队伍官网
- 箱根官方报名资料
- NTV 箱根页面
- 高校駅伝官方资料
- 媒体名鉴
- 粉丝站/数据站
<<<<<<< HEAD
9.6 姓名与罗马字来源规则
姓名相关字段需要单独维护优先级和抽样规则。
统一原则:
displayNameJa以日文原文为主,保存“姓 名”,且统一使用单个半角空格。displayNameRoman内部统一整理成GivenName FamilyName。- 来源页面原文中的罗马字顺序,只作为来源证据,不直接决定 slug。
导入前要求:
- 首次访问某类来源时,先抽样 2 到 3 个已知选手。
- 判断该来源常用的是
Family Given还是Given Family。 - 抽样结论记录到来源说明或本地 skill。
- 若该来源内部混用顺序,则该来源的人名导入默认进入保守模式,优先复用既有实体,不直接新建人物。
当前已知风险:
- NTV、部分报名页、部分名鉴页,可能出现不同罗马字顺序。
- 同一选手在不同站点之间出现顺序反转是常见现象。
- 因此罗马字只能作为辅助匹配,不能当主身份键使用。
9.7 存量重复治理口径
当前库中已发现的重复人物,需要按“历史姓名顺序误判”处理,而不是当成真实不同人物。
治理口径:
- 先确认保留哪一个主 slug。
- 迁移关联数据。
- 写入
AuditLog,原因建议使用entity_merge或format_normalization。 - 删除被合并实体前,先确认页面路由、来源映射和结果记录都已转移完成。
4d3e3d7 (Add featured article and sync latest posts)
10. 对黑田朝日样本的建议采集项
先围绕一个选手建立完整样本。
建议采集:
- 姓名、读音、罗马字
- 生年月日
- 出身地
- 身高体重,如可靠
- 出身高中
- 大学、学部、学科、年级
- 5000m / 10000m / 半马 PB
- PB 创造日期、比赛名、地点、当时阶段
- 箱根报名与出场记录
- 出云駅伝、全日本大学駅伝出场记录
- 主要赛季成绩
- 数据来源
- 来源优先级判断
- 待确认项
11. 页面与模型的关系
数据采集不必等页面完全完备,但也不应先批量采集。
推荐方式:
用一个选手做深样本,在采集过程中完善模型和页面;不要先拉大量数据。
原因:
- 真实数据会暴露模型缺口。
- 页面会暴露哪些字段真正有展示价值。
- 单选手样本的修正成本低。
- 批量导入太早会把错误模型固化。
12. 后续动作
短期建议:
- 以黒田朝日为样本建立数据采集清单。
- 逐条记录来源和优先级。
- 建立待办项机制,先支持选手补齐、比赛补齐、来源校验、数据修正。
- 首页展示可公开的最近五个待更新项目。
- 根据样本补充必要字段。
- 页面上新增“数据状态/来源说明”的更清晰展示。
- 等模型稳定后再做 CSV 导入管线。