MongoDB数据类型学习笔记
MongoDB 数据类型学习笔记
MongoDB 的核心是文档(Document),而文档的强大之处在于其值的类型非常丰富。与只有字符串、数字等简单类型的 JSON 不同,MongoDB(底层使用 BSON 格式)支持更多的数据类型,这使得数据存储和查询变得更加灵活和高效。
我们将这些数据类型分为几类来学习。
一、 常用基础类型
这些是构建文档最常用、最基础的砖块。
数据类型 | 描述与示例 | 注意事项 |
---|---|---|
String | 字符串,最常见的数据类型。 | 必须是合法的 UTF-8 编码。 |
{"name": "张三"} | ||
Integer | 整数,用于存储年龄、数量等。 | MongoDB 支持32位和64位整数。在 Mongo Shell 中输入的数字默认可能被视为浮点数。 |
{"age": 30, "quantity": 100} | ||
Double | 双精度浮点数,用于存储价格、坐标等小数。 | {"price": 19.99, "latitude": 39.9} |
Boolean | 布尔值,用于表示真或假。 | {"is_active": true, "is_deleted": false} |
Null | 用于表示一个字段为空值或不存在。 | {"middle_name": null} |
二、 结构化类型
这两种类型是构建复杂、嵌套文档结构的关键。
数据类型 | 描述与示例 | 注意事项 |
---|---|---|
Object | 内嵌文档 (Embedded Document),一个文档可以嵌套在另一个文档中。 | 这是实现复杂数据关系的核心,无需像关系型数据库那样进行表连接。 |
{"user": "李四", "address": {"city": "上海", "street": "南京路"}} | ||
Array | 数组,可以将多个值存储在一个键中。 | 数组中的元素可以是不同类型的,包括数字、字符串、甚至内嵌文档。 |
{"tags": ["nosql", "database", 101], "scores": [85, 92, 78]} |
三、 特殊ID与时间类型 (重点)
这几个类型非常重要,特别是 ObjectId
和 Date
,理解它们的区别是关键。
1. ObjectId
- 文档的“身份证”
每个存入 MongoDB 的文档都必须有一个 _id
键,它的值在集合内必须是唯一的。ObjectId
就是 _id
的默认数据类型。
-
特性:
ObjectId
是一种特殊设计的12字节ID,它不是一个简单的随机字符串,而是由四部分组成:- 4字节时间戳:文档创建时的Unix时间戳(精确到秒)。这让你可以根据ID大致排序文档的创建时间!
- 3字节机器码:运行MongoDB实例的主机唯一标识符。
- 2字节进程ID (PID):创建该ID的MongoDB进程的ID。
- 3字节计数器:一个随机起始的、自增的计数器,确保在同一秒内生成的ID也是唯一的。
-
优点:
- 自动生成:你无需手动指定主键,MongoDB 会帮你处理。
- 高度唯一:在分布式系统中也能基本保证唯一性。
- 自带时间信息:可以从
ObjectId
中提取出文档的创建时间。
-
实用操作示例:
// 在 Mongo Shell 中创建一个新的 ObjectId > var newId = ObjectId() > print(newId) ObjectId("632b0a1f9d7a2b4d8c7e4f2b")// 从 ObjectId 中提取创建时间 > newId.getTimestamp() ISODate("2022-09-21T12:08:31Z") // 这是格林尼治时间 (UTC)// 将 ObjectId 转换为普通字符串 > newId.toString() 'ObjectId("632b0a1f9d7a2b4d8c7e4f2b")' > newId.str // 一个更简洁的属性 '632b0a1f9d7a2b4d8c7e4f2b'
2. Date
- 推荐使用的日期类型
这是在应用中存储时间、日期信息的标准和推荐方式。
-
存储格式:它内部存储的是一个64位整数,表示自 Unix 纪元(1970年1月1日 UTC)以来经过的毫秒数。它可以表示1970年之前的时间(负数)。
-
优点:
- 类型精确:它是一个真正的日期类型,而不是字符串。
- 查询友好:MongoDB 提供了丰富的查询操作符(如
$gt
,$lt
)来对日期进行范围查询。 - 时区中立:所有日期都以UTC(格林尼治标准时间)格式存储,避免了时区混淆。
-
实用操作示例:
// 创建一个表示当前时间的 Date 对象 > var now = new Date() > print(now) ISODate("2025-09-19T06:30:00.000Z") // 输出 ISODate 格式// 检查它的类型 > typeof now object // 在 JavaScript 环境中,Date 是一个对象
3. Timestamp
- 内部使用的时间戳
请注意: 这个类型不应该被用作常规的日期时间存储。
-
用途:它主要供 MongoDB 内部使用,特别是在**复制(Replication)的操作日志(oplog)**中,用来记录操作的精确顺序。
-
结构:它是一个64位的值,由两部分组成:
- 前32位:Unix时间戳(秒)。
- 后32位:在这一秒内发生的第几次操作的序号。
-
核心区别:
Date
是用来记录“某个事件发生在哪个时间点”的。Timestamp
是用来记录“某个操作在数据库内部的发生顺序”的。
结论:在你的业务开发中,当你需要存储创建时间、更新时间、生日等信息时,请始终使用 Date
类型。
四、 其他类型
这些类型在特定场景下非常有用。
数据类型 | 描述 |
---|---|
Binary Data | 用于存储二进制数据,如图片、文件等。(但更推荐使用 GridFS 来存储大文件)。 |
Code | 用于在文档中直接存储 JavaScript 代码。 |
Regular expression | 用于存储正则表达式,可以直接在查询中使用。 |