Docs 菜单

分片键

分片键可以是单个索引字段,也可以是复合索引涵盖的多个字段,复合索引决定集合文档在集群分片中的分布。

MongoDB 将分片键值(或哈希分片键值)的取值区间划分为不重叠的分片键值(或哈希分片键值)范围。每个范围都与一个数据块相关联,MongoDB 会尝试在集群中的各个分片之间均匀分配这些数据块。

Diagram of the shard key value space segmented into smaller ranges or chunks.

分片键与数据段分发的有效性有直接关系。请参阅选择分片键。

Sharded collections typically require an index that supports the shard key. The index can be an index on the shard key or a compound index where the shard key is a prefix of the index.

如果索引是唯一支持分片键的非隐藏索引,则无法将其删除隐藏

Starting in MongoDB 6.0.12 and 5.0.22, you can drop the index for a hashed shard key. For details, see 删除哈希分片键索引。

MongoDB 可以对范围分片键索引执行唯一性约束。通过在分片键上使用唯一索引,MongoDB 将确保整个键的组合的唯一性,而不是分片键的各个组成部分。

对于范围分片集合,只有以下索引是唯一的

  • 分片键上的索引

  • 一个复合索引,其中分片键是前缀

  • 默认的 _id索引;但是,如果_id_id 字段不是分片键,则 索引仅对每个分片强制执行唯一性约束。

重要

只有当 _id 字段也是分片键时,分片集群才会在整个集群中对 _id 字段执行唯一性约束。

如果 _id字段不是分片键或者只是分片键的前缀,则唯一性约束仅适用于存储文档的分片。 这意味着两个或多个文档可以具有相同的 _id 值,前提是它们出现在不同的分片上。

示例,考虑一个分片键为 {x: 1}的分片的集合,它跨越两个分片 A 和 B。由于 _id 键不是分片键,因此该集合可能在分片A 中包含 _id 值为 1 的文档以及分片B 中另一个 _id 值为 1 的文档。

如果 _id 字段不是分片键,MongoDB 希望应用程序确保所有分片上 _id 值的唯一性。

唯一索引约束意味着:

  • 对于要分片的集合,如果该集合有多个唯一索引,则无法对该集合分片,除非分片键是所有唯一索引的前缀。

  • 对于已分片的集合,除非包含分片键作为前缀,否则无法在其他字段上创建唯一索引。

  • 唯一索引为缺少索引字段的文档存储空值;即缺少的索引字段将被视为null索引键值的另一个实例。有关详细信息,请参阅唯一单字段索引中的缺失文档字段。

要确保分片键值的唯一性,请将unique参数作为true传递给sh.shardCollection()方法:

尽管可以有以分片键为前缀的唯一复合索引,但如果使用unique参数,则集合必须在分片键上有唯一索引。

不能在哈希索引上指定唯一约束。

要保持分片键字段的唯一性,请参阅任意字段的唯一性约束。

分片集合中的文档可能缺少分片键字段。要设置缺失的分片键字段,请参阅设置缺失的分片键字段。

分片键字段缺失的文档与分片键字段值为 null 的文档同属一个数据块范围。例如,如果分片键位于字段{ x: 1, y: 1 }上,则:

缺少分片键的文档
属于与以下项目相同的范围

{ x: "hello" }

{ x: "hello", y: null }

{ y: "goodbye" }

{ x: null, y: "goodbye" }

{ z: "oops" }

{ x: null, y: null }

要定位分片键字段缺失的文档,可以对分片键字段使用{ $exists: false }过滤条件。例如,如果分片键位于字段{ x: 1, y: 1 }上,则可以通过运行以下查询找到分片键字段缺失的文档:

db.shardedcollection.find( { $or: [ { x: { $exists: false } }, { y: { $exists: false } } ] } )

如果指定了 null 值相等匹配过滤条件(例如 { x: null }),筛选器会匹配那些缺少分片键字段的文档,会匹配那些分片键字段被设置为 null 的文档。

某些写入操作(例如使用upsert规范的写入)需要对分片键进行等值匹配。在这些情况下,要定位缺少分片键的文档,除了与null的等值匹配之外,还应包含另一个过滤条件。例如:

{ _id: <value>, <shardkeyfield>: null } // _id of the document missing shard key