化学信息学基础:分子结构表示、Mol文件格式、SDF文件、分子数据库

做分子表示学习,第一件事就是要搞清楚——分子在计算机里到底长什么样。

你可能会想,不就是画个结构式吗?还真不是。计算机不认识苯环、双键这些图形,它只认数字、坐标和连接关系。这一章我就带你梳理一下,化学信息学里最基础的几种分子结构表示方式,以及它们背后那些"看着有点老但依然能打"的文件格式。

本章核心脉络:从分子结构如何数字化出发,拆解 Mol 和 SDF 两种文件格式的底层结构,最后聊聊主流分子数据库的选型思路。
分子表示知识体系 分子结构表示 Mol 文件格式 SDF 文件格式 分子数据库 原子块 · 键块 · 属性块 Mol 头 + 数据字段 PubChem / ChEMBL / DrugBank 三种表示方式各有适用场景,实践中常组合使用

1. 分子结构表示 —— 从化学结构到计算机语言

说白了,计算机要描述一个分子,需要知道三件事:有哪些原子、它们怎么连、连了什么样的键。这听起来简单,但实现方式五花八门。

最常见的思路叫连接表(Connection Table)。你可以把它想象成一张二维表格:每一行是一个原子,记录它的坐标、元素类型;另起一部分记录哪些原子之间有键,以及键的类型(单键、双键、芳香键等)。Mol 文件就是基于连接表的典型代表。

我在项目中遇到过不少新手,一上来就问我:"老师,为什么不用图片存分子?" 嗯,图片存的是像素,计算机没法从像素里知道哪个原子连了哪个。连接表才是"可计算"的结构表示。

除了连接表,还有 SMILES、InChI 这些字符串表示法。不过这一章我们先聚焦文件格式,字符串表示后面会单独讲。

我的建议:学习初期,先把连接表的结构吃透。因为不管你以后用 SMILES 还是图神经网络,底层都绕不开"原子 + 键"这个逻辑。

2. Mol 文件格式 —— 最经典的结构存储方式

Mol 格式是 MDL(现在属于 BIOVIA)在 80 年代推出的。你看着它老,但它至今仍是化学信息学的底层通用格式。RDKit、Open Babel、ChemDraw 全都支持它。

一个标准的 Mol 文件长这样:

benzene.mol
  ChemDraw10101516022D

  6  6  0  0  0  0  0  0  0  0999 V2000
    1.0000    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
    0.5000    0.8660    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -0.5000    0.8660    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -1.0000    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -0.5000   -0.8660    0.0000 C   0  0  0  0 0  0  0  0  0  0  0  0
    0.5000   -0.8660    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
  1  2  2  0  0  0  0
  2  3  1  0  0  0  0
  3  4  2  0  0  0  0
  4  5  1  0  0  0  0
  5  6  2  0  0  0  0
  6  1  1  0  0  0  0
M  END

结构拆开来看,分三块:

区块行范围内容说明
头块1~3 行文件标题、程序来源、空白行(有时含注释)
原子计数行第 4 行原子数、键数、手性标识等 — 这是整张表的"目录"
原子块5~10 行每个原子一行:x, y, z 坐标 + 元素符号 + 其他属性
键块11~16 行每条键一行:起始原子索引、终止原子索引、键类型
属性块M END 之前电荷、同位素、标记等附加信息(可选)

这里有个容易踩的坑——原子索引是从 1 开始数的。我曾经在写批量处理脚本时,用 Python 的 0 下标直接去读键表,结果连出来的结构全乱套。排查了半天才发现是索引偏移的问题。

注意:Mol 格式的坐标是二维平面坐标(x, y),z 一般填 0.0000。别以为它是三维结构。V2000 是主流版本,还有 V3000 支持超大分子,但日常用 V2000 就够了。

3. SDF 文件格式 —— 带数据的分子集合

SDF(Structure-Data File)其实是 Mol 的"升级版"。它把多个 Mol 拼在一起,每个分子后面还能挂一串自定义属性。格式上的核心变化就是多了 $$$$ 作为分隔符。

