目录
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