# 2.5 针对集合的命令

set:和list相同,也是在同一个key下存储多个元素;不同之处在于,set中存储的元素**不能重复**,且set是**无序**的

## 2.5.1 读写集合的命令

* `SADD`
  * 语法:`SADD key member [member ...]`
  * 功能:向key指定的集合中添加1个或多个元素
* `SMEMBERS`
  * 语法:`SMEMBERS key`
  * 功能:读取key对应集合里的所有数据

例:

向集合中添加元素:

```
127.0.0.1:6379> SADD teamName 'HR' 'Account' 'DataTeam' 'HR'
(integer) 3
```

注意此时添加的元素是有重复的.因此最终添加结果显示有3个元素被添加到了集合中

查看集合中的元素:

```
127.0.0.1:6379> SMEMBERS teamName
1) "Account"
2) "HR"
3) "DataTeam"
```

可以看到,读取时的顺序和写入时的顺序是不同的.

## 2.5.2 列表和集合类数据的使用场景

* 列表在写入时是有序的;集合是无序的
* 列表用于按一定规范存储同一类数据

例如:用`Name`,`Salary`,`TeamName`的规范存储同一类员工的数据:

```
127.0.0.1:6379> RPUSH 001 "Mike" 12000 "dataTeam"
(integer) 3
127.0.0.1:6379> RPUSH 002 "David" 13000 "businessTeam"
(integer) 3
127.0.0.1:6379> RPUSH 003 "Peter" 14000 "userTeam"
(integer) 3
```

在本例中,这3个列表中的第1个元素均为员工姓名;第2个元素均为员工工资;第3个元素均为员工部门

* 集合用于存储并列数据

例如:存储公司名称

```
127.0.0.1:6379> SADD companyName "Apple" "Google" "Facebook"
(integer) 3
```

```
127.0.0.1:6379> SMEMBERS companyName
1) "Apple"
2) "Facebook"
3) "Google"
```

在本例中,Apple、Facebook、Google均为公司名称,是并列关系

## 2.5.3 用`SISMEMBER`命令判断元素是否存在

集合是无序的,因此"读取指定索引的元素"的命令是没有意义的,因为存入集合的次序和输出次序不一定相同.

* `SISMEMBER`
  * 语法:`SISMEMBER key member`
  * 功能:判断某个元素是否在集合中.元素存在于集合中则返回1,否则返回0

例:

向set中写入:

```
127.0.0.1:6379> DEL teamName
(integer) 1
127.0.0.1:6379> SADD teamName 'HR' 'Account' 'DataTeam'
(integer) 3
```

判断给定的元素值在set中是否存在:

```
127.0.0.1:6379> SISMEMBER teamName HR
(integer) 1
127.0.0.1:6379> SISMEMBER teamName Dev
(integer) 0
```

## 2.5.4 获取集合的交集、并集和差集

* `SINTER`
  * 语法:`SINTER key [key ...]`
  * 功能:获取多个key对应的set的交集
* `SUNION`
  * 语法:`SUNION key [key ...]`
  * 功能:获取多个key对应的set的并集
* `SDIFF`
  * 语法:`SDIFF key [key ...]`
  * 功能:获取多个key对应的set的差集

例:

创建2个set:

```
127.0.0.1:6379> SADD Mike Math English Computer
(integer) 3
127.0.0.1:6379> SADD Tom Computer Math Piano
(integer) 3
```

取2个集合的交集:

```
127.0.0.1:6379> SINTER Mike Tom
1) "Computer"
2) "Math"
```

取2个集合的并集:

```
127.0.0.1:6379> SUNION Mike Tom
1) "Math"
2) "Computer"
3) "English"
4) "Piano"
```

取2个集合的差集:

```
127.0.0.1:6379> SDIFF Mike Tom
1) "English"
127.0.0.1:6379> SDIFF Tom Mike
1) "Piano"
```

注意:差集的含义是存在于集合A但不存在于集合B中的元素.因此`SDIFF Mike Tom`和`SDIFF Tom Mike`的返回值是不同的

## 2.5.5 用`SREM`命令删除集合数据

* `SREM`
  * 语法:`SREM key member [member ...]`
  * 功能:删除key对应的集合中的数据.该命令的返回值为删除的元素个数

例:

创建一个set:

```
127.0.0.1:6379> SADD number 1 2 4 8 16
(integer) 5
```

从set中删除值为1、4、5的元素

```
127.0.0.1:6379> SREM number 1 4 5
(integer) 2
```

可以看到,返回值为2.因为set中没有值为5的元素

```
127.0.0.1:6379> SMEMBERS number
1) "2"
2) "8"
3) "16"
```

从一个不存在的set中删除元素:

```
127.0.0.1:6379> SREM notExist 1
(integer) 0
```

可以看到,若从一个不存在的set中删除元素,返回值为0

对非set类型的对象调用`SREM`命令:

```
127.0.0.1:6379> LPUSH myList 1
(integer) 1
127.0.0.1:6379> SREM myList 1
(error) WRONGTYPE Operation against a key holding the wrong kind of value
```

可以看到,对非set类型的对象调用`SREM`命令则报错
