前言

最近在学习调研ElasticSearch,ES是一款热度较高的开源搜索服务器,能够提供近实时的数据全文检索功能,而实现检索功能一个其中较为重要的思想就是使用倒排索引,之所以成为倒排,与我们关系型数据库如Mysql的正排索引的区别在哪?在这篇文章总结一下我对两种索引的理解。

正文

正排索引

拿Mysql Innodb的聚簇索引来说,如下图所示,一个极简版(无页属性)的B+树索引结构大概是这样,叶子节点存放完整数据,非叶子节点存放建立对应聚簇索引对应的字段(主键),一条可以使用到聚簇索引的Sql,会依次从上到下进行B+树的查找直到字段一致;

CREATE TABLE user_info (

id int,

name varchar(16),

hobby varchar(256)

);

而对应非聚簇索引只是叶子节点的内容存放的是该表的主键信息,查询的顺序则是 先通过非聚簇索引的字段找到叶子节点中一致的 单个或者多个主键id,再使用这些主键id进行回表,最终获得对应的完整实体数据。

如果我们看上面在mysql中表的hobby爱好字段,如果我们有业务需求:根据用户爱好关键字如“篮球”去查询对应用户列表,我们怎么做,只能是写个字符串的like sql,全表扫描的逻辑。

SELECT *

FROM user_info

WHERE hobby LIKE '%篮球%';

即使我们对hobby字段创建了普通索引,在Innodb引擎下,在查询中想使用字符串类型的索引也只能走最左前缀索引的逻辑,即 LIKE ‘篮球%’。幸好Innodb在5.6版本后支持了全文索引full text,在创建完全文索引后,查询中使用MATCH、AGAINST就能够使用全文索引了,比全表扫B+树效率会高很多,但是对应全文索引会占据相当的磁盘空间。全文索引与我们要说的倒排索引就是一个意思了。

SELECT *

FROM user_info

WHERE MATCH (hobby) AGAINST ('篮球');

倒排索引

相比B+树的正排索引,如果我们对hobby字段建立了索引,他的倒排索引极简的数据格式如下。创建倒排索引的field,会通过分词器根据语义将字段中的field分成一个一个对应的词索引(term index),构成该类型数据的全部词索引集合(term dictionary),如“喜欢篮球、唱歌”会被分成 “篮球”和“唱歌”两个term index;第二列是含有这些term index对应的文档Id(documentId),这个数据可以帮助我们最终溯源到完整实体数据;第三列则是对应term index在该文档字段中的位置,0表示在开头的位置,这个可以帮助标注检索出来数据的高亮信息。

倒排索引与分词

如何输入一个文档数据后创建对应的倒排索引,如 {“id”:1,“name”:“张三”,“hobby”:“喜欢篮球、唱歌”}。拿ES来说,可以预先设置字段为string及对应的分词器,会针对hobby这个字段进行预处理,一整句话在经过下面的三个分词步骤,会被分成多个对应的词索引(term index),每个term index对应的位置、文档id也都会生成,添加到上述的数据结构中。

Character Filters:针对原始文本进行处理,比如去除html标签

Tokenizer:将原始文本按照一定规则切分为单词

Token Filters:针对Tokenizer处理的单词进行再加工,比如转小写、删除或增新等处理

针对不同的文本内容,我们可以使用不同的分词器甚至是自定义分词器,如ES的分词器:Standard Analyzer(默认分词器,按词切分,处理标点)、Simple Analyzer(不是子母的字符会被忽略切为切分点)、Whitespace Analyzer(基于空格的分词器)、IKAnalyzer(比较流行的中文分词器);Mysql的全文索引也有对应的中文分词器ngram。

两个索引查询顺序

通过上面的描述,我们可以知道在使用正排索引、倒排索引时的一个大概的查询顺序

倒排索引思想的应用

之前有接过一个需求描述:我们要对不同城市、年级、学期、设备的用户设定不同的内容展现规则,这几个属性是可以设置为空的,最后如果一个用户的属性匹配到了多个规则,那么就需要根据这几个属性的权重来打分,取分最高的规则,如我们配置规则如下:那么一个上海小学一年级春季的用户过来就匹配到了两个规则,然后根据这两个规则的属性进行权重值打分计算即可,最后选择显示A或B。

city

grade

term

device

rule

上海

春季

显示A

上海

小学一年级

显示B

上面在进行数据查询时,sql如下,在这个or的过程的思想就类似于“倒排索引中分词+查找所有含有该词索引的文档数据”(只是这个词索引是早已确定好的),然后在搜索到多条记录后进行权重值计算(类似ES中的检索关联程度打分)。

SELECT *

FROM tb_rules

WHERE (city = '上海' OR grade = '小学一年级' OR term = '春季')

总结

通过这篇文章,我们了解了正排索引、倒排索引的思想及简要的实现方式,希望能通过这些不一样的原理能给工作中的问题带来不同解决的思路。

