Redis的五种数据类型

233 阅读7分钟

Redis的五种数据类型

  • String类型
  • Hash
  • list
  • set
  • zset

redis自身的存储方式是一个Map类型的,所有的数据都是采用key:value的形式存储的

这里数据类型指的是value部分的类型


键(key)

基本命令

命令描述
del key用于key存在时,删除key
dump key序列化给定的key,并返回序列化的值
exists key检查给定的key是否存在
expire key seconds对给定的key设置过期时间,以秒计
expireat key timestamp作用同上,设置过期时间,不同的是expireat命令接受的时间参数时unix时间戳
pexpire key milliseconds设置key的过期时间,以毫秒计
pexpireat key milliseconds-timestamp设置key过期时间的时间戳,以毫秒计
keys pattern查找所有给定模式(pattern)的key
move key db将当前数据库的key移动到给定数据库db中
persist key移除key的过期时间,key将持久保持
pttl key以毫秒为单位,返回key的剩余过期时间
ttl key以秒为单位,返回给定key剩余的生存时间
randomkey从数据库中随机返回一个key
rename key newkey修改key的名称
renamenx key newkey仅当newkey不存在时,将key名修改为newkey
scan cursor [match pattern] [Count count]迭代数据库中数据库键
type key返回key所存储的值的类型

String类型

String类型基本信息

  • String类型是一个二进制安全的,意思时redis的string可以包含任何数据,jpg图片或者序列化的对象等
  • String类型是redis中最基本的数据类型,一个redis中的value值最多是512M
  • 存储的格式:一个key对应一个value
  • 存储的内容:通常使用字符串,如果value中是以整数的形式展示,可以作为数字来操作。

常用命令

  1. 添加或者修改数据

    set key value

  2. 获取数据

    get key

  3. 删除数据

    del key

  4. 添加或修改多个数据

    mset key1 value1 key2 value2...

    msetnx key1 value1 key2 value2 ... 用于给定key都不存在时,同时设置为一个或多个key-value对

  5. 获取多个数据

    mget key1 key2...

  6. 获取字符串的长度 (数据字符个数)

    strlen key

  7. 在原始信息的尾部追加信息(如果存在原始信息就追加,没有就新建)

    append key value

  8. 设置数值数据增加指定范围的值

    incr key // 自增1

    incrby key increment //增加指定数值

    incrbyfloat key increment //增加一个浮点数

  9. 设置数值数据减少指定范围的值

    decr key //自减1

    decrby key increment //减少指定数值

String作为数值操作时注意事项

  • redis的操作都是原子性的,采用单线程处理所有业务,命令是一个一个的执行的,无需担心并发带来的数据影响
  • 按照数值进行操作时,如果没有装成数值,或者超出了redis数值上线的范围,会报错
  1. 设置数据的时效性

    setex key seconds value //增加、修改键值对并对其设置生命周期

  2. 新换旧

    getset key value

    192.168.30.70:6379> keys *
    (empty array)
    192.168.30.70:6379> getset k1 v100
    (nil)
    192.168.30.70:6379> get k1
    "v100"
    192.168.30.70:6379> getset k1 v100aaa
    "v100"
    192.168.30.70:6379> get k1
    "v100aaa"
    192.168.30.70:6379> 
    
  3. 对值的范围进行操作

    getrange key 起始位置 结束位置 获取值的范围,类似于java中substring

    setrange key 起始位置 value 用value值覆盖原始信息,从起始位置开始

    192.168.30.70:6379> keys *
    1) "k1"
    192.168.30.70:6379> getrange k1 0 -1
    "v100aaa"
    192.168.30.70:6379> getrange k1 0 1
    "v1"
    192.168.30.70:6379> getrange k1 0 3
    "v100"
    192.168.30.70:6379> setrange k1 3 tom
    (integer) 7
    192.168.30.70:6379> getrange k1 0 -1
    "v10toma"
    
    # 0 -1 表示获取key中的所有
    # 起始位置即索引位置
    

string类型的数据结构

相关链接:Redis底层数据结构之String

Redis中字符串称为Simple Dybamic String,简称SDS,与c语言原始的字符串相比,SDS多了一个头部信息,头部信息里面包含的内容如下:

