MongoDB學習【二】—MongoDB基礎和數據類型

1、MongoDB基礎知識

在MongoDB中相關術語的解釋和sql術語對應關係正則表達式

SQL術語/概念 MongoDB術語/概念 解釋/說明
database database 數據庫
table collection 數據庫表/集合
row document 數據記錄行/文檔
column field 數據字段/域
index index 索引
table joins   錶鏈接,MongoDB不支持
primary key primary key 主鍵,MongoDB自動將_id字段設置爲主鍵

經過下圖實例,咱們也能夠更直觀的瞭解Mongo中的一些概念sql

1.數據庫

一個mongodb中能夠創建多個數據庫。mongodb

MongoDB的默認數據庫爲"db",該數據庫存儲在data目錄中。數據庫

MongoDB的單個實例能夠容納多個獨立的數據庫,每個都有本身的集合和權限,不一樣的數據庫也放置在不一樣的文件中。express

數據庫相關操做

show databases  # 顯示當前服務器上全部數據庫
​
use database  # 使用某個數據庫,若是不存在則建立

數據庫也經過名字來標識。數據庫名能夠是知足如下條件的任意UTF-8字符串。數組

  • 不能是空字符串("")。服務器

  • 不得含有' '(空格)、.、$、/、\和\0 (空字符)。數據結構

  • 應所有小寫。併發

  • 最多64字節。分佈式

有一些數據庫名是保留的,能夠直接訪問這些有特殊做用的數據庫。

  • admin: 從權限的角度來看,這是"root"數據庫。要是將一個用戶添加到這個數據庫,這個用戶自動繼承全部數據庫的權限。一些特定的服務器端命令也只能從這個數據庫運行,好比列出全部的數據庫或者關閉服務器。

  • local: 這個數據永遠不會被複制,能夠用來存儲限於本地單臺服務器的任意集合

  • config: 當Mongo用於分片設置時,config數據庫在內部使用,用於保存分片的相關信息。

2.文檔(Document)

文檔是MongoDB的核心概念。

文檔是一組鍵值(key-value)對(即 BSON)。MongoDB 的文檔不須要設置相同的字段,而且相同的字段不須要相同的數據類型,這與關係型數據庫有很大的區別,也是 MongoDB 很是突出的特色。

須要注意的是:

  1. 文檔中的鍵/值對是有序的。

  2. 文檔中的值不只能夠是在雙引號裏面的字符串,還能夠是其餘幾種數據類型(甚至能夠是整個嵌入的文檔)。

  3. MongoDB區分類型和大小寫。

  4. MongoDB的文檔不能有重複的鍵。

  5. 文檔的鍵是字符串。除了少數例外狀況,鍵可使用任意UTF-8字符。

文檔鍵命名規範:

  • 鍵不能含有\0 (空字符)。這個字符用來表示鍵的結尾。

  • .和$有特別的意義,只有在特定環境下才能使用。

  • 如下劃線"_"開頭的鍵是保留的(不是嚴格要求的)。

3.集合

集合就是 MongoDB 文檔組,相似於 RDBMS (關係數據庫管理系統:Relational Database Management System)中的表格。

若是將MongoDB中的一個文檔比喻爲關係型數據的一行,那麼一個集合就是至關於一張表。

好比,咱們能夠將如下不一樣數據結構的文檔插入到集合中:

{"site":"www.baidu.com"}
{"site":"www.google.com","name":"Google"}
{"site":"www.runoob.com","name":"菜鳥教程","num":5}

1.集合存在於數據庫中,一般狀況下爲了方便管理,不一樣格式和類型的數據應該插入到不一樣的集合,但其實集合沒有固定的結構,這意味着咱們徹底能夠把不一樣格式和類型的數據通通插入一個集合中。

2.組織子集合的方式就是使用「.」,分隔不一樣命名空間的子集合。

好比一個具備博客功能的應用可能包含兩個集合,分別是blog.posts和blog.authors,這是爲了使組織結構更清晰,這裏的blog集合(這個集合甚至不須要存在)跟它的兩個子集合沒有任何關係。

