Redis数据结构
Redis数据结构介绍
Redis是一种高级的key-value的存储系统,其中value支持五种数据类型。
-
字符串(String)
-
哈希(hash)
-
字符串列表(list)
-
字符串集合(set)
-
有序字符串集合(sorted set)
而关于key的定义呢,需要注意的几点:
-
key不要太长,最好不要操作1024个字节,这不仅会消耗内存还会降低查找效率。
-
key不要太短,如果太短会降低key的可读性。
-
在项目中,key最好有一个统一的命名规范。
下面重点介绍五种类型:
-
存储string
字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这便意味着该类型存入和获取的数据相同。在Redis中字符串类型的Value最多可以容纳的数据长度是512M
常用命令
赋值
-
Set key value:设定key持有指定的字符串value,如果该key存在则进行覆盖操作,总是返回”OK”
Set name yuanwang
取值
-
get key :获取key的value。如果与该key关联的value不是String类型,redis将返回错误信息,因为get命令只能用于获取String value;如果改key不存在,返回(nil)
Get name
Get name1
-
Getset key value:先获取该key的值,然后在设置改key的值。
Getset name baidu
Get name
删除
-
Del key:删除指定key
Set age 18
Get age
Del age
Get age
数值增减
-
Incr key:将指定的key的value原子性的递增1,如果该key不存在,其初始值为0,在incr之后其值为1。如果value的值不能转成整型,如hello,该操作将执行失败并返回相应的错误信息.
-
Decr key :将指定的key的value原子性的递减1,如果该key不存在,其初始值为0,在incr之后其值为-1,如果value的值不能转成整型,如hello,该操作将执行失败并返回相应的错误信息.
追加
-
Append key value:拼凑字符串。如果该key存在,则在原有的value后追加该值;如果该key不存在,则重新创建一个key/value.
-
存储hash
Redis中的hash类型可以看成具有String key和String Value的map容器。所以该类型非常适合于存储值对象的信息。如username,password和age等,如果hash中包括很少的字段,那么该类型的数据也将仅占用很少的磁盘空间。每一个Hash可以存储4294967295个键值对。
常用命令
赋值
-
Hset key field value:为指定的key设定field/value对(键值对)。
-
Hmset key field value[field2 value2…]:设置key中的多个field/value
取值
-
Hget key field :返回指定的key中的field的值
-
Hmget key field1 field2…:获取key中的多个field值
-
Hgetall key:获取key中的所有filed-value
删除
-
Hdel key field[field…] :可以删除一个或多个字段,返回值是被删除的字段个数
Del key :通用
增加数字
-
Hincrby key field incement:设置key中filed的值增加increment,如age增加20
扩展
-
Hexists key field:判断指定的key中的field 是否存在。
-
Hlen key:获取key所包含的field 数量
-
Hkeys key :获取所有的key
-
存储list
在redis中,List类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表一样,我们可以在其头部(left)和尾部(right)添加新的元素。在插入时,如果该键并不存在,redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。List中可以包含的最大元素数量是4294967295.
在元素插入和删除的效率视角来看,如果我们是在链表的两头插入或删除元素,这将会是非常高效的操作,即使链表中已经存储了百万条记录,该操作也可以在常量时间内完成。如果元素插入或删除操作是作用于链表中间,那将会是非常低效的。
回顾基础:
arrayList与linkedList区别?
双向链表中添加数据
双向链表中删除数据
常用命令
两端添加
-
Lpush key values[value1 value2…]:在指定的key所关联的list的头部插入所有的values,如果该key不存在,该命令在插入的之前创建一个与该key关联的空链表,之后再向该链表的头部插入数据。插入成功,返回元素的个数。
-
Rpush key values[value1、value2…]:在该list的尾部添加元素。
查看列表
-
Lrange key start end: 获取链表中从start到end的元素的值,start,end从0开始计数;也可为负数,若为-1则表示链表尾部的元素,-2则表示倒数第二个,以此类推….
两端弹出
-
Lpop key :返回并弹出指定的key关联的链表中的第一个元素,即头部元素。如果该key不存在,返回nil;若key存在,则返回链表的头部元素。
-
Rpop key :从尾部弹出元素
获取列表中元素的个数
-
Llen key:返回指定的key关联的链表中的元素的数量。
删除
-
Lrem key count value: 删除count 个值为value的元素,如果count大于0,从头向尾遍历并删除count个值为value的元素,如果count小于0,则从尾向头遍历并删除。如果count等于0,则删除链表中所有等于value的元素。
初始化数据
从头删除,2个数字‘3’
从尾删除,
Lrem mylist3 -2 1
删除所有数字的‘2’
Lrem mylist 0 2
扩展
-
Lpushx key value:仅当参数中指定的key存在时,向关联的list的头部插入value,如果不存在,将不进行插入。
-
Rpushx key value:在list尾部添加元素
索引插入
-
Lset key index value:设置链表中的index的角标的元素值,0代表链表的头元素,-1代表链表的尾元素。操作链表的角标不存在则抛异常。
-
Linsert key before |after pivot value: 在pivot元素前或者后插入value这个元素。
Rpoplpush resource destination:将链表中的尾部元素弹出并添加到头部。
-
将mylist5右端弹出,压入到mylist6 左边
-
将mylist6右端数据弹出,压入到左端
应用范围
lists的应用相当广泛,随便举几个例子:
1.我们可以利用lists来实现一个消息队列,而且可以确保先后顺序,不必像MySQL那样还需要通过ORDER BY来进行排序。
2.利用LRANGE还可以很方便的实现分页的功能。
3.在博客系统中,每个博文的评论也可以存入一个单独的list中。
4.存储set
在redis中,我们可以将set类型看作为没有排序的字符集合,和list类型一样,我们也可以在该类型的数据值上执行添加、删除或判断某一元素是否存在等操作。
和list类型不同的是,set集合中不允许出现重复的元素,这一点和咱java中的hashSet是完全相同的。和list类型相比,set类型在功能上还存在着一个非常重要的特性,即在服务器端完成多个sets之间的聚合计算操作,如unions、intersections和differences。由于这些操作均在服务端完成,因此效率极高,而且也节省了大量的网络IO开销。
常用命令
添加/删除元素
-
Sadd key values[value1、value2…]:向set中添加数据,如果该key的值已有则不会重复添加
-
Srem key members[member1、member2…]:删除set中指定的成员
Sadd myset 1 2 3
Srem myset 1 2
获取集合中的元素
-
Smembers key:获取set中所有的成员
Smembers myset
集合的差集运算
-
Sdiff key1 key2…:返回key1与key2中相差的成员,而且与key的顺序有关。即返回差集。(属于A并且不属于B的元素构成的集合)
Sadd mya1 a b c
Sadd myb1 a c 1 2
Sdiff mya1 myb1
集合的交集运算
-
Sinter key1 key2 key3…:返回交集(属于A且属于B的元素构成的集合)
Sadd mya2 a b c
Sadd myb2 a c 1 2
Sinter mya2 myb2
集合的并集运算
-
Sunion key1 key2 key3…:返回并集(属于A或者属于B的元素构成的集合)
Sadd mya3 a b c
Sadd myb3 a c 1 2
Sunion mya3 myb3
应用范围
1). 可以使用Redis的Set数据类型跟踪一些唯一性数据,比如访问某一博客的唯一IP地址信息。对于此场景,我们仅需在每次访问该博客时将访问者的IP存入Redis中,Set数据类型会自动保证IP地址的唯一性。
2). 充分利用Set类型的服务端聚合操作方便、高效的特性,可以用于维护数据对象之间的关联关系。比如所有购买某一电子设备的客户ID被存储在一个指定的Set中,而购买另外一种电子产品的客户ID被存储在另外一个Set中,如果此时我们想获取有哪些客户同时购买了这两种商品时,Set的intersections命令就可以充分发挥它的方便和效率的优势了。
5.存储sortedset
Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复.
常用命令
添加元素
-
Zadd key score member score2 member2….: 将所有成员以及该成员的分数存放到sorted-set中。如果该元素已经存在则会用新的分数替换原有的分数
Zadd mysort 20 zhangsan 80 lisi 90 wangwu
Zadd mysort 100 zhangsan
Zadd mysort 50 jack
获得元素
-
Zscore key member:返回指定成员的分数
Zscore mysort zhangsan
-
Zcard key:获取集合中的成员数量
Zcard mysort
删除元素
-
Zrem key member[member…]:移除集合中指定的成员,可以指定多个成员。
Zrem mysort jack wangwu
Zcard mysort
范围查询
-
Zrange key start end[withscores]:获取集合中角标为start-end的成员,[withscores]表示包含其分数
Zadd mysort 85 jack 95 rose
Zrange mysort 0 -1
Zrange mysort 0 -1 withscores
-
Zrevrange key start stop [withscores]:照元素分数从大到小的顺序返回索引从start到stop之间的所有元素(包含两端的元素)
Zrevrange mysort 0 -1 withscores