概述
关于redis的数据结构
一、 String——字符串
String数据结构是简单的 key-value 类型,value 不仅可以是 String,也可以是数字(当数字类型用 Long 可以表示的时候encoding 就是整型,其他都存储在 sdshdr 当做字符串)。
1.设置值
set key value
2.获取值
get key
3.删除值
del key
二、 Hash——字典
在 Memcached 中,我们经常将一些结构化的信息打包成 hashmap,在客户端序列化后存储为一个字符串的值(一般是 JSON 格式),比如用户的昵称、年龄、性别、积分等。这时候在需要修改其中某一项时,通常需要将字符串(JSON)取出来,然后进行反序列化,修改某一项的值,再序列化成字符串(JSON)存储回去。简单修改一个属性就干这么多事情,消耗必定是很大的,也不适用于一些可能并发操作的场合(比如两个并发的操作都需要修改积分)。而 Redis 的 Hash 结构可以使你像在数据库中 Update 一个属性一样只修改某一项属性值。
1.设置值
hset key name value 设置一个对象的单个属性值
hmset key name1 value1 name2 value2…… 设置一个对象的多个属性值
2.获取值
hget key name 获取对象中一个属性的值
hmget key name1 name2…… 获取对象中多个属性的值
hgetall key 获取对象中所有属性和值
3.删除值
hdel key name 删除对象中指定属性的内容(属性名称和值一起删除)
del key 删除所有
三、List——列表
List类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表一样,我们可以在其头部(left)和尾部(right)添加新的元素。在插入时,如果该键并不存在,Redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。
》ArrayList使用数组方式存储数据,所以根据索引查询数据速度快,而新增或者删除元素时需要涉及到位移操作,所以比较慢。(存放的内容越多,速 度越慢)
》LinkedList使用双向链接方式存储数据,每个元素都记录前后元素的指针,所以插入、删除数据时只是更改前后元素的指针指向即可,速度非常快, 然后通过下标查询元素时需要从头开始索引,所以比较慢。(插入修改快,查询慢)
1.设置值:
左侧插入数据:lpush key value1 value2 value3……
例如:lpush mylist a b c d
执行指令:lrange mylist 0 3 【结果:d c b a 】
右侧插入数据:rpush key value1 value2 value3……
例如:rpush mylist 1 2 3 4
执行指令:lrange mylist 0 7 【结果:d c b a 1 2 3 4】
2.获取值:
lrange key startIndex endIndex
例如:lrange mylist 0 3 【结果:d c b a 】
lrange mylist 0 -2 【结果:d c b a 1 2 3】
使用最多的是查询所有的数据 lrange mylist 0 -1
3.删除值
从左侧删除数据:lpop key
例如:lpop mylist 返回的是左侧第一个数据(d)
lrange mylist 0 -1 结果:c b a 1 2 3 4
从右侧删除数据:rpop key
例如:rpop mylist 返回的是右侧第一个数据(4)
lrange mylist 0 -1 结果:c b a 1 2 3
4.查看元素的个数:llen key
llen mylist 结果:6
Set 就是一个集合,集合的概念就是一堆不重复值的组合。利用 Redis 提供的 Set 数据结构,可以存储一些集合性的数据。比如在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。因为 Redis 非常人性化的为集合提供了求交集、并集、差集等操作,那么就可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。
》共同好友、二度好友
》利用唯一性,可以统计访问网站的所有独立 IP
》好友推荐的时候,根据 tag 求交集,大于某个 threshold 就可以推荐
1.添加数据:【不要添加重复的数据,无法添加进去的】
sadd key value1 value2 value3 ……
例如:sadd myset a b c a c 返回的是添加数据的长度(3)
2.查看数据:
smembers key
例如:smembers myset 结果:a b c
3.删除
srem key value1
例如:srem myset c
判断某个元素是否存在
sismember key value1
例如:sismember myset c 结果:0
sismember myset a 结果:1
4.聚合操作差集
初始化数据:
myset: a b d 1
myset1: a c d 2
执行指令:sdiff myset myset1 b 1
执行指令:sdiff myset1 myset c 2
特点:前面有的数据,但是后面没有的数据
5.聚合操作交集
初始化数据:
myset: a b d 1
myset1: a c d 2
执行指令:sinter myset myset1 a d
执行指令:sinter myset1 myset a d
特点:前后都有的数据
6.聚合操作并集
初始化数据:
myset: a b d 1
myset1: a c d 2
执行指令:sunion myset myset1
执行指令:sunion myset1 myset
特点:前后数据相加,去掉重复的数据
五、 Sorted Set——有序集合
和Sets相比,Sorted Sets是将 Set 中的元素增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列,比如一个存储全班同学成绩的 Sorted Sets,其集合 value 可以是同学的学号,而 score 就可以是其考试得分,这样在数据插入集合的时候,就已经进行了天然的排序。另外还可以用 Sorted Sets 来做带权重的队列,比如普通消息的 score 为1,重要消息的 score 为2,然后工作线程可以选择按 score 的倒序来获取工作任务。让重要的任务优先执行。
》带有权重的元素,比如一个游戏的用户得分排行榜
》比较复杂的数据结构,一般用到的场景不算太多
1.设置值
zadd key score1 value1 score2 value2
例如:zadd mysort 50 zhangsan 80 lisi 100 wangwu 返回值为添加数据的个数
注意:value不能重复(重复的无法添加进去,如果分数变了,score会更新)
2.获取值:
zscore key value 查看指定元素的得分
例如:zscore mysort zhangsan 结果:50
zcard key 查看元素的长度
例如:zcard mysort 结果:3
3.删除:
zrem key value 删除指定的元素及分数
zrem mysort zhangsan 返回值是个数
删除多个:del key
4.范围查看
zrange key startIndex endIndex [withscores]
查询所有的
zrange key 0 -1 [withscores]
redis 其他功能使用场景
1、订阅-发布系统
Pub/Sub 从字面上理解就是发布(Publish)与订阅(Subscribe),在 Redis 中,你可以设定对某一个 key 值进行消息发布及消息订阅,当一个 key 值上进行了消息发布后,所有订阅它的客户端都会收到相应的消息。这一功能最明显的用法就是用作实时消息系统,比如普通的即时聊天,群聊等功能。
2、 事务——Transactions
谁说 NoSQL 都不支持事务,虽然 Redis 的 Transactions 提供的并不是严格的 ACID 的事务(比如一串用 EXEC 提交执行的命令,在执行中服务器宕机,那么会有一部分命令执行了,剩下的没执行),但是这个 Transactions 还是提供了基本的命令打包执行的功能(在服务器不出问题的情况下,可以保证一连串的命令是顺序在一起执行的,中间有会有其它客户端命令插进来执行)。Redis 还提供了一个 Watch 功能,你可以对一个 key 进行 Watch,然后再执行 Transactions,在这过程中,如果这个 Watched 的值进行了修改,那么这个 Transactions 会发现并拒绝执行。
3、取最新N个数据的操作
比如典型的取你网站的最新文章,通过下面方式,我们可以将最新的5000条评论的ID放在Redis的List集合中,并将超出集合部分从数据库获取
(1)使用LPUSHlatest.comments <ID>命令,向list集合中插入数据
(2)插入完成后再用LTRIMlatest.comments 0 5000命令使其永远只保存最近5000个ID
(3)然后我们在客户端获取某一页评论时可以用下面的逻辑(伪代码)
# 伪代码
FUNCTION get_latest_comments(start, num_items):
id_list =redis.lrange("latest.comments", start, start+num_items-1)
IF id_list.length <num_items
id_list =SQL_DB("SELECT ... ORDER BY time LIMIT ...")
END
RETURN id_list
END
如果你还有不同的筛选维度,比如某个分类的最新N条,那么你可以再建一个按此分类的List,只存ID的话,Redis是非常高效的。
4、排行榜应用,取TOP N操作
这个需求与上面需求的不同之处在于,前面操作以时间为权重,这个是以某个条件为权重,比如按顶的次数排序,这时候就需要我们的sortedset出 马了,将你要排序的值设置成sortedset的score,将具体的数据设置成相应的value,每次只需要执行一条ZADD命令即可。
5、需要精准设定过期时间的应用
比如你可以把上面说到的sortedset的score值设置成过期时间的时间戳,那么就可以简单地通过过期时间排序,定时清除过期数据了,不仅是清除 Redis中的过期数据,你完全可以把 Redis里这个过期时间当成是对数据库中数据的索引,用Redis来找出哪些数据需要过期删除,然后再精准地从数据库 中删除相应的记录。
6、计数器应用
Redis的命令都是原子性的,你可以轻松地利用INCR,DECR命令来构建计数器系统。
7、Uniq操作,获取某段时间所有数据排重值
这个使用Redis的set数据结构最合适了,只需要不断地将数据往set中扔就行了,set意为集合,所以会自动排重。
8、实时系统,反垃圾系统
通过上面说到的set功能,你可以知道一个终端用户是否进行了某个操作,可以找到其操作的集合并进行分析统计对比等。没有做不到,只有想不 到。
9、Pub/Sub构建实时消息系统
Redis的Pub/Sub系统可以构建实时的消息系统,比如很多用Pub/Sub构建的实时聊天系统的例子。
10、构建队列系统
使用list可以构建队列系统,使用sorted set甚至可以构建有优先级的队列系统。
最后
以上就是糊涂钢笔为你收集整理的Redis的数据结构和使用场景介绍的全部内容,希望文章能够帮你解决Redis的数据结构和使用场景介绍所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复