安装Redis之后大家肯定都试过 get set 命令了,也了解了最基本的数据类型字符串,下面让我们认识以下 Redis 中的其他成员吧。
二进制安全(Binary-safe)的字符串(String)
二进制安全的字符串列表(List)
二进制安全的字符串集合(Set)
有序的集合(Sorted Set)
这里的key指的是 Redis 键值对的key。
Redis Key 是二进制安全的,也就是说你可以用任意二进制序列作为 key,从一个简单的字符串到一个jpg图片内容。空字符串也是有效的key值。
key个几个规则:
不要太长。这个大家都明白,越长越消耗内存,查找时的计算代价也越高。
不要太短。太短的key不容已阅读和理解,比如 user:100:password 写成 u:1000:p,会让人不明所以。因为key相对与value总是很小的,所以由此带来的一点点的空间节省并无太大优势。
遵循一种模式。比如“对象类型:id:字段名”,就行上面提到的 user:100:password,如果有多个单词,可以用一个点来代替空格:comment:1234:reply.to
这个是 Redis 最简单的数据类型,如果还没有安装 Redis,那么到下面网页感受一下把:
ps: 本文的例子都是在线录入的。 直接在 Example 下面的文本框里输入命令,回车 。
redis> set 我 alan
OK
redis> get 我
"alan"
redis> set 暗号 "还记得 大名湖畔的 唉冬瓜吗 "
OK
redis> get 暗号
"还记得 大名湖畔的 唉冬瓜吗 "
redis>
这里我直接用中文作为 key,没有一点问题。
前面提到 key 可以是任意二进制字符串,那么值也同样,你可以保存一副图片(值大小不能超过512M)。
虽然字符串是基本类型,也可以进行一些有趣的操作:
redis> set qty 256
OK
redis> get qty
"256"
redis> incr qty
(integer) 257
redis> get qty
"257"
redis> incrby qty 100
(integer) 357
redis> get qty
"357"
redis>
incr 命令把字符串解析成整型,然后+1,再保存为字符串。类似的命令还有 incrby, decr, decrby。
如果字符串值不能解析成整数,incr命令会报错,如 ERR value is not an integer or out of range。
redis> set name alan
OK
redis> incr name
ERR value is not an integer or out of range
redis>
incr 叫做 atomic increment,其 atomic (原子)特性的意义:如果两个客户端同时发送 incr 命令,客户端会同时读到 “10”,对它们+1,最终的结果一定为12,要更多了解可以去官网查看相关资料。
首先讲一下list的理论背景,list这个词很多时候都被不恰当的使用,比如 python 的 list,她们实际上是数组。一般意义上讲,list 就是有序元素的集合。而使用 数组 实现,和使用 linked list 实现的list在属性上有所不同。
Redis 的 list 是使用 Linked List 实现的,其优点是在 list 的两端添加元素其时间复杂度是常数级的。也就是说你在‘10个元素的list头部添加新元素,和在一亿个元素的list头部添加消耗的时间相同;而使用数组实现list的优势在于索引速度非常快。
Redis使用 Linked List 实现的原因是:对于一个数据库系统来说,能快速在很大的列表上添加元素至关重要。
添加新元素的命令是 lpush 和 rpush,分别在左边(头部)和右边(尾部)添加一个元素。lrange接受三个参数,列表的key,范围的开始,范围的结束,返回一个列表的片段。
redis> lpush message "你好,很高兴认识你"
(integer) 1
redis> lpush message "我也很高兴认识你,我是 alan"
(integer) 2
redis> lpush message "我的名字是 bruce "
(integer) 3
redis> lrange message 0 2
1) "我的名字是 bruce "
2) "我也很高兴认识你,我是 alan"
3) "你好,很高兴认识你"
redis>
由上面例子里,我们每次都在列表头部添加一个元素。
lrange也可已接受负数来表示范围, -1 是最后一个元素,-2 是倒数第二个元素。
redis> lrange message -1 -1
1) "你好,很高兴认识你"
redis> lrange message -1 2
1) "你好,很高兴认识你"
redis> lrange message -2 2
1) "我也很高兴认识你,我是 alan"
2) "你好,很高兴认识你"
redis>
由上例,list可以应用到聊天系统;可以用在评级系统里,比如 reddit.com;用在博客引擎中,每篇日志都是一个list,然后向里面放入评论;等等。
上例中,我们直接将数据对象(消息的内容)放入了 list,由于对象可能多次被引用,通常我们不那样做,而是存放ID到list中。
上面聊天的例子,我们用新的方式来存储:
redis> incr next.message.id
(integer) 1
redis> set message:1:sender alan
OK
redis> set message:1:content "hello, something else"
OK
redis> lpush messages 1
(integer) 1
redis> incr next.message.id
(integer) 2
redis> set message:2:sender bruce
OK
redis> set message:2:content "something else else ..."
OK
redis> lpush messages 2
(integer) 2
这次,我们先通过 incr 生成一个唯一的ID,然后创建对象,并为对象赋值,最后把这个对象的 id 放入list中。
在命令参考里可以看到更多关于list的命令,Redis命令参考传送
Redis的 Set 是无序的,元素是二进制安全的字符串。
sadd命令可以向集合中添加一个元素
scard命令获得集合中元素的个数
smembers命令获得集合中所有元素(无序)
srem 移除集合中的一个或者多个元素
redis> sadd myset 1
(integer) 1
redis> sadd myset 2
(integer) 1
redis> scard myset
(integer) 2
redis> sadd myset 3
(integer) 1
redis> scard myset
(integer) 3
redis> smembers myset
1) "1"
2) "2"
3) "3"
redis> srem myset 1
(integer) 1
redis> srem myset 2 3
(integer) 2
redis> smembers myset
(empty list or set)
redis>
sismenber 判断元组是否在集合中存在
redis> sadd myset 2
(integer) 1
redis> sismember myset 2
(integer) 1
redis> sismember myset 22
(integer) 0
如果元素存在返回1,不存在返回0。
sinter 命令可与取两个集合的交集
redis> sadd set1 1
(integer) 1
redis> sadd set1 2
(integer) 1
redis> sadd set1 3
(integer) 1
redis> sadd set2 2
(integer) 1
redis> sadd set2 3
(integer) 1
redis> sadd set2 4
(integer) 1
redis> sinter set1 set2
1) "2"
2) "3"
redis>
关于有序集合的意义不多说,可以用 zadd 来创建一个有序集合,用 zrange 获取元素:
redis> zadd students 15 tom
(integer) 1
redis> zadd students 33 bill
(integer) 1
redis> zadd students 18 alis
(integer) 1
redis> zadd students 18 alan
(integer) 1
redis> zrange students 0 -1
1) "tom"
2) "alan"
3) "alis"
4) "bill"
ZSet 的每个元素都有一个评分,Redis通过这个评分排序。上面例子中 15 33 18 18 都是评分,如果评分相同那么会根据元素进行排序。上面 alan 排在了 alis 的前面。
通过 zrevrange 进行反向排序
redis> zrevrange students 0 -1
1) "bill"
2) "alis"
3) "alan"
4) "tom"
通过 zrangebyscore 来获取 ZSet 的片段,比如我们要获得评分在 18 - 30 之间的元素:
redis> zrangebyscore students 18 30
1) "alan"
2) "alis"
可以看到 评分为 18 的元素都包含进来了。
inf 代表正的极限, -inf 代表负的极限,可以用这个来获取大/小于某个评分的元素
redis> zrangebyscore students -inf 30
1) "tom"
2) "alan"
3) "alis"
通过 zremrangebyscore 删除元素
redis> zremrangebyscore students -inf 30
(integer) 3
redis> zrange students 0 -1
1) "bill"
redis>
可以看到评分为 -inf 到 30 的元素都被删除了(共3个),最后只剩下了一个元素。