本文主要介绍了Redis中5种基本的数据结构,以及相应的数据操作命令。
Redis基本数据结构
Redis是键值对(Key-Value)存储的非关系型数据库,存储形式可以类比Python中的字典。
其中,键的类型是字符串,而值的类型常见的有以下5种:
- 字符串(String)
- 哈希(Hash)
- 列表(List)
- 集合(Set)
- 有序集合(Sorted Set)
数据库操作命令
在介绍5种基本数据结构之前,先简单了解一下Redis数据库的基本操作。
安装配置好的Redis,默认是有16个数据库的,而且,这16个数据库的名称是由0-15命名的,我们可以通过以下命令进行查询数据库数量:
代码语言:javascript复制CONFIG GET databases
默认情况下,我们选中的是0
数据库,可以通过以下命令进行切换:
SELECT db
可以看到,我们成功切换到1
数据库:
Python连接Redis数据库
讲完Redis数据库的简单操作,我们先讲解一下如何通过Python连接Redis数据库,方便后面对命令行操作Redis和Python操作Redis进行对比。
Pyton连接Redis服务也非常简单,只需要通过redis.StrictRedis
方法即可:
import redis
# 如果有设置redis密码,那么在连接时则需要传入"password"参数
r = redis.StrictRedis(host='localhost', port=6379, db=1)
可以看到,我们不仅成功的连接上了Redis,同时还选择了1
数据库:
接下来我们开始介绍Redis的5种基本数据结构。
String 字符串
简介
字符串的特性:
- string是redis最基本的类型;
- 最大能存储512MB的数据;
- string类型是二进制安全的,即可以为任何数据,比如数字、图片、序列化对象等。
数据操作
新增(插入数据)
设置键值:
代码语言:javascript复制SET key value
设置key=name, value="data"
:
同时设置多个键值:
代码语言:javascript复制MSET key value [key value ...]
设置k1:v1, k2:v2, k3:v3
共3对键值对:
查询
接下来查询一下刚刚新增的数据。
根据键获取值:
代码语言:javascript复制GET key
如果不存在此键则返回nil
:
同时根据多个键获取多个值:
代码语言:javascript复制MGET key [key ...]
更新
追加值(在字符串后面增加):
代码语言:javascript复制APPEND key value
往刚刚名称为name
的key后面添加字符串,并查询修改结果:
GETSET
:获取旧值并设置新值。
GETSET
命令就像GET
命令和SET
命令的组合版本,GETSET
首先获取字符串键目前已有的值,接着为键设置新值,最后把之前获取到的旧值返回给用户:
GETSET key new_value
把“12”替换成“123”:
运算
前提要求:值是数字的才可以进行运算操作。
将key对应的value加1:
代码语言:javascript复制INCR key
将key对应的value加整数increment
:
INCRBY key increment
先设置number=1
,然后再分别 1
, 10
:
将key对应的value减1:
代码语言:javascript复制DECR key
将key对应的value减整数decrement
:
DECRBY key decrement
操作同加法,不再进行演示。
其他操作
获取字符串值的字节长度:
代码语言:javascript复制STRLEN key
查询刚刚修改后的number
的值的长度:
Python操作
新增和查询键值对:
代码语言:javascript复制r.set("number", 123) # 新增键值对
r.get("number") # 查询键
Output:
代码语言:javascript复制b'123'
多键值对的同时操作:
代码语言:javascript复制r.mset({"k1": 1, "k2": "2"}) # 注意:多对键值对需要以字典形式传入
r.mget(["k1", "k2"])
Output:
代码语言:javascript复制[b'1', b'2']
键命令
主要介绍跟键key
相关的一些常用命令。
查找键,参数支持正则:
代码语言:javascript复制KEYS pattern
判断键是否存在,如果存在返回1,不存在返回0:
代码语言:javascript复制EXISTS key [key ...]
查看键对应的value
的类型:
TYPE key
可以看到,number
虽然是可以进行运算的,但是实际上还是以“string”形式进行存储的:
删除键及对应的值:
代码语言:javascript复制DEL key [key ...]
删除k1
及对应的值:
设置键值对的过期时间(以秒为单位):
创建时没有设置过期时间则一直存在,直到使用DEL移除。
代码语言:javascript复制EXPIRE key seconds
查看有效时间(以秒为单位):
代码语言:javascript复制TTL key
Hash 哈希/散列
简介
Hash
用于存储对象,对象的格式为键值对,可以类比为Pyton中的字典嵌套字典。
数据操作
新增(插入数据)
同时设置一个或多个属性:
代码语言:javascript复制HSET key field value [field value ...]
# 可以理解为下面这种结构
key: {
field: value
}
查询
获取一个属性的值:
代码语言:javascript复制HGET key field
获取多个属性的值:
代码语言:javascript复制HMGET key field [field ...]
注意这里的查询和string类型不同,需要具体到属性名:
获取所有属性:
代码语言:javascript复制HKEYS key
获取所有值:
代码语言:javascript复制HVALS key
获取所有属性和对应值:
代码语言:javascript复制HGETALL key
获取属性的个数:
代码语言:javascript复制HLEN key
获取属性的长度:
代码语言:javascript复制HLEN key
判断属性是否存在:
代码语言:javascript复制HEXISTS key field
删除
删除属性及对应值:
代码语言:javascript复制HDEL key field [field ...]
Python操作
代码语言:javascript复制# 一次设置多个属性
r.hset('student', mapping={"name": "xiaoming", "age": 18})
# 一次查询一个属性
r.hget('student', 'name')
# 一次查询多个属性
r.hmget('student', ['name', 'age'])
List 列表
简介
列表特性:
- 列表的元素类型为string;
- 按照插入顺序排序;
- 可在列表的头部或者尾部添加元素。
数据操作
新增
插入数据:
代码语言:javascript复制# 在头部(左边)插入数据
LPUSH key value [value ...]
# 在尾部(右边)插入数据
RPUSH key value [value ...]
注意最终列表元素的顺序,LPUSH
越晚插入的排在越前面:
在一个元素的前|后插入新元素:
代码语言:javascript复制LINSERT key BEFORE|AFTER pivot value
在s1
前面插入s0
:
设置指定索引的元素值:
说明:索引从0开始,负数表示从尾部开始。
代码语言:javascript复制LSET key index value
把索引0位置的元素替换为“s5”:
查询
返回存储在 key 的列表里指定范围内的元素:
代码语言:javascript复制LRANGE key start stop
-1
表示最后一位元素,所以0 -1
表示获取所有元素,这一点和Python的列表一样。
返回列表里索引对应的元素:
代码语言:javascript复制LINDEX key index
返回存储在 key 里的list的长度:
代码语言:javascript复制LLEN key
更新
裁剪列表,改为原集合的一个子集,相当于Python中列表进行了切片和重新赋值两个操作:
代码语言:javascript复制LTRIM key start stop
删除
移除第一个元素:
代码语言:javascript复制# 移除并且返回 key 对应的 list 的第一个元素(左边第一个元素)
LPOP key
# 移除并返回存于 key 的 list 的最后一个元素(右边第一个元素)
RPOP key
移除所有元素:
说明:只要start
的数值比end
的数值大即可,且要求数值都为正数。
LTRIM key 1 0
Python操作
从左边插入一个元素:
代码语言:javascript复制r.lpush("list0", "s1")
r.lrange("list0", 0, -1)
Output:
代码语言:javascript复制[b's1']
从右边插入一个元素:
代码语言:javascript复制r.rpush("list0", "s2")
r.lrange("list0", 0, -1)
Output:
代码语言:javascript复制[b's1', b's2']
Set 无序集合
简介
Set的特性:
- 没有顺序;
- 元素为string类型;
- 元素具有唯一性,不重复(这一点类似Python的
set
)。
数据操作
新增
添加元素:
代码语言:javascript复制SADD key member [member ...]
查询
返回集合所有的元素:
代码语言:javascript复制SMEMBERS key
返回集合元素个数(长度):
代码语言:javascript复制SCARD key
计算
先准备好两个集合:
代码语言:javascript复制# set0
("s1", "s2")
# set1
("s2", "s3", "s4")
交集:
代码语言:javascript复制SINTER key [key ...]
差集:
代码语言:javascript复制SDIFF key [key ...]
并集:
代码语言:javascript复制SUNION key [key ...]
判断元素是否在集合中:
代码语言:javascript复制SISMEMBER key member
Python操作
添加元素:
代码语言:javascript复制r.sadd("set0", "s1", "s2")
r.smembers("set0")
Output:
代码语言:javascript复制{b's1', b's2'}
计算集合:
代码语言:javascript复制r.sinter("set0", "set1") # 交集
r.sdiff("set0", "set1") # 差集
r.sunion("set0", "set1") # 并集
Sorted Set 有序集合
简介
Sorted Set的特性:
- 元素为string类型;
- 元素具有唯一性,不重复;
- 元素之间有序,每个元素都会关联一个double类型的
score
,表示权重,通过权重将元素从小到大排序,不同元素之间的权重可以相同。
数据操作
新增
添加(score
参数表示顺序,数字越小,排名越前):
ZADD key score member [score member ...]
查询
返回指定范围内的元素:
代码语言:javascript复制# 增加 [WITHSCORES] 参数能同时显示权重和元素
ZRANGE key start stop [WITHSCORES]
新增zset0
并且查询所有元素,同时插入两个score
相同的a
和b
,可以看到成功的插入了3个元素:
返回元素个数:
代码语言:javascript复制ZCARD key
返回有序集key
中,score
值在min
和max
之间的成员个数:
ZCOUNT key min max
返回有序集key
中,指定成员member
的score
值:
ZSCORE key member
Python操作
和命令行输入的命令相同,新增一个有序集合,并进行查询:
代码语言:javascript复制# 插入元素以字典形式表示,key对应元素,value对应score
r.zadd("zset0", {"a": 1, "b": 1, "c": 2})
r.zrange("zset0", 0, -1, withscores=True)
Output:
代码语言:javascript复制[(b'a', 1.0), (b'b', 1.0), (b'c', 2.0)]
小结
至此,Redis中最基础的数据结构我们已经介绍完毕,最后总结一下文章介绍的所有内容:
- 常用键命令;
- Python连接和操作Redis数据库;
- 5种基本的数据结构:字符串、哈希、列表、无序集合和有序集合,及其相应的数据操作命令。