Redis的数据类型(lists、Sets)
lists类型
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边) LPUSH 命令插入一个新的元素到头部, 而 RPUSH 插入一个新元素导尾部.当一个这两个操作在一个空的Key上被执行的时候一个新的列表被创建。相似的,如果一个列表操作清空一个列表那么对应的key将被从key空间删除。这是非常方便的语义,因为他们被调用使用一个空列表完全就像他们被调用时使用一个不存在的键值(可以)做为参数。 一些类表操作和结果的例子:
LPUSH mylist a # 现在类表中是 "a"
LPUSH mylist b # 现在列表中是 "b","a"
RPUSH mylist c # 现在类表中是 "b","a","c" (这次RPUSH被使用)
一个列表最多可以包含232 - 1个元素 (4294967295, 每个列表超过40亿个元素)。 从时间复杂度的角度来看Redis列表的主要特征是在头和尾的元素插入和删除是固定时间,即便是数以百万计的插入。在列表的两端访问元素是非常快的但是如果你试着访问一个非常大的列表的中间的元素是很慢的,因为那是一个O(N)操作。你可以用Redis列表做很多有趣的事情,比如你可以:
-
在一个社交网络中建立一个时间线模型,使用LPUSH 去添加新的元素到用户的时间线, 使用LRANGE去接收一些最近插入的元素。
-
你可以将 LPUSH 和 LTRIM 一起用去创建一个永远也不会超过指定元素数目的列表,但是记住是最后的N个元素。
-
列表能够被用来作为消息传递primitive[译注:不清楚表达的意思], 例如众所周知的用来创建后台工作的Resque Ruby库.
-
你可以使用列表做更多的事,这个数据类型支持许多命令,包括像BLPOP这样的阻塞命令。请查看可获得的列表操作命令 以获得更多的信息。
lists操作方法
lpush 在key对应list的头部添加字符串元素。
127.0.0.1:6379> lpush mylist world (integer) 1 127.0.0.1:6379> lpush mylist hello (integer) 2 127.0.0.1:6379> lrange mylist 0 -1 1) "hello" 2) "world"
rpush 在key对应list的尾部添加字符串元素。
127.0.0.1:6379> rpush list2 hello (integer) 1 127.0.0.1:6379> rpush list2 world (integer) 2 127.0.0.1:6379> lrange list2 0 -1 1) "hello" 2) "world"
linsert 在key对应list的特定位置前或后添加字符串
127.0.0.1:6379> rpush list3 world (integer) 1 127.0.0.1:6379> linsert list3 before world hello (integer) 2 127.0.0.1:6379> lrange list3 0 -1 1) "hello" 2) "world"
lset 设置list中指定下标的元素值。
127.0.0.1:6379> rpush list4 hello (integer) 1 127.0.0.1:6379> lset list4 0 world OK 127.0.0.1:6379> lrange list4 0 -1 1) "world"
lrem 从key对应list中删除n个和value相同的元素。(n<0从尾删除,n=0全部删除)
127.0.0.1:6379> rpush list5 hello (integer) 1 127.0.0.1:6379> rpush list5 hello (integer) 2 127.0.0.1:6379> lrange list5 0 -1 1) "hello" 2) "hello" 127.0.0.1:6379> lrem list5 1 hello (integer) 1 127.0.0.1:6379> lrange list5 0 -1 1) "hello"
ltrim 保留指定key的值范围内的数据
127.0.0.1:6379> rpush list8 one (integer) 1 127.0.0.1:6379> rpush list8 two (integer) 2 127.0.0.1:6379> rpush list8 three (integer) 3 127.0.0.1:6379> ltrim list8 1 2 OK 127.0.0.1:6379> lrange list8 0 -1 1) "two" 2) "three"
lpop 从list的头部删除元素,并返回删除元素
127.0.0.1:6379> rpush list9 hello (integer) 1 127.0.0.1:6379> rpush list9 world (integer) 2 127.0.0.1:6379> lrange list9 0 -1 1) "hello" 2) "world" 127.0.0.1:6379> lpop list9 "hello" 127.0.0.1:6379> lrange list9 0 -1 1) "world"
rpop 从list的尾部删除元素,并返回删除元素
127.0.0.1:6379> rpop list9 "world" 127.0.0.1:6379> lrange list9 0 -1 (empty list or set)
rpoplpush 从第一个list的尾部移除元素并添加到第二个list的头部。
127.0.0.1:6379> lrange mylist5 0 -1 1) "hello" 2) "world" 127.0.0.1:6379> lrange mylist6 0 -1 1) "hello1" 2) "world1" 127.0.0.1:6379> rpoplpush mylist5 mylist6 "world" 127.0.0.1:6379> lrange mylist5 0 -1 1) "hello" 127.0.0.1:6379> lrange mylist6 0 -1 1) "world" 2) "hello1" 3) "world1"
lindex 返回名称为key的list中index位置的元素
127.0.0.1:6379> lrange mylist8 0 -1 1) "hello" 2) "world" 127.0.0.1:6379> lindex mylist8 0 "hello" 127.0.0.1:6379> lindex mylist8 1 "world" 127.0.0.1:6379> lindex mylist8 2 (nil)
llen 返回key对应list的长度
127.0.0.1:6379> llen mylist8 (integer) 2 127.0.0.1:6379> llen mylist9 (integer) 0
集合(Sets)
Redis 集合(Set)是一个无序的字符串集合,你可以以O(1)的时间复杂度(无论集合中有多少元素时间复杂度都是常量)完成添加,删除,以及测试元素是否存在。Redis 集合拥有令人满意的不允许包含相同成员的属性。多次添加相同的元素,最终在集合里只会有一个元素。 实际上说这些就是意味着在添加元素的时候无须检测元素是否存在。一个Redis集合的非常有趣的事情是他支持一些服务端的命令从现有的集合出发去进行集合运算,因此你可以在非常短的时间内进行合并(unions), 求交集(intersections),找出不同的元素(differences of sets)。 一个集合最多可以包含232 - 1 个元素(4294967295, 每个集合超过40亿个元素). 你可以使用集合多很多有趣的事情,比如你能够:
-
你可以使用集合追踪一件(独一无二的)事情,想要知道所有访问一个博客文章的独立IP? 每次当你处理一个页面访问的事简单的使用SADD。你可以肯定重复的IP是不会被插入的。
-
Redis 集合是很擅长表现关系的。你可以使用Redis集合创建一个tagging系统去表现每一个tag。接下来你能够使用SADD命令将有一个给定tag的所有对象的所有ID添加到一个用来展现这个特定tag的集合里。你想要同时有三个不同tag的所有对象的ID吗?使用SINTER就好了。
-
使用SPOP或者SRANDMEMBER命令你可以使用集合去随意的抽取元素。
sets操作方法
sadd 向名称为key的set中添加元素
127.0.0.1:6379> sadd myset1 one (integer) 1 127.0.0.1:6379> sadd myset1 two (integer) 1 127.0.0.1:6379> sadd myset1 two (integer) 0 127.0.0.1:6379> smembers myset1 1) "one" 2) "two"
srem 删除名称为key的set中的元素
127.0.0.1:6379> srem myset1 one (integer) 1 127.0.0.1:6379> smembers myset1 1) "two"
spop 随机返回并删除名称为key的set中一个元素
127.0.0.1:6379> smembers myset3 1) "one" 2) "two" 3) "four" 4) "three" 127.0.0.1:6379> spop myset3 "two" 127.0.0.1:6379> spop myset3 "one" 127.0.0.1:6379> smembers myset3 1) "four" 2) "three"
sdiff 返回所有给定key与第一个key的差集
127.0.0.1:6379> smembers mytest4 1) "two" 2) "three" 127.0.0.1:6379> smembers mytest5 1) "one" 2) "two" 127.0.0.1:6379> sdiff mytest4 mytest5 1) "three" 127.0.0.1:6379> sdiff mytest5 mytest4 1) "one"
sdiffstore 返回所有给定key与第一个key的差集,并将结果存为另一个key
127.0.0.1:6379> sdiffstore mytest6 mytest5 mytest4 (integer) 1 127.0.0.1:6379> smembers mytest6 1) "one"
sinter 返回所有给定key的交集
127.0.0.1:6379> smembers set6 1) "two" 2) "three" 127.0.0.1:6379> smembers set7 1) "one" 2) "two" 127.0.0.1:6379> sinter set6 set7 1) "two"
sinterstore 返回所有给定的交集,并将结果存为另一个key
127.0.0.1:6379> sinterstore set8 set6 set7 (integer) 1 127.0.0.1:6379> smembers set8 1) "two"
sunion 返回所有给定key的并集
127.0.0.1:6379> smembers sets1 1) "two" 2) "three" 127.0.0.1:6379> smembers sets2 1) "one" 2) "two" 127.0.0.1:6379> sunion sets1 sets2 1) "one" 2) "two" 3) "three"
sunionstore 返回所有给定key的并集,并将结果存为另一个key
127.0.0.1:6379> sunionstore sets3 sets1 sets2 (integer) 3 127.0.0.1:6379> smembers sets3 1) "one" 2) "two" 3) "three"
smove 从第一个key对应的set中移除member并添加到第二个对应的set中
127.0.0.1:6379> smembers sets4 1) "two" 2) "three" 127.0.0.1:6379> smembers sets5 1) "one" 2) "two" 127.0.0.1:6379> smove sets4 sets5 three (integer) 1 127.0.0.1:6379> smembers sets4 1) "two" 127.0.0.1:6379> smembers sets5 1) "one" 2) "two" 3) "three"
scard 返回名称为key的set的元素个数
127.0.0.1:6379> smembers sets6 1) "one" 2) "two" 127.0.0.1:6379> scard sets6 (integer) 2
sismember 测试member是否是名称为key的set的元素
127.0.0.1:6379> smembers sets6 1) "one" 2) "two" 127.0.0.1:6379> sismember sets6 one (integer) 1 127.0.0.1:6379> sismember sets6 three (integer) 0
srandmember 随机返回名称为key的set的一个元素,但不删除元素
127.0.0.1:6379> smembers sets7 1) "one" 2) "two" 3) "three" 127.0.0.1:6379> srandmember sets7 "three" 127.0.0.1:6379> srandmember sets7 "three" 127.0.0.1:6379> srandmember sets7 "two"
有序集合(Sorted Sets)
Redis 有序集合与普通集合非常相似,是一个没有重复元素的字符串集合。不同之处是有序集合的每个成员都关联了一个评分,这个评分被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但是评分可以是重复了。 使用有序集合你可以以非常快的速度(O(log(N)))添加,删除和更新元素。因为元素是有序的, 所以你也可以很快的根据评分(score)或者次序(position)来获取一个范围的元素。访问有序集合的中间元素也是非常快的,因此你能够使用有序 集合作为一个没有重复成员的智能列表。在有序集合中,你可以很快捷的访问一切你需要的东西:有序的元素,快速的存在性测试,快速访问集合的中间元素! 简而言之使用有序集合你可以做完成许多对性能有极端要求的任务,而那些任务使用其他类型的数据库真的是很难完成的。 使用有序集合你可以:
-
在一个大型的在线游戏中展示一个排行榜,在那里一旦一个新的分数被提交,你可以使用ZADD命令去更新它.你也可用使用 ZRANGE命令来得到顶级的用户,你还可以使用ZRANK命令根据用户名返回该用户在排行榜中的位次。同时使用ZRANK 和 ZRANGE 你可以显示和给定用户分数相同的所有用户。所有这些操作都非常的快速。
-
有序集合常常被用来索引存储在Redis中的数据。举个例子,如 果你有许多的哈希(Hashes)来代表用户,你可以使用一个有序集合,这个集合中的元素的年龄字段被用来当做评分,而ID作为值。因此,使用ZRANGEBYSCORE命令,那是微不足道的并且能够很快的接收到给定年龄段的所有用户。
-
有序集合或许是最高级的Redis数据类型,因此花点时间查看完整的有序集合命令列表去发现你能用Redis做些什么。
sorted sets操作方法
zadd 向名称为key的zset中添加元素member,score用于排序。如果该元素存在,则更新其顺序
127.0.0.1:6379> zadd myzset 1 one (integer) 1 127.0.0.1:6379> zadd myzset 1 two (integer) 1 127.0.0.1:6379> zadd myzset 2 two (integer) 0 127.0.0.1:6379> zrange myzset 0 -1 withscores 1) "one" 2) "1" 3) "two" 4) "2" 127.0.0.1:6379> zrange myzset 0 -1 1) "one" 2) "two"
zrem 删除名称为key的zset中的元素member
127.0.0.1:6379> zrange myzset 0 -1 withscores 1) "one" 2) "1" 3) "two" 4) "2" 127.0.0.1:6379> zrem myzset two (integer) 1 127.0.0.1:6379> zrange myzset 0 -1 withscores 1) "one" 2) "1"
zincrby 如果在名称为key的zset中已经存在元素member,则该元素的score增加increment否则向该集合中添加该元素,其score的值为increment
127.0.0.1:6379> zrange myzset 0 -1 withscores 1) "one" 2) "1" 127.0.0.1:6379> zincrby myzset 2 one "3" 127.0.0.1:6379> zrange myzset 0 -1 withscores 1) "one" 2) "3"
zrank 返回名称为key的zset中member元素的排名(按score从小到大排序)即下标
127.0.0.1:6379> zrange zset2 0 -1 withscores 1) "one" 2) "1" 3) "two" 4) "2" 5) "three" 6) "3" 7) "four" 8) "4" 9) "five" 10) "5" 127.0.0.1:6379> zrank zset2 four (integer) 3
zrevrank 返回名称为key的zset中member元素的排名(按score从大到小排序)即下标
127.0.0.1:6379> zrange zset2 0 -1 withscores 1) "one" 2) "1" 3) "two" 4) "2" 5) "three" 6) "3" 7) "four" 8) "4" 9) "five" 10) "5" 127.0.0.1:6379> zrevrank zset2 four (integer) 1
zrevrange 返回名称为key的zset(按score从大到小顺序)中的index从start到end的所有元素
zrangebyscore 返回集合中score在给定区间的元素
127.0.0.1:6379> zrange zset2 0 -1 withscores 1) "one" 2) "1" 3) "two" 4) "2" 5) "three" 6) "3" 7) "four" 8) "4" 9) "five" 10) "5" 127.0.0.1:6379> zrangebyscore zset2 2 4 withscores 1) "two" 2) "2" 3) "three" 4) "3" 5) "four" 6) "4"
zcount 返回集合中score在给定区间的数量
127.0.0.1:6379> zrange zset2 0 -1 withscores 1) "one" 2) "1" 3) "two" 4) "2" 5) "three" 6) "3" 7) "four" 8) "4" 9) "five" 10) "5" 127.0.0.1:6379> zcount zset2 2 3 (integer) 2
zcard 返回集合中所有元素的个数
127.0.0.1:6379> zrange zset2 0 -1 withscores 1) "one" 2) "1" 3) "two" 4) "2" 5) "three" 6) "3" 7) "four" 8) "4" 9) "five" 10) "5" 127.0.0.1:6379> zcard zset2 (integer) 5
zremrangebyrank 删除集合中排名在给定区间的元素(按索引删除)
127.0.0.1:6379> zrange zset2 0 -1 withscores 1) "one" 2) "1" 3) "two" 4) "2" 5) "three" 6) "3" 7) "four" 8) "4" 9) "five" 10) "5" 127.0.0.1:6379> zremrangebyrank zset2 2 3 (integer) 2 127.0.0.1:6379> zrange zset2 0 -1 withscores 1) "one" 2) "1" 3) "two" 4) "2" 5) "five" 6) "5"
zremrangebyscore 删除集合中score在给定区间的元素(按score删除)
127.0.0.1:6379> zrange zset2 0 -1 withscores 1) "one" 2) "1" 3) "two" 4) "2" 5) "five" 6) "5" 127.0.0.1:6379> zremrangebyscore zset2 2 5 (integer) 2 127.0.0.1:6379> zrange zset2 0 -1 withscores 1) "one" 2) "1"