我的文档结构是:
"_id": ObjectId("50c41fae0e708237dc7a5187"),
"uid": "999",
"appname": "authentication",
"activityId": "login",
"activityName": "login",
"date": ISODate("2012-12-09T05: 20: 46.117Z"),
"yearmonth": "201212"
uid是来自RDMS序列的其他应用程序生成的用户标识。 yearmonth是我在应用程序中创建的人工字段,仅用于更好的分片密钥。
写模式: 当用户登录或在站点上执行特定操作时,我将事件写入mongoDB。这意味着uid相对随机,具有非常高的基数。 对于同一个uid,我可以编写数百个事件。
阅读模式: 大多数查询都基于uid作为第一个查询参数。 {uid:“9999”,日期:{$ gt:....},activityId:'login'}
我的初始分片键是{uid:1,date:1}。 - 提供良好的查询隔离,并且如果任何一个uid文件太多,则具有可拆分的块。 现在,基于How to choose a shard key:纸牌游戏文章和一些网络研讨会和评论在这个论坛上,我意识到更好的关键应该是 {粗时间戳:1,搜索条件:1}。想法是为分片键提供更好的位置以帮助提高写入性能。 所以我创建了yearmonth字段并考虑将我的分片键更改为{yearmonth:1,uid:1}
问题是: 由于更改,我是否会松开查询隔离和读取操作的性能? 我的查询参数将不再与分片键的第一个元素匹配。
答案 0 :(得分:0)
我会坚持使用uid,因为这是您将用于获取数据的关键。
分片键 - uid
特别是当它是基于随机uid的事件插入和读取时,将uid保持为分片键是非常理想的。
当块变得更大时,MongoDB中的 Balancer 将自动平衡不同分片服务器上的块。所以你也被覆盖在这里(因为自动平衡会照顾一些分片服务器变得越来越大)。
希望这有帮助。