前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis五种数据类型及命令操作(一)

Redis五种数据类型及命令操作(一)

作者头像
可为编程
发布2023-11-14 11:52:46
2800
发布2023-11-14 11:52:46
举报

戳上方蓝字“可为编程” 点击右上角选择“设为星标”,好文不错过!

上回我们介绍了Redis的部署及简单的原理性介绍,今天总结一下Redis的数据类型以及操作命令包括String、List、Set,下一篇为Hash和ZSet,喜欢的记得点赞收藏。

概述

这里说的数据类型是value的数据类型,key的类型都是字符串。

5种数据类型:

  • redis字符串(String)
  • redis列表(List)
  • redis集合(Set)
  • redis哈希表(Hash)
  • redis有序集合(Zset)

哪里去获取redis常用数据类型操作命令:http://redis.cn/commands.html

这里我采用的Docker容器化部署Redis,后面会单独出一篇文章详细介绍容器化Redis的部署和操作文章。

首先连接并登录Redis,执行以下命令:

代码语言:javascript
复制
redis-cli -h host -p port -a password
redis-cli -h 192.168.30.198 -p 6379 -a 1234 //这是我本地IP
代码语言:javascript
复制
root@391f6fd11521:/data# redis-cli -h 192.168.30.198 -p 6379 -a 1234
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.30.198:6379>

提示我们直接使用密码形式是不安全的,直接忽略即可,因为我们一般操作Redis都是在程序中采用,将密码配置在项目的配置文件当中,诚然在实际的生产环境中不能将Redis密码设置的这么简单,因为很可能被不法分子将你的Redis当成肉鸡,攻击者可以通过向Redis发送大量的请求,导致其负载过高,进而使Redis崩溃。

Redis通用操作命令

通用Redis操作命令

  • keys *:查看当前库所有的key
  • exists key:判断某个key是否存在 0表示不存在 1表示存在
代码语言:javascript
复制
192.168.30.198:6379> exists kewei
(integer) 0
192.168.30.198:6379> set kewei keweibiancheng
OK
192.168.30.198:6379> exists kewei
(integer) 1
  • type key:查看你的key是什么类型
代码语言:javascript
复制
192.168.30.198:6379> type kewei
string
192.168.30.198:6379>
  • del key:删除指定的key数据
  • unlink key:根据value删除非阻塞删除,仅仅将keys从keyspace元数据中删除,真正的删除会在后续异步中操作。
代码语言:javascript
复制
192.168.30.198:6379> unlink kewei
(integer) 1
192.168.30.198:6379> get kewei
(nil)
192.168.30.198:6379>
  • expire key 10:为指定的key设置有效期10秒
  • ttl key:查看指定的key还有多少秒过期,-1:表示永不过期,-2:表示已过期
代码语言:javascript
复制
192.168.30.198:6379> set kewei keweibiancheng
OK
192.168.30.198:6379> ttl kewei
(integer) -1
192.168.30.198:6379> ttl kewei
(integer) -1
192.168.30.198:6379> expire kewei 10
(integer) 1
192.168.30.198:6379> ttl kewei
(integer) 7
192.168.30.198:6379> ttl kewei
(integer) 6
192.168.30.198:6379> ttl kewei
(integer) 5
192.168.30.198:6379> ttl kewei
(integer) 4
192.168.30.198:6379> ttl kewei
(integer) 3
192.168.30.198:6379> ttl kewei
(integer) 2
192.168.30.198:6379> ttl kewei
(integer) 1
192.168.30.198:6379> ttl kewei
(integer) 0
192.168.30.198:6379> ttl kewei
(integer) -2
  • select dbindex:切换数据库【0-15】,默认为0
代码语言:javascript
复制
192.168.30.198:6379> select 6
OK
192.168.30.198:6379[6]>
  • dbsize:查看当前数据库key的数量
代码语言:javascript
复制
192.168.30.198:6379> dbsize
(integer) 3532
192.168.30.198:6379>
  • flushdb:清空当前库
  • flushall:通杀全部库

上面这俩就不演示了,不然数据都没了

Redis字符串(String)

简介

String是Redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。String类型是二进制安全的。意味着Redis的string可以包含任何数据。比如jpg图片或者序列化的对象。同时String类型是Redis最基本的数据类型,一个Redis中字符串value最多可以是512M大小的字符串。

常用命令

set:添加键值对
代码语言:javascript
复制
127.0.0.1:6379>set key value [EX seconds|PX milliseconds|EXAT timestamp|PXAT milliseconds-timestamp|KEEPTTL][NX|XX][GET]
 

  • NX:当数据库中key不存在时,可以将key-value添加到数据库
  • XX:当数据库中key存在时,可以将key-value添加数据库,与NX参数互斥
  • EX:key的超时秒数
  • PX:key的超时毫秒数,与EX互斥
  • value中若包含空格、特殊字符,需用双引号包裹
get:获取值
代码语言:javascript
复制
get<key>

示例

代码语言:javascript
复制
127.0.0.1:6379>set name kewei
 
OK
 
127.0.0.1:6379>get name
 
"kewei"
 
apend:追加值
代码语言:javascript
复制
append <key><value>

将给定的value追加到原值的末尾。

示例

代码语言:javascript
复制
127.0.0.1:6379>set k1 hello
 
OK
 
127.0.0.1:6379> append k1 " world"
 
(integer)11
 
127.0.0.1:6379>get k1
 
"hello world"
strlen:获取值的长度
代码语言:javascript
复制
strlen <key>

示例

代码语言:javascript
复制
127.0.0.1:6379>set name ready
 
OK
 
127.0.0.1:6379> strlen name
 
(integer)5
setnx:key不存在时,设置key的值
代码语言:javascript
复制
setnx <key><value>

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb #清空db,方便测试
 
OK
 
127.0.0.1:6379> setnx site "kewei"#kewei不存在,返回1,表示设置成功
 
(integer)1
 
127.0.0.1:6379> setnx kewei "可为编程"
 
(integer) 1
 
127.0.0.1:6379> get kewei
 
"\xe5\x8f\xaf\xe4\xb8\xba\xe7\xbc\x96\xe7\xa8\x8b"
 
127.0.0.1:6379>
 
127.0.0.1:6379> setnx kewei "可为编程"#再次通过setnx设置kewei,由于已经存在了,所以设置失败,返回0
 
(integer)0
 

incr:原子递增1
代码语言:javascript
复制
incr <key>

将key中存储的值增1,只能对数字值操作,如果key不存在,则会新建一个,值为1,注意我们设置自增的key的value需是Integet数值类型,小数和字符串都不可以设置自增。

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb #清空db,方便测试
 
OK
 
127.0.0.1:6379>set age 30#age值为30
 
OK
 
127.0.0.1:6379> incr age #age增加1,返回31
 
(integer)31
 
127.0.0.1:6379>get age #获取age的值
 
"31"
 
127.0.0.1:6379> incr salary #salary不存在,自动创建一个,值为1
 
(integer)1
 
127.0.0.1:6379>get salary #获取salary的值
 
"1"
 

decr:原子递减1
代码语言:javascript
复制
decr <key>

将key中存储的值减1,只能对数字值操作,如果为空,新增值为-1

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb #清空db,方便测试
 
OK
 
127.0.0.1:6379>set age 30#age值为30
 
OK
 
127.0.0.1:6379> decr age #age递减1,返回29
 
(integer)29
 
127.0.0.1:6379>get age #获取age的值
 
"29"
 
127.0.0.1:6379> decr salary #salary不存在,自动创建一个,值为-1
 
(integer)-1
 
127.0.0.1:6379>get salary #获取salary
 
"-1"
 

incrby/decrby:递增或者递减指定的数字
代码语言:javascript
复制
incrby/decrby <key><步长>

将key中存储的数字值递增指定的步长,若key不存在,则相当于在原值为0的值上递增指定的步长。

示例

代码语言:javascript
复制
127.0.0.1:6379>set salary 10000#设置salary为10000
 
OK
 
127.0.0.1:6379> incrby salary 5000#salary添加5000,返回15000
 
(integer)15000
 
127.0.0.1:6379>get salary #获取salary
 
"15000"
 
127.0.0.1:6379> decrby salary 800#salary减去800,返回14200
 
(integer)14200
 
127.0.0.1:6379>get salary #获取salary
 
"14200"
 
mset:同时设置多个key-value
代码语言:javascript
复制
mset <key1><value1><key2><value2>...

示例

代码语言:javascript
复制
127.0.0.1:6379> mset name ready age 30
 
OK
 
127.0.0.1:6379>get name
 
"ready"
 
127.0.0.1:6379>get age
 
"30"
 

mget:获取多个key对应的值
代码语言:javascript
复制
mget <key1><key2>...
 

示例

代码语言:javascript
复制
127.0.0.1:6379> mset name ready age 30#同时设置name和age
 
OK
 
127.0.0.1:6379> mget name age #同时读取name和age的值
 
1)"ready"
 
2)"30"
 

msetnx:当多个key都不存在时,则设置成功
代码语言:javascript
复制
msetnx <key1><value1><key2><value2>...
 

原子性的,要么都成功,或者都失败。

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb #清空db,方便测试
 
OK
 
127.0.0.1:6379>set k1 v1 #设置k1
 
OK
 
127.0.0.1:6379> msetnx k1 v1 k2 v2 #当k1和k2都不存在的时候,同时设置k1和k2,由于k1已存在,所以这个操作失败
 
(integer)0
 
127.0.0.1:6379> mget k1 k2 #获取k1、k2,k2不存在
 
1)"v1"
 
2)(nil)
 
127.0.0.1:6379> msetnx k2 v2 k3 v3 #当k2、h3都不存在的时候,同时设置k2和k3,设置成功
 
(integer)1
 
127.0.0.1:6379> mget k1 k2 k3 #获取k1、k2、k3的值
 
1)"v1"
 
2)"v2"
 
3)"v3"
 

getrange:获取值的范围,类似java中的substring
代码语言:javascript
复制
getrange key start end
 

获取[start,end]返回为的字符串

示例

代码语言:javascript
复制
1、127.0.0.1:6379> set kewei keweibiancheng
2、OK
3、127.0.0.1:6379>
4、127.0.0.1:6379> get kewei 0 1
5、"ke"
setrange:覆盖指定位置的值
代码语言:javascript
复制
setrange <key><起始位置><value>
 

示例

代码语言:javascript
复制

127.0.0.1:6379>set k1 helloworld
 
OK
 
127.0.0.1:6379>get k1
 
"helloworld"
 
127.0.0.1:6379> setrange k1 1 java
 
(integer)10
 
127.0.0.1:6379>get k1
 
"hjavaworld"
 

setex:设置键值&过期时间(秒)
代码语言:javascript
复制
setex <key><过期时间(秒)><value>
 

示例

代码语言:javascript
复制
127.0.0.1:6379> setex k1 100 v1 #设置k1的值为v1,有效期100秒
 
OK
 
127.0.0.1:6379>get k1 #获取k1的值
 
"v1"
 
127.0.0.1:6379> ttl k1 #获取k1还有多少秒失效
 
(integer)96
 

getset:以新换旧,设置新值同时返回旧值
代码语言:javascript
复制
getset <key><value>
 

127.0.0.1:6379>set name ready #设置name为ready
 
OK
 
127.0.0.1:6379> getset name tom #设置name为tom,返回name的旧值
 
"ready"
 
127.0.0.1:6379> getset age 30#设置age为30,age未设置过,返回age的旧值为null
 

(nil)
 

数据结构

String的数据结构为简单动态字符串(Simple Dynamic String,缩写SDS)。是可以修改的字符串,内部结构上类似于Java的ArrayList,采用分配冗余空间的方式来减少内存的频繁分配。

如图所示,内部为当前字符串实际分配的空间capacity一般要高于实际字符串长度len。当字符串长度小于1M时,扩容都是加倍现有的空间,如果超过1M,扩容时一次会多扩容1M的空间。我们要注意的是字符串最大长度为512M。

Redis列表(List)

简介

Redis的列表可以说是单键多值,其只是简单的字符串列表,按照插入顺序排序。可以添加一个元素到列表的头部(左边)或者尾部(右边)。其实它的底层实际上是使用双向链表实现的,对两端的操作性能很高,通过索引下标操作中间节点性能会较差。后面我会针对数据结构再出一系列文章,再去讨论双向链表的原理。

常用命令

lpush/rpush:从左边或者右边插入一个或多个值
代码语言:javascript
复制
lpush/rpush <key1> <value1> <key2> <value2> ...

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb #清空db,方便测试
 
OK
 
127.0.0.1:6379> rpush name java spring "springboot" "spring cloud" #列表name的右边插入4个元素
 
(integer) 4
 
127.0.0.1:6379> lrange name 1 2 #从左边取出索引位于[1,2]范围内的元素
 
1) "spring"
 
2) "springboot"
 

lrange:从列表左边获取指定范围内的值
代码语言:javascript
复制
lrange <key> <star> <stop>
 

返回列表 key 中指定区间内的元素,区间以偏移量 startstop 指定。 下标(index)参数 startstop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。 返回值: 一个列表,包含指定区间内的元素。

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb
 
OK
 
127.0.0.1:6379> rpush course java c c++ php js nodejs #course集合的右边插入6个元素
 
(integer) 6
 
127.0.0.1:6379> lrange course 0 -1 #取出course集合中所有元素
 
1) "java"
 
2) "c"
 
3) "c++"
 
4) "php"
 
5) "js"
 
6) "nodejs"
 
127.0.0.1:6379> lrange course 1 3 #获取course集合索引[1,3]范围内的元素
 
1) "c"
 
2) "c++"
 
3) "php"
 

lpop/rpop:从左边或者右边弹出多个元素
代码语言:javascript
复制
lpop/rpop <key> <count>

count:可以省略,默认值为1 lpop/rpop 操作之后,弹出来的值会从列表中删除 值在键在,值光键亡。

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb
 
OK
 
127.0.0.1:6379> rpush course java c++ php js node js #集合course右边加入6个元素
 
(integer) 6
 
127.0.0.1:6379> lpop course #从左边弹出1个元素
 
"java"
 
127.0.0.1:6379> rpop course 2 #从右边弹出2个元素
 
1) "js"
 
2) "node"
 

rpoplpush:从一个列表右边弹出一个元素放到另外一个列表中
代码语言:javascript
复制
rpoplpush source destination
 

从source的右边弹出一个元素放到destination列表的左边

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb
 
OK
 
127.0.0.1:6379> rpush k1 1 2 3 #列表k1的右边添加3个元素[1,2,3]
 
(integer) 3
 
127.0.0.1:6379> lrange k1 0 -1 #从左到右输出k1列表中的元素
 
1) "1"
 
2) "2"
 
3) "3"
 
127.0.0.1:6379> rpush k2 4 5 6 #列表k2的右边添加3个元素[4,5,6]
 
(integer) 3
 
127.0.0.1:6379> lrange k2 0 -1 #从左到右输出k2列表中的元素
 
1) "4"
 
2) "5"
 
3) "6"
 
127.0.0.1:6379> rpoplpush k1 k2 #从k1的右边弹出一个元素放到k2的左边
 
"3"
 
127.0.0.1:6379> lrange k1 0 -1 #k1中剩下2个元素了
 
1) "1"
 
2) "2"
 
127.0.0.1:6379> lrange k2 0 -1 #k2中变成4个元素了
 
1) "3"
 
2) "4"
 
3) "5"
 
4) "6"
 

lindex:获取指定索引位置的元素(从左到右)
代码语言:javascript
复制
lindex key index
 

这样就返回列表 key 中,下标为 index 的元素。下标(index)参数 startstop 都以 0 为底,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推,这个和java中的list也是一样的。你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。但是需要注意的是如果 key 不是列表类型,返回一个错误。 返回值: 列表中下标为 index 的元素。如果 index 参数的值不在列表的区间范围内的话回报超出范围异常(out of range),返回 nil。

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb
 
OK
 
127.0.0.1:6379> rpush course java c c++ php #列表course中放入4个元素
 
(integer) 4
 
127.0.0.1:6379> lindex course 2 #返回索引位置2的元素
 
"c++"
 
127.0.0.1:6379> lindex course 200 #返回索引位置200的元素,没有
 
(nil)
 
127.0.0.1:6379> lindex course -1 #返回最后一个元素
 
"php"
 

llen:获得列表长度
代码语言:javascript
复制
llen key

返回列表 key 的长度。如果 key 不存在,则 key 被解释为一个空列表,返回 0 。如果 key 不是列表类型,返回一个错误。

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb
 
OK
 
127.0.0.1:6379> rpush name ready tom jack
 
(integer) 3
 
127.0.0.1:6379> llen name
 
(integer) 3
 

linsert:在某个值的前或者后面插入一个值
代码语言:javascript
复制
linsert <key> before|after <value> <newvalue>
 

将值 newvalue 插入到列表 key 当中,位于值 value之前或之后,当 value 不存在于列表 key 时,不执行任何操作。但是当 key 不存在时, key 被视为空列表,不执行任何操作指令。如果 key 不是列表类型,返回一个错误。 返回值: 如果命令执行成功,返回插入操作完成之后,列表的长度。 如果没有找到 value ,返回 -1 。 如果 key 不存在或为空列表,返回 0

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb
 
OK
 
127.0.0.1:6379> rpush name ready tom jack #列表name中添加3个元素
 
(integer) 3
 
127.0.0.1:6379> lrange name 0 -1 #name列表所有元素
 
1) "ready"
 
2) "tom"
 
3) "jack"
 
127.0.0.1:6379> linsert name before tom lily #tom前面添加lily
 
(integer) 4
 
127.0.0.1:6379> lrange name 0 -1 #name列表所有元素
 
1) "ready"
 
2) "lily"
 
3) "tom"
 
4) "jack"
 
127.0.0.1:6379> linsert name before xxx lucy # 在元素xxx前面插入lucy,由于xxx元素不存在,插入失败,返回-1
 
(integer) -1
 
127.0.0.1:6379> lrange name 0 -1
 
1) "ready"
 
2) "lily"
 
3) "tom"
 
4) "jack"
 

lrem:删除指定数量的某个元素
代码语言:javascript
复制
LREM key count value
 

根据参数 count 的值,移除列表中与参数 value 相等的元素。 count 的值可以是以下几种:

  • count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count
  • count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。
  • count = 0 : 移除表中所有与 value 相等的值。

返回值: 被移除元素的数量。 因为不存在的 key 被视作空表(empty list),所以当 key 不存在时,总是返回 0

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb #清空db,方便测试
 
OK
 
127.0.0.1:6379> rpush k1 v1 v2 v3 v2 v2 v1 #k1列表中插入6个元素
 
(integer) 6
 
127.0.0.1:6379> lrange k1 0 -1 #输出k1集合中所有元素
 
1) "v1"
 
2) "v2"
 
3) "v3"
 
4) "v2"
 
5) "v2"
 
6) "v1"
 
127.0.0.1:6379> lrem k1 2 v2 #k1集合中从左边删除2个v2
 
(integer) 2
 
127.0.0.1:6379> lrange k1 0 -1 #输出列表,列表中还有1个v2,前面2个v2干掉了
 
1) "v1"
 
2) "v3"
 
3) "v2"
 
4) "v1"
 

lset:替换指定位置的值
代码语言:javascript
复制
lset <key> <index> <value>
 

将列表 key 下标为 index 的元素的值设置为 value 。当 index 参数超出范围,或对一个空列表( key 不存在)进行lset时,返回一个错误。 返回值: 操作成功返回 ok ,否则返回错误信息。

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb #清空db,方便测试
 
OK
 
127.0.0.1:6379> rpush name tom jack ready #name集合中放入3个元素
 
(integer) 3
 
127.0.0.1:6379> lrange name 0 -1 #输出name集合元素
 
1) "tom"
 
2) "jack"
 
3) "ready"
 
127.0.0.1:6379> lset name 1 lily #将name集合中第2个元素替换为liy
 
OK
 
127.0.0.1:6379> lrange name 0 -1 #输出name集合元素
 
1) "tom"
 
2) "lily"
 
3) "ready"
 
127.0.0.1:6379> lset name 10 lily #索引超出范围,报错
 
(error) ERR index out of range
 
127.0.0.1:6379> lset course 1 java #course集合不存在,报错
 
(error) ERR no such key
 

数据结构

List的数据结构为快速链表quickList,快速链表是一个双向链表,首先在列表元素较少的情况下会使用一块连续的内存存储,这个结构是ziplist,也就是压缩列表。它将所有的元素紧挨着一起存储,分配的是一块连续的内存,这样节省空间。当存储的数据比较多的时候才会改成quickList。

redis3 .2版本之前,List类型数据使用的底层数据结构是压缩列表(ziplist)或双向链表(linkedlist),当列表元素个数比较少并且每个元素占用空间比较小时使用压缩列表;当列表元素个数比较多或者某个元素占用空间比较大的时使用双向链表,redis3 .2版本开始,List类型数据使用的底层数据结构是快速列表,快速列表是以压缩列表为节点的双向链表,将双向链表按段切分,每一段使用压缩列表进行内存的连续存储,多个压缩列表通过prev和next指针组成的双向链。其实快速列表实质就是压缩列表+双向链表的组合,结合了压缩列表和双向链表各自的优点,因为普通的链表需要的附加指针空间太大,会比较浪费空间,比如这个列表里存储的只是int类型的数据,结构上还需要2个额外的指针prev和next。

Redis将链表和ziplist结合起来组成了quicklist。也就是将多个ziplist使用双向指针串起来使用,这样既满足了快速的插入删除性能,又不会出现太大的空间冗余。

Redis集合(Set)

2.4.1、简介

在Redis中的Set对外提供的功能和list很是类似,也是一个列表的功能,主要不同在于set是可以自动去重的,当需要存储一个不希望出现重复数据的时候,直接使用Set会事半功倍。Redis的set是String类型的无序集合,他的底层实际是一个value为null的hash表,所以其时间复杂度在添加、删除、查找都是O(1)。那就很香了,数据增加查找的时间还是不变的,这多香。

常用命令

sadd:添加一个或多个元素
代码语言:javascript
复制
sadd <key> <value1> <value2> ...
 

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb
 
OK
 
127.0.0.1:6379> sadd k1 v1 v2 v1 v3 v2 #k1中放入5个元素,会自动去重,成功插入3个
 
(integer) 3
 

smembers:取出所有元素
代码语言:javascript
复制
smembers <key>
 

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb
 
OK
 
127.0.0.1:6379> sadd k1 v1 v2 v1 v3 v2
 
(integer) 3
 
127.0.0.1:6379> smembers k1
 
1) "v2"
 
2) "v1"
 
3) "v3"
 

sismember:判断集合中是否有某个值
代码语言:javascript
复制
sismember <key> <value>
 

判断集合key中是否包含元素value,1:有,0:没有

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb
 
OK
 
127.0.0.1:6379> sadd k1 v1 v2 v1 v3 v2 #k1集合中成功放入3个元素[v1,v2,v3]
 
(integer) 3
 
127.0.0.1:6379> sismember k1 v1 #判断k1中是否包含v1,1:有
 
(integer) 1
 
127.0.0.1:6379> sismember k1 v5 #判断k1中是否包含v5,0:无
 
(integer) 0
 

scard:返回集合中元素的个数
代码语言:javascript
复制
scard <key>
 

返回集合 key 的基数(集合中元素的数量) 返回值: 集合的基数。 当 key 不存在时,返回 0

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb
 
OK
 
127.0.0.1:6379> sadd k1 v1 v2 v1 v3 v2
 
(integer) 3
 
127.0.0.1:6379> scard k1
 
(integer) 3
 
srem:删除多个元素
代码语言:javascript
复制
srem key member [member ...]
 

移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略。 当 key 不是集合类型,返回一个错误。 返回值: 被成功移除的元素的数量,不包括被忽略的元素。

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb #清空db,方测试
 
OK
 
127.0.0.1:6379> sadd course java c c++ python #集合course中添加4个元素
 
(integer) 4
 
127.0.0.1:6379> smembers course #获取course集合所有元素
 
1) "python"
 
2) "java"
 
3) "c++"
 
4) "c"
 
127.0.0.1:6379> srem course java c #删除course集合中的java和c
 
(integer) 2
 
127.0.0.1:6379> smembers course #获取course集合所有元素,剩下2个了
 
1) "python"
 
2) "c++"
 

spop:随机弹出多个值
代码语言:javascript
复制
spop <key> <count>
 

随机从key集合中弹出count个元素,count默认值为1 返回值: 被移除的随机元素。 当 key 不存在或 key 是空集时,返回 nil

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb
 
OK
 
127.0.0.1:6379> sadd course java c c++ python #course集合中添加4个元素
 
(integer) 4
 
127.0.0.1:6379> smembers course #获取course集合中所有元素
 
1) "python"
 
2) "java"
 
3) "c++"
 
4) "c"
 
127.0.0.1:6379> spop course #随机弹出1个元素,被弹出的元素会被删除
 
"c++"
 
127.0.0.1:6379> spop course 2 #随机弹出2个元素
 
1) "java"
 
2) "python"
 
127.0.0.1:6379> smembers course #输出剩下的元素
 
1) "c"
 

srandmember:随机获取多个元素,不会从集合中删除
代码语言:javascript
复制
srandmember <key> <count>
 

从key指定的集合中随机返回count个元素,count可以不指定,默认值是1。 srandmember 和 spop的区别: 都可以随机获取多个元素,srandmember 不会删除元素,而spop会删除元素。 返回值: 只提供 key 参数时,返回一个元素;如果集合为空,返回 nil 。 如果提供了 count 参数,那么返回一个数组;如果集合为空,返回空数组。

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb #清空db,方便测试
 
OK
 
127.0.0.1:6379> sadd course java c c++ python #course中放入5个元素
 
(integer) 4
 
127.0.0.1:6379> smembers course #输出course集合中所有元素
 
1) "python"
 
2) "java"
 
3) "c++"
 
4) "c"
 
127.0.0.1:6379> srandmember course 3 #随机获取3个元素,元素并不会被删除
 
1) "python"
 
2) "c++"
 
3) "c"
 
127.0.0.1:6379> smembers course #输出course集合中所有元素,元素个数未变
 
1) "python"
 
2) "java"
 
3) "c++"
 
4) "c"
 

smove:将某个元素从一个集合移动到另一个集合
代码语言:javascript
复制
smove <source> <destination> member
 

member 元素从 source 集合移动到 destination 集合。 smove 是原子性操作。 如果 source 集合不存在或不包含指定的 member 元素,则 smove 命令不执行任何操作,仅返回 0 。否则, member 元素从 source 集合中被移除,并添加到 destination 集合中去。 当 destination 集合已经包含 member 元素时,smove 命令只是简单地将 source 集合中的 member 元素删除。 当 sourcedestination 不是集合类型时,返回一个错误。 返回值: 如果 member 元素被成功移除,返回 1 。 如果 member 元素不是 source 集合的成员,并且没有任何操作对 destination 集合执行,那么返回 0

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb #清空db,方便测试
 
OK
 
127.0.0.1:6379> sadd course1 java php js #集合course1中放入3个元素[java,php,js]
 
(integer) 3
 
127.0.0.1:6379> sadd course2 c c++ #集合course2中放入2个元素[c,c++]
 
(integer) 2
 
127.0.0.1:6379> smove course1 course2 js #将course1中的js移动到course2
 
(integer) 1
 
127.0.0.1:6379> smembers course1 #输出course1中的元素
 
1) "java"
 
2) "php"
 
127.0.0.1:6379> smembers course2 #输出course2中的元素
 
1) "js"
 
2) "c++"
 
3) "c"
 

sinter:取多个集合的交集
代码语言:javascript
复制
sinter key [key ...]
 

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb
 
OK
 
127.0.0.1:6379> sadd course1 java php js #集合course1:[java,php,js]
 
(integer) 3
 
127.0.0.1:6379> sadd course2 c c++ js #集合course2:[c,c++,js]
 
(integer) 3
 
127.0.0.1:6379> sadd course3 js html #集合course3:[js,html]
 
(integer) 2
 
127.0.0.1:6379> sinter course1 course2 course3 #返回三个集合的交集,只有:[js]
 
1) "js"
 

sinterstore:将多个集合的交集放到一个新的集合中
代码语言:javascript
复制
sinterstore destination key [key ...]
 

这个命令类似于sinter命令,但它将结果保存到 destination 集合,而不是简单地返回结果集。 返回值: 结果集中的成员数量。

sunion:取多个集合的并集,自动去重
代码语言:javascript
复制
sunion key [key ...]
 

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb
 
OK
 
127.0.0.1:6379> sadd course1 java php js #集合course1:[java,php,js]
 
(integer) 3
 
127.0.0.1:6379> sadd course2 c c++ js #集合course2:[c,c++,js]
 
(integer) 3
 
127.0.0.1:6379> sadd course3 js html #集合course3:[js,html]
 
(integer) 2
 
127.0.0.1:6379> sunion course1 course2 course3 #返回3个集合的并集,会自动去重
 
1) "php"
 
2) "js"
 
3) "java"
 
4) "html"
 
5) "c++"
 
6) "c"
 

sunionstore:将多个集合的并集放到一个新的集合中
代码语言:javascript
复制
sinterstore destination key [key ...]
 

这个命令类似于 sunion 命令,但它将结果保存到 destination 集合,而不是简单地返回结果集。 返回值: 结果集中的成员数量。

sdiff:取多个集合的差集
代码语言:javascript
复制
SDIFF key [key ...]
 

返回一个集合的全部成员,该集合是所有给定集合之间的差集。 不存在的 key 被视为空集。

示例

代码语言:javascript
复制
127.0.0.1:6379> flushdb
 
OK
 
127.0.0.1:6379> sadd course1 java php js #集合course1:[java,php,js]
 
(integer) 3
 
127.0.0.1:6379> sadd course2 c c++ js #集合course2:[c,c++,js]
 
(integer) 3
 
127.0.0.1:6379> sadd course3 js html #集合course3:[js,html]
 
(integer) 2
 
127.0.0.1:6379> sdiff course1 course2 course3 #返回course1中有的而course2和course3中都没有的元素
 
1) "java"
 
2) "php"
 

sdiffstore:将多个集合的差集放到一个新的集合中
代码语言:javascript
复制
sdiffstore destination key [key ...]
 

这个命令类似于 sdiff 命令,但它将结果保存到 destination 集合,而不是简单地返回结果集。 返回值: 结果集中的成员数量。

3.4.3、数据结构

又到了数据结构环节,Redis中的Set数据结构是字典,字典是用hash表实现的。Java中的HashSet的内部实现使用HashMap,实际上,HashSet 使用了 HashMap 的 key 来存储元素,而并没有使用 HashMap 的 value 来存储数据。HashSet 中,所有的元素都是作为 HashMap 的 key 来存储的,而 HashMap 的 value 则是一个固定的对象,通常称为“存在性标记”(presence bit)。这个存在性标记对象仅仅用于表示 key 存在于 HashSet 中,并不存储实际的元素数据。Redis的set结构也是一样的,它的内部也使用hash结构。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-11-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 可为编程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 常用命令
    • set:添加键值对
      • get:获取值
        • apend:追加值
          • strlen:获取值的长度
            • setnx:key不存在时,设置key的值
              • incr:原子递增1
                • decr:原子递减1
                  • incrby/decrby:递增或者递减指定的数字
                    • mset:同时设置多个key-value
                      • mget:获取多个key对应的值
                        • msetnx:当多个key都不存在时,则设置成功
                          • getrange:获取值的范围,类似java中的substring
                            • setrange:覆盖指定位置的值
                              • setex:设置键值&过期时间(秒)
                                • getset:以新换旧,设置新值同时返回旧值
                                • 数据结构
                                • 简介
                                • 常用命令
                                  • lpush/rpush:从左边或者右边插入一个或多个值
                                    • lrange:从列表左边获取指定范围内的值
                                      • lpop/rpop:从左边或者右边弹出多个元素
                                        • rpoplpush:从一个列表右边弹出一个元素放到另外一个列表中
                                          • lindex:获取指定索引位置的元素(从左到右)
                                            • llen:获得列表长度
                                              • linsert:在某个值的前或者后面插入一个值
                                                • lrem:删除指定数量的某个元素
                                                  • lset:替换指定位置的值
                                                  • 数据结构
                                                  • 2.4.1、简介
                                                  • 常用命令
                                                    • sadd:添加一个或多个元素
                                                      • smembers:取出所有元素
                                                        • sismember:判断集合中是否有某个值
                                                          • scard:返回集合中元素的个数
                                                            • srem:删除多个元素
                                                              • spop:随机弹出多个值
                                                                • srandmember:随机获取多个元素,不会从集合中删除
                                                                  • smove:将某个元素从一个集合移动到另一个集合
                                                                    • sinter:取多个集合的交集
                                                                      • sinterstore:将多个集合的交集放到一个新的集合中
                                                                        • sunion:取多个集合的并集,自动去重
                                                                          • sunionstore:将多个集合的并集放到一个新的集合中
                                                                            • sdiff:取多个集合的差集
                                                                              • sdiffstore:将多个集合的差集放到一个新的集合中
                                                                              • 3.4.3、数据结构
                                                                              相关产品与服务
                                                                              云数据库 Redis
                                                                              腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
                                                                              领券
                                                                              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档