前言:set类似于数学上面的集合概念,包含的元素无序,不能重复,能进行交、并、差操作。

一、内部原理

             set数据结构,也是随着元素数目的多少而变化。当set中添加的元素都是整数且元素数据较少时,set使用intset为底层的数据结构,否则,set使用dict作为底层的数据结构。

   intset是什么?

             从字面意思可以看出是由整数组成的集合。是一个整数组成的有序集合,便于进行二分查找,快速判断一个元素是否属于这个集合。内存分配上也是一整块连续的内存空间,而且根据数值的大小采取了不同的编码,对内存使用进行了优化。
             intset数据结构如下:

 typedef struct intset {
uint32_t encoding;/*数据编码,表示intset中每个数据元素用几个字节来存储。有三种:数据编码,表示intset中每个数据元素用几个字节来存储。
1.INTSET_ENC_INT16表示每个元素用2个字节存储,
2.INTSET_ENC_INT32表示每个元素用4个字节存储,
3.INTSET_ENC_INT64表示每个元素用8个字节存储。
因此,intset中存储的整数最多只能占用64bit*/
uint32_t length; /*元素个数。encoding和length组成了intset头部。*/
int8_t contents[]; /*是一个柔性数组,表示intset的header后面紧跟着数据元素。这个数组的总长度(即总字节数)等于encoding * length*/
} intset;

注:intset可能会随着数据的添加而改变它的数据编码,创建时intset使用占内存最小的INTSET_ENC_INT16作为编码,每增加一个元素,则根据大小决定是否对数据编码进行改变。

例子:

     如上图:
             1、新建一个intset只有一个header,总共8个字节,encoding=2,length=0。
             2.、添加6,15之后,因为数值较小,所以encoding不变,length=2。
             3、添加32768的时候,超过了两个字节(2个字节能表达的数据范围是-32768~32767),此时encoding升级到INTSET_ENC_INT32为4,即用4个字节表示一个元素。
             4、添加元素都是按照从小到大的顺序。
             5、intset是按little endian模式存储的。在上图intset添加完所有数据之后,32768=>0x00008000
             什么时间转为dict?
             1、大于512,默认设置:set-max-intset-entries 512
             2、超出最大范围-264~264-1
             3、元素里面包含非数字
             set底层用dict时,key是要添加的元素,value为NULL。
             区别:
             小集合(整数)用intset存储节省内存。dict带来的开销很大(包含元数据信息,两个hash表、链表指针等等)
             从时间复杂度上看,intset是o(log n),而dict可以认为是o(1)(因为zipmap),但是intset元素个数较少,影响不大

二、相关操作
             SADD key member [member ...]
             将一个或多个元素加入到集合key中,已存在被忽略。若不存在,则创建。
             SCARD key
             返回集合key的数目。
             SDIFF key [key ...]
             返回集合之间的差集
             SDIFFSTORE destination key [key ...]
             返回集合之间的差集,并将结果存储到目标集合。
             SINTER key [key ...]
             返回集合集合之间的交集
             SINTERSTORE destination key [key ...]
             返回集合之间的交集,并将结果存储到目标集合。
             SISMEMBER key member
             判断元素是否属于集合key的成员。
             SMOVE source destination member
             将元素从源集合移动到目标集合。
             SPOP key
             随机移除key集合的某一元素,并返回该元素。
             SRANDMEMBER key [count]
             随机返回一个key集合的元素,若提供count参数,则返回一个包含count个元素的数组。
             SREM key member [member ...]
             移除集合中的一个或多个元素。不存在则忽略。
             SUNION key [key ...]
             返回若干个集合的并集。
             SUNIONSTORE destination key [key ...]
             返回若干个集合的并集,并存储在目标集合

