2021SC@SDUSC
本篇博客主要讲解Gin索引的介绍和相关的组织结构

目录

  • GIN索引介绍
  • GIN扩展
    • 实现扩展步骤
  • GIN索引组织结构
  • 相关数据结构
    • GISTPageOpaqueData
    • GISTENTRY
    • GinMetaPageData

GIN索引介绍

GIN(Generalized Inverted Index, 通用倒排索引) 是一个存储对(key, posting list)集合的索引结构,其中key是一个键值,而posting list 是一组出现过key的位置。如(‘hello’, ‘14:2 23:4’)中,表示hello在14:2和23:4这两个位置出现过,在PG中这些位置实际上就是元组的tid(行号,包括数据块ID(32bit),以及item point(16 bit) )。
在表中的每一个属性,在建立索引时,都可能会被解析为多个键值,所以同一个元组的tid可能会出现在多个key的posting list中。
通过这种索引结构可以快速的查找到包含指定关键字的元组,因此GIN索引特别适用于多值类型的元素搜索,比如支持全文搜索,数组中元素的搜索,而PG的GIN索引模块最初也是为了支持全文搜索而开发的。

GIN扩展

GIN是一个开放的索引接口,所以它不仅适用于已经存在的如数组、全文检索等数据类型,同样也可以扩展支持更多的数据类型。

在PG9.0版本中,定义一个GIN访问方法所要做的就是实现5个用户定义的方法,这些方法定义了键值、键值与键值之间的关系、被索引值、能够使用索引的查询以及部分匹配。

这些方法是:
1.compare方法:比较两个键值a和b,然后返回一个整数值,返回负值表示a < b,返回0表示a = b,返回正值表示a > b。

其函数原型如下:

int compare(Datum a, Datum b)

2.extractValue方法:根据参数inputValue生成一个键值数组,并返回其指针,键值数组中元素的个数存放在另一个参数nkeys中。

其函数原型如下:

Datum *extractValue(Datum inputValue, int32 *nkeys)

3.extractQuery方法:根据参数query生成一个用于查询的键值数组,并返回其指针。

函数原型如下:

Datum *extractQuery(Datum query, int32 *nkeys, StrategyNumber n, bool **pmatch, Pointer **extra_data)

extractQuery通过参数n指定的操作符策略号来决定query的数据类型以及需要提取的键值,返回键值数组的长度存放在nkeys参数中。
如果query中不包含键值,则nkeys可以为0或者-1:
nkeys = 0 表示索引中所有值都满足查询,将执行完全索引扫描(查询null时是这样); nkeys = -1 表示索引中没有键值满足查询,跳过索引扫描。
在部分匹配时,输出参数pmatch记录返回的键值数组中的每一个键值是否请求部分匹配。
输出参数extra_data用来向consistent和comparPartial方法传递用户自定义需要的数据。
4. consistent方法:用于检查索引值是否满足查询,
其函数原型如下:

bool consistent(bool check[], StrategyNumber n, Datum query, int32 nkeys, Pointer extra_data[], bool *recheck)

如果索引值满足查询则返回true,如果recheck = true,则返回true的索引还需要进一步的检查。具体过程如下图所示

recheck: 精确比较时recheck = false;否则recheck = true,通过索引找到的基表元组还需要进行是否满足操作符的检查(在TSVector类型时,如果key带有权值,则recheck = true)。
5. comparePartial方法:将部分匹配的查询与索引值进行比较,返回值为负值表示两者不匹配,但继续索引扫描;返回值为0表示两者匹配;返回值为正值表示停止扫描。

其函数原型如下:

int comparePartial(Datum partial_key, Datum key, StrategyNumber n, Pointer extra_data)

实现扩展步骤

