MongoDB 复合分片键策略

MongoDB compound shard key strategy

我有这样的文件: {_id: "someid1", "bar": "somevaluebar1"} {_id: "someid2", "foo": "somevaluefoo2", "bar": "somevaluebar2"} {_id: "someid3", "foo": "somevaluefoo3", "zoo": "somevaluezoo3"} {_id: "someid4", "zoo": "somevaluezoo4"}

1。 如果我们最多按 "foo" 查询文档,其次按 "bar" 查询文档,那么创建像 { "foo" : 1, [=23= 这样的复合分片键是否有意义] : 1, "_id" : 1 }?

2。 "foo" 或 "bar" 也可能从文档中丢失,因此我将“_id”添加到复合分片键。这是一个好的决定吗?

3。 如果我通过"bar"查询会发生什么?是不是打遍了所有的分片才得到结果?

注:回答有些问题,太老了,无法调试。

如果需要,可以作为正确答案删除,不确定 Whosebug 政策。

在创建分片键时理解这一点很重要,与常规键(主要或次要)相比,它们需要具有不同的 属性。通常,分片将包含相似分片键值(即位于特定范围内的值)的数据块分组。所以,一个好的分片键不应该是单调递增的。

在复合分片键的情况下,因为它包含“_id”字段,所以它对于每个文档都是唯一的。因此,对于分片键来说,它是一个糟糕的选择,因为所有的块都会被转储到一个分片上。这可以通过使用散列键来克服,如下所示,

sh.shardCollection("<your-db>", {{ "foo" : 1, "bar" : 1, "_id" : 1 }:"hashed"})

现在,解决您提出的各个问题。 1. 由于您在 "foo" 上查询数据的次数多于 "bar",因此将 "foo" 作为分片键是有意义的。如果 "foo" 是均匀分布的,则不需要对其进行哈希处理。

  1. 您可以用一些虚拟值编辑 "foo" 字段,这样您就不需要在复合分片键中添加“_id”。但是,如果空 "foo" 字段的数量很多,您可以使用一系列虚拟值。

  2. 如果你只根据"foo"创建分片,当你使用"bar"查询时,所有的分片都会被命中以收集结果。

tl;博士。如果 "foo" 上的操作频率明显高于基于 "bar" 的操作,并且 "foo" 均匀分布在所有行上,那么 foo 可以用作分片键,并且虚拟值( s) 可用于填充缺失的 "foo" 值。