NoSQL從小白到碼神 Redis MongoDB 安裝特點應用場景教程 火推

qq1350048638發表於2018-02-22

NoSQL從小白到碼神

參考安裝教程包含圖片(更詳細): https://my.oschina.net/u/3680357/blog/1607009

本課程適用於運維、開發相關人員。

課程目錄:

  • NoSQL背景
  • NoSQL簡介
  • NoSQL和關係型資料庫對比

  • Redis簡介

  • Redis下載安裝配置(Linux環境)
  • Redis優點
  • Redis效能
  • Redis常見命令
  • Redis資料型別
  • Redis的功能
    • Redis釋出/訂閱
    • Redis事務支援
    • Redis主從複製(叢集)
    • Redis持久化
  • Java操作Redis示例
  • Redis總結

  • MongoDB簡介

  • MongoDB下載安裝(Linux)
  • MongoDB基本操作
    • 體系結構
    • 啟動、停止資料庫
    • 連線資料庫
    • 增刪改查操作
    • 高階查詢操作
    • 資料備份、恢復
    • 訪問控制
    • 索引
    • Replica Sets
    • 自動分片(Auto-Sharding)
  • MongoDB常見命令
  • MongoDB工具集
  • MongoDB叢集搭建
  • MongoDB安全驗證
  • MongoDB應用場景
  • Java操作MongoDB示例
  • MongoDB總結
    NoSQL篇

NoSQL背景

隨著網際網路Web網站的興起,傳統的關聯式資料庫在應付Web網站,特別是超大規模和高併發的社交網路型別的Web純動態網站已經顯得力不從心,暴露出了很多難以克服的問題。例如:關聯式資料庫為了降低資料冗餘,保證資料約束性,在資料查詢時不得不使用多個資料表之間的連線操作,這極大地降低了查詢效率,不能夠滿足當前Internet的高實時性的要求。而非關係型資料庫對併發的大規模訪問有著效率上的優勢,因此,非關聯式資料庫是在具體應用背景下得到了迅速的發展。

NoSQL簡介

NoSQL指的是非關係型的資料庫。其實,NoSQL概念最早出現在1998年,當時的含義是反SQL技術革命運動,但並未引起太多的關注。直到2009年,NoSQL概念被來自Rackspace的EricEvans再次提出,這時的NoSQL已經不是單純的反SQL運動,指的主要是非關係型的分散式資料庫,並且不支援原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、永續性(Durability)的資料庫設計模式。在亞特蘭大舉行的有關NoSQL的討論會上,學者給出了NoSQL較為普遍的解釋,即“非關係型的”。並且指出Key-Value儲存和文件資料庫是NoSQL的主要特點。

原子性:

多個事情組成一個單元,要麼同時成功或失敗,不能只執行其中一個

一致性:

事務處理要將資料庫從一種狀態轉變為另一種狀態。一旦提交了修改資料,那麼其它人讀取這個資料,也是被修改後的資料

隔離性:

在事務處理提交之前,事務處理的效果不能由系統中其它事務處理。多個使用者,不能同時讀寫同一個資料,應該有先後順序,在資料庫中是一個一 個事件地執行,如果事件的條件不滿足,後續事件就回滾

永續性:

事件一旦提交成功,資料就發生了變化

例如:

網上定p系統,扣錢和定p是一個事務,它需要有原子性即不能只執行扣錢不執行定p。符合原子性。

這張p被多人同時在網上定,就會有先來的才定上這個p,後來定p的動作,如果發現p已賣出,(p的狀態改變了,其它人通過網站訪問這個資料,就會發現p已賣出符合一致性),就會回滾到不扣錢,p訂不上的狀態。符合隔離性。

p被定了,在資料庫裡設定標誌位,它就一直顯示為賣出狀態。符合永續性
NoSQL特點

1:key-value儲存

2:最終一致性

3:可擴充
NoSQL和關係型資料庫對比

關係型資料庫

優勢:
1.擅長小資料量的處理
2.擅長複雜的SQL操作,可以進行Join等複雜查詢
3.可以方便的生成各種資料物件,利用儲存的資料建立窗體和報表,可視性好

劣勢:
1.很難進行分散式應用和大量資料的寫入處理
2.為有資料更新的表做索引和結構變更
3.欄位不固定的應用
4.對簡單查詢需要快速返回結果的處理
NoSQL資料庫

優勢:
1.擅長大量資料的寫入和讀取
2.快速的查詢響應,靈活的資料模型
3.資料結構變更或更新非常方便,不需要更改已有資料的資料結構
4.擊碎了效能瓶頸,可以使執行速度變的更快

劣勢:
1.不提供複雜的API介面
2.一般僅提供key索引
3.不適合小資料的處理
4.現有產品的不夠成熟,大多數產品都還處於初創期
NoSQL 資料庫分類

Redis篇

Redis簡介

Redis(REmote DIctionary Server)是一個開源的使用ANSI C語言編寫、是一個由Salvatore Sanfilippo寫的key-value儲存系統,支援網路、可基於記憶體亦可持久化的日誌型、並提供多種語言的API。

Redis是一個key-value儲存系統。和Memcached類似,它支援儲存的value型別相對更多,包括string(字串)、list(連結串列)、set(集合)、zset(sorted set –有序集合)和hash(雜湊型別)。與memcached一樣,為了保證效率,資料都是快取在記憶體中。區別的是redis會週期性的把更新的資料寫入磁碟或者把修改操作寫入追加的記錄檔案,並且在此基礎上實現了master-slave(主從)同步。

