首页 > 代码库 > Redis 的数据类型 - MULTI 事务,SORT 排序

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 缓存结果

Redis 的数据类型 - MULTI 事务,SORT 排序