• redis 数据结构,及其常用命令


    目录

    redis 的数据结构

    常用数据类型的编码

    OBJECT ENCODING

    redis 为什么快

    redis 的专用指令

    string

    SET

    FLUSHALL

    GET

    MSET

    MGET

    INCR

    INCRBY

    DECR

    DECRBY

    INCRFLOAT

    APPEND

    GETRANGE

    SETRANGE

    STRLEN

    内部编码方式

    hash

    HSET

    HGET

    HDEUL

    HEXIXTS

    HKEYS

    HVALS

    HGETALL

    HMHET

    HLEN

    HSETNX

    HINCRBY

    HINCRBYFLOAT

    hash 的编码方式


    redis 的数据结构

    • Strings

    • Lists

    • Sets

    • Hashes

    • Sorted sets

    • Strems

    • Geospatial

    • Bimaps

    • Bitfields

    • Probabilistic

    虽然目前的 redis 有十个数据类型,但是我们常用的只有5个

    常用数据类型的编码

    数据结构内部编码
    raw
    stringint
    embstr
    hashhashtable
    ziplist
    listlinkedlist
    ziplist
    sethashtable
    inset
    zsetskiplist
    ziplist
    • string

    • raw:最基本字符串(底层就是一个char 数组)

    • int:就是整数

    • embstr:针对段字符串进行特殊优化

    • hash

    • hashtable:最基本的 hash 表

    • ziplist:压缩链表

    • list

    • linkedlist:链表

    • ziplist:压缩链表

    从 redis 3.2 开始,引入了新的实现方式 quicklist,quicklist 兼容了linkedlist 和 zipist的优点

    quicklist就是一个链表,每一个元素又是ziplist

    • set

    • hashtable:hash 表

    • inset:集合中存的都是整数

    • zset

    • skiplist:跳表

    • ziplist

    OBJECT ENCODING

    • 该命令可以查看 key 队列value 的编码

    object encoding key
    • 返回值是 value 的编码方式

      1. 127.0.0.1:6379> object encoding key1
      2. "embstr"
      3. 127.0.0.1:6379> object encoding key2
      4. "quicklist"
      5. 127.0.0.1:6379> object encoding key3
      6. "hashtable"
      7. 127.0.0.1:6379> object encoding key4
      8. "ziplist"

    redis 为什么快

    • 谈论 redis 为什么快,当然需要一个参照(mysql)

    • 首先是因为 redis 是访问内存,而mysql访问的是硬盘

    • redis 的核心功能比 mysql 的核心功能简单

    • redis 是单线程,无需为线程竞争切换等浪费时间

    • 其中redis 是单线程和它的操作有关,redis 的操作都是短平快,不需要占用太多的cup资源,所以可以使用单线程

    • redis 处理网络请求的时候使用的是 epoll 多路复用

    redis 的专用指令

    string

    • redis 中的 string,直接就是按照二进制的方式存储的(不会做任何编码,存的什么去的就是什么)

    • string 可以存储很多数据类型,普通字符串、整数、JSON、xml、二进制数据(图片、视频、音频...)

    SET

    • 设置一个 key 和 value ,value 为string 类型

      SET key value [expiration EX second | PX millisecond] [NX | XX]

    • []:表示可选项

    • EX:表示设置超时时间 单位秒

    • PX:表示设置超时时间 单位毫秒

    • NX:如果key 不存在才设置,key存在则不设置,返回nil

    • XX:如果key存在,才设置(相当于跟新key的value)如果key不存在,则不设置

    为了方便SET 的使用,还有一些类似的命令

    • SETNX

    • SETEX

    • SETPX

    在介绍下面的命令之前,先介绍一个命令

    FLUSHALL

    • flushall 作用就是删除 redis 上所有的数据

    • set 插入一个数据

      1. 127.0.0.1:6379> set key1 1
      2. OK

    • set 插入数据设时间

      1. 127.0.0.1:6379> set key2 2 ex 10
      2. OK
      3. 127.0.0.1:6379> ttl key2
      4. (integer) 7

    • set插入数据,没有 key 就插入

      1. 127.0.0.1:6379> set key3 3 NX
      2. OK

    • set 插入数据,有数据才插入

      1. 127.0.0.1:6379> set key3 3.1415926
      2. OK
      3. 127.0.0.1:6379> get key3
      4. "3.1415926"

    • setex 插入数据

      1. 127.0.0.1:6379> setex key4 10 4
      2. OK
      3. 127.0.0.1:6379> get key4
      4. "4"

    • setnx 插入数据

      1. 127.0.0.1:6379> setnx key5 5
      2. (integer) 1

    GET

    • get 返回对应 key 的value 主要就是返回 string 的value

    GET key
    • 查询 string 类型

      1. 127.0.0.1:6379> get key1
      2. "1"

    • 查询非 string 类型

      1. 127.0.0.1:6379> lpush key6 6 66 666 6666
      2. (integer) 4
      3. 127.0.0.1:6379> get key6
      4. (error) WRONGTYPE Operation against a key holding the wrong kind of value

    MSET

    • mset设置多组 key value

    MSET key value [key value ....]

    • 设置多组 key value

      1. 127.0.0.1:6379> mset key1 1 ksy2 2 ksy3 3
      2. OK

    MGET

    • 获取多组 key 对应的value

    MGET key [key...]
    • 获取多组 key

      1. 127.0.0.1:6379> mget key1 ksy2 ksy3
      2. 1) "1"
      3. 2) "2"
      4. 3) "3"

    INCR

    • 对 value 进行 + 1

    INCR key
    • 返回值是+1后的值

    • 如果没有对应的 key 则认为 key 为 0,然后返回对0+1 后的值

    • value 必须是 64 位整数才可以

    • string 类型不可以使用该命令

    • 超过 64 位整数也不可以使用该命令

    • 浮点数不可以使用该命令

    • 插入数据后自增

      1. 127.0.0.1:6379> set key1 100
      2. OK
      3. 127.0.0.1:6379> get key1
      4. "100"
      5. 127.0.0.1:6379> incr key1
      6. (integer) 101
      7. 127.0.0.1:6379> get key1
      8. "101"

    • 对string 类型进行自增

      1. 127.0.0.1:6379> set key2 hello
      2. OK
      3. 127.0.0.1:6379> get key2
      4. "hello"
      5. 127.0.0.1:6379> incr key2
      6. (error) ERR value is not an integer or out of range

    • 对浮点类型自增

      1. 127.0.0.1:6379> set key3 1.1
      2. OK
      3. 127.0.0.1:6379> get key3
      4. "1.1"
      5. 127.0.0.1:6379> incr key3
      6. (error) ERR value is not an integer or out of range

    • 没有对应的key进行自增

      1. 127.0.0.1:6379> incr key4
      2. (integer) 1
      3. 127.0.0.1:6379> get key4
      4. "1"

    • 对超出64位整数进行自增

      1. 127.0.0.1:6379> set key5 9999999999999999999999999
      2. OK
      3. 127.0.0.1:6379> incr key5
      4. (error) ERR value is not an integer or out of range

    INCRBY

    • 对key对应的value进行加N操作

    INCRBY key N
    • 返回值是加N后的值

    • 还可以加负数

    • 其余和incr基本一样

    • 加N

      1. 127.0.0.1:6379> set key6 100
      2. OK
      3. 127.0.0.1:6379> incrby key6 100
      4. (integer) 200
      5. 127.0.0.1:6379> get key6
      6. "200"

    • 对该值加一个负数

      1. 127.0.0.1:6379> get key6
      2. "200"
      3. 127.0.0.1:6379> incrby key6 -199
      4. (integer) 1
      5. 127.0.0.1:6379> get key6
      6. "1"

    DECR

    • 对 key 对应的value 进行减一

    DECR key
    • decr 也是只能对64位整数进行操作

    • 返回值还是对value减一后的值

    • 设置一个key对key进行减一

      1. 127.0.0.1:6379> set key1 100
      2. OK
      3. 127.0.0.1:6379> decr key1
      4. (integer) 99
      5. 127.0.0.1:6379> get key1
      6. "99"

    • 对没有对应key的进行减一

      1. 127.0.0.1:6379> decr key2
      2. (integer) -1
      3. 127.0.0.1:6379> get key2
      4. "-1"

    • 剩下的其实和incr 的条件都一样

    DECRBY

    • decrby 同样是对 key进行减N

    DECRBY key N
    • 返回对key减N后的值

    • 其余的条件也是和上面类似

    • 对key减N

      1. 127.0.0.1:6379> set key3 100
      2. OK
      3. 127.0.0.1:6379> decrby key3 99
      4. (integer) 1
      5. 127.0.0.1:6379> get key3
      6. "1"

    • 其余和上面类似,下面就不演示了

    INCRFLOAT

    • 对key对应的value进行加(或者减)一个浮点数

    INCRFLOAT key float
    • 返回值是对key加或者减后的值

    • 限制条件和上面的也差不多,但是还可以对浮点数进行操作

    • 对key进行加一个数

      1. 127.0.0.1:6379> set key1 10
      2. OK
      3. 127.0.0.1:6379> incrbyfloat key1 1.9
      4. "11.9"
      5. 127.0.0.1:6379> get key1
      6. "11.9"

    • 对key减一个数

      1. 127.0.0.1:6379> set key2 10
      2. OK
      3. 127.0.0.1:6379> incrbyfloat key2 -0.5
      4. "9.5"
      5. 127.0.0.1:6379> get key2
      6. "9.5"

    • 对没有对应key value 的进行操作当然也是从0开始计算

      1. 127.0.0.1:6379> incrbyfloat key -0.5
      2. "-0.5"

    • 对浮点数进行操作

      1. 127.0.0.1:6379> set key3 3.14
      2. OK
      3. 127.0.0.1:6379> incrbyfloat key3 1.1
      4. "4.24"
      5. 127.0.0.1:6379> get key3
      6. "4.24"

    其中字符串也可以进行一些操作

    APPEND

    • 追加字符串

    APPEND key 
    • 返回值是追加后字符串的长度(字节数)

    • 操作的对象必须是字符串

    • 如果没有对应的key value则向set一样的功能

    • 对key追加字符串

      1. 127.0.0.1:6379> set key1 hello
      2. OK
      3. 127.0.0.1:6379> append key1 world
      4. (integer) 10
      5. 127.0.0.1:6379> get key1
      6. "helloworld"

    • 对没有对应的 key value 追加

      1. 127.0.0.1:6379> append key2 hello
      2. (integer) 5
      3. 127.0.0.1:6379> get key2
      4. "hello"

    • 对key追加汉字,会返回多少

      1. 127.0.0.1:6379> append key3 中国
      2. (integer) 6

    • 查询 key3

      1. 127.0.0.1:6379> get key3
      2. "\xe4\xb8\xad\xe5\x9b\xbd"

    • 为什么会是这样?

    • 我们前面说过 redis 是不会对数据进行编码的存储进去什么取出来就是什么,汉字在 Xshell 上默认就是 utf8 所以存储进是按照二进制存储的,但是取出来不翻译

    • 如何让 redis 尝试翻译?

    • 可以在启动客户端的时候可以加 --raw

      1. [lxy@hecs-165234 ~]$ redis-cli --raw
      2. 127.0.0.1:6379> get key3
      3. 中国

    GETRANGE

    • 获取字符串中的一部分,类似于 substring

    getrange key start end
    • 返回值是截取到的字符

    • 其中 start 和 end 可以为负数

    • 但是这里的负数表示的并不是下标,而是从倒数开始

    • 这里的 start 和 end 是闭区间

    • 截取一段字符串

      1. 127.0.0.1:6379> getrange key1 0 -1
      2. helloworld

      上面表示从第0个字符开始,到最后一个字符

    • 还可以截取中文

      1. 127.0.0.1:6379> getrange key3 0 -1
      2. 中国

    • 如果截取一部分呢?

      1. 127.0.0.1:6379> getrange key3 1 -2
      2. ¸­

      上面截取出来的并不认识,这是因为现在的客户端还是 raw 模式,但是这里截取了四个字节的数据,然后客户端翻译后就成了这样

    SETRANGE

    • setrange 修改一段字符串

    setrange key offset value
    • 返回值就是修改后的字符串

    • offset 表示偏移量,从偏移量开始修改

    • 修改的字符串的个数由value 的size决定

    • 修改一个key对于的value

      1. 127.0.0.1:6379> set key helloworld
      2. OK
      3. 127.0.0.1:6379> setrange key 1 TTTT
      4. (integer) 10
      5. 127.0.0.1:6379> get key
      6. "hTTTTworld"

    • 如果超出原本字符串长度那么就会全部覆盖

      1. 127.0.0.1:6379> set key1 china
      2. OK
      3. 127.0.0.1:6379> setrange key1 1 CCCCCCCCCCCCCCCCCCCCCCCCCC
      4. (integer) 27
      5. 127.0.0.1:6379> get key1
      6. "cCCCCCCCCCCCCCCCCCCCCCCCCCC"

    • 如果对没有对应 key 和 value

      1. 127.0.0.1:6379> setrange key3 1 hello
      2. (integer) 6
      3. 127.0.0.1:6379> get key3
      4. "\x00hello"

      如果没有对应的 key 那么就会从偏偏移量开始将设置的value设置进去,在偏移量之前的则使用 /x00代替

    STRLEN

    • 返回字符串的长度

    STRLEN key
    
    • 返回值是字符串的长度,单位字节

    • 如果对于不存在的 key 返回0

    • 操作对象只能是string类型

    • 插入数据,使用 strlen 查看

      1. 127.0.0.1:6379> set key1 helloworld
      2. OK
      3. 127.0.0.1:6379> strlen key1
      4. 10

    • 插入中文

      1. 127.0.0.1:6379> set key2 中国
      2. OK
      3. 127.0.0.1:6379> strlen key2
      4. 6

    • 查看不存在的 key

      1. 127.0.0.1:6379> strlen key3
      2. 0

    • 查看其他类型

      1. 127.0.0.1:6379> lpush key3 111 222 333
      2. 3
      3. 127.0.0.1:6379> strlen key3
      4. WRONGTYPE Operation against a key holding the wrong kind of value

    内部编码方式

    • int:64位的整型/8位的整数

    • embstr:短的字符串

    • raw:字符串

    hash

    • hash 里面存储的是键值对

    • redis 里面存储的也是键值对

    • 所以为例区分 hash 和 redis 的键值对redis 使用的是 key-value 而 hash 使用的是 field-value

    HSET

    • hset 可以设置多个 field-value

    hset key field value [field value]
    • hset 的返回值是设置成功后个数的返回值

    • hset 一个 key 可以有多个 field-value

    • 设置多个 field-value

      1. 127.0.0.1:6379> hset key1 f1 111 f2 222 f3 333
      2. 3

    • 设置后也可以继续设置

      1. 127.0.0.1:6379> hset key1 f4 444
      2. 1

    HGET

    • 查看 key 和 field 对应的value

    hget key field [field]
    • 返回值是 key 和 field 对应的值

    • 查看刚才设置入的值

      1. 127.0.0.1:6379> hget key1 f1
      2. 111

    • 查看不存在的值

      127.0.0.1:6379> hget key1 f5

      不存在的值什么都没有

    HDEUL

    • hdel 删除的是 field-value

    hdel key field [field ...]
    • hdel 可以删除多个 field-value

    • hdel的返回值是删除成功的个数

    • 这里注意 del 删除的是 key 而hdel 删除的是 field-value

    • 删除一个 field-value

      1. 127.0.0.1:6379> hdel key1 f1
      2. 1

    • 删除多个

      1. 127.0.0.1:6379> hdel key1 f2 f3
      2. 2

    • 删除不存在

      1. 127.0.0.1:6379> hdel key1 f5
      2. 0

    • 查看刚才删除的 field

      127.0.0.1:6379> hget key1 f1

      这里显示没有,说明 f1 已经被删除了

    • del 删除 key1

      1. 127.0.0.1:6379> del key1
      2. 1

    HEXIXTS

    • 判断 key-field 是否存在

    hexists key field
    • 返回值,存在则返回 1 不存在则返回 0

    • 判断是否存在

      1. 127.0.0.1:6379> hexists key1 f1
      2. (integer) 0

    • 下面插入一个 f1 1,然后查询

      1. 127.0.0.1:6379> hset key1 f1 1
      2. (integer) 1
      3. 127.0.0.1:6379> hexists key1 f1
      4. (integer) 1

    HKEYS

    • 查看 hash 中所有的 field

    hkeys key
    • 返回值是 key 对应的所有的 field

    • 如果不存在那么就返回空

    • 查看 key

      1. 127.0.0.1:6379> hkeys key1
      2. 1) "f1"
      3. 2) "f2"
      4. 3) "f3"

    • 查看不存在的 key

      1. 127.0.0.1:6379> hkeys kwy
      2. (empty list or set)

    HVALS

    • 返回key 中对应的所有的 value

    hvals key
    • 返回值是 key 中 每个 field 对应的 value

    • 如果为空则返回空

    • 查看 key

      1. 127.0.0.1:6379> hvals key1
      2. 1) "111"
      3. 2) "222"
      4. 3) "333"

    • 查看不存在的值

      1. 127.0.0.1:6379> hvals key
      2. (empty list or set)

    HGETALL

    • 获取所有的 key 中的 field 和 value

    hgetall key
    • 返回值就是field 和 value 其中一条 field 下面是对应的 value

    • 如果没有返回空

    • 查看 key

      1. 127.0.0.1:6379> hgetall key1
      2. f1
      3. 111
      4. f2
      5. 222
      6. f3
      7. 333

    • 查看不存在的 key

      127.0.0.1:6379> hgetall key

      但是这个空是什么都没有,而不是报错。

      上面的 hgetall 是将 key 里面对应的 field 和 value 统统返回,但是在线上环境的话这样左是比较危险的,所以还有一个命令是返回指定个数的 field 和 value

    HMHET

    • 返回指定的 field 和 value

    hmget key field [field ...]
    • 返回值是field 对应的 value

    • 如果不存在返回空

    • 查看 key-field

      1. 127.0.0.1:6379> hmget key1 f1 f2 f3
      2. 111
      3. 222
      4. 333

    • 查看不存在的值

      1. 127.0.0.1:6379> hmget key1 f1 2 3
      2. 111

      其中 f1 是存在的 2 和 3 都不存在

    HLEN

    • 返回 key 中对应的 hash 的个数

    hlen key
    • 返回值是 key 中对应的hash的个数

    • 不存在则返回0

    • 查看 key 里面 hash 的个数

      1. 127.0.0.1:6379> hlen key1
      2. 3

    HSETNX

    • 看到这个命令其实就猜到了其实个setnx差不多

    • 这个命令也是不存在则设置,存在则设置失败

    hsetnx key field value
    • 返回值是,如果设置成功则返回 1,失败则返回 0

    • 设置重复值

      1. 127.0.0.1:6379> hsetnx key1 f1 111
      2. 0

    • 设置不重复的值

      1. 127.0.0.1:6379> hsetnx key1 f4 444
      2. 1

    HINCRBY

    • 其实看到这个我们也可以想起 incrby

    • 该命令就是对 field 对应的value进行加一个值

    hincrby key field increment
    • 返回值就是增加后的 value 的值

    • 如果没有对应的那么就默认是以0开始

    • 当然也可以加一个负数

    • 对其中一个 key0field 增加一个值

      1. 127.0.0.1:6379> hincrby key1 f1 100
      2. 211

    • 对一个不存在的增加一个值

      1. 127.0.0.1:6379> hincrby key1 f5 1
      2. 1

    HINCRBYFLOAT

    • 对一个 key-field 对应的value增加一个浮点数

    hincrbyfloat key field increment
    • 返回值是增加后的值

    • 若是没有对应的 key-field 那么就默认以0开始

    • 也可以加一个负数

    • 对一个值增加

      1. 127.0.0.1:6379> hincrbyfloat key1 f1 0.5
      2. 211.5

    • 对一个没有的增加

      1. 127.0.0.1:6379> hincrbyfloat key1 f6 0.5
      2. 0.5

    hash 的编码方式

    • ziphash:压缩链表

    • hashtable: 普通的hash表

    如果 hash 表中国的元素个数比较少,那么使用 ziplist,如果元素个数比较多,那么就是用hashtable

    每个 value 的长度比较短,使用zipist,如果value的长度比较长的话,也会使用 hashtable

  • 相关阅读:
    [Python]字符串处理与常用函数
    Java版本spring cloud + spring boot企业电子招投标系统源代码
    GPT引领前沿与应用突破之GPT4科研实践技术与AI绘图
    浅学一下二叉树的顺序存储结构——堆
    得物Flink内核探索实践
    微软智能云在华发布多项混合云服务及功能更新
    【docker专栏7】容器自启动与守护进程停止后容器保活
    训练营第三十五天动态规划(基础题part1)
    javaweb springboot餐厅点餐系统源码
    【39. 最长公共子序列】
  • 原文地址:https://blog.csdn.net/m0_73455775/article/details/132787523