
MongoDB 中数据库和集合的创建是惰性的:仅在首次插入文档时自动创建,无需显式声明;调用 session.DB("name").C("coll") 仅返回对应对象引用,不触发实际创建。
mongodb 中数据库和集合的创建是惰性的:仅在首次插入文档时自动创建,无需显式声明;调用 `session.db("name").c("coll")` 仅返回对应对象引用,不触发实际创建。
在 Go 中使用 mgo(或现代替代如 mongo-go-driver)操作 MongoDB 时,常有人误解 session.DB("taskdb").C("categories") 这类调用会立即在服务器端创建数据库或集合。实际上,它既不创建数据库,也不创建集合——它只是构建一个逻辑上的引用对象(*mgo.Database 和 *mgo.Collection),用于后续操作。
真正的创建行为发生在第一次写入时。例如:
c := session.DB("taskdb").C("categories")
err := c.Insert(bson.M{"name": "Programming", "active": true})
if err != nil {
log.Fatal(err)
}
执行 Insert 后,MongoDB 才会:
- 自动创建名为 taskdb 的数据库(若不存在);
- 自动创建名为 categories 的集合(若不存在);
- 写入该文档。
✅ 注意:读操作(如 Find、Count)即使作用于不存在的数据库或集合,也不会触发创建——此时查询将返回空结果或 not found 错误(取决于具体操作),但不会新建任何资源。
此外,MongoDB 没有类似 SQL 的 CREATE DATABASE 或 CREATE COLLECTION 命令(除非显式调用 createCollection 命令并指定选项,如 capped、validator 等)。默认情况下,一切按需延迟创建,这是其 Schema-less 和轻量部署设计的重要体现。
? 总结:
- DB() 和 C() 是纯客户端构造器,仅生成操作句柄;
- 创建数据库/集合的唯一可靠触发点是对目标集合执行写操作(如 Insert、UpdateOne with upsert=true、replaceOne 等);
- 开发中无需预先“建库建表”,可专注业务逻辑;但需注意:首次写入失败(如权限不足、磁盘满)会导致创建失败,应妥善处理错误;
- 若需预设集合选项(如 TTL 索引、校验规则),则必须显式调用 db.createCollection() —— 此时应通过 Run 或驱动提供的 CreateCollection 方法实现,而非依赖惰性创建。
因此,Listing 8-5 中的 session.DB("taskdb").C("categories") 仅准备就绪,静待数据落盘——这才是 MongoDB “按需即用”哲学的精妙所在。











