Redis五大基础数据类型详解

Redis五种基本数据类型 五种基本数据类型 redis无论什么数据类型,在数据库中都是以key-value形式保存,并且所有的key(键)都是字符串,所以讨论基础数据结构都是讨论的value值的数据类型 主要包括常见的5种数据类型,分别是:String、List、Set、Zset、Hash。 结构类型 结构存储的值 结构的读写能力 String字符串 可以是字符串、整数或浮点数 对整个字符串或字符串的一部分进行操作;对整数或浮点数进行自增或自减操作; List列表 一个链表,链表上的每个节点都包含一个字符串 阅读详情

Redis五大基础数据类型

redis 基础数据类型有5种: string、set、zset、list和hash。

String数据类型

string类型是redis中最常见的数据类型,其内部存在三种编码:EMBSTR、RAW和INT编码。

RAW编码

  • 基本编码方式是RAW,基于简单动态字符串(SDS)实现,存储上限为512mb。
    在这里插入图片描述
    下方是sds其中一种数据结构。详情可去看笔者的另一篇文章:Redis数据结构系列一:动态字符串SDS
    struct __attribute__ ((__packed__)) sdshdr8 {
        uint8_t len; /* used:已保存的字符串字节数,不包括结束符。表示字节数最大长度8个bit,也就是2^8 -1 */
        uint8_t alloc; /* buf申请的总字节数,不包括结束符*/
        unsigned char flags; /* 不同SDS 头类型(sdshdr5|sdshdr8|sdshdr16|sdshdr32|sdshdr64), 用来控制SDS 头的大小*/
        char buf[];
    };
    
    在上图中的数据,总字节数len=50,可用flags=sdshdr8编码格式保存。

EMBSTR编码

  • 如果存储的SDS长度小于44字节,则会采用EMBSTR编码,此时RedisObject header与SDS是一段连续空间。申请内存时只需要调用一次内存分配函数,效率更高。

    在这里插入图片描述

    为什么RedisObject header和sds会变成连续空间?

    1. 由于上图中的数据,总字节数len=44,可用flags=sdshdr8编码格式保存。

    2. sds 占用的总字节数totalSdsBytes = len:1 + alloc:1 + flags:1 + 44 + 1(结束标识) = 48byte;

    3. RedisObject header固定为16byte, RedisObject header + totalSdsBytes = 16 + 48 = 64byte,正好是8k,即一个Redis内存页,没有内存碎片。同时只需申请一次内存,减少用户态和内核态的交互,提交效率。若总字节数len>44byte,会导致整个sds>48byte,就会转成RAW编码。

INT编码

  • 如果string类型保存的是LONG_MAX(2^32)范围内的数字,即采用INT编码。

  • 若采用的是INT 编码,则使用*ptr 指针存储二进制数据(*ptr占用8byte,64bit,足以存储long_max的2^32大小的数据),去除sds结构,更加节省内存空间。

    其数据结构如下:
    在这里插入图片描述
    redis实践如下:
    在这里插入图片描述

String总结:

  • 使用string类型存储数据时,尽量不超过44byte,即内部采用embstr编码;

  • 使用string类型存储数据时,尽量将数据转为数字,即内部采用int编码;

List数据类型

List类型可以从首、尾操作列表中的元素

有以下类型满足List数据类型的特征:

  • LinkedList:普通链表,可以从双端访问,但内存占用较高、内存碎片较多,不是连续内存

  • ZipList:压缩链表,可以从双端访问,连续内存,内存占用低,但是存储上限低

  • QuickList:等于LinkedList+QuickList,可以从双端访问,内存占用低,包含多个ZipList,存储上限高

所以:Redis 3.2版本之后,都采用QuickList作为List数据类型的底层结构。 结构如下:

在这里插入图片描述

List源码分析

由lpushxCommand命令,进入查看发现所有的操作命令底层都是调用的pushGenericCommand

void lpushxCommand(client *c) {
    pushGenericCommand(c,LIST_HEAD,1);
}

进入pushGenericCommand命令:

