mongo中的稀疏索引和空值

Posted

技术标签:

【中文标题】mongo中的稀疏索引和空值【英文标题】:sparse indexes and null values in mongo 【发布时间】:2012-01-26 08:55:00 【问题描述】:

我不确定我是否正确理解稀疏索引。

我在 fbId 上有一个稀疏的唯一索引


    "ns" : "mydb.users",
    "key" : 
        "fbId" : 1
    ,
    "name" : "fbId_1",
    "unique" : true,
    "sparse" : true,
    "background" : false,
    "v" : 0

我期待这将允许我插入带有 null 作为 fbId 的记录,但这会引发重复键异常。如果 fbId 属性被完全删除,它只允许我插入。

不是应该用稀疏索引来处理吗?

【问题讨论】:

【参考方案1】:

稀疏索引不包含缺少索引字段的文档。但是,如果字段存在并且值为null,它仍然会被索引。因此,如果该字段的缺失及其与 null 的相等性在您的应用程序中看起来相同,并且您希望保持 fbId 的唯一性,那么在您获得它的值之前不要插入它。

当您有大量文档时,您需要稀疏索引,但其中只有一小部分包含某个字段,并且您希望能够通过该字段快速找到文档。创建一个普通的索引太贵了,你只会浪费宝贵的内存来索引你不感兴趣的文档。

【讨论】:

从 MongoDB 3.2 开始,MongoDB 提供了创建部分索引的选项。部分索引提供了稀疏索引功能的超集。 docs.mongodb.com/manual/core/index-partial【参考方案2】:

为确保索引的最大性能,我们可能希望省略那些不包含您正在执行索引的字段的文档的索引。为此,MongoDB 具有如下工作的稀疏属性:

db.addresses.ensureIndex(  "secondAddress": 1 ,  sparse: true  );

此索引将忽略所有不包含 secondAddress 字段的文档,并且在执行查询时,这些文档将永远不会被扫描。

让我分享这篇关于基本索引及其一些属性的文章:

地理空间、文本、哈希索引以及唯一和稀疏属性:http://mongodbspain.com/en/2014/02/03/mongodb-indexes-part-2-geospatial-2d-2dsphere/

【讨论】:

ensureIndex 自 MongoDB 3.0 起已被弃用,因此请使用 createIndex。【参考方案3】:

a:1, b:5, c:2
a:8, b:15, c:7
a:4, b:7
a:3, b:10

假设我们希望在上述文档上创建索引。在ab 上创建索引不会有问题。但是如果我们需要在c 上创建索引怎么办。唯一约束不适用于 c 键,因为 null 值重复 用于 2 个文档。这种情况下的解决方案是使用sparse 选项。此选项告诉数据库不包括丢失密钥的文档。相关命令是db.collectionName.createIndex(thing:1, unique:true, sparse:true)。稀疏索引也让我们使用更少的空间。

请注意,即使我们有一个sparse 索引,数据库也会执行所有文档扫描,尤其是在进行排序时。这可以在explain 的结果的获胜计划部分中看到。

【讨论】:

以上是关于mongo中的稀疏索引和空值的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 索引

MySQL优化 SQL 语句的优化

MySQL-索引

MySQL学习笔记

密集索引稀疏索引

MySQL索引机制(详细+原理+解析)