目录
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:
该命令可以查看 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 为什么快,当然需要一个参照(mysql)
首先是因为 redis 是访问内存,而mysql访问的是硬盘
redis 的核心功能比 mysql 的核心功能简单
redis 是单线程,无需为线程竞争切换等浪费时间
其中redis 是单线程和它的操作有关,redis 的操作都是短平快,不需要占用太多的cup资源,所以可以使用单线程
redis 处理网络请求的时候使用的是 epoll 多路复用
redis 中的 string,直接就是按照二进制的方式存储的(不会做任何编码,存的什么去的就是什么)
string 可以存储很多数据类型,普通字符串、整数、JSON、xml、二进制数据(图片、视频、音频...)
设置一个 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 作用就是删除 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 返回对应 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设置多组 key value
MSET key value [key value ....]
设置多组 key value
- 127.0.0.1:6379> mset key1 1 ksy2 2 ksy3 3
- OK
获取多组 key 对应的value
MGET key [key...]
获取多组 key
- 127.0.0.1:6379> mget key1 ksy2 ksy3
- 1) "1"
- 2) "2"
- 3) "3"
对 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
对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"
对 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 同样是对 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"
其余和上面类似,下面就不演示了
对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 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
- 中国
获取字符串中的一部分,类似于 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 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 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 里面存储的是键值对
redis 里面存储的也是键值对
所以为例区分 hash 和 redis 的键值对redis 使用的是 key-value 而 hash 使用的是 field-value
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
查看 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 不存在的值什么都没有
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
判断 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
查看 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)
返回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)
获取所有的 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
返回指定的 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 都不存在
返回 key 中对应的 hash 的个数
hlen key
返回值是 key 中对应的hash的个数
不存在则返回0
查看 key 里面 hash 的个数
- 127.0.0.1:6379> hlen key1
- 3
看到这个命令其实就猜到了其实个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
其实看到这个我们也可以想起 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
对一个 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
ziphash:压缩链表
hashtable: 普通的hash表
如果 hash 表中国的元素个数比较少,那么使用 ziplist,如果元素个数比较多,那么就是用hashtable
每个 value 的长度比较短,使用zipist,如果value的长度比较长的话,也会使用 hashtable