zoukankan      html  css  js  c++  java
  • Redis数据类型-Strings

    Redis 简介

    REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。

    Redis是一个开源的使用ANSI C语言编写的基于内存的可持久化的Key-Value数据库。

    Redis的数据类型

    string,list,hash,set,sorted set

    String

    string是redis最基本的类型,而且string类型是二进制安全的。意思是redis的string可以包含任何数据,比如jpg图片或者序列化的对象。 

    与String相关的常用命令:

    • SET:为一个key设置value,可以配合EX/PX参数指定key的有效期,通过NX/XX参数针对key是否存在的情况进行区别操作,时间复杂度O(1)
    • GET:获取某个key对应的value,时间复杂度O(1)
    • GETSET:为一个key设置value,并返回该key的原value,时间复杂度O(1)
    • MSET:为多个key设置value,时间复杂度O(N)
    • MSETNX:同MSET,如果指定的key中有任意一个已存在,则不进行任何操作,时间复杂度O(N)
    • MGET:获取多个key对应的value,时间复杂度O(N)

    如果保存的是整数值并且可以用long表示,那么编码会设置为INT,那么还有额外的命令

    • INCR:将key对应的value值自增1,并返回自增后的值。只对可以转换为整型的String数据起作用。时间复杂度O(1)
    • INCRBY:将key对应的value值自增指定的整型数值,并返回自增后的值。只对可以转换为整型的String数据起作用。时间复杂度O(1)
    • DECR/DECRBY:同INCR/INCRBY,自减函数。

    用法1

     1 127.0.0.1:6379> set test-string hi
     2 OK
     3 127.0.0.1:6379> get test-string
     4 "hi"
     5 127.0.0.1:6379> getset test-string2 "how are you"
     6 (nil)
     7 127.0.0.1:6379> getset test-string2 "how are you"
     8 "how are you"
     9 127.0.0.1:6379> mset test-string hello test-string2 "good to see you"
    10 OK
    11 127.0.0.1:6379> get test-string
    12 "hello"
    13 127.0.0.1:6379> get test-string2
    14 "good to see you"

    用法2

     1 127.0.0.1:6379> mget test-string test-string2
     2 1) "hello"
     3 2) "good to see you"
     4 127.0.0.1:6379> append test-string2 "!"
     5 (integer) 16
     6 127.0.0.1:6379> get test-string2
     7 "good to see you!"
     8 127.0.0.1:6379> set test-string2 20
     9 OK
    10 127.0.0.1:6379> incr test-string2
    11 (integer) 21
    12 127.0.0.1:6379> 

    string的encoding

    字符串对象的编码可以是 INT、RAW 或 EMBSTR。如果保存的是整数值并且可以用long表示,那么编码会设置为INT。当字符串值得长度大于39字节使用raw 并且用sds来保存,小于等于39字节使用embstr。

    127.0.0.1:6379> object encoding test-string 
    "embstr"
    127.0.0.1:6379> object encoding test-string2
    "int"
    127.0.0.1:6379> 
    1 127.0.0.1:6379> set l39 111111111122222222223333333333444444444
    2 OK
    3 127.0.0.1:6379> object encoding l39
    4 "embstr"
    5 127.0.0.1:6379> set l40 1111111111222222222233333333334444444444
    6 OK
    7 127.0.0.1:6379> object encoding l40
    8 "raw"
    9 127.0.0.1:6379> 

    encoding的变换

    1 127.0.0.1:6379> append test-string2 " is a raw"
    2 (integer) 11
    3 127.0.0.1:6379> object encoding test-string2
    4 "raw"

    向一个保存整数值的字符串对象追加了一个字符串,程序会先将之前保存的整数值 转换为字符串值  , 然后再执行追加操作, 操作的执行结果就是一个 raw 编码的、保存了字符串值的字符串对象。

     1 127.0.0.1:6379> set test-string2 "I'm a embstr"
     2 OK
     3 127.0.0.1:6379> set test-string3 "I'm a embstr"
     4 OK
     5 127.0.0.1:6379> get test-string3
     6 "I'm a embstr"
     7 127.0.0.1:6379> object encoding test-string3
     8 "embstr"
     9 127.0.0.1:6379> append test-string3 " I changed to raw"
    10 (integer) 29
    11 127.0.0.1:6379> get test-string3
    12 "I'm a embstr I changed to raw"
    13 127.0.0.1:6379> object encoding test-string3
    14 "raw"

     embstr 编码的字符串对象实际上是只读的, 当我们对 embstr 编码的字符串对象执行任何修改命令时, redis会先将encoding从 embstr 转换成 raw , 然后再执行修改命令; 因为这个原因, embstr 编码的字符串对象在执行修改命令之后, 总会变成一个 raw 编码的字符串对象

    源码

    先看一下sds

     1 struct __attribute__ ((__packed__)) sdshdr5 {
     2     unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
     3     char buf[];
     4 };
     5 struct __attribute__ ((__packed__)) sdshdr8 {
     6     uint8_t len; /* used */
     7     uint8_t alloc; /* excluding the header and null terminator */
     8     unsigned char flags; /* 3 lsb of type, 5 unused bits */
     9     char buf[];
    10 };
     1 /* Create a string object with encoding OBJ_ENCODING_RAW, that is a plain
     2  * string object where o->ptr points to a proper sds string. */
     3 robj *createRawStringObject(const char *ptr, size_t len) {
     4     return createObject(OBJ_STRING, sdsnewlen(ptr,len));
     5 }
     6 
     7 /* Create a string object with encoding OBJ_ENCODING_EMBSTR, that is
     8  * an object where the sds string is actually an unmodifiable string
     9  * allocated in the same chunk as the object itself. */
    10 robj *createEmbeddedStringObject(const char *ptr, size_t len) {
    11     robj *o = zmalloc(sizeof(robj)+sizeof(struct sdshdr8)+len+1);
    12     struct sdshdr8 *sh = (void*)(o+1);
    13 
    14     o->type = OBJ_STRING;
    15     o->encoding = OBJ_ENCODING_EMBSTR;
    16     o->ptr = sh+1;
    17     o->refcount = 1;
    18     if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) {
    19         o->lru = (LFUGetTimeInMinutes()<<8) | LFU_INIT_VAL;
    20     } else {
    21         o->lru = LRU_CLOCK();
    22     }
    23 
    24     sh->len = len;
    25     sh->alloc = len;
    26     sh->flags = SDS_TYPE_8;
    27     if (ptr == SDS_NOINIT)
    28         sh->buf[len] = '';
    29     else if (ptr) {
    30         memcpy(sh->buf,ptr,len);
    31         sh->buf[len] = '';
    32     } else {
    33         memset(sh->buf,0,len+1);
    34     }
    35     return o;
    36 }
    37 
    38 /* Create a string object with EMBSTR encoding if it is smaller than
    39  * OBJ_ENCODING_EMBSTR_SIZE_LIMIT, otherwise the RAW encoding is
    40  * used.
    41  *
    42  * The current limit of 44 is chosen so that the biggest string object
    43  * we allocate as EMBSTR will still fit into the 64 byte arena of jemalloc. */
    44 #define OBJ_ENCODING_EMBSTR_SIZE_LIMIT 44
    45 robj *createStringObject(const char *ptr, size_t len) {
    46     if (len <= OBJ_ENCODING_EMBSTR_SIZE_LIMIT)
    47         return createEmbeddedStringObject(ptr,len);
    48     else
    49         return createRawStringObject(ptr,len);
    50 }
  • 相关阅读:
    SQL Server 锁的 8 种类型
    MYSQL 提取时间中的信息的 4 方法
    MYSQL 时间计算的 3 种函数
    MYSQL 的 6 个返回时间日期函数
    SQL Server 错误18456
    MYSQL <=>运算符
    django比较相等或者不相等的模板语法ifequal / ifnotequal
    django模板语言的注释
    ECharts修改坐标轴,坐标轴字体,坐标轴网格样式以及控制坐标轴是否显示
    http://www.cnblogs.com/linxiyue/p/8244724.html
  • 原文地址:https://www.cnblogs.com/13579net/p/10132125.html
Copyright © 2011-2022 走看看