4. BLAST 数据库构建:从开始到跑通

好,咱们今天聊聊数据库构建。BLAST 跑得快不快,结果好不好,很大程度上取决于你身后那个数据库靠不靠谱。

我自己入行那会儿,第一件事就是把 NR 数据库全量下载下来。嗯,结果硬盘直接爆了。那之后我才明白,数据库构建不是简单跑条命令,你得先想清楚:查什么?怎么查?查多大?

4.1 makeblastdb:最简单的入门

不管你是用官方数据库还是自己造的序列,第一步永远是 makeblastdb。这工具是 BLAST+ 套件自带的,装好 BLAST 就能用。

基本用法特别直接。假设你手里有个 FASTA 文件 my_seqs.fasta,想把它变成 BLAST 能查的库:

makeblastdb -in my_seqs.fasta -dbtype nucl -out my_db

这里 -dbtype 后面跟两个值:

  • nucl:核酸序列。主要用于 blastn、tblastn。
  • prot:蛋白序列。用于 blastp、blastx。

-out 参数指定输出库的名字。我个人习惯把库名写得有意义,比如 human_refseq_rna_2024,这样过几个月回头还能想起这是啥。

技巧:如果你库文件很大,可以加 -max_file_sz 参数。比如 -max_file_sz 4GB,表示单个索引文件的最大尺寸,超过就会分卷。这能避免系统文件大小限制。

4.2 关键参数,一次讲透

别看 makeblastdb 命令短,里面门道不少。我搞过不少次因为漏参数导致结果出错的,咱一次性避开这些坑。

参数 作用 我的踩坑记录
-dbtype 指定核酸/蛋白 记得把 nucl 拼对,我打成 nucl 也见过别人打成 nucleotide,会报错。
-title 为数据库起个名称 如果你建的库很多,有个好标题方便后续管理。建议体现物种、版本、来源。
-parse_seqids 解析序列 ID 默认不解析,但如果你后续要用 blastdbcmd 提取子集,就必须加这参数。
-hash_index 构建哈希索引 用于 blastdb_aliastool,一般用户用不到,但做大规模整合时很实用。

举个例子,一个更完整的命令:

makeblastdb -in zebrafish_protein.faa \
            -dbtype prot \
            -title "Danio rerio RefSeq protein" \
            -parse_seqids \
            -out zebrafish_refseq_prot

这样建出来的库,后期你用它做任何查询,都能直接从结果反查回原始序列,非常方便。

注意:如果没有 -parse_seqids,你的 blastdbcmd 没法根据序列 ID 提取信息,整个库就是个“黑盒”。我曾经因为这个,浪费了一天时间批量改代码。

4.3 NT 与 NR:官方两大护法

咱们做质控,经常需要用到官方的 NT 或 NR 库。这两个库到底选哪个?你想想看,你的核心问题是什么?

库 全称 内容 典型场景
NT Nucleotide collection 所有已知核酸序列,含冗余 物种分类、污染检测、组装后验证
NR Non-redundant protein 蛋白质序列,去冗余 功能注释、同源性搜索、比较基因组

实践中我自己的习惯:

  • 做污染检测(比如质控、去除宿主污染)→ 选 NT。因为 NT 含冗余,对低丰度污染的敏感度很高。
  • 做功能注释(比如给新组装基因做 blastx)→ 选 NR。去冗余后,结果更容易聚焦在最相关的 hit。

下载策略

NT 和 NR 官方提供了预构建的 BLAST 数据库,直接下载后解压就能用,不用自己跑 makeblastdb。下载地址去 NCBI FTP,但具体链接我建议你别死记,可以写个脚本自动拉。

我记得有一次项目急,我直接手动下载 NT 库,300多GB,下到一半网络断了。哎,后来我就学会用 wget -c(断点续传)配合序列化了。

wget -c ftp://ftp.ncbi.nlm.nih.gov/blast/db/FASTA/nt.gz
gunzip nt.gz
makeblastdb -in nt -dbtype nucl -title "NT full" -parse_seqids -out nt_full

当然,官方数据库更推荐直接下载 .tar.gz 格式的分卷包:

wget -r -np -nd ftp://ftp.ncbi.nlm.nih.gov/blast/db/nt.*.tar.gz
for f in nt.*.tar.gz; do tar xzf "$f"; done