參考地址:http://www.runoob.com/redis/redis-conf.html

Redis下載安裝配置(Linux環境)

下載:

官網:https://redis.io/
下載步驟:

安裝(Linux版本下CentOS Linux release 7.3.1611 (Core))

線上安裝:

1:檢視系統版本:

cat /etc/redhat-release

2:進入到opt目錄下、建立redis資料夾:

cd /opt/
mkdir redis

3:進入/opt/redis/目錄下,下載redis

wget http://download.redis.io/releases/redis-4.0.6.tar.gz

4:解壓redis-4.0.6.tar.gz

tar -zvxf redis-4.0.6.tar.gz

5:在安裝之前需要預裝gcc、tcl

沒有安裝的小夥伴,需要安裝,如果已經存在,則略過此步驟

檢視安裝gcc資訊:
gcc -v
安裝命令:
mount /dev/cdrom /mnt
yum install gcc tcl -y
6:執行redis安裝

make
或者 make MALLOC=libc

7:切換到目錄/usr下新建目錄/usr/lksoft/redis

cd /usr
mkdir lksoft
cd lksoft
mkdir redis

8:重新設定PREFIX

make PREFIX=/usr/lksoft/redis/ install

9:檢視當前系統中埠使用情況

ss -tanl

10:將redis設定成服務(配置環境變數)

cd ./opt/redis/redis-4.0.6/src
cp redis-sentinel /usr/lksoft/redis/bin/

11:設定環境變數bash_profile

vim ~/.bash_profile

修改內容部分:

export REDIS_HOME=/usr/lksoft/redis
export PATH=PATH:

PATH:
REDIS_HOME/bin

使檔案生效
source ~/.bash_profile
12:任何地方,都可以啟動redis了

為了更說明,切換到根目錄下
cd /
可以自動補全redis-server了
13:將redis啟動程式做成服務

切換到之前的redis目錄:
cd /opt/redis/redis-4.0.6/utils

./install_server.sh

提示是否使用預設的6379埠,點選回車即可,使用預設
Please select the redis port for this instance: [6379]

是否將redis的服務配置檔案,放到[/etc/redis/6379.conf]下面,直接回車即可:
Please select the redis config file name [/etc/redis/6379.conf]

是否將redis服務的日誌檔案,放到[/var/log/redis_6379.log]下面,直接回車即可:
Please select the redis log file name [/var/log/redis_6379.log]

是否將redis的資料,存放到[/var/lib/redis/6379]下面,直接回車即可:
Please select the data directory for this instance [/var/lib/redis/6379]

是否預設redis可執行的檔案路徑為[/usr/lksoft/redis/bin/redis-server],直接回車即可
Please select the redis executable path [/usr/lksoft/redis/bin/redis-server]

然後顯示的是設定的檔案資訊,直接回車即可。

發現:Copied /tmp/6379.conf => /etc/init.d/redis_6379

14:修改啟動的名稱

cd /etc/init.d/
mv redis_6379 redisd

15:啟動redis

service redisd start
發現已經啟動
需要停止服務:
service redisd stop
重新啟動
service redisd start
檢視目前系統使用埠情況:
ss -tanl

16:測試連線redis

切換到根目錄
cd /

檢視客戶端連線幫助
redis-cli –help

連線0號庫
redis-cli

Redis優點

效能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
豐富的資料型別 – Redis支援二進位制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 資料型別操作。
原子 – Redis的所有操作都是原子性的,意思就是要麼成功執行要麼失敗完全不執行。單個操作是原子性的。多個操作也支援事務,即原子性,通過MULTI和EXEC指令包起來。
豐富的特性 – Redis還支援 publish/subscribe, 通知, key 過期等等特性。
Redis支援資料的持久化,可以將記憶體中的資料儲存在磁碟中,重啟的時候可以再次載入進行使用。
Redis支援資料的備份,即master-slave模式的資料備份。
Redis效能

在50個併發的情況下請求10W次,寫的速度是11W次/s,讀的速度是8.1w次/s
Redis常見命令

官網參考命令地址:https://redis.io/commands

菜鳥教程命令地址:http://www.runoob.com/redis

對value操作的命令

exists(key):確認一個key是否存在
del(key):刪除一個key
type(key):返回值的型別
keys(pattern):返回滿足給定pattern的所有key
randomkey:隨機返回key空間的一個
keyrename(oldname, newname):重新命名key
dbsize:返回當前資料庫中key的數目
expire:設定一個key的活動時間(s)
ttl:獲得一個key的活動時間
select(index):按索引查詢
move(key, dbindex):移動當前資料庫中的key到dbindex資料庫
flushdb:刪除當前選擇資料庫中的所有key
flushall:刪除所有資料庫中的所有key
對string操作的命令

