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