Redis底层数据结构

Redis数据结构

一、基本数据结构

常见数据结构:String(字符串)、List(列表)、Hash(哈希)、Set(集合)和 Sorted Set(有序集合)

Redis底层数据结构_第1张图片

​ String 类型的底层实现只有一种数据结构,也就是简单动态字符串。而 List、Hash、Set 和 Sorted Set 这四种数据类型,都有两种底层实现结构。通常情况下,我们会把这四种类型称为集合类型,它们的特点是一个键对应了一个集合的数据。

​ 压缩列表和跳表我们平时接触得可能不多,但它们也是 Redis 重要的数据结构,需要重点学习一下。

  • 压缩列表实际上类似于一个数组,数组中的每一个元素都对应保存一个数据。和数组不同的是,压缩列表在表头有三个字段 zlbytes、zltail 和 zllen,分别表示列表长度、列表尾的偏移量和列表中的 entry 个数;压缩列表在表尾还有一个 zlend,表示列表结束。

Redis底层数据结构_第2张图片

  • 有序链表只能逐一查找元素,导致操作起来非常缓慢,于是就出现了跳表。具体来说,跳表在链表的基础上,增加了多级索引,通过索引位置的几个跳转,实现数据的快速定位。
    Redis底层数据结构_第3张图片

当数据量很大时,跳表的查找复杂度就是 O(logN)。

二、高级数据结构
1、Bitmap

Bitmap 本身是用 String 类型作为底层数据结构实现的一种统计二值状态的数据类型。如果只需要统计数据的二值状态,例如商品有没有、用户在不在、签到没签到等,就可以使用 Bitmap,因为它只用一个 bit 位就能表示 0 或 1。在记录海量数据时,Bitmap 能够有效地节省内存空间
后续布隆过滤器用到这种结构,会重点介绍。

2、HyperLogLog
3、GEO

​ 举例:网约车有车ID、经纬度,用户经纬度,把位置相近的用户和车辆匹配上以后,叫车应用就会根据车辆的编号,获取车辆的信息,并返回给用户。可以用Hash存储,但是涉及范围查询,需要存储有序,Hash是无序的,所以不能满足业务需求。

​ Sorted Set 可以根据元素的权重分数排序,支持范围查询。实际上,GEO 类型的底层数据结构就是用 Sorted Set 来实现的,使用GEOHash编码。

GeoHash 的编码方法

基本原理就是“二分区间,区间编码”,对一组经纬度进行 GeoHash 编码时,我们要先对经度和纬度分别编码,然后再把经纬度各自的编码组合成一个最终编码。

进行第一次二分区时,经度范围[-180,180]会被分成两个子区间:[-180,0) 和[0,180](我称之为左、右分区)。此时,我们可以查看一下要编码的经度值落在了左分区还是右分区。如果是落在左分区,我们就用 0 表示;如果落在右分区,就用 1 表示。这样一来,每做完一次二分区,我们就可以得到 1 位编码值。

举个例子,假设我们要编码的经度值是 116.37,我们用 5 位编码值(也就是 N=5,做 5 次分区)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jLXSYKXC-1650876348573)(/Users/cenjinxing/lean/博客笔记/图片/GEO Hash编码.webp)]

纬度同理可得,然后把经纬度组合基数位填经度,偶数位填纬度。

常用命令:

  • GEOADD 命令:用于把一组经纬度信息和相对应的一个 ID 记录到 GEO 类型集合中;

  • GEORADIUS 命令:会根据输入的经纬度位置,查找以这个经纬度为中心的一定范围内的其他元素。当然,我们可以自己定义这个范围。

下期预告:Redis为什么这么快?

你可能感兴趣的:(Redis,redis,数据库,java)