課程目錄:html
- 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總結
隨着互聯網Web網站的興起,傳統的關係數據庫在應付Web網站,特別是超大規模和高併發的社交網絡類型的Web純動態網站已經顯得力不從心,暴露出了不少難以克服的問題。例如:關係數據庫爲了下降數據冗餘,保證數據約束性,在數據查詢時不得不使用多個數據表之間的鏈接操做,這極大地下降了查詢效率,不可以知足當前Internet的高實時性的要求。而非關係型數據庫對併發的大規模訪問有着效率上的優點,所以,非關係數據庫是在具體應用背景下獲得了迅速的發展。java
NoSQL指的是非關係型的數據庫。其實,NoSQL概念最先出如今1998年,當時的含義是反SQL技術革命運動,但並未引發太多的關注。直到2009年,NoSQL概念被來自Rackspace的EricEvans再次提出,這時的NoSQL已經不是單純的反SQL運動,指的主要是非關係型的分佈式數據庫,而且不支持原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)的數據庫設計模式。在亞特蘭大舉行的有關NoSQL的討論會上,學者給出了NoSQL較爲廣泛的解釋,即「非關係型的」。而且指出Key-Value存儲和文檔數據庫是NoSQL的主要特色。linux
原子性:redis
多個事情組成一個單元,要麼同時成功或失敗,不能只運行其中一個算法
一致性:sql
事務處理要將數據庫從一種狀態轉變爲另外一種狀態。一旦提交了修改數據,那麼其它人讀取這個數據,也是被修改後的數據mongodb
隔離性:數據庫
在事務處理提交以前,事務處理的效果不能由系統中其它事務處理。多個用戶,不能同時讀寫同一個數據,應該有前後順序,在數據庫中是一個一 個事件地運行,若是事件的條件不知足,後續事件就回滾json
持久性:vim
事件一旦提交成功,數據就發生了變化
例如:
網上定p系統,扣錢和定p是一個事務,它須要有原子性即不能只運行扣錢不運行定p。符合原子性。 這張p被多人同時在網上定,就會有先來的才定上這個p,後來定p的動做,若是發現p已賣出,(p的狀態改變了,其它人經過網站訪問這個數據,就會發現p已賣出符合一致性),就會回滾到不扣錢,p訂不上的狀態。符合隔離性。 p被定了,在數據庫裏設置標誌位,它就一直顯示爲賣出狀態。符合持久性
1:key-value存儲 2:最終一致性 3:可拓展
關係型數據庫
優點: 1.擅長小數據量的處理 2.擅長複雜的SQL操做,能夠進行Join等複雜查詢 3.能夠方便的生成各類數據對象,利用存儲的數據創建窗體和報表,可視性好 劣勢: 1.很難進行分佈式應用和大量數據的寫入處理 2.爲有數據更新的表作索引和結構變動 3.字段不固定的應用 4.對簡單查詢須要快速返回結果的處理
NoSQL數據庫
優點: 1.擅長大量數據的寫入和讀取 2.快速的查詢響應,靈活的數據模型 3.數據結構變動或更新很是方便,不須要更改已有數據的數據結構 4.擊碎了性能瓶頸,可使執行速度變的更快 劣勢: 1.不提供複雜的API接口 2.通常僅提供key索引 3.不適合小數據的處理 4.現有產品的不夠成熟,大多數產品都還處於初創期
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(主從)同步。
(Memcached 是一個高性能的分佈式內存對象緩存系統,用於動態Web應用以減輕數據庫負載。它經過在內存中緩存數據和對象來減小讀取數據庫的次數,從而提升動態、數據庫驅動網站的速度。Memcached基於一個存儲鍵/值對的hashmap。)
參考地址:http://www.runoob.com/redis/redis-conf.html
下載:
官網: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
若是wget 未安裝, 顯示 未找到命令
須要到根目錄下
cd / yum install wget -y
等待安裝完成便可重複第3步
4:解壓redis-4.0.6.tar.gz
tar -zvxf redis-4.0.6.tar.gz
5:在安裝以前須要預裝gcc、tcl
沒有安裝的小夥伴,須要安裝,若是已經存在,則略過此步驟
回到根目錄 cd/ 查看安裝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
切換到目錄 cd /opt/redis/redis-4.0.6
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
切換到根目錄 cd /
vim ~/.bash_profile 或者 vi ~/.bash_profile
修改內容部分: export REDIS_HOME=/usr/lksoft/redis export 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
在50個併發的狀況下請求10W次,寫的速度是11W次/s,讀的速度是8.1w次/s
官網參考命令地址:https://redis.io/commands
菜鳥教程命令地址:http://www.runoob.com/redis
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
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的子串
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的頭部
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的一個元素
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
string(字符串)
應用場景:String是最經常使用的一種數據類型,普通的key/value存儲.
list(雙向鏈表)
應用場景:Redis list應用場景很是多,也是Redis最重要的數據結構之一,好比twitter的關注列表,粉絲列表等均可以用Redis的list結構來實現.
set(無序集合)
應用場景:Set對外提供的功能與list相似,當你須要存儲一個列表數據,又不但願出現重複數據時,set 是一個很好的選擇,而且set提供了判斷某個成員是否在一個set集合內的接口,這個也是list所不能提供的
Sorted set(有序集合)-- zset
應用場景:Sorted set的使用場景與set相似,區別是set不是自動有序的,而sorted set能夠經過用戶額外提供一個優先級(score)的參數來爲成員排序,而且是插入有序的,即自動排序.當你須要一個有序的而且不重複的集合列表,那麼能夠選擇sorted set數據結構
hash(hash表)
應用場景:好比,咱們存儲供應商酒店價格的時候能夠採起此結構,用酒店編碼做爲Key, 價格信息做爲Value
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 。
所需jar包:
<!-- https://mvnrepository.com/artifact/redis.clients/jedis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency>
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) { //獲取redis的鏈接 //表明使用端口號爲6379,默認,若是端口號非默認的,則須要new Jedis("192.168.168.226",8888); Jedis jd = new Jedis("39.106.131.203"); System.out.println("鏈接redis成功"); //須要設置redis服務器(虛擬機中的6379.conf文件,將bind修改成:0.0.0.0) // 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使用最佳方式是所有數據in-memory。 Redis更多場景是做爲Memcached的替代者來使用。 當須要除key/value以外的更多數據類型支持時,使用Redis更合適。 當存儲的數據不能被剔除時,使用Redis更合適。(持久化)
面向集合(Collenction-Orented)
模式自由(schema-free)
意味着對於存儲在 MongoDB 數據庫中的文件,咱們不須要知道它的任何結構定義。提了這麼屢次"無模式"或"模式自由",它到是個什麼概念呢? 例如,下面兩個記錄能夠存在於同一個集合裏面:
{"welcome" : "Beijing"}
{"age" : 25}
文檔型:
適合場景:
1.網站數據,實時的插入,更新與查詢。 2.因爲性能很高,可作持久化緩存層。 3.存儲大尺寸,低價值的數據。 4.高伸縮性的集羣場景。 5.BSON格式很是適合文檔化數據的存儲及查詢。
不適合場景:
1.高度事務性的系統,例如銀行或會計系統。 2.傳統的商業智能應用,針對特定問題的BI數據庫會對產生高度優化的查詢方式。對於此類應用,數據倉庫多是更合適的選擇。
教程系統版本:(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:$HOME/bin:/usr/local/mongodb/bin source ~/.bash_profie
注意:
export MONGODB_HOME=/usr/local/mongodb //配置剛纔的路徑
PATH=$PATH:$HOME/bin:/usr/local/mongodb/bin
# User specific environment and startup programs PATH=$PATH:$HOME/bin export REDIS_HOME=/usr/lksoft/redis export MONGODB_HOME=/usr/local/mongodb PATH=$PATH:$HOME/bin:/usr/local/mongodb/bin export PATH
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 進程號便可 mongod --config /usr/local/mongodb/mongodb.conf 啓動
啓動3:配置service服務啓動(推薦)
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 <db name>:切換當前數據庫,這和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 在運維管理上的方便。
配置所需jar包
<dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>3.3.0</version> </dependency>
增長鏈接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); // 參數爲 數據庫,集合,ip,端口 》 // 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主要解決的是海量數據的訪問效率問題,根據官方的文檔,當數據量達到50GB以上的時候,Mongo的數據庫訪問速度是MySQL的10倍以上。Mongo的併發讀寫效率不是特別出色,根據官方提供的性能測試代表,大約每秒能夠處理0.5萬-1.5次讀寫請求。由於Mongo主要是支持海量數據存儲的,因此Mongo還自帶了一個出色的分佈式文件系統GridFS,能夠支持海量的數據存儲,最後因爲Mongo能夠支持複雜的數據結構,並且帶有強大的數據查詢功能和相似於sql的索引。
Mongodb的高性能在於模式自由,使用高效的二進制數據存儲,包括大型對象(如視頻等)自動處理碎片,以支持雲計算層次的擴展性。在存儲海量數據的同時,還有良好的查詢性能。固然了mongodb支持多種語言,支持RUBY,PYTHON,JAVA,C++,PHP,C#等多種語言
更多