1. 程式人生 > >Mongodb 資料庫(增刪改查)

Mongodb 資料庫(增刪改查)

MongoDB(芒果資料庫)

資料儲存階段

檔案管理階段(.txt   .doc   .xls)

資料庫管理階段

檔案管理階段

(.txt .doc .xls)

優點

1、使用簡單方便

2、資料能夠長期儲存

3、可以儲存大量資料

缺點

1、資料一致性差

2、資料的查詢修改不方便

3、資料冗餘(大量重複的資料)

資料庫管理階段

優點

1、資料組織結構化,降低冗餘

2、提高增刪改查效率

3、方便擴充套件

4、方便程式呼叫,做自動化的處理

缺點

1、資料庫使用特定的語句操作,相對複雜

資料

能夠輸入到計算機中並被識別處理的資訊的集合

資料結構

研究一個數據集合中,資料之間關係的學科

資料庫

按照資料結構儲存資料的倉庫。

在資料庫管理系統管理下一定介質上的資料集合。

資料庫管理系統

管理資料庫的軟體,用於建立維護資料庫

資料庫系統

由資料庫的資料庫管理系統等開發工具組成的集合

!關係資料庫

採用關係模型來組織資料結構的資料庫(二維表)

比如:oracle(甲骨文)  DB2  SQLServer(微軟) Mysql   sqlite(嵌入式)

優點

  1. 容易理解,邏輯類似常見的表格
  2. 使用方便,都使用sql語句很成熟
  3. 資料一致性高,冗餘低,完整性好

4、技術成熟,可以使用外部關聯複雜操作

缺點

1、 每次都需要sql語句的解析,消耗大

2、 不能很好的滿足併發需求,特別是海量資料爆發,讀寫能力不足

3、 關係型資料庫每一步都要加鎖,

以保證操作的原子性,增加了資料庫負擔

4、 資料的一致性有時會導致空間浪費

!非關係資料庫

(Nosql ----à   not noly sql)

優點

  1. 高併發,讀寫能力強
  2. 普遍比關係型資料庫容易擴充套件
  3. 弱化了資料結構,降低資料的一致性

缺點

  1. 通用性差,沒有sql語句一樣的一致化操作
  2. 操作過於冗長,容易混亂
  3. 沒有join等複雜操作,很多也不支援事務等操作

Nosql使用情況

  1. 對資料一致性要求低
  2. 資料庫需要處理海量併發
  3. 需要處理速度較快,比如做一個臨時的中間過度儲存器
  4. 資料庫構建比較方便的構建非關係模型

Nosql分類

1、鍵值型資料庫:Redis

2、列儲存資料庫

3、文件型資料庫:MongDB

4、圖形資料庫

MongoDB 資料庫 (非關係型資料庫 à 文件型 資料庫)

特點

1、由c++ 編寫的資料庫管理系統

2、支援豐富的增刪改查操作

3、支援豐富的資料型別