3.當第一個文檔插入時,集合就會被建立。

合法的集合名:

  • 集合名不能是空字符串""。

  • 集合名不能含有\0字符(空字符),這個字符表示集合名的結尾。

  • 集合名不能以"system."開頭,這是爲系統集合保留的前綴。

  • 用戶建立的集合名字不能含有保留字符。有些驅動程序的確支持在集合名裏面包含,這是由於某些系統生成的集合中包含該字符。除非你要訪問這種系統建立的集合,不然千萬不要在名字裏出現$。

2、MongoDB數據類型

在概念上,MongoDB的文檔與Javascript的對象相近,於是能夠認爲它相似於JSON。

下表爲MongoDB中經常使用的幾種數據類型。

數據類型 描述
String 字符串。存儲數據經常使用的數據類型。在 MongoDB 中,UTF-8 編碼的字符串纔是合法的。
Integer 整型數值。用於存儲數值。根據你所採用的服務器,可分爲 32 位或 64 位。
Boolean 布爾值。用於存儲布爾值(真/假)。
Double 雙精度浮點值。用於存儲浮點值。
Min/Max keys 將一個值與 BSON(二進制的 JSON)元素的最低值和最高值相對比。
Array 用於將數組或列表或多個值存儲爲一個鍵。
Timestamp 時間戳。記錄文檔修改或添加的具體時間。
Object 用於內嵌文檔。
Null 用於建立空值。
Symbol 符號。該數據類型基本上等同於字符串類型,但不一樣的是,它通常用於採用特殊符號類型的語言。
Date 日期時間。用 UNIX 時間格式來存儲當前日期或時間。你能夠指定本身的日期時間:建立 Date 對象,傳入年月日信息。
Object ID 對象 ID。用於建立文檔的 ID。
Binary Data 二進制數據。用於存儲二進制數據。
Code 代碼類型。用於在文檔中存儲 JavaScript 代碼。
Regular expression 正則表達式類型。用於存儲正則表達式。

1.ObjectId

ObjectId 相似惟一主鍵,能夠很快的去生成和排序,包含 12 bytes,含義是:

  • 前 4 個字節表示建立 unix 時間戳,格林尼治時間 UTC 時間,比北京時間晚了 8 個小時

  • 接下來的 3 個字節是機器標識碼

  • 緊接的兩個字節由進程 id 組成 PID

  • 最後三個字節是隨機數

MongoDB 中存儲的文檔必須有一個 _id 鍵。這個鍵的值能夠是任何類型的,默認是個 ObjectId 對象

因爲 ObjectId 中保存了建立的時間戳,因此你不須要爲你的文檔保存時間戳字段,你能夠經過 getTimestamp 函數來獲取文檔的建立時間:

> var newObject = ObjectId()
> newObject.getTimestamp()
ISODate("2017-11-25T07:21:10Z")

ObjectId 轉爲字符串。

> newObject.str
5a1919e63df83ce79df8b38f

2.時間戳

BSON 有一個特殊的時間戳類型用於 MongoDB 內部使用,與普通的 日期 類型不相關。 時間戳值是一個 64 位的值。其中:

  • 前32位是一個 time_t 值(與Unix新紀元相差的秒數)

  • 後32位是在某秒中操做的一個遞增的序數

在單個 mongod 實例中,時間戳值一般是惟一的。

在複製集中, oplog 有一個 ts 字段。這個字段中的值使用BSON時間戳表示了操做時間。

BSON 時間戳類型主要用於 MongoDB 內部使用。在大多數狀況下的應用開發中,你可使用 BSON 日期類型。

3.日期

表示當前距離 Unix新紀元(1970年1月1日)的毫秒數。日期類型是有符號的, 負數表示 1970 年以前的日期。

> var mydate1 = new Date()     //格林尼治時間
> mydate1
ISODate("2018-03-04T14:58:51.233Z")
> typeof mydate1
object
> var mydate2 = ISODate() //格林尼治時間
> mydate2
ISODate("2018-03-04T15:00:45.479Z")
> typeof mydate2
object

