1. 程式人生 > >MongoDB----邏輯與物理儲存結構

MongoDB----邏輯與物理儲存結構

基本的操作

一、常用的命令和基礎知識

1、進入MongoDB shell

首先我們進入到MongoDB所在目錄執行

cd /work/app/mongodb/bin/
#啟動
./mongo

為了方便執行我們可以,這樣直接在終端輸入mongo呼叫就可以了

alias mongo='/work/app/mongodb/bin/mongo'

如果想永久生效,把他加入到/etc/profile中即可
2、檢視資料庫命令

 
#可以通過show dbs;  或者 和Mysql一樣執行show databases;

> show dbs;
local  0.000GB
> show databases;
local  0.000GB
> 
 

3、開啟資料庫

和關係型資料庫(mysql)中開啟資料庫是一樣的

#使用資料庫使用use dbs即可,進入後可以使用showtables;去檢視資料庫中的表
> use dbs;
switched to db dbs
> show tables;
> 

從上面可以看出,一個MongoDB例項是由一個或多個數據庫組成的

但是這裡需要注意:

在Mysql中的表中,我們給裡面的每行叫做‘記錄’,但是在MongoDB中我們給每行資料叫做‘文件’

所以在MongoDB中我們給每個表叫做‘集合’。集合中就是儲存了文件的集合。

檢視當前資料庫中的集合命令為:

show collections;

所以:show tables; 和 show databases;命令只是相容關係型資料庫而已,因此他們之間的層次關係就明白了

總結:

1、MongoDB邏輯概念總結

文件:文件(Document)是MongodDB中的核心概念,他是MongoDB邏輯儲存的最小基本單元

集合:多個文件組成的集合

資料庫:多個集合組成的資料庫

MongoDb 關係型資料庫Mysql
文件(document) 行(row)
集合(collections) 表(table)
資料庫(databases) 資料庫(databases)

 

 

 

 

2、MongoDB 物理儲存總結

2.1 名稱空間檔案:名稱空間(.ns結尾檔案) 它儲存了分配和正在使用的磁碟空間

2.2 資料庫檔案:以(0,1,2,3...)結尾的,並且後面的檔案大小是前面一個檔案大小的2倍!

為什麼MongodDB物理儲存使用這種方式設計呢?好處是什麼?:當一方面如果資料庫很小的時候,不至於資料庫小而浪費儲存空間,另外一方面如果資料庫增長比較快,通過預分配的方式,是上一個檔案的兩倍的辦法,來避免資料的劇增造成分配檔案造成的效能下降,來預分配空間,以空間的辦法來換取效能的提升。

2.3 日誌檔案

    系統日誌檔案logpath
    oplog複製操作日誌檔案 #只有在主從複製開啟之後才會出現
    慢查詢日誌  #需要開啟後才可以

慢查詢日誌通過help就可以看到如何啟用

  #這兩個引數需要組合使用 --slowms 大於多少秒才算慢查詢 
  --slowms arg (=100)                   value of slow for profile and console 
                                        log
  #預設是關閉的, 1為慢查詢,all為所有的都日誌
  --profile arg                         0=off 1=slow, 2=all

我們可以通過配置檔案進行設定:

profile=1
#生產中這裡應該大於200毫秒,並且這個必須根據生產中實際的需求來定義的
slowms=1

MongoDB資料型別

MongodDB的資料型別是:BSON的資料型別

BSON:是Binary JSON是二進位制的格式,能將MongoDB的所有文件表示為位元組字串!

JSON:是一種輕量級的資料交換格式。它基於JavaScript的一個子集!

一、在初識MongoDB的時候瞭解“幫助”

1、最高的幫助

在MongoDB shell中輸入help

