我什么时候应该在MongoDB中使用ObjectId vs UUID



我正在使用MongoDB制作一个简单的CRUD应用程序,以便我可以了解更多信息。

该应用程序是一个简单的博客,我有一个名为"文章"的集合,它存储各种文档,每个文档代表我博客的帖子。

当我显示所有博客文章的列表时,我可以做一个db.collection.find((,并列出所有这些。

但问题是当我需要单独显示单个帖子时,当我需要查询单个特定文档的集合时。

合乎逻辑的解决方案是使用RDBMS和自动增量功能,但MongoDB是NoSQL,没有自动增量功能。

我正在使用文档自动生成的_id字段,该字段默认存储 ObjectId,这意味着我的 url 如下所示:

http://localhost/blog/article.php?_id=5d41f6e5fc1a2f3d80645185

我在文档中看到 ObjectId 包含服务器的唯一标识符,以及时间戳和计数器,暴露这些东西不是安全风险吗?

作为解决方案,我偶然发现了UUID https://docs.mongodb.com/manual/reference/method/UUID/,这是一个自动生成的唯一ID,不会在其中公开时间戳和计算机信息。使用它而不是包含我的 ObjectId 的_id来查询和查找文档似乎是一个合乎逻辑的解决方案。

所以我可以让我的网址看起来像这样:

http://localhost/blog/article.php?_id=23829651-26f7-4092-99d0-5be8658c966e

但是,我应该保留_id属性吗? 我应该添加另一个名为"id"的存储 UUID 的吗? 我甚至应该使用 UUID 吗?

以下是我在选择标识符之前要考虑的内容:

碰撞

UUIDsObjectIDs的碰撞风险都非常低。这个问题在另一个问题中已经详细讨论过了。

自然界

UUIDs是随机的,而ObjectID值总是随着时间的推移而增加。这使得ObjectIDs成为分片的糟糕选择。

其他用途

ObjectIDs将创建时间戳作为一部分,可以用作常用createdAt字段的替代。按ObjectIDs排序是按创建时间排序。

不安全的对象引用 (OWASP(

简短定义:如果攻击者具有一个对象的 ID,则无法推断另一个对象的 ID。您可以在此处阅读有关此内容的更多信息。UUIDsObjectIDs都不容易受到此影响.
链接到另一个讨论ObjectIDs安全性的问题(感谢zbee(。

易于使用

注意:这是主观的
在Mongo生态系统中使用ObjectIds要容易得多。处理ObjectIDs+库的特殊聚合运算符的存在增加了它。

可移植性

UUIDsObjectIDs更便携。除了Mongo之外,我不知道任何其他系统在内部使用ObjectIDs。而还有其他数据库,例如 Postgres,它们具有用于UUIDs的特殊数据类型 + 用于随机生成的扩展等。

最新更新