在PG中添加一种新的数据类型并且让GIN支持该数据类型,则需要完成以下步骤:
1.添加数据类型
2.为新数据类型实现并注册各种操作符所需要的函数,然后创建新类型的操作符
3.用CREATE OPERATOR CLASS为新的数据类型创建一个操作符类,该语句需要指定GIN索引所需要的5个支持函数

PG的GIN索引,内部实现了对于TSVector数据类型的支持,并提供了把TEXT类型转换成TSVector的接口,所以可以说PG的GIN索引支持TSVector和TEXT的数据类型。

GIN索引组织结构

GIN索引包括四个部分:
1.Entry:相当于GIN索引的一个元素,Entry可以理解为GIN中的一个键值
2.Entry Tree:在一些Entry上构建B-Tree
3.Posting Tree:在一个Entry出现的物理位置构建的B-Tree
4.Posting List:一个Entry出现的物理位置的列表
GIN索引包含一个构建在Entry上的B-Tree索引,“Entry Tree”的内部节点与B-Tree一样,而叶子节点的索引项指针指向不同。在GIN索引中叶子节点上,指针指向分为两种情况:
1.如果Entry所出现的物理位置大于TOAST_INDEX_TARGET指定的值,则在这些位置上构建Posting Tree
2.如果小于索引项指针直接指向 Posting List
可以根据图示来更好的理解

相关数据结构

GISTPageOpaqueData

关于GIST索引页面的相关数据结构

typedef struct GISTPageOpaqueData
{PageGistNSN nsn;           /* 记录页面分割*/BlockNumber rightlink;       /* 指向下一个节点的右指针 */uint16     flags;          /* 标志位 */uint16     gist_page_id;   /* GIST索引的页号 */
} GISTPageOpaqueData;

GISTENTRY

Entry的相关数据结构

typedef struct GISTENTRY
{Datum      key;Relation    rel;Page        page;OffsetNumber offset;  //在页面的偏移量bool        leafkey;//子节点
} GISTENTRY;

GinMetaPageData

typedef struct GinMetaPageData
{BlockNumber head;//待建立的索引页的链头BlockNumber tail;//待建立的索引页的链尾uint32       tailFreeSize;//尾部剩余空间BlockNumber nPendingPages;//挂起列表的块号int64       nPendingHeapTuples;//挂起列表的堆元组数//相关的统计数据BlockNumber nTotalPages;BlockNumber nEntryPages;BlockNumber nDataPages;int64     nEntries;int32      ginVersion;//gin索引的版本
} GinMetaPageData;

