vcfclick:ClickHouse + DuckDB 协作范例
vcfclick:让 VCF 回到可查询、可解释、可带走的地方
如果你做过基因组分析,大概见过这样的夜晚:磁盘里躺着 VCF,终端里流着管道,脚本一层层加,最后只有作者知道哪一步在筛选。你可能是那个最后还能解释脚本的人,也可能是那个收到一份 VCF 却无法复现结果的合作者。
VCF 是变异的交换格式,却常被当成分析格式。要做家系、质控、多 caller 对比,私有流程很快堆起来。Hail 一类平台能撑起人群规模,但对多数实验室偏重。
vcfclick 走第三条路:把队列 VCF 落成本地可查询分析库,用 SQL 说话,并明确把两类数据交给两个引擎。ClickHouse(chDB)管队列事实,DuckDB 管注释与便携查询。它目前是 Apache 2.0 的 research preview,面向探索性研究,不做临床报告。作为产品它还很早;作为架构样本,这套分工值得写清楚。
真正好的工具,不替你思考,只让你更容易把思考交给别人检验。
它解决什么
vcfclick 的目标用户是研究实验室和生信团队,而不是诊断科室或云上万人队列平台。它做的事情很具体:摄入 joint VCF 或一批 per-sample VCF;用 SQL 查位点、基因型、样本、摄入批次;跑 trio 与家系过滤,包括 de novo、隐性、显性、复合杂合,可叠加 gnomAD 频率;做样本 QC,含 het/hom、Ti/Tv、chrX 性别检查;合并多个 caller,并用 set= 保留来源,补上 GATK4 拿掉的 CombineVariants 能力;用 CLI、终端 UI、本地浏览器,或 MCP 让模型写出可见、可审计的 SQL;把库导出成 Parquet 包带走。
技术底座是嵌入式的:默认分析后端是 chDB,注释走共享 DuckDB;也允许把 DuckDB 设成备选主库。数据库落在本机目录,安装走 uv 或 pipx。限制也清楚:多等位要先分解,家系关系要显式加载 PED,DuckDB 主库与 chDB 并不对等。这些限制说明产品边界:中小队列、本机优先、科研探索。
两个数据库,各自站在哪
基因组分析里其实有两种表,只是长期被塞进同一种文件。
ClickHouse 与 chDB 是队列主库。它存的是“这批样本里发生了什么”:变异位点、稀疏基因型,主要保留非参考等位,样本元数据,哪一次摄入,以及家系与质控依赖的工作表。数据私有,随队列变宽,查询以区间过滤、按样本或位点聚合为主。列存和嵌入式 OLAP 适合这种“扫一段染色体,再按基因型条件收窄”的模式。
DuckDB 是参考层和分发层。它存的是“这些位点在公共知识里是什么”:基因坐标、ClinVar 一类共享注释。表相对小,更新节奏与队列无关,多个研究库可以共用同一份参考。同一套生态还覆盖 Parquet 导出,以及用 DuckDB-Wasm 在浏览器里打开 1000 Genomes 演示队列。需要时,它也能降级成分析后端,但那是兼容路径,不是对等双活。
可以记成一副对仗:
ClickHouse 回答事实:谁在哪个位置带了什么等位。
DuckDB 回答语境:这个位置落在哪个基因,公共库怎么注释,以及表格如何带走。
| 维度 | ClickHouse / chDB | DuckDB |
|---|---|---|
| 角色 | 队列事实主库 | 参考层与分发层 |
| 回答 | 谁在哪个位置带了什么等位 | 这个位置落在哪个基因,公共库怎么注释 |
| 数据 | 变异位点、稀疏基因型、样本元数据、摄入批次、家系与 QC 工作表 | 基因坐标、ClinVar 注释、Parquet、Wasm 演示队列 |
| 变化 | 随队列增长、重跑 caller、加样本 | 按版本更新,与队列解耦 |
| 查询 | 区间过滤、按样本或位点聚合 | 小表点查、便携查询、分发 |
协作方式
协作不是“两个库做同一件事再互相同步”,而是按生命周期拆开。
摄入时,VCF 进入 chDB 成为队列库;注释预先或独立落在 DuckDB,不随每次摄入复制一份。分析时,SQL 先在主库完成位点与基因型的筛选、家系逻辑和 QC,再按需 join 参考层。分享时,计算可以留在产出方的 ClickHouse 里,阅读方只拿 Parquet,用 DuckDB 或 Wasm 打开。注释升级只换参考库,不必重写整个队列。
这形成一条完整工作流:
文件 VCF → ClickHouse 队列库 → DuckDB 注释解释 → Parquet / Wasm 分发
MCP 坐在这条链的查询面上。模型生成的是用户能看见的 SQL,而不是对两个引擎的黑盒调用。对科研来说,可审计比“对话即结果”更重要。
小学数学公式:
VCF 文件 = ClickHouse 队列事实 + DuckDB 公共注释 + Parquet 便携分发为什么要这么用
因为两类数据的变化率和查询形状不同。
队列会增长、会重跑 caller、会加样本;注释按版本发布,体积稳定,却在几乎每次解释里都要被 join。绑在一个库里,结果往往是:更新 ClinVar 却要触碰整库,或为了分享一个小结果而要求对方安装分析集群。拆开之后,更新解耦,存储也对口。宽表过滤给 ClickHouse,小表点查和便携查询给 DuckDB。
这也贴合实验室的真实约束。数据常常不能随手上云,合作者不一定能复现你的计算环境,但能够打开一份 Parquet。嵌入式双引擎让“本机算得动”和“对方看得懂”同时成立。DuckDB 作为备选 backend,则是对安装现实的让步:chDB 的原生依赖不是每台机器都顺利。
它没有试图成为联邦数仓,也没有把双引擎伪装成对用户透明的单一存储。用户仍然面对 SQL,只是产品自己承认:主分析在 ClickHouse,解释和带走在 DuckDB。这种诚实,比“一个引擎包打天下”更接近基因组数据的结构。
总结
vcfclick 可以看作生物研究工具,但范围是基因组变异,不是生物学全栈库。它也可以看作 DuckDB 案例,但真正完整的叙事是协作:ClickHouse 做队列事实库,DuckDB 做注释库与便携查询层,应用在本地 VCF 科研分析。
作为产品,它仍是早期预览,生态和用户规模都还小。作为范例,它示范的是一种可复用的拆法:把“样本里有什么”和“公共知识怎么解释、结果怎么离开机器”分成两个引擎,用 SQL 接起来,用可见的查询保持可重复。对中小队列、家系研究和需要把表交给合作者的实验室,这套分工比追求单一数据库更重要。
好的工具,先让人看见自己的问题,再看见数据的规律,最后看见合作者的处境。数据各归其位,人才能把精力还给研究本身。