mysql是正排还是倒排_正排索引与倒排索引的理解相关推荐

  1. mysql是正排还是倒排_正排索引和倒排索引的区别

    建立索引是搜索引擎对网站页面的tag title.meta descripiton.描述.抓取记录.页面外链等等,进行标记添加的行为.这其中,还将对页面中的关键词信息进行识别和储存,当用户搜索的时候, ...

  2. 推荐系统的中的正排和倒排

    在推荐系统的实际业务场景中,当我们针对业务场景优化推荐策略,尤其是召回策略时,大部分情况下需要工程同学对索引的支持.比如本地化推荐,我们就要以物料中带有City_id(城市id),并且City_id ...

  3. lisp坐标一键生成_联排建筑一键生成?你的SU有外挂吧!

    今天小吧要给你们安利一款 超厉害的插件--联排建筑 ▼ 这些都可以一键生成哟 绘制建筑 插件介绍 联排建筑 SUAPP编号450 作者:Eneroth3 插件下载地址 http://www.suapp ...

  4. php关键词分词搜索 最多匹配的排在最前面_图解 | 通用搜索引擎背后的技术点...

    来源 | 后端技术指南针头图 | 图虫 写在前面 今天准备和盆友们一起学习下关于通用搜索引擎的一些技术点. 鉴于搜索引擎内容非常多,每一部分都够写好几篇文章的所以本文只是抛砖引玉,深入挖掘还得老铁们亲 ...

  5. 搜索 正排索引 和 倒排索引 区别

    一.什么是正排索引(forward index)? 简言之,由key查询实体的过程,使用正排索引. 例如,用户表: t_user(uid, name, passwd, age, sex) 由uid查询 ...

  6. 在proteus中的排阻的查找_排阻在proteus中怎么找

    排阻概要 排阻(NetworkResistor),即网络电阻器(Wire-woundResistor).排阻是将若干个参数完全相同的电阻集中封装在一起,组合制成的.它们的一个引脚都连到一起,作为公共引 ...

  7. python 排产计划_生产排程计划表

    生产计划排程表 3-1 3-2 3-3 3-4 3-5 3-6 3-7 3-8 3-9 3-10 3-11 3-12 六 日 一 二 三 四 五 六 日 一 二 三 A 20140276 FG0000 ...

  8. 排序方法python实现_八字排盘,四柱八字排盘算命,免费排八字,卜易居在线排盘系统...

    为方便您正确排好八字命盘,请阅读卜易居在线排盘系统之说明: 1. 将年月日时排成命盘,每个时间概念称为一柱,共有四柱:每柱有天干地支两个字,共八个字,故称四柱八字排盘. 2. 公历即是阳历,农历即是阴 ...

  9. 在线排卵计算机,【美柚女性排卵期计算器_美柚女性排卵期计算器专题】- 天鹅到家...

    很多要想比较技术专业且精确地预测分析自身的排卵期的女性.要想怀孕或避开怀孕的女性,或是要想根据对排卵期的预测分析,根据排卵期時间的不一,对生理学病症做出一些预防的女性,能够运用女性排卵期计算器.女性排 ...

  10. 排序方法python实现_八字排盘,排大运

    八字排盘,排大运 八字排盘也叫排大运,八字排盘是起四柱之后要做的第一件事,八字算命门槛较高,如果你不了解起四柱的内容,也就无法理解八字排盘. 相关阅读:如何起四柱? 一,什么是阴年?什么是阳年? 在甲 ...

最新文章

  1. Build Tools三问
  2. 通俗解释协方差与相关系数
  3. postGIS相关数据库参数
  4. flutter 泛型_flutter用NestedScrollView的项目必须知道的坑
  5. Eclipse导入github项目后不显示分支名称没有黄色小油桶标志
  6. apache jmeter 使用
  7. 贝叶斯学派与频率学派有何不同?
  8. easypoi 语法_知识点总结及语法学习资料及视频
  9. 【图像去噪】基于matlab GUI中值滤波图像去噪【含Matlab源码 205期】
  10. kali netstat使用教程
  11. 光纤交换机 序列号_FAQ-如何查询设备的SN号
  12. mysql 过滤微信昵称表情符号_js 过滤微信昵称的表情符号
  13. map的基本使用-go篇
  14. qpython3使用手册图_qpython 图
  15. php 表格制作教程下载,word表格如何制作教程?
  16. TeamViewer由商业用途改为个人用途
  17. js实现十大经典排序算法
  18. 文章阅读统计php,WordPress博客统计文章阅读次数及访客数并刷访问数
  19. RMQ与SparseTable(ST表)
  20. matlab中ct值直方图,CT值直方图在原发性肝癌诊断中的应用

热门文章

  1. JPA 中@Enumerated
  2. iOS根据ts文件路径封装成m3u8文件及m3u8播放
  3. 【Tableau server 8.0】Tableau server 考试真题回顾总结
  4. tableau连接Mysql出现的密码验证 cannot be loaded
  5. C/C++ C语言定义结构体的几种方法
  6. Unity之使用Shader实现背景循环播放
  7. 蒙版操作—利用图层蒙版换脸
  8. JavaScript 中 typeof 和 instanceof 的区别及如何判断数组
  9. 苹果logo_苹果 ARM Mac 发布会独特标志 Logo 亮相
  10. 【高中数学】向量积坐标公式