这样你得到的就是已经做好的 BLAST 库,直接 blastn -db nt 就能用。

核心建议:如果做质控,一定先用 NT 做扫库。NR 适合做后续精细分析,但粗筛阶段 NT 的灵敏度更优。我见过有人拿 NR 做污染检测,结果阴性对照全过了,换个 NT 一查全是低丰度细菌序列。

4.4 自定义数据库:你想查什么就建什么

官方库虽然强大,但还是有局限性。比如你工作在小鼠的肠道宏基因组,那 NT 里的水稻、拟南芥、人源序列就是你不需要的干扰项。这时候,自定义数据库就派上用场了。

说句实话,我做过的商业项目,90% 都用了自定义库。好处很明显:

  • 体积小:搜索速度快得多
  • 特异性高:干扰序列少,结果更干净
  • 可重复利用:团队共享,统一规范

怎么构建?直接套用 makeblastdb

假设你要建一个小型病毒库,包含几十条序列:

cat virus1.fasta virus2.fasta virus3.fasta > my_virus_db.fasta
makeblastdb -in my_virus_db.fasta -dbtype nucl -title "My Virus DB" -out my_virus_db -parse_seqids

就这么简单。关键是你要保证输入序列质量:

  • 去除低质量序列(尤其短于 100bp 的,容易导致假阳性)
  • 去除重复 ID,否则 -parse_seqids 会报错
  • 序列行不要带空格或特殊字符,NCB 的格式要求严格
技巧:如果你想建蛋白库,就把 -dbtype prot 加上。有时候交叉验证,把核酸翻译成蛋白再建库去做 blastx,结果更精确。我曾在一个宏基因组项目里,用 nt 库扫出大量“未知”,换成自定义病毒蛋白库,直接命中率飙升到 85%。

一个真实案例

早些年我做过一个临床微生物检测平台。医院想快速判断样本中是否含耐药基因。建一个自定义的耐药基因蛋白库,配合 blastx,整个流程从原来 3 小时缩到 20 分钟,且假阳性率很低。

流程大致是:

  1. 从 CARD、ResFinder、ARG-ANNOT 下载所有耐药蛋白序列
  2. 去冗余(用 cd-hit 或 USearch,聚类 90% 以上序列)
  3. 合并为一个 FASTA
  4. makeblastdb 建库
  5. 每天晚上增量更新

这套流程至今仍是我推荐给客户的标配方案。

4.5 库维护与更新策略

数据库不是建完就完事了。我个人的经验是:

  • 官方库每 2-3 个月更新一次,不要太频繁,因为全量下载太慢。增量更新可以用 NCBI 的 update_blastdb.pl 脚本。
  • 自定义库每次有新数据或新版本时重建,但注意保持库名与版本对应,建议在库名里加日期或版本号。
重要提醒:改参数或增加新序列后,务必删除旧的 .phr/.pin/.psq 等索引文件后再重建。我见过有人直接覆盖,结果新旧索引混在一起,blast 直接挂掉,报错信息还特别隐晦。

4.6 核心流程图

BLAST 数据库构建决策流程 准备 FASTA 序列 选择来源 NT / NR 自定义库 下载预构建 tar.gz 包 质量过滤 去冗余 makeblastdb -dbtype / -parse_seqids / -title BLAST 可查询数据库 官方库:直接解压,不需重建 自定义库:每次建新库后 建议做完整性测试

嗯,这张图基本概括了数据库构建的选择逻辑。你照着走,不会迷路。

4.7 常见问题与避坑

坑1:库文件被截断。 下载 NT/NR 时,网络不稳导致 tar.gz 损坏。解压时没报错,但序列数不对。解决:下载完后做 md5 校验,或者用 gunzip -t 确认完整性。

坑2:自定义库序列 ID 重复。 这会导致 -parse_seqids 报错或查询结果混乱。解决:建库前用 grep '^>' 检查重复 ID,必要时加前缀分群。
我的个人经验:别图省事把所有序列塞到一个文件。按功能或物种分库,用 blastdb_aliastool 做多库联合查询。这样后续维护、更新都清晰。我曾经把所有细菌序列放一个库,后来想删掉某个属的序列,哎,根本没法做,只能重建整个库。