複製程式碼
> help
        db.help()                    help on db methods
        db.mycoll.help()             help on collection methods
        sh.help()                    sharding helpers
        rs.help()                    replica set helpers
        help admin                   administrative help
        help connect                 connecting to a db help
        help keys                    key shortcuts
        help misc                    misc things to know
        help mr                      mapreduce

        show dbs                     show database names
        show collections             show collections in current database
        show users                   show users in current database
        show profile                 show most recent system.profile entries with time >= 1ms
        show logs                    show the accessible logger names
        show log [name]              prints out the last segment of log in memory, 'global' is default
        use <db_name>                set current database
        db.foo.find()                list objects in collection foo
        db.foo.find( { a : 1 } )     list objects in foo where a == 1
        it                           result of the last line evaluated; use to further iterate
        DBQuery.shellBatchSize = x   set default number of items to display on shell
        exit                         quit the mongo shell
> 
複製程式碼

2、開啟資料庫在資料庫中檢視幫助

進入到資料庫中後我們可以使用db.help()檢視資料庫級別的幫助

db.help()  #檢視資料庫級別的幫助,裡面會顯示資料庫級別的幫助

3、檢視集合中的幫助

> show dbs;
local  0.000GB
tim    0.000GB
> show collections;
users
> db.users.help()

二、建立資料庫

檢視當前的資料庫

> show dbs;
local  0.000GB
tim    0.000GB

可以看到當前只有tim和系統自帶的local資料庫,我們通過use 去開啟一個數據庫shuai並且檢視資料庫

> use shuai;
switched to db shuai
> show dbs;
local  0.000GB
tim    0.000GB
> 

發現數據庫並沒有新增,當我們在給資料庫中的集合插入一條文件的時候就會:自動建立一條文件合、一個集合、一個數據庫。

 
> db.users.insert({"uid":1})
WriteResult({ "nInserted" : 1 })
> 
#這個時候看下是否添加了資料庫和集合!!!
> show dbs;
local  0.000GB
shuai  0.000GB
tim    0.000GB

#當前資料庫"shuai"下的集合
> show collections;
users
> 
 

2、插入一條資料

 
> db.users.insert({"uid":2,"uname":"luotianshuai","isvip":true,"sex":null,"favorite":["apple","banana",1,2,3,4,5],"regtime":new Date()})
WriteResult({ "nInserted" : 1 })
> db.users.find()
{ "_id" : ObjectId("5754f1ea4b7f62c4992c4ef4"), "uid" : 1 }
{ "_id" : ObjectId("5754f2c84b7f62c4992c4ef5"), "uid" : 2, "uname" : "luotianshuai", "isvip" : true, "sex" : null, "favorite" : [ "apple", "banana", 1, 2, 3, 4, 5 ], "regtime" : ISODate("2016-06-06T03:49:28.946Z") }
 

注:這裡的資料型別,列表、字典,這裡的new Date()是MongoDB就類似Django Model的時間選項類似於:date = models.DateTimeField(auto_now=True)

3、查詢資料

查詢一條資料

 
> db.users.findOne({"uid":2})
{
        "_id" : ObjectId("5754f2c84b7f62c4992c4ef5"),
        "uid" : 2,
        "uname" : "luotianshuai",
        "isvip" : true,
        "sex" : null,
        "favorite" : [
                "apple",
                "banana",
                1,
                2,
                3,
                4,
                5
        ],
        "regtime" : ISODate("2016-06-06T03:49:28.946Z")
}
> 
 

並且我們可以吧取出來的資料儲存在一個變數中,並且通過變數去呼叫其值

 
> a = db.users.findOne({"uid":2})
{
        "_id" : ObjectId("5754f2c84b7f62c4992c4ef5"),
        "uid" : 2,
        "uname" : "luotianshuai",
        "isvip" : true,
        "sex" : null,
        "favorite" : [
                "apple",
                "banana",
                1,
                2,
                3,
                4,
                5
        ],
        "regtime" : ISODate("2016-06-06T03:49:28.946Z")
}

