Redis:数据类型和基本命令

目录

1、string字符串

1.1 键值对操作

1.2 批量键值对操作

1.3 过期

1.4 计数

2、list列表

2.1 队列:反方向提交和获取

2.2 栈:同方向提交和获取

2.3 列表操作

2.4 快速列表

3、字典hash

3.1 渐进式rehash

3.2 设置操作

3.3 查询操作

3.4 获取集合

3.5 删除操作

3.6 单个字段的操作

4、集合set

4.1 基本操作

4.2 集合运算

5、有序集合zset

5.1 增加元素

5.2 获取元素

5.3 获取范围

5.4 计数个数

5.5 删除元素

5.6 增加元素分数

5.7 跳表

6、通用命令

6.1 过期时间

6.2 容器型数据结构的通用规则

6.3 其他命令


    Redis包含5中基本的数据类型。Redis中存储的数据是以键值对的形式进行存储的,Redis的数据类型指的是value部分的数据类型,而key部分则一直都是一个string字符串。

1、string字符串

    字符串常用来缓存用户信息,例如将用户信息的JSON序列化成字符串,存入到Redis。

    Redis的字符串是动态的、可修改的,这点和Java的字符串是不同的,Redis的字符串类似于Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配。

    当字符串长度小于1MB的时候,扩容是加倍现有的空间;如果字符串长度超过1MB,一次只会多扩1MB的空间。字符串的最大长度是512MB。

1.1 键值对操作

    对单个键值对的增删改查:

// 设置name = zhangsan(增或改)
set name zhangsan
// 如果属性不存在就执行set操作,可以理解为 set if not exists (增)
setnx name lisi
// 查询属性name对应的value(查)
get name
// 查询属性name是否存在(查)
exists name
// 删除属性name及其对应的value(删)
del name

1.2 批量键值对操作

    对多个键值对进行读写,以节省网络耗时开销。

// 批量设置
mset name1 zhangsan name2 lisi name3 wangwu
// 批量获取
mget name1 name2 name3

1.3 过期

    可以对key设置过期时间,到时间后会自动删除,以控制缓存的失效时间。

// 设置name 5s后超时,单位是s
expire name 5
// 设置name = lisi,且超时时间为5s
setex name 5 lisi

1.4 计数

    如果value是一个整数,还可以对它进行自增操作。自增的范围是有符号long型的最大值和最小值。

set age 30
// 递增,每次+1
incr age
// 递增,每次加2, 2可以设置
incrby age 2
// 递减,每次减1
decr age
// 递减,每次减2, 2可以设置
decrby age 2

2、list列表

    Redis的列表类似于Java中的LinkedList,它的数据结构是基于双向链表,而不是基于数组。

    Redis的列表经常用来做异步队列使用,将需要延后处理的任务结构体序列化并放入Redis的列表,另一个线程从这个列表中轮询数据进行处理。

    由于Redis的列表是双向链表,使用不同的使用方式可以分别达到队列和栈的效果。

    其实Redis的列表并不是简单的双向链表,而是一种“快速链表(quicklist)”。在列表元素较少的情况下,会使用一块连续的内存存储数据,这种结构叫做压缩列表(ziplist);当数据量比较大的时候,则会修改为quicklist,而quicklist实际上是链表和ziplist结合使用的一个结果。由于ziplist需要的是连续的内存空间,数据量较大的时候分配多个连续的大块内存,会造成空间冗余,导致内存空间的浪费,同时还会加重内存的碎片化。

2.1 队列:反方向提交和获取

    队列的特点是先进先出。可以通过在一个方向放入数据,在另一个方向弹出数据,来实现队列的结构。

// 从右侧向列表中按照前后顺序依次放入多个元素。r表示right
rpush names zhangsan lisi wangwu
// 获取列表的长度
llen names
// 从左侧出栈一个数据,数据弹出后列表中就没有这个元素了。l表示left
lpop names

    当然,上述方向反过来,从左边放入从右边弹出元素,也是可以的。

2.2 栈:同方向提交和获取

    栈是后入先出的数据结构,可以通过在同一个方向放入元素和弹出数据来实现。使用到的命令和队列基本相同。

// 从右侧向列表中按照前后顺序依次放入多个元素。r表示right
rpush names zhangsan lisi wangwu
// 从又侧出栈一个数据,数据弹出后列表中就没有这个元素了。l表示left
rpop names

2.3 列表操作

    上面两节用到的都是对端点元素的放入和弹出操作,根据链表的特性可知,时间复杂度都是O(1)。作为列表,还有一些基于列表特性的一些操作,不过这些操作的时间复杂度大多会高一些。

    有如下相关命令:

rpush names zhangsan lisi wangwu
// 查询
// 获取指定index的元素,时间复杂度是O(n)
lindex names 1
// 获取指定范围的全部元素,时间复杂度是O(n)
lrange names 0 -1
// 获取列表的长度
llen names 

// 删除
// 清除指定范围的全部元素,时间复杂度是O(n)
ltrim names 1 -1
// 删除从左向右数的前1个值为李四的节点
lrem names 1 lisi

// 增加和修改
// 设置指定索引位置的元素的值,索引为0表示左边第一个元素
lset names 1 zhaoliu
// 在lisi后面插入元素zhaoliu(后面指的是右边)
linsert names after lisi zhaoliu

// 其他
// 把一个列表的元素转移到另一个列表
rpoplpush names newnames

lindex

    lindex用来获得指定索引的元素值。索引从0开始,左边第一个元素的索引是0。

    语法:LINDEX key index

lrange

    lrange命令是列表类型最常用的命令之一,获取列表中的某一片段,将返回start、stop之间的所有元素(包含两端的元素),索引从0开始,左边的第一个元素的索引是0。索引可以是负数,如:“-1”代表最后边的一个元素。

    语法:LRANGE key start stop

llen

    llen用来获取列表中元素的个数。

    语法:LLEN key

ltrim

    ltrim清除指定范围的全部元素。指定范围和lrange一致。

    语法:LTRIM key start stop

lrem

    lrem命令会删除列表中从左数前count个值为value的元素,返回实际删除的元素个数。根据count值的不同,该命令的执行方式会有所不同:

  1. 当count>0时, LREM会从列表左边开始删除。
  2. 当count<0时, LREM会从列表后边开始删除。
  3. 当count=0时, LREM删除所有值为value的元素。

    语法:LREM key count value

lset

    设置指定索引的元素值。索引是从0开始的,左边第一个元素的索引值为0。

    语法:LSET key index value

linsert

    该命令首先会在列表中从左到右查找值为pivot的元素,然后根据第二个参数是BEFORE还是AFTER来决定将value插入到该元素的前面还是后面。

    语法:LINSERT key BEFORE|AFTER pivot value

rpoplpush

    将元素从一个列表转移到另一个列表中。

    语法:RPOPLPUSH source destination

3、字典hash

    hash类型也叫字典或者散列类型,它提供了字段和字段值的映射,它的字段和字段值都只能是字符串类型。hash类型也可以用来存储用户信息。和string相比,hash不需要全部序列化用户数据,可以单独保存用户数据中的每个字段,以方便读取,节省网络流量。当然hash结构也有不足,它的存储消耗是要高于string的。

    Redis的hash类型类似于Java中的HashMap,是一种无序的字典结构。hash类型的底层也是基于数组+链表来实现的,当发生hash冲突的时候,就把冲突的元素放入到同一个链表中。

3.1 渐进式rehash

    Redis的hash类型和Java的HashMap的rehash的方式是不同的。Java的HashMap的rehash是一次性rehash全部的元素,这样在字典很大的时候会导致耗时严重的问题。Redis为了追求高性能,采用渐进式rehash策略。

    渐进式rehash的特点是,在rehash期间保留新旧两个hash结构,这样在查询的时候会同时查询两个hash结构,然后在后续的定时任务已经hash操作指令中,循序渐进地将旧hash的内容迁移到新的hash结构,直到迁移完毕,删除旧的hash结构。

3.2 设置操作

// 如果是插入字段值,则返回1;如果是更新字段值,则返回0
hset names zhang zhangsan
// 如果字段值中间有空格,则必须用双引号括起来
hset names li "li si"
// 批量设置字段值
hmset names wang wangwu zhao zhaoliu
// 当字段不存在时赋值,否则不执行赋值操作
hsetnx names li lidasi

3.3 查询操作

// 获取指定字段的字段值
hget names zhang
// 获取key对应的全部字段-字段值组合
hgetall names
// 一次获取多个字段的字段值
hmget names zhang li wang
// 获取hash的字段数量
hlen names
// 字段是否存在。返回值为1表示字段存在
hexists names zhang

3.4 获取集合

// 获取全部字段名
hkeys names
// 获取全部字段值
hvals names

3.5 删除操作

// 删除指定字段,可以是单个或多个字段。返回值是被删除的字段个数
hdel names zhang li

3.6 单个字段的操作

    hash还可以对单个字段进行操作,包括计数、增加等。

hset ages zhangsan 20
// 按1的步长递增
hincrby ages zhangsan 1

4、集合set

    Redis的set相当于Java的HashSet,内部是无序且不可重复的字段。它的内部实现也和Java的HashSet类似,是一个特殊的字典,只不过所有的字段值都是null。

    如果set的全部元素都被移除后,集合的数据结构将会被删除,内存空间也会被回收。

4.1 基本操作

// 向集合中加入一个元素
sadd names zhangsan
// 查询集合中的全部元素
smenbers names
// 查询集合中是否存在指定元素。返回1表示存在,0表示不存在
sismember names zhangsan
// 计数集合中的元素数量
scard names
// 从集合中弹出一个元素。一般用在遍历并清空结合的操作
spop names
// 删除指定的一个或多个元素
srem names zhangsan lisi

4.2 集合运算

sadd setA 1 2 3
sadd setB 2 3 4
// 差集:返回属于A并且不属于B的元素集
sdiff setA setB
// 交集:属于A且属于B的元素元素集
sinter setA setB
// 并集:属于A或者属于B的元素集
sunion setA setB

5、有序集合zset

    Sortedset又叫zset。Sortedset是有序集合,可排序并且不可重复。zset兼具Java的SortedSet和HashMap的特性。一方面zset是一个集合,具备集合的特性,即内部元素是唯一的;另一方面,它也给每个元素赋予一个分数,代表这个元素的排序权重,然后通过这个分数进行排序。

    跟set一样,当最后一个元素都被移除后,会删除结构并回收内存。

5.1 增加元素

// 增加元素
zadd names 5 zhangsan
zadd names 4.5 lisi
zadd names 3.7 "wang wu"

5.2 获取元素

// 获取元素的分数
zscore names zhangsan
// 获取元素从小到大的排名
zrank names zhangsan
// 获取元素从大到小的排名
zrevrank names zhangsan

5.3 获取范围

// 打印范围内的全部元素,按照元素分数从小到大的顺序返回,包含两端的元素
// 下标参数start和stop都以0为底,也就是说,以0表示有序集第一个成员,以1表示有序集第二个成员,以此类推
// 负数下标,以-1表示最后一个成员,-2 表示倒数第二个成员,以此类推。
zrange names 0 -1
// 逆序列出全部元素
zrevrange names 0 -1
// 获得指定分数范围的元素
zrangebyscore names 0 4.6
// inf即infinite,表示无穷大;withscores表示返回结果携带着分数值
zrangebyscore names -inf 4.6 withscores

5.4 计数个数

// 计数集合中元素的个数
zcard names
// 获取分数范围内的元素个数
zcount names 4 5

5.5 删除元素

// 删除元素
zrem names lisi
// 删除分数范围内的元素
zremrangebyscore names 0 4
// 删除排名范围内的元素
zremrangebyrank names 0 1

5.6 增加元素分数

// zhangsan的分数增加4分
zincrby names 4 zhangsan

5.7 跳表

    由于当zset插入元素的时候,要按排序结果插入到合适的位置,所以zset需要支持随机的插入和删除,所以不适合使用数组来实现;而如果使用链表来实现,又不能很快的定位指定的位置。实际上,zset内部的排序功能是通过跳表来实现的。跳表查询和插入、删除的时间复杂度都是O(lgn)。

6、通用命令

    还有一些是全部或者多个数据类型通用的操作。

6.1 过期时间

    Redis所有的数据结构都可以设置过期时间,时间到了Redis会自动删除相应的对象。需要注意的是,过期是以Redis的一组key-value为单位的,例如hash类型,已过期整个hash对象和它对应的key都会过期。

    另外,如果一个字符串已经设置了过期时间,然后调用set方法修改了它,那么过期时间失效。

// 设置name 5s后超时,单位是s
expire name 5
// 查看key生于的生存时间
ttl key
// 清除生存时间
persist key
// 生存时间设置单位为:毫秒
pexpire key milliseconds

6.2 容器型数据结构的通用规则

    list、hash、set、zset四种数据结构是容器型的数据结构,共享以下两条规则:

  1. create if not exists:如果容器不存在,就创建一个,再进行操作;
  2. drop if no elements:如果容器中不包含元素了,就立刻删除容器,释放内存。

6.3 其他命令

// 列出符合给定pattern的所有key
keys name*
// 确认一个key 是否存在
exists name
// 删除一个key
del name
// 重命名key
rename name name_new
// 返回key对应的值的类型
type name
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值