ClinVar 数据库结构与数据模型

说实话,一开始接触 ClinVar 的时候,我也被它的一大堆表和字段搞晕过。但后来我发现,只要你抓住它最核心的几个概念,整个结构就清晰了。

核心数据模型

ClinVar 本质上是一个“变异-表型-临床意义”的关系网。我把它拆成几个关键实体:

  1. Submission(提交)—— 谁提交了这条记录,什么时候提交的。
  2. Variation(变异)—— 具体的基因变异,比如 BRCA1 c.68_69delAG。
  3. Condition(表型/疾病)—— 关联的疾病名称,比如“遗传性乳腺癌”。
  4. Clinical Significance(临床意义)—— 该变异与疾病的关系判定,例如“致病性”。
  5. Evidence(证据)—— 支撑判定的原始数据,比如文献 PMID、功能实验。

这几个实体之间是多对多的关系。举个例子:一个变异可能对应多个疾病,同一个疾病也可能由不同证据等级支持。

经验之谈: 我早期做数据清洗时,经常忽略“证据”这张表,结果拿到的临床意义根本没有来源支撑,后来花了大量时间回溯。所以一开始就理清证据链,能省去很多麻烦。

核心表结构(简化版)

ClinVar 官方提供 XML 和 VCF 两种格式,但我建议你直接看数据库模式。这里是几张核心表:

表名 主要字段 说明
submissions submitter_name, submission_date, accession 记录每次提交的机构和个人
variations variation_id, hgvs_expression, gene_symbol 标准化的变异描述,如 HGVS 格式
conditions condition_id, name, medgen_id 疾病或表型,关联到 MedGen 数据库
clinical_significance significance_id, clinsig_code, classification 临床意义枚举,如 Pathogenic, Benign
evidence evidence_id, type, source, reference 支持判定的证据条目

这些表通过外键关联。最常见的关联方式是通过 variation_id + condition_id + submitter_id 来定位唯一记录。

临床意义分类枚举

ClinVar 对每个变异-表型对给出一个临床意义等级,ACMG 指南在此基础上做了五级分类。我直接列出来:

  • Pathogenic(致病性) —— 明确致病的变异。
  • Likely Pathogenic(可能致病) —— 有强证据支持但尚未完全确认。
  • Uncertain Significance(意义不明确) —— 证据不足,无法判断。
  • Likely Benign(可能良性) —— 很可能不致病。
  • Benign(良性) —— 明确不致病。

另外还有一些二级分类,比如“Drug Response”等,这些在 clinical_significance 表的 clinsig_code 字段里用数字表示。具体对应关系可在 ClinVar 文档里查到。

技巧: 解析 XML 时,临床意义字段可能包含多个值(例如同时有 Pathogenic 和 Risk Factor)。我习惯用 split_and_join 拆开再映射枚举,避免丢失信息。

数据模型关系图

下面是我画的一张关系图,帮你看清各实体是怎么连的:

ClinVar 数据模型实体关系 提交 Submission 变异 Variation 表型 Condition 临床意义 ClinicalSig 证据 Evidence 提交变异 关联表型 判定 关联 支撑 说明:一个提交可包含多个变异和表型;一个变异-表型对对应一个临床意义;每个临床意义由多条证据支撑。 多对多关系在具体表设计中通过中间表实现。

数据抽取时的常见坑

我踩过的坑,现在写出来给你当避雷针:

  • 重复提交问题 —— 同一个变异、同一个表型、同一个提交者,可能多次提交。ClinVar 会用 version 字段区分,最新版本才是有效值。我刚开始写解析时没检查版本,结果一堆过期数据。
  • 临床意义多值 —— 某些记录在 XML 中有多个 ClinicalSignificance 标签,你需要按优先级取最高的那个,或者保留全量再做后处理。
  • 表型命名混乱 —— 同一疾病可能同时出现 OMIM 名、MeSH 名、free text。我建议统一用 MedGen ID 来合并,否则后续分析会抓狂。
注意: 不要直接使用 ClinVar VCF 文件中的临床意义字段做判读,因为 VCF 简化了信息,有时候会丢失多表型对应关系。如果需要完整记录,请用 XML 或 JSON 格式。

实际查询示例(PostgreSQL)

假设你已经把 ClinVar 数据导入本地数据库,想找所有 BRCA1 致病性变异:

SELECT v.hgvs_expression, cs.classification, c.name AS condition_name
FROM variations v
JOIN clinical_significance cs ON v.variation_id = cs.variation_id
JOIN conditions c ON cs.condition_id = c.condition_id
WHERE v.gene_symbol = 'BRCA1'
  AND cs.classification IN ('Pathogenic', 'Likely pathogenic')
ORDER BY cs.classification DESC;

这个查询看起来简单,但如果你的表做了分库或者索引没建好,跑起来会很慢。我会在 gene_symbol 和 classification 上加联合索引。

个人习惯: 每次做关联查询之前,我都会先跑一下 EXPLAIN,看看查询计划是不是全表扫描。尤其是 clinical_significance 表,数据量上千万,不加索引就是灾难。

好了,以上就是 ClinVar 数据库的结构和数据模型。记住这些东西,你后面处理数据时会顺手很多。对,就保持这个框架:提交→变异+表型→临床意义→证据,所有操作都围绕着这条链条展开。