/**
 * client *c: 客户端连接redis服务器时,会将客户端的信息及输入的命令都封装成client对象
 * where:插入的位置,head|tail
 * xx:当xx=true时,代表key存在时,才push;当xx=false时,不存在则直接return。 默认为false
*/
void pushGenericCommand(client *c, int where, int xx) {
    int j;
    /**
     * lpush key1 v1 v2 v3; 
     * argv[0] = lpush
     * argv[1] = key1
     * argv[2] = v1
     * ...
    */
   // 1.判断输入的参数个数是否超出上限
    for (j = 2; j < c->argc; j++) {
        // 因为redis所有的键和值都会封装成RedisObject,其真实数据实际上是*ptr指向的地址,所以执行sdslen(c->argv[j]->ptr)获取数据长度
        if (sdslen(c->argv[j]->ptr) > LIST_MAX_ITEM_SIZE) {
            addReplyError(c, "Element too large");
            return;
        }
    }

    // 2.根据client中的db和key查询是否存在的RedisObject(robj是RedisObject的缩写)
    robj *lobj = lookupKeyWrite(c->db, c->argv[1]);
    // 3.判断lobj类型是否为LIST类型,若不是则直接返回
    if (checkType(c,lobj,OBJ_LIST)) return;
    if (!lobj) {
        // 4.1如果lobj不存在,且xx=true,代表key不存在则直接return,不执行push
        if (xx) {
            addReply(c, shared.czero);
            return;
        }
        // 4.2如果lobj不存在,且xx=false,代表需要创建新的List RedisObject
        // 在此处可见实际上创建的是 Quicklist
        lobj = createQuicklistObject();
        // 4.2.1 设置lobj中quicklist的属性
        // list_max_ziplist_size: 限制ziplist的最大长度
        // list_compress_depth: qucikList 头尾节点不压缩数量
        quicklistSetOptions(lobj->ptr, server.list_max_ziplist_size,
                            server.list_compress_depth);
        // 4.3 将创建的robj赋值给key
        dbAdd(c->db,c->argv[1],lobj);
    }

    for (j = 2; j < c->argc; j++) {
        // 5.依次将数据保存进list orbj
        listTypePush(lobj,c->argv[j],where);
        server.dirty++;
    }
    ... // 略
}

上述代码都已添加注释,可看出List数据类型最终创建的还是quicklist结构。

Set数据类型

set数据类型的特点:

  1. 不保证数据有序

  2. 保证元素唯一(可以判断元素是否存在。添加SADD、判断是否存在SISMEMBER和差集SINTER命令中**都需要判断元素是否存在 **)

  3. 便于求交集、并集和差集

由于底层数据结构中快速查找和唯一仅有skipList和dict数据结构,而skipList中是由数值score来做排序,而set中不一定全是数值,所以只能选用dict数据结构。

Set编码

  • 为了查询效率和唯一性,set采用HT编码(Dict)。dict的key用来存储元素,value统一为null。

  • 若set保存的全是数值类型,且不超过set-max-intset-entries时,Set会采用IntSet编码,节省内存。

robj *setTypeCreate(sds value) {
    // 若存储的数据都是整数,创建Inset编码的robj
    if (isSdsRepresentableAsLongLong(value,NULL) == C_OK)
        return createIntsetObject();
    // 若存储的数据不全是整数,创建hash-table(dict类型)编码的robj
    return createSetObject();
}
robj *createIntsetObject(void) {
    intset *is = intsetNew();
    robj *o = createObject(OBJ_SET,is);
    o->encoding = OBJ_ENCODING_INTSET;
    return o;
}
// 默认创建OBJ_ENCODING_HT编码的set,即dict类型
robj *createSetObject(void) {
    dict *d = dictCreate(&setDictType,NULL);
    robj *o = createObject(OBJ_SET,d);
    o->encoding = OBJ_ENCODING_HT;
    return o;
}
/** 向set添加元素,若元素存在直接返回;若不存在则在相应编码的结构中添加*/
int setTypeAdd(robj *subject, sds value) {
    long long llval;
    // 若是dict类型
    if (subject->encoding == OBJ_ENCODING_HT) {
        dict *ht = subject->ptr;
        // 直接添加元素到新的dictEntry中
        dictEntry *de = dictAddRaw(ht,value,NULL);
        if (de) {
            dictSetKey(ht,de,sdsdup(value));
            dictSetVal(ht,de,NULL);
            return 1;
        }
    } else if (subject->encoding == OBJ_ENCODING_INTSET) {
        // 若是intset类型
        // 先判断value是否是整数
        if (isSdsRepresentableAsLongLong(value,&llval) == C_OK) {
            uint8_t success = 0;
            // 若是整数,使用intsetAdd添加到set
            subject->ptr = intsetAdd(subject->ptr,llval,&success);
            if (success) {
                // 若添加成功,最后还需要判断是否大于set_max_intset_entries
                size_t max_entries = server.set_max_intset_entries;
                if (max_entries >= 1<<30) max_entries = 1<<30;
                // 若intset的entry数量>set_max_intset_entries,则转换编码为HT
                if (intsetLen(subject->ptr) > max_entries)
                    setTypeConvert(subject,OBJ_ENCODING_HT);
                return 1;
            }
        } else {
            // 若不是整数,则转换编码为HT
            setTypeConvert(subject,OBJ_ENCODING_HT);
            // 使用dictAdd添加元素到set
            serverAssert(dictAdd(subject->ptr,sdsdup(value),NULL) == DICT_OK);
            return 1;
        }
    } else {
        serverPanic("Unknown set encoding");
    }
    return 0;
}
  • Set中保存的**{5, 10, 20}**,结构如下:
    在这里插入图片描述

  • Set中保存的**{5, 10, 20, m1}**,结构如下:

