mysql全文索引中文分词在java中的实现_极限 MySQL (2) InnoDB 表与索引

d276b39a71a98941102905971c48fe1c.png

InnoDB 中的表根据主键顺序组织存放的,这种存储方式的表称为索引组织表 Index Organized Table。InnoDB 中的每个表都有一个主键,如果没有主键则选择第一个非空唯一索引,如果还没有则自动生成一个 6 字节大小指针。

InnoDB 存储引擎中,主键是唯一的标识符。主键又叫做 Primary Key,Clustered Index,聚集索引,聚簇索引,簇集索引。一般来说插入簇集索引是非常块的,因为是按照主键递增插入的。

InnoDB的逻辑存储结构为:

  • 表空间 tablespace,InnoDB 存储引擎逻辑结构的最高层,默认 ibdata1。
  • 段 segment,包含数据段、索引段等。数据段即为 B+ 树的叶子节点,索引段即为 B+ 树的非叶子节点。
  • 区 extent,是由连续页组成的空间,区的大小 1MB。为保证区中页的连续性。默认情况下,InnoDB 页大小 16K,即一个区中共有64个连续页。
  • 页 page 或 block
  • 行 Row,数据是按行进行存放的。

页是 InnoDB 磁盘管理的最小单位,常见的页类型有。

  • 数据页
  • undo 页
  • 未压缩的二进制大对象页 Uncompressed BLOB page
  • 压缩的二进制大对象页 compressed BLOB page

InnoDB 提供了 Compact 和 Redundant 两种格式来存放行记录数据。其中 Redundant 是为兼容老版本而保留,建议使用 Compact格式。Compact 行记录存储方式如下,

73f1238f459b6e8861095d1b59d8241e.png

可以看出变长字段和 NULL 是两种特殊的类型。变长字段不超过两字节,因为 MySQL 中的 varchar 最多 65535 长。
每行数据还有两个隐藏列,事务 ID 列和回滚指针列。分别为 6 字节和 7 字节。若 InnoDB 表没有定义主键,每行还会增加一个 6 字节的 rowid 列。


varchar(15),char(15),int(15) 分别代表什么?

  • varchar(15),字符总长 15 字节。根据编码不同,每个字可能由多个字节构成。
  • char(15),同上,区别是不足的空位将由 0x20 强行补齐。
  • int(15),用 0 往前补齐位数。

InnoDB 支持,

  • B+ 树索引
  • 全文索引
  • 哈希索引

B+ 树索引最为常见,使用也最为频繁。B+ 树索引不能找到具体行,只能找到所在页。然后把页读入内存再进行查找。B+ 树的数据只保存在叶子上,叶子靠双向链表连接可以顺序很方便做数据的范围扫描。

B+ 树索引分为聚集索引和辅助索引,二者的区别是聚集索引的叶子节点里的是全信息,辅助索引里的是主键。

聚集索引(聚簇索引)

InnoDB 表中数据按照主键顺序存放,也就是按照聚集索引构造一颗 B+ 树,叶子结点中存放数据总和的就是整张表的行记录数据,一个个的叶子节点就是一个个数据页。这也是为什么一张表只有一个聚集索引。

辅助索引

非聚集索引,也叫辅助索引,Secondary Index,不保证唯一性。,其叶子节点包含一个书签,该书签就是相应行的聚集索引键。

69e3ea531c88e6e0e8287cdeb348d4db.png

当通过辅助索引来寻找数据时,InnoDB 会通过辅助索引的叶子节点获得的主键,然后再通过主键索引找到完整的行记录。辅助索引不影响数据在聚集索引中的组织。因此一个表可以由多个辅助索引。

那么应该在哪些列添加辅助索引比较合适呢?

一般来说,索引应该是高选择性的而非低选择性的,如性别就不适合,姓名就适合。

自行创建的索引,如联合索引、唯一索引等都属于非聚簇索引。

联合索引是用多个字段来创建辅助索引,使用时 where 条件的顺序必须和索引顺序一致。

索引覆盖 Coving Index 指的是假设需要的数据恰好在辅助索引 B+ 树上能完整获得,那就不用聚集索引查询。索引覆盖的好处是辅助索引大小远远小于聚簇索引,可以减少大量的 IO 操作。

B+ 树索引可以实现前缀查找,这是因为在 B+ 树中进行索引插入的时候会进行主键比较,那么前缀比较自然也是可行的。如,