set(key, value):給資料庫中名稱為key的string賦予值value
get(key):返回資料庫中名稱為key的string的value
getset(key, value):給名稱為key的string賦予上一次的value
mget(key1, key2,…, key N):返回庫中多個string的value
setnx(key, value):新增string,名稱為key,值為value
setex(key, time, value):向庫中新增string,設定過期時間time
mset(key N, value N):批量設定多個string的值
msetnx(key N, value N):如果所有名稱為key i的string都不存在
incr(key):名稱為key的string增1操作
incrby(key, integer):名稱為key的string增加integer
decr(key):名稱為key的string減1操作
decrby(key, integer):名稱為key的string減少integer
append(key, value):名稱為key的string的值附加value
substr(key, start, end):返回名稱為key的string的value的子串
對List 操作的命令

rpush(key, value):在名稱為key的list尾新增一個值為value的元素
lpush(key, value):在名稱為key的list頭新增一個值為value的 元素
llen(key):返回名稱為key的list的長度
lrange(key, start, end):返回名稱為key的list中start至end之間的元素
ltrim(key, start, end):擷取名稱為key的list
lindex(key, index):返回名稱為key的list中index位置的元素
lset(key, index, value):給名稱為key的list中index位置的元素賦值
lrem(key, count, value):刪除count個key的list中值為value的元素
lpop(key):返回並刪除名稱為key的list中的首元素
rpop(key):返回並刪除名稱為key的list中的尾元素
blpop(key1, key2,… key N, timeout):lpop命令的block版本。
brpop(key1, key2,… key N, timeout):rpop的block版本。
rpoplpush(srckey, dstkey):返回並刪除名稱為srckey的list的尾元素,並將該元素新增到名稱為dstkey的list的頭部
對Set操作的命令

sadd(key, member):向名稱為key的set中新增元素member
srem(key, member) :刪除名稱為key的set中的元素member
spop(key) :隨機返回並刪除名稱為key的set中一個元素
smove(srckey, dstkey, member) :移到集合元素
scard(key) :返回名稱為key的set的基數
sismember(key, member) :member是否是名稱為key的set的元素
sinter(key1, key2,…key N) :求交集
sinterstore(dstkey, (keys)) :求交集並將交集儲存到dstkey的集合
sunion(key1, (keys)) :求並集
sunionstore(dstkey, (keys)) :求並集並將並集儲存到dstkey的集合
sdiff(key1, (keys)) :求差集
sdiffstore(dstkey, (keys)) :求差集並將差集儲存到dstkey的集合
smembers(key) :返回名稱為key的set的所有元素
srandmember(key) :隨機返回名稱為key的set的一個元素
對Hash操作的命令

hset(key, field, value):向名稱為key的hash中新增元素field
hget(key, field):返回名稱為key的hash中field對應的value
hmget(key, (fields)):返回名稱為key的hash中field i對應的value
hmset(key, (fields)):向名稱為key的hash中新增元素field
hincrby(key, field, integer):將名稱為key的hash中field的value增加integer
hexists(key, field):名稱為key的hash中是否存在鍵為field的域
hdel(key, field):刪除名稱為key的hash中鍵為field的域
hlen(key):返回名稱為key的hash中元素個數
hkeys(key):返回名稱為key的hash中所有鍵
hvals(key):返回名稱為key的hash中所有鍵對應的value
hgetall(key):返回名稱為key的hash中所有的鍵(field)及其對應的value
Redis資料型別

string(字串)

string是redis最基本的型別,而且string型別是二進位制安全的。意思是redis的string可以包含任何資料。比如jpg圖片或者序列化的物件
從內部實現來看其實string可以看作byte陣列,最大上限是1G位元組
string型別的值也可視為integer,從而可以讓“incr”命令族操作,這種情況下,該integer的值限制在64位有符號數
在list、set和zset中包含的獨立的元素型別都是string型別
應用場景:String是最常用的一種資料型別,普通的key/value儲存.

list(雙向連結串列)

redis的list型別其實就是一個每個子元素都是string型別的雙向連結串列,所以[lr]push和[lr]pop命令的演算法時間複雜度都是O(1),另外list會記錄連結串列的長度,所以llen操作也是O(1).
可以通過push,pop操作從連結串列的頭部或者尾部新增刪除元素。這使得list既可以用作棧,也可以用作佇列
list的最大長度是2^32-1個元素
應用場景:Redis list應用場景非常多,也是Redis最重要的資料結構之一,比如twitter的關注列表,粉絲列表等都可以用Redis的list結構來實現.

set(無序集合)

set就是redis string的無序集合,不允許有重複元素
set的最大元素數是2^32-1
對set的操作還有交集、並集、差集等
應用場景:Set對外提供的功能與list類似,當你需要儲存一個列表資料,又不希望出現重複資料時,set 是一個很好的選擇,並且set提供了判斷某個成員是否在一個set集合內的介面,這個也是list所不能提供的

Sorted set(有序集合)– zset

zset是set的一個升級版本,在set的基礎上增加了一個順序屬性,這一屬性在新增修改元素時可以指定,每次指定後zset會自動安裝指定值重新調整順序。可以理解為一張表,一列存value,一列存順序。操作中的key理解為zset的名字。
zset的最大元素數是2^32-1。
對於已經有序的zset,仍然可以使用sort命令,通過指定asc|desc引數對其進行排序。
應用場景:Sorted set的使用場景與set類似,區別是set不是自動有序的,而sorted set可以通過使用者額外提供一個優先順序(score)的引數來為成員排序,並且是插入有序的,即自動排序.當你需要一個有序的並且不重複的集合列表,那麼可以選擇sorted set資料結構

hash(hash表)

