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
string int
embstr
hash hashtable
ziplist
list linkedlist
ziplist
set hashtable
inset
zset skiplist
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 的编码方式

    127.0.0.1:6379> object encoding key1
    "embstr"
    127.0.0.1:6379> object encoding key2
    "quicklist"
    127.0.0.1:6379> object encoding key3
    "hashtable"
    127.0.0.1:6379> object encoding key4
    "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 插入一个数据

    127.0.0.1:6379> set key1 1
    OK

  • set 插入数据设时间

    127.0.0.1:6379> set key2 2 ex 10
    OK
    127.0.0.1:6379> ttl key2
    (integer) 7

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

    127.0.0.1:6379> set key3 3 NX
    OK

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

    127.0.0.1:6379> set key3 3.1415926
    OK
    127.0.0.1:6379> get key3
    "3.1415926"

  • setex 插入数据

    127.0.0.1:6379> setex key4 10 4
    OK
    127.0.0.1:6379> get key4
    "4"

  • setnx 插入数据

    127.0.0.1:6379> setnx key5 5
    (integer) 1

GET

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

GET key
  • 查询 string 类型

    127.0.0.1:6379> get key1
    "1"

  • 查询非 string 类型

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

MSET

  • mset设置多组 key value

MSET key value [key value ....]

  • 设置多组 key value

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

MGET

  • 获取多组 key 对应的value

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

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

INCR

  • 对 value 进行 + 1

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

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

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

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

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

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

  • 插入数据后自增

    127.0.0.1:6379> set key1 100
    OK
    127.0.0.1:6379> get key1
    "100"
    127.0.0.1:6379> incr key1
    (integer) 101
    127.0.0.1:6379> get key1
    "101"

  • 对string 类型进行自增

    127.0.0.1:6379> set key2 hello
    OK
    127.0.0.1:6379> get key2
    "hello"
    127.0.0.1:6379> incr key2
    (error) ERR value is not an integer or out of range

  • 对浮点类型自增

    127.0.0.1:6379> set key3 1.1
    OK
    127.0.0.1:6379> get key3
    "1.1"
    127.0.0.1:6379> incr key3
    (error) ERR value is not an integer or out of range

  • 没有对应的key进行自增

    127.0.0.1:6379> incr key4
    (integer) 1
    127.0.0.1:6379> get key4
    "1"

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

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

INCRBY

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

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

  • 还可以加负数

  • 其余和incr基本一样

  • 加N

    127.0.0.1:6379> set key6 100
    OK
    127.0.0.1:6379> incrby key6 100
    (integer) 200
    127.0.0.1:6379> get key6
    "200"

  • 对该值加一个负数

    127.0.0.1:6379> get key6
    "200"
    127.0.0.1:6379> incrby key6 -199
    (integer) 1
    127.0.0.1:6379> get key6
    "1"

DECR

  • 对 key 对应的value 进行减一

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

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

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

    127.0.0.1:6379> set key1 100
    OK
    127.0.0.1:6379> decr key1
    (integer) 99
    127.0.0.1:6379> get key1
    "99"

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

    127.0.0.1:6379> decr key2
    (integer) -1
    127.0.0.1:6379> get key2
    "-1"

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

DECRBY

  • decrby 同样是对 key进行减N

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

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

  • 对key减N

    127.0.0.1:6379> set key3 100
    OK
    127.0.0.1:6379> decrby key3 99
    (integer) 1
    127.0.0.1:6379> get key3
    "1"

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

INCRFLOAT

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

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

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

  • 对key进行加一个数

    127.0.0.1:6379> set key1 10
    OK
    127.0.0.1:6379> incrbyfloat key1 1.9
    "11.9"
    127.0.0.1:6379> get key1
    "11.9"

  • 对key减一个数

    127.0.0.1:6379> set key2 10
    OK
    127.0.0.1:6379> incrbyfloat key2 -0.5
    "9.5"
    127.0.0.1:6379> get key2
    "9.5"

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

    127.0.0.1:6379> incrbyfloat key -0.5
    "-0.5"

  • 对浮点数进行操作

    127.0.0.1:6379> set key3 3.14
    OK
    127.0.0.1:6379> incrbyfloat key3 1.1
    "4.24"
    127.0.0.1:6379> get key3
    "4.24"

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

APPEND

  • 追加字符串

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

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

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

  • 对key追加字符串

    127.0.0.1:6379> set key1 hello
    OK
    127.0.0.1:6379> append key1  world
    (integer) 10
    127.0.0.1:6379> get key1
    "helloworld"

  • 对没有对应的 key value 追加

    127.0.0.1:6379> append key2 hello
    (integer) 5
    127.0.0.1:6379> get key2
    "hello"

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

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

  • 查询 key3

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

  • 为什么会是这样?

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

  • 如何让 redis 尝试翻译?

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

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

