创建哈希索引
要为已包含数据的集合启用分片,必须创建支持分片分片键的索引。 要为空集合启用分片,您可以在对集合进行分片时指定分分片键索引集合。
哈希索引支持哈希分片,即根据分片键值的哈希将数据分布在各个分片上。
要创建单字段哈希索引,请指定 hashed
作为索引键的值:
db.<collection>.createIndex( { <field>: "hashed" } )
要创建包含多个字段的哈希索引(复合哈希索引),请将hashed
指定为单个索引键的值。 对于其他索引键,请指定排序顺序( 1
或-1
):
db.<collection>.createIndex( { <field1>: "hashed", <field2>: "<sort order>", <field3>: "<sort order>", ... } )
关于此任务
哈希索引非常适合具有像 ObjectId 值或时间戳这样单调变化字段的分片键。当您使用具有单调递增分片键值的范围分片时,上限为 MaxKey
的块将接收大多数传入写入。此行为将插入操作限制为单个分片,从而消除了分片集群中分布式写入的优势。
有关为应用程序选择最佳分片方法的更多信息,请参阅哈希分片与范围分片对比。
选择哈希分片键
对于哈希分片密钥,请考虑以下指南:
您选择作为哈希分片键的字段应具有较高的关联基数,即有大量不同的值。
如果您的数据模型不包含具有高关联基数的单个字段,请考虑创建复合哈希索引。 复合哈希索引可提供更多唯一索引值,并可增加关联基数。
您的分片键应支持常见的查询模式。范围查询(如
$gt
和 {$lt
)不能使用哈希索引。如果您的应用程序经常对分片键中包含的字段执行范围查询,请考虑改用基于范围的分片。
哈希索引最多可包含 32 个字段。
开始之前
如要实施哈希分片,您必须部署一个分片群集。
示例
以下示例展示了如何:
创建单字段哈希索引
考虑一个已经包含数据的 orders
集合。在 orders
集合的 _id
字段中创建哈希索引:
db.orders.createIndex( { _id: "hashed" } )
_id
字段单调递增,因此非常适合作为哈希索引键。 尽管_id
值逐渐增加,但当MongoDB为各个_id
值生成哈希时,这些哈希值不太可能位于同一数据数据块上。
创建索引后,您可以对 orders
集合进行分片:
sh.shardCollection( "<database>.orders", { _id: "hashed" } )
创建复合哈希索引
考虑一个已经包含数据的 customers
集合。在 name
、address
和 birthday
字段上的 customers
集合中创建一个复合哈希索引:
db.customers.createIndex( { "name" : 1 "address" : "hashed", "birthday" : -1 } )
在创建复合哈希索引时,您必须将 hashed
指定为单个索引键的值。对于其他索引键,请指定排序顺序 (1
or -1
)。在前面的索引中,address
是哈希字段。
创建索引后,您可以对 customers
集合进行分片:
sh.shardCollection( "<database>.customers", { "name" : 1 "address" : "hashed", "birthday" : -1 } )