Redis Sets(官网翻译)
Sets是没有排序的字符串集合(<i>和数学定义一致,确定,无序,互异</i>),SADD命令添加一个新的元素到一个集合,它也可以做一些其他的针对sets的操作,比如测试元素是否已经存在元素,交集,并集,差集等操作。例如:
> sadd myset 1 2 3
(integer) 3
> smembers myset
1. 3
2. 1
3. 2
添加三个元素到myset集合中,无序地返回myset的所有元素,因为没有关于元素的任何约束。Redis有测试集合中元素的命令,测试一个被给的元素是否存在
> sismember myset 3
(integer) 1
> sismember myset 30
(integer) 0
“3”是集合中的成员,而“30”不是。
Sets在表达两个对象的关系时更有优势,例如我们很容易地使用Sets来实现tag,一个简单的模型就是我们有一个Sets,里面有我们想要标记的每一个对象,这个Set包含和对象关联的tags的ID。一个插图标记一个文章,假如文章的ID是1000,被1,2,5,77标记,一个集合能使用新闻项关联他们的tagID:
> sadd news:1000:tags 1 2 5 77
(integer) 4
然而有时我也想有反比关系:所有新闻的列表标记一个tag:
> sadd tag:1:news 1000
(integer) 1
> sadd tag:2:news 1000
(integer) 1
> sadd tag:5:news 1000
(integer) 1
> sadd tag:77:news 1000
(integer) 1
获得被给对象的所有Tags
> smembers news:1000:tags
1. 5
2. 1
3. 77
4. 2
注:在示例中,我们假定你有其他的数据结构,例如 Redis Hash,它tagIDs映射到tag names
有一些其他的不一般的操作使用Redis命令可以很容易的实现,例如我们想要所有对象中的一些带有tag1,2,10,27的。我们可以用SINTER(交集),它执行多个不同集合相交,我们可以用:
> sinter tag:1:news tag:2:news tag:10:news tag:27:news
... results here ...
除了交集,你还可以执行并,差和提取一个随机的元素。提取一个元素的命令是SPOP,它很方便去模型某些问题,例如一个网页的扑克游戏,你想用一个集合代表你的deck,想象我们用花色(Clubs),方框(Diamonds),红桃(Heart),黑桃(Spades)的第一个字符:
> sadd deck C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 CJ CQ CK
D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 DJ DQ DK H1 H2 H3
H4 H5 H6 H7 H8 H9 H10 HJ HQ HK S1 S2 S3 S4 S5 S6
S7 S8 S9 S10 SJ SQ SK
(integer) 52
现在我们要为每一个玩家发5张牌,SPOP命令移除一个随机的元素,并把这个元素返回给客户端,因此它是很适合在这种情况下。
然而,我们直接调用它针对我们的deck,那么在下一次时,我们就必须再一次填充我们的cards,这不是很理想。所以开始我们应该做一个copy。
使用SUNIONSTORE命令,它通常合并两个集合,并把结果存到另一个集合。因为单个集合可以合并它自身,我可以:
> sunionstore game:1:deck deck
(integer) 52
在集合理论的上下文中,我们通常称一个集合的cardinality是集合元素的数量,因此Redis 使用SCARD命令来获得一个集合的数量
> scard game:1:deck
(integer) 47
当你仅仅需要获得某个随机的元素并且不打算移除获得的元素,可以使用SRANDMEMBER命令。它还具有返回重复和不重复元素的特性。