Redis基础数据结构

Redis一共5种数据结构,分别是string(字符串)、list(列表)、set(集合)、hash(哈希)、zset(有序集合) 所有的数据结构都是以唯一的 key 字符串作为名称,然后通过这个唯一 key 值来获取相应的 value 数据。不同类型的数据结 构的差异就在于 value 的结构不一样。

string(字符串)

字符串是最简单的数据结构,但是应用场景非常广泛,很多场景中都是以字符串的形式缓存到redis中,例如存储用户信息,通过json序列化之后存入redis中,然后取的时候再将该字符串反序列化即可取得用户信息。
redis的字符串是动态字符串是可以动态修改的,这里区别java中的字符串,java中的字符串是不可修改的。
其采用预分配冗余空间的方式来减少内存的频繁分配,换句话说就是每个字符串都有一个分配好的空间capacity,这个空间大小一般是大于实际字符串的大小。当字符串长度小于1M的时候,内部扩容都是直接扩容capacity的倍数,当字符串长度大于1M的时候,扩容的时候是扩容1M的倍数。字符串最大长度是512M

//新增key
127.0.0.1:6379> set name xiaoming
OK
//查询key
127.0.0.1:6379> get name
"xiaoming"
//修改key
127.0.0.1:6379> set name xiaohong
OK
127.0.0.1:6379> get name
"xiaohong"
//删除key
127.0.0.1:6379> del name
(integer) 1 //返回数字1表示操作成功
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> del name
(integer) 0 //返回数字0表示修改失败
//批量操作可以减少网络耗时开销
127.0.0.1:6379> mset name xiaoming age 18
OK
127.0.0.1:6379> mget name age
1) "xiaoming"
2) "18"
127.0.0.1:6379> mset name xiaohong age 20
OK
127.0.0.1:6379> mget name age
1) "xiaohong"
2) "20"
127.0.0.1:6379> del name age
(integer) 2
127.0.0.1:6379> mget name age
1) (nil)
2) (nil)
127.0.0.1:6379> del name age
(integer) 0

list(列表)

Redis 的列表相当于 Java 语言里面的 LinkedList,其底层是链表。这意味着list 的插入和删除操作非常快,时间复杂度为 O(1),但是查询很慢,时间复杂度为 O(n)。因为每查询一个值都要先找到这个值前面的节点然后才能获得这个节点的值。当list的最后一个值删除之后,这个list结构就会被自动删除,内存也会被回收。

127.0.0.1:6379> rpush animals tiger monkey rabbit
(integer) 3
127.0.0.1:6379> llen animals
(integer) 3
127.0.0.1:6379> lpop animals //从左侧取出
"tiger"
127.0.0.1:6379> rpop animals //从右侧取出
"rabbit"
127.0.0.1:6379> lpop animals
"monkey"
127.0.0.1:6379>
127.0.0.1:6379> lpop animals
(nil)
127.0.0.1:6379> del animals //无法直接删除该key
(integer) 0

hash(哈希)

Redis中的字典相当于java中的hashMap,其底层实现是类似的都是散列结构(数组+链表),不同的是Redis中的字典值只能是字符串,另外就是refresh操作方式不太一样吗,Redis为了高性能,不堵塞服务采用了渐进式rehash策略
渐进式rehash策略:在rehash的同时,会同时保留新、旧两个hash结构,查询的时候也会查询两个,如果新的hash结构中有数据则采用新hash结构的数据否则采用旧的数据,在后续的过程中慢慢讲旧hash的数据全部迁移到新hash中。
当 hash 移除了最后一个元素之后,该数据结构自动被删除,内存被回收。
hash 结构也可以用来存储用户信息,不同于字符串一次性需要全部序列化整个对象, hash 可以对用户结构中的每个字段单独存储。这样当我们需要获取用户信息时可以进行部分获取。而以整个字符串的形式去保存用户信息的话就只能一次性全部读取,这样就会比较浪费网络流量。
hash 也有缺点,hash 结构的存储消耗要高于单个字符串,到底该使用 hash 还是字符串,需要根据实际情况再三权衡

127.0.0.1:6379> hset people age 18
(integer) 1
127.0.0.1:6379> hset people sex 1
(integer) 1
127.0.0.1:6379> hset people name xiaoming
(integer) 1
127.0.0.1:6379> hget people name
"xiaoming"
127.0.0.1:6379> hgetall people //字段名称和字段值是交替出现的
1) "age"
2) "18"
3) "sex"
4) "1"
5) "name"
6) "xiaoming"
127.0.0.1:6379> hset people age 20 //更新操作成功返回0
(integer) 0
127.0.0.1:6379> hget people age
"20"
127.0.0.1:6379> hmset people age 21 name xiaohong sex 0
OK
127.0.0.1:6379> hgetall people
1) "age"
2) "21"
3) "sex"
4) "0"
5) "name"
6) "xiaohong"

set(集合)

Redis 的集合相当于 Java 语言里面的 HashSet,它内部的键值对是无序的唯一的。它的内部实现相当于一个特殊的字典,字典中所有的 value 都是一个值 NULL。当集合中最后一个元素移除之后,数据结构自动删除,内存被回收。

127.0.0.1:6379> sadd animals monkey tiger dog
(integer) 1
127.0.0.1:6379> smembers animals //查询所有,注意此时的顺序和插入顺序不同因为其是无序的
1) "monkey"
2) "dog"
3) "tiger"
127.0.0.1:6379> sismember animals dog //判断是否存在
(integer) 1
127.0.0.1:6379> sismember animals bird
(integer) 0
127.0.0.1:6379> scard animals //统计集合中的元素个数
(integer) 3
127.0.0.1:6379> spop animals //弹出一个元素
"dog"
127.0.0.1:6379> scard animals
(integer) 2
127.0.0.1:6379> smembers animals
1) "monkey"
2) "tiger"

zset(有序列表)

zset的排序功能是通过跳表实现的结构比较特殊。
zset 类似于 Java 的 SortedSet 和 HashMap 的结合体,一方面它是一个 set,保证了内部 value 的唯一性,另一方面它可以给每个 value 赋予一个 score,代表这个 value 的排序权重。它的内部实现用的是一种叫着「跳跃列表」的数据结构。 zset 中最后一个 value 被移除后,数据结构自动删除,内存被回收。

127.0.0.1:6379> zadd animals 1.0 "dog" //添加数据:key score value
(integer) 1
127.0.0.1:6379> zadd animals 2.0 "tiger"
(integer) 1
127.0.0.1:6379> zadd animals 3.0 "bird"
(integer) 1
127.0.0.1:6379> zrange animals 0 -1 //按顺序排列(-1表示最后一位)
1) "dog"
2) "tiger"
3) "bird"
127.0.0.1:6379> zrevrange animals 0 -1 //倒序排列
1) "bird"
2) "tiger"
3) "dog"
127.0.0.1:6379> zcard animals //统计集合中的个数
(integer) 3
127.0.0.1:6379> zscore animals dog //获取指定value的权重
"1"
127.0.0.1:6379> zrank animals dog  //获取指定value的排名(从0开始计算)
(integer) 0
127.0.0.1:6379> zrank animals tiger
(integer) 1
127.0.0.1:6379> zrangebyscore animals 0 3.0 //根据指定权重进行排列
1) "dog"
2) "tiger"
3) "bird"
127.0.0.1:6379> zrangebyscore animals 0 2.0
1) "dog"
2) "tiger"
127.0.0.1:6379> zrem animals dog //移除指定value的元素
(integer) 1
127.0.0.1:6379> zrangebyscore animals 0 3.0
1) "tiger"
2) "bird"
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值