我在MongoDB中有一个用户集合。_id当前是标准的MongoDB生成的ObjectId。我还针对必填的“email”字段设置了唯一键约束。这似乎是浪费。
如果我将'email'字段丢弃并将该数据作为'_id'字段,是否存在任何不应这样做的原因?
我在MongoDB中有一个用户集合。_id当前是标准的MongoDB生成的ObjectId。我还针对必填的“email”字段设置了唯一键约束。这似乎是浪费。
如果我将'email'字段丢弃并将该数据作为'_id'字段,是否存在任何不应这样做的原因?
我已经阅读了尼尔的回答并在某种程度上同意他(我也对“显著的性能提升”非常怀疑)。在你的问题中,我没有发现“你要用这个电子邮件地址做什么”。你是要通过它进行搜索还是只是保存在那里?而且前面的回答中没有解决的一个最重要的问题是:它是否会被更改?
使用你的系统的人更改电子邮件地址并不罕见(丢失/不再使用)。如果将_id
作为他们的电子邮件地址,则无法轻松更改它(无法在mongo中修改_id
)。在这种情况下,你需要复制、删除和添加新元素(这不是原子操作)。
因此,我认为这是不这样做的一个很大的理由。但你需要决定是否允许用户更改电子邮件地址。
一般来说,如果你使用“电子邮件”作为主键,没有真正的理由,事实上,如果你确实使用“电子邮件”作为主键,可以获得显著的性能提升。
在大多数情况下,查找主键是最常见的操作。即使创建了不同字段的唯一键,MongoDB 也会进行优化,以便轻松找到“_id”字段索引。它总是存在的。
没有额外的空间用于索引。因此,在查找主键时,除默认索引外,不需要拉入任何其他内容,这自然也节省了磁盘空间,并节约了需要进行的 I/O 成本。
也许唯一真正相关的考虑是分片。只有当您的用例更适合某些不同形式的“桶式”分布的“高/低”卷用户时,才需要考虑这一点。在这种情况下,需要其他形式的主键以便于实现这一点。
通常占据“_id”字段的默认“ObjectId”类型非常好,因为它保持自然插入顺序,甚至使得可能执行基于范围或时间的查询(在合理范围内)。因此,当需要自然插入顺序时,它通常是最佳选择,并且高度冲突安全。
但是,如果您通常正在查找主键值,则任何为自然主键服务的东西都应该放在集合的“_id”字段中,只要可以合理地保证其唯一性即可。