首页 / MongoDB 入门教程 / TTL、唯一、稀疏、部分索引

MongoDB 入门教程

TTL、唯一、稀疏、部分索引

本教程共 50 篇 · 第 45 篇 · 更新于 2026-07-30 · 约 4 分钟阅读

MongoDBMongoDB 入门教程TTL索引唯一索引稀疏索引部分索引

45. TTL、唯一、稀疏、部分索引

本节目标:掌握四种特殊索引属性的用法与边界,知道什么时候该用哪一个。

除了普通索引,MongoDB 还提供几种带「特殊行为」的索引。它们解决的是具体的工程问题,用对了事半功倍。

45.1 TTL 索引:自动过期

TTL(Time To Live,存活时间)索引会在指定时间后自动删除文档。适合存验证码、会话、日志这类「过期即废」的数据。

// 建一个会话集合,并让文档在 created_at 后 1 小时自动删除
test> db.sessions.createIndex(
  { created_at: 1 },
  { expireAfterSeconds: 3600 }
)

插入带时间的会话文档:

test> db.sessions.insertOne({
  token: "abc123",
  user_id: 1,
  created_at: new Date()
})
Warning

TTL 靠后台线程定时清理,不是精确到秒。删除可能有分钟级延迟。另外 TTL 字段必须是日期(Date)类型,否则不生效。

45.2 唯一索引:禁止重复

unique: true 保证字段值不重复。我们给 users.email 加唯一约束,防止重复注册。

// 邮箱不可重复
test> db.users.createIndex({ email: 1 }, { unique: true })

再插一个相同邮箱会报错:E11000 duplicate key error

Note

前面提过,_id 上的索引天生唯一且不能删。其它字段要唯一,得显式加 unique

45.3 稀疏索引:跳过缺失文档

普通索引会给每个文档建项,包括字段缺失的。稀疏索引(Sparse Index)只为「字段存在」的文档建项。

// 只为有 nickname 的文档建索引
test> db.users.createIndex({ nickname: 1 }, { sparse: true })

这对「字段多数缺失」的场景能省下大量索引空间,也避免把一堆 null 排在一起。

Tip

稀疏索引 + 唯一索引组合,可允许「多个文档都没有该字段」:因为缺失的不会被索引,自然不冲突。想要「有值则唯一、无值随意」就用它。

45.4 部分索引:按条件建索引

部分索引(Partial Index)只给「满足过滤条件」的文档建索引,比稀疏更灵活。靠 partialFilterExpression 指定条件。

// 只为已上架(status: "on")的商品建索引,省空间
test> db.products.createIndex(
  { category: 1 },
  { partialFilterExpression: { status: "on" } }
)

只有 status: "on" 的文档进索引。查询时也带了这个条件,才能命中该部分索引:

test> db.products.find({ category: "外设", status: "on" })
Note

部分索引适合「高频查的只是数据的一个子集」的场景,比如只查未完成的订单、只查上架商品。索引变小,写入也更快。

45.5 四种属性一览

属性作用典型场景
TTL到点自动删文档验证码、会话、临时日志
unique字段值不重复邮箱、手机号、订单号
sparse只为存在字段的文档建索引可选字段、避免 null 聚集
partial只为满足条件的文档建索引只查子集(如上架商品)

45.6 小结

TTL 管自动过期,unique 管不重复,sparse 管「有才建」,partial 管「符合条件才建」。它们都是为特定问题省资源、加约束,按场景取用即可。