首页 > 其他分享 >索引组织表和堆表索引结构

索引组织表和堆表索引结构

时间:2024-10-10 22:34:49浏览次数:7  
标签:组织 gavin 索引 mysqldb key test 表和堆 主键

18. 索引组织表

 

在InnoDB存储引擎中,Row都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表(index organized table),或者叫聚集索引(clustered index) 

  1. 每张表必须有一个主键
  2. 根据主键的值构建一个B+树
  3. 这颗B+树的叶子节点存放所有记录
  4. 非叶子节点存放主键和指针(若干个{主键,指针}组成一个非页节点)
    1. 这里指针其实就是PageNumber,这个PageNumber就是下一层节点的PageNumber(这里不需要SpaceID,因为SpaceID对应的是ibd文件,我们现在是在ibd文件内部查找数据)

 

主键

如果创建表的时候没有显示指定主键,则InnoDB会按照如下方式选择或创建主键

  1. 判断表中是否有非空唯一索引,如果有,该列为主键
    1. 如果存在多个非空唯一索引,以创建表时第一个定义的非空唯一索引为准,而不是(columns)定义的顺序
  2. 如果上述条件都不符合,则InnoDB自动创建一个6字节大小的主键

主键实验

  • 多个非空唯一键
    root@mysqldb 13:35:  [gavin]> create table test_key(
        -> a int,  -- int类型
        -> b int not null, 
        -> c int not null,
        -> unique key(a),
        -> unique key(c),  -- C列先定义
        -> unique key(b)
        -> );
    Query OK, 0 rows affected (3.01 sec)
    
    root@mysqldb 13:37:  [gavin]> insert into test_key values(1,2,3),(4,5,6),(7,8,9);
    Query OK, 3 rows affected (0.00 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    root@mysqldb 13:38:  [gavin]> select *, _rowid from test_key;
    +------+---+---+--------+
    | a    | b | c | _rowid |
    +------+---+---+--------+
    |    1 | 2 | 3 |      3 |
    |    4 | 5 | 6 |      6 |
    |    7 | 8 | 9 |      9 |
    +------+---+---+--------+
    3 rows in set (0.00 sec)
    
    root@mysqldb 13:41:  [gavin]> create table test_key_2 (
        -> a varchar(8), -- 使用varchar类型
        -> b varchar(8) not null,
        -> c varchar(8) not null,
        -> unique key(a),
        -> unique key(c),
        -> unique key(b)
        -> );
    Query OK, 0 rows affected (0.01 sec)
    
    root@mysqldb 13:41:  [gavin]> insert into test_key_2 values('a','b','c'),('d','e','f'),('g','h','i');
    Query OK, 3 rows affected (0.00 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    root@mysqldb 13:41:  [gavin]> select *, _rowid from test_key_2;    -- _rowid只能是在key的类型为整型时才有效
    ERROR 1054 (42S22): Unknown column '_rowid' in 'field list'
    
    -- 可以用下面的方法查看
    -- 方法1
    root@mysqldb 13:42:  [information_schema]> select * from information_schema.COLUMNS where table_name='test_key_2' and column_key='PRI'\G
    *************************** 1. row ***************************
               TABLE_CATALOG: def
                TABLE_SCHEMA: gavin
                  TABLE_NAME: test_key_2
                 COLUMN_NAME: c
            ORDINAL_POSITION: 3
              COLUMN_DEFAULT: NULL
                 IS_NULLABLE: NO
                   DATA_TYPE: varchar
    CHARACTER_MAXIMUM_LENGTH: 8
      CHARACTER_OCTET_LENGTH: 32
           NUMERIC_PRECISION: NULL
               NUMERIC_SCALE: NULL
          DATETIME_PRECISION: NULL
          CHARACTER_SET_NAME: utf8mb4
              COLLATION_NAME: utf8mb4_0900_ai_ci
                 COLUMN_TYPE: varchar(8)
                  COLUMN_KEY: PRI
                       EXTRA: 
                  PRIVILEGES: select,insert,update,references
              COLUMN_COMMENT: 
       GENERATION_EXPRESSION: 
                      SRS_ID: NULL
    1 row in set (0.00 sec)
    
    -- 方法2
    root@mysqldb 13:44:  [gavin]> desc test_key_2;
    +-------+------------+------+-----+---------+-------+
    | Field | Type       | Null | Key | Default | Extra |
    +-------+------------+------+-----+---------+-------+
    | a     | varchar(8) | YES  | UNI | NULL    |       |
    | b     | varchar(8) | NO   | UNI | NULL    |       |
    | c     | varchar(8) | NO   | PRI | NULL    |       |
    +-------+------------+------+-----+---------+-------+
    3 rows in set (0.00 sec)

 

  • 系统定义主键
    root@mysqldb 13:50:  [gavin]> create table test_key_3(
        -> a int,
        -> b int,
        -> c int);
    Query OK, 0 rows affected (0.01 sec)
    
    root@mysqldb 13:51:  [gavin]>  insert into test_key_3 values(1,2,3),(4,5,6),(7,8,9);
    Query OK, 3 rows affected (0.01 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    root@mysqldb 13:51:  [gavin]> select *,_rowid from test_key_3;    -- 这里无法用_rowid查看,因为系统rowid对用户是透明的
    ERROR 1054 (42S22): Unknown column '_rowid' in 'field list'

假设有a和b两张表都使用了系统定义的主键,则系统定义的主键的ID不是在表内进行单独递增的,而是全局递增 。
该系统的rowid是定义在ibdata1.ibd中的sys_rowid中,全局自增
6个字节表示的数据量为 2^48 ,通常意义上是够用的

注意:强烈建议自己显示定义主键 

 

索引组织表与堆表

  • 堆表

堆表将索引和数据分开(如MyISAM),索引中叶子节点存放的是数据的位置,而不是数据本身

 

  • 索引组织表

索引组织表将索引和数据放在了一起,索引的叶子节点(leaf page)存放了所有完整的记录(Row)。
索引即数据,数据即索引

注意:

1. 非叶子节点(Non-leaf page)中不会存放所有的数据(Row)的 {主键, PageNumber},而是从叶子节点(leaf page)中选出一个数据的主键,将这个主键和该页的PageNumber填入到非叶节点(Non-leaf page)中
2. 从逻辑上看,是一棵B+树,但是从物理上看都是每个页(非叶子节点和叶子节点)通过指针串在一起,使得逻辑有序。

 

  • 二级索引

二级索引中的叶子节点不存放数据本身,而是存放主键 

 

  • 查询数据对比
    • 堆表查询

    • 索引组织表及二级索引查询

 

Page的空间申请

  • 叶子节点(leaf page) 由 leaf page segment 进行申请空间
  • 非叶子节点(Non-leaf page) 由 Non-leaf page segment 进行申请空间

所以索引由两个段组成

  • leaf page segment
  • Non-leaf page segment

段(segment)是由区(extent)组成,申请空间就按照区(extent)进行申请(一般情况下一次申请4个区) 

 

引用:
https://www.cnblogs.com/gavin-zheng/p/18127784

标签:组织,gavin,索引,mysqldb,key,test,表和堆,主键
From: https://www.cnblogs.com/hsjz-xinyuan/p/18457333

相关文章

  • 一文搞懂SaaS业务架构:价值流、业务能力、业务流程、业务对象、组织架构
    1目标与步骤2价值流分析2.1从价值主张到价值流2.2价值流的概念2.2价值流如何识别?2.3价值流阶段如何识别?3业务流程3.1业务流程的概念3.2端到端流程3.3职能流程3.4示例:零售企业的业务流程4业务能力4.1业务能力的概念4.2业务能力的构成4.3业务流程与业......
  • MySQL事务、索引、数据恢复和备份
    1事务1.1事务介绍事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。就比如:张三给李四转账1000块钱,张三银行账户的钱减少1000,而李四银行账户的钱要增加1000。这一组......
  • MySQL的索引
    MySQL索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可提高数据库中特定数据的查询效率。本节将介绍索引的含义、分类和设计原则。7.1.1索引的含义和特点索引是一个单独的、存储在磁盘上的数据库结构,包含了对数据表里所有记录的引用指针。使用索引可以快速找出在......
  • 查询优化器选错索引:问题分析与解决方案详解
    引言在现代数据库系统中,查询优化器是负责决定如何执行SQL查询的核心组件。它会根据查询语句、数据分布、索引情况等,选择最优的执行计划。然而,查询优化器并不总是能够做出最佳选择,某些情况下可能会选择一个不理想的索引,从而导致查询性能下降。当查询优化器选错索引时,如何......
  • 联合索引:何时使用及如何优化
    引言在数据库优化中,索引的设计是影响查询性能的关键因素之一。联合索引(CompositeIndex)是指在多个列上创建的组合索引,它可以同时覆盖多个查询条件,从而提高复杂查询的效率。然而,何时应该使用联合索引?如果查询中只有一个条件,是否有必要创建联合索引?这是很多数据库设计者在实......
  • 创建索引时需要考虑的关键问题详解
    引言在数据库中,索引是加快数据查询速度的重要工具。通过索引,数据库可以快速定位需要的数据,而无需扫描整个表的数据。尽管索引能极大提高查询效率,但不合理的索引设计也可能导致性能下降,甚至增加不必要的系统开销。尤其在高并发的大规模数据系统中,索引的设计与优化直接关系到......
  • InnoDB 和 MyISAM 的索引结构区别详解
    引言在MySQL中,索引是提升数据库查询性能的关键组成部分。通过索引,数据库可以快速定位记录,而无需扫描整个表的数据。MySQL中的两个常用存储引擎——InnoDB和MyISAM都提供了索引功能,但它们在底层的索引结构上有显著的区别。这些区别不仅影响性能,还影响事务支持、数据一......
  • 植物学复习:植物各部分组织的中英文名称
    来源:soybeaninformations......
  • 探索MySQL的InnoDB索引失效
    MySQL8+InnoDB- 序章索引失效,发生在已经建立索引,但是,查询(SELECT)时没有用到建立的(预期会用到)索引的情况下。失效原因有两个方面:1、建立索引的方式错误需要弄清楚 字段的#区分度(极其重要)这个概念。选择区分度高的建立索引。2、某些SELECT语句不支持使用索引注意,......
  • zoomeye类似搜索引擎和子域名搜索
    与zoomeye类似的搜索引擎[fofa][网络空间测绘,网络空间安全搜索引擎,网络空间搜索引擎,安全态势感知-FOFA网络空间测绘系统](https://fofa.info/)[Shodan][https://www.shodan.io](https://www.shodan.io/)[Censys][https://search.censys.io](https://search.censys.io/)子......