- #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 有什麼優勢?:
- 全域唯一且可由 Client 端自動生成,不需向資料庫請求序號,適合分散式環境。
- 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