ClinVar 数据库结构与数据模型
说实话,一开始接触 ClinVar 的时候,我也被它的一大堆表和字段搞晕过。但后来我发现,只要你抓住它最核心的几个概念,整个结构就清晰了。
核心数据模型
ClinVar 本质上是一个“变异-表型-临床意义”的关系网。我把它拆成几个关键实体:
- Submission(提交)—— 谁提交了这条记录,什么时候提交的。
- Variation(变异)—— 具体的基因变异,比如 BRCA1 c.68_69delAG。
- Condition(表型/疾病)—— 关联的疾病名称,比如“遗传性乳腺癌”。
- Clinical Significance(临床意义)—— 该变异与疾病的关系判定,例如“致病性”。
- 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 会用
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 数据库的结构和数据模型。记住这些东西,你后面处理数据时会顺手很多。对,就保持这个框架:提交→变异+表型→临床意义→证据,所有操作都围绕着这条链条展开。