27.MongoDB稀疏索引

  1. 27.MongoDB稀疏索引
    1. 27.1 知识点
      1. MongoDB 稀疏索引
      2. 特点
      3. 语法
      4. 常规索引与稀疏索引的区别
      5. 稀疏索引的限制
      6. 应用场景
      7. 示例代码
      8. 总结

27.MongoDB稀疏索引


27.1 知识点

MongoDB 稀疏索引

稀疏索引(Sparse Index)是一种特殊的索引类型,允许索引中仅包含那些在指定字段中存在且非 null 的文档。简单来说,稀疏索引不会为不存在索引字段的文档创建索引条目,从而减少索引的大小和内存占用。

特点

  • 节省存储空间:索引只包含有相关字段的文档,未定义字段的文档将被跳过。
  • 提高查询效率:适用于查询稀疏数据的场景(某些字段可能只有部分文档存在)。
  • 避免未定义字段的影响:在某些字段常为空或未定义时,稀疏索引可以避免索引无意义的 null 值。

语法

在创建索引时可以通过设置选项 sparse: true 来指定稀疏索引。以下是创建稀疏索引的语法:

db.collection.createIndex({ field: 1 }, { sparse: true });
  • field: 1 表示按升序索引字段 field
  • { sparse: true } 是稀疏索引的选项。

常规索引与稀疏索引的区别

假设有一个集合 users,包含以下文档:

[
  { "_id": 1, "name": "Alice", "age": 25 },
  { "_id": 2, "name": "Bob" },
  { "_id": 3, "name": "Charlie", "age": 30 }
]

普通索引

如果为 age 字段创建普通索引:

db.users.createIndex({ age: 1 });

索引会为所有文档创建条目,即使文档中没有 age 字段。索引的内容如下:

null -> _id: 2
25   -> _id: 1
30   -> _id: 3

普通索引包含了 age 字段不存在的文档(值为 null)。

稀疏索引

如果为 age 字段创建稀疏索引:

db.users.createIndex({ age: 1 }, { sparse: true });

索引只包含那些包含 age 字段的文档。索引的内容如下:

25 -> _id: 1
30 -> _id: 3

文档 _id: 2 被排除,因为它没有 age 字段。

稀疏索引的限制

唯一性约束

如果为某字段创建稀疏索引,并且设置了唯一性(unique: true),则只有包含该字段的文档会受到唯一性约束的限制。未定义该字段的文档不受限制。

db.users.createIndex({ email: 1 }, { unique: true, sparse: true });

与复合索引的配合

在复合索引中,如果任意一个字段是稀疏的,整个索引条目可能被排除。

db.users.createIndex({ name: 1, email: 1 }, { sparse: true });

应用场景

  • 部分文档包含特定字段:比如,某些用户会有 email 字段,但其他用户没有,查询 email 时可以利用稀疏索引。
  • 优化存储和查询性能:在字段很少使用时,稀疏索引减少了不必要的存储开销。
  • 避免无意义的索引条目:当字段值可能为 null 或未定义,且这些值不需要出现在索引中时,稀疏索引是合适的选择。

示例代码

1. 创建稀疏索引

// 创建一个稀疏索引,仅索引包含 "email" 字段的文档
db.users.createIndex({ email: 1 }, { sparse: true });

2. 插入文档

db.users.insertMany([
  { name: "Alice", email: "alice@example.com" },
  { name: "Bob" },
  { name: "Charlie", email: "charlie@example.com" },
  { name: "David" }
]);

3. 使用索引进行查询

// 查询包含 "email" 字段的文档
db.users.find({ email: { $exists: true } });

4. 稀疏索引与唯一性

// 创建一个稀疏且唯一的索引
db.users.createIndex({ email: 1 }, { unique: true, sparse: true });

// 插入文档
db.users.insertMany([
  { name: "Eve", email: "eve@example.com" },
  { name: "Frank" } // 没有 email 字段,允许插入
]);

// 尝试插入重复的 email
db.users.insert({ name: "Grace", email: "eve@example.com" });
// 会抛出错误:E11000 duplicate key error

总结

  • 稀疏索引主要用于提升稀疏数据场景下的性能。
  • 它可以减少索引的大小,提高查询效率,但需要注意与唯一性和复合索引的配合关系。
  • 使用稀疏索引时,必须了解索引仅适用于字段存在的文档,查询时需要显式考虑字段是否存在。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