一个典型的 SDF 文件片段:

benzene.sdf
  ChemDraw10101516022D

  6  6  0  0  0  0  0  0  0  0999 V2000
    1.0000    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
    0.5000    0.8660    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -0.5000    0.8660    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -1.0000    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -0.5000   -0.8660    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
    0.5000   -0.8660    0.0000 C   0  0  0  0  0  0  0 0  0  0  0  0
  1  2  2  0  0  0  0
  2  3  1  0  0  0  0
  3  4  2  0  0  0  0
  4  5  1  0  0  0  0
  5  6  2  0  0  0  0
  6  1  1  0  0  0  0
M  END
> <PUBCHEM_COMPOUND_CID>
241

> <PUBCHEM_MOLECULAR_FORMULA>
C6H6

> <PUBCHEM_MOLECULAR_WEIGHT>
78.11

$$$$

比起纯 Mol,SDF 的优势很明显——你能把 分子结构 + 属性数据 打包在一个文件里。比如做虚拟筛选时,每个分子都带着 LogP、分子量、活性值,一个 SDF 文件就能把整批结果存下来。

我记得有一次批量下载 PubChem 数据集,拿到手就是一整个 SDF 文件,里面几万个分子。解析时一定要按 $$$$ 分割,别一次性全读到内存里——嗯,这个教训是用 OOM 换来的。

解析小技巧:用 RDKit 的 SDMolSupplier 可以像迭代器一样逐条读取 SDF,不占内存。代码就一行:suppl = Chem.SDMolSupplier('data.sdf')。

4. 分子数据库概述

有了文件格式,还得有地方存、有地方查。这就是分子数据库要做的事。目前主流的公开分子数据库有这几个:

数据库分子数特色常用格式
PubChem1.1 亿+覆盖面最广,免费,更新快SDF, SMILES, XML
ChEMBL200 万+聚焦生物活性数据,药物研发常用SDF, Excel
DrugBank1.4 万+已上市/在研药物,带靶点信息SDF, XML
ZINC2.3 亿+专为虚拟筛选设计,可购买化合物SDF, Mol2
PDB (蛋白质)20 万+生物大分子三维结构PDB, mmCIF

我个人习惯是:做小分子药物项目,优先用 ChEMBL + PubChem 搭配。ChEMBL 的数据干净、标注规范,PubChem 用来补全缺失的结构。如果做虚拟筛选,ZINC 的化合物库更合适,因为它直接关联了供应商。

你想想看,这些数据库动辄上亿个分子,要是每个都存成单独的 Mol 文件,文件系统根本撑不住。所以它们内部通常用 SDF 或压缩后的 SMILES 存储,再配合索引加速检索。

版权提醒:PubChem 和 ChEMBL 是公开数据,但 DrugBank 的部分数据需要授权。商用前务必查清楚许可协议。

5. 格式选择与实践建议

讲了这么多,到底该用哪种?我列几条实际经验供你参考:

  • 单个分子、临时查看 → 用 Mol。简单、直接、随便一个化学软件都能打开。
  • 小批量数据(几百个分子) → 用 SDF。结构 + 属性一起存,比 CSV 靠谱得多。
  • 大规模数据(百万级以上) → 用 SMILES + 数据库索引。SDF 文件太大,解析也慢。
  • 需要三维构象 → 用 SDF 或 Mol2。Mol 的 V2000 版本不支持三维坐标,得用 V3000 或 Mol2。

我曾经在做一个化合物库清洗项目时,对方给的是 CSV 文件,SMILES 字符串里混着各种非法字符。我花了三天写清洗脚本,最后干脆让对方重新导了一份 SDF 出来——十分钟就搞定了。所以我的教训是:能用 SDF 就别用 CSV,格式规范能省掉你 90% 的清洗时间。

一句话总结:Mol 是"原子+键"的骨架,SDF 是"骨架+数据"的档案袋,数据库是"档案柜"。理解这三层关系,后面学分子表示学习会顺很多。