一、redis的普遍特性
- redis的下标支持正数、也支持负数。+1表示第一个元素;-1表示倒数最后一个元素。所以可以很好的利用这个特性去遍历,比如list,lrange list 1 -1就可以遍历list。
- redis的范围都是闭区间,不像java的都是包左不包右。
二、KEY
redis的数据结构有String、List、set、Sorted Set、hash五种。
但是为什么API手册里有命令:Key、String、List、Hash、Set、Sorted Set 6大类数据结构的API呢?
1.类似java的简单API
对于redis为什么有Key的API,是因为redis的底层应该是map<String, Object>,然后key的API也就是用来操作这个Map的,比如:
map.remove("keyName") == del key "keyName"
map.get("key").getClass() == type "keyName"
map.forEach(item -> sysout(item.getKey)) == keys *
map.keyset().contails("keyName") == exists "keyName"
2.类似java的复合API
除了类似java的简单API,还有类似于多条java语句的复合API,比如
keys "list*" == {
List<> result = new ArrayList();
` for(String key : map.keySet()){
if(key 正则满足 "list*"){
result.add(key)'
}
return result;
}
}
rename key newkey == {
if(!map.keySet().contains("key")){
return "ERR no such key"
}
map.put("newKey", map.get("key"))
return "OK"
}
renamenx key newkey == {
if(!map.keySet().contains("key")){
return "ERR no such key"
}
if(map.keySet().contains("newKey")){
return;
}
map.put("newKey", map.get("key"))
return "OK"
}
3.生命周期相关
但是redis的key的API除了跟javaAPI类似有部分类似之后,也有部分新增的特性。
比如有“过期时间”的概念
ttl、pttl:time to live
expire、pexpire
expireat、pexpireat
persist
其他
//TODO
另外,redis有16个库,所以这些key还可以移动到其他的库
还有一些复合操作,
sort
删除list,除了对item逐个pop,redis不会保存空的list进而删除list外;还可以用del key [listKey]删除list
三、String
redis的string的API指的是针对key对应的object是String类型的API!
增删改查
增:set、setnx、setex、psetex
批量增:mset、msetnx
删:用key的API,del key “keyName”
改:setRange、append、
查:get、getRange、strlen
批量查:mget
复合操作:getset
数值型字符串的递增递减:decr、decrBy、incr、incrBy、incrByFloat
二进制操作:
修改某位:setBit
查询某位:getBit
按位逻辑与或非:bittop
查询1的位数:bitCount
值得说明的是
1.incr、incrBy这些是支持负数的,所以incrBy val -2跟decr val 2是等价的,这也就解释了为什么API没有decrByFloat,因为incrByFloat也可以实现相同的功能
2.对于set操作,如果传入了数值(整形、浮点型),会自动转换成数值型字符串;
3.对于get操作,如果key对应的类型不是String,则会报错;但是如果mget的话,如果部分对应的是String,部分对应的不是String,则会返回成功的结果,失败的会返回null
四、Hash
redis的string的API指的是针对key对应的object是hash类型的API!
增删改查
增:hset、hsetnx、hmset
删:用key的API,del key “keyName”、hdel
查:hget、hmget、hgetAll、hkeys、hvals、hlen、hexists
改:
数值、数值型字符串的递增递减:hincrby、hincrbyFloat
五、List
redis的string的API指的是针对key对应的object是list类型的API!值得说明的是,redis的list是双向链表,所以既可以作为栈使用,也可以作为链表使用;redis的list还有一个特性,可以阻塞式取值,假如list中没有值了,可以一直阻塞直到有值可拿。
增删改查
添加元素:lpush、lpushx、rpush、rpushx、linsert
拿取元素:lpop、rpop、blpop、brpop
删除元素:用key的API,del key “keyName”、lrem、ltrim
查:llen、lindex
改:lset
复合操作:rpoplpush、brpoplpush
lpush是当要操作的key不存在则会先新建一个key的list,然后在插入;如果当key已存在,但是其类型不是list,则会报错;lpushx是当且仅当key存在并且是list类型,才会进行操作。简单来说就是lpush有错误校验机制、lpushx是一定能操作成功但可能插入失败。
blpop如果接收多个key,则会从左到右依次看看哪个list有值,哪个有值就立即返回,如blpop list1 list2 list3,其中list1没值,list2中有value2,list3有value3,则blpop list1 list2 list3 0会返回list2 value2。至于为什么要返回list2 value2,而不是直接返回value2,因为blpop可以接收多个list,如果只返回value的话,就不知道这个value是从哪个list中弹出的了。
rpoplpush可以使redis的list作为消息队列,并且保证安全的。而且可以使用rpoplpush来遍历list,而不是lrange一下子获取所有的list的item。
六、set
增删改查
查询:smembers(查询set里所有的元素)
添加元素:sadd
删除元素:srem、spop
其他操作:sismember、smove(类似list的rpoplpush)、sinter(取交集)、sinterstore、sdiff(取差集)、sdiffstore
spop、srem、srandmember的区别:spop只能接收一个key,并且弹出(删除)的是该key中随机的一个item;srem是接受一个key和多个item,可以一次性弹出(删除)多个item,返回的是弹出(删除)item的数量;srandmember可以指定属相,相当于多次执行spop
为什么set不提供取并集的API:因为取并集可以通过smembers+sadd实现。smembers拿到所有集合的元素,然后在新建一个set,然后在sadd该set中。
七、sorted set
redis的sorted set是通过item的score来实现的,默认是按照score从小到大进行排序。
添加元素:zadd
拿取元素:
删除元素:zrem、zremRangeByRank、zremRangeByScore
查询操作:zcard(相当于set.size())、zcount(根据item的score进行统计size,相当于zcard+范围过滤)、zscore(查询item对应的分数)、zrange、zrevrange(查询指定score范围内的item)、zrangeByscore、zrangeByScore(zrange的分页版)、zrank(获取排名)
其他操作:zincrby、zinterStore(取交集)、zunionstore(取并集)