六、redis多数据类型介绍(常用命令)
6、1前提操作
#如果前面的redis环境没搭好,那么可以先暂时在
“http://try.redis.io/”中实践redis命令部分。
#为了测试方便,把redis登录密码暂时撤销
#redis一共分为五种基本数据类型:String,Hash,List,Set,ZSet
#所有命令都可以到“http://www.redis.cn/commands.html” 去搜索到。
#首先由于redis是一个基于key-value键值对的持久化数据库存储系统,所以要先定义key值的规范,最好坚持使用一种模式,例如:”object-type:id:field”就是个不错的主意,像”user:1000:password”,再比如在字段上加一个点”comment:1234:reply.to”。
#检查redis是否启动
[root@redis conf]# lsof -i:6379
COMMAND PIDUSER FD TYPE DEVICE SIZE/OFF NODE NAME
redis-ser 6616 root 4u IPv6 21770 0t0 TCP *:6379 (LISTEN)
redis-ser 6616 root 5u IPv4 21772 0t0 TCP *:6379 (LISTEN)
比如:
[root@redis conf]# redis-cli set user:01:passwd 1000
OK
[root@redis conf]# redis-cli get user:01:passwd
"1000"
#上述操作跟下述操作是一致的:
[root@redis conf]# redis-cli
127.0.0.1:6379> set user:01:passwd 1000
OK
127.0.0.1:6379> get user:01:passwd
"1000"
#这只是一个操作示例,看不懂接着往下学习即可。
#查找命令使用技巧
127.0.0.1:6379>help(加一个英文空格,按tab键)
#会自动出现下述内容
127.0.0.1:6379>help @string
#可修改@后的命令查看需要使用的命令操作
6、2字符串类型(string)
6、2、1简介
String类型是包含很多种类型的特殊类型,并且是二进制安全的。比如序列化的对象进行存储,比如一张图片进行二进制存储,比如一个简单的字符串,数值等等。
String类型是最简单的redis类型。如果只使用这种类型,redis就是一个可持久化的memcached服务器(注:memcached的数据仅保存在内存中,服务器重启后,数据将丢失。)
通常用set和get可以来设置和获取字符串的值。值可以是任何种类的字符串(包括二进制数据),例如你可以在一个键下保存一副jpeg图片,值的长度不能超过1GB。
6、2、2操作
6、2、2、1第一部分
set
#设置值,获取值
#set将键key设定为指定的字符串值。如果key已经保存了一个值,那么这个操作会直接覆盖原来的值,并且忽略原始类型。当set命令执行成功之后,之前设置的过期时间都将失效。
#get返回key的value。如果key不存在,返回特殊值nil。如果key的value不是string,就返回错误,因为GET只处理string类型的values。
127.0.0.1:6379> set name nameval
OK
127.0.0.1:6379> get name
"nameval"
#注意一个问题,当set时,key值后面的value包含空格,那么要把整个value用引号包起来,不然set不能正确识别。
127.0.0.1:6379> set name name1 val1
(error) ERR syntax error
127.0.0.1:6379> set name 'name1 val1'
OK
127.0.0.1:6379> get name
"name1 val1"
127.0.0.1:6379> set name "name2 val2"
OK
127.0.0.1:6379> get name
"name2 val2"
del
#删除值
#如果删除的key不存在,则直接忽略。返回值指被删除的keys的数量。
#时间复杂度(参考百度百科):O(N)将要被删除的key的数量,当删除的key是字符串以外的复杂数据时,比如list,set,zset,hash删除这个key的时间复杂度是O(1)。
127.0.0.1:6379> del name
(integer) 1
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> keys *
(empty list or set)
#删除一个不存在的key
127.0.0.1:6379> del test
(integer) 0
setnx
#setnx
#将key设置为value,如果key不存在,这种情况下等同于set命令。当key存在时,什么也不做。
127.0.0.1:6379> setnx name nameval
(integer) 1#如果key被设置了返回1
127.0.0.1:6379> setnx name nameval
(integer) 0#如果key已经存在了返回0
127.0.0.1:6379> get name
"nameval"
setex
#setex
#设置key对应字符串value,并且设置key在给定的seconds时间之后超时过期。这个命令等效于下述两个命令:
set testkey value
expire testkey seconds
#setex是原子的,也可以把上述两个命令放在MULTI/EXEC块中执行的方式重现。相比连续执行上面两个命令,它更快,因为当redis当做缓存使用时,这个操作更加常用。
127.0.0.1:6379> setex name 5 namevalue
OK
127.0.0.1:6379> get name
"namevalue"
127.0.0.1:6379> get name
(nil)
setrange
#setrange
#这个命令的作用是覆盖key对应的string的一部分,从指定的offset开始,覆盖value的长度。如果offset比当前key对应string还长,那么这个string后面就补0以达到offset。不存在的keys被认为是空字符串,所以这个命令可以确保key有一个足够大的字符串,能在offset处设置value。
#个人理解:开始位置是0,从第几位开始替换到最后,不足的补零。
127.0.0.1:6379> set name testname@name.com
OK
127.0.0.1:6379> get name
"testname@name.com"
127.0.0.1:6379> SETRANGE name 9 test.com
(integer) 17
127.0.0.1:6379> get name
"testname@test.com"
127.0.0.1:6379> setrange name 17 other
(integer) 22
127.0.0.1:6379> get name
"testname@test.comother"
#补零操作
127.0.0.1:6379> setrange name 30 meiyou
(integer) 36
127.0.0.1:6379> get name
"testname@test.comother\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00meiyou"
#不存在的key
127.0.0.1:6379> setrange name2 10 other
(integer) 15
127.0.0.1:6379> get name2
"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00other"
getrange
#getrange
#返回key对应的字符串value的子串,自个子串是由start和end位移决定的(两者都在string内)。可以用负的位移来表示从string尾部开始数的下标。所以-1就是最后一个字符,-2就是倒数第二个,以此类推。这个函数超出范围的请求时,都把结果限制在string内。
127.0.0.1:6379> set name "this is a string"
OK
127.0.0.1:6379> GETRANGE name 0 3
"this"
127.0.0.1:6379> getrange name -3 -1
"ing"
127.0.0.1:6379> getrange name 0 -1
"this is a string"
127.0.0.1:6379> getrange name 10 100
"string"
6、2、2、2第二部分
incr
#incr
#对存储在指定key的数值执行原子的加1操作。
#如果指定的key不存在,那么在执行incr操作之前,会先把它的值设定为0.
#如果指定的key中存储的值不是字符串类型或者存储的字符串类型不能表示为一个整数,那么执行这个命令时服务器会返回一个错误((error) ERR value is not an integer or out of range)。
#这个操作仅限于64位的有符号整型数据。
#注意:由于redis并没有一个明确的类型来表示整型数据,所以这个操作是一个字符串操作。执行这个操作的时候,key对应存储的字符串被解析为10进制的64位有符号整型数据。
#事实上,redis内部采用整数形式来存储对应的整数值,所以对该类字符串值实际上是用整数保存,也就不存在存储整数的字符串表示所带来的额外消耗。
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set age1 10
OK
127.0.0.1:6379> incr age1
(integer) 11
127.0.0.1:6379> get age1
"11"
127.0.0.1:6379> incr age2
(integer) 1
127.0.0.1:6379> get age2
"1"
127.0.0.1:6379> keys *
1) "age2"
2) "age1"
#incr的原子操作是说即使多个客户端对同一个key发出incr命令,也决不会导致竞争的情况,例如如下情况永远不可能发生:客户端1和客户端2同时读出10,他们俩都对其加到11,然后将新值设置为11,最终值一定为12.read-increment-set操作完成时,其他客户端不会在同一时间执行任何命令。
#对字符串,get和set命令,它为key设置新值并返回原值。用处是,例如:你的系统每当有新用户访问时就用incr命令操作一个redis key。你希望每小时对这个信息收集一次,那么就可以get和set这个key,读取原值并赋值为0。
decr
#decr
#对key对应的数字做减一操作。如果key不存在,那么在操作之前,这个key对应的值会被设定为0。如果key有一个错误类型的value或者是一个不能表示成数字的字符串,就返回错误。这个操作最大支持在64位有符号的整型数字。
127.0.0.1:6379> get age1
"11"
127.0.0.1:6379> decr age1
(integer) 10
127.0.0.1:6379> get age1
"10"
127.0.0.1:6379> decr age4
(integer) -1
127.0.0.1:6379> get age4
"-1"
incrby
#incrby
#将key进行递增。如果key不存在,操作之前,key就会被置为0.如果key的value类型错误或者是个不能表示成数字的字符串,就返回错误。这个操作最多支持64位有符号的×××数字。
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set age 10
OK
127.0.0.1:6379> get age
"10"
127.0.0.1:6379> incrby age 5
(integer) 15
127.0.0.1:6379> get age
"15"
127.0.0.1:6379> incrby age2 2
(integer) 2
127.0.0.1:6379> get age2
"2"
decrby
#decrby
#将key对应的数字递减。如果key不存在,操作之前,key就会被置为0.如果key的value类型错误或者是个不能表示成数字的字符串,就返回错误。这个操作最多支持64位有符号的×××数字。
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set age 10
OK
127.0.0.1:6379> decrby age 5
(integer) 5
127.0.0.1:6379> get age
"5"
127.0.0.1:6379> decrby age2 5
(integer) -5
127.0.0.1:6379> get age2
"-5"
mset
#mset
#对应给定的keys到他们对应的values上。Mset会用新的value替代已经存在的value,就像普通的set命令一样。如果你不想覆盖已经存在的values,那么需要参考msetnx.
#mset是原子性的,所以所有给定的keys是一次性set的。客户端不可能看到这种一部分keys被更新而另外的没有改变的情况。
#其返回值总是OK,因为mset不会失败。
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> mset age1 age1val age2 age2val age3age3val
OK
127.0.0.1:6379> keys *
1) "age2"
2) "age1"
3) "age3"
mget
#mget
#返回所有指定的key的value。对于每个不对应string或者不存在的key,都返回特殊值nil。整因此如此,这个操作从来不会失败。
127.0.0.1:6379> keys *
1) "age2"
2) "age1"
3) "age3"
127.0.0.1:6379> mget age1 age2 age3 age4
1) "age1val"
2) "age2val"
3) "age3val"
4) (nil)
msetnx
#msetnx
#对应给定的keys到他们相应的values上。只要有一个values已经存在,MSETNX一个操作都不会执行。由于这种特性,MSETNX可以实现要么所有的操作都成功,要么一个都不执行,这个可以用来设置不同的key,来表示一个唯一的对象的不同字段。MSETNX是原子的,所以所有给定的keys是一次性set的。客户端不可能看到这种一部分keys被更新而另外的没有改变的情况。
#返回值,1如果所有的key被set,0如果没有key被set(至少其中有一个key是存在的。)
127.0.0.1:6379> keys *
1) "age2"
2) "age1"
3) "age3"
127.0.0.1:6379> mget age1 age2 age3
1) "age1val"
2) "age2val"
3) "age3val"
127.0.0.1:6379> msetnx age1 age11val age2 age22val
(integer) 0
127.0.0.1:6379> mget age1 age2
1) "age1val"
2) "age2val"
127.0.0.1:6379> msetnx age1 age11val age2 age22valage4 age4val
(integer) 0
127.0.0.1:6379> mget age1 age2 age4
1) "age1val"
2) "age2val"
3) (nil)
127.0.0.1:6379> msetnx age4 age4val age5 age5val
(integer) 1
127.0.0.1:6379> mget age4 age5
1) "age4val"
2) "age5val"
6、3列表类型(list)
6、3、1简介
List类型是一个链表结构的集合,其主要功能有push,pop,获取元素等。更详细的说,list类型是一个双端链表结构,我们可以通过相关操作进行集合的头部或者尾部添加删除元素,list的设计非常简单精巧,既可以作为栈(后进先出),又可以作为队列(先进先出),满足绝大多数要求。
一般意义上讲,列表就是有序元素的序列:10,20,1,2,3就是一个列表。但用数组实现的list和用linkedlist实现的list,在属性方面大不相同。
Redis list基于linkedlist实现,这意味着即使在一个list中有数百万个元素,在头部或尾部添加一个元素的操作,其时间复杂度也是常数级别的。用lpush命令在十个元素的list头部添加新元素和在千万元素list头部添加新元素的速度相同。
但是,在数组实现的list中利用索引访问元素的速度极快,而同样的操作在linkedlist实现的list上没有那么快。
Redislist用linkedlist实现的原因是:对于数据库系统来说,至关重要的特性是:能非常快的在很大的列表上添加元素,另一个重要因素是,redislist能在常数时间取得常数长度。
List可别用来实现聊天系统,还可以作为不同进程间传递消息的队列。关键是,你可以每次都以原先添加的顺序访问数据。这不需要任何SQL ORDER BY操作,将会非常快,也会很容易扩展到百万级别元素的规模。
例如在评级系统中,比如社会化新闻网站reddit.com,你可以把每个新提交的链接添加到一个list,用lrange可简单的对结果分页。
在博客引擎实现中,你可为每篇日志设置一个list,在该list中推入进博客评论等。
向redis list压入ID而不是实际的数据。
6、3、2操作
6、3、2、1第一部分
lpush
#栈部分
#lpush(从头部添加元素,先进后出-栈)
#将所有指定的值插入到存于key的列表的头部。如果key不存在,那么在进行push操作前会创建一个空列表。如果key对应的值不是一个list的话,那么会返回一个错误。可以使用一个命令把多个元素push进入列表,只需在命令末尾加上多个指定的参数。元素是从最左端的到最右端的、一个接一个的被插入到list的头部。所以对于这个命令例子:lpush list a b c ,返回的列表是c为第一个元素,b为第二个元素,a为第三个元素。返回值为在push操作后的list长度。
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> lpush list1 val1
(integer) 1
127.0.0.1:6379> lpush list1 val2
(integer) 2
127.0.0.1:6379> lpush list1 val3
(integer) 3
127.0.0.1:6379> keys *
1) "list1"
127.0.0.1:6379> lrange list1 0 -1(表示从头取到末尾)
1) "val3"
2) "val2"
3) "val1"
127.0.0.1:6379> lpush list2 val1 val2 val3
(integer) 3
127.0.0.1:6379> lrange list2 0 -1
1) "val3"
2) "val2"
3) "val1"
rpush
#队列部分(从尾部加入元素,先进先出-队列)
#向存于key的列表的尾部插入所有指定的值。如果key不存在,那么会创建一个空的列表然后再进行push操作。当key保存的不是一个列表,那么会返回一个错误。可以使用一个命令把多个元素打入队列。元素是从左到右一个接一个从列表尾部插入。
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> rpush list1 val1 val2 val3
(integer) 3
127.0.0.1:6379> lrange list1 0 -1
1) "val1"
2) "val2"
3) "val3"
127.0.0.1:6379> rpush list2 val1
(integer) 1
127.0.0.1:6379> rpush list2 val12
(integer) 2
127.0.0.1:6379> rpush list2 val3
(integer) 3
127.0.0.1:6379> lrange list2 0 -1
1) "val1"
2) "val12"
3) "val3"
lrange
#lrange(格式:lrange key start stop)
#返回存储在key的列表里指定范围内的元素。Start和end偏移量都是基于0的下标,即list的第一个元素下标是0(list的开头),第二个元素是下标1,以此类推。偏移量也可以是负数,表示偏移量是从list尾部开始计数。例如,-1表示列表的最后一个元素,-2是倒数第二个,以此类推。
#在不同的编程语言里,关于求范围函数的一致性:需要注意的是,如果你有一个list,里面的元素是0到100,那么lrange list 0 10这个命令会返回11个元素,即最右边的那个元素也会包含在内。在你使用的编程语言里,这一点可能是也可能不是跟那些求范围有关的函数都是一致的。
#超过范围的下标:当下标超过list范围的时候不会产生error。如果start比list尾部下标大的时候,会返回一个空列表。如果stop比list的实际尾部大的时候,redis会当它是list的最后一个元素的下标。
127.0.0.1:6379> lrange list1 0 -1
1) "list1val5"
2) "list1val4"
3) "list1val3"
4) "list1val2"
5) "list1val1"
127.0.0.1:6379> lrange list1 -3 -1
1) "list1val3"
2) "list1val2"
3) "list1val1"
127.0.0.1:6379> lrange list1 0 -3
1) "list1val5"
2) "list1val4"
3) "list1val3"
127.0.0.1:6379> lrange list1 0 3
1) "list1val5"
2) "list1val4"
3) "list1val3"
4) "list1val2"
127.0.0.1:6379> lrange list1 0 10
1) "list1val5"
2) "list1val4"
3) "list1val3"
4) "list1val2"
5) "list1val1"
linsert
#linsert(格式:linsert key before|after pivot value)
#把value插入存于key的列表中在基准值pivot的前面或后面。
#当key不存在时,这个list会被看做是空list,任何操作都不会发生。
#在key存在,但保存的不是一个list的时候,会返回error
#返回值为经过插入操作后的list长度,或者当pivot值找不到的时候返回-1.
127.0.0.1:6379> keys *
1) "list1"
127.0.0.1:6379> lrange list1 0 -1
1) "list1val5"
2) "list1val4"
3) "list1val3"
4) "list1val2"
5) "list1val1"
127.0.0.1:6379> linsert list1 before list1val3 list1val31
(integer) 6
127.0.0.1:6379> lrange list1 0 -1
1) "list1val5"
2) "list1val4"
3) "list1val31"
4) "list1val3"
5) "list1val2"
6) "list1val1"
127.0.0.1:6379> linsert list1 after list1val3list1val32
(integer) 7
127.0.0.1:6379> lrange list1 0 -1
1) "list1val5"
2) "list1val4"
3) "list1val31"
4) "list1val3"
5) "list1val32"
6) "list1val2"
7) "list1val1"
127.0.0.1:6379> linsert list1 before testval values
(integer) -1
127.0.0.1:6379> linsert list2 before testval values
(integer) 0
127.0.0.1:6379> lrange list2 0 -1
(empty list or set)
#知识延伸,
关于栈与队列的知识点,在自己博客中有写到
“http://ylcodes01.blog.51cto.com/5607366/1867337”
Linkedlist是双向链表,插入快,查询慢,具体描述参考Java编程思想第四版。
双向链表的操作可以查考java中“Queue的dequeue方法”,它可以操作链表的头部和尾部。
6、3、2、2第二部分
lset
#lset(将指定下标的元素替换掉)
#设置index位置的list元素的值为value。当index超出范围时会返回一个value。
127.0.0.1:6379> lrange list1 0 -1
1) "list1val5"
2) "list1val4"
3) "list1val31"
4) "list1val3"
5) "list1val32"
6) "list1val2"
7) "list1val1"
127.0.0.1:6379> lset list1 7 list1val7
(error) ERR index out of range
127.0.0.1:6379> lset list1 6 list1val6
OK
127.0.0.1:6379> lrange list1 -1 -1
1) "list1val6"
127.0.0.1:6379> lrange list1 0 -1
1) "list1val5"
2) "list1val4"
3) "list1val31"
4) "list1val3"
5) "list1val32"
6) "list1val2"
7) "list1val6"
lrem
#lrem(删除元素,返回删除的个数)
#从存于key的列表里移除前count次出现的值为value的元素。这个count参数通过以下几种方式影响这个操作:
Count>0:从头往尾移除值为value的元素。
(个人理解是从头到尾删除前几count个为value的元素。)
Count<0:< span="">从尾往头移除值为value的元素。
(个人理解是从尾往头删除前几count个为value的元素。)
Count=0:移除所有值为value的元素。
(个人理解是删除所有为value的元素。)
比如,lrem list -2 “hello”,会从存于list的列表里移除最后两个出现的hello,需要注意的是,如果list里没有存在key就会被当做空list处理,所以当key不存在的时候,这个命令返回0.
#返回值为被移除的元素个数。
127.0.0.1:6379> lrange list 0 -1
1)"list1"
2)"list1"
3)"list2"
4)"list3"
5)"list4"
6)"list5"
7)"list6"
8)"list7"
9)"list8"
10) "list1"
11) "list1"
12) "list2"
13) "list3"
14) "list4"
15) "list2"
16) "list2"
17) "list5"
18) "list2"
19) "list2"
20) "list6"
21) "list7"
22) "list7"
23) "list8"
127.0.0.1:6379> lrem list 2 list2
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1)"list1"
2)"list1"
3)"list3"
4)"list4"
5)"list5"
6)"list6"
7)"list7"
8)"list8"
9)"list1"
10) "list1"
11) "list3"
12) "list4"
13) "list2"
14) "list2"
15) "list5"
16) "list2"
17) "list2"
18) "list6"
19) "list7"
20) "list7"
21) "list8"
127.0.0.1:6379> lrem list -3 list2
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1)"list1"
2)"list1"
3)"list3"
4)"list4"
5)"list5"
6)"list6"
7)"list7"
8)"list8"
9)"list1"
10) "list1"
11) "list3"
12) "list4"
13) "list2"
14) "list5"
15) "list6"
16) "list7"
17) "list7"
18) "list8"
127.0.0.1:6379> lrem list 0 list7
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1)"list1"
2)"list1"
3)"list3"
4)"list4"
5)"list5"
6)"list6"
7)"list8"
8)"list1"
9)"list1"
10) "list3"
11) "list4"
12) "list2"
13) "list5"
14) "list6"
15) "list8"
6、3、2、3第三部分
ltrim
#ltrim
#修剪(trim)一个已经存在的list,这样list就会只包含指定范围的指定元素start和stop都是从0开始计数的,这里的0是列表里的第一个元素(表头),1是第二个元素,以此类推。
#例如:ltrim foobar 0 2将会对存储在foobar的列表进行修剪,只保留列表里的前三个元素。
#start和end也可以用负数来表示与表尾的偏移量,比如-1表示列表里的最后一个元素,-2表示列表里的倒数第二个元素,以此类推。
#超过范围的下标并不会产生错误:如果start超过列表尾部,或者start>end,结果会是列表变成空表(即该key会被移除)。如果end超过列表尾部,redis会将其当做列表的最后一个元素。
#ltrim的一个常见用法是和lpush/rpush一起使用,例如:
LPUSH mylist someelement
LTRIM mylist 0 99
#这一对命令会将一个新的元素push进列表里,并保证该列表不会增长到超过100个元素。这个是很有用的,比如当用redis来存储日志,需要特别注意的是,当用这种方式来使用ltrim的时候,操作复杂度是O(1),因为平均情况下,每次只有一个元素会被移除 。
127.0.0.1:6379> keys *
1) "list"
127.0.0.1:6379> lrange list 0 -1
1) "list1"
2) "list2"
3) "list3"
4) "list4"
5) "list5"
6) "list6"
7) "list7"
8) "list8"
127.0.0.1:6379> ltrim list 10 9
OK
127.0.0.1:6379> lrange list 0 -1
(empty list or set)
127.0.0.1:6379> rpush list list1 list2 list3 list4list5 list6 list7 list8
(integer) 8
127.0.0.1:6379> lrange list 0 -1
1) "list1"
2) "list2"
3) "list3"
4) "list4"
5) "list5"
6) "list6"
7) "list7"
8) "list8"
127.0.0.1:6379> ltrim list -3 -1
OK
127.0.0.1:6379> lrange list 0 -1
1) "list6"
2) "list7"
3) "list8"
127.0.0.1:6379> lrange list 0 -1
1) "list1"
2) "list2"
3) "list3"
4) "list4"
5) "list5"
6) "list6"
7) "list7"
8) "list8"
9) "list9"
127.0.0.1:6379> ltrim list 1 5
OK
127.0.0.1:6379> lrange list 0 -1
1) "list2"
2) "list3"
3) "list4"
4) "list5"
5) "list6"
127.0.0.1:6379> ltrim list 4 10
OK
127.0.0.1:6379> lrange list 0 -1
1) "list6"
lpop
#lpop(从list的头部删除元素,并返回删除元素)
#移除并且返回key对应list的第一个元素
#返回值:返回第一个元素的值,或者当key不存在时返回nil
127.0.0.1:6379> lrange list 0 -1
1) "list1"
2) "list2"
3) "list3"
4) "list4"
5) "list5"
6) "list6"
7) "list7"
8) "list8"
9) "list9"
127.0.0.1:6379> lpop list
"list1"
127.0.0.1:6379> lrange list 0 -1
1) "list2"
2) "list3"
3) "list4"
4) "list5"
5) "list6"
6) "list7"
7) "list8"
8) "list9"
127.0.0.1:6379> del list
(integer) 1
127.0.0.1:6379> lpop list
(nil)
rpop
#rpop(从list的尾部删除元素,并返回删除元素)
#移除并返回存于key的list的最后一个元素
#返回值:最后一个元素的值,或者当key不存在时返回nil
127.0.0.1:6379> rpop list
"list9"
127.0.0.1:6379> lrange list 0 -1
1) "list2"
2) "list3"
3) "list4"
4) "list5"
5) "list6"
6) "list7"
7) "list8"
127.0.0.1:6379> rpop list
(nil)
6、3、2、4第四部分
rpoplpush
#rpoplpush(格式: RPOPLPUSH source destination)
#原子性的返回并移除存储在source列表的最后一个元素(列表尾部元素),并把该元素放入存储在destination的列表的第一个元素位置(列表头部)。
例如:假设 source 存储着列表 a,b,c,destination存储着列表 x,y,z。 执行RPOPLPUSH 得到的结果是 source 保存着列表a,b ,而 destination 保存着列表c,x,y,z。
#如果source不存在,那么会返回nil值,并且不会执行任何操作。如果source和destination是同样的,那么这个操作等同于移除列表最后一个元素并且把该元素放在列表头部,所以这个命令也可以当做是一个旋转列表的命令。
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> rpush list1 list1val1 list1val2list1val3
(integer) 3
127.0.0.1:6379> lrange list1 0 -1
1) "list1val1"
2) "list1val2"
3) "list1val3"
127.0.0.1:6379> rpush list2 list2val1 list2val2list2val3
(integer) 3
127.0.0.1:6379> lrange list2 0 -1
1) "list2val1"
2) "list2val2"
3) "list2val3"
127.0.0.1:6379> rpoplpush list1 list2
"list1val3"
127.0.0.1:6379> lrange list1 0 -1
1) "list1val1"
2) "list1val2"
127.0.0.1:6379> lrange list2 0 -1
1) "list1val3"
2) "list2val1"
3) "list2val2"
4) "list2val3"
127.0.0.1:6379> del list1
(integer) 1
127.0.0.1:6379> rpoplpush list1 list2
(nil)
127.0.0.1:6379> del list2
(integer) 1
127.0.0.1:6379> rpoplpush list1 list2
(nil)
127.0.0.1:6379> rpush list1 list1val1 list1val2list1val3
(integer) 3
127.0.0.1:6379> rpoplpush list1 list2
"list1val3"
127.0.0.1:6379> lrange list1 0 -1
1) "list1val1"
2) "list1val2"
127.0.0.1:6379> lrange list2 0 -1
1) "list1val3"
lindex
#lindex(返回名称为key的list中index位置的元素)
#返回列表里的元素索引index存储在key里面。下标是从0开始索引的,所以0是表示第一个元素,1表示第二个元素,并以此类推。负数索引用于指定从列表尾部开始索引的元素。在这种方法下,-1表示最后一个元素,-2表示倒数第二个元素,并依次往前推。当key的位置不是一个列表的时候,会返回一个error。
#返回值:请求的对应元素,或者当index超过范围的时候返回nil。
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> rpush list1 list1val1 list1val2list1val3
(integer) 3
127.0.0.1:6379>
127.0.0.1:6379> lrange list1 0 -1
1) "list1val1"
2) "list1val2"
3) "list1val3"
127.0.0.1:6379> lindex list1 1
"list1val2"
127.0.0.1:6379> lindex list1 -1
"list1val3"
127.0.0.1:6379> lindex list1 -3
"list1val1"
127.0.0.1:6379> lindex list1 -4
(nil)
127.0.0.1:6379> lindex list1 5
(nil)
127.0.0.1:6379> lindex list2 5
(nil)
127.0.0.1:6379> keys *
1) "list1"
127.0.0.1:6379> lindex list2 test
(nil)
llen
#llen(返回元素的个数)
#返回存储在key里的list长度。如果key不存在,那么就被看做是空list,并且返回长度为0.当存储在key里的值不是一个list的话,会返回error 。
127.0.0.1:6379> keys *
1) "list1"
127.0.0.1:6379> lrange list1 0 -1
1) "list1val1"
2) "list1val2"
3) "list1val3"
127.0.0.1:6379> llen list1
(integer) 3
127.0.0.1:6379> llen list2
(integer) 0
6、4set无序集合和zset有序集合
6、4、1简介
set集合是string类型的无需集合,set是通过hashtable实现的,其元素是二进制安全的字符串。Set集合不允许重复元素。
集合特别适合表现对象之间的关系。例如用redis集合可以很容易实现标签功能。
6、4、2操作
6、4、2、1set无序集合部分
6、4、2、1、1第一部分
sadd
#sadd
#添加一个或多个指定的member元素到集合的key中,指定的一个或者多个元素member如果已经在集合key中存在则忽略,如果集合key不存在,则新建集合key,并添加member元素到集合key中。如果key的类型不是集合则返回错误。
#返回值:返回新成功添加到集合里元素的数量,不包括已经存在于集合中的元素。
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> sadd set1 set1val1
(integer) 1
127.0.0.1:6379> sadd set1 set1val2 set1val3
(integer) 2
127.0.0.1:6379> smembers set1
1) "set1val3"
2) "set1val2"
3) "set1val1"
127.0.0.1:6379> rpush list1 list1val1 list1val2
(integer) 2
127.0.0.1:6379> lrange list1 0 -1
1) "list1val1"
2) "list1val2"
127.0.0.1:6379> sadd list1 testval
(error) WRONGTYPE Operation against a key holding thewrong kind of value
127.0.0.1:6379> smembers list1
(error) WRONGTYPE Operation against a key holding thewrong kind of value
127.0.0.1:6379>
smembers
#smembers
#返回key集合所有的元素
127.0.0.1:6379> smembers set1
1) "set1val3"
2) "set1val2"
3) "set1val1"
srem
#srem
#在key集合中移除指定的元素,如果指定的元素不是key集合中的元素则忽略,如果key集合不存在则被视为一个空的集合,该命令返回0.如果key的类型不是一个集合,则返回错误。
#返回值:从集合中移除元素的个数,不包括不存在的成员。
127.0.0.1:6379> smembers set1
1) "set1val3"
2) "set1val2"
3) "set1val1"
127.0.0.1:6379> srem set1 set1val2
(integer) 1
127.0.0.1:6379> smembers set1
1) "set1val3"
2) "set1val1"
127.0.0.1:6379> srem set1 set1val1 set1val3
(integer) 2
127.0.0.1:6379> smembers set1
(empty list or set)
127.0.0.1:6379> sadd set2 set2val1
(integer) 1
127.0.0.1:6379> srem set2 testval
(integer) 0
127.0.0.1:6379> srem set3 testval
(integer) 0
spop
#spop
#随机返回被删除的key
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> sadd set1 set1val1 set1val2 set1val3set1val4 set1val5
(integer) 5
127.0.0.1:6379> smembers set1
1) "set1val4"
2) "set1val3"
3) "set1val2"
4) "set1val1"
5) "set1val5"
127.0.0.1:6379> spop set1
"set1val4"
127.0.0.1:6379> smembers set1
1) "set1val1"
2) "set1val2"
3) "set1val3"
4) "set1val5"
127.0.0.1:6379> spop set2
(nil)
127.0.0.1:6379> rpush list1 list1val1
(integer) 1
127.0.0.1:6379> spop list1
(error) WRONGTYPE Operation against a key holding thewrong kind of value
sdfii
#sdiff(返回两个集合的不同元素,哪个集合在前面,就以哪个集合为准)
#返回一个集合与给定集合的差集的元素。不存在的key认为是空集
#返回值为结果集的元素
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> sadd set1 a b c
(integer) 3
127.0.0.1:6379> sadd set2 c d e
(integer) 3
127.0.0.1:6379> smembers set1 set2
(error) ERR wrong number of arguments for 'smembers'command
127.0.0.1:6379> smembers set1
1) "c"
2) "a"
3) "b"
127.0.0.1:6379> smembers set2
1) "e"
2) "c"
3) "d"
127.0.0.1:6379> sdiff set1 set2
1) "a"
2) "b"
127.0.0.1:6379> sdiff set1 set3
1) "a"
2) "c"
3) "b"
127.0.0.1:6379> sdiff set3 set1
(empty list or set)
127.0.0.1:6379> sdiff set3 set4
(empty list or set)
127.0.0.1:6379> rpush list1 list1val1 list1val2
(integer) 2
127.0.0.1:6379> sdiff set1 list1
(error) WRONGTYPE Operation against a key holding thewrong kind of value
127.0.0.1:6379> sdiff list1 set4
(error) WRONGTYPE Operation against a key holding thewrong kind of value
sdfiistore
#sdiffstore
#将返回的不同元素存储到另外一个集合里(下面例子以set1为准,参考上述sdiff)
127.0.0.1:6379> keys *
1) "set2"
2) "set1"
127.0.0.1:6379> smembers set1
1) "c"
2) "a"
3) "b"
127.0.0.1:6379> smembers set2
1) "e"
2) "c"
3) "d"
127.0.0.1:6379> sdiffstore set3 set1 set2
(integer) 2
127.0.0.1:6379> smembers set3
1) "a"
2) "b"
127.0.0.1:6379> sdiffstore set4 set2 set1
(integer) 2
127.0.0.1:6379> smembers set4
1) "e"
2) "d"
127.0.0.1:6379> sdiffstore set5 set6 set7
(integer) 0
127.0.0.1:6379> keys *
1) "set4"
2) "set3"
3) "set2"
4) "set1"
6、4、2、1、2第二部分
sinter
#sinter
#返回指定的所有集合的成员的交集。如果key不存在则被认为是一个空的集合,当给定的集合为空的时候,结果也为空(一个集合为空,结果一直为空)
127.0.0.1:6379> keys *
1) "set2"
2) "set1"
127.0.0.1:6379> smembers set1
1) "c"
2) "a"
3) "b"
127.0.0.1:6379> smembers set2
1) "e"
2) "c"
3) "d"
127.0.0.1:6379> sinter set1 set2
1) "c"
127.0.0.1:6379> sinter set2 set2
1) "e"
2) "c"
3) "d"
127.0.0.1:6379> sinter set2 set1
1) "c"
127.0.0.1:6379> sinter set1 set3
(empty list or set)
127.0.0.1:6379> sinter set3 set1
(empty list or set)
127.0.0.1:6379> sinter set3 set4
(empty list or set)
sinterstore
#sinterstore
#把两个集合的结果集结果保存到一个新的集合中。如果这个新的集合是已经存在的,那么这个新的集合则会被重写。
#返回值为结果集中成员的个数。
127.0.0.1:6379> keys *
1) "set2"
2) "set1"
127.0.0.1:6379> sinterstore set3 set1 set2
(integer) 1
127.0.0.1:6379> smembers set3
1) "c"
127.0.0.1:6379> sadd set4 a b d
(integer) 3
127.0.0.1:6379> sinterstore set3 set1 set4
(integer) 2
127.0.0.1:6379> smembers set3
1) "a"
2) "b"
127.0.0.1:6379> sinterstore set3 set1 set5
(integer) 0
sunion
#sunion
#返回给定的多个集合的并集中的所有成员,不存在的key可以认为是空的集合。
#返回值为并集的成员列表。
127.0.0.1:6379> keys *
1) "set4"
2) "set2"
3) "set1"
127.0.0.1:6379> smembers set1
1) "c"
2) "a"
3) "b"
127.0.0.1:6379> smembers set2
1) "e"
2) "c"
3) "d"
127.0.0.1:6379> smembers set4
1) "a"
2) "d"
3) "b"
127.0.0.1:6379> sunion set1 set2 set4
1) "e"
2) "d"
3) "b"
4) "c"
5) "a"
127.0.0.1:6379> smembers set3
(empty list or set)
127.0.0.1:6379> sunion set1 set2 set3
1) "b"
2) "e"
3) "d"
4) "c"
5) "a"
sunionstore
#sunionstore
#将集合结果集存储在新的集合中,如果新的集合已经存在,那么会覆盖这个新的集合。
#返回值为结果集中元素的个数。
127.0.0.1:6379> keys *
1) "set4"
2) "set2"
3) "set1"
127.0.0.1:6379> del set4
(integer) 1
127.0.0.1:6379> sunionstore set3 set1 set2
(integer) 5
127.0.0.1:6379> smembers set3
1) "b"
2) "e"
3) "d"
4) "c"
5) "a"
127.0.0.1:6379> sunionstore set3 set1 set4
(integer) 3
127.0.0.1:6379> smembers set3
1) "a"
2) "c"
3) "b"
127.0.0.1:6379> sunionstore set3 set3 set3
(integer) 3
127.0.0.1:6379> sunionstore set3 set4 set5
(integer) 0
6、4、2、1、3第三部分
smove
#smove(把A的set集合中的一个元素移动到B的set集合中)
#将member从source集合移动到destination集合中. 对于其他的客户端,在特定的时间元素将会作为source或者destination集合的成员出现.
如果source 集合不存在或者不包含指定的元素,这smove命令不执行任何操作并且返回0.否则对象将会从source集合中移除,并添加到destination集合中去,如果destination集合已经存在该元素,则smove命令仅将该元素充source集合中移除. 如果source和destination不是集合类型,则返回错误.
#返回值:如果该元素成功移除,返回1.如果该元素不是 source集合成员,无任何操作,则返回0.
127.0.0.1:6379> keys *
1) "set2"
2) "set1"
127.0.0.1:6379> smembers set1
1) "c"
2) "a"
3) "b"
127.0.0.1:6379> smembers set2
1) "e"
2) "c"
3) "d"
127.0.0.1:6379> smove set1 set2 a
(integer) 1
127.0.0.1:6379> smembers set1
1) "c"
2) "b"
127.0.0.1:6379> smembers set2
1) "a"
2) "e"
3) "c"
4) "d"
127.0.0.1:6379> smove set1 set2 testval
(integer) 0
127.0.0.1:6379> smove set3 set1 testval
(integer) 0
scard
#scard(查看集合中元素的个数)
#返回集合存储的key的基数(集合元素的数量)
#返回值:集合的基数(元素的数量),如果key不存在,则返回0.
127.0.0.1:6379> smembers set1
1) "c"
2) "b"
127.0.0.1:6379> scard set1
(integer) 2
127.0.0.1:6379> scard set3
(integer) 0
sismember
#sismember
#返回成员 member 是否是存储的集合 key的成员.
#返回值:
如果member元素是集合key的成员,则返回1
如果member元素不是key的成员,或者集合key不存在,则返回0
127.0.0.1:6379> smembers set1
1) "c"
2) "b"
127.0.0.1:6379> sismember set1 a
(integer) 0
127.0.0.1:6379> sismember set3 testval
(integer) 0
srandmember
#srandmember
#仅提供key参数,那么随机返回key集合中的一个元素.
Redis 2.6开始, 可以接受 count 参数,如果count是整数且小于元素的个数,返回含有 count 个不同的元素的数组,如果count是个整数且大于集合中元素的个数时,仅返回整个集合的所有元素,当count是负数,则会返回一个包含count的绝对值的个数元素的数组,如果count的绝对值大于元素的个数,则返回的结果集里会出现一个元素出现多次的情况.
仅提供key参数时,该命令作用类似于SPOP命令, 不同的是SPOP命令会将被选择的随机元素从集合中移除, 而SRANDMEMBER仅仅是返回该随记元素,而不做任何操作.
#返回值
bulk-string-reply: 不使用count 参数的情况下该命令返回随机的元素,如果key不存在则返回nil.
array-reply: 使用count参数,则返回一个随机的元素数组,如果key不存在则返回一个空的数组.
127.0.0.1:6379> smembers set1
1) "c"
2) "b"
127.0.0.1:6379> srandmember set1
"b"
127.0.0.1:6379> srandmember set1
"c"
127.0.0.1:6379> srandmember set1 1
1) "b"
127.0.0.1:6379> srandmember set1 3
1) "c"
2) "b"
127.0.0.1:6379> srandmember set1 -3
1) "c"
2) "b"
3) "b"
127.0.0.1:6379> srandmember set1 -5
1) "b"
2) "b"
3) "b"
4) "b"
5) "c"
127.0.0.1:6379> srandmember set1 -2
1) "c"
2) "b"
127.0.0.1:6379> srandmember set1 -2
1) "c"
2) "c"
127.0.0.1:6379> srandmember set1 -1
1) "c"
127.0.0.1:6379> srandmember set1 -1
1) "b"
6、4、2、2zset有序集合部分
Zset是有序集合,可以做数据排行,跟solr和luecence用。Rank是做排序(过滤玩再排序,比如用户访问最多的)的,但是跟搜索/过滤不同。Rank,比如在每隔多长时间在内存中计算100W条数据中找到匹配度最高的。
6、4、2、2、1第一部分
zadd
#zadd
#将所有指定成员添加到键为key有序集合(sorted set)里面。 添加时可以指定多个分数/成员(score/member)对。 如果指定添加的成员已经是有序集合里面的成员,则会更新改成员的分数(scrore)并更新到正确的排序位置。
#如果key不存在,将会创建一个新的有序集合(sorted set)并将分数/成员(score/member)对添加到有序集合,就像原来存在一个空的有序集合一样。如果key存在,但是类型不是有序集合,将会返回一个错误应答。
#分数值是一个双精度的浮点型数字字符串。+inf和-inf都是有效值。
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> zadd zset1 1 one
(integer) 1
#同一位置插入不同的数据会新增
127.0.0.1:6379> zadd zset1 1 uno
(integer) 1
127.0.0.1:6379> zadd zset1 2 two 3 three
(integer) 2
127.0.0.1:6379> zadd zset1 -1 -1one
(integer) 1
127.0.0.1:6379> zrange zset1 0 -1 withscores
1)"-1one"
2) "-1"
3) "one"
4) "1"
5) "uno"
6) "1"
7) "two"
8) "2"
9)"three"
#同一位置插入相同的值不会新增
10) "3"127.0.0.1:6379> zadd set1 2 two
(integer) 1
127.0.0.1:6379> zrange zset1 0 -1 withscores
1)"-1one"
2) "-1"
3) "one"
4) "1"
5) "uno"
6) "1"
7) "two"
8) "2"
9)"three"
10) "3"
127.0.0.1:6379> zadd zset1 4 two
(integer) 0
#不同位置插入相同的值,那么会变动位置,原位置数据被删除
127.0.0.1:6379> zrange zset1 0 -1 withscores
1)"-1one"
2) "-1"
3) "one"
4) "1"
5) "uno"
6) "1"
7)"three"
8) "3"
9) "two"
10) "4"
zrange
#zrange
#根据指定的index返回成员列表
127.0.0.1:6379> zrange zset1 0 -1 withscores
1)"-1one"
2) "-1"
3) "one"
4) "1"
5) "uno"
6) "1"
7) "two"
8) "2"
9)"three"
10) "3"
127.0.0.1:6379> zrange zset1 0 3 withscores
1) "-1one"
2) "-1"
3) "one"
4) "1"
5) "uno"
6) "1"
7) "two"
8) "2"
127.0.0.1:6379> zrange zset1 1 10 withscores
1) "one"
2) "1"
3) "uno"
4) "1"
5) "two"
6) "2"
7) "three"
8) "3"
127.0.0.1:6379> zrange zset1 -3 -1 withscores
1) "uno"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"
#下述是否加withscores的区别
127.0.0.1:6379> zrange set1 0 -1
1) "1val"
2) "6val"
3) "2val"
4) "7val"
5) "8val"
127.0.0.1:6379> zrange set1 0 -1 withscores
1)"1val"
2) "1"
3)"6val"
4) "6"
5)"2val"
6) "7"
7)"7val"
8) "7"
9)"8val"
10) "8"
6、4、2、2、2第二部分
zrem
#zrem(从排序的集合中删除一个或多个成员)
#当key存在,但是其不是有序集合类型,就返回一个错误
#返回值为从有序集合中删除的成员个数,不包括不存在的成员。
127.0.0.1:6379> zrange zset1 0 -1 withscores
1)"-1one"
2) "-1"
3) "one"
4) "1"
5) "uno"
6) "1"
7)"three"
8) "3"
9) "two"
10) "4"
127.0.0.1:6379> zrem zset1 three
(integer) 1
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "-1one"
2) "-1"
3) "one"
4) "1"
5) "uno"
6) "1"
7) "two"
8) "4"
127.0.0.1:6379> zrem zset1 one two
(integer) 2
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "-1one"
2) "-1"
3) "uno"
4) "1"
zincrby
#zincrby
#为有序集key的成员member的score值加上增量increment。如果key中不存在member,就在key中添加一个member,score是increment(就好像它之前的score是0.0)。如果key不存在,就创建一个只含有指定member成员的有序集合。
当key不是有序集类型时,返回一个错误。
score值必须是字符串表示的整数值或双精度浮点数,并且能接受double精度的浮点数。也有可能给一个负数来减少score的值。
#返回值: member成员的新score值,以字符串形式表示。
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "-1one"
2) "-1"
3) "uno"
4) "1"
127.0.0.1:6379> zincrby zset1 3 uno
"4"
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "-1one"
2) "-1"
3) "uno"
4) "4"
127.0.0.1:6379> zrange zset2 0 -1 withscores
(empty list or set)
127.0.0.1:6379> zincrby zset2 2 one
"2"
127.0.0.1:6379> zrange zset2 0 -1 withscores
1) "one"
2) "2"
zrangebyscore
#zrangebyscore(找到指定区间范围的数据进行返回)
#如果M是常量(比如,用limit总是请求前10个元素),你可以认为是O(log(N))。
返回key的有序集合中的分数在min和max之间的所有元素(包括分数等于max或者min的元素)。元素被认为是从低分到高分排序的。
具有相同分数的元素按字典序排列(这个根据redis对有序集合实现的情况而定,并不需要进一步计算)。
可选的LIMIT参数指定返回结果的数量及区间(类似SQL中SELECT LIMIT offset, count)。注意,如果offset太大,定位offset就可能遍历整个有序集合,这会增加O(N)的复杂度。
可选参数WITHSCORES会返回元素和其分数,而不只是元素。这个选项在redis2.0之后的版本都可用。
#返回值: 指定分数范围的元素列表(也可以返回他们的分数)。
#注意下述的数值范围是根据指定数值下标取的值,而不是根据序号,注意跟list的不同。
127.0.0.1:6379> zrange zset1 0 -1 withscores
1)"-1one"
2) "-1"
3) "two"
4) "2"
5)"three"
6) "3"
7) "uno"
8) "4"
9)"five"
10) "5"
11) "six"
12) "6"
13) "nine"
14) "9"
127.0.0.1:6379> zrangebyscore zset1 1 3
1) "two"
2) "three"
127.0.0.1:6379> zrangebyscore zset1 0 -1
(empty list or set)
127.0.0.1:6379> zrangebyscore zset1 0 6
1) "two"
2) "three"
3) "uno"
4) "five"
5) "six"
127.0.0.1:6379> zrangebyscore zset1 0 8
1) "two"
2) "three"
3) "uno"
4) "five"
5) "six"
127.0.0.1:6379> zrangebyscore zset1 5 9
1) "five"
2) "six"
3) "nine"
127.0.0.1:6379> zrangebyscore zset1 5 10
1) "five"
2) "six"
3) "nine"
127.0.0.1:6379> zrangebyscore zset1 -1 -1
1) "-1one"
zremrangebyrank
#移除有序集key中,指定排名(rank)区间内的所有成员。下标参数start和stop都以0为底,0处是分数最小的那个元素。这些索引也可是负数,表示位移从最高分处开始数。例如,-1是分数最高的元素,-2是分数第二高的,依次类推。
127.0.0.1:6379> zrange set1 0 -1 withscores
1)"0val"
2) "0"
3)"1val"
4) "1"
5)"2val"
6) "2"
7)"3val"
8) "3"
9)"4val"
10) "4"
11) "5val"
12) "5"
127.0.0.1:6379> zremrangebyrank set1 -1 1
(integer) 0
127.0.0.1:6379> zremrangebyrank set1 0 3
(integer) 4
127.0.0.1:6379> zrange set1 0 -1 withscores
1) "4val"
2) "4"
3) "5val"
4) "5"
127.0.0.1:6379> zremrangebyrank set1 1 1
(integer) 1
127.0.0.1:6379> zrange set1 0 -1 withscores
1) "4val"
2) "4"
127.0.0.1:6379> del set1
(integer) 1
127.0.0.1:6379> zadd set1 0 0val 1 1val 2 2val 3 3val4 4val 5 5val
(integer) 6
127.0.0.1:6379> zremrangebyrank set1 1 3
(integer) 3
127.0.0.1:6379> zrange set1 0 -1 withscores
1) "0val"
2) "0"
3) "4val"
4) "4"
5) "5val"
6) "5"
zremrangebyscore(删除指定序号)
#移除有序集key中,所有score值介于min和max之间(包括等于min或max)的成员。 自版本2.1.6开始,score值等于min或max的成员也可以不包括在内
#返回值: 删除的元素的个数。
127.0.0.1:6379> zrange set1 0 -1 withscores
1)"0val"
2) "0"
3)"1val"
4) "1"
5)"2val"
6) "2"
7)"3val"
8) "3"
9)"4val"
10) "4"
11) "7val"
12) "7"
13) "8val"
14) "8"
127.0.0.1:6379> zremrangebyscore set1 2 4
(integer) 3
127.0.0.1:6379> zrange set1 0 -1 withscores
1) "0val"
2) "0"
3) "1val"
4) "1"
5) "7val"
6) "7"
7) "8val"
8) "8"
127.0.0.1:6379> zremrangebyscore set1 3 4
(integer) 0
127.0.0.1:6379> zrange set1 0 -1 withscores
1) "0val"
2) "0"
3) "1val"
4) "1"
5) "7val"
6) "7"
7) "8val"
8) "8"
127.0.0.1:6379> zremrangebyscore set1 7 10
(integer) 2
127.0.0.1:6379> zrange set1 0 -1 withscores
1) "0val"
2) "0"
3) "1val"
4) "1"
6、4、2、2、3第三部分
zrank
#zrank(确定在排序集合成员的索引,从小到大排序,升序排序之后再找索引,注意,一个是顺序号,一个是索引,zrank返回的索引,与zrevrank相反)
#返回有序集key中成员member的排名。其中有序集成员按score值递增(从小到大)顺序排列。排名以0为底,也就是说,score值最小的成员排名为0。
使用ZREVRANK命令可以获得成员按score值递减(从大到小)排列的排名。
返回值:如果member是有序集key的成员,返回integer-reply:member的排名。
如果member不是有序集key的成员,返回bulk-string-reply:nil。
127.0.0.1:6379> zrange set1 0 -1 withscores
1)"1val"
2) "1"
3)"6val"
4) "6"
5)"2val"
6) "7"
7)"7val"
8) "7"
9)"8val"
10) "8"
127.0.0.1:6379> zrank set1 2val
(integer) 2
127.0.0.1:6379> zrank set1 otherval
(nil)
zrevrank(返回排序索引,从大到小排序,降序排序之后再找索引。与zrank相反。)
#返回有序集key中成员member的排名,其中有序集成员按score值从大到小排列。排名以0为底,也就是说,score值最大的成员排名为0。
使用ZRANK命令可以获得成员按score值递增(从小到大)排列的排名。
返回值
如果member是有序集key的成员,返回integer-reply:member的排名。
如果member不是有序集key的成员,返回bulk-string-reply:nil。
127.0.0.1:6379> zrange set1 0 -1 withscores
1)"1val"
2) "1"
3)"6val"
4) "6"
5)"2val"
6) "7"
7)"7val"
8) "7"
9)"8val"
10) "8"
127.0.0.1:6379> zrevrank set1 7val
(integer) 1
127.0.0.1:6379> zrevrank set1 8val
(integer) 0
127.0.0.1:6379> zrevrank set1 1val
(integer) 4
127.0.0.1:6379> zrevrank set1 otherval
(nil)
zrangebyscore(返回有序集合中指定分数(不是指索引)区间内的成员,分数由低到高排序)
127.0.0.1:6379> zrange set1 0 -1 withscores
1)"1val"
2) "1"
3)"6val"
4) "6"
5)"2val"
6) "7"
7)"7val"
8) "7"
9)"8val"
10) "8"
127.0.0.1:6379> zrevrank set1 7val
(integer) 1
127.0.0.1:6379> zrevrank set1 8val
(integer) 0
127.0.0.1:6379> zrevrank set1 1val
(integer) 4
127.0.0.1:6379> zrevrank set1 otherval
(nil)
127.0.0.1:6379> zrangebyscore set1 0 1
1) "1val"
127.0.0.1:6379> zrangebyscore set1 0 5
1) "1val"
127.0.0.1:6379> zrangebyscore set1 1 5
1) "1val"
127.0.0.1:6379> zrangebyscore set1 1 7
1) "1val"
2) "6val"
3) "2val"
4) "7val"
127.0.0.1:6379> zrangebyscore set1 1 7 withscores
1) "1val"
2) "1"
3) "6val"
4) "6"
5) "2val"
6) "7"
7) "7val"
8) "7"
6、4、2、2、4第四部分
zcard
#zcard(获取一个排序的集合中的成员数量)
#返回值: key存在的时候,返回有序集的元素个数,否则返回0。
127.0.0.1:6379> zrange set1 0 -1
1) "1val"
2) "6val"
3) "2val"
4) "7val"
5) "8val"
127.0.0.1:6379> zrange set1 0 -1 withscores
1)"1val"
2) "1"
3)"6val"
4) "6"
5)"2val"
6) "7"
7)"7val"
8) "7"
9)"8val"
10) "8"
127.0.0.1:6379> zcard set1
(integer) 5
127.0.0.1:6379> zcard set2
(integer) 0
zcount
#zcount(返回分数范围内的成员数量)
#返回有序集key中,score值在min和max之间(默认包括score值等于min或max)的成员。
#返回值:integer-reply: 指定分数范围的元素个数。
127.0.0.1:6379> zrange set1 0 -1 withscores
1)"1val"
2) "1"
3)"6val"
4) "6"
5)"2val"
6) "7"
7)"7val"
8) "7"
9)"8val"
10) "8"
127.0.0.1:6379> zcount set1 0 2
(integer) 1
127.0.0.1:6379> zcount set1 0 1
(integer) 1
127.0.0.1:6379> zcount set1 1 1
(integer) 1
127.0.0.1:6379> zcount set1 1 5
(integer) 1
127.0.0.1:6379> zcount set1 1 7
(integer) 4
6、4、2、2、5第五部分
zremrangebyrank(在排序设置的所有成员在给定的索引中删除)
#移除有序集key中,指定排名(rank)区间内的所有成员。下标参数start和stop都以0为底,0处是分数最小的那个元素。这些索引也可是负数,表示位移从最高分处开始数。例如,-1是分数最高的元素,-2是分数第二高的,依次类推。
返回值: 被移除成员的数量。
127.0.0.1:6379> zrange set1 0 -1 withscores
1)"1val"
2) "1"
3)"6val"
4) "6"
5)"2val"
6) "7"
7)"7val"
8) "7"
9)"8val"
10) "8"
127.0.0.1:6379> zremrangebyrank set1 2 3
(integer) 2
127.0.0.1:6379> zrange set1 0 -1 withscores
1) "1val"
2) "1"
3) "6val"
4) "6"
5) "8val"
6) "8"
127.0.0.1:6379> zremrangebyrank set1 -2 -1
(integer) 2
127.0.0.1:6379> zrange set1 0 -1 withscores
1) "1val"
2) "1"
127.0.0.1:6379> zremrangebyrank set1 0 0
(integer) 1
127.0.0.1:6379> zrange set1 0 -1 withscores
(empty list or set)
127.0.0.1:6379> zrange set1 0 -1 withscores
1)"0val"
2) "0"
3)"1val"
4) "1"
5)"2val"
6) "2"
7)"3val"
8) "3"
9)"4val"
10) "4"
11) "5val"
12) "5"
127.0.0.1:6379> zremrangebyrank set1 0 1
(integer) 2
127.0.0.1:6379> zrange set1 0 -1 withscores
1) "2val"
2) "2"
3) "3val"
4) "3"
5) "4val"
6) "4"
7) "5val"
8) "5"
127.0.0.1:6379> zremrangebyrank set1 0 0
(integer) 1
127.0.0.1:6379> zrange set1 0 -1 withscores
1) "3val"
2) "3"
3) "4val"
4) "4"
5) "5val"
6) "5"
127.0.0.1:6379> zremrangebyrank set1 1 1
(integer) 1
127.0.0.1:6379> zrange set1 0 -1 withscores
1) "3val"
2) "3"
3) "5val"
4) "5"
127.0.0.1:6379> zrange set1 0 -1 withscores
1)"0val"
2) "0"
3)"1val"
4) "1"
5)"2val"
6) "2"
7)"3val"
8) "3"
9)"4val"
10) "4"
11) "5val"
12) "5"
127.0.0.1:6379> zremrangebyrank set1 -3 0
(integer) 0
127.0.0.1:6379> zremrangebyrank set1 -3 -1
(integer) 3
127.0.0.1:6379> zrange set1 0 -1 withscores
1) "0val"
2) "0"
3) "1val"
4) "1"
5) "2val"
6) "2"
zremrangebyscore(在排序设置的所有成员在给定的序号中删除)
#移除有序集key中,所有score值介于min和max之间(包括等于min或max)的成员。
#返回值: 删除的元素的个数。
127.0.0.1:6379> zrange set1 0 -1 withscores
1)"0val"
2) "0"
3)"2val"
4) "2"
5)"3val"
6) "3"
7)"4val"
8) "4"
9)"5val"
10) "5"
11) "7val"
12) "7"
127.0.0.1:6379> zrange set1 0 -1
1) "0val"
2) "2val"
3) "3val"
4) "4val"
5) "5val"
6) "7val"
127.0.0.1:6379> keys *
1) "set1"
127.0.0.1:6379> zremrangebyscore set1 3 5
(integer) 3
#按序号升序排序
127.0.0.1:6379> zrange set1 0 -1 withscores
1) "0val"
2) "0"
3) "2val"
4) "2"
5) "7val"
6) "7"
127.0.0.1:6379> zrange set1 0 -1
1) "0val"
2) "2val"
3) "7val"
6、5hash
6、5、1操作
hset
#hset
设置 key 指定的哈希集中指定字段的值。
如果 key 指定的哈希集不存在,会创建一个新的哈希集并与 key 关联。
如果字段在哈希集中存在,它将被重写。
返回值
integer-reply:含义如下
1如果field是一个新的字段
0如果field原来在map里面已经存在
127.0.0.1:6379> hset myhash field1 hello
(integer) 1
127.0.0.1:6379> hget myhash field1
"hello"
hget
#hget
返回 key 指定的哈希集中该字段所关联的值
返回值
bulk-string-reply:该字段所关联的值。当字段不存在或者 key 不存在时返回nil。
127.0.0.1:6379> hset myhash field1 hello
(integer) 1
127.0.0.1:6379> hget myhash field1
"hello"
127.0.0.1:6379> hget myhash field2
(nil)
127.0.0.1:6379> hget mytest field
(nil)
hkeys
#hkeys
返回 key 指定的哈希集中所有字段的名字。
返回值
array-reply:哈希集中的字段列表,当 key 指定的哈希集不存在时返回空列表。
127.0.0.1:6379> hset myhash field1 hello
(integer) 1
127.0.0.1:6379> hset myhash field2 val2
(integer) 1
127.0.0.1:6379> hset myhash field3 val3
(integer) 1
127.0.0.1:6379> hset myhash field4 val4
(integer) 1
127.0.0.1:6379> hset myhash filed5 val5
(integer) 1
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "field2"
3) "field3"
4) "field4"
5) "filed5"
hdel
#hdel
从 key 指定的哈希集中移除指定的域。在哈希集中不存在的域将被忽略。
如果 key 指定的哈希集不存在,它将被认为是一个空的哈希集,该命令将返回0。
返回值
integer-reply: 返回从哈希集中成功移除的域的数量,不包括指出但不存在的那些域
历史
在 2.4及以上版本中 :可接受多个域作为参数。小于 2.4版本 的 Redis 每次调用只能移除一个域 要在早期版本中以原子方式从哈希集中移除多个域,可用MULTI/EXEC块。
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "field2"
3) "field3"
4) "field4"
5) "filed5"
127.0.0.1:6379> hdel myhash field2
(integer) 1
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "field3"
3) "field4"
4) "filed5"
127.0.0.1:6379> hdel myhash field3 field4
(integer) 2
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "filed5"
127.0.0.1:6379> hdel myhash testfield
(integer) 0
127.0.0.1:6379> hdel mytest testfield
(integer) 0
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "filed5"
127.0.0.1:6379> hkeys mytest
(empty list or set)
hlen
#hlen
返回 key 指定的哈希集包含的字段的数量。
返回值
integer-reply: 哈希集中字段的数量,当 key 指定的哈希集不存在时返回 0
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "filed5"
127.0.0.1:6379> hlen myhash
(integer) 2
hmset
#hmset(可同时设置多个值,hset只能一次设置一个)
设置 key 指定的哈希集中指定字段的值。该命令将重写所有在哈希集中存在的字段。如果 key指定的哈希集不存在,会创建一个新的哈希集并与 key 关联
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "filed5"
127.0.0.1:6379> hmset myhash field2 val2 field3 val3field4 val4
OK
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "filed5"
3) "field2"
4) "field3"
5) "field4"
127.0.0.1:6379> hmset myhash field2 val22 field3 val33
OK
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "filed5"
3) "field2"
4) "field3"
5) "field4"
127.0.0.1:6379> hget myhash field2
"val22"
127.0.0.1:6379> hget myhash field3
"val33"
127.0.0.1:6379> hmget myhash field2 field3
1) "val22"
2) "val33"
hmget
#hmget
返回 key 指定的哈希集中指定字段的值。
对于哈希集中不存在的每个字段,返回 nil 值。因为不存在的keys被认为是一个空的哈希集,对一个不存在的 key 执行 HMGET 将返回一个只含有 nil 值的列表
返回值
array-reply:含有给定字段及其值的列表,并保持与请求相同的顺序。
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "filed5"
3) "field2"
4) "field3"
5) "field4"
127.0.0.1:6379> hmget myhash field4
1) "val4"
127.0.0.1:6379> hmget myhash field1 field2 field3field99
1) "hello"
2) "val22"
3) "val33"
4) (nil)
127.0.0.1:6379> hmget mytest field2 field3
1) (nil)
2) (nil)
hincrby
#hincrby
增加 key 指定的哈希集中指定字段的数值。如果 key 不存在,会创建一个新的哈希集并与 key 关联。如果字段不存在,则字段的值在该操作执行前被设置为 0
HINCRBY 支持的值的范围限定在 64位 有符号整数
返回值
integer-reply:增值操作执行后的该字段的值。
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "filed5"
3) "field2"
4) "field3"
5) "field4"
127.0.0.1:6379> hget myhash field2
"val22"
127.0.0.1:6379> hincrby myhash field2 1
(error) ERR hash value is not an integer
127.0.0.1:6379> hset myhash field6 1
(integer) 1
127.0.0.1:6379> hincrby myhash field6 2
(integer) 3
127.0.0.1:6379> hget myhash field6
"3"
127.0.0.1:6379> hincrby myhash field7 2
(integer) 2
127.0.0.1:6379> hget myhash field7
"2"
hexists
#hexists
返回hash里面key是否存在的标志
返回值
integer-reply, 含义如下:
1 哈希集中含有该字段。
0 哈希集中不含有该存在字段,或者key不存在。
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "filed5"
3) "field2"
4) "field3"
5) "field4"
6) "field6"
7) "field7"
127.0.0.1:6379> hexists myhash field2
(integer) 1
127.0.0.1:6379> hexists myhash fieldtest
(integer) 0
hvals
#hval
返回 key 指定的哈希集中所有字段的值。
返回值
array-reply:哈希集中的值的列表,当 key 指定的哈希集不存在时返回空列表。
例子
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "filed5"
3) "field2"
4) "field3"
5) "field4"
6) "field6"
7) "field7"
127.0.0.1:6379> hvals myhash
1) "hello"
2) "val5"
3) "val22"
4) "val33"
5) "val4"
6) "3"
7) "2"
127.0.0.1:6379> hvals mytesthash
(empty list or set)
hsetnx
#hsetnx
只在 key 指定的哈希集中不存在指定的字段时,设置字段的值。如果 key 指定的哈希集不存在,会创建一个新的哈希集并与 key 关联。如果字段已存在,该操作无效果。
返回值
integer-reply:含义如下
1:如果字段是个新的字段,并成功赋值
0:如果哈希集中已存在该字段,没有操作被执行
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "filed5"
3) "field2"
4) "field3"
5) "field4"
6) "field6"
7) "field7"
127.0.0.1:6379> hsetnx myhash field7 val7
(integer) 0
127.0.0.1:6379> hsetnx myhash field8 val8
(integer) 1
127.0.0.1:6379> hget myhash field8
"val8"
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "filed5"
3) "field2"
4) "field3"
5) "field4"
6) "field6"
7) "field7"
8) "field8"
hgetall
#hgetall
返回 key 指定的哈希集中所有的字段和值。返回值中,每个字段名的下一个是它的值,所以返回值的长度是哈希集大小的两倍
返回值
array-reply:哈希集中字段和值的列表。当 key 指定的哈希集不存在时返回空列表。
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "filed5"
3) "field2"
4) "field3"
5) "field4"
6) "field6"
7) "field7"
8) "field8"
127.0.0.1:6379> hgetall myhash
1)"field1"
2)"hello"
3)"filed5"
4)"val5"
5)"field2"
6)"val22"
7)"field3"
8)"val33"
9)"field4"
10) "val4"
11) "field6"
12) "3"
13) "field7"
14) "2"
15) "field8"
16) "val8"
hstrlen
#hstrlen
返回hash指定field的value的字符串长度,如果hash或者field不存在,返回0.
返回值
integer-reply:返回hash指定field的value的字符串长度,如果hash或者field不存在,返回0.
127.0.0.1:6379> hgetall myhash
1)"field1"
2)"hello"
3)"filed5"
4)"val5"
5)"field2"
6)"val22"
7)"field3"
8)"val33"
9)"field4"
10) "val4"
11) "field6"
12) "3"
13) "field7"
14) "2"
15) "field8"
16) "val8"
127.0.0.1:6379> hstrlen myhash field4
(integer) 4
127.0.0.1:6379> hstrlen myhash field10
(integer) 0
127.0.0.1:6379> hstrlen myhashtest testfield
(integer) 0
hincrbyfloat
#hincrbyfloat
为指定key的hash的field字段值执行float类型的increment加。如果field不存在,则在执行该操作前设置为0.如果出现下列情况之一,则返回错误:
field的值包含的类型错误(不是字符串)。
当前field或者increment不能解析为一个float类型。
此命令的确切行为与INCRBYFLOAT命令相同,请参阅INCRBYFLOAT命令获取更多信息。
返回值
bulk-string-reply: field执行increment加后的值
实现细节
该命令始终是在复制和模仿HSET,因此,在底层的浮点数运算不会出现数据不一致性问题。
127.0.0.1:6379> hgetall myhash
1)"field1"
2)"hello"
3)"filed5"
4)"val5"
5)"field2"
6)"val22"
7)"field3"
8)"val33"
9)"field4"
10) "val4"
11) "field6"
12) "3"
13) "field7"
14) "2"
15) "field8"
16) "val8"
127.0.0.1:6379> HINCRBYFLOAT myhash field7 10.00
"22"
127.0.0.1:6379> HINCRBYFLOAT myhash field7 10.111
"32.111"
127.0.0.1:6379> hincrbyfloat myhash field8 223
(error) ERR hash value is not a valid float
127.0.0.1:6379> hincrbyfloat myhash field9 1.1109
"1.1109"
127.0.0.1:6379> hget myhash field9
"1.1109"
127.0.0.1:6379> hgetall myhash
1)"field1"
2)"hello"
3)"filed5"
4)"val5"
5)"field2"
6)"val22"
7)"field3"
8)"val33"
9)"field4"
10) "val4"
11) "field6"
12) "3"
13) "field7"
14) "32.111"
15) "field8"
16) "val8"
17) "field9"
18) "1.1109"
6、6高级命令及特性一
exists
#exists判断key是否存在
返回值
integer-reply,如下的整数结果
1 如果key存在
0 如果key不存在
127.0.0.1:6379> keys *
1) "set1"
127.0.0.1:6379> exists set1
(integer) 1
127.0.0.1:6379> exists set2
(integer) 0
expire
#expire
设置key的过期时间,超过时间后,将会自动删除该key。在Redis的术语中一个key的相关超时是不确定的。
超时后只有对key执行DEL命令或者SET命令或者GETSET时才会清除。 这意味着,从概念上讲所有改变key的值的操作都会使他清除。例如,INCR递增key的值,执行LPUSH操作,或者用HSET改变hash的field所有这些操作都会触发删除动作。
使用PERSIST命令可以清除超时,使其变成一个永久的key。
如果key被RENAME命令修改,相关的超时时间会转移到新key上面。
如果key被RENAME命令修改,比如原来就存在Key_A,然后调用RENAME Key_B Key_A命令,这时不管原来Key_A是永久的还是设置为超时的,都会由Key_B的有效期状态覆盖。
刷新过期时间
对已经有过期时间的key执行EXPIRE操作,将会更新它的过期时间。有很多应用有这种业务场景,例如记录会话的session。
返回值
integer-reply, 具体的:
1 如果成功设置过期时间。
0 如果key不存在或者不能设置过期时间。
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set name1 name1val
OK
127.0.0.1:6379> get name1
"name1val"
#设置超时时间10秒
127.0.0.1:6379> expire name1 10
(integer) 1
127.0.0.1:6379> ttl name1
(integer) 8
127.0.0.1:6379> ttl name1
(integer) 4
127.0.0.1:6379> ttl name1
(integer) -2
127.0.0.1:6379> get name1
(nil)
127.0.0.1:6379> set name1 name1val
OK
127.0.0.1:6379> ttl name1
(integer) -1
#更多操作参考“http://www.redis.cn/commands/expire.html”
persist
#persist
移除给定key的生存时间,将这个 key 从『易失的』(带生存时间 key )转换成『持久的』(一个不带生存时间、永不过期的 key )。
返回值
integer-reply, 只有以下两种值:
当生存时间移除成功时,返回 1 .
如果 key 不存在或 key 没有设置生存时间,返回 0 .
127.0.0.1:6379> get name1
"name1val"
127.0.0.1:6379> persist name1
(integer) 0
127.0.0.1:6379> set name2 name2val
OK
127.0.0.1:6379> expire name2 10
(integer) 1
127.0.0.1:6379> ttl name2
(integer) 8
127.0.0.1:6379> persist name2
(integer) 1
127.0.0.1:6379> get name2
"name2val"
127.0.0.1:6379> ttl name2
(integer) -1
rename
#rename
将key重命名为newkey,如果key与newkey相同,将返回一个错误。如果newkey已经存在,则值将被覆盖。
127.0.0.1:6379> set name3 name3val
OK
127.0.0.1:6379> get name3
"name3val"
127.0.0.1:6379> expire name3 50
(integer) 1
127.0.0.1:6379> ttl name3
(integer) 48
127.0.0.1:6379> rename name3 name4
OK
127.0.0.1:6379> ttl name3
(integer) -2
127.0.0.1:6379> ttl name4
(integer) 31
127.0.0.1:6379> get name4
"name3val"
127.0.0.1:6379> persist name4
(integer) 1
127.0.0.1:6379> ttl name4
(integer) -1
127.0.0.1:6379> get name4
"name3val"
127.0.0.1:6379> set name5 name5val
OK
127.0.0.1:6379> expire name5 20
(integer) 1
127.0.0.1:6379> rename name5 name4
OK
127.0.0.1:6379> ttl name5
(integer) -2
127.0.0.1:6379> ttl name4
(integer) 7
127.0.0.1:6379> get name4
"name5val"
127.0.0.1:6379> get name4
"name5val"
127.0.0.1:6379> get name5
(nil)
127.0.0.1:6379> get name4
(nil)
select
#select
选择一个数据库,下标值从0开始,一个新连接默认连接的数据库是DB0(数据库为0-15,一共16个数据库)。
为什么把数据库切成16份?
数据安全。
16份是内存上逻辑划分。
早期(没集群):每份放在不同的机器上,备份,为了数据安全。
127.0.0.1:6379> keys *
1) "name1"
2) "name2"
3) "name6"
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> keys *
(empty list or set)
127.0.0.1:6379[1]> get name2
(nil)
127.0.0.1:6379[1]> select 15
OK
127.0.0.1:6379[15]> select 16
(error) ERR invalid DB index
127.0.0.1:6379[15]> select 0
OK
127.0.0.1:6379> keys *
1) "name1"
2) "name2"
3) "name6"
move
#move
将当前数据库的 key 移动到给定的数据库 db 当中。
如果当前数据库(源数据库)和给定数据库(目标数据库)有相同名字的给定 key ,或者key 不存在于当前数据库,那么 MOVE 没有任何效果。
因此,也可以利用这一特性,将 MOVE 当作锁(locking)原语(primitive)。
返回值
integer-reply:
移动成功返回 1
失败则返回 0
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> keys *
(empty list or set)
127.0.0.1:6379[1]> set name1 name1val
OK
127.0.0.1:6379[1]> set name2 name2val
OK
127.0.0.1:6379[1]> keys *
1) "name1"
2) "name2"
127.0.0.1:6379[1]> select 2
OK
127.0.0.1:6379[2]> keys *
(empty list or set)
127.0.0.1:6379[2]> set name1 name1val2
OK
127.0.0.1:6379[2]> set name2 name2val2
OK
127.0.0.1:6379[2]> keys *
1) "name1"
2) "name2"
127.0.0.1:6379[2]> move name1 1
(integer) 0
127.0.0.1:6379[2]> select 1
OK
127.0.0.1:6379[1]> get name1
"name1val"
127.0.0.1:6379[1]> set name3 name3val
OK
127.0.0.1:6379[1]> move name3 2
(integer) 1
127.0.0.1:6379[1]> keys *
1) "name1"
2) "name2"
127.0.0.1:6379[1]> get name3
(nil)
127.0.0.1:6379[1]> select 2
OK
127.0.0.1:6379[2]> keys *
1) "name1"
2) "name3"
3) "name2"
127.0.0.1:6379[2]> get name3
"name3val"
#randomkey
#随机返回某数据库里的一个key
127.0.0.1:6379[2]> randomkey
"name3"
127.0.0.1:6379[2]> randomkey
"name2"
127.0.0.1:6379[2]> randomkey
"name2"
127.0.0.1:6379[2]> randomkey
"name1"
##6、7高级命令及特性二
echo
#echo
打印命令
127.0.0.1:6379[2]> keys *
1) "name1"
2) "name3"
3) "name2"
127.0.0.1:6379[2]> echo name3
"name3"
127.0.0.1:6379[2]> echo name1
"name1"
dbsize
#dbsize
返回当前数据库的key的数量
127.0.0.1:6379[2]> keys *
1) "name1"
2) "name3"
3) "name2"
127.0.0.1:6379[2]> dbsize
(integer) 3
127.0.0.1:6379[2]> flushdb
OK
127.0.0.1:6379[2]> keys *
(empty list or set)
127.0.0.1:6379[2]> dbsize
(integer) 0
info
#info
INFO命令以一种易于理解和阅读的格式,返回关于Redis服务器的各种信息和统计数值。
通过给定可选的参数 section ,可以让命令只返回某一部分的信息:
server: Redis服务器的一般信息
clients: 客户端的连接部分
memory: 内存消耗相关信息
persistence: RDB和AOF相关信息
stats: 一般统计
replication: 主/从复制信息
cpu: 统计CPU的消耗
commandstats: Redis命令统计
cluster: Redis集群信息
keyspace: 数据库的相关统计
它也可以采取以下值:
all: 返回所有信息
default: 值返回默认设置的信息
如果没有使用任何参数时,默认为default。
返回值
bulk-string-reply: 文本行的合集
每一行包含了包含一种信息或者属性(从#字符开始)。 所有的属性都是以字段:值(field:value)的形式,已\r\n结尾。
注意
请注意不同Redis版本会添加或者删除一些字段。一个健壮的客户端应用解析该命令的结果时,应该跳过未知的字段,并且优雅的处理缺少的字段。
已下描述要求 Redis >= 2.4
下面是所有 server 相关的信息:
redis_version: Redis 服务器版本
redis_git_sha1: Git SHA1
redis_git_dirty: Git dirty flag
os: Redis 服务器的宿主操作系统
arch_bits: 架构(32 或 64 位)
multiplexing_api: Redis 所使用的事件处理机制
gcc_version: 编译 Redis 时所使用的 GCC 版本
process_id: 服务器进程的 PID
run_id: Redis 服务器的随机标识符(用于 Sentinel 和集群)
tcp_port: TCP/IP 监听端口
uptime_in_seconds: 自 Redis 服务器启动以来,经过的秒数
uptime_in_days: 自 Redis 服务器启动以来,经过的天数
lru_clock: 以分钟为单位进行自增的时钟,用于 LRU 管理
下面是所有 clients 相关的信息:
connected_clients: 已连接客户端的数量(不包括通过从属服务器连接的客户端)
client_longest_output_list: 当前连接的客户端当中,最长的输出列表
client_biggest_input_buf: 当前连接的客户端当中,最大输入缓存
blocked_clients: 正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量
下面是所有 memory 相关的信息:
used_memory: 由Redis 分配器分配的内存总量,以字节(byte)为单位
used_memory_human: 以人类可读的格式返回 Redis 分配的内存总量
used_memory_rss: 从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致。
used_memory_peak: Redis 的内存消耗峰值(以字节为单位)
used_memory_peak_human: 以人类可读的格式返回 Redis 的内存消耗峰值
used_memory_lua: Lua 引擎所使用的内存大小(以字节为单位)
mem_fragmentation_ratio: used_memory_rss 和 used_memory 之间的比率
mem_allocator: 在编译时指定的, Redis 所使用的内存分配器。可以是 libc 、 jemalloc 或者 tcmalloc 。 在理想情况下, used_memory_rss 的值应该只比 used_memory 稍微高一点儿。
当 rss > used ,且两者的值相差较大时,表示存在(内部或外部的)内存碎片。
内存碎片的比率可以通过mem_fragmentation_ratio 的值看出。
当 used > rss 时,表示 Redis 的部分内存被操作系统换出到交换空间了,在这种情况下,操作可能会产生明显的延迟。
当 Redis 释放内存时,分配器可能会,也可能不会,将内存返还给操作系统。
如果 Redis 释放了内存,却没有将内存返还给操作系统,那么 used_memory 的值可能和操作系统显示的 Redis 内存占用并不一致。
查看 used_memory_peak 的值可以验证这种情况是否发生。
#更多信息参考“http://www.redis.cn/commands/info.html”
config get
#config get
CONFIG GET命令用来读取redis服务器的配置文件参数,但并不是所有参数都支持。 与之对应的命令是CONFIGSET用来设置服务器的配置参数。
CONFIG GET 命令只接受一个参数,所有配置参数都采用key-value的形式。
#个人理解对应“/application/redis/conf/redis.conf”中的内容。
#查看配置中的所有信息
127.0.0.1:6379[2]> config get *
127.0.0.1:6379[2]> config get port
1) "port"
2) "6379"
config set
#config set
#设置配置文件中的参数
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) "redis"
127.0.0.1:6379> config set requirepass test
OK
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) "test"
127.0.0.1:6379> quit
[root@redis ~]# redis-cli
127.0.0.1:6379> config get *
(error) NOAUTH Authentication required.
127.0.0.1:6379> auth redis
(error) ERR invalid password
127.0.0.1:6379> auth test
OK
127.0.0.1:6379> config get *
127.0.0.1:6379> config set port 8888
(error) ERR Unsupported CONFIG parameter: port
127.0.0.1:6379> config get port
1) "port"
2) "6379"
flushdb
#flushdb
删除当前数据库里面的所有数据。
这个命令永远不会出现失败。
这个操作的时间复杂度是O(N),N是当前数据库的keys数量。
127.0.0.1:6379[1]> select 2
OK
127.0.0.1:6379[2]> keys *
(empty list or set)
127.0.0.1:6379[2]> set name1 name1val
OK
127.0.0.1:6379[2]> set name2 name2val
OK
127.0.0.1:6379[2]> keys *
1) "name1"
2) "name2"
127.0.0.1:6379[2]> flushdb
OK
127.0.0.1:6379[2]> keys *
(empty list or set)
127.0.0.1:6379[2]> select 1
OK
127.0.0.1:6379[1]> keys *
1) "name1"
2) "name2"
flushall
#flushall
删除所有数据库里面的所有数据,注意不是当前数据库,而是所有数据库。
这个命令永远不会出现失败。
这个操作的时间复杂度是O(N),N是数据库的数量。
127.0.0.1:6379> keys *
1) "name1"
2) "name2"
3) "name6"
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> keys *
1) "name1"
2) "name2"
127.0.0.1:6379[1]> flushall
OK
127.0.0.1:6379[1]> keys *
(empty list or set)
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> keys *
(empty list or set)
七、redis常用命令结合java代码的使用
package org.mbox.testredis;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
public class TestRedis {
private staticJedis jedis = new Jedis("10.0.0.7", 6379);
publicTestRedis(){
jedis.auth("redis");
}
@Test
public voidtest(){
// //1
// jedis.flushDB();//清空当前库,默认select 0
//
// jedis.set("name1","name1val");
// jedis.set("name2","name2val");
//
// System.out.println(jedis.get("name1"));
// //2操作map
// jedis.flushDB();
// jedis.mset("name1","name1val","name2","name2val"); //设置多个值,多个key val的形式
//
// List<String>listNames = jedis.mget("name1","name2");
//// Iterator<String>iterators = listNames.iterator();
//// while(iterators.hasNext()){
//// System.out.println(iterators.next());
//// }
//
// for(Iterator<String>iterators = listNames.iterator();iterators.hasNext();){
// Stringnameval = (String)iterators.next();
// System.out.println(nameval);
// }
// //3
// jedis.flushDB();
// Map<String,String>map = new HashMap<String,String>();//key和value只能是string类型
// map.put("name1","name1val");
// map.put("name2","name2val");
// map.put("name3","name3val");
// jedis.hmset("myhashmap",map);
//
// Set<String>setNames = jedis.hkeys("myhashmap");
// for(Iterator<String>iterators = setNames.iterator();iterators.hasNext();){
// Stringkey = iterators.next();
// System.out.println(key+ "---->" + jedis.hget("myhashmap", key));
// }
// //4
// //打印map中的所有值
// System.out.println(jedis.hmget("myhashmap","name1", "name2", "name3"));
// System.out.println("............................");
// List<String>listNames = jedis.hmget("myhashmap", "name1","name2", "name3");
// //打印map中的所有值
// for(Iterator<String>iterators = listNames.iterator();iterators.hasNext();){
// System.out.println(iterators.next());
// }
// jedis.hdel("myhashmap","name1");//删除map中的某个key
// System.out.println("............................");
// for(Iterator<String>iterators = listNames.iterator();iterators.hasNext();){
// System.out.println(iterators.next());
// }
// System.out.println("............................");
// //5
// //获取map中某个key的值
// System.out.println(jedis.hmget("myhashmap","name1"));
// System.out.println(jedis.hmget("myhashmap","name3"));
// //获取map中的key个数
// System.out.println(jedis.hlen("myhashmap"));
// //是否存在以myhashmap为key的记录
// System.out.println(jedis.exists("myhashmap"));
// //获取map中的所有key名称
// System.out.println(jedis.hkeys("myhashmap"));
// //获取map中的所有key的value值
// System.out.println(jedis.hvals("myhashmap"));
// //6事务
//// jedis.flushDB();
// jedis.set("age","11");
// jedis.set("name","nameval1");
// Transactiontransaction = jedis.multi();
// //如果用了multi方法,那么就必须利用transaction进行处理其他命令操作,
// //不然报错内容为:"Cannot use Jedis when inMulti. Please use JedisTransaction instead."
// transaction.incr("age");
// transaction.incr("name");
//// 上述name为啥不报错,并能通过,但在linux环境下操作就报错
//// 127.0.0.1:6379>incr name
//// (error)ERR value is not an integer or out of range
//
//// System.out.println(transaction.get("age"));
//// System.out.println(transaction.get("name"));
// //discard和exec方法与multi方法分别是成对存在的,不要把discard和exec一起使用
//// transaction.discard();
// transaction.exec();
//
// System.out.println(jedis.get("age"));
// System.out.println(jedis.get("name"));
// //7操作list
// jedis.flushDB();
// //lpush栈:后进先出
// //list名称,后面全是值
// jedis.lpush("testlist","list1", "list3", "list2", "list4");
// //list名称,0到-1是查询出所有
// System.out.println("1----------------"+ jedis.lrange("testlist", 0, -1));
// jedis.lpush("testlist","list6");
// jedis.lpush("testlist","list5");
// System.out.println("2----------------"+ jedis.lrange("testlist", 0, -1));
// jedis.del("testlist");
// //rpush队列:先进先出
// jedis.rpush("testlist","list1", "list3", "list2", "list4");
// System.out.println("3----------------"+ jedis.lrange("testlist", 0, -1));
// //8操作set无序集合
// jedis.flushDB();
// jedis.sadd("testset","set1");
// jedis.sadd("testset","set3");
// jedis.sadd("testset","set2");
// jedis.sadd("testset","set4", "set7", "set6", "set5");
// System.out.println(jedis.smembers("testset"));//获取所有元素
// System.out.println(jedis.sismember("testset","set2"));//判断元素是否在set中
// System.out.println(jedis.scard("testset"));//返回set中元素的个数
// jedis.srem("testset","set4", "set2");//删除其中的元素
// System.out.println(jedis.smembers("testset"));//获取所有元素
// System.out.println(jedis.sismember("testset","set2"));//判断元素是否在set中
// System.out.println(jedis.srandmember("testset"));//随机返回一个元素
// System.out.println(jedis.scard("testset"));//返回set中元素的个数
// //9操作zset有序集合
// jedis.flushDB();
// //前面是key后面是value
// jedis.zadd("zset1",1, "test1");
// jedis.zadd("zset1",3, "test3");
// jedis.zadd("zset1",2, "test2");
// jedis.zadd("zset1",4, "test4");
// Map<String,Double>zsetMap = new HashMap<String,Double>();
// //前面是value后面是key
// zsetMap.put("8",11.11);
// zsetMap.put("6",21.11);
// jedis.zadd("zset1",zsetMap);
// System.out.println(jedis.zrange("zset1",0, -1));
}
}
标题:总结redis第二部分(redis常用命令、高级命令特性以及与java代码的结合)
作者:yazong
地址:https://blog.llyweb.com/articles/2016/12/11/1578156421076.html