Redis学习小计(6) - 基本数据类型:哈希(hash)

Redis基本数据类型:哈希(hash)

  Redis内部使用两种结构来实现hash

  • 压缩列表(ziplist)
  • 哈希表(hashtable)

1. 压缩列表(ziplist)

  Redis每次创建哈希类型的时候,都会先使用默认ziplist。
  使用这种结构时,redisObject.encoding = OBJ_ENCODING_ZIPLIST

robj *createHashObject(void) {
    unsigned char *zl = ziplistNew();
    robj *o = createObject(OBJ_HASH, zl);
    o->encoding = OBJ_ENCODING_ZIPLIST;
    return o;
}

  当ziplist不满足下面条件时,会自动转成哈希表

hash-max-ziplist-entries 512

hash-max-ziplist-value 64


2. 哈希表(hashtable)

  使用这种结构时,redisObject.encoding = OBJ_ENCODING_HT
  先来简单介绍下hashtable用到的结构:


  dict struct

typedef struct dict {
  dictType *type;
  void *privdata;
  dictht ht[2];
  long rehashidx;
  unsigned long iterators;
} dict;

  • ht[2] - 默认建立两个hashtable,正常时都使用ht[0],当需要移动hashtable时,会逐个把ht[0]里面的节点拷贝到ht[1]。如果此时有更新操作,也会直接对ht[1]进行修改。当ht[0]全部移动到ht[1]里面后,将两个hashtable进行切换
  • rehashidx - 移动hashtable标识,-1表示没有发生移动
ht = dictIsRehashing(d) ? &d->ht[1] : &d->ht[0];

  dictht struct

typedef struct dictht {
  dictEntry **table;
  unsigned long size;
  unsigned long sizemask;
  unsigned long used;
} dictht;

  • table - 字典数组,记录每个节点信息,初始化为NULL
  • size - 字典数组的大小,初始化为0
  • sizemask - size-1,初始化为0
  • used - 字典数组已经使用的个数,初始化为0
static void _dictReset(dictht *ht)
{
    ht->table = NULL;
    ht->size = 0;
    ht->sizemask = 0;
    ht->used = 0;
}

当插入节点大于空闲节点数时(size-used),就会对hashtable进行扩容,大概的步骤:

  1. 创建一个新的hashtable,size是原来的2倍(如果原来的size是0,会使用默认大小4)
  2. 将字典的ht[1]替换为新创建的hashtable
  3. 将ht[0]里面的节点移动到ht[1]
  4. 移动完成,切换ht[1]到ht[0]

  dictEntry struct

typedef struct dictEntry {
  void *key;
  union {
     void *val;
     uint64_t u64;
     int64_t s64;
     double d;
  } v;
  struct dictEntry *next;
} dictEntry;

  • key - 节点索引
  • val - 节点值
  • next - 指向下一个节点的指针,当索引相同时,使用“拉链法”处理冲突

3. command

  • HDEL - Delete one or more hash fields
  • HEXISTS - Determine if a hash field exists
  • HGET - Get the value of a hash field
  • HGETALL - Get all the fields and values in a hash
  • HINCRBY - Increment the integer value of a hash field by the given number
  • HINCRBYFLOAT - Increment the float value of a hash field by the given amount
  • HKEYS - Get all the fields in a hash
  • HLEN - Get the number of fields in a hash
  • HMGET - Get the values of all the given hash fields
  • HMSET - Set multiple hash fields to multiple values
  • HSCAN - Incrementally iterate hash fields and associated values
  • HSET - Set the string value of a hash field
  • HSETNX - Set the value of a hash field, only if the field does not exist
  • HSTRLEN - Get the length of the value of a hash field
  • HVALS - Get all the values in a hash

上一篇:Redis学习小计(5) - 基本数据类型:列表(list)
下一篇:Redis学习小计(7) - 基本数据类型:集合(set)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值