
# 如何设置MongoDB数据库分片集群的分片键
MongoDB数据库中数据的分片是以集合为基本单位的，集合中的数据通过片键被分成多部分。
对集合进行分片时，您需要选择一个片键 , 片键是每条记录都必须包含的，且建立了索引的单个字段或复合字段，MongoDB数据库按照片键将数据划分到不同的数据块中，并将数据块均衡地分布到所有分片中。为了按照片键划分数据块，MongoDB数据库使用基于范围的分片方式或者基于哈希的分片方式。
表1分片键分类 
| **分片键类型** | **描述**                                                                                                                                                                                                                | **使用场景**                                          |
|:---|:---|:---|
| 基于范围的分片键  | 基于范围的分片键是根据分片键值把数据分成一个个邻接的范围，如果没有指定特定的分片类型，则基于范围的分片键是默认的分片类型。 特点：基于范围的分片键对于范围类型的查询比较高效，给定一个片键的范围，分发路由可以很简单地确定哪个数据块存储了请求需要的数据，并将请求转发到相应的分片中。 | 建议在分片键基数较大，频率较低，并且分片键值不是单调变化的情况下使用基于范围的分片键。       |
| 基于哈希的分片键  | 基于哈希的分片键是指MongoDB数据库计算一个字段的哈希值，并用这个哈希值来创建数据块。 特点：保证了集群中数据的均衡。哈希值的随机性使数据随机分布在每个数据块中，因此也随机分布在不同分片中。                                          | 如果分片键值的基数较大，拥有大量不一样的值，或者分片键值是单调变化的，则建议使用基于哈希的分片键。 |
   
集合设置分片并插入文档之后，其中的每个文档的分片的键和值都是不可更改的。如果需要修改文档的分片键，必须要先删除文档，再修改分片键，然后重新插入文档。
![](https://support.huaweicloud.com/drs_faq/public_sys-resources/note_3.0-zh-cn.png)
分片键不支持数组索引，文本索引和地理空间索引。
#### 基于范围的分片键设置
1. 使用如下命令，开启数据库分片开关。 
   **sh.enableSharding** *(database)*
   ![](https://support.huaweicloud.com/drs_faq/public_sys-resources/note_3.0-zh-cn.png)
   参数database表示要开启分片集合的数据库。
   
   
2. 设置分片键。 
   **sh.shardCollection** *(namespace, key)*
   ![](https://support.huaweicloud.com/drs_faq/public_sys-resources/note_3.0-zh-cn.png)
   - 参数namespace表示需要进行分片的目标集合的完整命名空间\<database\>.\<collections\>。
   
   - key表示要设置分片键的索引。
    
   - 如果需要进行分片的目标集合是空集合，可以不创建索引直接进行下一步的分片设置，该操作会自动创建索引。 **sh.shardCollection()**
     
   
   - 如果需要进行分片的目标集合是非空集合，则需要先创建索引key。然后使用如下命令设置分片键。 **sh.shardCollection()**
     
   
   
   
   
 
#### 基于哈希的分片键设置
1. 使用如下命令，开启数据库分片开关。 
   **sh.enableSharding** *(database)*
   ![](https://support.huaweicloud.com/drs_faq/public_sys-resources/note_3.0-zh-cn.png)
   参数database表示要开启分片集合的数据库。
   
   
2. 设置基于哈希的分片键。 
   **sh.shardCollection** (*"\<database\>.\<collection\>", { \<shard key\> : "hashed" }*, false, {numInitialChunks: 预置的chunk个数})
   其中numInitialChunks值的估算方法是：db.collection.stats().size / (64\*1024\*1024) 。
   如果集合已经包含数据，则需要先使用如下命令对需要创建的基于哈希的分片键先创建哈希索引：
   **db.collection.createIndex()**
   然后再使用如下命令创建基于哈希的分片键：
   **sh.shardCollection()**
   
   
 
