首页 > 社交 > 科普中国

MySQL索引原理篇:深入数据库底层揭开索引机制的神秘面纱

常驻编辑 科普中国 2022-10-08 索引   节点   字段   面纱   指针   底层   磁盘   机制   神秘   过程   类型   结构   数据库   引擎   数据
dDi拜客生活常识网

二、建立索引时那些不为人知的内幕

弄明白了索引的底层数据结构后,再一起来聊一聊创建索引后会发生什么事情呢?一般我们都会以下述方式创建索引:dDi拜客生活常识网

-- ①通过CREATE语句创建
CREATE INDEX indexName ON tableName (columnName(length) [ASC|DESC]);
-- ②通过ALTER语句创建
ALTER TABLE tableName ADD INDEX indexName(columnName(length) [ASC|DESC]);
-- ③建表时通过DML语句创建
CREATE TABLE tableName(  
  columnName1 INT(8) NOT NULL,   
  columnName2 ....,
  .....,
  INDEX [indexName] (columnName(length))  
);
复制代码

在咱们通过SQL命令创建索引时,MySQL首先会判断一下当前表的存储引擎,索引机制本身是由存储引擎层提供实现的,不同的引擎实现的索引也不同,因此创建索引时第一步就会先判断存储引擎,然后根据不同的存储引擎创建索引,这里重点聊一下常用的MyISAM、InnoDB。dDi拜客生活常识网

2.1、常用存储引擎的数据存储

首先为了能够实际观察到两个引擎之间的区别,分别使用MyISAM、InnoDB两个引擎创建两张表:dDi拜客生活常识网

-- 创建一张使用MyISAM引擎的表:zz_myisam_index
CREATE TABLE `zz_myisam_index`  (
  `z_m_id` int(8) NOT NULL,
  `z_m_name` varchar(255) NULL DEFAULT ''
) 
ENGINE = MyISAM 
CHARACTER SET = utf8 
COLLATE = utf8_general_ci 
ROW_FORMAT = Compact;

-- 创建一张使用InnoDB引擎的表:zz_innodb_index
CREATE TABLE `zz_innodb_index`  (
  `z_i_id` int(8) NOT NULL,
  `z_i_name` varchar(255) NULL DEFAULT ''
) 
ENGINE = InnoDB 
CHARACTER SET = utf8 
COLLATE = utf8_general_ci 
ROW_FORMAT = Compact;
复制代码

上述过程中创建了两张表:zz_myisam_index、zz_innodb_index,分别使用了不同的引擎,而MySQL中对于所有的数据都会放入到磁盘中存储,因此先来找一下这两张表的本地位置,默认位于C:ProgramDataMySQLMySQL Server 5.xdata这个目录中,在这里保存着所有已创建的数据库磁盘文件,首先从这里面找到对应的数据库并进入目录,如下:dDi拜客生活常识网

dDi拜客生活常识网


dDi拜客生活常识网

2.1.1、使用MyISAM引擎的表

zz_myisam_index这张表是使用MyISAM引擎的表,在磁盘中有三个文件:dDi拜客生活常识网

  • zz_myisam_index.frm:该文件中存储表的结构信息。
  • zz_myisam_index.MYD:该文件中存储表的行数据。
  • zz_myisam_index.MYI:该文件中存储表的索引数据。

也就是说,MyISAM引擎的表数据和索引数据,是分别放在两个不同的磁盘文件中存储的,这也意味着MyISAM引擎并不支持聚簇索引,因为聚簇索引要求表数据和索引数据一起存储在同一块空间,而MyISAM的.MYI索引文件中,存储的是表数据所在的地址指针。dDi拜客生活常识网

2.1.2、使用InnoDB引擎的表

zz_innodb_index这张表是使用InnoDB引擎的表,在磁盘中仅有两个文件:dDi拜客生活常识网

  • zz_innodb_index.frm:该文件中存储表的结构信息。
  • zz_innodb_index.ibd:该文件中存储表的行数据和索引数据。

因为InnoDB引擎中,表数据和索引数据都一起放在.ibd文件中,也就代表着索引数据和表数据是处于同一块空间存储的,这符合聚簇索引的定义,因此InnoDB支持聚簇索引。dDi拜客生活常识网

同时也正由于这个原因,所以如果使用InnoDB引擎的表未主动创建聚簇索引,它会自动选择表中的主键字段,作为聚簇索引的字段。但如果表中未声明主键字段,那则会选择一个非空唯一索引来作为聚簇索引。但如果表中依旧没有非空的唯一索引,InnoDB则会隐式定义一个主键来作为聚簇索引(这个列在上层是不可见的,是一个按序自增的值)。dDi拜客生活常识网

OK~,搞明白两种常用引擎的底层存储区别后,接下来再聊聊手动创建索引后究竟会发生什么?dDi拜客生活常识网

2.2、手动创建索引后发生的事情

当手动创建索引后,MySQL会先看一下当前表的存储引擎是谁,接着会判断一下表中是否存在数据,如果表中没有数据,则直接构建一些索引的信息,例如索引字段是谁、索引键占多少个字节、创建的是啥类型索引、索引的名字、索引归属哪张表、索引的数据结构.....,然后直接写入对应的磁盘文件中,比如MyISAM的表则写入到.MYI文件中,InnoDB引擎的表则写入到.ibd文件中。

相关阅读:

  • 如何建立索引(数据库中表属性的默认值)
  • 如何建索引(界面方式创建索引)
  • word目录怎么做索引,word文档怎么做索引目录
  • POI导入导出百万级数据Excel
  • MySQL专题1:
  • MongoDB高并发下的upsert问题
  • 面渣逆袭:MySQL六十六问,两万字+五十图详解!有点六
  • MySQL
  • 索引和目录的区别是什么
  • lucene学习
    • 网站地图 |
    • 声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。文章内容仅供参考,不做权威认证,如若验证其真实性,请咨询相关权威专业人士。