1. 程式人生 > >MongoDB 數據模型

MongoDB 數據模型

多個 bms 創建 文件 java 處理 database ins 文件夾

MongoDB數據庫介紹

  • 特點

    • 面向集合存儲
    • 豐富的查詢語句
    • 復制集機制
    • 支持文件存儲
    • 模式自由
    • 多級索引
    • 易水平擴展
    • 跨平臺、支持語言眾多
    • 可插入式存儲引擎(3.0)
  • 適用場景

    • 數據緩存
    • JSON格式的數據
    • 局伸如性場景
    • 弱事務類型業務

    MongoDB更多適合於大數據量、高並發、弱事務的互聯網應用,其內置的水平擴展 機制提供了從幾百萬到十億級別的數據處理能力,可以很好的滿足Web2.0和移動互聯網應 用的數據存儲要求。

MongoDB的相關網站

官方文檔:https://docs.mongodb.com/tutorials/

中文網站:http://www.mongoing.com/

谷歌Group:https://groups.google.com/forum/

MongoDB概念解析

SQL術語/概念 MongoDB術語/概念 解釋/說明
database database 數據庫
table collection 數據庫表/集合
row document 數據記錄行/文檔
column field 數據字段/域
index index 索引
table joins embedded documents/reference 表連接/(內嵌/引用)
primary key primary key 主鍵,MongoDB自動將_id字段設置為主鍵

通過下圖實例,可以更直觀的的了解Mongo中的一些概念:

技術分享圖片


數據庫

多個文檔組成集合,而多個集合組成了數據庫。一個MongoDB實例可以 承載多個數據庫,每個數據庫都有獨立的權限,在磁盤上,不同的數據庫也 可放置在不同的文件夾中(啟動時加directoryperdb選項)。

為了更好的組織數據,一般情況下,會把屬於同一個應用程序(或同一種 業務類型)的所有數據放到一個數據庫中。

show dbs 命令可以顯示所有數據的列表。

? at [09/10/17][0:21:00] 
? ?  mongo
MongoDB shell version: 3.2.11
connecting to: test
> exit
bye
? at [09/10/17][0:21:04] 
? ?  mongo
MongoDB shell version: 3.2.11
connecting to: test
> show dbs
local  0.000GB

執行 "db" 命令可以顯示當前數據庫對象或集合。

> db
test

運行use db_name命令,切換數據庫,沒有數據庫時自動創建

> use local
switched to db local
> db
local
> 

以上實例命令中,local 是你要鏈接的數據庫。

在下一個章節我們將詳細講解MongoDB中命令的使用。

數據庫也通過名字來標識。數據庫名可以是滿足以下條件的任意UTF-8字符串。

  • 不能是空字符串("")。
  • 不得含有‘ ‘(空格)、.、$、/、\和\0 (空字符)。
  • 數據庫名字區分大小寫(建議數據庫名全部使用小寫)
  • 最多64字節。
  • 不要與系統保留的數據庫名字相同,這些數據庫包括:admin、local、 config等

有一些數據庫名是保留的,可以直接訪問這些有特殊作用的數據庫。

  • admin: 從權限的角度來看,這是"root"數據庫。要是將一個用戶添加到這個數據庫,這個用戶自動繼承所有數據庫的權限。一些特定的服務器端命令也只能從這個數據庫運行,比如列出所有的數據庫或者關閉服務器。
  • local: 這個數據永遠不會被復制,可以用來存儲限於本地單臺服務器的任意集合
  • config: 當Mongo用於分片設置時,config數據庫在內部使用,用於保存分片的相關信息。

相關操作

命令 操作
db 查看當前數據庫
show dbs 查看當前端口有多少數據庫
use db_name 切換數據庫,沒有數據庫時自動創建
db.dropDatabase() 刪除數據庫

文檔

文檔是MongoDB最核心的概念,本質上是一種類JSON的BSON格式的數據。
BSON是一種類JSON的二進制格式數據,它可以理解為在JSON基礎上添加了 _些新的數據類型,包括曰期、int32、int64等。
BSON是由一組組鍵值對組成,它具有輕量性、可遍 歷性和高效性三個特征。可遍歷性是MongoDB將BSON 作為數據存儲的主要原因。
BSON官網地址:http://bsonspec.org/

{
    fieldl:valuel,
    field2:value2,
    field3:value3,
    ...
    fieldN:valuen
}

下表列出了 RDBMSMongoDB 對應的術語:

RDBMS MongoDB
數據庫 數據庫
表格 集合
文檔
字段
表聯合 嵌入文檔
主鍵 主鍵 (MongoDB 提供了 key 為 _id )
數據庫服務 客戶端
Mysqld/Oracle mysql/sqlplus
mongod mongo

