Redis入门-五种数据类型
Redis入门 - 五种数据类型
Redis所有的key(键)都是字符串。我们在谈基础数据结构时,讨论的是存储值的数据类型,主要包括常见的5种数据类型,分别是:字符串类型(String)、散列类型(Hash)、列表类型(List)、集合类型(Set)、有序集合类型(Zset)
Redis 数据结构简介
结构类型 | 结构存储的值 | 结构的读写能力 |
---|---|---|
String字符串 | 可以是字符串、整数或浮点数 | 对整个字符串或字符串的一部分进行操作;对整数或浮点数进行自增或自减操作; |
List列表 | 一个链表,链表上的每个节点都包含一个字符串 | 对链表的两端进行push和pop操作,读取单个或多个元素;根据值查找或删除元素; |
Set集合 | 包含字符串的无序集合 | 字符串的集合,包含基础的方法有看是否存在添加、获取、删除;还包含计算交集、并集、差集等 |
Hash散列 | 包含键值对的无序散列表 | 包含方法有添加、获取、删除单个元素 |
Zset有序集合 | 和散列一样,用于存储键值对 | 字符串成员与浮点数分数之间的有序映射;元素的排列顺序由分数的大小决定;包含方法有添加、获取、删除单个元素以及根据分值范围或成员来获取元素 |
基础数据结构详解
字符串类型(String)
String是redis中最基本的数据类型,一个key对应一个value
String类型是二进制安全的,意思是 redis 的 string 可以包含任何数据。如数字,字符串,jpg图片或者序列化的对象
- 命令使用
命令 | 简述 | 使用 |
---|---|---|
get | 获取存储在给定键中的值 | get name |
set | 设置存储在给定键中的值 | set name value |
setex | 存入键值对,timeout表示失效时间,单位s | setex key timeout value |
setnx | 如果key已经存在,不做操作, 如果key不存在,直接添加 | setnx key value |
del | 删除存储在给定键中的值 | del name |
incr | 将键存储的值加1 | incr key |
decr | 将键存储的值减1 | decr key |
incrby | 将键存储的值加上整数 | incrby key amount |
decrby | 将键存储的值减去整数 | decrby key amount |
ttl | 可以查询出当前的key还剩余多长时间过期 | ttl key |
mset | 批量存入键值对 | mset k1 v1 k2 v2 |
mget | 批量取出键值 | mget k1 k2 |
ttl 命令说明: 当查询 key 不存在时或者过期时,返回 -2 ,当 key 没有设置过期时间时,返回 -1
- 命令执行
127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> get hello
"world"
127.0.0.1:6379> del hello
(integer) 1
127.0.0.1:6379> get hello
(nil)
127.0.0.1:6379> set counter 1
OK
127.0.0.1:6379> get counter
"1"
127.0.0.1:6379> incr counter
(integer) 2
127.0.0.1:6379> get counter
"2"
127.0.0.1:6379> incrby counter 10
(integer) 12
127.0.0.1:6379> get counter
"12"
127.0.0.1:6379> decr counter
(integer) 11
127.0.0.1:6379> get counter
"11"
127.0.0.1:6379> decrby counter 10
(integer) 1
127.0.0.1:6379> get counter
"1"
127.0.0.1:6379> setex test 10 test
OK
127.0.0.1:6379> ttl test
(integer) 6
127.0.0.1:6379> ttl test
(integer) 2
127.0.0.1:6379> ttl test
(integer) -2
- 实战场景
- 缓存: 经典使用场景,把常用信息,字符串,图片或者视频等信息放到redis中,redis作为缓存层,mysql做持久化层,降低mysql的读写压力。
- 计数器:redis是单线程模型,一个命令执行完才会执行下一个,同时数据可以一步落地到其他的数据源。
- session:常见方案spring session + redis实现session共享
散列类型(Hash)
Hash类型是String类型的field和value的映射表,或者说是一个String集合
它特别适合存储对象,相比较而言,将一个对象存储在Hash类型里要比存储在String类型里占用更少的内存空间,并方便存储整个对象
- 命令使用
命令 | 简述 | 使用 |
---|---|---|
hset | 添加键值对 | hset key sub-key1 value1 |
hget | 获取指定散列键的值 | hget key key1 |
hgetall | 获取散列中包含的所有键值对 | hgetall key |
hdel | 如果给定键存在于散列中,那么就移除这个键 | hdel key sub-key1 |
hexists | 判断hash对象是含有某个键 | hexists key hashkey |
hincrby | 递增hashkey对应的值 | hincrby key hashkey 递增值 |
hlen | 获取hash对象键的数量 | hlen key |
hkeys | 获取hash对象的所有键 | hkeys key |
hvals | 获取hash对象的所有值 | hvals key |
- 命令执行
127.0.0.1:6379> hset has1 name zs age 12
(integer) 2
127.0.0.1:6379> hget has1 name
"zs"
127.0.0.1:6379> hgetall has1
1) "name"
2) "zs"
3) "age"
4) "12"
127.0.0.1:6379> hincrby has1 age 4
(integer) 16
127.0.0.1:6379> hdel has1 age
(integer) 1
127.0.0.1:6379> hgetall has1
1) "name"
2) "zs"
127.0.0.1:6379> hexists has1 name
(integer) 1
127.0.0.1:6379> hlen has1
(integer) 1
127.0.0.1:6379> hkeys has1
1) "name"
127.0.0.1:6379> hvals has1
1) "zs"
- 实战场景
- 缓存: 能直观,相比string更节省空间,的维护缓存信息,如用户信息,视频信息等
列表类型(List)
Redis中的List其实就是链表(Redis用双端链表实现List)按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
Redis中的List类似Java中的queue,也可以当做List来用
使用 List 结构,我们可以轻松地实现最新消息排队功能(比如新浪微博的TimeLine),List的另一个应用就是消息队列,可以利用List的 PUSH 操作,将任务存放在List中,然后工作线程再用 POP 操作将任务取出进行执行
- 命令使用
命令 | 简述 | 使用 |
---|---|---|
rpush | 将给定值推入到列表右端 | rpush key value |
lpush | 将给定值推入到列表左端 | lpush key value |
rpop | 从列表的右端弹出一个值,并返回被弹出的值 | rpop key |
lpop | 从列表的左端弹出一个值,并返回被弹出的值 | lpop key |
llen | 获取列表长度 | llen key |
lrange | 获取列表在给定范围上的所有值 | lrange key 0 -1 |
ltrim | 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素 | ltrim key start end |
lindex | 通过索引获取列表中的元素。你也可以使用负数下标,以 -1 表示列表的最后一个元素,以此类推。 | lindex key index |
使用列表的技巧
- lpush+lpop=Stack(栈)
- lpush+rpop=Queue(队列)
- lpush+ltrim=Capped Collection(有限集合)
- lpush+brpop=Message Queue(消息队列)
命令执行
127.0.0.1:6379> rpush list1 1 2 3 4
(integer) 4
127.0.0.1:6379> lrange list1 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> rpop list1
"4"
127.0.0.1:6379> lrange list1 0 -1
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> llen list1
(integer) 3
127.0.0.1:6379>
127.0.0.1:6379> ltrim list1 1 2
OK
127.0.0.1:6379>
127.0.0.1:6379> lrange list1 0 -1
1) "2"
2) "3"
- 实战场景
- 微博TimeLine: 有人发布微博,用lpush加入时间轴,展示新的列表信息。
- 消息队列
集合类型(Set)
Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据
Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)
- 命令使用
命令 | 简述 | 使用 |
---|---|---|
sadd | 向集合添加一个或多个成员 | sadd key value |
scard | 获取集合的成员数 | scard key |
smembers | 返回集合中的所有成员 | smembers key member |
sismember | 判断 member 元素是否是集合 key 的成员 | sismember key member |
srem | 删除set集合中的元素 | srem key value |
spop | 随机弹出集合中的元素 | spop key count |
srandmember | 随机获取set集合中元素 | srandmember key count |
127.0.0.1:6379> sadd set1 1 2 3 3 4
(integer) 4
127.0.0.1:6379> scard set1
(integer) 4
127.0.0.1:6379> smembers set1
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> sismember set1 5
(integer) 0
127.0.0.1:6379> sismember set1 4
(integer) 1
127.0.0.1:6379> spop set1
"1"
127.0.0.1:6379> smembers set1
1) "2"
2) "3"
3) "4"
127.0.0.1:6379> srem set1 3 4
(integer) 2
127.0.0.1:6379> smembers set1
1) "2"
- 集合我们可以取交集,并集,差集
命令 | 简述 | 使用 |
---|---|---|
sdiff | 返回key1中特有元素(差集) | sdiff key1 key2 |
sdiffstore | 返回key1中特有元素存入另一个set集合 | sdiffstore var key1 key2 |
sinter | 返回两个set集合的交集 | sinter key1 key2 |
sinterstore | 返回两个set集合的交集存入另一个set集合 | sinterstore var key1 key2 |
sunion | 返回两个set集合的并集 | sunion key1 key2 |
sunionstore | 返回两个set集合的并集存入另一个set集合 | sunionstore var key1 key2 |
smove | 把key1中的某元素移入key2中 | smove key1 key2 value |
127.0.0.1:6379> sadd key1 4 3 2 1
(integer) 4
127.0.0.1:6379> sadd key2 8 6 4 2
(integer) 4
127.0.0.1:6379> sdiff key1 key2
1) "1"
2) "3"
127.0.0.1:6379> sinter key1 key2
1) "2"
2) "4"
127.0.0.1:6379> sunion key1 key2
1) "1"
2) "2"
3) "3"
4) "4"
5) "6"
6) "8"
- 实战场景
- 标签(tag),给用户添加标签,或者用户给消息添加标签,这样有同一标签或者类似标签的可以给推荐关注的事或者关注的人。
- 点赞,或点踩,收藏等,可以放到set中实现
有序集合类型(Zset)
Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序
- 命令使用
命令 | 简述 | 使用 |
---|---|---|
zadd | 将一个带有给定分值的成员添加到哦有序集合里面 | zadd zset-key 178 member1 |
zrem | 如果给定元素成员存在于有序集合中,那么就移除这个元素 | zrem zset-key member1 |
zincrby | 追加名称对应的分数 | zincrby key score column |
zcount | 按照分数范围统计个数 | zcount key min max |
zrange | 按照分数升序输出名称 | zrange zset-key 0-1 withscores |
zrevrange | 按照分数降序输出名称 | zrevrange key start end |
zrank | 升序返回排名 | zrank key name |
zrevrank | 降序返回排名 | zrevrank key name |
- 命令执行
127.0.0.1:6379> zadd key4 140 aaa 150 bbb 145 ccc 132 ddd
(integer) 4
127.0.0.1:6379> zrange key4 0 -1
1) "ddd"
2) "aaa"
3) "ccc"
4) "bbb"
127.0.0.1:6379> zrange key4 0 -1 withscores
1) "ddd"
2) "132"
3) "aaa"
4) "140"
5) "ccc"
6) "145"
7) "bbb"
8) "150"
127.0.0.1:6379> zincrby key4 10 aaa
"150"
127.0.0.1:6379> zrange key4 0 -1 withscores
1) "ddd"
2) "132"
3) "ccc"
4) "145"
5) "aaa"
6) "150"
7) "bbb"
8) "150"
- 实战场景
- 排行榜:有序集合经典使用场景。例如小说视频等网站需要对用户上传的小说视频做排行榜,榜单可以按照用户关注数,更新时间,字数等打分,做排行