leveldb(六):key的不同种类型

本文深入探讨了数据库中五种关键概念:User_key、Sliceuser_key、ParsedInternalKey、InternalKey及LookupKey与MemtableKey。详细介绍了这些Key的结构组成、格式以及它们之间的关系,帮助读者理解数据库内部如何通过这些Key进行高效操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有5个key的概念,可能会让人混淆,下面就来一个一个的分析。
这里写图片描述

User_key;

最简单的key了,就是用户传入的数据
Slice user_key;

ParsedInternalKey

enum ValueType {
  kTypeDeletion = 0x0,
  kTypeValue = 0x1
};
//我们后面会讲到,我们对key进行delete操作时其实也是插入一条记录,只不过ValueType用delete标识

typedef uint64_t SequenceNumber;
struct ParsedInternalKey {
  Slice user_key;
  SequenceNumber sequence;
  ValueType type;
};

Sequence number是所有基于op log系统的关键数据,它唯一指定了不同操作的时间顺序。
ValueType type代表的是将对key进行的操作类型。

InternalKey

InternalKey是一个复合概念,是有几个部分组合成的一个key,ParsedInternalKey就是对InternalKey分拆后的结果,也就是说InternalKey是由User key + SequenceNumber + ValueType组合而成的
InternalKey的格式为:
| User key (string) | sequence number (7 bytes) | value type (1 byte) |

把user key放到前面的原因是,这样对同一个user key的操作就可以按照sequence number顺序连续存放了,不同的user key是互不相干的,因此把它们的操作放在一起也没有什么意义。

另外用户可以为user key定制比较函数,系统默认是字母序的。

LookupKey & Memtable Key

Memtable的查询接口传入的是LookupKey,它也是由User Key和Sequence Number组合而成的,从其构造函数:LookupKey(const Slice& user_key, SequenceNumber s)中分析出LookupKey的格式为:

| Size (int32变长)| User key (string) | sequence number (7 bytes) | value type (1 byte) |

注意:

  • 这里的Size是user key长度+8,也就是整个字符串长度了;
  • value type是kValueTypeForSeek,它等于kTypeValue。
  • 由于LookupKey的size是变长存储的,因此它使用kstart_记录了user key string的起始地址,否则将不能正确的获取size和user key;

LookupKey导出了三个函数,可以分别从LookupKey得到Internal Key,Memtable Key和User Key,如下:


  // Return a key suitable for lookup in a MemTable. 
  //可以看出memtable_key就是LookupKey的slice形式
  Slice memtable_key() const { return Slice(start_, end_ - start_); }

  // Return an internal key (suitable for passing to an internal iterator)

  Slice internal_key() const { return Slice(kstart_, end_ - kstart_); }

  // Return the user key

  Slice user_key() const { return Slice(kstart_, end_ - kstart_ - 8); }

其中start_是LookupKey字符串的开始,end_是结束,kstart_是user key字符串的起始地址。

class LookupKey {
 private:
  // We construct a char array of the form:
  //    klength  varint32               <-- start_
  //    userkey  char[klength]          <-- kstart_
  //    tag      uint64
  //                                    <-- end_
  // The array is a suitable MemTable key.
  // The suffix starting with "userkey" can be used as an InternalKey.
  const char* start_;//整个LookupKey的起始位置
  const char* kstart_;
  const char* end_;
  char space_[200];      // Avoid allocation for short keys
}

LookupKey::LookupKey(const Slice& user_key, SequenceNumber s) {
  size_t usize = user_key.size();//user_key的长度
  size_t needed = usize + 13;
  // 为什么加13?因为8是SequenceNumber和 value type的长度,5是Size (int32变长)的最大长度

  char* dst;
  if (needed <= sizeof(space_)) {
    dst = space_;
  } else {
    dst = new char[needed];//超过预留space就得重新设置start_
  }
  start_ = dst;
  dst = EncodeVarint32(dst, usize + 8);//变长编码size
  kstart_ = dst;
  memcpy(dst, user_key.data(), usize);
  dst += usize;
  EncodeFixed64(dst, PackSequenceAndType(s, kValueTypeForSeek));
  //定长编码SequenceNumber和 value type
  dst += 8;
  end_ = dst;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值