redis Hash型別對資料域和值提供了對映,這一結構很方便表示物件
在Hash中可以只儲存有限的幾個“域”,而不是將所有的“域”作為key,這可以節省記憶體
應用場景:比如,我們儲存供應商酒店價格的時候可以採取此結構,用酒店編碼作為Key, 價格資訊作為Value

Redis的功能

Redis釋出/訂閱

Redis的釋出/訂閱(Publish/Subscribe)功能類似於傳統的訊息路由功能,釋出者釋出訊息,訂閱者接收訊息,溝通釋出者和訂閱者之間的橋樑是訂閱的Channel或者Pattern.訂閱者和釋出者之間的關係是鬆耦合的,釋出者不指定哪個訂閱者才能接收訊息,訂閱者不只接收特定釋出者的訊息.

Redis事務支援

Redis目前對事務支援還比較簡單,也即支援一些簡單的組合型的命令,只能保證一個client發起的事務中的命令可以連續的執行,而中間不會插入其他client的命令. 由於Redis是單執行緒來處理所有client的請求的所以做到這點是很容易的.事務的執行過程中,如果redis意外的掛了,這時候事務可能只被執行了一半,可以用redis-check-aof 工具進行修復

Redis主從複製(叢集)

Master/Slave配置:

Master IP:175.41.209.118

Master Redis Server Port:6379

Slave配置很簡單,只需要在slave伺服器的redis.conf加入:

slaveof 175.41.209.118 6379

啟動master和slave,然後寫入資料到master,讀取slave,可以看到資料被複制到slave了.

用途:讀寫分離,資料備份,災難恢復等
Redis主從複製過程:

配置好slave後,slave與master建立連線,然後傳送sync命令.

無論是第一次連線還是重新連線,master都會啟動一個後臺程式,將資料庫快照儲存到檔案中,同時master主程式會開始收集新的寫命令並快取.

後臺程式完成寫檔案後,master就傳送檔案給slave,slave將檔案儲存到硬碟上,再載入到記憶體中。

接著master就會把快取的命令轉發給slave,後續master將收到的寫命令傳送給slave.

如果master同時收到多個slave發來的同步連線命令,master只會啟動一個程式來寫資料庫映象, 然後傳送給所有的slave
Redis主從複製特點:

  1. master可以擁有多個slave.
  2. 多個slave可以連線同一個master外,還可以連線到其他slave.
  3. 主從複製不會阻塞master,在同步資料時,master可以繼續處理client請求.
  4. 可以在master禁用資料持久化,註釋掉master配置檔案中的所有save配置,只需在slave上配置資料持久化.
  5. 提高系統的伸縮性
    Redis主從複製速度:

官方提供了一個資料, 㻿lave在21秒即完成了對Amazon網站 10G key set的複製.
Redis持久化

由於Redis是記憶體資料庫,它將自己的資料庫狀態儲存在記憶體裡面,所以如果不想辦法將儲存在記憶體中的資料庫狀態儲存到磁碟裡面,那麼一旦伺服器退出,伺服器中的資料庫狀態也會消失不見。為了解決這個問題,Redis提供了RDB、AOF持久化方式,將記憶體中的資料儲存到磁碟中,避免資料意外丟失

(1)RDB是 Snapshotting(快照)也是預設方式: 快照是預設的持久化方式。這種方式將記憶體中資料以快照的方式寫入到二進位制檔案中,預設的檔名為dump.rdb。可以配置自動做快照持久 化的方式。我們可以配置redis在n秒內如果超過m個key被修改就自動做快照

RDB持久化通過將伺服器某個時間點上的資料庫狀態(非空資料庫以及相關鍵值對)儲存到一個RDB檔案中,Redis伺服器可以用它來還原資料庫狀態。 SAVE命令會阻塞Redis伺服器程式。而BGSAVE會派生出一個子程式,然後由子程式負責建立RDB檔案,伺服器父程式繼續處理命令請求。還可以SAVE命令設定自動間隔儲存, 例如SAVE 60 10000 伺服器在60秒之內,對資料庫進行了至少10000次修改,自動執行BGSAVE命令。RDB檔案是一個經過壓縮的二進位制檔案。

(2)AOF(Append-only file): AOF持久化通過儲存Redis伺服器所執行的寫命令來記錄資料庫狀態的。被寫入AOF檔案的所有命令都是以Redis的命令請求協議格式儲存的,Redis的命令請求協議儲存為純文字格式。AOF持久化功能的實現分為命令追加、檔案寫入、檔案同步三個步驟:當AOF持久化處於開啟狀態時,伺服器在執行完一個寫命令後,會以協議格式將被執行的寫命令(如SET、SADD、RPUSH)追加到伺服器狀態的aofbuf緩衝區的末尾。伺服器在每次結束一個事件迴圈之前,它都會呼叫flushAppendOnlyFile函式,考慮是否需要將aof_buf緩衝區中的內容寫入和儲存到AOF檔案裡面。flushAppendOnlyFile函式的行為由伺服器配置的appendfsync選項的值( always 、 everysec(預設) 、 no )來決定

RDB與AOF比較

RDB
優點:RDB 是一個非常緊湊的檔案,它儲存了 Redis 在某個時間點上的資料集。這種檔案非常適合用於進行備份。

