Redis数据类型
查阅Redis官方文档可知,Redis提供给用户的核心数据类型有以下九个,从上到下依次是字符串,哈希,列表,集合,有序集合,流,位图,位域,地址空间。因为Redis本身就是通过键值对的方式存储数据,这些数据类型都存在于Redis的value中 ,不同的数据类型,所需要的插入命令也不相同。下面我将依据官方文档对这九种数据类型依次进行介绍,本篇文章将着重对String,Hash两种数据类型进行介绍。
1.String类型
字符串类型是 Redis 最基础的数据类型,关于字符串需要特别注意:
- ⾸先 Redis 中所有的键的类型都是字符串类型,⽽且其他⼏种数据结构也都是在字符串类似基础上构建的,例如列表和集合的元素类型是字符串类型。
- 其次,字符串类型的值实际可以是字符串,包含⼀般格式的字符串或者类似 JSON、XML 格式的字符串;数字,可以是整型或者浮点型;甚⾄是⼆进制流数据,例如图⽚、⾳频、视频等。不过⼀个字符串的最⼤值不能超过 512 MB。
tips: 由于 Redis 内部存储字符串完全是按照⼆进制流的形式保存的,所以 Redis 是不处理字符集 编码问题的,客⼾端传⼊的命令中使⽤的是什么字符集编码,就存储什么字符集编码。处理中文乱码问题可以在启动Redis客户端时加上一个 --raw命令就可以使redis客户端自动把二进制的数据尝试翻译。
(1)常见命令
Redis操作字符串类型常见的有以下命令set,get,mget,mset,setnx,setxx,incr,incrby,decr,decrby,incrbyfloat,append,getrange,setrange,strlen。下面将按顺序依次介绍用法。
代码语言:javascript复制SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
时间复杂度O(1),set命令可添加的选项:
- EX seconds⸺使⽤秒作为单位设置 key 的过期时间。
- PX milliseconds⸺使⽤毫秒作为单位设置 key 的过期时间。
- NX ⸺只在 key 不存在时才进⾏设置,即如果 key 之前已经存在,设置不执⾏。
- XX ⸺只在 key 存在时才进⾏设置,即如果 key 之前不存在,设置不执⾏。
get key
时间复杂度O(1),get命令返回key对应的value(value只能是字符串类型),key不存在时返回nil 。
代码语言:javascript复制MGET key [key ...]
时间复杂度O(N), mget命令用于一次查询多个key值,因为Redis是客户端-服务器结构,每条命令都需要经过网络传递到服务器执行,把多条命令结合在一次执行能很大程度减少因为网络传递消耗的时间。
代码语言:javascript复制MSET key value [key value ...]
时间复杂度O(N),mset的设计初衷与mget相似。
代码语言:javascript复制INCR key
时间复杂度O(1),incr返回 key的值加一。
代码语言:javascript复制INCRBY key decrement
时间复杂度O(1),incrby返回key的值加decrement。
代码语言:javascript复制DECR key
时间复杂度O(1),decr返回 key的值减一。
代码语言:javascript复制DECRBY key decrement
时间复杂度O(1),decrby返回key的值减decrement。
代码语言:javascript复制INCRBYFLOAT key increment
时间复杂度O(1),incrbyfloat返回key的值加decrement。(可以是浮点数类型)
代码语言:javascript复制APPEND KEY VALUE
时间复杂度O(1),append把value 追加到原有 string 的后边。
代码语言:javascript复制GETRANGE key start end
时间复杂度O(N),getrange类似于切片,返回key对应string的子串,左右区间均为闭区间,可以用负数表示从后往前数。
代码语言:javascript复制SETRANGE key offset value
时间复杂度O(N),setrange命令从offset位置开始用value覆盖原字符串后面的内容。
代码语言:javascript复制STRLEN key
时间复杂度O(1),strlen用于返回字符串的长度。
(2)内部编码
Redis的字符串类型在内存中存储时有三种编码方式,分别是int,embstr和raw三种类型,Redis会根据当前值的类型和长度动态决定使用哪种内部编码实现,可以通过object encoding key 命令来查看编码方式。
- int:8 个字节的⻓整型。
- embstr:⼩于等于 39 个字节的字符串。
- raw:⼤于 39 个字节的字符串。
2.Hash类型
Redis本身就是依据键值对进行数据存储的,所谓哈希类型指的是在Redis的值当中又存在多个键值对结构。形如 key = "key",value = { { field1, value1 }, ..., {fieldN, valueN } }。
(1)常见命令
hash类型的常见命令有hset,hget,hexists,hdel,hkeys,hvals,hgetall,hmget,hlen,hsetnx,hincrby,hincrbyfloat,hstrlen。下面将按顺序依次介绍用法。
代码语言:javascript复制HSET key field value [field value ...]
时间复杂度为O(N), hset命令负责插入N组键值对,返回添加字段个数。
代码语言:javascript复制HGET key field
时间复杂度为O(1), hget命令返回字段对应的值或者nil。
代码语言:javascript复制HEXISTS key field
时间复杂度为O(1), hexists负责判断字段是否存在。
代码语言:javascript复制HDEL key field [field ...]
时间复杂度为O(N), hdel命令用来删除指定字段。
代码语言:javascript复制HKEYS key
时间复杂度为O(N), hkeys用来获取hash中的所有字段。
代码语言:javascript复制HVALS key
时间复杂度为O(N), hvals用来获取hash中所有的值。
代码语言:javascript复制HGETALL key
时间复杂度为O(N), hgetall用来获取hash中所有字段以及对应的值。
代码语言:javascript复制HMGET key field [field ...]
时间复杂度为O(N), hmget用于一次性获取多个字段的值。
代码语言:javascript复制HLEN key
时间复杂度为O(1), hlen用于获取hash中的所有字段的个数。
代码语言:javascript复制HSETNX key field value
时间复杂度为O(1),hsetnx在字段不存在的情况下,设置hash中的字段和值。
代码语言:javascript复制HINCRBY key field increment
时间复杂度为O(1), hincrby将hash中字段对应的数值添加指定的值。
代码语言:javascript复制HINCRBYFLOAT key field increment
时间复杂度为O(1), hincrbyfloat与hincrby相似不过添加的值为浮点数。
代码语言:javascript复制HSTRLEN key field
时间复杂度为O(1),hstrlen命令用于计算value的字符串的长度。
(2)内部编码
hash类型在内存中的编码方式有两种,分别是ziplist和hashtable类型。Redis会根据当前值的类型和长度动态决定使用哪种内部编码实现,可以通过object encoding key 命令来查看编码方式。
- ziplist(压缩列表):当哈希类型元素个数⼩于 hash-max-ziplist-entries 配置(默认 512 个)、 同时所有值都⼩于 hash-max-ziplist-value 配置(默认 64 字节)时,Redis 会使⽤ ziplist 作为哈希的内部实现,ziplist 使⽤更加紧凑的结构实现多个元素的连续存储,所以在节省内存⽅⾯⽐hashtable 更加优秀。
- hashtable(哈希表):当哈希类型⽆法满⾜ ziplist 的条件时,Redis 会使⽤ hashtable 作为哈希 的内部实现,因为此时 ziplist 的读写效率会下降,⽽ hashtable 的读写时间复杂度为 O(1)。