Redis 的数据类型 - MULTI 事务,SORT 排序
开启事务
MULTI:开启事务,事务块中的多条语句会按照顺序放入对列当中,最后由EXEC命令来执行
MULTI
INCR counter1 #当实物开启后执行命令时不会直接返回结果而是先加入到执行队列中#
INCR counter2
INCR counter3
PING
GET counter1
执行事务块中的命令
EXEC #执行事务块中的命令#
127.0.0.1:6379> MULTI OK 127.0.0.1:6379> INCR counter1 QUEUED 127.0.0.1:6379> INCR counter2 QUEUED 127.0.0.1:6379> INCR counter3 QUEUED 127.0.0.1:6379> PING QUEUED 127.0.0.1:6379> GET counter1 QUEUED 127.0.0.1:6379> EXEC 1) (integer) 1 2) (integer) 1 3) (integer) 1 4) PONG 5) "1"
监视一个或者多个 key
WATCH:监视一个或者多个 key,如果在执行事务之前这个 key 如果被其它命令改动,事务就被打断了。
UNWATCH:取消 WATCH 命令对所有 key 的监视
127.0.0.1:6379> WATCH counter1 counter2 OK 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> INCR counter1 QUEUED 127.0.0.1:6379> INCR counter2 QUEUED 127.0.0.1:6379> EXEC (nil) 127.0.0.1:6379> GET counter1 "10" 127.0.0.1:6379> GET counter2 "1"
DISCARD:取消事务
MULTI
SET testMulti 'this is a test'
INCR counter4
INCR counter5
DISCARD
KEYS * #这里返回的还是之前的值,事务并没有执行#
127.0.0.1:6379> MULTI OK 127.0.0.1:6379> SET testMulti 'this is a test' QUEUED 127.0.0.1:6379> INCR counter4 QUEUED 127.0.0.1:6379> INCR counter5 QUEUED 127.0.0.1:6379> DISCARD OK 127.0.0.1:6379> KEYS * 1) "counter3" 2) "counter2" 3) "counter1"
事务中的错误处理
语法错误:命令不存在,或者参数错误,如果有语法错误,Redis 接到 EXEC 后直接返回错误,里面正确的命令也不会被执行
MULTI
SET test hello
SET test1 #在这一步有语法错误,将直接报错,事务终止#
ERRORCOMMAND
运行错误,错误指在运行命令的时候出现的问题
MULTI
SET test2 1
SADD test2 2 #这里有运行错误,但是事务没有执行的时候看不出来,所以不会对事务的执行有影响#
SET test2 3
EXEC #事务执行后得到的执行结果会略过有错误的地方,正确的命令依然全部执行了#
127.0.0.1:6379> SET test hello QUEUED 127.0.0.1:6379> SET test1 (error) ERR wrong number of arguments for 'set' command 127.0.0.1:6379> EXEC (error) EXECABORT Transaction discarded because of previous errors. 127.0.0.1:6379> KEYS * 1) "counter3" 2) "counter2" 3) "counter1" 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> SET test2 1 QUEUED 127.0.0.1:6379> SADD test2 2 QUEUED 127.0.0.1:6379> SET test2 3 QUEUED 127.0.0.1:6379> EXEC 1) OK 2) (error) WRONGTYPE Operation against a key holding the wrong kind of value 3) OK
连接相关
PING:测试和服务器之间是否连接有效,如果服务器运行正常的话会得到PONG
ECHO:打印一个特定信息
QUIT:请求服务器关闭与当前客户端的连接,EXIT
SHUTDOWN:关闭服务器和客户端
AUTH:指定Redis的身份验证,Redis配置文件中requirepass选项的值
CONFIG SET requirepass password
登陆进来之后通过AUTH命令进行验证
连接的时候-a pwd
SELECT:选择数据库
#这里就只拿 ECHO 和 CONFIG 来举例说明了,其他几条命令都是之前用过很多次了#
127.0.0.1:6379> ECHO 'this is a test' "this is a test" 127.0.0.1:6379> CONFIG SET requirepass tom OK 127.0.0.1:6379> KEYS * (error) NOAUTH Authentication required. 127.0.0.1:6379> AUTH tom OK 127.0.0.1:6379> KEYS * 1) "test2" 2) "counter1" 3) "counter3" 4) "counter2"
生存时间
EXPIRE/EXPIREAT #过期的秒数/时间戳#
PEXPIRE/PEXPIREAT #过期的毫秒数#
PERSIST #持久化#
TTL #得到生存时间#
PTTL #得到毫秒的生存时间#
SET session:test1 uid1
EXPIRE session:test1 900
TTL session:test1
SET session:test2 uid2
EXPIRE session:test2 30
SET key hello
EXPIRE key 100
TTL key
SET key world #使用SET GETSET也会清楚过期时间#
TTL key
127.0.0.1:6379> SET session:test1 uid1 OK 127.0.0.1:6379> EXPIRE session:test1 900 (integer) 1 127.0.0.1:6379> TTL session:test1 (integer) 887 127.0.0.1:6379> SET session:test2 uid2 OK 127.0.0.1:6379> EXPIRE session:test2 30 (integer) 1 127.0.0.1:6379> TTL session:tes2 (integer) -2 127.0.0.1:6379> PERSIST session:test1 (integer) 1 127.0.0.1:6379> TTL session:test1 (integer) -1 127.0.0.1:6379> SET key hello OK 127.0.0.1:6379> EXPIRE key 100 (integer) 1 127.0.0.1:6379> TTL key (integer) 98 127.0.0.1:6379> SET key world OK 127.0.0.1:6379> TTL key (integer) -1
SORT:排序相关
按照键值从小到大或者从大到小的顺序排序
SORT key
SORT key DESC
对数值进行排序
LPUSH testSort1 12 33 -13 45 90
SORT testSort1 #升序#
SORT testSort1 DESC #降序#
127.0.0.1:6379> SORT testSort1 1) "-13" 2) "12" 3) "33" 4) "45" 5) "90" 127.0.0.1:6379> SORT testSort1 DESC 1) "90" 2) "45" 3) "33" 4) "12" 5) "-13"
对字母进行排序
LPUSH testSort2 a b c test1 test2 tom jerry lucy
SORT testSort2 ALPHA
SORT testSort2 ALPHA DESC
127.0.0.1:6379> LPUSH testSort2 a b c test1 test2 tom jerry lucy (integer) 8 127.0.0.1:6379> SORT testSort2 ALPHA 1) "a" 2) "b" 3) "c" 4) "jerry" 5) "lucy" 6) "test1" 7) "test2" 8) "tom" 127.0.0.1:6379> SORT testSort2 ALPHA DESC 1) "tom" 2) "test2" 3) "test1" 4) "lucy" 5) "jerry" 6) "c" 7) "b" 8) "a"
使用 LIMIT 限制返回结果
LPUSH testSort3 a b c d e f g h i j k l m n 1 2 3 4 6 8 900 23
SORT testSort3 ALPHA LIMIT 0 5 #起点0 偏移量5#
SORT testSort3 ALPHA LIMIT 0 5 DESC
127.0.0.1:6379> LPUSH testSort3 a b c d e f g h i j k l m n 1 2 3 4 6 8 900 23 (integer) 22 127.0.0.1:6379> SORT testSort3 ALPHA LIMIT 0 5 1) "1" 2) "2" 3) "23" 4) "3" 5) "4" 127.0.0.1:6379> SORT testSort3 ALPHA LIMIT 0 5 DESC 1) "n" 2) "m" 3) "l" 4) "k" 5) "j"
根据外部 key 的权重进行排序
LPUSH uid 1
SET user_name_1 admin
SET user_level_1 9999
LPUSH uid 2
SET user_name_2 tom
SET user_level_2 800
LPUSH uid 3
SET user_name_3 jerry
SET user_level_3 600
LPUSH uid 4
SET user_name_4 jack
SET user_level_4 300
LPUSH uid 5
SET user_name_5 mario
SET user_level_5 860
SORT uid
SORT uid BY user_level_* #根据用户等级对用户 uid 进行排序#
127.0.0.1:6379> LPUSH uid 1 (integer) 1 127.0.0.1:6379> SET user_name_1 admin OK 127.0.0.1:6379> SET user_level_1 9999 OK 127.0.0.1:6379> LPUSH uid 2 (integer) 2 127.0.0.1:6379> SET user_name_2 tom OK 127.0.0.1:6379> SET user_level_2 800 OK 127.0.0.1:6379> LPUSH uid 3 (integer) 3 127.0.0.1:6379> SET user_name_3 jerry OK 127.0.0.1:6379> SET user_level_3 600 OK 127.0.0.1:6379> LPUSH uid 4 (integer) 4 127.0.0.1:6379> SET user_name_4 jack OK 127.0.0.1:6379> SET user_level_4 300 OK 127.0.0.1:6379> LPUSH uid 5 (integer) 5 127.0.0.1:6379> SET user_name_5 mario OK 127.0.0.1:6379> SET user_level_5 860 OK 127.0.0.1:6379> SORT uid 1) "1" 2) "2" 3) "3" 4) "4" 5) "5" 127.0.0.1:6379> SORT uid BY user_level_* 1) "4" 2) "3" 3) "2" 4) "5" 5) "1"
根据排序结果取出相应键值
SORT uid GET user_name_*
SORT uid BY user_level_* GET user_name_* #根据用户等级对 uid 进行排序,输出 uid 对应的名称 user_name #
SORT uid GET user_name_* GET user_level_* #对 uid 进行排序,输出 uid 对应的名称 user_name 和 等级 user_level #
SORT uid GET # GET user_level_* GET user_name_* #这里 '#' 井号代表得到键的编号#
SORT uid BY user_level_* GET # GET user_level_* GET user_name_* #根据用户等级对 uid 进行排序,输出 uid 对应的 uid,名称 user_name 和 等级 user_level #
SORT uid BY noExists #对一个不存在的字段进行排序,系统将自动忽略这个条件,跟没写一样#
SORT uid BY noExists GET # GET user_level_* GET user_name_*
127.0.0.1:6379> SORT uid GET user_name_* 1) "admin" 2) "tom" 3) "jerry" 4) "jack" 5) "mario" 127.0.0.1:6379> SORT uid BY user_level_* GET user_name_* 1) "jack" 2) "jerry" 3) "tom" 4) "mario" 5) "admin" 127.0.0.1:6379> SORT uid GET user_name_* GET user_level_* 1) "admin" 2) "9999" 3) "tom" 4) "800" 5) "jerry" 6) "600" 7) "jack" 8) "300" 9) "mario" 10) "860" 127.0.0.1:6379> SORT uid GET # GET user_level_* GET user_name_* 1) "1" 2) "9999" 3) "admin" 4) "2" 5) "800" 6) "tom" 7) "3" 8) "600" 9) "jerry" 10) "4" 11) "300" 12) "jack" 13) "5" 14) "860" 15) "mario" 127.0.0.1:6379> SORT uid BY user_level_* GET # GET user_level_* GET user_name_* 1) "4" 2) "300" 3) "jack" 4) "3" 5) "600" 6) "jerry" 7) "2" 8) "800" 9) "tom" 10) "5" 11) "860" 12) "mario" 13) "1" 14) "9999" 15) "admin" 127.0.0.1:6379> SORT uid BY noExists 1) "5" 2) "4" 3) "3" 4) "2" 5) "1" 127.0.0.1:6379> SORT uid BY noExists GET # GET user_level_* GET user_name_* 1) "5" 2) "860" 3) "mario" 4) "4" 5) "300" 6) "jack" 7) "3" 8) "600" 9) "jerry" 10) "2" 11) "800" 12) "tom" 13) "1" 14) "9999" 15) "admin"
HMSET user_info_1 username admin level 1000
HMSET user_info_2 username tom level 999
HMSET user_info_3 username jerry level 77
HMSET user_info_4 username mario level 90
#当 SORT 对一个 HASH 类型的对象进行排序时,可以通过 表名 -> 字段名的方式来指定排序方式#
SORT uid BY user_info_*->level #根据 user_info_ 系列的表中的 level 字段进行排序#
SORT uid GET user_info_*->username #排序结果返回 username #
SORT uid BY user_info_*->level GET # GET user_info_*->username #根据 user_info_ 系列的表中的 level 字段进行排序,返回 uid 和 username #
127.0.0.1:6379> HMSET user_info_1 username admin level 1000 OK 127.0.0.1:6379> HMSET user_info_2 username tom level 999 OK 127.0.0.1:6379> HMSET user_info_3 username jerry level 77 OK 127.0.0.1:6379> HMSET user_info_4 username mario level 90 OK 127.0.0.1:6379> SORT uid BY user_info_*->level 1) "5" 2) "3" 3) "4" 4) "2" 5) "1" 127.0.0.1:6379> SORT uid GET user_info_*->username 1) "admin" 2) "tom" 3) "jerry" 4) "mario" 5) (nil) 127.0.0.1:6379> SORT uid BY user_info_*->level GET # GET user_info_*->username 1) "5" 2) (nil) 3) "3" 4) "jerry" 5) "4" 6) "mario" 7) "2" 8) "tom" 9) "1" 10) "admin"
将排序结果保存起来
SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern]] [ASC|DESC|ALPHA] [STORE destination]
BY pattern:一个参数,根据谁来排序
LIMIT offset count:两个参数,限制显示条数,offset 是偏移量,count 是条数
GET pattern:一个参数,返回结果中得到的值,可以写多个,比如 username level 等等
ASC|DESC|ALPHA:ASC为升序(默认值),DESC为降序,ALPHA以字母排序
STORE destination:把结果保存在一个新的结果集中,指定的结果集名称
RPUSH testSort4 1 2 5 8 9 20
RPUSH testSort4 43 56 90 120
SORT testSort4 DESC STORE sortRes4
127.0.0.1:6379> RPUSH testSort4 1 2 5 8 9 20 (integer) 6 127.0.0.1:6379> RPUSH testSort4 43 56 90 120 (integer) 10 127.0.0.1:6379> LRANGE testSort4 0 -1 1) "1" 2) "2" 3) "5" 4) "8" 5) "9" 6) "20" 7) "43" 8) "56" 9) "90" 10) "120" 127.0.0.1:6379> SORT testSort4 1) "1" 2) "2" 3) "5" 4) "8" 5) "9" 6) "20" 7) "43" 8) "56" 9) "90" 10) "120" 127.0.0.1:6379> SORT testSort4 DESC STORE sortRes4 (integer) 10 127.0.0.1:6379> LRANGE sortRes4 0 -1 1) "120" 2) "90" 3) "56" 4) "43" 5) "20" 6) "9" 7) "8" 8) "5" 9) "2" 10) "1"
注意:
SORT 命令的时间复杂度 O (n+mlogm),n 表示要排序的列表或者集合中的元素的个数,m 表示要返回元素的个数
尽可能减少待排序中键的数量 (使 n 尽可能的小)
使用 LIMIT 参数限制获取元素的个数 (使 m 尽可能小)
如果要排序的数据量比较大,尽可能通过 STORE 缓存结果