缺點:如果你需要儘量避免在伺服器故障時丟失資料,那麼 RDB 不適合你。 雖然 Redis 允許你設定不同的儲存點(save point)來控制儲存 RDB 檔案的頻率, 但是, 因為RDB 檔案需要儲存整個資料集的狀態,所以它並不是一個輕鬆的操作。因此你可能會至少 5 分鐘才儲存一次 RDB 檔案。 在這種情況下, 一旦發生故障停機, 你就可能會丟失好幾分鐘的資料。

AOF
優點:使用 AOF 持久化會讓 Redis 變得非常耐久:你可以設定不同的 fsync 策略,比如無 fsync ,每秒鐘一次 fsync ,或者每次執行寫入命令時 fsync 。 AOF 的預設策略為每秒鐘 fsync 一次,在這種配置下,Redis 仍然可以保持良好的效能,並且就算髮生故障停機,也最多隻會丟失一秒鐘的資料( fsync 會在後臺執行緒執行,所以主執行緒可以繼續努力地處理命令請求)。

缺點:對於相同的資料集來說,AOF 檔案的體積通常要大於 RDB 檔案的體積。根據所使用的 fsync 策略,AOF 的速度可能會慢於 RDB 。

Java操作Redis示例

所需jar包:



redis.clients
jedis
2.9.0

java操作:

import java.util.Iterator;
import java.util.List;
import java.util.Set;

import redis.clients.jedis.Jedis;

public class RedisTest {

public static void main(String[] args) {
    Jedis jd = new Jedis("39.106.131.203");
    System.out.println("連線redis成功");
//  System.out.println("服務正在執行" + jd.ping());

    /**
     * 操作string型別
     */

//  jd.set("key2", "java1212");
//  System.out.println("redis中儲存的值為:"+jd.get("key2"));

    /**
     * 操作list型別
     */

//  jd.lpush("list", "listvalue1");
//  jd.lpush("list", "listvalue2");
//  jd.lpush("list", "listvalue3");
//      
//  List<String> list = jd.lrange("list", 0, 2);
//  for (int i = 0; i < list.size(); i++) {
//      System.out.println("list的結果是:" + list.get(i));
//  }

    /**
     * 操作set型別
     */

    jd.sadd("setKey1", "setvalue1");
    jd.sadd("setKey1", "setvalue2");
    jd.sadd("setKey1", "setvalue3");
    Set<String> keys = jd.keys("*");
//  Set<String> keys = jd.smembers("setKey1");
    Iterator<String> it = keys.iterator();
    while(it.hasNext()){
        String key = it.next();
        System.out.println(key);
    }
}

}
Redis總結

Redis使用最佳方式是全部資料in-memory。
Redis更多場景是作為Memcached的替代者來使用。
當需要除key/value之外的更多資料型別支援時,使用Redis更合適。
當儲存的資料不能被剔除時,使用Redis更合適。(持久化)
MongoDB篇

MongoDB簡介

MongoDB是一個跨平臺,面向文件的資料庫,提供高效能,高可用性和易於擴充套件。MongoDB是工作在集合和文件上一種概念
MongoDB 是一個基於分散式檔案儲存的資料庫。由C++語言編寫。旨在為WEB應用提供可擴充套件的高效能資料儲存解決方案
MongoDB 是一個介於關聯式資料庫和非關聯式資料庫之間的產品,是非關聯式資料庫當中功能最豐富,最像關聯式資料庫的。他支援的資料結構非常鬆散,是類似json的bson格式,因此可以儲存比較複雜的資料型別。Mongo最大的特點是他支援的查詢語言非常強大,其語法有點類似於物件導向的查詢語言,幾乎可以實現類似關聯式資料庫單表查詢的絕大部分功能,而且還支援對資料建立索引
MongoDB特點

面向集合儲存,易於儲存物件型別的資料
模式自由
支援動態查詢
支援完全索引,包含內部物件
支援查詢
支援複製和故障恢復
使用高效的二進位制資料儲存,包括大型物件(如視訊等)
自動處理碎片,以支援雲端計算層次的擴充套件性
支援 Python,PHP,Ruby,Java,C,C#,Javascript,Perl 及 C++語言的驅動程式
檔案儲存格式為 BSON(一種 JSON 的擴充套件),文件型
可通過網路訪問
面向集合(Collenction-Orented)

意思是資料被分組儲存在資料集中,被稱為一個集合(Collenction)。每個集合在資料庫中都有一個唯一的標識名,並且可以包含無限數目的文件。集合的概念類似關係型資料庫(RDBMS)裡的表(table),不同的是它不需要定義任何模式(schema)
模式自由(schema-free)

意味著對於儲存在 MongoDB 資料庫中的檔案,我們不需要知道它的任何結構定義。提了這麼多次”無模式”或”模式自由”,它到是個什麼概念呢? 例如,下面兩個記錄可以存在於同一個集合裡面:

{“welcome” : “Beijing”}

{“age” : 25}

文件型:

意思是我們儲存的資料是鍵-值對的集合,鍵是字串,值可以是資料型別集合裡的任意型別,包括陣列和文件. 我們把這個資料格式稱作 “BSON” 即 “Binary Serialized dOcument Notation.”
MongoDB應用場景

適合場景:

1.網站資料,實時的插入,更新與查詢。
2.由於效能很高,可做持久化快取層。
3.儲存大尺寸,低價值的資料。
4.高伸縮性的叢集場景。
5.BSON格式非常適合文件化資料的儲存及查詢。
不適合場景:

1.高度事務性的系統,例如銀行或會計系統。
2.傳統的商業智慧應用,針對特定問題的BI資料庫會對產生高度優化的查詢方式。對於此類應用,資料倉儲可能是更合適的選擇。
MongoDB下載安裝(Linux)

教程系統版本:(Linux版本下CentOS Linux release 7.3.1611 (Core))

下載:

1:線上下載

wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.2.9.tgz

2:官網下載

https://www.mongodb.com/download-center?ct=atlasheader#atlas

安裝(線上安裝):

1:進入/opt目錄下

cd /opt

2:建立資料夾

mkdir mongodb

3:進入mongodb目錄下,線上下載mongodb資源安裝包

cd mongodb/
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.2.9.tgz

4:解壓mongodb資源包到當前路徑下

tar -zvxf mongodb-linux-x86_64-3.2.9.tgz

5:進入目錄/usr/local/下,並建立資料夾mongodb

cd /usr/local
mkdir mongodb

6:將mongodb-linux-x86_64-3.2.9資料夾內的內容 移動到 /usr/local/mongodb下

