# ObjectId 与主键设计

URL: https://caijiao.org/mongodb/04-modeling/03-objectid
Source: docs/mongodb/04-modeling/03-objectid.md
Description: 本章节介绍 MongoDB 中 ObjectId 的作用及主键设计原则，帮助用户合理管理文档唯一标识。

MongoDB 默认使用 `ObjectId` 作为文档的唯一标识（主键），该字段存储在 `_id` 字段中，每个文档必须唯一。

## ObjectId 结构

`ObjectId` 是一个 12 字节的 BSON 类型，包含：

- 4 字节时间戳（精确到秒）
- 5 字节随机值（机器标识和进程 ID）
- 3 字节自增计数器

这种结构保证了在分布式环境下的唯一性和按时间排序的特性。

## 主键设计原则

- 默认使用 [MongoDB](/mongodb/) 自动生成的 `_id`（ObjectId），适用于绝大多数场景。
- 如果业务需求有特殊主键，可以自定义 `_id` 字段，如字符串、数字等，但必须保证唯一性。
- 避免频繁更新 `_id`，因为主键不可变，更新需删除重建。
- 主键应尽量短小，避免占用过多存储空间，影响索引效率。
- 利用 ObjectId 的时间戳部分，可以进行时间范围查询或排序。

## 示例

默认插入文档，自动生成 ObjectId：

```js
db.users.insertOne({ name: "Alice", age: 30 })
// _id 字段自动生成 ObjectId
````

自定义 `_id`：

```js
db.products.insertOne({ _id: "SKU12345", name: "Product A" })
```

---

理解 ObjectId 及主键设计，有助于保障数据唯一性和查询效率，是数据库设计的重要环节。
