Python資料庫(MySQL、MongoDB、Redis)程式設計
MySQL
- 資料庫系統解決的問題:持久化儲存,優化讀寫,保證資料的有效性
- 當前使用的資料庫,主要分為兩類
- 文件型,如sqlite,就是一個檔案,通過對檔案的複製完成資料庫的複製
- 服務型,如mysql、postgre,資料儲存在一個物理檔案中,但是需要使用終端以tcp/ip協議連線,進行資料庫的讀寫操作
E-R模型
- 當前物理的資料庫都是按照E-R模型進行設計的
- E表示entry,實體
- R表示relationship,關係
- 一個實體轉換為資料庫中的一個表
- 關係描述兩個實體之間的對應規則,包括
- 一對一
- 一對多
- 多對多
- 關係轉換為資料庫表中的一個列 *在關係型資料庫中一行就是一個物件
三正規化
- 第一正規化(1NF):列不可拆分
- 第二正規化(2NF):唯一標識
- 第三正規化(3NF):引用主鍵
說明:後一個正規化,都是在前一個正規化的基礎上建立的
安裝
ubuntu中先切換到root賬戶,sudo -s
,然後
sudo apt-get install mysql-server mysql-client
管理服務
- 啟動
service mysql start
- 停止
service mysql stop
- 重啟
service mysql restart
允許遠端訪問
- 找到mysql配置檔案並修改
sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
將bind-address=127.0.0.1
註釋 - 登入mysql,執行命令
grant all privileges on *.* to 'root'@'%' identified by 'mysql' with grant option;
flush privileges;
- 重啟mysql
登入
mysql -uroot -p
####退出
exit;
或quit
欄位型別
- 數字:int,decimal(小數),如decimal(5,2)一共5位數,小數位2位
- 字串:char,varchar,text
- 日期:datetime
- 布林:bit
約束
- 主鍵primary key
- 非空not null
- 唯一unique
- 預設default
- 外來鍵foreign key
命令指令碼操作
遠端連線
mysql -hip地址 -uroot -p
資料庫操作
- 建立資料庫
create database 資料庫名 charset=utf8;
- 刪除資料庫
drop database 資料庫名;
- 切換資料庫
use 資料庫名;
- 查詢當前使用的資料庫
select database();
- 顯示所有的資料庫
show databases;
表操作
- 檢視所有表
show tables;
- 建立表
- 建立資料庫
create table 表名(列及型別);
如:
create table students(
id int auto_increment primary key,
sname varchar(10) not null
);
- 修改表
alter table 表名 add|change|drop 列名 型別;
- 刪除表
drop table 表名;
- 查看錶結構
desc 表名;
- 更改表名稱
rename table 原表名 to 新表名;
- 查看錶的建立語句
show create table '表名';
資料操作
- 查詢
select * from 表名
- 增加
全列插入:insert into 表名 values(...)
預設插入:insert into 表名(列1,...) values(值1,...)
同時插入多條資料:insert into 表名 values(...),(...)...;
或insert into 表名(列1,...) values(值1,...),(值1,...)...;
- 修改
update 表名 set 列1=值1,... where 條件
- 刪除
delete from 表名 where 條件
- 邏輯刪除
本質就是修改操作update
資料備份
- 進入管理員
sudo -s
- 進入mysql庫目錄
cd /var/lib/mysql
- 執行mysqldump命令
mysqldump –uroot –p 資料庫名 > ~/Desktop/備份檔案.sql;
資料恢復
- 連線mysqk,建立資料庫
- 退出連線,執行如下命令
mysql -uroot –p 資料庫名 < ~/Desktop/備份檔案.sql
查詢
- 消除重複行
select distinct gender from students;
條件
比較運算子
- 等於=
- 大於>
- 大於等於>=
- 小於<
- 小於等於<=
- 不等於!=或<>
邏輯運算子
- and
- or
- not
模糊查詢
like
%
表示任意多個任意字元_
表示一個任意字元
範圍查詢
in
表示在一個非連續的範圍內between ... and ...
表示在一個連續的範圍內
空判斷
- 注意:null與”是不同的
- 判空is null
優先順序
- 小括號,not,比較運算子,邏輯運算子
- and比or先運算,如果同時出現並希望先算or,需要結合()使用
聚合
為了快速統計結果,提供了5個聚合函式。
- count
- max
- min
- sum
- avg
分組
分組的目的是為了聚合
- 按照欄位分組,表示此欄位相同的資料會被放到一個組中
- 分組後,只能查詢出相同的資料列,對於有差異的資料列無法出現在結果集中
- 可以對分組後的資料進行統計,做聚合運算
語法select 列1,列2,聚合... from 表名 group by 列1,列2,列3...
select後面的列必須是在group by後面出現的列名。
比如select gender as 性別,count(*) from students group by gender;
分組後的資料篩選
- 語法
select 列1,列2,聚合... from 表名
group by 列1,列2,列3...
having 列1,...聚合...
- 對比where與having
where是對from後面指定的表進行資料篩選,屬於對原始資料的篩選
having是對group by的結果進行篩選
排序
- 語法
select * from 表名
order by 列1 asc|desc,列2 asc|desc,...
- 將行資料按照列1進行排序,如果某些行列1的值相同時,則按照列2排序,以此類推
- 預設按照列值從小到大排列
- asc從小到大排列,即升序
- desc從大到小排序,即降序
分頁
- 語法
select * from 表名
limit start,count
- 從start開始,獲取count條資料
- start索引從0開始
總結
- 完整的查詢語句
select distinct *
from 表名
where ....
group by ... having ...
order by ...
limit star,count
- 執行順序
- from 表名
- where ….
- group by …
- select distinct *
- having …
- order by …
- limit star,count
連線查詢
- 語法
inner join
select *
from tableName
inner join tableName2 on condition
inner join tableName3 on condition2 ...
- 左連線 表A left join 表B ,以左表為準,右邊沒有的資料以Null填充
- 右連線 表A right join 表B,以表B為準。
檢視
- 檢視本質就是對查詢的一個封裝。
create view view_name as
select * from tableName
where ...;
- 檢視的用途就是查詢
select * from view_name;
事務
- 當一個業務邏輯需要多個sql完成時,如果其中某條sql語句出錯,則希望整個操作都退回
- 使用事務可以完成退回的功能,保證業務邏輯的正確性
- 事務四大特性(簡稱ACID)
- 原子性(Atomicity):事務中的全部操作在資料庫中是不可分割的,要麼全部完成,要麼均不執行
- 一致性(Consistency):幾個並行執行的事務,其執行結果必須與按某一順序序列執行的結果相一致
- 隔離性(Isolation):事務的執行不受其他事務的干擾,事務執行的中間結果對其他事務必須是透明的
- 永續性(Durability):對於任意已提交事務,系統必須保證該事務對資料庫的改變不被丟失,即使資料庫出現故障
- 要求:表的型別必須是
innodb或bdb
型別,才可以對此表使用事務
查看錶的建立語句
show create table 表名;
修改表的型別
alter table '表名' engine=innodb;
事務語句
開啟begin;
提交commit;
回滾rollback;
索引
索引能提高資料庫訪問效能。
- 單列索引
- 組合索引
檢視索引
show INDEX from tableName
建立索引
create INDEX indexName ON tableName(colName(length),colName2...)
刪除索引
drop INDEX [indexName] ON tableName
缺點:
在執行更新操作時需要額外更新索引。
MySQL中測試執行時間
1、set profiling=1;
2、some operation
3、show profiles;show profile
與Python互動
Linux下安裝
sudo apt-get install python-mysqldb
引用
import Mysqldb
Connection物件
- 用於建立與資料庫的連線
建立物件:呼叫connect()方法:
conn=connect(引數列表)
- 引數host:連線的mysql主機,如果本機是’localhost’
- 引數port:連線的mysql主機的埠,預設是3306
- 引數db:資料庫的名稱
- 引數user:連線的使用者名稱
- 引數password:連線的密碼
- 引數charset:通訊採用的編碼方式,預設是’gb2312’,要求與資料庫建立時指定的編碼一致,否則中文會亂碼
物件的方法
- close()關閉連線
- commit()事務,所以需要提交才會生效
- rollback()事務,放棄之前的操作
- cursor()返回Cursor物件,用於執行sql語句並獲得結果
Cursor物件
- 執行sql語句
- 建立物件:呼叫Connection物件的cursor()方法:
cursor1=conn.cursor()
物件的方法
- close()關閉
- execute(operation [, parameters ])執行語句,返回受影響的行數
- fetchone()執行查詢語句時,獲取查詢結果集的第一個行資料,返回一個元組
- next()執行查詢語句時,獲取當前行的下一行
- fetchall()執行查詢時,獲取結果集的所有行,一行構成一個元組,再將這些元組裝入一個元組返回
- scroll(value[,mode])將行指標移動到某個位置
- mode表示移動的方式
- mode的預設值為relative,表示基於當前行移動到value,value為正則向下移動,value為負則向上移動
- mode的值為absolute,表示基於第一條資料的位置,第一條資料的位置為0
物件的屬性
- rowcount只讀屬性,表示最近一次execute()執行後受影響的行數
- connection獲得當前連線物件
SQL語句引數化
sname = '北京'
params=[sname] #list
count=cs1.execute('insert into areas(name) values(%s)',params)
MongoDB
NoSQL簡介
- NoSQL,全名為Not Only SQL,指的是非關係型的資料庫
- 隨著訪問量的上升,網站的資料庫效能出現了問題,於是nosql被設計出來
優點
- 高可擴充套件性
- 分散式計算
- 低成本
- 架構的靈活性,半結構化資料
- 沒有複雜的關係
缺點
- 沒有標準化
- 有限的查詢功能(到目前為止)
- 最終一致是不直觀的程式
型別 | 部分代表 | 特點 |
---|---|---|
列儲存 | Hbase、Cassandra、Hypertable | 顧名思義,是按列儲存資料的。最大的特點是方便儲存結構化和半結構化資料,方便做資料壓縮,對針對某一列或者某幾列的查詢有非常大的IO優勢。 |
文件儲存 | MongoDB、CouchDB | 文件儲存一般用類似json的格式儲存,儲存的內容是文件型的。這樣也就有有機會對某些欄位建立索引,實現關係資料庫的某些功能。 |
key-value儲存 | Tokyo Cabinet / Tyrant、Berkeley DB、MemcacheDB、Redis | 可以通過key快速查詢到其value。一般來說,儲存不管value的格式,照單全收。(Redis包含了其他功能) |
圖儲存 | Neo4J、FlockDB | 圖形關係的最佳儲存。使用傳統關係資料庫來解決的話效能低下,而且設計使用不方便。 |
物件儲存 | db4o、Versant | 通過類似面嚮物件語言的語法操作資料庫,通過物件的方式存取資料 |
xml資料庫 | Berkeley DB XML、BaseX | 高效的儲存XML資料,並支援XML的內部查詢語法,比如XQuery,Xpath。 |
基本資訊
- MongoDB將資料儲存為一個文件,資料結構由鍵值(key=>value)對組成
- MongoDB文件類似於JSON物件,欄位值可以包含其他文件、陣列、文件陣列
MongoDB特點
- 模式自由 :可以把不同結構的文件儲存在同一個資料庫裡
- 面向集合的儲存:適合儲存 JSON風格檔案的形式
- 完整的索引支援:對任何屬性可索引
- 複製和高可用性:支援伺服器之間的資料複製,支援主-從模式及伺服器之間的相互複製。複製的主要目的是提供冗餘及自動故障轉移
- 自動分片:支援雲級別的伸縮性:自動分片功能支援水平的資料庫叢集,可動態新增額外的機器
- 豐富的查詢:支援豐富的查詢表達方式,查詢指令使用JSON形式的標記,可輕易查詢文件中的內嵌的物件及陣列
- 快速就地更新:查詢優化器會分析查詢表示式,並生成一個高效的查詢計劃
- 高效的傳統儲存方式:支援二進位制資料及大型物件(如照片或圖片)
名詞
SQL術語/概念 | MongoDB術語/概念 | 解釋/說明 |
---|---|---|
database | database | 資料庫 |
table | collection | 資料庫表/集合 |
row | document | 資料記錄行/文件 |
column | field | 資料欄位/域 |
index | index | 索引 |
table | joins | 表連線,MongoDB不支援 |
primary key | primary key | 主鍵,MongoDB自動將_id欄位設定為主鍵 |
三元素:資料庫,集合,文件
- 集合就是關係資料庫中的表
- 文件對應著關係資料庫中的行
文件,就是一個物件,由鍵值對構成,是json的擴充套件Bson形式
{'name':'guojing','gender':'男'}
- 集合:類似於關係資料庫中的表,儲存多個文件,結構不固定,如可以儲存如下文件在一個集合中
- 資料庫:是一個集合的物理容器,一個數據庫中可以包含多個文件
- 一個伺服器通常有多個數據庫
安裝
- 下載mongodb的版本,兩點注意
- 根據業界規則,偶數為穩定版,如1.6.X,奇數為開發版,如1.7.X
- 32bit的mongodb最大隻能存放2G的資料,64bit就沒有限制
- 到官網,選擇合適的版本下載
- 解壓
tar -zxvf mongodb.tgz
或者Mac上使用brew
安裝brew install mongodb --with-openssl
- 移動到/usr/local/目錄下
sudo mv -r mongodb-linux-x86_64-ubuntu1604-3.4.0/ /usr/local/mongodb
- 將可執行檔案新增到PATH路徑中
export PATH=/usr/local/mongodb/bin:$PATH
Mac下安裝可以直接使用
brew update
,brew install mongodb
,然後使用mongod —config /usr/local/etc/mongod.conf
啟動mongodb的服務
MongoDB官網https://www.mongodb.com/
管理mongo
- 配置檔案在/etc/mongod.conf
- 預設埠27017
- 啟動
sudo service mongod start
- 停止
sudo service mongod stop
- 使用終端連線
mongo
命令
db
檢視當前資料庫名稱db.stats()
檢視當前資料庫資訊show dbs
列出所有在物理上存在的資料庫use 資料庫名稱
切換資料庫。如果資料庫不存在,則指向資料庫,但不建立,直到插入資料或建立集合時資料庫才被建立;預設的資料庫為test,如果你沒有建立新的資料庫,集合將存放在test資料庫中db.dropDatabase()
刪除當前指向的資料庫,如果資料庫不存在,則什麼也不做db.createCollection(name, options)
選項引數是可選的- 引數capped:預設值為false表示不設定上限,值為true表示設定上限
- 引數size:當capped值為true時,需要指定此引數,表示上限大小,當文件達到上限時,會將之前的資料覆蓋,單位為位元組
show collections
檢視當前資料庫的集合db.集合名稱.drop()
刪除集合
資料型別
- Object ID:文件ID
- String:字串,最常用,必須是有效的UTF-8
- Boolean:儲存一個布林值,true或false
- Integer:整數可以是32位或64位,這取決於伺服器
- Double:儲存浮點值
- Arrays:陣列或列表,多個值儲存到一個鍵
- Object:用於嵌入式的文件,即一個值為一個文件
- Null:儲存Null值
- Timestamp:時間戳
- Date:儲存當前日期或時間的UNIX時間格式
object id
- 每個文件都有一個屬性,為_id,保證每個文件的唯一性
- 可以自己去設定_id插入文件
- 如果沒有提供,那麼MongoDB為每個文件提供了一個獨特的_id,型別為objectID
- objectID是一個12位元組的十六進位制數
- 前4個位元組為當前時間戳
- 接下來3個位元組的機器ID
- 接下來的2個位元組中MongoDB的服務程序id
- 最後3個位元組是簡單的增量值
操作
插入
語法:db.集合名稱.insert(document)
如db.test.insert({name:'bendeng'})
- 插入文件時,如果不指定_id引數,MongoDB會為文件分配一個唯一的ObjectId
簡單查詢
語法:db.集合名稱.find()
更新
語法
db.集合名稱.update(
<query>,
<update>,
{multi: <boolean>}
)
- 引數query:查詢條件,類似sql語句update中where部分
- 引數update:更新操作符,類似sql語句update中set部分
- 引數multi:可選,預設是false,表示只更新找到的第一條記錄,值為true表示把滿足條件的文件全部更新
- 例:全文件更新
db.test.update({},{name:"newName"})
- 指定屬性更新,通過操作符
$set
,db.test.update({},$set:{name:"newName"})
儲存
語法:db.集合名稱.save(document)
- 如果文件的_id已經存在則修改,如果文件的_id不存在則新增
刪除
語法:
db.集合名稱.remove(
<query>,
{
justOne: <boolean>
}
)
- 引數query:可選,刪除的文件的條件
- 引數justOne:可選,如果設為true或1,則只刪除一條,預設false,表示刪除多條
如db.test.remove({_id:1234})
- 全部刪除
db.stu.remove({})
資料查詢
基本查詢
db.集合名稱.find({條件文件})
db.集合名稱.findOne({條件文件})
只返回第一條db.集合名稱.find({條件文件}).pretty()
將結果格式化
比較運算子
- 等於,預設是等於判斷,沒有運算子
- 小於$lt
- 小於或等於$lte
- 大於$gt
- 大於或等於$gte
- 不等於$ne
邏輯運算子
- 邏輯與:預設是邏輯與的關係
- 邏輯或:使用
$or
。db.stu.find({or:[{_id:{gt:18}},{name:”bendeng”}]}) - and和or一起使用
範圍運算子
使用$in
,$nin
判斷是否在某個範圍內
db.test.find({_id:{$in:[18,28]}})
支援正則表示式
使用//
或$regex
編寫正則表示式
db.test.find({name:/^p/})
db.test.find({name:{$regex:’^p’}}})
自定義查詢
使用$where
後面寫一個函式,返回滿足條件的資料
db.test.find({$where:function(){return this.id>20}})
Limit
用於讀取指定數量的文件
語法:db.集合名稱.find().limit(NUMBER)
- 引數NUMBER表示要獲取文件的條數
- 如果沒有指定引數則顯示集合中的所有文件
skip
用於跳過指定數量的文件
語法:db.集合名稱.find().skip(NUMBER)
- 引數NUMBER表示跳過的記錄條數,預設值為0
分頁
- 方法limit()和skip()可以一起使用,不分先後順序
投影
在查詢到的返回結果中,只選擇必要的欄位,而不是選擇一個文件的整個欄位。如:一個文件有5個欄位,需要顯示只有3個,投影其中3個欄位即可
語法:db.集合名稱.find({},{欄位名稱:1,...})
- 引數為欄位與值,值為1表示顯示,值為0不顯示
- 對於需要顯示的欄位,設定為1即可,不設定即為不顯示
- 特殊:對於_id列預設是顯示的,如果不顯示需要明確設定為0db.test.find({},{_id:0})
排序
語法:db.集合名稱.find().sort({欄位:1,...})
- 引數1為升序排列
- 引數-1為降序排列
如:db.test.find().sort({name:1})
,結果是:
{ "_id" : ObjectId("59e1c73d82debd5e42f2d81a"), "name" : "huhu" }
{ "_id" : ObjectId("59e1c73882debd5e42f2d819"), "name" : "kaixin" }
{ "_id" : ObjectId("59e1c61682debd5e42f2d818"), "name" : "newDocumanet" }
{ "_id" : ObjectId("59e1c74082debd5e42f2d81b"), "name" : "pupu" }
統計
語法:db.集合名稱.find({條件}).count()
或者db.集合名稱.count({條件})
例如:統計年齡大於20的男生人數
db.stu.count({age:{$gt:20},gender:1})
去重
語法:db.集合名稱.distinct('去重欄位',{條件})
高階操作
聚合
主要用於計算資料,類似sql中的sum()、avg()
語法:db.集合名稱.aggregate([{管道:{表示式}}])
- 管道在Unix和Linux中一般用於將當前命令的輸出結果作為下一個命令的輸入。如
ps ajx | grep mongo
- 在mongodb中,管道具有同樣的作用,文件處理完畢後,通過管道進行下一次處理
- 常用管道:
- $group:將集合中的文件分組,可用於統計結果
- $match:過濾資料,只輸出符合條件的文件
- $project:修改輸入文件的結構,如重新命名、增加、刪除欄位、建立計算結果
- $sort:將輸入文件排序後輸出
- $limit:限制聚合管道返回的文件數
- $skip:跳過指定數量的文件,並返回餘下的文件
- $unwind:將陣列型別的欄位進行拆分
如:db.test.aggregate([{$group:{_id:'$name',c:{$sum:1}}}])
這裡將name欄位進行group分組,並查出每個名字的個數。
結果是
{ "_id" : "panpan", "c" : 3 }
{ "_id" : "pupu", "c" : 1 }
{ "_id" : "huhu", "c" : 1 }
{ "_id" : "kaixin", "c" : 1 }
{ "_id" : "newDocumanet", "c" : 1 }
表示式:’$列名’
- 常用表示式
sum:計算總和, sum:1同count表示計數- $avg:計算平均值
- $min:獲取最小值
- $max:獲取最大值
- $push:在結果文件中插入值到一個數組中
- $first:根據資源文件的排序獲取第一個文件資料
- $last:根據資源文件的排序獲取最後一個文件資料
索引
- 建立唯一索引,實現唯一約束的功能
db.test.ensureIndex({"name":1})
- 聯合索引,對多個屬性建立一個索引
db.test.ensureIndex({"name":1},{"gender":1})
- 檢視文件的所有索引
db.test.getIndexes()
- 刪除索引
db.test.dropIndex({"name":1})
db.test.ensureIndexes()
安全管理
- 為了更安全的訪問mongodb,需要訪問者提供使用者名稱和密碼,於是需要在mongodb中建立使用者
- 採用了
角色-使用者-資料庫
的安全管理方式 - 常用系統角色如下:
- root:只在admin資料庫中可用,超級賬號,超級許可權
- Read:允許使用者讀取指定資料庫
- readWrite:允許使用者讀寫指定資料庫
- 建立超級管理使用者
use admin
db.createUser({
user:'admin',
pwd:'123',
roles:[{role:'root',db:'admin'}]
})
啟用安全認證
- 修改配置檔案
sudo vi /etc/mongod.conf
- 啟用身份驗證(注意:keys and values之間一定要加空格, 否則解析會報錯)
security:
authorization: enabled - 重啟服務
sudo service mongod stop
sudo service mongod start - 終端連線
mongo -u 'admin' -p '123' --authenticationDatabase 'admin'
- 修改使用者:可以修改pwd、roles屬性`db.updateUser(‘admin’,{pwd:’456’})
複製(副本集)
- 複製提供了資料的冗餘備份,並在多個伺服器上儲存資料副本,提高了資料的可用性,並可以保證資料的安全性
- 複製還允許從硬體故障和服務中斷中恢復資料
為什麼要複製
- 資料備份
- 資料災難恢復
- 讀寫分離
- 高(24* 7)資料可用性
- 無宕機維護
- 副本集對應用程式是透明
複製的工作原理
- 複製至少需要兩個節點A、B…
- A是主節點,負責處理客戶端請求
- 其餘的都是從節點,負責複製主節點上的資料
- 節點常見的搭配方式為:一主一從、一主多從
- 主節點記錄在其上的所有操作,從節點定期輪詢主節點獲取這些操作,然後對自己的資料副本執行這些操作,從而保證從節點的資料與主節點一致
- 主節點與從節點進行資料互動保障資料的一致性
複製的特點
- N 個節點的叢集
- 任何節點可作為主節點
- 所有寫入操作都在主節點上
- 自動故障轉移
- 自動恢復
步驟
- step1:建立資料庫目錄t1、t2
- step2:使用如下格式啟動mongod,注意replSet的名稱是一致的
mongod --bind_ip 192.168.196.128 --port 27017 --dbpath ~/Desktop/t1 --replSet rs0
mongod --bind_ip 192.168.196.128 --port 27018 --dbpath ~/Desktop/t2 --replSet rs0
- step3:連線主伺服器,此處設定192.168.196.128:27017為主伺服器
mongo --host 192.168.196.128 --port 27017
- step4:初始化
rs.initiate()
- step5:檢視當前狀態
rs.status()
- step6:新增複本集
rs.add('192.168.196.128:27018')
- step7:複本集新增成功
- step8:連線第二個mongo服務
mongo --host 192.168.196.128 --port 27018
- step9:向主伺服器中插入資料
- step10:在從伺服器中插查詢
- 說明:如果在從伺服器上進行讀操作,需要設定
rs.slaveOk()
rs.slaveOk()
db.t1.find()
其它
- 刪除從節點rs.remove('192.168.196.128:27018')
- 關閉主伺服器後,再重新啟動,會發現原來的從伺服器變為了從伺服器,新啟動的伺服器(原來的從伺服器)變為了從伺服器
備份
語法:mongodump -h dbhost -d dbname -o dbdirectory
- -h:伺服器地址,也可以指定埠號
- -d:需要備份的資料庫名稱
- -o:備份的資料存放位置,此目錄中存放著備份出來的資料
例如:
sudo mkdir test1bak
sudo mongodump -h 192.168.196.128:27017 -d test1 -o ~/Desktop/test1bak
恢復
語法:mongorestore -h dbhost -d dbname --dir dbdirectory
- -h:伺服器地址
- -d:需要恢復的資料庫例項
- -dir:備份資料所在位置
例如
mongorestore -h 192.168.196.128:27017 -d test2 --dir ~/Desktop/test1bak/test1
與Python的互動
檢視官方文件
安裝pymongo:pip install pymongo
Mac中安裝使用
sudo python -m pip install pymongo
- 引入包pymongo
import pymongo - 連線,建立客戶端
client=pymongo.MongoClient(“localhost”, 27017) - 獲得資料庫test
db=client.test - 獲得集合test
test = db.test - 新增文件
s1={name:’gj’,age:18}
s1_id = test.insert_one(s1).inserted_id - 查詢一個文件
s2=test.find_one() - 查詢多個文件1
for cur in test.find():
print cur - 查詢多個文件2
cur=test.find()
cur.next()
cur.next()
cur.next() - 獲取文件個數
print test.count()
Redis
安裝
1、去Redis官網下載最新的穩定版。目前是4.0.2。curl -O http://download.redis.io/releases/redis-4.0.2.tar.gz
2、解壓tar zxvf redis-4.0.2.tar.gz
3、複製:推薦放到usr/local目錄下
sudo mv -r redis-3.2.3/* /usr/local/redis/
進入redis目錄
cd /usr/local/redis/
4、sudo make
,sudo make test
5、安裝:將redis的命令安裝到/usr/bin/目錄。sudo make install
6、執行redis-server
,按Ctrl+C停止
7、啟動客戶端:在新終端中執行如下程式碼。redis-cli
配置
- 在原始檔/usr/local/redis目錄下,檔案redis.conf為配置檔案
- 繫結地址:如果需要遠端訪問,可將此行註釋
bind 127.0.0.1
- 埠,預設為6379
port 6379
- 是否以守護程序執行
- 如果以守護程序執行,則不會在命令列阻塞,類似於服務
- 如果以非守護程序執行,則當前終端被阻塞,無法使用
- 推薦改為yes,以守護程序執行
daemonize no|yes
- 資料檔案
dbfilename dump.rdb
- 資料檔案儲存路徑
dir的預設值為./,表示當前目錄。推薦改為:dir /var/lib/redis
- 使用配置檔案方式啟動
- 直接執行redis-server會直接執行,阻塞當前終端
- 一般配置檔案都放在/etc/目錄下
sudo cp /usr/local/redis/redis.conf /etc/redis/
- 推薦指定配置檔案啟動
sudo redis-server /etc/redis/redis.conf
- 停止redis服務
ps ajx|grep redis
sudo kill -9 redis的程序id
資料操作
- redis是key-value的資料,所以每個資料都是一個鍵值對
- 鍵的型別是字串
- 值的型別分為五種:
- 字串string
- 雜湊hash
- 列表list
- 集合set
- 有序集合zset
string
- string是redis最基本的型別
- 最大能儲存512MB資料
- string型別是二進位制安全的,即可以為任何資料,比如數字、圖片、序列化物件等
命令
- 設定鍵值
set key value
- 獲取鍵值
get key
- 設定鍵值及過期時間,以秒為單位
SETEX key seconds value
- 設定多個鍵值
MSET key value [key value ...]
- 獲取多個鍵值
MGET key [key ...]
- 將值加1
INCR key
- 將key對應的value加整數
INCRBY key increment
- 將key對應的value減1
DECR key
- 將key對應的value減整數
DECRBY key decrement
- 追加值
APPEND key value
- 獲取值長度
STRLEN key
鍵命令
- 查詢鍵,引數支援正則
KEYS pattern
比如KEYS *
- 判斷鍵是否存在,如果存在返回1,不存在返回0
EXISTS key [key ...]
- 檢視鍵對應的value的型別
TYPE key
- 刪除鍵及對應的值
DEL key [key ...]
- 設定過期時間,以秒為單位
EXPIRE key seconds
- 檢視有效時間,以秒為單位
TTL key
hash
- hash用於儲存物件,物件的格式為鍵值對
- 設定單個屬性
HSET key field value
- 設定多個屬性
HMSET key field value [field value ...]
- 獲取一個屬性的值
HGET key field
- 獲取多個屬性的值
HMGET key field [field ...]
- 獲取所有屬性的值
HGETALL key
- 獲取所有的屬性
HKEYS key
- 返回包含屬性的個數
HLEN key
- 獲取所有值
HVALS key
- 判斷屬性是否存在
HEXISTS key field
- 刪除屬性及值
HDEL key field [field ...]
- 返回值的字串長度
HSTRLEN key field
list
- 列表的元素型別為string
- 按照插入順序排序
- 在列表的頭部或者尾部新增元素
- 在頭部插入資料
LPUSH key value [value ...]
- 在尾部插入資料
RPUSH key value [value ...]
- 在一個元素的前|後插入新元素
LINSERT key BEFORE|AFTER pivot value
- 設定指定索引的元素值,索引是基於0的下標
- 索引可以是負數,表示偏移量是從list尾部開始計數,如-1表示列表的最後一個元素
LSET key index value
- 移除並且返回 key 對應的 list 的第一個元素
LPOP key
- 移除並返回存於 key 的 list 的最後一個元素
RPOP key
- 返回儲存在 key 的列表裡指定範圍內的元素,start 和 end 偏移量都是基於0的下標,偏移量也可以是負數,表示偏移量是從list尾部開始計數,如-1表示列表的最後一個元素
LRANGE key start stop
- 裁剪列表,改為原集合的一個子集,start 和 end 偏移量都是基於0的下標,偏移量也可以是負數,表示偏移量是從list尾部開始計數,如-1表示列表的最後一個元素
LTRIM key start stop
- 返回儲存在 key 裡的list的長度
LLEN key
- 返回列表裡索引對應的元素
LINDEX key index
無序集合set
- 元素為string型別
- 元素具有唯一性,不重複
- 新增元素
SADD key member [member ...]
- 返回key集合所有的元素
SMEMBERS key
- 返回集合元素個數
SCARD key
- 求多個集合的交集
SINTER key [key ...]
- 求某集合與其它集合的差集
SDIFF key [key ...]
- 求多個集合的合集
SUNION key [key ...]
- 判斷元素是否在集合中
SISMEMBER key member
有序集合zset
- 元素為string型別
- 元素具有唯一性,不重複
- 每個元素都會關聯一個double型別的score,表示權重,通過權重將元素從小到大排序
- 元素的score可以相同
- 新增
ZADD key score member [score member ...]
- 返回指定範圍內的元素
ZRANGE key start stop
- 返回元素個數
ZCARD key
- 返回有序集key中,score值在min和max之間的成員
ZCOUNT key min max
- 返回有序集key中,成員member的score值
ZSCORE key member
高階
釋出訂閱
- 釋出者不是計劃傳送訊息給特定的接收者(訂閱者),而是釋出的訊息分到不同的頻道,不需要知道什麼樣的訂閱者訂閱
- 訂閱者對一個或多個頻道感興趣,只需接收感興趣的訊息,不需要知道什麼樣的釋出者釋出的
- 釋出者和訂閱者的解耦合可以帶來更大的擴充套件性和更加動態的網路拓撲
- 客戶端發到頻道的訊息,將會被推送到所有訂閱此頻道的客戶端
- 客戶端不需要主動去獲取訊息,只需要訂閱頻道,這個頻道的內容就會被推送過來
訊息格式
- 推送訊息的格式包含三部分
- part1:訊息型別,包含三種類型
- subscribe,表示訂閱成功
- unsubscribe,表示取消訂閱成功
- message,表示其它終端釋出訊息
- 如果第一部分的值為subscribe,則第二部分是頻道,第三部分是現在訂閱的頻道的數量
- 如果第一部分的值為unsubscribe,則第二部分是頻道,第三部分是現在訂閱的頻道的數量,如果為0則表示當前沒有訂閱任何頻道,當在Pub/Sub以外狀態,客戶端可以發出任何redis命令
- 如果第一部分的值為message,則第二部分是來源頻道的名稱,第三部分是訊息的內容
命令
- 訂閱
SUBSCRIBE 頻道名稱 [頻道名稱 ...]
- 取消訂閱(如果不寫引數,表示取消所有訂閱)
UNSUBSCRIBE 頻道名稱 [頻道名稱 ...]
- 釋出
PUBLISH 頻道 訊息
主從配置
- 一個master可以擁有多個slave,一個slave又可以擁有多個slave,如此下去,形成了強大的多級伺服器叢集架構
- 比如,將ip為192.168.1.10的機器作為主伺服器,將ip為192.168.1.11的機器作為從伺服器
- 設定主伺服器的配置
bind 192.168.1.10
- 設定從伺服器的配置(注意:在slaveof後面寫主機ip,再寫埠,而且埠必須寫)
bind 192.168.1.11
slaveof 192.168.1.10 6379
- 在master和slave分別執行info命令,檢視輸出資訊
- 在master上寫資料
set hello world
- 在slave上讀資料
get hello
- 在master上寫資料
與python互動
安裝
sudo pip install redis
或者使用原始碼安裝
unzip redis-py-master.zip
cd redis-py-master
sudo python setup.py install
使用
import redis
try:
r=redis.StrictRedis(host='localhost',port=6379)
except Exception,e:
print e.message
- 方式一:根據資料型別的不同,呼叫相應的方法,完成讀寫
r.set('name','hello')
r.get('name')
- 方式二:pipline
- 緩衝多條命令,然後一次性執行,減少伺服器-客戶端之間TCP資料庫包,從而提高效率
pipe = r.pipeline()
pipe.set('name', 'world')
pipe.get('name')
pipe.execute()
封裝
import redis
class RedisHelper():
def __init__(self,host='localhost',port=6379):
self.__redis = redis.StrictRedis(host, port)
def get(self,key):
if self.__redis.exists(key):
return self.__redis.get(key)
else:
return ""
def set(self,key,value):
self.__redis.set(key,value)