Mongodb 主键:使用 ObjectId() 设置 _id 字段的示例

什么是主键 MongoDB?
In MongoDB,_id 字段作为集合的主键,以便每个文档都可以在集合中唯一标识。_id 字段包含唯一的 ObjectID 值。
默认情况下,在集合中插入文档时,如果没有添加字段名称中包含 _id 的字段名称,则 MongoDB 将自动添加一个 Object id 字段,如下所示
当查询集合中的文档时,您可以看到集合中每个文档的 ObjectId。
如果你想确保 MongoDB 在创建集合时不会创建 _id 字段,如果您想指定自己的 id 作为集合的 _id,那么您需要在创建集合时明确定义这一点。
当明确创建 id 字段时,需要在其名称中使用 _id 来创建。
让我们看一个例子来了解如何实现这一点。
db.Employee.insert({_id:10, "EmployeeName" : "Smith"})
Code 说明:
- 我们假设正在创建集合中的第一个文档,因此在创建集合时的上述语句中,我们明确定义字段 _id 并为其定义一个值。
如果命令执行成功,现在使用 find 命令显示集合中的文档,将显示以下输出
输出:
输出清楚地表明,我们在创建集合时定义的 _id 字段现在用作集合的主键。
什么是 ObjectId? MongoDB?
ObjectId 是默认值类型, MongoDB 分配给 _id 主键。这是一个 12 字节的标识符,旨在跨服务器和集合全局唯一,因此两个文档几乎永远不会获得相同的值。因为客户端驱动程序无需向服务器请求即可生成 ObjectId, MongoDB 无需中央计数器即可快速插入文档并扩展到多台机器。
每个 ObjectId 都以紧凑的二进制形式存储,但显示为 24 个字符的十六进制字符串,例如 ObjectId(“507f1f77bcf86cd799439011”)。前几个字节基于当前时间,这意味着随着文档的创建,这些值会稳步递增。这使得 ObjectId 不仅唯一,而且可以大致按插入顺序排序,当您想要优先显示最新或最旧的记录时,这是一个非常有用的特性。
一个结构 MongoDB 对象标识
A MongoDB ObjectId 的长度正好是 12 个字节,每个部分都有特定的含义。理解这种结构有助于解释为什么 ObjectId 是唯一的并且按时间顺序排列:
- 4字节时间戳: 自 Unix 纪元以来的秒数,记录对象 ID 的创建时间。这使得 ID 可以按时间排序。
- 5字节随机值: 每个进程生成一次的值,结合了机器和进程标识,因此不同的客户端会生成不同的 ID。
- 3字节递增计数器: 一个计数器,从随机值开始,并随着同一秒内每个新的 ObjectId 的增加而递增,从而防止快速插入期间发生冲突。
这三个部分共同确保每个 ObjectId 都是唯一的,即使多个文档同时插入到不同的服务器上也是如此。您可以随时通过调用 ObjectId 的 getTimestamp() 方法读取其嵌入的创建时间。
使用 ObjectId 作为主键的优势
使用默认的 ObjectId 作为 _id 主键有几个实际的好处,这也是为什么大多数情况下都这样做的原因。 MongoDB 收藏品依赖于它:
- 自动生成: 您无需自行创建或管理键值,从而降低了出现重复键的几率。
- 全球独特性: ObjectId 在各个服务器上保持唯一性,因此它们在分布式和分片部署中效果很好。
- 内置时间戳: 内置的创建时间允许您按文档的创建时间进行排序或筛选,而无需额外的日期字段。
- 高性能: 客户端生成避免了与服务器的往返通信,保持ping 快速插入。
虽然 ObjectId 适用于大多数应用场景,但当使用自然的业务键能简化查询时,您仍然可以选择自定义 _id,例如电子邮件地址或产品代码。正确的选择取决于您计划如何查找和关联数据。


