NoSql的含義
NoSQL ,(Not Only SQL),泛指非關系型數(shù)據(jù)庫, 它是由一次叫“反Sql運動”的社區(qū)討論而誕生的體系。這個運動的發(fā)起最早源自于社區(qū)網(wǎng)站 LiveJournal的開發(fā)團隊,它們的初衷是為了用于減少數(shù)據(jù)庫連接數(shù),減輕數(shù)據(jù)庫的工作壓力,但發(fā)展至今有著其他不同的應用領域,因此NoSQL處于一種所謂百家爭鳴的,各執(zhí)一詞的時期。但我們作為NoSql的學習者和應用者,我們不需要關心和糾結這些NoSql的爭論,也不需要參與到這些爭論當中。
只要不是關系型數(shù)據(jù)庫里面的東西,都可以叫做nosql數(shù)據(jù)庫。
NoSql的共同特點和優(yōu)勢
- NoSQL 通常是以key-value形式存儲的(如:Memcache、Redis、Mongodb)
- 不支持SQL語句
- 沒有表結構
- 配置簡單
- 靈活、高效的操作與數(shù)據(jù)模型(key-value存儲,一般叫做hash表)
- 低廉的學習成本
- 能很好地作為MySql的中間層(cache is king 有緩存肯定會更好、緩存也會引來問題?數(shù)據(jù) 一致性的問題)
- 能很好地支持PHP
NoSql的共同的缺點
- 沒有統(tǒng)一的標準
- 安全性極差(memcache沒有權限系統(tǒng) )
- 沒有正式的官方支持 (社區(qū)維護)(GitHub)
- 各種產(chǎn)品還不算成熟
- 權威支持的產(chǎn)品價格很高(如:阿里云)
NoSql的產(chǎn)品分類
- 網(wǎng)站:http://www.nosql-database.org/
- redis
- mongodb
- memcache
- Aliyun MQ
- HBASE
- .....
Memcache
端口:11211
純內存存儲,是所有NoSQL產(chǎn)品中最簡單,速度最快的,但也是功能最弱的
-
內置分布式算法,開發(fā)者不需要自己去實現(xiàn)
- 使用分布式存儲數(shù)據(jù)
$mem = new Memcache(); $mem->addServer('127.0.0.1', 11212); $mem->addServer('127.0.0.1', 11213); $mem->addServer('127.0.0.1', 11214); # 數(shù)據(jù)自動分布在3臺memcache服務器上,不用開發(fā)人員操心 for($i = 1; $i < 99; $i++){ $mem->set('key_' . $i, 'value_' . $i, 0, 86400); } echo "ok";- 獲取分布式數(shù)據(jù)
$mem = new Memcache(); $mem->addServer('127.0.0.1', 11212); $mem->addServer('127.0.0.1', 11213); $mem->addServer('127.0.0.1', 11214); # 開發(fā)人員無法得知數(shù)據(jù)的來源 $data = $mem->get('key_1'); var_dump($data); -
可以設置數(shù)據(jù)有效期
Memcache設置緩存的有效期可以使用:
- 緩存時間:使用s秒數(shù),但是不能超過86400*30s,也就是30天的秒數(shù)
- 時間戳:但是該方式只有在Linux下才可以使用,windows下不生效,使用時間戳可以設置大于30天的有效期
使用Telnet協(xié)議進行傳輸,沒有加密功能,安全性很差,但在
內網(wǎng)上影響不大最大存儲空間只有64M,一旦爆滿,Memcache會指定重啟,并釋放當前所有的內存
存儲形式為KV型,單個Value值最大為1M(單個chunk最大為1M)
數(shù)據(jù)存儲在內存中,一旦服務器維護或重啟,數(shù)據(jù)就會丟失
數(shù)據(jù)零散,無法遍歷,管理數(shù)據(jù)完整性非常一般
存儲的數(shù)據(jù)都是字符串類型
-
可以配置Session共享(在php.ini中配置session.save_handler = memcache,session.save_path = "tcp://
#memcache服務器的IP#:11211"); php.ini session.save_handler = memcache session.save_path = "tcp://127.0.0.1:11211" -
Memcache的內存分配機制
? 由于Memcache是一個內存緩存系統(tǒng),就涉及內存申請和釋放的問題,不斷的申請和釋放內存,會導致內存的碎片化。為了解決內存碎片化的問題,Memcache使用了內存預先分配機制。
? Memcache將64M的存儲空間分割成64份,每一份都是1M的空間,這樣的空間稱為slab class。
? slab class里面的存儲數(shù)據(jù)的單元稱為chunk,最小的chunk默認為96B,最大為1M。
? 相鄰slab class之間chunk大小的比值是固定的,這個比值被稱為增長因子,它可以根據(jù)實際的業(yè)務做相應的調整。
-
Memcache內部使用了LRU算法
? LRU(Least Recently Used )算法被稱為
最近最少使用原則。? 當memcache的一個slab里面的chunk不夠使用的情況下(存儲滿了,數(shù)據(jù)在有效期)當有新的滿足chunk的數(shù)據(jù)過來的情況下,memcache會優(yōu)先把slab里面最近一段時間內,最不活躍的數(shù)據(jù)先剔除掉,騰出空間,給新的數(shù)據(jù)使用。
-
Memcache使用惰性刪除機制
? Memcache本身不監(jiān)控數(shù)據(jù)是否過期,當下一次重新獲取數(shù)據(jù)的時候,才會去查看數(shù)據(jù)是否有效,如果有效則返回,否則就清除。
-
Memcache實現(xiàn)高可用
- sina公司開發(fā)的MemcacheDB
- repcached:全稱replication cached,是由日本人發(fā)明的memcache的高可用技術,簡稱復制緩沖區(qū)技術。
Redis
端口:6379
默認存在0~15共16個數(shù)據(jù)庫
支持緩存數(shù)據(jù)持久化
-
支持5種數(shù)據(jù)類型
- String(字符串)
- list(鏈表)
- hash(哈希表)
- set(無序集合)
- sorted set(有序集合,縮寫為zset)
為高并發(fā)而生
Redis使用一致性哈希虛擬節(jié)點算法可以實現(xiàn)分布式功能
存儲形式為KV型,單個Value值最大可以存儲1G的數(shù)據(jù),存儲總量可以視硬盤大小而定
-
Redis可以開啟安全認證
# redis.conf # 由于配置文件中的密碼是明文,所以一般會把該配置文件的權限設置為600 requirepass ##密碼##(明文) -
Redis的持久化
-
快照模式
默認模式,快照文件為dump.rdb。
當網(wǎng)站的數(shù)據(jù)量變大時,該文件也會隨之增大,操作效率很低。
-
aof模式(append of file)
aof文件有點類似MySQL的binlog日志(讀寫分離)
aof文件會把用戶的操作記錄包括查詢的過程全部記錄,當服務器出現(xiàn)問題的時候,Redis會將數(shù)據(jù)從內存中保存到aof文件當中,當服務器重新運行時,Redis就會根據(jù)aof文件中的操作記錄,把數(shù)據(jù)重新還原到內存當中去,以確保數(shù)據(jù)的完整性。
快照模式和aof模式是完全互斥的。
如果aof的模式一旦啟動,那么快照就會失效,Redis就會把所有的數(shù)據(jù)緩存到內存當中,如果發(fā)生重啟,停止,關閉服務器等行為,那么aof文件就會把內存中數(shù)據(jù)同步到硬盤中。
開啟aof模式:
# redis.conf appendonly yes appendfilename "appendonly.aof" # appendfsync always # always 的選項代表Redis的命令每一次只要運行那么就會馬上寫入aof文件當中,該選項是最沒有效率的,然而它卻是最具備操作記錄完整性的。 appendfsync everysec # everysec 的選項是Redis比較折中的選項,代表每一秒中只有有操作那么就會進行操作記錄,但是如果在某一秒當中redis發(fā)生故障,那么這一秒的數(shù)據(jù)操作記錄將有可能發(fā)生丟失的情況,存在一定的風險,然而這個配置的性能比較適中,所以建議使用 # appendfsync no # no 該配置的效率完全依賴您當前所在使用的操作系統(tǒng)和計算機的性能,如果操作系統(tǒng)穩(wěn)定,計算機的性能強大,那么這一項是最有效率的,反而就是最差,所以一般最好不要設置該項
-
MongoDB
端口:27017
文檔型數(shù)據(jù)庫
存儲的是經(jīng)過特殊處理的json數(shù)據(jù),也叫Bson(json二進制化后的數(shù)據(jù))
MongoDB內部使用js解釋引擎來實現(xiàn)數(shù)據(jù)的分析,在插入的時候,將數(shù)據(jù)轉換成二進制的Bson來存儲;在查詢的時候,將數(shù)據(jù)Bson轉換成json對象返回
-
存在數(shù)據(jù)庫的概念
# 查看當前所有數(shù)據(jù)庫 > show dbs; # 選擇數(shù)據(jù)庫 > use test; # 查看當前庫下所有的數(shù)據(jù)表 > show tables; > show conllections; # 創(chuàng)建數(shù)據(jù)庫 # MongoDB的數(shù)據(jù)庫是隱式創(chuàng)建,當該數(shù)據(jù)庫下有數(shù)據(jù)之后,它就會被自動創(chuàng)建了 # 刪除當前數(shù)據(jù)庫 > db.dropDatabase(); -
Collection(集合) → 相當于MySQL中的表
# 創(chuàng)建表 # 顯式創(chuàng)建 > db.createConllection('collectionName'); # 隱式創(chuàng)建 > db.collectionName.insert(/*json數(shù)據(jù)*/); # 刪除表 > db.collectionName.drop(); ####### 查找 # 查找所有 > db.collectionName.find(); # 將取出的數(shù)據(jù)以優(yōu)雅的格式顯式,鏈式調用 > db.collectionName.find().pretty(); # 按條件查找和展示 > db.collectionName.find({/*查詢條件*/}, {/*要展示的字段*/}); # 例如:select age, name from stu where age > 18; > db.stu.find({'age':{$gt:18}}, {'_id':0, 'age':1, 'name':1}); # 只查詢一條 # 例如:select age, name from stu where age > 18 limit 1; > db.stu.findOne({'age':{$gt:18}}, {'_id':0, 'age':1, 'name':1}); -
Document(文檔) → 相當于MySQL表中的記錄
####### 增加 > db.collectionName.insert(/*json數(shù)據(jù)*/); # 增加單條記錄 > db.collectionName.insert({'name':'rico', 'age':19, 'gender':male}); # 增加多條記錄 > db.collectionName.insert([ {'name':'rico', 'age':19, 'gender':male}, {'name':'nacy', 'age':22, 'gender':female, 'birthday':'1993/01/05'}, {'name':'zaks', 'age':30, 'gender':male, 'className':'php88'} ]); ####### 刪除 > db.collectionName.remove(/*查詢表達式*/, /*選項*/); # 例如:delete from stu where age < 10; > db.stu.remove({'name':{$gt:10}}); # 例如:delete from stu where age < 10 limit 1; > db.stu.remove({'name':{$gt:10}}, {justOne:true}); ####### 修改 > db.collectionName.update(/*查詢表達式*/, /*新值*/); # 例如:update stu set name='coco' where _id=3; > db.stu.update({'_id':3}, {'name':'coco'}); # 注意:這里修改之后,文檔中只有'_id'和'name'了 # 如果只是想修改某列,則可以使用$set > db.stu.update({'_id':3}, {$set:{'name':'coco'}}); ####### 分頁 # 例如:select * from stu limit 5, 3; > db.stu.find().limit(3).skip(5); ####### 排序 # 例如:select * from stu order by age; > db.stu.find().sort({'age':1}); # 例如:select * from stu order by age desc; > db.stu.find().sort({'age':-1}); 怎么關閉 mongoDB?千萬不要 kill -9 pid,可以 kill -2 pid 或 db.shutdownServer()
-
mongodb的權限驗證機制