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”
![](https://app.yinxiang.com/shard/s71/res/255fb65b-9b33-4c6e-9513-e7c0cabac778.png)
Set name yuanwang
取值
-
get key :获取key的value。如果与该key关联的value不是String类型,redis将返回错误信息,因为get命令只能用于获取String value;如果改key不存在,返回(nil)
![](https://app.yinxiang.com/shard/s71/res/b39f7be0-a55a-4fa0-a27e-6fbb6121078b.png)
![](https://app.yinxiang.com/shard/s71/res/8578c29c-6ed0-4cd6-8691-9e8d3366b7f2.png)
Get name
Get name1
-
Getset key value:先获取该key的值,然后在设置改key的值。
![](https://app.yinxiang.com/shard/s71/res/7a82f5d0-9c98-4f81-9e7a-d5d1f2ebd4a5.png)
Getset name baidu
Get name
删除
-
Del key:删除指定key
![](https://app.yinxiang.com/shard/s71/res/2611de25-285a-482a-98d2-7701d86d120b.png)
Set age 18
Get age
Del age
Get age
数值增减
-
Incr key:将指定的key的value原子性的递增1,如果该key不存在,其初始值为0,在incr之后其值为1。如果value的值不能转成整型,如hello,该操作将执行失败并返回相应的错误信息.
![](https://app.yinxiang.com/shard/s71/res/00d51ecd-c9b3-4469-9722-8c972238b6a1.png)
-
Decr key :将指定的key的value原子性的递减1,如果该key不存在,其初始值为0,在incr之后其值为-1,如果value的值不能转成整型,如hello,该操作将执行失败并返回相应的错误信息.
![](https://app.yinxiang.com/shard/s71/res/8ac672fc-ba52-43fe-b18f-2c14446c8a54.png)
追加
-
Append key value:拼凑字符串。如果该key存在,则在原有的value后追加该值;如果该key不存在,则重新创建一个key/value.
![](https://app.yinxiang.com/shard/s71/res/ac227424-210a-4b2f-b5fe-12c43eb0a897.png)
-
存储hash
Redis中的hash类型可以看成具有String key和String Value的map容器。所以该类型非常适合于存储值对象的信息。如username,password和age等,如果hash中包括很少的字段,那么该类型的数据也将仅占用很少的磁盘空间。每一个Hash可以存储4294967295个键值对。
常用命令
赋值
-
Hset key field value:为指定的key设定field/value对(键值对)。
![](https://app.yinxiang.com/shard/s71/res/204a7080-b4f6-4d0f-ad23-3f0362117fc6.png)
-
Hmset key field value[field2 value2…]:设置key中的多个field/value
![](https://app.yinxiang.com/shard/s71/res/b56ac4f7-46bd-4bb4-8d62-cc75cdcb777f.png)
取值
-
Hget key field :返回指定的key中的field的值
![](https://app.yinxiang.com/shard/s71/res/37d21402-4949-4a39-92e6-d2a34fdfff7a.png)
-
Hmget key field1 field2…:获取key中的多个field值
![](https://app.yinxiang.com/shard/s71/res/c702a236-9a71-4f9f-809f-462f57ffffaf.png)
-
Hgetall key:获取key中的所有filed-value
![](https://app.yinxiang.com/shard/s71/res/a4f3a0cd-eed6-4eb5-a7bb-36e76247a86e.png)
删除
-
Hdel key field[field…] :可以删除一个或多个字段,返回值是被删除的字段个数
![](https://app.yinxiang.com/shard/s71/res/9486d360-8235-4ec4-afaf-89dc1d384015.png)
Del key :通用
增加数字
-
Hincrby key field incement:设置key中filed的值增加increment,如age增加20
![](https://app.yinxiang.com/shard/s71/res/8b2c5ae2-f7eb-4692-812a-9aa679f735c2.png)
扩展
-
Hexists key field:判断指定的key中的field 是否存在。
![](https://app.yinxiang.com/shard/s71/res/ecb20ecc-1760-4ddb-ad69-070a05d26967.png)
-
Hlen key:获取key所包含的field 数量
![](https://app.yinxiang.com/shard/s71/res/734343fd-2a40-46fe-a89c-a27e865aa815.png)
-
Hkeys key :获取所有的key
![](https://app.yinxiang.com/shard/s71/res/6ddfbe10-847f-499b-9151-be7cc9e4fbaa.png)
-
存储list
在redis中,List类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表一样,我们可以在其头部(left)和尾部(right)添加新的元素。在插入时,如果该键并不存在,redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。List中可以包含的最大元素数量是4294967295.
在元素插入和删除的效率视角来看,如果我们是在链表的两头插入或删除元素,这将会是非常高效的操作,即使链表中已经存储了百万条记录,该操作也可以在常量时间内完成。如果元素插入或删除操作是作用于链表中间,那将会是非常低效的。
回顾基础:
arrayList与linkedList区别?
双向链表中添加数据
![](https://app.yinxiang.com/shard/s71/res/cd952c6e-386f-49ad-a1ff-10b74c5dcbd7.png)
双向链表中删除数据
![](https://app.yinxiang.com/shard/s71/res/363cd858-46ab-471b-bb72-0408454807c5.png)
常用命令
两端添加
-
Lpush key values[value1 value2…]:在指定的key所关联的list的头部插入所有的values,如果该key不存在,该命令在插入的之前创建一个与该key关联的空链表,之后再向该链表的头部插入数据。插入成功,返回元素的个数。
![](https://app.yinxiang.com/shard/s71/res/1553cb96-c70f-4831-bae3-0d3f8af9fb16.png)
-
Rpush key values[value1、value2…]:在该list的尾部添加元素。
![](https://app.yinxiang.com/shard/s71/res/f6ef211c-5ac9-4cc5-9d72-9127c2e89888.png)
查看列表
-
Lrange key start end: 获取链表中从start到end的元素的值,start,end从0开始计数;也可为负数,若为-1则表示链表尾部的元素,-2则表示倒数第二个,以此类推….
![](https://app.yinxiang.com/shard/s71/res/c9a6def3-8c8a-4c48-86a1-768258a3c781.png)
两端弹出
-
Lpop key :返回并弹出指定的key关联的链表中的第一个元素,即头部元素。如果该key不存在,返回nil;若key存在,则返回链表的头部元素。
![](https://app.yinxiang.com/shard/s71/res/9964eec1-a714-434f-98ce-2519843a3b67.png)
-
Rpop key :从尾部弹出元素
![](https://app.yinxiang.com/shard/s71/res/c732abea-3590-48f0-9f6f-670ccf7594e0.png)
![](https://app.yinxiang.com/shard/s71/res/a0de61f3-36ba-4416-bc83-d7d388fc759f.png)
获取列表中元素的个数
-
Llen key:返回指定的key关联的链表中的元素的数量。
![](https://app.yinxiang.com/shard/s71/res/fb05e709-364e-4667-b738-00624b6051d5.png)
删除
-
Lrem key count value: 删除count 个值为value的元素,如果count大于0,从头向尾遍历并删除count个值为value的元素,如果count小于0,则从尾向头遍历并删除。如果count等于0,则删除链表中所有等于value的元素。
初始化数据
![](https://app.yinxiang.com/shard/s71/res/55b29782-e9dd-48cb-9a38-64262bbd7845.png)
从头删除,2个数字‘3’
![](https://app.yinxiang.com/shard/s71/res/122c1a8c-8bf4-4988-a822-991df1097dc9.png)
从尾删除,
Lrem mylist3 -2 1
删除所有数字的‘2’
Lrem mylist 0 2
扩展
-
Lpushx key value:仅当参数中指定的key存在时,向关联的list的头部插入value,如果不存在,将不进行插入。
![](https://app.yinxiang.com/shard/s71/res/e5f0ab23-69cf-481c-b81c-f074db6dfb86.png)
-
Rpushx key value:在list尾部添加元素
![](https://app.yinxiang.com/shard/s71/res/41461d20-f462-4977-a096-c9ae230804a8.png)
索引插入
-
Lset key index value:设置链表中的index的角标的元素值,0代表链表的头元素,-1代表链表的尾元素。操作链表的角标不存在则抛异常。
![](https://app.yinxiang.com/shard/s71/res/9e3e22c4-9087-44cd-92e1-a320d7795fb5.png)
-
Linsert key before |after pivot value: 在pivot元素前或者后插入value这个元素。
![](https://app.yinxiang.com/shard/s71/res/6d1cac9f-8bc9-4d9a-b179-13a855a964b0.png)
Rpoplpush resource destination:将链表中的尾部元素弹出并添加到头部。
![](https://app.yinxiang.com/shard/s71/res/716af5c0-1126-40d2-90d9-78cbb1da045b.png)
-
将mylist5右端弹出,压入到mylist6 左边
![](https://app.yinxiang.com/shard/s71/res/7ad34bb7-19ba-4e31-9b76-5b4ccf2a1627.png)
-
将mylist6右端数据弹出,压入到左端
![](https://app.yinxiang.com/shard/s71/res/79eacd71-f8d5-4333-b290-2db6f685f3f1.png)
应用范围
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的值已有则不会重复添加
![](https://app.yinxiang.com/shard/s71/res/337b678d-3249-4949-9b73-4a39f09d82bb.png)
-
Srem key members[member1、member2…]:删除set中指定的成员
![](https://app.yinxiang.com/shard/s71/res/dc6b37c5-cbde-4fa4-9593-45c8ce277dc7.png)
Sadd myset 1 2 3
Srem myset 1 2
获取集合中的元素
-
Smembers key:获取set中所有的成员
![](https://app.yinxiang.com/shard/s71/res/d5b3b355-a03d-4d17-bdba-6dbda7f0d44b.png)
Smembers myset
集合的差集运算
-
Sdiff key1 key2…:返回key1与key2中相差的成员,而且与key的顺序有关。即返回差集。(属于A并且不属于B的元素构成的集合)
![](https://app.yinxiang.com/shard/s71/res/d9f1210a-86e5-464f-bf70-b95d11d86e77.png)
Sadd mya1 a b c
Sadd myb1 a c 1 2
Sdiff mya1 myb1
集合的交集运算
-
Sinter key1 key2 key3…:返回交集(属于A且属于B的元素构成的集合)
![](https://app.yinxiang.com/shard/s71/res/79e0e13c-5de8-464f-a189-39e0d72c10e2.png)
Sadd mya2 a b c
Sadd myb2 a c 1 2
Sinter mya2 myb2
集合的并集运算
-
Sunion key1 key2 key3…:返回并集(属于A或者属于B的元素构成的集合)
![](https://app.yinxiang.com/shard/s71/res/f160e8ef-eaad-4c64-8338-8870bb8e6682.png)
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中。如果该元素已经存在则会用新的分数替换原有的分数
![](https://app.yinxiang.com/shard/s71/res/3ed3d6a9-6749-4a25-a408-3a12e603e05f.png)
![](https://app.yinxiang.com/shard/s71/res/5a8e199f-b50e-40e9-b5e4-1d0020215ebf.png)
Zadd mysort 20 zhangsan 80 lisi 90 wangwu
Zadd mysort 100 zhangsan
Zadd mysort 50 jack
获得元素
-
Zscore key member:返回指定成员的分数
![](https://app.yinxiang.com/shard/s71/res/f57131b7-7311-45fe-b641-1f4bfd620cb6.png)
Zscore mysort zhangsan
-
Zcard key:获取集合中的成员数量
![](https://app.yinxiang.com/shard/s71/res/0568fe8c-2049-4980-8d80-9b1ce598e118.png)
Zcard mysort
删除元素
-
Zrem key member[member…]:移除集合中指定的成员,可以指定多个成员。
![](https://app.yinxiang.com/shard/s71/res/53de6e5d-79a1-42db-aefb-7ada25f7c59b.png)
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