NoSQL(NoSQL = Not Only SQL ),意即「不只僅是SQL」,泛指非關係型的數據庫,隨着互聯網web2.0網站的興起,傳統的關係數據庫在應付web2.0網站,特別是超大規模和高併發的SNS類型的web2.0純動態網站已經顯得力不從心,暴露了不少難以克服的問題,而非關係型的數據庫則因爲其自己的特色獲得了很是迅速的發展。NoSQL數據庫的產生就是爲了解決大規模數據集合多重數據種類帶來的挑戰,尤爲是大數據應用難題。javascript
redis是業界主流的key-value nosql 數據庫之一。和Memcached相似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操做,並且這些操做都是原子性的。在此基礎上,redis支持各類不一樣方式的排序。與memcached同樣,爲了保證效率,數據都是緩存在內存中。區別的是redis會週期性的把更新的數據寫入磁盤或者把修改操做寫入追加的記錄文件,而且在此基礎上實現了master-slave(主從)同步。java
異常快速 : Redis是很是快的,每秒能夠執行大約110000設置操做,81000個/每秒的讀取操做。node
支持豐富的數據類型 : Redis支持最大多數開發人員已經知道如列表,集合,可排序集合,哈希等數據類型。python
操做都是原子的 : 全部 Redis 的操做都是原子,從而確保當兩個客戶同時訪問 Redis 服務器獲得的是更新後的值(最新值)。git
$sudo apt-get update $sudo apt-get install redis-server
啓動 Redis程序員
$redis-server
查看 redis 是否還在運行github
$redis-cli
redis 127.0.0.1:6379>
redis 127.0.0.1:6379> ping PONG
1
2
3
4
5
6
7
|
sudo pip install redis
or
sudo easy_install redis
or
源碼安裝
詳見:https:
/
/
github.com
/
WoLpH
/
redis
-
py
|
要在Ubuntu 上安裝 Redis桌面管理,能夠從 http://redisdesktop.com/download 下載包並安裝它。web
redis-py 的API的使用能夠分類爲:redis
一、操做模式
redis-py提供兩個類Redis和StrictRedis用於實現Redis的命令,StrictRedis用於實現大部分官方的命令,並使用官方的語法和命令,Redis是StrictRedis的子類,用於向後兼容舊版本的redis-py。
1
2
3
4
5
|
import
redis
r
=
redis.Redis(host
=
'10.211.55.4'
, port
=
6379
)
r.
set
(
'foo'
,
'Bar'
)
print
r.get(
'foo'
)
|
二、鏈接池
redis-py使用connection pool來管理對一個redis server的全部鏈接,避免每次創建、釋放鏈接的開銷。默認,每一個Redis實例都會維護一個本身的鏈接池。能夠直接創建一個鏈接池,而後做爲參數Redis,這樣就能夠實現多個Redis實例共享一個鏈接池。
redis中的String在在內存中按照一個name對應一個value來存儲。如圖:
set(name, value, ex=None, px=None, nx=False, xx=False)
1
2
3
4
5
6
|
在Redis中設置值,默認,不存在則建立,存在則修改
參數:
ex,過時時間(秒)
px,過時時間(毫秒)
nx,若是設置爲True,則只有name不存在時,當前set操做才執行
xx,若是設置爲True,則只有name存在時,崗前set操做才執行
|
返回 key 所關聯的字符串值。
若是 key 不存在那麼返回特殊值 nil 。
若給定的 key 已經存在,則 SETNX 不作任何動做。
將值 value 關聯到 key ,並將 key 的生存時間設爲 seconds (以秒爲單位)。
若是 key 已經存在, SETEX 命令將覆寫舊值。
psetex (name, time_ms, value) mset(*args, **kwargs)
同時設置一個或多個 key-value 對。
mget(keys, *args)返回 key 中字符串值的子字符串,字符串的截取範圍由 start 和 end 兩個偏移量決定(包括 start 和 end 在內)。
負數偏移量表示從字符串最後開始計數, -1 表示最後一個字符, -2 表示倒數第二個,以此類推
setrange(name, offset, value)
1
2
3
4
|
# 修改字符串內容,從指定字符串索引開始向後替換(新值太長時,則向後添加)
# 參數:
# offset,字符串的索引,字節(一個漢字三個字節)
# value,要設置的值
|
# 對name對應值的二進制表示的位進行操做
# 參數:
# name,redis的name
# offset,位的索引(將值變換成二進制後再進行索引)
# value,值只能是 1 或 0
# 注:若是在Redis中有一個對應: n1 = "foo",
那麼字符串foo的二進制表示爲:
01100110
01101111
01101111
因此,若是執行 setbit(
'n1'
,
7
,
1
),則就會將第
7
位設置爲
1
,
那麼最終二進制則變成
01100111
01101111
01101111
,即:
"goo"
# 擴展,轉換二進制表示:
# source = "薩德"
source
=
"foo"
for
i
in
source:
num
=
ord
(i)
print
bin
(num).replace(
'b'
,'')
特別的,若是source是漢字
"薩德"
怎麼辦?
答:對於utf
-
8
,每個漢字佔
3
個字節,那麼
"薩德"
則有
9
個字節
對於漢字,
for
循環時候會按照 字節 迭代,那麼在迭代時,將每個字節轉換 十進制數,而後再將十進制數轉換成二進制
11100110
10101101
10100110
11100110
10110010
10011011
11101001
10111101
10010000
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
|
getbit(name, offset)
1
|
# 獲取name對應的值的二進制表示中的某位的值 (0或1)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
|
hscan_iter(name, match=None, count=None)
1
2
3
4
5
6
7
8
9
|
|
List操做,redis中的List在在內存中按照一個name對應一個List來存儲。如圖:
lpush(name,values)
1
2
3
4
5
6
7
8
|
|
lpushx(name,value)
1
2
3
4
|
|
llen(name)
1
|
|
linsert(name, where, refvalue, value))
1
2
3
4
5
6
7
|
|
lset(name, index, value)
1
2
3
4
5
6
|
|
lrem(name, value, num)
1
2
3
4
5
6
7
8
|
|
ltrim(name, start, end)
1
2
3
4
5
|
|
rpoplpush(src, dst)
1
2
3
4
|
|
blpop(keys, timeout)
1
2
3
4
5
6
7
8
|
|
brpoplpush(src, dst, timeout=0)
1
2
3
4
5
6
|
|
Set操做,Set集合就是不容許重複的列表
sadd(name,values)
1
scard(name)
1
|
|
sdiff(keys, *args)
1
|
|
sdiffstore(dest, keys, *args)
1
|
|
sinter(keys, *args)
1
|
|
sinterstore(dest, keys, *args)
1
|
|
sismember(name, value)
1
|
|
smembers(name)
1
|
|
smove(src, dst, value)
1
|
|
spop(name)
1
|
|
srandmember(name, numbers)
1
|
|
srem(name, values)
1
|
|
sunion(keys, *args)
1
|
|
sunionstore(dest,keys, *args)
1
|
|
sscan(name, cursor=0, match=None, count=None)
sscan_iter(name, match=None, count=None)
1
|
|
zadd(name, *args, **kwargs)
1
2
3
4
5
|
|
zcard(name)
1
|
|
zcount(name, min, max)
1
|
|
zincrby(name, value, amount)
1
|
|
zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
|
zrank(name, value)
1
2
3
4
|
|
zrem(name, values)
1
2
3
|
|
zremrangebyrank(name, min, max)
1
|
|
zremrangebyscore(name, min, max)
1
|
|
zscore(name, value)
1
|
|
zinterstore(dest, keys, aggregate=None)
1
2
|
|
zunionstore(dest, keys, aggregate=None)
1
2
|
|
zscan(name, cursor=0, match=None, count=None, score_cast_func=float)
zscan_iter(name, match=None, count=None,score_cast_func=float)
1
|
|
delete(*names)