GETRANGE

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

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

  • 其中 start 和 end 可以为负数

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

  • 这里的 start 和 end 是闭区间

  • 截取一段字符串

    127.0.0.1:6379> getrange key1 0 -1
    helloworld

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

  • 还可以截取中文

    127.0.0.1:6379> getrange key3 0 -1
    中国

  • 如果截取一部分呢?

    127.0.0.1:6379> getrange key3 1 -2
    ¸­

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

SETRANGE

  • setrange 修改一段字符串

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

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

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

  • 修改一个key对于的value

    127.0.0.1:6379> set key helloworld
    OK
    127.0.0.1:6379> setrange key 1 TTTT
    (integer) 10
    127.0.0.1:6379> get key
    "hTTTTworld"

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

    127.0.0.1:6379> set key1 china
    OK
    127.0.0.1:6379> setrange key1 1 CCCCCCCCCCCCCCCCCCCCCCCCCC
    (integer) 27
    127.0.0.1:6379> get key1
    "cCCCCCCCCCCCCCCCCCCCCCCCCCC"

  • 如果对没有对应 key 和 value

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

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

STRLEN

  • 返回字符串的长度

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

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

  • 操作对象只能是string类型

  • 插入数据,使用 strlen 查看

    127.0.0.1:6379> set key1 helloworld
    OK
    127.0.0.1:6379> strlen key1
    10

  • 插入中文

    127.0.0.1:6379> set key2 中国
    OK
    127.0.0.1:6379> strlen key2
    6

  • 查看不存在的 key

    127.0.0.1:6379> strlen key3
    0

  • 查看其他类型

    127.0.0.1:6379> lpush key3 111 222 333
    3
    127.0.0.1:6379> strlen key3
    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

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

  • 设置后也可以继续设置

    127.0.0.1:6379> hset key1 f4 444
    1

HGET

  • 查看 key 和 field 对应的value

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

  • 查看刚才设置入的值

    127.0.0.1:6379> hget key1 f1
    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

    127.0.0.1:6379> hdel key1 f1
    1

  • 删除多个

    127.0.0.1:6379> hdel key1 f2 f3
    2

  • 删除不存在

    127.0.0.1:6379> hdel key1 f5
    0

  • 查看刚才删除的 field

    127.0.0.1:6379> hget key1 f1

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

  • del 删除 key1

    127.0.0.1:6379> del key1
    1

HEXIXTS

  • 判断 key-field 是否存在

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

  • 判断是否存在

    127.0.0.1:6379> hexists key1 f1
    (integer) 0

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

    127.0.0.1:6379> hset key1 f1 1
    (integer) 1
    127.0.0.1:6379> hexists key1 f1
    (integer) 1

HKEYS

  • 查看 hash 中所有的 field

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

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

  • 查看 key

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

  • 查看不存在的 key

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

HVALS

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

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

  • 如果为空则返回空

  • 查看 key

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

  • 查看不存在的值

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

HGETALL

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

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

  • 如果没有返回空

  • 查看 key

    127.0.0.1:6379> hgetall key1
    f1
    111
    f2
    222
    f3
    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

    127.0.0.1:6379> hmget key1 f1 f2 f3
    111
    222
    333

  • 查看不存在的值

    127.0.0.1:6379> hmget key1 f1 2 3
    111
    

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

HLEN

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

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

  • 不存在则返回0

  • 查看 key 里面 hash 的个数

    127.0.0.1:6379> hlen key1
    3

HSETNX

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

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

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

  • 设置重复值

    127.0.0.1:6379> hsetnx key1 f1 111
    0

  • 设置不重复的值

    127.0.0.1:6379> hsetnx key1 f4 444
    1

HINCRBY

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

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

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

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

  • 当然也可以加一个负数

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

    127.0.0.1:6379> hincrby key1 f1 100
    211

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

    127.0.0.1:6379> hincrby key1 f5 1
    1

HINCRBYFLOAT

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

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

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

  • 也可以加一个负数

  • 对一个值增加

    127.0.0.1:6379> hincrbyfloat key1 f1 0.5
    211.5

  • 对一个没有的增加

    127.0.0.1:6379> hincrbyfloat key1 f6 0.5
    0.5

hash 的编码方式

  • ziphash:压缩链表

  • hashtable: 普通的hash表

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

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

你可能感兴趣的:(redis,redis,数据结构,数据库)