DAY5 資料型別與 _id
資料型別
首先要理解 MongoDB 儲存的格式 BSON,就是 Binary JSON,雖然呈現都是 JSON 格式,但儲存還是有型別之分,這就是 BSON 的優點。
BSON 型別有以下幾種,常見的就不特別說明了
- int
- long
- string
- double
- decimal
- bool
- date
- timestamp
- array
- null
- binData:此欄位儲存二進制的資料(binary data)
- objectId:MongoDB 的精髓,稍後會提到
- object:相當於
embedded document
或nested document
,更白話的說就是文件內的子文件,如範例的publisher
欄位:
1 | { |
- regex: 這型別是宣告此欄位專門用來儲存正則式
1 | { |
- javascript:儲存 javascript 語法用
1 | { |
–
資料型別有很多,不過使用上多半還是原始的那幾種,比較多人討論到的是時間型別。
Date
我本身還真的沒使用過,大部分都是使用Timestamp
就能解決,且還有時區問題,如果沒開發過跨時區系統,請務必縝密思考使用情境,例如不同時區的使用者如何查詢資料。
_id 是什麼
- MongoDB 預設每一個文件都有的欄位(連 embedded document 也是)
- 系統會自動產生這個欄位
- 每一個文件的唯一位置
- 系統預設的 single index key
- Collection 層級的唯一值
- 資料型別為
ObjectId
長相如下:_id: ObjectId("612cf44a031915cb2af17374")
_id 是由16進位、24字元所組成的(請特別注意並不等於 string),故 ObjectId 為 12 bytes,這 12 bytes 組成依序為:
- Timestamps 的 4 bytes
- 隨機碼的 5 bytes。
- 隨機起始的遞增計數器 3 bytes
特別要注意的是 timestamp 精確度只到秒級;第二項的隨機碼又可拆分為
- 機器碼(machine id) 3 bytes
- 作業序(process id) 2 bytes
*註:這個項目在 MongoDB document 已經移除細節討論,不過還是可以從過往文章來了解
所以最常被提及到的是,「系統產生的 _id 是否會重複?」關於這個答案其實可以從拆分的這 12 bytes 得到答案,在非刻意的情況下,理論上是有可能重複的。假設一秒內一台機器的同一個process,產生超過 3bytes 的計數器數量,就有可能會重複了。但在大部分商務情境使用,應該是沒什麼機會遇到
_id 可否自行定義?
可以,只要你確保 Collection 層級的唯一性。
假設這是一個會員 Collection,那通常 MemberId
就相當適合當作 _id 欄位,因為 MemberId 是不會重複的,且可以快速地找到這筆資料,是上上之選。
_id 一定要 ObjectId 型別?
其實上面的問題就給出答案了,不需要。
int, long 都可以當作是 _id 的型別,只是 MongoDB 幫你產生的是 ObjectId。