- #128
操作 MongoDB 一定会遇到的 _id ObjectId 问题
在 MongoDB 任何文件都会有个
_id字段作为 primary key,如果未指派 Mongo 会自动产生。而工作上就遇过几个与其相关的问题:- 使用
_id查询会暴露敏感信息吗? - 能否自定义 id?
_id的数据类型是 ObjectId而不是字符串或数字,为什么要特别设计这个东西?
根据 ObjectId 官方文档描述,ObjectId 数值是 12 bytes 的数据,组成如下:
- 一个 4 bytes 的时间戳,表示 ObjectId 的创建时间,以自 Unix 纪元以来的秒数计算。
- 一个 5 bytes 的随机值,每个客户端进程产生一次。该随机值对于机器和进程都是唯一的。如果进程重启或进程的主节点发生变化,则该值会被重新生成。
- 一个 3 bytes 的递增计数器,每个客户端进程初始值为一个随机值。当进程重新启动时,计数器会重置。
ObjectId 的目的为:
- 保证唯一性:确保不同服务或机器上唯一
- 包含时间戳:记录文档创建时间
- 效率:为分布式系统设计,生成时无需考虑其他服务
回到一开始的问题:
- 是否包含敏感信息:ObjectId 的确包含数据的创建时间,在某些商业情境下可能涉及隐私,且能抽样推估大致数据量。
- 是否可以自定义
_id:可以,但通常让_id负责技术上的唯一性,而语义上额外创建字段。
{_id: ObjectId("..."),userId: "u_123456"}- ObjectId 有什么优势?:
- 全局唯一且可由客户端自动生成,不需向数据库请求序号,适合分布式环境。
- MongoDB 强制作为文档的 primary key,并自动建立 unique index。
- 体积小且可排序(包含时间信息),对 index 与存储空间更友好。
- 使用
- #127
- #126
- #125
- #124
- #123
- #122
- #121
- #120
- #119
- #118
- #117
- #116
- #115
- #114
- #113
- #112
- #111
- #110
- #109
- #108
- #107
- #106
- #105
- #104
- #103
- #102
- #101
- #100
- #99
- #98
- #97
- #96
- #95
- #94
- #93
- #92
- #91
- #90
- #89
- #88
- #87
- #86
- #85
- #84
- #83
- #82
- #81
- #80
- #79
- #78
- #77
- #76
- #75
- #74
- #73
- #72
- #71
- #70
- #69
- #68
- #67
- #66
- #65
- #64
- #63
- #62
- #61
- #60
- #59
- #58
- #57
- #56
- #55
- #54
- #53
- #52
- #51
- #50
- #49
- #48
- #47
- #46
- #45
- #44
- #43
- #42
- #41
- #40
- #39
- #38
- #37
- #36
- #35
- #34
- #33
- #32
- #31
- #30
- #29
- #28
- #27
- #26
- #25
- #24
- #23
- #22
- #21
- #20
- #19
- #18
- #17
- #16
- #15
- #14
- #13
- #12
- #11
- #10
- #9
- #8
- #7
- #6
- #5
- #4
- #3
- #2
- #1