在这里插入图片描述

ZSet数据类型

ZSet数据类型的特点:zset也就是sortedSet,其中每一个元素都需要指定一个member和score:

  • 可以根据score排序

  • member必须唯一

  • 可以根据member查询分数

ZSet底层数据结构必须满足:键值存储、键必须唯一、可排序和能根据key找到value这几个需求。(此时·key=member,score=value·)

  • SkipList:可排序,可同时存储score和element值(member)。(1.不能做到key唯一;2.不能做到通过key查找value)

  • HT(Dict):可以存储键值,可以根据key找到value。(1.不能通过score快速定位range;2.不能排序)

由于无法使用一种数据结构完成zset类型的封装,所以redis采用dict +skiplist 类型一起作为zset的底层数据结构。
其结构代码如下:

typedef struct zset {
    dict *dict;
    zskiplist *zsl;
} zset;
robj *createZsetObject(void) {
    zset *zs = zmalloc(sizeof(*zs));// 初始化zset内存
    robj *o;
    zs->dict = dictCreate(&zsetDictType,NULL);//创建dict
    zs->zsl = zslCreate();// 创建skiplist
    o = createObject(OBJ_ZSET,zs);// 创建zset的robj
    o->encoding = OBJ_ENCODING_SKIPLIST;// 可看出,zset虽然时候dict+skiplist组成,但使用的编码是skipList类型
    return o;
}

上述的结构图如下:
在这里插入图片描述

当元素数量不多时,HT和SkipList的优势不明显,且更耗内存。因此Redis还会采用ZIpList结构作为zset的第二种底层结构。不过需要同时满足以下两个条件:

  • 元素数量<zset_max_ziplist_entries,默认值128

  • 每个元素都<zset_max_ziplist_value字节,默认值64

/** t_zset.c zaddGenericCommand */
// zadd添加元素时,现根据key查找zset对应的robj,没有则创建
zobj = lookupKeyWrite(c->db,key);
if (checkType(c,zobj,OBJ_ZSET)) goto cleanup;
if (zobj == NULL) {
    if (xx) goto reply_to_client; /* No key + XX option: nothing to do. */
    // 若不存在,且zset_max_ziplist_entries==0,则代表使用HT+SkipList
    // 若不存在,且zset_max_ziplist_value(字节大小)<value大小,则代表使用HT+SkipList
    if (server.zset_max_ziplist_entries == 0 ||
        server.zset_max_ziplist_value < sdslen(c->argv[scoreidx+1]->ptr)){
        zobj = createZsetObject();
    } else {
        zobj = createZsetZiplistObject();
    }
    dbAdd(c->db,key,zobj);
}

ZipList本身没有排序功能,而且没有键值对的概念,因此需要有zset通过逻辑编码实现相应功能。

  • ZipList是连续内存,因此score和element是紧挨在一起的两个entry,element在前,score在后

  • Score越小越接近队首,score越大越接近队尾,按照score值升序排列

内存结构图如下:
在这里插入图片描述

Hash数据类型

Hash数据类型的特点:——和zset数据类型相似

  1. 都是兼职存储

  2. 都需求根据键查询值

  3. 都需求键唯一

  4. 不同点:hash无序;zset要求有序

综上:Redis将使用类似Zset的底层结构作为hash的结构。Zset使用HT+SkipList / ZipList 底层数据结构,hash无需排序,所以无需使用SkipList,则最终为HT / ZipList底层数据结构。

  • Hash底层默认使用的ZipList编码,用以节省内存。ZipList中相邻的两个entry分别存储key和value

  • 当数据量较大时,hash结构会转为HT编码,也就是Dict。触发条件两个如下:

    • ZipList中元素超过hash-max-ziplist-entries(默认512)

    • ZipList中任一entry大小超过hash-max-ziplist-value(默认64byte)

ZipList编码 内存结构如下:

在这里插入图片描述

HT编码 内存结构如下:
在这里插入图片描述
通过hsetCommand # hashTypeLookupWriteOrCreate逻辑中,可看出hash 默认创建的是ZIPLIST编码。

void hsetCommand(client *c) {
    int i, created = 0;
    robj *o;
    /**
     * hmset key filed value ...
     * hmset user name jack age 10
     * argv[0] = hset
     * argv[1] = user
     * argv[2] = name
     * argv[3] = jack
     * ...
    */
    // 通过key查找对应的hash robj,若不存在则创建
    if ((o = hashTypeLookupWriteOrCreate(c,c->argv[1])) == NULL) return;
    // 判断是否要转换类型,由ziplist -> ht
    hashTypeTryConversion(o,c->argv,2,c->argc-1);

    for (i = 2; i < c->argc; i += 2)
        //将file 和value 依次添加到dict
        created += !hashTypeSet(o,c->argv[i]->ptr,c->argv[i+1]->ptr,HASH_SET_COPY);
}
robj *hashTypeLookupWriteOrCreate(client *c, robj *key) {
    robj *o = lookupKeyWrite(c->db,key);
    if (checkType(c,o,OBJ_HASH)) return NULL;
    if (o == NULL) {
    	// 若robj为null,则创建
        o = createHashObject();
        dbAdd(c->db,key,o);
    }
    return o;
}
//默认创建的是ZIPLIST编码,那么插入逻辑中将会涉及到由ZIPLIST编码-> 转为 HT编码的过程
robj *createHashObject(void) {
    unsigned char *zl = ziplistNew();
    robj *o = createObject(OBJ_HASH, zl);
    o->encoding = OBJ_ENCODING_ZIPLIST;
    return o;
}

再看尝试转化HT编码的逻辑,通过下述代码可明显看出只判断的ZIPLIST的value大小,对于长度的判断并没有体现。

void hashTypeTryConversion(robj *o, robj **argv, int start, int end) {
    int i; size_t sum = 0;
    // 由于默认是ZIPLIST编码,若目前不是ZIPLIST编码,则代表已经是HT编码
    if (o->encoding != OBJ_ENCODING_ZIPLIST) return;
    for (i = start; i <= end; i++) {
        // 判断是否是key和value是不是sds,redis中数字和字符串都为sds
        if (!sdsEncodedObject(argv[i])) continue;
        size_t len = sdslen(argv[i]->ptr);
        // 判断key和value的字节长度是否>hash_max_ziplist_value(默认64byte)
        // 若大于,则需要转为HT编码
        if (len > server.hash_max_ziplist_value) {
            hashTypeConvert(o, OBJ_ENCODING_HT);
            return;
        }
        sum += len;
    }
    // 判断所有的key和value的总字节数,总字节数>1G时,则需要转为HT编码
    // Don't let ziplists grow over 1GB in any case
    if (!ziplistSafeToAdd(o->ptr, sum))  hashTypeConvert(o, OBJ_ENCODING_HT);
}

紧着看hashTypeSet方法,该方法是具体插入hash数据的方法。

