一. 五种数据类型
- 字符串(String)——常用
- 哈希(hash)——常用
- 字符串列表(list)
- 字符串集合(set)
- 有序字符串集合(sorted set)
二. Key定义的注意点
- 不要过长(消耗内存,降低查找效率)
- 不要过短(降低可读性)
- 统一的命名规范
三. 存储String
1.常用命令:
- set [key] [value] 设值
- get [key] 取值
- getset [key] [value] 先获取key的值,再把key的值更新为value
- del [key] 删除,删完后再get,会返回(nil),代表值不存在
- incr [key] 将指定的key的值递增1,若该key的值不存在,则默认其为0,再递增1. 若该值不能转成整型,比如String类型,使用该操作会报错
- decr [key] 与上面相反,是递减1.
- incrby [key] [num] 递增的数额是[num]的值
- decby [key] [num] 递减的数额是[num]的值
- append [key] [value] 拼凑字符串,若key存在,则会在原有的value后追加[value]的值,若key不存在,则会创建这个(key,value)
四. 存储Hash
Redis中的Hash类型可以看成是一个具有String Key和String Value的map容器,这个类型非常适合存储值对象类型,比如:用户名、密码、年龄等等。每一个Hash可以存储4294967295个键值对
1.常用命令:
- hset [hashName] [key] [value] 设值,如:hset myhash username jack,hset myhash age 18
- hmset [hashName] [key] [value] [key] [value] 一次存入多个键值对,如:hmset myhash2 username rose age 21
- hget [hashName] [key] 取值,如:hget myhash username
- hmget [hashName] [key] [key] 一次取得多个属性的值,如:hmget myhash username age
- hgetall [hashName] 获取一个集合中所有属性和属性和属性值,如:hgetall myhash
- hdel [hashName] [key] [key] 删除一个集合下的多个属性,如:hdel myhash2 username age
- del [hashName] 删除整个集合,如:del myhash2
- hincrby [hashName] [key] [num] 给某属性值增加数值,如:hincrby myhash age 5
- hexists [hashName] [key] 判断某个hash中的属性是否存在,若存在会返回1.如:hexists myhash username
- hlen [hashName] 获取属性数量,如:hlen myhash
- hkeys [hashName] 获得所有属性名称,如:hkeys myhash
- hvals [hashName] 获取所有属性值,如:hvalues myhash
五. 存储list
Redis中的list类型,是按照插入顺序排序的字符串链表,和数据结构中的普通链表是一样的,我们可以在他的头部和尾部添加新的元素,在插入时,若该键不存在,那么redis就会为这个键创建一个新的链表,与此相反,如果链表中的所有元素都被移除了,那么该键也会被删除。如果链表元素的插入与删除是作用在链表的两头,那么这是比较高效的操作,即使链表中已经存在百万条数据,这个操作也可以在常量时间内完成。若是在链表的中间进行元素的插入与删除操作,那么这样操作的效率就比较低了
1.存储数据的方式:
- ArrayList使用数组方式。根据索引查询速度非常快,但是新增和删除操作需要涉及到位移操作,所以比较慢
- LinkedList使用双向链表方式。每个元素都记录了前后元素的指针,所以插入和删除数据的时候,只是改变了前后元素指针的指向,速度较快
- 双向链表中添加数据
- 双向链表中删除数据
2.常用命令:
1. 两端添加:
- lpush mylist a b c 向链表mylist头部(左侧)添加a,b,c
- rpush mylist 1 2 3 向链表mylist尾部(右侧)添加1,2,3
2. 查看链表中元素:
- lrange mylist 0 5 查看链表mylist中的元素,从位置0开始,到位置5结束。也可以用负数,-1表示链表尾部的元素,-2表示倒数第二个,以此类推
- lrange mulist 0 -1 查看链表mylist中所有元素(从头部到尾部)
3. 两端弹出:
- lpop mylist 左端弹出链表头部第一个元素,此时链表中就没有这个元素了
- rpop mylist 右端弹出链表尾部第一个元素,此时链表中就没有这个元素了
4. 获取链表中元素个数:
- llen mylist
5. 扩展命令
- lpushx mylist x 仅当mylist关联的链表存在时,往该链表头部插入值x,如果不存在,则不会插入值
- rpushx mulist y 仅当mylist关联的链表存在时,往该链表尾部插入值y,如果不存在,则不会插入值
- lrem mylist 2 3 从mylist链表头部开始,删去两个3
- lrem mylist -2 1 从mylist链表尾部开始,删去两个1
- lrem mylist 0 2 从mylist链表中删除所有2
- lset mylist 3 mmm 把mylist链表中脚标为3的值设为mmm
- linsert mylist before b 11 从链表头部开始,在第一个b之前插入11
- linsert mylist after b 22 从链表左侧开始,在第一个b之后插入22
6. rpoplpush mylist5 mylist6 将mylist5中的尾部元素弹出,压入到mylist6的头部中去。
3.使用场景:
redis链表经常会被用于消息队列的一些服务,来完成多个程序之间的消息交互。假设一个应用程序正在执行lpush向链表中添加新的元素,我么通常将这样的程序称之为"生产者",另外一个程序正在执行从链表中取出元素,我们称之为“消费者”,于此同时,消费者程序在取出元素后立即崩溃,由于该消息已经被取出,却没有被正常处理,可以认为该消息已经丢失,由此可能会导致业务数据的丢失或者业务状态的不一致。通过rpoplpush操作,消费者程序在主消息队列中取出元素之后,再将它插入到一个备份的队列之中,直到消费者程序完成正常的逻辑处理之后,再将消息从备份队列中删除,这样可以提供一个守护的线程,当发现备份队列中的消息过期的时候,可以将它重新放回到主消息队列中,以便其他的消费者可以继续的处理
六. 存储set
和List类型不同的是,Set集合中不允许出现重复的元素,如果多次添加相同的元素,set中仅保留一份该元素的拷贝,set可包含最大元素数量是4294967295
1.常用命令:
1. 添加/删除元素
- sadd myset a b c 向集合myset中添加了a,b,c
- srem myset a b 删除myset中的a,b
2.获得集合中的元素
- smembers myset 获得集合中的元素
- sismember myset a 判断a是否存在与myset中,若返回1,则存在;返回0,则不存在
3.集合中的差集运算(返回两个集合中相差的成员,而且与key的顺序有关)
sadd mya1 a b c
sadd myb1 a c 1 2
sdiff mya1 myb1
#结果返回 b,求差集结果和key的顺序有关
sdiff myb1 mya1
#结果返回 1 2
4.集合中的交集运算
sadd mya2 a b c
sadd myb2 a c 1 2
sinter mya2 myb2
#返回交集 a c
5.集合中的并集运算
sadd mya3 a b c
sadd myb3 a c 1 2
sunion mya3 myb3
#返回并集 a b c 1 2
6.拓展命令
- scard myset 得到集合中元素的数量
- srandmember myset 随机返回一个集合中的元素
- sdiffstore my1 mya1 myb1 把mya1和myb1相差的值存储到集合my1中
- sinterstore my2 mya2 myb2 把mya2和myb2的交集存储到集合my2中
- sunionstore my3 mya3 myb3 把 mya3和myb3的并集存储到集合my3中
2.使用场景:
可以使用redis的set数据类型跟踪一些具有唯一性的数据,比如访问某一博客的唯一ip地址的信息,对于这种场景,我们只需要在每次访问该博客的时候,将访问者的ip存入到redis当中,set数据类型就会自动保证ip地址的唯一性。还可以利用set类型服务器端聚合操作的方便高效的特性,来维护数据对象之间的关联关系。比如购买商品A的用户id被存入到某一指定set当中,购买商品B的用户id被存放的另一个set当中,若此时想查询哪些用户同时购买了这两种商品,只需要使用交集的操作即可
七. 存储Sorted-Set
1.和Set的相同点:
都是字符串的集合,都不允许出现重复的元素
2.主要区别:
Sorted-Set中每一个成员都有一个分数与之关联,redis通过这个分数将集合中的成员从小到大进行排序。该类型集合中成员必须唯一,但分数不必唯一。在该类型集合中进行添加删除与更新操作都是十分快速的,时间复杂度为集合中成员个数的对数。Sorted-Set中的成员在集合中的位置是有序的,即使访问集合中部的成员也是十分高效的。
3.常用命令:
a).添加元素
zadd mysort 70 zs 80 ls 90 ww
#分数+元素
#返回添加的元素个数
zadd mysort 100 zs
#若集合中已经存在该元素,则会用新的分数替换原有的分数
#集合中已经有zs 此处返回0
zadd mysort 60 tom
#添加了一个原集合中没有的元素,返回1
b).获得元素
zscore mysort zs
#获得zs的分数,此处返回100
zcard mysort
#返回集合中成员的数量
c).删除元素
zrem mysort tom ww
#删除集合中tom,ww
zcard mysort
#此时返回集合长度为2
d).范围查询
zrange mysort 0 -1
#查出所有元素,由小到大显示,-1代表最后一个
zrange mysort 0 -1 withscores
#由小到大显示元素和其相对应的分数
zrevrange mysort 0 -1 withscores
#从大到小显示
zremrangebyrank mysort 0 4
#按照范围删除,把位置从第0个到第4个的都删掉
zremrangebyscore mysort 80 100
#按分数删除,把80到100的都删掉
e).扩展命令
zrangebyscore mysort 0 100
#按分数查询,查分数从0到100的元素
zrangebyscore mysort 0 100 withscores
#按分数查询,查分数从0到100的元素,并且带着分数进行显示
zrangebyscore mysort 0 100 withscores limit 0 2
##按分数查询,查分数从0到100的元素,并且带着分数进行显示,并且只显示头两条
zincrby mysort 3 ls
#设置指定成员分数增加,此处ls的分数加3
zcount mysort 80 90
#获取80到90分的元素的个数
4.使用场景:
- 游戏排名、微博热点话题等
- 大型在线游戏积分排行榜,每当游戏玩家的积分发生变化的时候,可以执行zadd命令,去更新玩家的分数,再通过zrange命令去获取用户积分多少等信息,或者通过zrank命令获取玩家排行信息
- 构建索引数据
八. keys 的通用操作
- keys * 查询所有的key
- keys my? ?是一个占位符,代表一个字符,找出以my开头,后面还有1位字符的key
- exists [key] 判断key是否存在,若存在返回1,不存在返回0
- del [key] 删除my1
- rename [oldkey] [newkey] 将oldkey重命名为newkey
- expire [key] 1000 设置key的过期时间为1000秒
- ttl [key] 查看指定key还剩多少时间就会超时,若key没有设置超时时间,会返回-1
- type [key] 获得指定key的类型,