Redis数据类型之Set

      前言: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 ...]
           返回若干个集合的并集,并存储在目标集合

时间: 2024-10-14 04:31:09

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

redis数据类型

Redis 数据类型 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). String(字符串) string是redis最基本的类型,一个key对应一个value. string类型是二进制安全的.意思是redis的string可以包含任何数据.比如jpg图片或者序列化的对象 . string类型是Redis最基本的数据类型,一个键最大能存储512MB. 实例: 在以上实例中我们使用了 Redis

Redis数据类型之字典

Redis数据类型之字典 标签(空格分隔): redis redis的字典 字典又称符号表(symbol table),关联数组(associative array),或者映射(map).是用于保存键值对的一种抽象数据结构. 字典的key是唯一的,对键值对的操作基本都是基于key来操作的.redis中的数据库底层是使用字典来实现的,对于数据库的增删改查都是基于字典来实现的.redis的哈希键也是基于字典来实现的. 具体的实现是在src下的dict.h和dict.c文件 字典的数据结构 哈希表结点

Redis数据类型之链表

Redis数据类型之链表 链表的实现 redis的列表的底层实现就是一个双链表,源码在src下的adlist.h和adlist.c 链表的结点数据结构 /* * 双端链表节点 */ typedef struct listNode { // 前置节点 struct listNode *prev; // 后置节点 struct listNode *next; // 节点的值 void *value; } listNode; 链表数据结构 /* * 双端链表结构 */ typedef struct l

Redis数据类型简介

Redis 数据类型 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). String(字符串) string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value. string类型是二进制安全的.意思是redis的string可以包含任何数据.比如jpg图片或者序列化的对象 . string类型是Redis最基本的数据类型,一个键最大能存储512M

redis数据类型及使用场景

Redis数据类型  String: Strings 数据结构是简单的key-value类型,value其实不仅是String,也可以是数字. 常用命令:  set,get,decr,incr,mget 等. 应用场景:String是最常用的一种数据类型,普通的key/ value 存储都可以归为此类.即可以完全实现目前 Memcached 的功能,并且效率更高.还可以享受Redis的定时持久化,操作日志及 Replication等功能.除了提供与 Memcached 一样的get.set.in

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

当 Lua 通过 call() 或 pcall() 函数执行 Redis 命令的时候,命令的返回值会被转换成 Lua 数据结构. 同样地,当 Lua 脚本在 Redis 内置的解释器里运行时,Lua 脚本的返回值也会被转换成 Redis 协议(protocol),然后由 EVAL 将值返回给客户端. 数据类型之间的转换遵循这样一个设计原则:如果将一个 Redis 值转换成 Lua 值,之后再将转换所得的 Lua 值转换回 Redis 值,那么这个转换所得的 Redis 值应该和最初时的 Redi

Redis 学习笔记(二) Redis 数据类型

Redis 数据类型 Redis 支持五种数据类型:string(字符串).list(列表).hash(哈希).set(集合)和 zset(有序集合),接下来我们讲解分别讲解一下这五种类型的的使用. String(字符串) string 类型是 redis 最基本的类型,很多人说如果去除本地持久化,只使用 string 的话,那 redis 就是一个 memcached.string 类型,一个 key 对应一个 value,一个 value 最大能存储512MB的数据.string 类型是二进

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

Redis介绍: 一.介绍 redis 是一个开源的.使用C语言编写的.支持网络交互的.可以基于内存也可以持久化的Key-Value数据库. redis的源码非常简单,只要有时间看看谭浩强的C语言,在去看redis的源码能看懂50-60%. redis目前最大的集群应该是新浪的应该. redis目前是vmvaer来支持的,很多的开源软件都需要某些组织来支持的.如果一个开源软件没有金钱来支持的话很难走的持久 二.Redis和Memcache对比 持久化:以电商举例,session用memcache

python在运维项目中用到的redis数据类型

先感叹下,学东西一定要活学活用!   我用redis也有几年的历史了,今个才想到把集合可以当python list用.  最近做了几个项目都掺杂了redis, 遇到了一些个问题和开发中提高性能的方法,这都分享出来,共同学习. 下面先简单讲讲Redis集合的数据类型. sadd,创建一个集合,并添加数据. [[email protected] ~]# redis-cli redis 127.0.0.1:6379>  redis 127.0.0.1:6379>  redis 127.0.0.1:6

Redis数据类型之字符串

Redis数据类型之字符串 redis的字符串 redis的字符串不是C语言原生的字符串,而是自己构建的称为简单动态字符串(simple dynamic string),简称 SDS,和C语言原生的字符串相似,使用'\0'作为结尾. 除了打印日志之外,我们操作字符串基本是在使用SDS SDS的在redis的主要功能 1. 保存数据库的字符串值 2. 用作缓冲区buffer SDS在redis的定义 在源码包下面的src目录下的sds.h 和sds.c typedef char *sds; /**