分片键的选择
Last updated
Was this helpful?
Last updated
Was this helpful?
引用下上一篇文章的内容:
分片键是数据分区,或者数据切割的前提, 从而实现数据分发到不同服务器上,减轻服务器的负担。
对于分片键,它也不是什么高级的东东,它就是文档里面的一个字段,但是这个字段不是普通的字段,有一定的要求
它必须在所有文档中都出现
它必须是集合的一个索引,可以是单索引或复合索引的前缀索引(后面会讲到)
它的值一但定下,就不能改变,或者修改
因为作为分片键的字段必须是索引,也就注定它与索引之间的难舍难分。
那既然分片键必须为文档里面的索引,那是不是所有索引都可以呢?
其实不是的,可以作为分片键的索引只有“单索引”和“复合索引的前缀索引”, 关于前缀索引请查看下文 (原文:All sharded collections must have an index that supports the shard key; i.e. the index can be an index on the shard key or a compound index where the shard key is a prefix of the index.)
索引前缀,或者说前缀索引,其实就是复合索引的一个子集。
举个例子,比如你有这样的一个复合索引 { "item": 1, "location": 1, "stock": 1 }
则该索引的子索引有:
{ item: 1 }
{ location: 1 }
{ stock: 1 }
{ item: 1, location: 1 }
{ item: 1, stock: 1 }
{ location: 1, stock: 1 }
{ "item": 1, "location": 1, "stock": 1 }
但前缀索引只有:
{ item: 1 }
{ item: 1, location: 1 }
查询操作支持的索引有以下:
{ item: 1 }
{ item: 1, location: 1 }
{ item: 1, stock: 1 } # 我也不太懂,好像勉强算前缀索引,但是查询效率不高
{ "item": 1, "location": 1, "stock": 1 } # 全索引
唯一索引的三种情况:
被指定为分片键的索引
被指定为分片键的前缀索引
默认索引_id
注:
如果_id字段不是分片键的一部分,则_id索引仅对每个分片强制执行唯一性约束,而不是跨分片。
例如,考虑一个分片集合(带有分片键{x:1}),它跨越两个分片A和B.因为_id键不是分片键的一部分,所以该集合可以在分片A中具有_id值为1的文档和另一个在分片B中具有_id值1的文档。
唯一索引的意义(不太懂):
For a to-be-sharded collection, you cannot shard the collection if the collection has other unique indexes.
0 For an already-sharded collection, you cannot create unique indexes on other fields.
注:您不能在哈希索引上指定唯一约束。
分片键的大小不能超过512字节
分片键的索引不能是多索引,文本索引或地理空间位置索引(geospatial index)
分片键不能被修改(修改分片键将会遭受灭顶之灾,因为要推倒重来)
分片键最好避免单调递增,这会使插入操作都指向单个分片,从而产生吞吐量的瓶颈(可用哈希索引避免这个问题)
基数
频率
变化率
理想的分片键能够使数据均匀分布在数据块中,而数据块又均匀地分布在集群上。
详情参见: