Set 数据类型与结构
Set 数据类型介绍
redis 集合(set)类型和list列表类型类似,都可以用来存储多个字符串元素的集合。但是和 list 不同的是 set 集合当中不允许重复的元素。而且 set 集合当中元素是没有顺序的,不存在元素下标。
redis 的 set 类型是使用哈希表构造的,因此复杂度是O(1),它支持集合内的增删改查,并且支持多个集合间的交集、并集、差集操作。可以利用这些集合操作,解决程序开发过程当中很多数据集合间的问题。
常用命令
sadd 命令
描述:将一个或者多个元素加入到集合当中,加入的元素已经存在在集合当中,则不会添加。假如 key 不存在,则直接添加一个 key,并加入元素。
命令使用:[sadd 命令] [key 名称] [value 值]...
127.0.0.1:6379>
127.0.0.1:6379> sadd dbset mysql oracle redis php
(integer) 4
127.0.0.1:6379>
smembers 命令
描述:将返回集合中的所有的成员。
命令使用:[smembers 命令] [key 名称]
127.0.0.1:6379> smembers dbset
1) "mysql"
2) "redis"
3) "oracle"
4) "php"
127.0.0.1:6379>
scard 命令
描述:返回集合中元素的个数。
命令使用:[scard 命令] [key 名称]
127.0.0.1:6379> scard dbset
(integer) 4
127.0.0.1:6379>
sismember 命令
描述:判断指定的值是否是集合的成员,假如不是集合的成员,或 key 不存在,返回 0 。
命令使用:[sismember 命令] [key 名称] [value 值]
127.0.0.1:6379> sismember dbset php
(integer) 1
127.0.0.1:6379> sismember dbset java
(integer) 0
127.0.0.1:6379>
srem 命令
描述:用于移除集合元素中一个或者多个元素,假如要移除的元素不存在,默认不处理。
命令使用:[srem 命令] [key 名称] [value 值]...
127.0.0.1:6379> srem dbset oracle
(integer) 1
127.0.0.1:6379> srem dbset mysql java
(integer) 1
127.0.0.1:6379> smembers dbset
1) "redis"
2) "php"
127.0.0.1:6379>
sinter 命令(交集)
描述:返回给定所有给定集合的交集。 不存在的集合 key 被视为空集。 当给定集合当中有一个空集时,结果也为空集。
命令使用:[sinter 命令] [key 名称] [key 名称]
127.0.0.1:6379> smembers dbset
1) "redis"
2) "php"
127.0.0.1:6379> sadd dbset1 mysql redis memcache php
(integer) 4
127.0.0.1:6379> sinter dbset dbset1
1) "redis"
2) "php"
127.0.0.1:6379>
sdiff 命令(差集)
描述:返回指定集合之间的差集;如下命令参考:用 dbset 去与 dbset1 比较,得到的差集是 (empty array) 因为 dbset 的 value 值在 dbset1 中都存在;而用 dbset1 去与 dbset 比较,得到的差集就是 dbset 没有的 value 值。
命令使用:[sdiff 命令] [key 名称] [key 名称]
127.0.0.1:6379> smembers dbset
1) "redis"
2) "php"
127.0.0.1:6379> smembers dbset1
1) "mysql"
2) "memcache"
3) "redis"
4) "php"
127.0.0.1:6379> sdiff dbset1 dbset
1) "mysql"
2) "memcache"
127.0.0.1:6379>
sunion 命令(并集)
描述:返回给定集合的并集;不存在的集合 key 被视为空集;理解为:所有的 value 值都显示出来,但重复的 value 值只显示一个。
命令使用:[sunion 命令] [key 名称] [key 名称]
127.0.0.1:6379> sunion dbset dbset1
1) "memcache"
2) "redis"
3) "php"
4) "mysql"
127.0.0.1:6379>
sscan 命令
描述:用于迭代集合中元素,取出匹配条件的元素。
命令使用:[sscan 命令] [key 名称] [游标] [匹配规则] [r* 代表 r 开头的所有 value 值]
127.0.0.1:6379> sscan dbset 0 match r*
1) "0"
2) 1) "redis"
127.0.0.1:6379>
Set 数据类型的应用场景
一、抽奖
sRandMember、sPop
这两个命令功能非常相似,都是从集合中返回一个元素值。不同的是,sRandMember不会从集合中删除返回的元素,但是sPop会删除。这两个命令可以分别实现不同的抽奖算法。 比如,集合中有100个元素,值从数字1到数字100.我们定义抽到的是数字1的话,即表示中奖。 使用sRandMember的话,不管之前抽过多少次,下次抽中的概率都是1%。而使用sPop的话,则每次抽中的概率都不一样。第一个人抽中概率是1%,当第一个人没抽中的话,第二个人抽中概率就是1/99,以此类推。
简单的抽奖代码示例:
<?php
// 定义redis 地址 端口号 密码
$config = [
"host" => "127.0.0.1",
"port" => 6379,
"password" => "root"
];
// 实例化redis对象
$Redis = new Redis();
// 连接Redis
$Redis->connect($config['host'],$config['port']);
// 连接密码
$Redis->auth($config['password']);
// 生成抽奖号码
luckDraw($Redis);
// 抽奖方法,不移除抽奖号码
print_r(sRandMember($Redis));
echo '<br>';
// 抽奖方法,移除抽奖号码
print_r(sPop($Redis));
/**
* luckDraw() 生成100个抽奖号码方法
* $Redis 连接 redis 的对象
* $luckdraw 集合的key名称
* $len 定义多少个抽奖号码
*/
function luckDraw($Redis,$luckdraw='luckdraw',$len=100){
for ($i=0; $i < $len; $i++) {
$Redis->sadd($luckdraw,$i+1);
}
}
/**
* sRandMember() 抽奖方法,不移除抽奖号码
* $Redis 连接 redis 的对象
* $luckdraw 集合的key名称,默认为:luckdraw
* $len 抽多少个号码,默认抽一个
*/
function sRandMember($Redis,$luckdraw='luckdraw',$num=1){
return $Redis->sRandMember($luckdraw,$num);
}
/**
* sPop() 抽奖方法,移除抽奖号码
* $Redis 连接 redis 的对象
* $luckdraw 集合的key名称,默认为:luckdraw
* $len 抽多少个号码,默认抽一个
*/
function sPop($Redis,$luckdraw='luckdraw',$num=1){
return $Redis->sPop($luckdraw,$num);
}