需要註意的是:

  1. 文檔中的鍵/值對是有序的。MongoDB會盡量保持文檔被插入時鍵值對的順序
  2. 文檔中的值不僅可以是在雙引號裏面的字符串,還可以是其他幾種數據類型(甚至可以是整個嵌入的文檔)。
  3. MongoDB區分類型和大小寫。
  4. MongoDB的文檔不能有重復的鍵。
  5. 文檔的鍵是字符串。除了少數例外情況,鍵可以使用任意UTF-8字符。
  6. MongoDB中寫操作的原子性限制在文檔級別,對文檔的保存、修改、刪除 等都是原子操作
  7. 單個文檔占用的存儲空間不能超過16MB

關於文檔鍵的命名需要註意以下幾點:

  • _id是系統保留的關鍵字,它是默認的主鍵,該值在集合中必須唯一,且不可更改
  • .(命名空間)和$(操作符)有特別的意義,只有在特定環境下才能使用。
  • 以下劃線"_"開頭的鍵是保留的(不是嚴格要求的)。
  • 鍵不能包含\0或空字符,這個字符用於表示鍵的結尾
  • 鍵是區分大小寫的且不能重復例如:{foo:l,Foo:l}

內嵌文檔

文檔可以作為鍵的值,這樣的文檔稱為內嵌文檔。內嵌文檔可以使數據不用保存成扁平結構的鍵值對,從而使數據組織方式更加自然。

例如:下面是一個與博客管理有關的文檔

{
    _id: <Objectldl>, 
    title: MongoDBDateModeln, 
    author: foo, 
    comments:[
    {who:"John",comment:"Good"} 
    {who:"Joe",comment:"ExceUent"}
    ]
}

上面的文檔可以進行如下的拆分:

技術分享圖片

即拆分成引用文檔.

內嵌文檔特點

  • 子文檔比較少時,可以保證原子性,同時具備高速查詢;
  • 子文檔比較多時,會影響查詢和更新速度,同時也帶來數據冗余

集合

把一組相關的文檔放到一起組成了集合,如果將MongoDB的一個文檔比喻 為關系型數據庫中的一行,那麽一個集合就相當於一張表。

MongoDB的集合是模式自由的,一個集合裏面的文檔可以是各式各樣。

例如:下面的兩個文檔可以出現了同一個集合中。

{"x":1}
{"x":1,"y":2}
{"x":1,"y":2,"z":5}

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

MongoDB提供了一些特殊功能的集合,例如:cappedcollection、 system.indexes、system.namespaces 等。

合法的集合名

  • 集合名不能是空字符串""。
  • 集合名不能含有\0字符(空字符),這個字符表示集合名的結尾。
  • 集合名不能以system.開頭,這是為系統集合保留的前綴。
  • 用戶創建的集合名字不能含有保留字符。有些驅動程序的確支持在集合名裏面包含,這是因為某些系統生成的集合中包含該字符。除非你要訪問這種系統創建的集合,否則千萬不要在名字裏出現$(註:可包含.) 

如下實例:

db.col.findOne()

capped collections

Capped collections 就是固定大小的collection。

它有很高的性能以及隊列過期的特性(過期按照插入的順序). 有點和 "RRD" 概念類似。

Capped collections是高性能自動的維護對象的插入順序。它非常適合類似記錄日誌的功能 和標準的collection不同,你必須要顯式的創建一個capped collection, 指定一個collection的大小,單位是字節。collection的數據存儲空間值提前分配的。

要註意的是指定的存儲大小包含了數據庫的頭信息。

db.createCollection("mycoll", {capped:true, size:100000})
  • 在capped collection中,你能添加新的對象。
  • 能進行更新,然而,對象不會增加存儲空間。如果增加,更新就會失敗 。
  • 數據庫不允許進行刪除。使用drop()方法刪除collection所有的行。
  • 註意: 刪除之後,你必須顯式的重新創建這個collection。
  • 在32bit機器中,capped collection最大存儲為1e9( 1X109)個字節。

命名空間

把數據庫名添加到集合名字前面,中間用點號連接,得到集合的完全限定 名,就是命名空間,例如:命名空間parent.sub。

需要說明的是,點號還可以出現在集合名字中,例如:parent.subling0,parent.subling2可以將subling0和subling2集合看作是parent集合的子集合。
使用子集合可以使我們更好的組織數據,使數據的結構更加清晰明了。

元數據

數據庫的信息是存儲在集合中。它們使用了系統的命名空間:

dbname.system.*

在MongoDB數據庫中名字空間<dbname>.system.*是包含多種系統信息的特殊集合(Collection),如下:

集合命名空間 描述
db.system.namespaces 列出所有名字空間。
db.system.indexes 列出所有索引。
db.system.profile 包含數據庫概要(profile)信息。
db.system.users 列出所有可訪問數據庫的用戶。
db.local.sources 包含復制對端(slave)的服務器信息和狀態。

對於修改系統集合中的對象有如下限制。

{{system.indexes}}插入數據,可以創建索引。但除此之外該表信息是不可變的(特殊的drop index命令將自動更新相關信息)。