select * from blog where content like 'xxx%';

但在更多情况下,在博客或搜索引擎中需要查询的是某个单词,而不是某个单词开头,如,

select * from blog where content like '%xxx%';

此时如果使用 B+ 树索引依然只能进行全表扫描。


下面说明一下索引优化机制,

MRR Multi-Range Read 优化,MySQL 5.6 中引入了 MRR 来优化二级索引的范围扫描并且需要回表的情况。它的原理是,将多个需要回表的二级索引根据主键进行排序然后一起回表,将原来的回表时进行的随机IO,转变成顺序 IO。

建立外键的时候,InnoDB 自动增加索引。不只是因为可以提升查找性能,还因为外键列上无索引会导致死锁。

当外键父表要删除某一个数据的时候,为了维持外键的数据完整性,它不得不对子表进行查询,并删除子表中对应的表项。在极限情况,事务 A 持有子锁申请父锁,事务 B 持有父锁却因为外键关系级联申请表锁,产生死锁。如果此时子表有索引,事务 B 就不需要申请子锁了,它可以快速地根据索引定位行,申请行锁就行了。


自适应哈希索引

在 Hash 树中查询比在 B+ 树中要快得多,大概是 1 次和 3 - 4 次的区别。

InnoDB 会监控表上索引页的查询并统计所有的查询类型,如果访问类型都是 == 查询,则自动建立哈希索引。


全文索引

全文检索 Full-Text Search 是将整本书或文章内任意内容检索出来的技术。

倒排索引

全文索引通常使用倒排索引 Inverted Index 实现,倒排索引将分词 word 存储在一个辅助表 Auxiliary Table 中,为了提高全文检索的并行性能,共有 6 张辅助表,根据 word 的编码q区分。辅助表中存储了单词和单词在各行记录中位置的映射关系。它分为两种:

  • inverted file index 倒排文件索引,表现为{单词,单词所在文档 ID}
  • full inverted index 详细倒排索引,表现为{单词,(单词所在文档 ID, 文档中的位置)}

InnoDB 从 1.2 版本开始支持全文索引的技术,其采用 full inverted index 的技术。在InnoDB 中将(documentid, position)视为一个 ilist。在全文索引的表中有两个列,一个是 word 字段,另一个是 ilist 字段,在 word 字段上设有索引。

InnoDB 的全文索引还存在以下限制,

  • 每张表只能有一个全文索引
  • 由多列组合而成的全文索引必须使用相同的字符集与排序规则。
  • 不支持没有单词界定符的语言,如中文,日语,韩语等,但从 MySQL 5.7 开始内置了ngram 全文检索插件,用来支持中文分词。

上面说明了 InnoDB 的基本工作流程,下面来看看它引入的关键特性。

插入缓冲

如果按照非聚集索引去查询一个不唯一的数据项,由于数据是按照聚集索引组织的,索引性能较低。

InnoDB 开创性地提出了 Insert Buffer 也就是插入缓冲。将非聚簇索引的插入方式修改为如果缓存池中没有索引,则是插入数据缓冲到一个 Insert Buffer 对象中,一段时间后将一组 Insert Buffer 进行合并一起刷新到磁盘文件里面的。

很明显,聚簇索引不需要插入缓冲。保证唯一性的非聚簇索引也不用插入缓冲。因为插入缓存的目的是不去进行离散查找直接插入数据,而唯一性的保证可能需要大量查找比对,反而失去了意义。

InnoDB 在 1.0.x 版本引入了 Change Buffer,其包含了Insert Buffer,Delete Buffer, Purge Buffer。

两次写(Double Write)

缓冲池中脏页在写入磁盘时,可能会受到宕机的影响导致脏页数据未完全写入磁盘,导致数据丢失。这个时候 Redo日志是无效的,因为 Redo 日志记录的是对页的物理操作,但是这个时候可能发生的是页损坏。先建立一个页的副本,再根据 Redo 日志恢复。

为了解决这个问题,InnoDB 引入了double-write机制。脏页数据会先写入 double-write 缓冲区 double write buffer 中进行完备的页缓存,然后才会真正写入到数据存储的磁盘中。

自适应Hash索引

异步 IO

刷新临近页 Flush Nerghbor Page

用于传统硬盘,刷新一个脏页时顺便刷新本分区的所有页。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值