4、支援眾多的程式語言介面(python  PHP  c++  c# )

5、使用方便,便於部署,相對成熟

MongoDB安裝

自動安裝

sudo apt-get install mongodb

預設安裝位置

/var/lib/mongodb

配置檔案

  /etc/mongodb.conf

命令集(軟體安裝後提供功能性的命令)

/usr/bin  或者  /usr/local/bin

手動安裝

  1. 下載Mongodb(開源)

www.mongdb.com  --- >  get mongodb  --- > community server

選擇想要下載的版本

  1. 選擇合適的位置解壓(/use/local  /opt)

tar 解壓後得到 MongoDB 資料夾

  1. 將命令集(解壓後文件夾中bin目錄) 新增到環境變數

PATH=$PATH:/opt/mongo/bin

export PATH

將以上兩句新增 /etc/rc.local

4、重啟系統

MongoDB命令

設定資料庫儲存位置

mongod  --  dbopath 目錄

e.g. mongodb dboath dbs

設定資料庫埠

mongod  --port  8080

*預設埠  27017

進入mondo shell 介面:

mongodb的互動介面,操作資料庫

mongo

退出介面

quit() 或 ctrl + c

mongodb 資料庫組織形式

鍵值對 – > 文件 -- > 集合 -- > 資料庫

-----------------------------------------

ID  |  NAME  |   AGE  |

-----------------------------------------

1  |     lily   |   17   |

----------------------------------------

2  |    Lucy  |   20    |

----------------------------------------

{“_id”:1,

“NAME”:” lily”,

“AGE”:17

}

{“_id”:2,

“NAME”:” Lucy ”,

“AGE”:20

}

Mysql 和mongodb概念對比

mysql

mongodb

含義

database

database

資料庫

table

table

表/集合

column

field

欄位/域

row

document

記錄/文件

Index

Index

索引

mongodb資料庫關鍵詞

資料庫的建立

use databaseName

例子:

e.g.   use stu 

#建立一個stu資料庫

  1. use 實際上是表示選擇某個資料庫使用。

當這個資料庫不存在時會自動建立

  1.  使用use後資料不會馬上被建立,

而是在實際寫入資料時才會建立

檢視當前系統中資料庫

show dbs

系統資料庫

存放使用者及其許可權

admin

儲存本地資料

local

儲存分片資訊

config

資料庫的命名規則

  1. 使用utf-8字元
  2. 不能有空格、點、/、\、‘\0’字元
  3. 長度不能超過64位元組
  4. 不和系統資料庫重名

db

mongodb系統全域性變數,代表當前使用的資料庫

  1. 如果沒有使用任何資料庫情況下 db表示test。

此時插入資料則建立test資料庫

資料庫的備份和恢復

備份 : mongodb  -h  dbhost –d  dbname  –o  dbdir

                       主機    要備份資料庫  目錄

例子:

將stu資料庫備份到sthdent目錄中

mongodump -h 127.0.0.1 -d stu -o sthdent

恢復:mongorestore  -h  dbhost:port –d  dbname  path

                        主機          資料庫  目錄

例子:

將stu 資料庫恢復到sthdent 資料庫中

mongorestore -h 127.0.0.1:27017 -d sthdent sthdent/stu

 資料庫監測

mongostat

insert  query  update  delete  :每秒執行增刪改查次數

command :每秒執行命令此時

flushes : 每秒清理快取次數

vsize:使用的虛擬記憶體

res: 實體記憶體

監測每個資料的讀寫時長

mongotop

ns  :資料集合

total :總時長

read :讀時長

write :寫時長

刪除資料庫

刪除db代表的資料庫

db.dropDatbase()

建立集合

方法1

db.createCollection(collection_name)

例子:

建立一個class1的集合

db.createCollection("class1")

方法2

當向一個集合中插入資料的時候,如果這個集合不存在則會自動建立

db.collecinoName.insert(…)

例子:

如果class2不存在則自動建立

db.class2.insert({"name":'Tom','age':17,'sex':'m'})

檢視資料庫中的集合

show collections

show tables

集合命名規則

  1. utf-8 字元
  2. 不能有‘\0’
  3. 不要以system.開頭,因為這是系統保留集合字首
  4. 不要和關鍵字重複

刪除集合

db.collectionName.drop()

例子:

刪除class

db.class.drop()

集合的重新命名

db.collenctonName.renameCollection(“new_name”)

例子

db.class2.renameCollection("class0")

文件

Mongodb中資料的組織形式 --  > 文件

Mongodb檔案

以鍵值對形式組成的類似字典的資料描述形式

  1. 鍵:即文件的域

鍵的命名規則

  1. utf-8 字串
  2. 不含有‘\0’通常不用 . $
  3. 一個文件當中的鍵不能重複
  1. 文件中的鍵值對是有序的
  2. mongodb中資料嚴格區分大小寫

即文件儲存的資料    支援bson 資料

JavaScript ----- > 程式語言 前端

 |

json 前端和後端的傳輸格式

 |

bson

型別               

整型                   整數

    布林型別                true  false

浮點型                    小數

Array                      陣列

Timestamp                 時間戳

Date                      時間日期

Object                    內部文件

Null                      空值 null

String                    字串

Symbol                   特殊字串

Binary  data             二進位制字元

code                    程式碼

regex                    正則表示式

objeId                    objeId 子串

  1. objeId  

{ "_id" : ObjectId("5b504b6f25a94135d37fdf6c")

_id : 當在mongo 代表中插入文件時,如果不指定_id則會自動新增這個域,作為鍵。

ObjectID 值是系統自動生成的不重複子串標識

24位    前8位   文件建立時間

         6位     機器ID       

         4位     程序ID       

         6位     計數器

集合中的文件

  1. 集合中的文件不一定有相同的域
  2. 集合中的文件多少不一定相同
  3. 集合中的文件,值的型別不一定相同

集合設計

  1. 集合中的文件儘可能描述同一類資料
  2. 同一類資料不要過多分散在多個集合中存放
  3. 集合中文件的結構層次不易過多

獲取集合物件

db.getcollection(‘class1’) == > db.class1

例子:

db.getCollection('class1').insert({name:'Marry',age:16,sex:'w'})

增刪改查文件

插入文件

db.collectionName.insert()

例子:

插入單個文件

db.class0.insert({name:"HhanMei",age:17,sex:'w'})

  1. 插入資料時域名可以不加引號
  2. 檢視插入結果 db.class.find()
  3. _id 為系統自動新增主鍵,如果自己寫_id則為自己設定的值,

但是仍然不可重複

  1. 一個集合中的文件是有序的

save()插入文件

db.collectionName.save()

例子:

e.g.   db.class1.save({name:'Lily',age:13,sex:'w'})

插入多個文件

db.collectionName.insert([{},{},{}])

例子:

db.class2.insert([{name:'阿寶',age:32},{name:'阿哲',age:31},{name:'阿蓉',age:26}])

  1. 如果不加_id域時用法同insert()
  2. 如果加_id,此_id值存在則save表示修改該文件

檢視操作

mysql:    select … from table where …

mongo:   db.collection.find(query,field)

查詢所有內容

db.collection.find()  ---- > select *from table

查詢資料

Find(query,field)

引數:  query:   篩選條件,相當於where子句

        field:   選定要展示的域

返回值: 返回查詢找到的文件

query : 以鍵值對形式給出篩選條件

          {name:’Lily’}

      例子:查詢以name為Lily的域

        db.class1.find({name:'Lily'})

field:   以鍵值對的形式給出要展示(不展示)的域,

       域名為鍵,值為1表示展示,0表示不展示

        例子:顯示name為Lily但不展示_id

            db.class1.find({name:"Lily"},{_id:0})

  1. 如果某個域設定為0則表示不展示該域其它的均展示
  2. 如果某個域設定為1則表示該域其它的均不展示
  3. _id 必須設定為0才不會顯示
  4. 除了_id其餘設定的值必須相同

例子

> db.class1.find({name:'Lily'},{_id:0,name:1,age:1})

只查詢

第一條複合新增的文件

findOne(query,field)

引數返回值同find()

例子:

 db.class1.findOne({sex:'w'},{_id:0})

**************************************************

Query

更多篩選功能

操作符

使用$符號標註的一個有特殊意義的字串,用於表達一定的含義,

比如 $1t 表示小於

比較操作符

$eq  等於

例子:年齡等於13

> db.class1.find({age:{$eq:13}},{_id:0})

        等同於以下

> db.class1.find({age:13},{_id:0})

$lt   小於 <

例子: 年齡小於15

> db.class1.find({age:{$lt:15}},{_id:0})

  1. 字串也可以比較大小

$lte  小於等於  <=

例子 年齡小於等於15

> db.class1.find({age:{$lte:15}},{_id:0})

$gt   大於>

例子:年齡大於15

> db.class1.find({age:{$gt:15}},{_id:0})

$gte  大於等於

例子:年齡大於等於15

> db.class1.find({age:{$gte:15}},{_id:0})

$ne   不等於 !=

例子:年齡不等於13

> db.class1.find({age:{$ne:13}},{_id:0})

  1. 如果某個文件不存在查詢的域,則不等於可以匹配到該文件

$ in  包含

例子:檢視年齡包含在11,12,13,14的

> db.class1.find({age:{$in:[11,12,13,14]}},{_id:0})

$nin  不包含

例子:檢視年齡不包含在13,14的

> db.class1.find({age:{$nin:[13,14]}},{_id:0})

邏輯操作符

Query 逗號分隔的條件即為與關係

例子: 年齡大於13 小於16

> db.class1.find({age:{$gt:13,$lt:16}},{_id:0})

例子:年齡大於13 且性別女

db.class1.find({age:{$gt:13},sex:'w'},{_id:0})

$and 邏輯與

例子: 年齡大於13 且姓名大於Lily

db.class1.find({$and:[{age:{$gt:13}},{name:{$lt:'Lily'}}]},{_id:0})

$or 邏輯或

例子:年齡大於15或者為男生

db.class1.find({$or:[{age:{$gt:15}},{sex:'m'}]},{_id:0})

$not 邏輯非

例子:年齡不大於15

db.class1.find({age:{$not:{$gt:15}}},{_id:0})

$nor  即不也不

例子:既不大於16 也不是女生

db.class1.find({$nor:[{age:{$gt:16}},{sex:'w'}]},{_id:0})

練習:

 年齡小於16 並且為男生,或者年齡小於14

    db.class1.find({$or:[{age:{$gt:16},sex:'m'},{age:{$lt:14}}]},{_id:0})

 年齡大於16 或者為女生,並且姓名大於Jame

     db.class1.find({name:{$gt:'Jame'},$or:[{age:{$gt:16}},{sex:'w'}]},{_id:0})

陣列

陣列查詢

檢視陣列中是否包含某一項

例子:查詢包含78

> db.class3.find({score:78},{_id:0})

例子: 大於90

db.class3.find({score:{$gt:90}},{_id:0})

$all

查詢資料中同時包含多項

例子: 同時包含64 和75

> db.class3.find({score:{$all:[64,75]}},{_id:0})

$size

通過陣列元素個數查詢

例子:查詢陣列元素有3個

> db.class3.find({score:{$size:3}},{_id:0})

$slice

取出陣列的部分進行顯示  放在field中

例子:查詢陣列元素前2項  ,跳過第1項顯示後面一項

> db.class3.find({},{_id:0,score:{$slice:2}})

> db.class3.find({},{_id:0,score:{$slice:[1,1]}})

其它查詢方法

$exists

判斷一個域是否存在

例子:查詢儲存age域的文件

> db.class1.find({age:{$exists:true}},{_id:0})

  1. true 表示有這個域 false表示篩選無這個域

$mod

餘數查詢

例子:查詢年齡除以2餘1文件

> db.class1.find({age:{$mod:[2,1]}},{_id:0})

$type

找出值為指定型別的文件

例子:查詢age 資料型別為1的文件

> db.class1.find({age:{$type:1}},{_id:0})

查詢結果相關函式

distinct

功能:檢視集合某個域的取值範圍

例子:檢視集合中年齡域的範圍

> db.class1.distinct('age')

pretty()

功能:格式化顯示查詢結果

例子:

> db.class1.find().pretty()

limit()

功能: 顯示查詢結果的前n條

例子:顯示查詢結果的前3條

> db.class1.find({},{_id:0}).limit(3)

skip(n)

功能:跳過前n條顯示

例子:跳過前3條,顯示後面的記錄

> db.class1.find({},{_id:0}).skip(3)

count()

功能:計數統計

例子:統計男生數量

> db.class1.find({sex:'m'},{_id:0}).count()

sort

({域:1/-1})

功能: 對查詢結果排序

引數: 以鍵值對的形式給出

         1表示按照升序排序

         -1表示按照降序排序

例子:按照年齡升序,降序

> db.class1.find({},{_id:0}).sort({age:1})

> db.class1.find({},{_id:0}).sort({age:-1})

複合排序:當第一個排序項相同時比較第二排序項

例子: 年齡選項升序相同,比較姓名選項進行升序

> db.class1.find({},{_id:0}).sort({age:1,name:1})

函式的連續呼叫

當函式返回文件集合時還可以繼續呼叫函式

例子:查詢班級年齡最大的三個

> db.class1.find({},{_id:0}).sort({age:-1}).limit(3)

文件的刪除操作

Mysql刪除文件

delete from table where …

db.collection.remove(query,justOne)

功能: 刪除文件

引數: query

 篩選要刪除的文件,相當於where用法同查詢

      justOne

 布林值,預設為false 表示刪除所有。

如果設定為true 只刪除第一條符合條件的文件

例子:justOne為true 則只刪除第一條符合條件

> db.class0.remove({age:17},true)

例子:刪除集合中姓名為Tom

> db.class0.remove({name:Tom})

例子:刪除集合中所有文件

db.class2.remove({})

練習:

  1. 建立資料庫名字叫  grade

use geage

  1. 資料庫中建立集合 class

3、集合中插入文件,格式如下

{name:’zhang’,age:10,sex:’m’,hobby:[‘a’,’b’]}

age 範圍 4-15

hobby (愛好)

 範圍[draw  dance  sing  pingpang  basketball  football  running  computer]

  1. 查詢練習

檢視班級所有人資訊

    *db.class.find({},{_id:0})

檢視班級年齡8歲的同學的資訊

*db.class.find({age:8},{_id:0})

檢視年齡大於10歲的學生資訊

    * db.class.find({age:{$gte:10}},{_id:0})

檢視年齡在 8-11歲之間的學生資訊

    * db.class.find({age:{$in:[8,11]}},{_id:0})

檢視年齡為9歲且為男生的學生

    *db.class. find({age:9,sex:'m'})

找到年齡小於7歲或大於12歲的學生

    *db.class. find({$or:[{age:{$lt:7}},{age:{$gt:12}}]})

找到年齡為8歲或者11歲的學生

    *db.class. find({age:{$in:[8,11]}})

找到有兩項興趣愛好的學生

*db.class. find({hobby:{$size:2}}

找到興趣中有draw 的學生

    *db.class. find(hobby:'draw')

找到喜歡畫畫draw又喜歡跳舞的學生

    *db.class.  find(hobby:{$all:['draw','dance']})

統計興趣 有三項學生人數

    *db.class.  find({hobby:{$size:3}}).count()

找到本班年齡第二大的同學

    *db.class. find().sort({age:-1}).skip(1).limit(1)

檢視興趣的範圍

找到年齡最小的三個同學

    * db.class. find().sort({age:1}).limit(3)

  1. 刪除所有年齡大於12或者小於7歲的學生

    *db.class. remove({$or:[{age:{$lt:7}},{age:{$gt:12}}]})

文件的修改操作

Mysql修改

update table set … where …

Mongodb修改

db.collection.update(query,update,upsert,multi)

功能: 修改文件

引數:

1.query: 篩選需要修改的文件相當於where

            用法同查詢

      2.update:要修改什麼內容,相當set.

往往需要配合修改操作符

      3.upsert: bool 值 預設false

如果query 的文件不存在則不做操作

如果設定為true 則文件不存在根據query和update內容插入新文件

      4.multi: bool值 預設false 如果刪選到多條文件則只修改第一條

           設定為true 則表示修改所有篩選到的文件

e.g年齡修改為18

db.class0.update({name:'HanMei'},{$set:{age:18}})

e.g. 如果篩選內容不存在則插入

    db.class0.update({name:'Jame'},{$set:{age:18}},true)

e.g. 如果匹配到多條,則修改所有

db.class0.update({sex:'w'},{$set:{name:'小芳'}},false,true)

*************************************************************************

普通修改操作符

$set

修改一個域的值,或增加一個域(如果該域不存在則增加這個域)

例子:把年齡為18歲的姓名修改

> db.class.update({age:18},{$set:{name:'小薇'}})

$unset

刪除一個域

例子:後面為空表示刪除一個域

$rename

修改域的 名稱

例子:把sex這個域修改為gender

> db.class1.update({},{$rename:{sex:'gender'}},false,true)

$setOnInsert

如果updare 執行了插入文件操作,表示補充插入內容

例子:

db.class0.update({name:'Tom'},{$set:{age:17},$setOnInsert:{gender:'m',tel:'12345'}},true)

  1. 在update 引數中可以同時小寫多個修改器

$inc

加減修改器

例子:把所有人的年齡都加2

db.class2.update({},{$inc:{age:2}},false,true)

例子:將姓名為Tom的年齡減少0.7

> db.class2.update({name:"Tom"},{$inc:{age:-0.7}})

  1. $inc 值可以是正數負數正數小數

$mul

乘法修改器

例子:將姓名為Tom的年齡乘以2

> db.class2.update({name:"Tom"},{$mul:{age:2}})

  1. $mul值可以是正數負數整數小數

$max

指定了某個域值的下限,如果小指定值則修改為指定值

例子:將年齡不到20的修改為20

db.class0.update({},{$max:{age:20}},false,true)

$min

指定了某個域值的上限,如果大於指定值則修改為指定值

例子:年齡大於25的修改為25

db.class0.update({},{$min:{age:25}},false,true)

陣列修改器

$pust

向陣列中新增一項

例子:向姓名為小明的文件中新增成績陣列 5

db.class3.update({name:'小明'},{$push:{score:5}})

$pusAll

向陣列中新增多項

例子:向姓名為小紅的文件中新增成績陣列5 和10

db.class3.update({name:'小紅'},{$pushAll:{score:[5,10]}})

$pull

從陣列中刪除一項

例子:刪除姓名為小王的成績為5

> db.class3.update({name:"小王"},{$pull:{score:5}})

$pullAll

刪除陣列中多項

例子:刪除姓名為小王成績中有64和10

> db.class3.update({name:"小王"},{$pullAll:{score:[64,10]}})

$each

對多個值逐一操作

例子:插入姓名為小明,在成績中插入5和10

> db.class3.update({name:'小明'},{$push:{score:{$each:[5,10]}}})

$position

指定插入位置

例子:插入姓名為小紅,在成績的1號位插入10

db.class3.update({name:'小紅'},{$push:{score:{$each:[10],$position:1}}})

  1. 需要搭配$each 使用

$sort

對陣列進行排序

例子:對姓名為小紅,在成績中程序排序(升序,降序)

> db.class3.update({name:'小紅'},{$push:{score:{$each:[],$sort:1}}})

> db.class3.update({name:'小紅'},{$push:{score:{$each:[],$sort:-1}}})

  1. $each[] 中如果不加數字則對現有的進行排序,相反如果加了則對新增後的內容程序排序 !!和$each 一起使用

$pop

彈出一項

例子:對姓名為小紅,成績的第一項進行刪除

db.class3.update({name:'小紅'},{$pop:{score:-1}})

例子:對姓名為小紅,成績的最後一項進行刪除

db.class3.update({name:'小紅'},{$pop:{score:1}})

$addToSet

向陣列中新增一項,如果和已有的內容重複

例子:向姓名為小紅,在成績中新增87(如果已有則新增失敗)

> db.class3.update({name:'小紅'},{$addToSet:{score:87}})

時間型別

mogodb 中儲存時間格式

ISODate()

方法1:自動生成當前時間

new Date() 

例子:在class2域中 插入python入門,插入當前時間

(和北京時間相差8小時)

> db.class2.insert({title:'python入門',date:new Date()})

ISODate()

方法2:自動生成當前時間

例子:在class2域中 插入python精通,插入當前時間

(和北京時間相差8小時)

> db.class2.insert({title:'python精通',date:ISODate()})

Date()

方法3 將生成的當前時間變為字串儲存

例子:在class2域中 插入python入門,插入當前時間

(和北京時間相差8小時)

> db.class2.insert({title:'python瘋狂',date:Date()})

顯示:

{ "title" : "python瘋狂", "date" : "Mon Jul 23 2018 11:42:04 GMT+0800 (CST)" }

ISODate()

功能: 生成時間型別儲存

引數: 引數指定時間

       ‘2018-7-1 12:10:56’

       ‘20180701 12:10:56’

        ‘20180701’

例子:class2域中 插入python學習,插入指定時間

> db.class2.insert({title:'python學習',date:ISODate("2018-07-01 01:12:12")})

時間輟

valueOF()

將時間轉換為時間輟

例子:在class2域中 插入python放生,插入時間戳

> db.class2.insert({title:'python放生',date:ISODate().valueOf()})

顯示:從1970年0:0:0 到現在的時間

{ "title" : "python放生", "date" : 1532318023513 }

Null------------ > nll

如果某個域存在卻沒有值,可以設定為Null

例子:

> db.class2.insert({title:'python涅槃',price:null})

如果某個域不存在可以使用null匹配

例子:找到date域不存在的文件

> db.class2.find({date:null},{_id:0})

objiect  內部文件

意義

文件內某個域的值還是一個文件,咋這個文件為內部文件

  1. 需要使用內部文件某個域的時候,可以使用外部文件 . 的方法引用內部文件,但是注意此時需要加引號

陣列下標應用

例子:查詢book2文件中域為titlepythonWEB

> db.class4.find({'book2.title':'pythonWEB'},{_id:0})

例子:查詢修改bookl文件中域為price38.8’修改為‘48.8

> db.class4.update({