mv /opt/mongodb/mongodb-linux-x86_64-3.2.9/* /usr/local/mongodb

7:在mongodb目錄下,新建1個資料夾和1個檔案

mkdir data
touch logs

8:在系統執行檔案~/.bash_profile中新增mongodb的執行命令

vim ~/.bash_profile
內容為:
PATH=PATH:

PATH:
HOME/bin:/usr/local/mongodb/bin

source ~/.bash_profie

Mongodb啟動方式

mongodb有三種啟動方式:

啟動1:進入/bin目錄下,輸入mongod –dbpath=/usr/local/mongodb/data –fork –logpath=/usr/local/mongodb/logs

啟動之後,輸入mongo就可以進入mongodb客戶端連線
然後輸入show dbs;如果顯示資料庫,則啟動搭建成功

啟動2:配置啟動檔案啟動mongodb.conf(推薦)

mongodb.conf內容:

logpath=/usr/local/mongodb/logs
logappend = true 
#fork and run in background
fork = true
#port = 27017
dbpath=/usr/local/mongodb/data
#location of pidfile
pidfilepath=/usr/local/mongodb/mongod.pid 

之前開啟資料庫了,所以先關庫:
可以使用db.shutdownServer()命令,或者ps -ef|grep mongod檢視程式號,使用kill -9 程式號即可

啟動3:配置service服務啟動(推薦)
MongoDB基本操作

體系結構
MongoDB 是一個可移植的資料庫,它在流行的每一個平臺上都可以使用,即所謂的跨平臺 特性。在不同的作業系統上雖然略有差別,但是從整體構架上來看,MongoDB 在不同的平 臺上是一樣的,如資料邏輯結構和資料的儲存等等。

一個執行著的 MongoDB 資料庫就可以看成是一個 MongoDB Server,該 Server 由例項和資料庫組成,在一般的情況下一個 MongoDB Server 機器上包含一個例項和多個與之對應的資料庫,但是在特殊情況下,如硬體投入成本有限或特殊的應用需求,也允許一個 Server 機器上可以有多個例項和多個資料庫。

MongoDB 中一系列物理檔案(資料檔案,日誌檔案等)的集合或與之對應的邏輯結構(集 合,文件等)被稱為資料庫,簡單的說,就是資料庫是由一系列與磁碟有關係的物理檔案的 組成。

  • 資料邏輯結構
    MongoDB 的邏輯結構是一種層次結構。主要由:文件(document)、集合(collection)、資料庫(database)這三部分組成的。邏輯結構是面向使用者的,使用者使用 MongoDB 開發應用程式使用的就是邏輯結構。
    1: MongoDB 的文件(document),相當於關聯式資料庫中的一行記錄
    2:多個文件組成一個集合(collection),相當於關聯式資料庫的表
    3:多個集合(collection),邏輯上組織在一起,就是資料庫(database)
    4:一個 MongoDB 例項支援多個資料庫(database)
  • 資料儲存結構
    MongoDB 的預設資料目錄是/data/db,它負責儲存所有的 MongoDB 的資料檔案。在 MongoDB內部,每個資料庫都包含一個.ns 檔案和一些資料檔案,而且這些資料檔案會隨著資料量的增加而變得越來越多
    對比:

啟動、停止資料庫

參考上面啟動方式
連線資料庫

參考上面連線命令

mongod引數說明

mongod 的主要引數有:
dbpath:
資料檔案存放路徑,每個資料庫會在其中建立一個子目錄,用於防止同一個例項多次執行的 mongod.lock 也儲存在此目錄中。
logpath
錯誤日誌檔案
logappend
錯誤日誌採用追加模式(預設是覆寫模式)
bind_ip
對外服務的繫結 ip,一般設定為空,及繫結在本機所有可用 ip 上,如有需要可以單獨指定
port
對外服務埠。Web 管理埠在這個 port 的基礎上+1000
fork
以後臺 Daemon 形式執行服務
journal
開啟日誌功能,通過儲存操作日誌來降低單機故障的恢復時間,在 1.8 版本後正式加入,取代在 1.7.5 版本中的 dur 引數。
syncdelay
系統同步重新整理磁碟的時間,單位為秒,預設是 60 秒。
directoryperdb
每個 db 存放在單獨的目錄中,建議設定該引數。與 MySQL 的獨立表空間類似maxConns最大連線數
repairpath
執行 repair 時的臨時目錄。在如果沒有開啟 journal,異常 down 機後重啟,必須執行 repair
操作
常見命令

show dbs:顯示資料庫列表
show collections:顯示當前資料庫中的集合(類似關聯式資料庫中的表)
show users:顯示使用者
use :切換當前資料庫,這和MS-SQL裡面的意思一樣
db.help():顯示資料庫操作命令,裡面有很多的命令
db.foo.help():顯示集合操作命令,同樣有很多的命令,foo指的是當前資料庫下,一個叫foo的集合,並非真正意義上的命令
db.foo.find():對於當前資料庫中的foo集合進行資料查詢(由於沒有條件,會列出所有資料)
db.foo.find( { a : 1 } ):對於當前資料庫中的foo集合進行查詢,條件是資料中有一個屬性叫a,且a的值為1
MongoDB沒有建立資料庫的命令,但有類似的命令。
修復當前資料庫 db.repairDatabase();
檢視當前使用的資料庫
db.getName();
db; db和getName方法是一樣的效果,都可以查詢當前使用的資料庫
顯示當前db狀態 db.stats();
當前db版本 db.version();
檢視當前db的連結機器地址 db.getMongo();
基本操作

新增文件:

db.users.insert({
“_id”:ObjectId(“52c3c518498a9646a48133a2”),
“name”:“likang”,
“email”:“likang@qq.com”
});
db.users.save({
“_id”:ObjectId(“52c3c518498a9646a48133a2”),
“name”:“likang2”,
“email”:“likang2@qq.com”
});

insert 當_id存在時報錯
save 當_id存在時覆蓋更新
刪除文件:

//刪除全部
db.user.remove();
//刪除指定記錄
db.user.remove({“name”:“likang”});

//刪除user集合
db.user.drop();
更新文件:

原⽂檔:
{ 
    “_id”:ObjectId("52c3c518498a9646a48133a2"),
    “name”:“likang”, 
    “email”:“likang@qq.com”
} 
!
修改後的⽂檔:
{ 
    “_id”:ObjectId("52c3c518498a9646a48133a2"),
    “name”:“likang”, 
    “email”:[
        “likang@qq.com”, 
        “likang2@qq.com” 
    ] 
}

var doc = db.users.findOne({"name" : “likang”});
doc.email =[ 
    “likang@qq.com”, 
    “likang2@qq.com” 
]; 
db.users.update({ "name" : "likang" }, doc);

// 更新:指定第三個引數為true可以開啟upsert模式
//根據條件查詢不到資料則建立⼀條新的
db.users.update({ "name" : "likang" }, doc, true);

查詢文件:

常用工具集

MongoDB 在 bin 目錄下提供了一系列有用的工具,這些工具提供了 MongoDB 在運維管理上的方便。

bsondump: 將 bson 格式的檔案轉儲為 json 格式的資料
mongo: 客戶端命令列工具,其實也是一個 js 直譯器,支援 js 語法
mongod: 資料庫服務端,每個例項啟動一個程式,可以 fork 為後臺執行
mongodump/ mongorestore: 資料庫備份和恢復工具
mongoexport/ mongoimport: 資料匯出和匯入工具
mongofiles: GridFS 管理工具,可實現二制檔案的存取 -mongos: 分片路由,如果使用了 sharding 功能,則應用程式連線的是 mongos 而不是 mongod
mongosniff: 這一工具的作用類似於 tcpdump,不同的是他只監控 MongoDB 相關的包請求,並且是以指定的可讀性的形式輸出
mongostat: 實時效能監控工具
Java操作MongoDB示例

新建maven project工程

配置所需jar包


org.mongodb
mongo-java-driver
3.3.0

增加連線mongodb的工具類

/**
* mongodb工具類
* @author likang
* @date 2017-4-23 下午8:19:53
*/
public class MongoDbUtil {

private static MongoCollection<Document> collection;

/**
 * 連結資料庫
 * 
 * @param databaseName 資料庫名稱
 * @param collectionName 集合名稱
 * @param hostName 主機名
 * @param port  埠號
 */
public static void connect(String databaseName, String collectionName,String hostName, int port) {
    @SuppressWarnings("resource")
    MongoClient client = new MongoClient(hostName, port);
    MongoDatabase db = client.getDatabase(databaseName);
    collection = db.getCollection(collectionName);
    System.out.println(collection);
}

/**
 * 插入一個文件
 * 
 * @param document  文件
 */
public static void insert(Document document) {
    collection.insertOne(document);
}

/**
 * 查詢所有文件
 * 
 * @return 所有文件集合
 */
public static List<Document> findAll() {
    List<Document> results = new ArrayList<Document>();
    FindIterable<Document> iterables = collection.find();
    MongoCursor<Document> cursor = iterables.iterator();
    while (cursor.hasNext()) {
        results.add(cursor.next());
    }
    return results;
}

/**
 * 根據條件查詢
 * 
 * @param filter
 *            查詢條件 //注意Bson的幾個實現類,BasicDBObject, BsonDocument,
 *            BsonDocumentWrapper, CommandResult, Document, RawBsonDocument
 * @return 返回集合列表
 */
public static List<Document> findBy(Bson filter) {
    List<Document> results = new ArrayList<Document>();
    FindIterable<Document> iterables = collection.find(filter);
    MongoCursor<Document> cursor = iterables.iterator();
    while (cursor.hasNext()) {
        results.add(cursor.next());
    }
    return results;
}

/**
 * 更新查詢到的第一個
 * @param filter  查詢條件
 * @param update  更新文件
 * @return 更新結果
 */
public static UpdateResult updateOne(Bson filter, Bson update) {
    UpdateResult result = collection.updateOne(filter, update);
    return result;
}

/**
 * 更新查詢到的所有的文件
 * 
 * @param filter 查詢條件
 * @param update 更新文件
 * @return 更新結果
 */
public static UpdateResult updateMany(Bson filter, Bson update) {
    UpdateResult result = collection.updateMany(filter, update);
    return result;
}

/**
 * 更新一個文件, 結果是replacement是新文件,老文件完全被替換
 * 
 * @param filter 查詢條件
 * @param replacement  跟新文件
 */
public static void replace(Bson filter, Document replacement) {
    collection.replaceOne(filter, replacement);
}

/**
 * 根據條件刪除一個文件
 * @param filter  查詢條件
 */
public static void deleteOne(Bson filter) {
    collection.deleteOne(filter);
}

/**
 * 根據條件刪除多個文件
 * @param filter 查詢條件
 */
public static void deleteMany(Bson filter) {
    collection.deleteMany(filter);
}

}
編寫mongodb操作測試類

