2016-06-17 23 views
0

我有这样的文件: {_id: "someid1", "bar": "somevaluebar1"} {_id: "someid2", "foo": "somevaluefoo2", "bar": "somevaluebar2"} {_id: "someid3", "foo": "somevaluefoo3", "zoo": "somevaluezoo3"} {_id: "someid4", "zoo": "somevaluezoo4"} MongoDB的复合片键战略

1. 如果我们通过查询“foo”的最多,“酒吧”第二,文件是否有意义创建的化合物等片键{“foo”:1,“bar”:1,“_id”:1}

2. 文件中可能缺少“foo”或“bar”,所以我在复合分片键中添加了“_id”。这是一个很好的决定吗?

3. 如果我用“bar”查询会发生什么?它是否碰到了所有的碎片来收集结果?

回答

0

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

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

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

现在,解决您提出的每个问题。 1.由于您在“foo”上查询数据的次数多于“bar”,因此将“foo”作为分片键是有意义的。如果“foo”是均匀分布的,则不需要散列。

  • 你可以用一些虚拟值编辑“foo”的领域,那么你就不需要在复合片键广告“_id”。但是,如果空“foo”字段的数量很高,则可以使用一系列虚拟值。

  • 如果您只是基于“foo”创建碎片,当您使用“bar”查询时,所有碎片都将被命中以收集结果。

  • tl; dr。如果“foo”上的操作频率显着高于“bar”操作,并且“foo”均匀分配给所有行,那么foo可以用作分片键,并且可以使用虚拟值填补缺失的“foo”值。

    +0

    我试过你上面发布的代码,但得到**语法错误**。这里是命令:'db.test_collection.ensureIndex({{“foo”:1,“bar”:1}:“hashed”})'。 – angelokh