MongoDB的复合片键战略
我有这样的文件: {_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”查询会发生什么?它是否碰到了所有的碎片来收集结果?
在创建分片键时理解它们非常重要,它们需要与常规键(主键或次键)相比具有不同的属性。通常,碎片将包含相似分片键值的数据块(即,存在于特定范围内的值)分组。所以,一个好的分片密钥不应单调递增。
在复合分片键的情况下,由于它包含“_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”值。
我试过你上面发布的代码,但得到**语法错误**。这里是命令:'db.test_collection.ensureIndex({{“foo”:1,“bar”:1}:“hashed”})'。 – angelokh