這樣建立的時間是日期類型,可使用 JS 中的 Date 類型的方法。

返回一個時間類型的字符串:

> var mydate1str = mydate1.toString()
> mydate1str
Sun Mar 04 2018 14:58:51 GMT+0000 (UTC) 
> typeof mydate1str
string

或者

> Date()
Sun Mar 04 2018 15:02:59 GMT+0000 (UTC)  

4.數據類型使用實例

#一、null:用於表示空或不存在的字段
d={'x':null}
#二、布爾型:true和false
d={'x':true,'y':false}
#三、數值
d={'x':3,'y':3.1415926}
#四、字符串
d={'x':'egon'}
#五、日期
d={'x':new Date()}
d.x.getHours()
#六、正則表達式
d={'pattern':/^egon.*?nb$/i}
​
正則寫在//內,後面的i表明:
i 忽略大小寫
m 多行匹配模式
x 忽略非轉義的空白字符
s 單行匹配模式
​
#七、數組
d={'x':[1,'a','v']}
​
#八、內嵌文檔
user={'name':'egon','addr':{'country':'China','city':'YT'}}
user.addr.country
​
#九、對象id:是一個12字節的ID,是文檔的惟一標識,不可變
d={'x':ObjectId()}

5._id和ObjectId

MongoDB中存儲的文檔必須有一個"_id"鍵。這個鍵的值能夠是任意類型,默認是個ObjectId對象。
在一個集合裏,每一個文檔都有惟一的「_id」,確保集合裏每一個文檔都能被惟一標識。
不一樣集合"_id"的值能夠重複,但同一集合內"_id"的值必須惟一

#一、ObjectId
ObjectId是"_id"的默認類型。由於設計MongoDb的初衷就是用做分佈式數據庫,因此可以在分片環境中生成
惟一的標識符很是重要,而常規的作法:在多個服務器上同步自動增長主鍵既費時又費力,這就是MongoDB採用
ObjectId的緣由。
ObjectId採用12字節的存儲空間,是一個由24個十六進制數字組成的字符串
    0|1|2|3|   4|5|6|     7|8    9|10|11    
    時間戳      機器      PID    計數器
若是快速建立多個ObjectId,會發現每次只有最後幾位有變化。另外,中間的幾位數字也會變化(要是在建立過程當中停頓幾秒)。
這是ObjectId的建立方式致使的,如上圖

時間戳單位爲秒,與隨後5個字節組合起來,提供了秒級的惟一性。這個4個字節隱藏了文檔的建立時間,絕大多數驅動程序都會提供
一個方法,用於從ObjectId中獲取這些信息。

由於使用的是當前時間,不少用戶擔憂要對服務器進行時鐘同步。其實不必,由於時間戳的實際值並不重要,只要它老是不停增長就好。
接下來3個字節是所在主機的惟一標識符。一般是機器主機名的散列值。這樣就能夠保證不一樣主機生成不一樣的ObjectId,不產生衝突

接下來連個字節確保了在同一臺機器上併發的多個進程產生的ObjectId是惟一的

前9個字節確保了同一秒鐘不一樣機器不一樣進程產生的ObjectId是惟一的。最後3個字節是一個自動增長的 計數器。確保相同進程的同一秒產生的
ObjectId也是不同的。

#二、自動生成_id
若是插入文檔時沒有"_id"鍵,系統會自幫你建立 一個。能夠由MongoDb服務器來作這件事。
但一般會在客戶端由驅動程序完成。這一作法很是好地體現了MongoDb的哲學:能交給客戶端驅動程序來作的事情就不要交給服務器來作。
這種理念背後的緣由是:即使是像MongoDB這樣擴展性很是好的數據庫,擴展應用層也要比擴展數據庫層容易的多。將工做交給客戶端作就
減輕了數據庫擴展的負擔。
相關文章
相關標籤/搜索