切片key决定集合的在集群中的分布。 切片键是存在于集合中的每个文档中的索引或索引字段。 MongoDB使用切片键值范围对集合中的数据进行。 每个范围定义了一个不重叠的切片键值范围,并与一个相关联。 MongoDB会试图在集群的切片之间均匀地分配块。 切片键与块分配的有效性直接相关。
重要提示
一旦对集合进行切分,切片键和切片键值是不可变的;即
- 不能为该集合选择不同的切片键。
- 不能更新切片键字段的值。
切片键规范
要对集合进行切分,在调用 方法时必须指定目标集合和切片键:
sh.shardCollection( namespace, key )
namespace
参数由字符串<database>.<collection>
组成, 它指定了目标集合的完整名称空间。- key参数由包含字段的文档和该字段的索引遍历方向组成。
有关使用 策略对集合进行分片的特定说明,请参见 。
有关使用 策略对集合进行分片的具体说明,请参见 。
切片键索引
所有被切片的集合必须有一个可以支持的索引; 也就是说,切片必须要有索引,索引可以是切片键上的索引,也可以是切片键是索引的。
- 如果集合为空,会根据切片键创建索引(如果该索引不存在)。
- 如果集合不是空的,在使用 前你就必须先创建索引。
如果删除切片键的最后一个有效索引,则通过仅在切片键上重新创建索引来恢复。
唯一索引
是不能指定唯一约束的。
对于范围分片集合,只有以下索引可以是惟一的:
- 切片键上的索引
- 切片键是前缀的复合索引
- 默认的_id索引;然而,如果_id字段不是切片key或切片key的前缀 _id索引只对每个切片强制唯一性约束
唯一性和_id索引:
如果 _id 字段不是切片key或者切片key的前缀, _id索引只强制每个切片的唯一性约束,而不是跨切片的唯一性约束。
例如,考虑一个切片集合(带有切片键{x: 1}),它跨越两个切片A和B。 由于_id键不是切片键的一部分,因此集合可以在切片A中具有_id值为1的文档,而在切片B中具有_id值为1的另一个文档。
如果 _id 字段既不是切片键,也不是切片键的前缀,MongoDB希望应用程序在shard之间强制_id 值的唯一性。
唯一索引的约束意味着 :
- 对于要切片的集合,如果集合具有其他惟一索引,则不能对该集合进行切片。
- 对于已切片的集合,不能在其他字段上创建惟一索引。
通过对切片键使用惟一索引,MongoDB可以对切片键值强制惟一性。 MongoDB对整个key组合强制唯一性,而不是对切片key的单个组件强制唯一性。 要对切片键值强制惟一性,请给 方法传递值为true的 unique 参数
- 如果集合为空, 会根据切片键创建惟一索引(如果该索引不存在)。
- 如果集合不是空的,在使用 前你就必须先创建索引。
虽然可以有一个切片键是前缀的惟一,但如果使用unique参数,则集合必须有一个位于切片键上的惟一索引。
切片键的选择
切片键的选择会影响块在可用之间的创建和 这将影响切片集群中操作的总体效率和性能。
切片键影响切片集群所使用的的性能和效率。
理想的切片键允许MongoDB在集群中均匀分布文档。
至少,考虑潜在切片键的、和率的结果。
限制
切片键的大小:切片键不能超过512字节。
有关切片键的限制,请参见 。
Collection Size
当切分一个非空的集合时,切分键只能为初始切分操作限制最大支持的集合大小。请参见 .
Important :切分成功后,切片集合可以增长到任意大小。
切片键的基数
切片键的决定平衡器可以创建的最大块数。 这可以降低或消除集群中水平扩展的有效性。
在任何给定时间,一个惟一的切片键值最多只能存在于一个块上。 如果一个切片键的基数为4,那么在切片集群中不能有超过4个块,每个块存储一个唯一的shard key值。 这将集群中有效切片的数量限制为4个----添加额外的切片不会带来任何好处。
下图演示了一个使用字段X作为切分键的切分集群。 如果X具有较低的基数,则插入的分布可能类似于下面的内容:
本例中的集群不会水平伸缩,因为传入的写只会路由到切片的子集。
具有高基数的切片键不能保证数据在切片集群中均匀分布,但它可以更好地促进水平扩展。 切片键的和也有助于数据分布。 在选择切片键时要考虑每个因素。
如果您的数据模型需要对基数较低的键进行分片,请考虑使用具有较高相对基数的字段来使用。
切片键的频率
考虑一个表示切片键值范围的集合---切片键的频率表示给定值在数据中 多长时间出现一次。 如果大多数文档只包含这些值的子集,那么存储这些文档的块将成为集群中的瓶颈。 此外,随着这些块的增长,它们可能成为,因为它们不能再被分割了。 它降低或消除了集群内水平扩展的有效性。
下图演示了一个使用字段X作为切分键的切分集群。 如果X值的子集出现频率很高,则插入的分布可能类似于下面的内容:
频率较低的切片键不能保证数据在切片集群中均匀分布。 切分键的和也有助于数据分布。 在选择切片键时要考虑每个因素。
如果您的数据模型需要对具有高频值的键进行分片,请考虑使用惟一或低频值的。
单调改变的切片键
切片键上的值如果单调地增加或减少,则更有可能将插入分布到集群中的单个切片上。
之所以会发生这种情况,是因为每个集群都有一个块来捕获一个上限为的范围。 maxKey总是比所有其他值都要高。 类似地,也有一个块来捕捉下限为的范围。 minKey总是比所有其他值都低。 如果切片键值总是在增加,则所有的新插入都将被路由到以maxKey为上界的块。 如果切片键值总是递减,则所有的新插入都将被路由到以minKey为下界的块。 包含该块的切片成为写操作的瓶颈。
下图演示了一个使用字段X作为切片键的切片集群。 如果X的值是单调递增的,则插入的分布可能类似如下所示:
如果切片键值是单调递减的,那么所有的插入都将路由到块A。
不单调变化的切片键不能保证数据在切片集群中均匀分布。 切片键的和也有助于数据分布。 在选择切片键时要考虑每个因素。
如果您的数据模型需要对一个单调变化的键进行分片,请考虑使用 。