一,redis-hash
1.概述
redis中的hash 是一个String类型的field 和 value的映射表,hash 特别适合存储对象
2.相关命令
i. add
hset key field value 设置/添加某个属性值 成功返回1,失败返回0(key中的field 已存在则失败)
hmset key field1 value1 field2 value2.....批量添加
ii.delete
hdel key field 删除某个属性
hmdel key field1,field2... 批量删除
iii.update
hincrby key field num 整型加法,加num
hincrybyfloat field num 浮点型加法
iv.query
hget key field 取某个值
hlen key 获取key的属性个数
hmget key field1 field2 ... 批量取值
hexists key field 判断是否存在,存在为1,不存在为0
hkeys key 获取所有的field
hvals key 获取所有的 value
hgetall key 获取所有的key 和value
v. attention
编码问题
ziplist | <压缩列表>, 当field个数少且没有大的value时,内部编码为ziplist 如:hmset user:3 name james age 24; object encoding user:3 |
hashtable | <哈希表> 当value大于64字节,内部编码由ziplist变成hashtable 如:hset user:4 address “fsgst64字节”; object encoding user:3 |
应用问题:
HASH类型是稀疏,每个键可以有不同的filed, 若用redis模拟做关系复杂查询开发因难,维护成本高
对于VALUE值不大于64字节可以使用hash类型
二,redis-list
1.概述
用来存储多个有序的字符串,一个列表最多可存2的32次方减1个元素,因为有序,可以通过索引下标获取元素或某个范围内元素列表,列表元素可以重复
2,命令
i.add
rpush key value1 value2 value 3... 从右向左插入(list的尾部插入值)
lpush key value 1 value 2 ... 从左到右插入(list的头部插入值)
ii.delete
lrem key count value 查找整个列表删除指定元素value,删除count个( lrem key 0 value 删除所有value)
ltrim key start end 保留[start,end]范围内的元素,其他的全部删除
iii.update
linsert key before/after value newValue在指定元素之前/之后插入值
lset key oldVal newVal 替换值
iv.query
lrange key start end // 从左到右查询值(0 list的第一个元素 -1 list的最后一个元素)
lindex key -1 返回list的最后一个元素
llen key 返回list 的length
lpop 返回并且删除list的头元素(左边第一个)
rpop 返回并删除list的尾元素(右边第一个)
v.attention
应用举例:
java-伪码
Jedis edis = new Jedis("192.168.31.99",6379);
edis.auth("654670150");//密码
Order order = new Order();
order.setId(UUID.randomUUID().toString().replace("-", "").toLowerCase());
order.setPayment(9.9);
order.setPayTime(new Date());
Map<String, String> javaBean2Map = javaBean2Map(order);
String currentUser = "dervish";
String orderInfoName = "order:"+order.getId();
String orderListName = "user:"+currentUser+":order";
//add
//添加order记录
edis.hmset(orderInfoName, javaBean2Map);
//list记录订单名称
edis.lpush(orderListName, orderInfoName);
//query
//查询当前用户的所有订单
List<String> lrange = edis.lrange(orderListName, 0, -1);
//拿出订单信息
for (String orderInfoName1 : lrange) {
List<String> hmget = edis.hmget(orderInfoName1,"id","payment" ,"payTime");
System.out.println(" ----------- ["+orderInfoName1+"] -----------");
for (String orderInfo : hmget) {
System.out.println(orderInfo);
}
}
list内部编码问题:
quicklist | 结合了ziplist和linkedlist两者的优势.使用quicklist内部编码效率更高 |
三,redis-set
1.概述
保存多元素,与列表不一样的是不允许有重复元素,且集合是无序,一个集合最多可存2的32次方减1个元素,除了支持增删改查,还支持集合交集、并集、差集;
2.命令
i.add
sadd key val1 val2 ... 插入元素,返回插入个数,若出现相同元素,重复元素无效 只插入一个。
ii.delete
srem key val1 删除元素,并返回删除的元素
iii.update
iv.query
smembers key 查出所有元素,无序
scard key 计算元素个数
sismember key val1 检查val1 是否为key中的元素
srandmember key count 随机从key中返回count个元素
spop key count 随机从key中返回count个元素,并且删除他们。
v.intersection
sinter key1 key2 返回 key1 key2 的交集
sinterstore key3 key1 key2 将key1,key2的交集保存到key3中 ,返回保存元素的个数
vi.union
sunion key1 key2 返回key1 key2 的并集
sunion key3 key1 key2 将key1 key2 的并集保存到key3中 ,返回保存元素的个数
vii.difference
sdiff key1 key2 返回key1 key2的差集(zhangsan 24 girl)-(james 24 boy)=zhangsan girl)
sdiff key3 key1 key2 将key1 key2的差集保存到key3中 ,返回保存元素的个数
viii.attention
内部编码:
intset | 当元素个数少(小于512个)且都为整数,redis使用intset减少内存的使用 |
hashtables | 当超过512个或不为整数(比如a b)时,编码为hashtables |
应用场景:
sadd (常用于标签) 给用户添加标签/给标签添加用户
spop/srandmember(用于随机抽取,比如抽奖)
sadd+sinter (用于社交,查询共同爱好的人,匹配,)
四,redis-有序集合
1.概述
常用于排行榜,如视频网站需要对用户上传视频做排行榜,或点赞数
与集合有联系,不能有重复的成员
list VS set vs 有序集合
2.命令
i. add
zadd key score1 member1 score2 member2 ... 添加(其中,score 只能是float ,不然报错)
zadd key [NX|XX] [CH] [INCR] score member [score member ...]
nx:添加的元素必须不存在(新增)
xx:添加的元素必须存在 (修改)
ch: change 表示修改元素,
incr: 表示增加
ii. delete
zrem key member 删除指定member,可以多个
zremrangebyrank start end 分数按升序排序后,删除指定下标范围内的member
zremrangebyscore min max 分数按升序排序后,删除指定分数范围内的member
iii.update
iv.query
zrange key start end withscores //查看指定下标范围的score 和member,(zrange key 0 -1 withscores 查看所有)升序
zrevrange key start end withscores //查看指定下标范围的score和member(降序)
zcard key //查看member个数
zscore key member 查看某个member的score
zrank key member 返回指定member的名次(升序),名次从0开始
zrevrank key member 返回指定member的名次(降序)
zincrby key score member 给member的分数再加上score
zrangebyscore key min max withscores 返回指定分数范围内的member 和score ,升序( 可加特殊符合 "("不等于 +inf 无限大, -inf 无限小 )
zrevrangebyscore key start end withscores 返回指定分数范围内的member和score
zcount key min max 返回指定分数范围内的member个数
v.intersection
zinterstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
destination : 交集结果存储的键的名称
numkeys: 要做交集计算的键的个数
key 要做交集的键名称,对应上面的numkeys的值。
weights num num个数与key对应,取得keys之间的交集后,按key的顺序依次给各key中score乘以相应的num,才做最终的运算
aggregate sum/min/max 交集产生的运算条件,默认为sum
vi.union
zunionstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX] 取并集
vii.attention
内部编码:
ziplist | 当元素个数少(小于128个),元素值小于64字节时,使用ziplist编码,可有效减少内存的使用 |
skiplist | 大于128个元素或元素值大于64字节时为skiplist编码 |
使用场景:
排行榜系统,如视频网站需要对用户上传的视频做排行榜
点赞数:zadd user:1:20180106 3 mike //mike获得3个赞
再获一赞:zincrby user:1:20180106 1 mike //在3的基础上加1
用户作弊,将用户从排行榜删掉:zrem user:1:20180106 mike
展示赞数最多的5个用户:
zadd user:4:20160101 9 jack 10 jj 11 dd 3 james 4 lee 6 mark 7 kate
zrevrangebylex user:4:20160101 + - limit 0 5
查看用户赞数与排名:
zscore user:1:20180106 mike zrank user:1:20180106 mike