#並且可以通過變數去呼叫裡面的值
> a.
a._id                    a.favorite               a.isvip                  a.regtime                a.toLocaleString(        a.uid                    a.valueOf(
a.constructor            a.hasOwnProperty(        a.propertyIsEnumerable(  a.sex                    a.toString(              a.uname
> a.
 

 三、MongoDB中的資料型別和Mysql資料型別對比

 
> db.users.insert({"uid":3,"salary":312402039840981098098309,"a":1.2423412314223423413})
WriteResult({ "nInserted" : 1 })

> b = db.users.findOne({"uid":3})
{
        "_id" : ObjectId("5754f7214b7f62c4992c4ef6"),
        "uid" : 3,
        "salary" : 3.124020398409811e+23,
        "a" : 1.2423412314223423
}
 

1、MongoDB中的數字型別和Mysql中的數字型別對比

檢視MongoDB中的數字型別他們都是number型別的

 
> typeof(b.uid)
number
> typeof(b.salary)
number
> typeof(b.a)
number
> 
 

可以看出在MongoDB中所有的數字型別都是數值型別的,我們比較下Mysql中的數字型別!

在Mysql中類似“uid":3 這個3應該屬於普通的整數,或者是短整形

類似薪水:salary 應該是長整型

類似a應該是雙精度浮點型

數字:

在Mysql中對數字型別分的非常詳細,有短整形、長整型,浮點數分為單精度和雙精度浮點型,而在MongoDB都是64位的浮點數!這樣的好處就是很簡單,他不需要區分數字型別,就是number型別,簡單、簡潔。容易理解和在處理的時候也方便。

字串:

在Mysql中分為定長、變長字串,無論是定長字串或者變長字串,都要對長度事先定義!但是MongoDB中無需事先定義,對長度沒有並且的定義並且他甚至可以儲存一篇文章!也表現的簡單、簡潔、

布林型:

布林值只有:真、假分別用:True  False  表示

null值:

 
> db.users.find({"sex":null})
{ "_id" : ObjectId("5754f1ea4b7f62c4992c4ef4"), "uid" : 1 }
{ "_id" : ObjectId("5754f2c84b7f62c4992c4ef5"), "uid" : 2, "uname" : "luotianshuai", "isvip" : true, "sex" : null, "favorite" : [ "apple", "banana", 1, 2, 3, 4, 5 ], "regtime" : ISODate("2016-06-06T03:49:28.946Z") }
{ "_id" : ObjectId("5754f7214b7f62c4992c4ef6"), "uid" : 3, "salary" : 3.124020398409811e+23, "a" : 1.2423412314223423 }
> 
 

咱們查詢以”sex“ 為null條件,但是查詢出了3條結果可以得出:

在MongoDB中,1、null代表著值為null   2、或者欄位不存在。

那麼怎麼把欄位存在並且為null值得文件查找出來呢?

> db.users.find({"sex":null,"sex":{"$exists":true}})
{ "_id" : ObjectId("5754f2c84b7f62c4992c4ef5"), "uid" : 2, "uname" : "luotianshuai", "isvip" : true, "sex" : null, "favorite" : [ "apple", "banana", 1, 2, 3, 4, 5 ], "regtime" : ISODate("2016-06-06T03:49:28.946Z") }
> 
#我們查詢sex為null的並且給其加一個條件    值存在{"$exists":true}

陣列:

一組資料集合

物件型別:

比如日期型別,日期型別是通過物件型別產生的,但是處理日期比較麻煩!這個也是MongoDB的問題表現力不足

 

BSON的特點:優點:簡單、簡潔、容易理解、解析方便、記憶

缺點:表現力不足比如日期格式(處理起來就比較麻煩)

四、命名規則

1、文件的鍵名命名幾乎所有utf8字串,只有以下少數例外

  1. $開頭
  2. \0   空字串
  3. _下劃線開頭,可以用但是不建議使用,凡是系統生成的都是以_開頭命名的,所以在實際生產中我們不使用_開頭的!

2、集合的命名幾乎所有的utf8字串,只有以下少數例外

  1. $開頭
  2. \0   空字串
  3. system.開頭
  4. ”“空字串

 3、資料庫的命名幾乎所有的utf8字串,只有以下少數例外

  1. $開頭
  2. \0   空字串
  3. system.開頭
  4. ”“空字串
  5. /
  6. \

並且這裡需要注意:資料庫名是不區分大小寫的,如果你有一個shuai的資料庫,你在建立一個SHUAI的資料庫插入資料的時候就會報錯,我們一般建立資料庫的時候都把MongoDB的資料庫名為小寫。