在MongoDB用户集合中,将电子邮件作为_id使用。

7

我在MongoDB中有一个用户集合。_id当前是标准的MongoDB生成的ObjectId。我还针对必填的“email”字段设置了唯一键约束。这似乎是浪费。

如果我将'email'字段丢弃并将该数据作为'_id'字段,是否存在任何不应这样做的原因?

2个回答

19

我已经阅读了尼尔的回答并在某种程度上同意他(我也对“显著的性能提升”非常怀疑)。在你的问题中,我没有发现“你要用这个电子邮件地址做什么”。你是要通过它进行搜索还是只是保存在那里?而且前面的回答中没有解决的一个最重要的问题是:它是否会被更改?

使用你的系统的人更改电子邮件地址并不罕见(丢失/不再使用)。如果将_id作为他们的电子邮件地址,则无法轻松更改它(无法在mongo中修改_id)。在这种情况下,你需要复制、删除和添加新元素(这不是原子操作)。

因此,我认为这是不这样做的一个很大的理由。但你需要决定是否允许用户更改电子邮件地址。


那种罕见的使用情况 - 更改电子邮件 - 可以通过添加具有实际电子邮件的单独文档/行/列来避免,不是吗?您无需复制所有数据 - 您只需添加用于通知的实际电子邮件即可。 - Nikolay Fominyh
@NikolayFominyh 这并不是一个罕见的情况。我非常怀疑,相比于没有将电子邮件作为您的_id字段,添加一个带有一些信息的新文档是否更简单。 - Salvador Dali
@SalvadorDali,是的。但你仍然不必复制所有数据。我只是在谈论它。添加别名需要一些应用逻辑,但不像看起来那么困难。 :) - Nikolay Fominyh

7

一般来说,如果你使用“电子邮件”作为主键,没有真正的理由,事实上,如果你确实使用“电子邮件”作为主键,可以获得显著的性能提升。

  1. 在大多数情况下,查找主键是最常见的操作。即使创建了不同字段的唯一键,MongoDB 也会进行优化,以便轻松找到“_id”字段索引。它总是存在的。

  2. 没有额外的空间用于索引。因此,在查找主键时,除默认索引外,不需要拉入任何其他内容,这自然也节省了磁盘空间,并节约了需要进行的 I/O 成本。

也许唯一真正相关的考虑是分片。只有当您的用例更适合某些不同形式的“桶式”分布的“高/低”卷用户时,才需要考虑这一点。在这种情况下,需要其他形式的主键以便于实现这一点。

通常占据“_id”字段的默认“ObjectId”类型非常好,因为它保持自然插入顺序,甚至使得可能执行基于范围或时间的查询(在合理范围内)。因此,当需要自然插入顺序时,它通常是最佳选择,并且高度冲突安全。

但是,如果您通常正在查找主键值,则任何为自然主键服务的东西都应该放在集合的“_id”字段中,只要可以合理地保证其唯一性即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接