Docs 菜单
Docs 主页
/
MongoDB Manual
/

分片键

在此页面上

  • 分片键索引
  • 缺少的分片键字段

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

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

分片键值空间被分割为较小范围或数据块的示意图。

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

所有分片集合都必须具有支持分片键的索引。索引可以是分片键上的索引,也可以是复合索引,其中分片键是索引的前缀

如果删除了分片键的最后一个有效索引,请通过仅在分片键上重新创建索引来恢复。

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 } } ] } )

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

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

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

后退

路由器 (mongos)