public class MongoTest {

public static void main(String[] args) {
    MongoDbUtil.connect("test", "jihe1", "*.*.*.*", 27017);

// testInsert();
// testFindAll();
// Mongo mg = new Mongo(“39.106.131.203”,27017);
// DB db = mg.getDB(“jihe1”);
// for(String s:db.getCollectionNames()){
// System.out.println(“內容如下:”);
// System.out.println(s);
// }
//
}

public static void testInsert() {
    Document document = new Document();
    document.append("name", "likang").append("phone", "18912341234");
    MongoDbUtil.insert(document);
}

public static void testFindAll() {
    List<Document> results = MongoDbUtil.findAll();
    for (Document doc : results) {
        System.out.println(doc.toJson());
    }
}

public static void testFindBy() {
    Document filter = new Document();
    filter.append("name", "li si");
    List<Document> results = MongoDbUtil.findBy(filter);
    for (Document doc : results) {
        System.out.println(doc.toJson());
    }
}

public static void testUpdateOne() {
    Document filter = new Document();
    filter.append("phone", "18912341235");
    // 注意update文件裡要包含"$set"欄位
    Document update = new Document();
    update.append("$set", new Document("phone", "123123123"));
    UpdateResult result = MongoDbUtil.updateOne(filter, update);
    System.out.println("matched count = " + result.getMatchedCount());
}

public static void testUpdateMany() {
    Document filter = new Document();
    filter.append("phone", "18912341235");
    // 注意update文件裡要包含"$set"欄位
    Document update = new Document();
    update.append("$set", new Document("phone", "123123123"));
    UpdateResult result = MongoDbUtil.updateMany(filter, update);
    System.out.println("matched count = " + result.getMatchedCount());
}

public static void testReplace() {
    Document filter = new Document();
    filter.append("name", "likang");
    // 注意:更新文件時,不需要使用"$set"
    Document replacement = new Document();
    replacement.append("value", 123);
    MongoDbUtil.replace(filter, replacement);
}

public static void testDeleteOne() {
    Document filter = new Document();
    filter.append("name", "wang");
    MongoDbUtil.deleteOne(filter);
}

public static void testDeleteMany() {
    Document filter = new Document();
    filter.append("phone", "18778907890");
    MongoDbUtil.deleteMany(filter);
}

}
MongoDB總結

Mongodb主要解決的是海量資料的訪問效率問題,根據官方的文件,當資料量達到50GB以上的時候,Mongo的資料庫訪問速度是MySQL的10倍以上。Mongo的併發讀寫效率不是特別出色,根據官方提供的效能測試表明,大約每秒可以處理0.5萬-1.5次讀寫請求。因為Mongo主要是支援海量資料儲存的,所以Mongo還自帶了一個出色的分散式檔案系統GridFS,可以支援海量的資料儲存,最後由於Mongo可以支援複雜的資料結構,而且帶有強大的資料查詢功能和類似於sql的索引。

Mongodb的高效能在於模式自由,使用高效的二進位制資料儲存,包括大型物件(如視訊等)自動處理碎片,以支援雲端計算層次的擴充套件性。在儲存海量資料的同時,還有良好的查詢效能。當然了mongodb支援多種語言,支援RUBY,PYTHON,JAVA,C++,PHP,C#等多種語言

Redis、Memcache、MongoDB特點、區別以及應用場景

https://mp.weixin.qq.com/s?_biz=MzIxMjg4NDU1NA==&mid=2247484268&idx=1&sn=5431c00c451ebeca8aa99ae59f05a3a2&chksm=97be0e49a0c9875fa918412aa0d2544c8dbb02b8875382b08217b1e7818e7ae913d72ae4107c&scene=21#wechatredirect

相關文章