Redis数据类型之Set的更多相关文章

  1. 初识redis数据类型

    初识redis数据类型 1.String(字符串) string是redis最基本的类型,一个key对应一个value. string类型是二进制安全的.意思是redis的string可以包含任何数据 ...

  2. redis数据类型及使用场景

    Redis数据类型  String: Strings 数据结构是简单的key-value类型,value其实不仅是String,也可以是数字. 常用命令:  set,get,decr,incr,mge ...

  3. Redis数据类型介绍

    Redis 数据类型 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). String(字符串) st ...

  4. redis数据类型

    Redis 数据类型 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). String(字符串) st ...

  5. Redis-cluster集群【第一篇】:redis安装及redis数据类型

    Redis介绍: 一.介绍 redis 是一个开源的.使用C语言编写的.支持网络交互的.可以基于内存也可以持久化的Key-Value数据库. redis的源码非常简单,只要有时间看看谭浩强的C语言,在 ...

  6. Lua 数据类型和 Redis 数据类型之间转换

    当 Lua 通过 call() 或 pcall() 函数执行 Redis 命令的时候,命令的返回值会被转换成 Lua 数据结构. 同样地,当 Lua 脚本在 Redis 内置的解释器里运行时,Lua ...

  7. redis数据类型-散列类型

    Redis数据类型 散列类型 Redis是采用字典结构以键值对的形式存储数据的,而散列类型(hash)的键值也是一种字典结构,其存储了字段(field)和字段值的映射,但字段值只能是字符串,不支持其他 ...

  8. redis数据类型-字符串类型

    Redis数据类型 字符串类型 字符串类型是Redis中最基本的数据类型,它能存储任何形式的字符串,包括二进制数据.你可以用其存储用户的邮箱.JSON化的对象甚至是一张图片.一个字符串类型键允许存储的 ...

  9. redis笔记总结之redis数据类型及常用命令

    三.常用命令 3.1 字符串类型(string) 字符串类型是Redis中最基本的数据类型,一个字符串类型的键允许存储的数据的最大容量为512MB. 3.1.1 赋值与取值: SET key valu ...

  10. redis介绍、安装、redis持久化、redis数据类型

    1.redis介绍  2.安装管网:https://redis.io/下载:wget -c http://download.redis.io/releases/redis-4.0.11.tar.gz解 ...

随机推荐

  1. gsoap创建webservice服务简单教程

    版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] WebServicesoapgsoap 使用gsoap创建webservice服务 下载gsop 准备待导出的服务接口定义文件比 ...

  2. JS上了贼船

    本文纯属个人观点,没有引经据典,没有小心求证,just吐槽. 互联网的火热.移动web,带动了前端的飞速发展,js好像搭上了顺风车,身价水涨船高,如日中天. web前端是啥?html + css + ...

  3. Linux下Hadoop2.7.1集群环境的搭建(超详细版)

                                本文旨在提供最基本的,可以用于在生产环境进行Hadoop.HDFS分布式环境的搭建,对自己是个总结和整理,也能方便新人学习使用. 一.基础环境 ...

  4. Android打开其它应用程序

    PackageManager pm = getPackageManager(); Intent i = pm.getLaunchIntentForPackage(packageName); start ...

  5. jQuery选择器---层次选择器总结

    今天要分享的是jQuery层次选择器,层次选择器的分类如图: 接下来就开始了 要不先养养眼精神一下: 开始1.祖先选择器: 案例: <form> <label>Name:< ...

  6. Gulp和webpack的区别,是一种工具吗?

    疑问:gulp和webpack 什么关系,是一种东西吗?可以只用gulp,不用webpack吗 或者反过来? 它们的区别和概念 ------------------------------------ ...

  7. Azure Event Hub 技术研究系列2-发送事件到Event Hub

    上篇博文中,我们介绍了Azure Event Hub的一些基本概念和架构: Azure Event Hub 技术研究系列1-Event Hub入门篇 本篇文章中,我们继续深入研究,了解Azure Ev ...

  8. Linux下非root用户安装软件的一般流程:

    1. 获取源代码,一般是wget方式,ubuntu可以使用apt-get source来获取源代码. 2. 解压源代码,一般使用tar -zxvf xxx.tar.gz即可 3. 切换到解压后的目录, ...

  9. 字符串时间和NSDate相互转换的坑

    项目中服务器传回来的时间是这种格式的 Sep 5, 2016 6:59:05 PM 现在要将这段字符串转换成 2016-09-05 06:59 被坑的地方有2个点 服务器传回来的英文的Sep,调试的时 ...

  10. android 本地数据库sqlite的封装

    单机android   sqlite数据库的实现,这个数据库可与程序一起生成在安装包中 一.下载sqlite3.exe文件 二.运行 cmd 转到sqlite3.exe 所在目录  运行 sqlite ...