3

我想要一个比 MongoDB 的 ObjectID 更友好的面对 id(即 Youtube 风格:/posts/cxB6Ey6)。

我读到为了可扩展性,最好将 _id 保留为 ObjectID,所以我考虑了两种解决方案:

1)为每个文档添加一个索引的 postid 字段

2)创建_id和postid之间的映射集合

在这两种情况下,都使用https://github.com/dylang/shortid之类的东西来生成短 id,并在生成时通过查询数据库确保 id 是唯一的。(这个查询生成插入可以是原子操作吗?)

这些解决方案会对性能产生显着影响吗?

这样做的最佳策略是什么?

4

3 回答 3

5

这样做的正常方法是对一个唯一的 id 进行 base64 编码,但是:

为每个文档添加一个索引的 postid 字段

你肯定想采用这种方法。在这两种方法中,我会说这种方法很容易是最具可扩展性和性能的,因为它只需要一次往返即可获得简短的 URL 详细信息,而第二种选择需要 2 次。另一个考虑是索引开销不足维护一个额外的集合,这有点不费吹灰之力。

我也不会替换_id文档中的字段,因为默认值ObjectId在可预见的将来仍然有用。

因此,这将其限制为 URL 短代码的单独字段和索引(唯一键)。

接下来是您不想要一个 ID,它会在每次插入之前强制您查询数据库的唯一性。这就是ObjectId闪耀的地方。擅长在ObjectId客户端应用程序中创建,同时在数据库中是唯一的,而无需专门查询这些假设。

不需要首先查询数据库的唯一 ID 通常是基于时间的。在 PHP ( http://php.net/manual/en/function.uniqid.php ) 和 MongoDB 驱动程序 ( http://docs.mongodb.org/manual/core/object-id/ ) 甚至插件中- 在您链接到 github(https://github.com/dylang/shortid/blob/master/lib/shortid.js#L50)时,它们都使用时间作为独一无二的基础。

考虑到您链接的插件不会查询数据库以检查其自己的 ID 唯一性,我会说这个插件可能非常高效,如果您将它与您所说的第一个解决方案一起使用,您应该从中获得一个很好的基准.

于 2013-01-05T16:16:37.847 回答
3

ObjectID如果你想用自定义的用户友好的短 id替换内置,那么就这样做。您可以使用内置_id字段或id为您的自定义 ID 添加新的唯一索引字段。使用 build-in 的好处ObjectID是即使您的数据库非常大,它们也不会重复。因此,通过用短 id 替换它们,您将承担 id 重复的风险。

现在关于性能。我认为最好的解决方案是不要在数据库中查询 id,因为通过适当调整 id 长度,重复的概率非常小。因此,在此模型中处理 ids 重复的最佳方法是检查 Mongo 响应。如果它以“重复键错误”响应,那么您将生成一个新的。

现在关于缩放。要扩展您的自定义 ID,您只需向其添加更多符号。“重复键错误”应是进行该更改的触发器。一般不会出现这样的错误。因此,如果它们开始出现,那么是时候扩大规模了。

于 2013-01-05T09:57:06.657 回答
1

我认为ObjectId_id字段生成不会直接影响可伸缩性或性能。这会发生在哪里?

主要区别在于 ObjectId 是由 MongoDB 创建的,您不必为此承担责任。否则,您必须自己确定 id 的最佳大小并确保_id集合中存储的文档的每个字段的唯一值。它是必需的,因为_id用作主键。如果您没有很大的集合并且您需要标识符的自定义值,这可能是合理的。

但是,您可以使用_id存储 ObjectId 值的字段作为从时间创建对象 id 的机会,并在查询中利用这一事实来发挥您的优势,从而获得额外的好处。您还可以使用getTimestamp()方法获取 ObjectId 创建的时间戳。在这种情况下排序_id相当于按创建时间排序。

但是,如果您要在 URL 或 HTML 中使用 ObjectId,那么出于安全考虑,您可以对其进行加密。防止信息泄露和获取对象的创建时间。这可能是安全风险。

关于您的解决方案:

1)我想这是非常方便和灵活的解决方案。在这种情况下,您可以指定任何postId不直接依赖于_id.

但是这个解决方案的小缺点是你必须有额外的字段并创建额外的索引。While_id被自动索引。

2)从noSQL方法的性能和理念的角度来看,我认为这不是一个好的解决方案。

于 2013-01-05T15:52:12.380 回答