postgreSQL源码分析——索引的建立与使用——GIN索引(1)相关推荐

  1. PostgreSQL源码分析

    PostgreSQL源码结构 PostgreSQL的使用形态 PostgreSQL采用C/S(客户机/服务器)模式结构.应用层通过INET或者Unix Socket利用既定的协议与数据库服务器进行通信 ...

  2. postgreSQL源码分析——索引的建立与使用——GIST索引(2)

    2021SC@SDUSC 本篇博客主要讲解GiST索引创建以及删除的相关函数 这里写目录标题 GIST创建 相关数据结构 GISTBuildState GISTInsertStack gistbuil ...

  3. postgreSQL源码分析——索引的建立与使用——Hash索引(3)

    2021SC@SDUSC 上一篇博客讲了关于Hash索引创建与插入的相关函数,这一篇博客讲述关于溢出页的操作函数以及Hash表的扩展相关的函数. 目录 溢出页的分配和回收 _hash_addovflp ...

  4. postgreSQL源码分析——索引的建立与使用——Hash索引(2)

    2021SC@SDUSC 目录 Hash索引创建 hashbuild函数 _hash_init函数 Hash索引的插入 hashinsert函数 _hash_doinsert函数 总结 Hash索引创 ...

  5. postgreSQL源码分析——索引的建立与使用——各种索引类型的管理和操作(2)

    2021SC@SDUSC 目录 上层操作函数 index_open index_beginscan() index_create() indexcmd.c 下层接口函数 IndexScanDescDa ...

  6. postgreSQL源码分析——索引的建立与使用——GIN索引(3)

    2021SC@SDUSC 本篇博客继续讲解GIN索引创建和插入相关的函数,并讲解GIN索引的查询过程 目录 GIN索引的创建 ginbuild 插入函数 ginEntryInsert GIN索引查询 ...

  7. postgreSQL源码分析——索引的建立与使用——Hash索引(1)

    2021SC@SDUSC 目录 Hash索引 Hash索引原理 Hash表 Hash索引结构 Hash的页面结构 元页 桶页,溢出页,位图页 和B-Tree相比的优缺点 优点 缺点 总结 Hash索引 ...

  8. postgreSQL源码分析——索引的建立与使用——各种索引类型的管理和操作(1)

    2021SC@SDUSC 目录 概述 管理索引的系统表 记录索引相关的系统表 与索引系统表相关的后端源码 索引的操作函数 上层操作函数 下层接口函数 概述 索引是指按表中某些关键属性或表达式建立元组的 ...

  9. postgreSQL源码分析——索引的建立与使用——总结篇

    2021SC@SDUSC 在小组中我负责索引的建立与使用的相关部分,在此一共写了16篇相关的分析报告,着重分析各种索引的操作和管理方法,以及分析了PG中四种最重要的索引B-Tree索引,Hash索引, ...

  10. postgreSQL源码分析——索引的建立与使用——B-Tree索引(3)

    2021SC@SDUSC 目录 B-Tree的插入 bt_insert _bt_doinsert BTInsertStateData _bt_search函数 _bt_moveright函数 B-Tr ...

最新文章

  1. Vue从Hello World到打包(后端适读)
  2. Linux信号列表(sigint,sigtstp..)
  3. 【Python学习系列十三】Python机器学习库scikit-learn实现逻辑回归
  4. TClientDataSet[28]: 读写其他格式的 XML 文件
  5. 【STM32】通用定时器(TIM2到TIM5)
  6. java封装 1210 速记
  7. Go内存分配跟踪调优
  8. PoostgreSQL在Windows平台安装失败的解决
  9. word 中快速加入序号等符号
  10. C#编写一个控制台程序,输入一个日期,输出这一天是星期几。
  11. OpenStack部署(未完成)
  12. 联发科MT6797/Helio X20软件用户手册资料介绍
  13. yolov4用1050ti_Windows下基于VS2019|Opencv4.2.0|CUDA10.0|YOLOv4
  14. 极客日报:腾讯《王者荣耀》禁止未满12周岁用户充值;B站发布16款新品游戏;华为注册姚安娜商标被驳回
  15. oracle函数笔记
  16. 如何在Abaqus中用扫掠的方法画六面体网格
  17. 使用ECS和OSS搭建个人网盘
  18. Spring框架快速入门(Spring超全面讲解)
  19. HTB打靶日记:Bashed
  20. [hdu-1814] Peaceful Commission题解

热门文章

  1. python课后题答案第一章_python核心编程课后习题解答第一章
  2. 【clickhouse】flink jdbc 方式写入 clickhouse 报错 request to {}->http://xxx:8123: Broken pipe
  3. 95-910-170-源码-FlinkSQL-Flink SQL 中的流和动态表
  4. 【flink】Flink 1.12.2 源码浅析 : yarn-per-job模式解析 JobMasger启动 YarnJobClusterEntrypoint
  5. 【Spring】Spring事务失效的 8 大原因
  6. Spark中RDD与DataFrame与DataSet的区别与联系
  7. 【ES】Mac 下安装ES 报错 Failed to create native process factories for Machine Learning
  8. 【Flink】Flink on RocksDB 参数调优指南
  9. 《spring-boot学习》-12-@controller和@RestController的区别?
  10. Caused by: java.lang.NoSuchMethodError: javax.persistence.spi.PersistenceUnitInfo.getValidationMode(