struct sdsshr<T>{
    T len;             //数组长度      1byte      
    T capacity;        //数组容量      1byte
    unsigned  flags;   //sdshdr类型    1byte
    char content[];    //数组内容      长度为capacity
}

redis的数据是存储在内存中的,为了对内存的优化,对于不同长度的字符串,redis的底层会采用不同的结构体来表示,这也是为什么len和capacity要使用泛型T来定义。

三种底层编码方式如下:

  • 当存储的字符串都是数字时,此时使用int方式来存储操作。(但是value本质上还是String类型)
  • 当存储的字符串长度小于或者等于32字节时,使用embstr方式存储。
  • 当存储的字符串长度大于32字节时,使用raw方式来存储

SDS的优点

相较于原始c语言:

  1. 避免频繁的内存分配

    sds每次进行内存分配时,都会通过内存的预分配来减少因为修改字符串而引发的内存重分配次数。这个原理参考java中ArrayList

  2. 缓存区溢出

    缓存区溢出是指当某个数据超过了处理程序限制的范围时,程序出现异常操作。sds的修改函数在修改前会判断内存,动态的分配内存,避免缓存区溢出的问题

  3. 二进制安全

    sds通过len字段来判断是或否到结尾,具备二进制安全的特性


Redis 列表(List)

简单介绍

redis列别是简单的字符串列表,按照插入顺序排序。

常用命令

命令描述
blpop key1 [key2] timeout移出并获取列表的第一个元素,如果没有元素会阻塞列表直到等待超时或者发现可弹出元素为止。
brpop key1 [key2] timeout移出并获取最后一个元素,若列表没有元素会阻塞列表直到等待超时或者发现可弹出元素为止
brpoplpush source destination timeout从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它;若列表中没有元素会阻塞列表直到等待超时或者发现可弹出元素为止
lindex key index通过索引获取列表中元素
linsert key brfore/after pivot value在列表的元素前或者后插入元素
llen key获取列表长度
lpop key移出并获取列表的第一个元素
lpush key value1 ...将一个或者多个值插入到列表头部
lpushx key value将一个值插入到已存在的列表头部
lrange key start stop获取列表指定范围内的元素
lrem key count value移除列表元素
lset key index value通过索引设置列表元素的值
ltrim key start stop对于一个列表进行修剪,让列表只保留指定区间内的元素,不在指定区间内的元素都将被删除
rpop key移除列表的最后一个元素,返回值为移除的元素
rpoplpush source destination移除列表中的最后一个元素,并将该元素添加到另外一个列表中并返回
rpush key value1 ...在列表中添加一个或者多个值
rpushhx key value为已存在的列表添加值
192.168.30.70:6379> lpush list1 "holle" "tom" "hello" "jerry"
(integer) 4
192.168.30.70:6379> lrange list1 0 -1
1) "jerry"
2) "hello"
3) "tom"
4) "holle"
192.168.30.70:6379> blpop list1 2
1) "list1"
2) "jerry"
192.168.30.70:6379> brpop list1 3
1) "list1"
2) "holle"
192.168.30.70:6379> rpush list2 tom jack merry li
(integer) 4
192.168.30.70:6379> lindex list2 1
"jack"
192.168.30.70:6379> lrange list2 0 -1
1) "tom"
2) "jack"
3) "merry"
4) "li"
192.168.30.70:6379> brpoplpush list1 list2 4
"tom"
192.168.30.70:6379> lpop list1
"hello"
192.168.30.70:6379> lrange list1 0 -1
(empty array)
192.168.30.70:6379> llen list1
(integer) 0
192.168.30.70:6379> lrange list2 0 -1
1) "tom"
2) "tom"
3) "jack"
4) "merry"
5) "li"
192.168.30.70:6379> ltrim list2 1 3
OK
192.168.30.70:6379> lrange list2 0 -1
1) "tom"
2) "jack"
3) "merry"

Reids中List的底层数据结构

redis3.2版本之前,使用两种数据结构作为底层实现:压缩列表ziplist和双向链表linkedlist redis3.2版本开始,redis修改了list的底层实现,将压缩列表和双向链表结合,称之为quickList

quickList是一个zipList组成的双向链表。每个节点使用zipList来保存数据。本质上说quickList就是由一个一个小的zipList串起来的链表。