{{system.users}}是可修改的。 {{system.profile}}是可刪除的。


MongoDB 數據類型

BSON可以理解為在JSON基礎上添加了一些新的數據類型,包括Date,正貝IJ 表達式,對數值類型的更進一步劃分等。

數據類型 類型編號 數據類型 類型編號
Double 1 Regular Expression 11
String 2 JavaScript 13
Object 3 Symbol 14
Array 4 JavaScript(Scope) 15
Binarydata 5 32-bit integer 16
Object id 7 Timestamp 17
Boolean 8 64-bit integer 18
Date 9 Min Key 255
Null 10 Max Key 127

可以使用類型編號進行條件查詢如下:

db.collection.find({name:{$type:2}})

基本數據類型

  • null 表示空值或不存在的字段例如:db.collection.find({nyn:null})

    • 布爾有兩個值true或false 例如:{"y":true}
  • 數值類型支持32-int、64-int以及64-double

    註:JavaScript只支持64位浮點數

    例如:

    • {"y":10} - double
    • {"y":Numberlnt(10)} - 32
    • {"y":NumberLong(10)} - 64
    7 Documents:0 > db.demo.insert({y:10})
    WriteResult({ "nInserted" : 1 })
    8 Documents:1 > db.demo.find({y:{$type:1}})
    { "_id" : ObjectId("5a7863305640374fb2cd5620"), "y" : 10 }
    9 Documents:1 > db.demo.insert({y:NumberInt(10)})
    WriteResult({ "nInserted" : 1 })
    10 Documents:2 > db.demo.find({y:{$type:16}})
    { "_id" : ObjectId("5a78636d5640374fb2cd5621"), "y" : 10 }
    11 Documents:2 > db.demo.insert({y:NumberLong(10)})
    WriteResult({ "nInserted" : 1 })
    12 Documents:3 > db.demo.find({y:{$type:18}})
    { "_id" : ObjectId("5a7863915640374fb2cd5622"), "y" : NumberLong(10) }
    • 字符串使用UTF-8對字符串進行編碼例如:{"y":"HelloMongoDB"}
  • 二進制數據可以保存由任意字節組成的字符串,例如:圖片、視頻等

  • 正則表達式:主要用於查詢,使用正則表達式作為限定條件

    例如:

    • {name:/foo/} name字段含有foo的文檔
    • {name:/foo/i} name字段含有foo的文檔,且不區分大小寫
    • {name:/^foo/i} name字段以foo幵頭,且不區分大小寫
  • JavaScript代碼:文檔中可以包含任意的JavaScript代碼

    例如:{"func":function(){}}

Date日期

  • MongoDB中,日期類型是一個64位的整數,它代表的是距Unixepoch的毫秒數
  • MongoDB在存儲時間時,先轉化為UTC時間
  • 北京時間(CST) = UTC + 8個小時
  • MongoDBShell中可以使用newDate或ISODate來創建時間對象,在進行顯示時,Shell會根據本地時間去設置顯示日期對象
14 Documents:3 > var mydate0 = new Date()
15 Documents:3 > var mydate9 = ISODate()
16 Documents:3 > mydate0
ISODate("2018-02-05T14:04:43.243Z")
17 Documents:3 > mydate9
ISODate("2018-02-05T14:04:57.715Z")
18 Documents:3 > mydate9.toString()
Mon Feb 05 2018 22:04:57 GMT+0800 (CST)

Timestamp

  • 時間戳類型有兩部分組成:

技術分享圖片

  • Timestmp只供MongoDB數據庫服務內部使用,用於記錄操作的詳細時間
  • Timestamp類型和Date類型是沒有關系的,對於我們來說使用更多的Date類型
  • 相關函數:Timestamp()

Objectld

Objectld由24個十六進制字符構成,每個字節存儲兩位十六進制數字,總共需 12字節存儲空間

每個字節代表的含義如下:

技術分享圖片

這種方式生成的Objectld在分布式仍然是唯一的.

相關函數

  • Objectld()

    用於取得Objectld

  • getTimestamp()

    用於取得Objectld的時間戳

  • valueOf()

    用於取得Objectld的字符串表示

19 Documents:3 > x = ObjectId()
ObjectId("5a7866e75640374fb2cd5623")
20 Documents:3 > x.getTimestamp()
ISODate("2018-02-05T14:15:03Z")
21 Documents:3 > x.valueOf()
5a7866e75640374fb2cd5623

數組

  • 數組是使用方括號來表示的一組值,它既可以作為有序對象(列表、棧、隊 歹|J),也能作為無序對象(如集合)來操作

  • 數組中可以包含不同數據類型的元素(字符串、浮點數、文檔等)

    例如:[3.14,"hello",[l2,3],{"key":"MongoDB"}]

    針對數組MongoDB提供了許多特定的操作符,例如:$push$pop$pull$slice$addToSet

  • MongoDB可自動的為數組元素建立Multikey索引

MongoDB 數據模型