Mongo - 复合索引和前缀索引的约束条件

3

来自Mongo文档:

如果您的集合既有复合索引,又有其前缀的索引(例如{ a:1,b:1 }和{ a:1 }),如果两个索引都没有稀疏或唯一约束,则可以删除前缀上的索引(例如{ a:1 })。 MongoDB将在所有情况下使用复合索引,它将使用前缀索引。

这些约束条件有什么区别吗?


说实话,这取决于具体情况。独特和稀疏的约束实际上会改变索引的形式和内容,因此,在满足db.c.find({a:1, b:1})时,{a:1,b:1}, {sparse: true}对于{a:1}来说并不是多余的。 - Sammaye
1个回答

1

这最好通过矛盾的例子来解释。

1)假设你有一个稀疏的复合索引{a,b}和一个普通索引{a},则文档

{ a : null, foo : "bar" }

这段文字中的 {a} 是常规索引中的一部分,而不是稀疏索引的一部分。因此,带有 { a : null } 的文档无法使用稀疏索引找到,但可以使用常规索引找到(顺便说一句,如果存在许多这样的文档,则树会变得不平衡和缓慢)。

2)假设您有一个复合索引 {a, b} 和一个唯一索引 {a},那么以下两个文档将违反 {a} 索引的唯一约束条件,但不会违反复合索引的唯一性约束条件,即使您将其转换为唯一索引:

{ a : 1, b : 1 }
{ a : 1, b : 2 }  // the {a,b} tuple is different, but a isn't unique

因此,唯一的a索引是否存在决定了第二个文档是否可以被插入。
同样地,{a, b}元组的唯一性并不意味着仅有a的唯一性,以此类推。除非两个索引都不是稀疏的,也没有唯一约束条件,否则你可以找到所有组合的矛盾。

不同意第3点) 如果我在{a,b}上有唯一索引,但在{a}上没有,并且我删除了{a},会产生什么影响? - Arun Pratap Singh
对不起,但我不明白你的意思。如果在a上没有索引,而是在{a, b}上有索引,并且你删除了{a}(我猜你的意思是“从集合中的文档中删除所有名为a的字段”),那么所有的{a, b}元组将变成{null, b}。如果b的值不唯一,更新a值将在创建非唯一元组时首次出错。你可以在一个小集合中轻松验证或证伪我所说的话,这样讨论会简化很多。 - mnemosyn
不同意第3点) 如果我在{a:1,b:1}上有唯一索引,但在{a:1}上有非唯一索引,并且我删除了前缀索引{a:1},会产生什么影响?- 我找不到一个只使用前缀索引{a:1}的查询,前缀索引不需要是唯一的。 - Arun Pratap Singh
我同意@ArunPratapSingh的观点,这个答案中的陈述(3)过于宽泛(正如问题中引用的原始文档中的措辞一样)。如果复合索引{a:1, b:1}是唯一的,但“较短”的索引{a:1}不是唯一的,那么删除{a:1}是没有问题的。不会丢失唯一性的保证,并且MongoDB可以在任何查询中使用{a:1, b:1}的前缀,而原本会使用{a:1}。如果{a:1}是唯一的,无论{a:1, b:1}的唯一性如何,都不安全删除它。 - mactyr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接