之前总结了Redis基础,那个实在太low,现在重新正儿八经老老实实真真切切安安分分实实在在认认真真的把这部分写写。后续的redis的高级部分总结下。
Redis简介
redis是远程内存数据库。性能强劲,具有复制特性,redis的数据结构是帮助用户解决问题的,不会像其他的数据库要求用户扭曲问题来适应数据库。
重点是,通过复制,持久化,客户端分片等特性,可以很方便的将redis扩展程一个能够包含数百GB数据,每秒处理上百万次请求的系统。
redis是速度很快的非关系型数据库。,可以存储键和5种不同的数据类型的值,键值之间是映射关系。, 还可以将内的键值对数据持久化到硬盘,可以复制特性扩展读性能, 可以使用客户端扩展写性能。
redis不使用表,也不会预定义或者强制要求redis对不同的数据进行关联。
如下图:
Redis数据结构
redis中有5中数据结构:字符串,列表,集合,有序集合,哈希(散列表)
字符串
字符串是以键值的形式存储。
set name ChenZhiqiang
name是键,ChenZhiqiang是值。
| 命令 | 行为 |
|---|---|
| GET | 获取已经存储的键的值 |
| SET | 设置存储的键和值 |
| DEL | 删除已经存储的键的值 |
127.0.0.1:6379> set name chenzhiqiang
OK
127.0.0.1:6379> get name
"chenzhiqiang"
127.0.0.1:6379> get age # 获取不存的值返回nil,在和python交互中返回的是None
(nil)
127.0.0.1:6379> del name #删除,返回的是返回的删除的条目数
(integer) 1
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379>
与Python交互
redis和python交互:
# coding=utf8
import redis
con = redis.Redis() # 创建链接对象
con.set('hello', 'world') #使用set方法
response_hello = con.get('hello')
response_age = con.get('age')
print('hello的值:%s' % response_hello)
print('-------------')
print('age的值:%s' % response_age) # 获取不存在的值
返回:
python@ubuntu:~/Desktop$ python redis_test.py
hello的值:world
-------------
age的值:None
列表
redis支持链表结构,列表的底层是链表构成的。 一个列表结构可以有序的存储多个字符串。 和其他的编程语言一样,LPSUH和RPUSH分别将元素推入列表的左端和右端;LPOP和RPOP分别将元素从左端和右端弹出元素;LINDEX获取给定位置上的元素。
| 命令 | 行为 |
|---|---|
| LPUSH | 左端添加元素 |
| RPUSH | 右端添加元素 |
| LPOP | 从左端弹出元素 |
| RPOP | 从右端弹出元素 |
| LINDEX | 获取给定位置的元素 |
| LRANGE | 获取给定范围的所有元素 |
127.0.0.1:6379> rpush list-key item1
(integer) 1
127.0.0.1:6379> lpush list-key item2
(integer) 2
127.0.0.1:6379> lrange list-key 0 -1 # 注意添加的顺序,显示添加的右边的item1,再是左边的item2
1) "item2"
2) "item1"
127.0.0.1:6379> lindex list-key 1 # 指定索引获取元素
"item1"
127.0.0.1:6379> lpop list-key # 从左端弹出一个元素,一次只弹出一个元素
"item2"
127.0.0.1:6379> lrange list-key 0 -1
1) "item1"
127.0.0.1:6379>
与Python交互
和python 的交互中,列表返回的中括号的列表形式:
# coding=utf8
import redis
con = redis.Redis()
con.lpush('lits', 'item2')
con.rpush('list', 'item1')
response_list = con.lrange('list', 0 ,-1)
print(response_list)
输出:
python@ubuntu:~/Desktop$ python redis_test.py
['item1', 'item1']
集合
redis中列表和集合都是存储多个值的,但是,集合是不同存相同的值的,但是列表可以。另外,使用的方法名也是不同的。 redis的集合是使用的无序的方式存储元素,所以不能象列表一样从某一端将元素推入集合。
| 命令 | 行为 |
|---|---|
| SADD | 添加元素 |
| SREM | 如果给定的元素存在集合中,那就移除这个元素 |
| SISMEMBER | 检查某元素是否在集合中 |
| SMEMBERS | 返回所有的集合元素 |
| SINSERT | 交集计算 |
| SUNION | 并集计算 |
| SDIFF | 差集计算 |
SISMEMBER: 是 set is member 的缩写
SMEMBERS: 是 set members 的缩写
127.0.0.1:6379> sadd set-key item
(integer) 1
127.0.0.1:6379> sadd set-key item2
(integer) 1
127.0.0.1:6379> sadd set-key item # 添加一个已经存在的值,返回的是0
(integer) 0
127.0.0.1:6379> smembers set-key # 注意顺序,set是无序的,并不是按照添加的顺序返回的,
1) "item2"
2) "item"
127.0.0.1:6379> sismember set-key item # 查看存在的值,返回1,和python交互中返回的是True
(integer) 1
127.0.0.1:6379> sismember set-key item3 # 查看存在的值,返回0,和python交互中返回的是False
(integer) 0
与Python交互
和python交互,返回的是集合中包含的列表:
import redis
con = redis.Redis()
con.sadd('set-key', 'item')
con.sadd('set-key', 'item2')
response_set = con.smembers('set-key')
print(response_set)
输出:
python@ubuntu:~/Desktop$ python redis_test.py
set(['item2', 'item'])
散列
python的字典就是用散列表实现的。 散列也成哈希。
散列可以存储多个关键字对之间的映射。值,既可以是字符串也可以是数字,还可以对散列表的数字值进行自增或者自减操作。
实际,就是定义个键名(即是散列),在这个键名之下,又可以存的多个键值形式数据。
| 命令 | 行为 |
|---|---|
| HSET | 在散列里面关联给定的 键值对 |
| GSET | 获取指定的散列键的值 |
| HGETALL | 获取散列中所有的键值对 |
| HDEL | 如果给定的键存在散列表中,那就移除 |
127.0.0.1:6379> hset hash-key sub va1
(integer) 1
127.0.0.1:6379> hset hash-key sub2 va2
(integer) 1
127.0.0.1:6379> hset hash-key sub va1 # 添加一个已经存在的返回的是0
(integer) 0
127.0.0.1:6379> hgetall hash-key # 获取全部的键值对,键值是分开的。python交互中是以字典格式显示
1) "sub"
2) "va1"
3) "sub2"
4) "va2"
127.0.0.1:6379> hget hash-key sub # 获取某一个值
"va1"
127.0.0.1:6379> hdel hash-key sub 删除某一个值
(integer) 1
127.0.0.1:6379> hgetall hash-key
1) "sub2"
2) "va2"
与Python交互
注意的一点是,获取返回的键值的时候,python是以字典格式显示的。
# coding=utf8
import redis
con = redis.Redis()
con.hset('hash-key', 'sub2', 'va1')
con.hset('hash-key', 'sub3', 'va1')
response_hash_sub2 = con.hget('hash-key', 'sub2')
response_hash = con.hgetall('hash-key')
print(response_hash_sub2)
print(response_hash)
输出:
python@ubuntu:~/Desktop$ python redis_test.py
va1
{'sub2': 'va1', 'sub': 'va1', 'sub3': 'va1'}
有序集合
有序集合和散列一样,存储的都是键值对,有序集合的键成为成员,每个成员各不相同;有序集合的值成为分值,分值鼻血为浮点数。
有序集合是既可以根据成员(键) 访问元素【这点和散列一样】, 又可以根据分值以及分值的排列顺来访问元素的结构。
| 命令 | 行为 | redis-py |
|---|---|---|
| ZADD | 添加元素 | |
| ZRANGE | 根据有序排列中所处的位置,从有序集合获取多个元素 | |
| ZRANGEBYSCORE | 根据分值范围获取集合中的元素 | zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func= ) |
| ZREM | 如果成员存在于有序集合,移除 |
127.0.0.1:6379> zadd zet 22 m1 # 注意添加的顺序: 22是分值,m1是成员名
(integer) 1
127.0.0.1:6379> zadd zet m2 1212 # 如果顺序不对会报错
(error) ERR value is not a valid float
127.0.0.1:6379> zrange zet 0 -1 withscores # 返回的是成员以及分值
1) "m1"
2) "22"
127.0.0.1:6379> zrange zet 0 -1 # 不加withscores返回的只是成员名
1) "m1"
127.0.0.1:6379> zrangebyscore zet 0 800 withscores
1) "3"
2) "2"
3) "m1"
4) "22"
127.0.0.1:6379> zrangebyscore zet 0 2 withscores # 根据分值来筛选输出 0 2 就是分值范围
1) "3"
2) "2"
127.0.0.1:6379> zrangebyscore zet 0 1 withscores
(empty list or set)
重点:分值必须是数字,成员可以是也可以不是。
与Python交互
更详细的指令说明,查看这里
redis的发布订阅
订阅者(listener)负责订阅(channel); 发送者负责向频道发送二进制字符串消息。每当有消息发送给频道的时候,频道的订阅这都会收到消息。
| 命令 | 行为 |
|---|---|
| subscribe | 订阅给定的一个或多个频道 |
| unsubscribe | 取消订阅一个或多个频道 |
| publish | 向给定的频道发送消息 |
| psubsribe | 订阅给定模式匹配的所有频道 |
| punsubscribe | 退订给定的模式 |