int hashTypeSet(robj *o, sds field, sds value, int flags) {
    int update = 0;// 0:新增;1:更新
    // 判断是否是ZIPLIST编码
    if (o->encoding == OBJ_ENCODING_ZIPLIST) {
        unsigned char *zl, *fptr, *vptr;
        zl = o->ptr;
        // 若是ZIPLIST编码,则查找头节点
        fptr = ziplistIndex(zl, ZIPLIST_HEAD);
        // 若头节点为空,则直接新增
        if (fptr != NULL) {
            //若头节点不为空,通过field查找entry位置
            fptr = ziplistFind(zl, fptr, (unsigned char*)field, sdslen(field), 1);
            if (fptr != NULL) { // 若查询到对应的entry
                // 计算得出filed对应value的位置
                vptr = ziplistNext(zl, fptr);
                serverAssert(vptr != NULL);
                // 将update=1,代表更新
                update = 1;
                // 更新filed对应的value
                zl = ziplistReplace(zl, vptr, (unsigned char*)value,
                        sdslen(value));
            }
        }

        // update=0,代表新增,依次新增filed 和 value
        if (!update) {
            /* Push new field/value pair onto the tail of the ziplist */
            zl = ziplistPush(zl, (unsigned char*)field, sdslen(field),
                    ZIPLIST_TAIL);
            zl = ziplistPush(zl, (unsigned char*)value, sdslen(value),
                    ZIPLIST_TAIL);
        }
        o->ptr = zl;

        // 判断ziplist中entry的长度是否>hash_max_ziplist_entries(默认512)
        // 若大于,则需要转为HT编码
        if (hashTypeLength(o) > server.hash_max_ziplist_entries)
            hashTypeConvert(o, OBJ_ENCODING_HT);
    } else if (o->encoding == OBJ_ENCODING_HT) {
    	// ht编码直接插入或覆盖
        ...
    } else {
        serverPanic("Unknown hash encoding");
    }
    ...
}

最终发现,需转换编码逻辑中对长度的判断再具体插入的时候处理。仔细一想,就应该放在这个位置,因为hash是保证filed唯一,所以hset数据时可能时插入或覆盖,覆盖的话就没有长度的增加了。

若有缺失或不当描述部分,后续修改补充…

Redis常用的五大数据类型 redis与传统sql数据库的取 Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储,它还支持数据的备份,即master-slave模式的数据备份,同样Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。 Redis支持的五大数据类型包括String(字符串 用法: 键 值),Hash(哈希 类似Java中的 map 用法: 键 键值对),List(列表 用法:键 集合 不可以重复),Set(集合 用法:... 阅读详情

相关推荐

redis的五种数据类型

(1)Redis(Remote Dictionary Server 远程字段服务)是一个开源的使用ANSI C语言编写、支持网络、科技与内存亦可持久化的日志型、key-value数据库,并提供多种语言的API。(2)Redis是一个key-value存储系统,它支持存储的value类型相对更多,包括string、list、set、zset(sorted set --有序集合)和hash。这些数据结构都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。

学Java,找哪吒 6万+

Redis 的五种数据类型及其底层原理

Redis是 key-value结构的数据库。 Redis常用的五种数据类型分别是:String、List、Set、Hash、Zset。 一、Redis五种类型的常用命令 1.1 String String是 redis 最基本的数据类型。一个 key 对应一个value。redis的String可以表示任何数据,比如 jpg图像或者序列化的对象,String的最大值能存储512MB。 常用命令: get、set、incr、decr、mget set:往redis里输入key-value,如:

ZJE 3万+

SAP CO模块实战:成本中心会计分割结构配置全流程(OKES事务码详解)

本文详细解析了SAP CO模块中成本中心会计分割结构的配置全流程,重点讲解了OKES事务码的实战操作。内容涵盖分割结构的概念理解、配置前的次级成本要素与作业类型主数据准备,并通过步骤拆解演示了如何定义分割结构、规则与版本,以及如何将配置关联到成本中心并执行分割。最后提供了常见问题排查与优化建议,旨在帮助顾问及财务人员掌握成本精确分摊的关键配置,确保期末成本核算的准确性。

embedding5hiker的博客 805

Redis常用的五种数据类型

Redis常用的五种数据类型 String (Key-Value),普通的key/value存储都可以归为此类 Hash(Key-Hash(field,value)) Key仍然是用户ID, value是一个Map 特别适合存储对象 String存对象会带来序列化和反序列化 List key理解为链表名字 作为栈,又可以作为队列 Set key理解为Set名字 string类型的无序集合 zset key理解为zSet名字 一列存 value,一列存顺序

u013905744的专栏 3万+

PCIe控制器深度解析-RK3588 PCIe子系统核心模块探秘

本文深度解析了RK3588芯片中PCIe子系统的核心架构与功能模块。文章将PCIe控制器比作智能交通枢纽,详细阐述了RADM、XADM、CDM、eDMA等核心模块的工作原理,包括数据流管理、地址转换、DMA加速及电源管理。旨在帮助开发者和硬件工程师深入理解RK3588 PCIe控制器的内部机制,为驱动开发、性能优化和故障排查提供清晰的思路与实用指导。

weixin_29246195的博客 189

手把手教你用CsvView分析大疆无人机飞行日志(附实战CTF题解)

本文详细介绍了如何使用CsvView工具分析大疆无人机飞行日志,包括环境搭建、日志提取、核心功能解析及CTF实战技巧。通过实战案例,帮助读者掌握无人机取证的关键技术,提升日志分析能力,特别适合网络安全竞赛和实际取证场景。

weixin_42652674的博客 458

Redis入门——Key、五大数据类型图文详解

文章目录1、Redis简介2、Redis常见命令3、Redis_Key关键字4、五大数据类型简介4.1、String(字符串)4.2、List(列表)4.3、Set4.3、Hash4.4、ZSet 1、Redis简介       Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。 Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,

Code皮皮虾的博客 4591

腾讯文档API逆向分析:不用Selenium也能批量导出的黑科技

本文揭秘了如何通过Python逆向分析腾讯文档的隐藏API,实现无需Selenium即可批量导出在线表格的高效方法。详细解析了API调用流程、Cookie维护及异常处理技巧,相比传统方案性能提升显著,适用于大量文档导出的自动化场景。

h9j8k7l6m5n的博客 1202

Redis五大数据类型详解

root@localhost ~]# ll /usr/bin/redis-* -rwxr-xr-x1 root root 656280 Oct 202021 redis-benchmark #性能测试程 序#AOF文件检查程序#RDB文件检查程序#客户端程序#哨兵程序,软连接到服务器端主程序#服务端主程序。

weixin_63581562的博客 299

电池管理系统(BMS)系列—状态估计之SOH

BMS系列文章,介绍了SOH估计

zxx52113140的博客 1846

python 写一个简单的 telegram bot (电报机器人)

replit.com 环境配置太恶心了,只能使用 poetry.poetry 这个名字是挺好听,用起来也是很垃圾,太恶心。heroku.com 注册登录不方便,需要各种验证。所以,部署的问题,目前搁置。

waterHBO的博客 3197

七天玩转Redis | Day2、Redis五大数据类型使用详解

号外号外????????????:小猿和优快云联合推出的“七天玩转Redis,打卡还能领周边”活动开始啦!点击查看????????【报名及活动细则】????????,轻轻松松和小伙伴们一起拿奖励吧! PS:零基础也能入门Redis哟,快去一起参与拿周边吧! 博主简介????????‍⚕️:国内某一线互联网公司Java工程师????????‍????,业余自媒体创作者????,优快云博客专家????,Java领域优质创作者????,华为云享专家????,华为HDZ核心成员????‍????,曾发表并

累计发表博客60余万字,优快云 博客专家、Java 领域优质创作者、华为云享专家、阿里云专家博主。专注分享 Java 优质文章,毕设实战项目开发,全网粉丝10W+ 1454

【Proteus仿真】51单片机+DAC0832+LM358放大电路波形发生器

【Proteus仿真】51单片机+DAC0832+LM358放大电路波形发生器

perseverance51博客 5787

Redis五大数据类型 详解

1、前言 关于Redis的五大数据类型,它们分别为:String、List、Hash、Set、SortSet。本文将会从它的底层数据结构、常用操作命令、一些特点和实际应用这几个方面进行解析。对于数据结构的解析,本文只会从大的方面来解析,不会介绍详细的代码实现。 2、String类型 1.实现结构   String是Redis中最常用的一种数据类型,也是Redis中最简单的一种数据类型。首先,表面上...

qq_41490913的博客 449

Pytorch图像去噪实战(七):Noise2Noise自监督图像去噪实战,没有干净图也能训练模型

PyTorch图像去噪实战:Noise2Noise自监督去噪方法 本文介绍了在没有干净图像的情况下使用Noise2Noise方法进行图像去噪的实战方案。主要内容包括: 问题场景:真实项目中经常只有带噪图像而没有对应的干净图像,如夜间监控、医学影像等场景。 Noise2Noise核心思想:使用同一场景的两张不同噪声版本的图像进行训练(noisy_image_a → noisy_image_b),让模型学习恢复共同的干净结构而非随机噪声。 技术原理:模型通过最小化两个独立噪声图像之间的差异,最终会收敛到真实干净

ai技术增长的博客 502

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

【Redis】五大基础数据类型-使用详解

Redis 有以下 5 大基础数据类型String —— 字符串类型(最常用)Hash —— 字典类型(最常用)List —— 列表类型Set —— 集合类型ZSet —— 有序集合类型接下来就来看看他们具体是如何使用的吧~

CYK_byte的博客 4889

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

【Redis八股|第2篇】Redis 五大基本数据类型详解

上一篇我们学习了 Redis 是什么,以及 Redis 为什么这么快。五大基本数据类型。Redis 虽然是 key-value 数据库,但它的 value 并不只是普通字符串。StringHashListSetZSetRedis 有哪些数据类型?String 可以用来做什么?Hash 适合存对象吗?List 和 Set 有什么区别?ZSet 为什么适合做排行榜?项目中怎么选择 Redis 数据类型?这一篇我们就把 Redis 五大基本数据类型完整梳理一遍。不是。

2401_88139521的博客 617

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Redis五大数据类型详解(加应用场景)

github地址:GitHub - DMW37/Redis: Redis五大数据类型详解

qq_52066954的博客 122

Redis——五大数据类型详解

redis五大数据类型全部命令官网对于redis的介绍Redis-KeyString字符串类型list(列表)Set(集合)Hash(哈希)Zset(有序集合) 官网对于redis的介绍 官网对于redis的介绍 ----Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间 件MQ。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合 (sets), 有序集合(sorted sets) 与范围查询, bi

hyk的博客 313

NoSQL之redis的五大数据类型详解

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

weixin_48185643的博客 248

redis五大数据类型详解

字符串类型(string) 特点 1、字符串、数字,都会转为字符串来存储 2、以二进制的方式存储在内存中 string常用命令 #字符串操作 1、set key value 2、set key value nx 3、get key 3、mset key1 value1 key2 value2 4、mget key1 key2 key3 5、set key value nx ex secon...

秋水中的鱼的博客 250

Redis五大数据类型API详解附带详细使用场景

学习Redis五大数据类型首先学习一下Redis的基础知识: 基础知识 redis默认有16个数据库 默认使用的是第0个 可以使用select 数据库编号进行切换数据库 查看数据库大小:dbsize 不同的数据库内容不共享 查看所有的key:keys * 清除当前数据库:flushdb 清除全部数据库的内容:flushall 为什么redis的端口是6379? 是一个女明星的名字九宫格打出来的数字。 Redis是单线程的! Redis是很快的。官方表示,Redis是基于内存操作,cpu不是Red

key_world的博客 430

Redis五大数据类型使用详解-String

[Redis客户端服务器启动,请见上一篇博文] Redis[key-value]的5种数据类型:String ;set; list; hash; zset。都是值的类型。hash是一个map类型,也有键值。hash类似于java中的Map<String, String>,但注意:redis中hash类型—map的泛型只能是String。hash特别适用于存储对象。。zset是有序的set集合,即有序,不重复,并且是key-value结构。 一. String类型 指令keys * 查看数据库中所

qq_40712111的博客 376

Redis五大数据类型详解及使用场景

Redis 数据类型String(字符串)Hash(哈希)List(列表)Set(集合)zset(sorted set:有序集合) Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。 String(字符串) string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value; string 类型是二进制安全的。意思是 redis 的 string

qq_29928513的博客 304
上一篇: Redis数据结构系列七:RedisObject
下一篇: Linux挂载本地ISO镜像源
Musclewl
博客等级 码龄9年 215粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值