03-如何建表更符合业务

文章详细介绍了InnoDB存储引擎中索引组织表的概念,主键和唯一索引的定义,以及B+树作为索引的数据结构。InnoDB中,表根据主键顺序组织,主键若不存在,系统会自动生成。B+树是主流的数据库索引算法,适合大数据量的快速查找。文章还讨论了不同类型的索引、数据存储结构如表空间、段、区、页和行,以及行记录格式和数据约束方法。
摘要由CSDN通过智能技术生成

1、什么叫索引组织表?

1.1、索引组织表的概念

1、索引组织表不是一种“组织表〞。
2、索引组织表是由索引 “组织起来的〞表。
3、InnoDB中,表都是根据主键顺序组织存放的。

1.2、索引 (Index)

1、索引是数据库中对某一列或多个列的值进行预排序的数据结构。
2、索引可以理解为数据的 “目录〞。
3、InnoDB中,主键是一个特殊索引字段。主键ID不是主索引,主键ID进行排序生成的叫主索引。

1.3、主键 (Primary Key)

1、InnoDB存储引擎表中,每张表都有一个主键。
2、若表中有一个非空唯一索引 (Unique NOT NULL),即为主键。
3、若有多个非空唯一索引,选择第一个定义的索引。
4、若无,InnoDB自动创建一个6字节的指针,作为主键。

1.3.1、演示主键

1、下面的SQL建表语句中,哪一列是主键?

CREATE TABLE my_test (a INT NOT NULL,b INT NULL,c INT NOT NULL,d INT NOT NULL,
UNIQUE KEY (b),UNIQUE KEY (d),UNIQUE KEY (c) );

答案:没有设置primary key 的情况下,b、c、d都是唯一索引,b可以为空,所以排除,c、d都是唯一索引并且不为空,因为d先声明的,所以唯一索引是d。

过程:

>创建数据库:右键->新建数据库。 

字符集:utf8mb4。

排序规则:utf8mb4_general_ci。

>创建数据表

//创建数据表
CREATE TABLE my_test (a INT NOT NULL,b INT NULL,c INT NOT NULL,d INT NOT NULL,
UNIQUE KEY (b),UNIQUE KEY (d),UNIQUE KEY (c) );

>查看my_test的详细信息

-- 查看my_test的详细信息
DESC my_test;

 1.4、总结

1、InnoDB数据表均为索引组织表。
2、索引组织表中的数据,被主键的索引组织起来。

2、B+ 树

Innodb的索引组织表的索引用的算法:B+ 树。

2.1、主流索引查找算法

1、线性查找 Linear Search
2、二分查找 Binary Search
3、二叉查找树 Binary Search Tree
4、平衡二叉树 AVL Tree
5、B树   B Tree
6、B+ 树    B+ Tree  

2.1.1、数据结构可视化

https://www.cs.usfca.edu/~galles/visualization/Algorithms.html

旧金山大学数据结构可视化页面。

2.1.2、线性查找 Linear Search

1、时间复杂度O(N)

        n 的值为多少,程序就运行多少次,类似于下图:


2、从第一个数据开始,逐个匹配。

 

 2.1.3、二分查找 Binary Search

1、时间复杂度O(logN)。
2、拿出有序数列中点位置作为比较对象。
3、根据中点数据大小,选取一半数据作为新的数列。
4、每次可以将数据量减小一半。

缺陷:磁密中的数据不是连续读写的,我们不知道中间的那个数据在哪里,所以这个二分查找就很
麻烦。

2.1.4、二叉查找树 Binary Search Tree

1、时间复杂度O(logN)。
2、使用经典的二叉树数据结构。
3、由根节点开始查找。
4、可能退化为线性查找。

2.1.5、平衡二叉树 AVL Tree 

1、查找时,与二叉查找树相同。
2、增删改时,通过旋转操作,维护树的平衡。
3、AVL树可以保证不会退化成线性查找。

演示:我们在插入一个数据66,他会进行旋转操作,维护树的平衡。

 

4、平衡二叉树效率已经非常高了,索引为什么不使用平衡二叉树?

        内存、硬盘的读写的最小基本单位,机器硬盘最小512B,SSD最小是4k,或8k,一个节点存放的数据占用4k,是不可行的。节点放的数据太少。

2.1.6、B树   B Tree

1、B树的结构

2、B树是线性数据结构和树的结合。
3、B树通过多数据节点大大降低了树的高度。
4、B树不需要旋转就可以保证树的平衡。

5、缺点:

        范围查找的时候效率非常慢。

2.1.7、B+ 树    B+ Tree  

1、B+树是由B树发展而来的一种数据结构。
2、B+树的所有数据均在叶子节点
3、B+树的所有数据形成了一个线性表 

2.1.8、总结

1、B+树是目前最主流的数据库索引算法。
2、B+树由线性表、二叉树、B树发展而来。
3、B+树集成了线性表、平衡二叉树的优势。

3、为什么说InnoDB索引即数据?

3.1、B+树索引

1、InnoDB使用B+树作为索引的数据结构。
2、B+树的高度一般为2-4层,查找速度非常快。

        一个节点就可以存上万条数据,2到4层就可以实现几百万条数据。
3、InnoDB索引分为聚族索引(主索引) 和辅助索引。

3.1.1、聚簇索引 Clustered Index

1、根据表的主键构造一个B+树。
2、叶子节点直接存放行数据,而不是指针。
3、索引组织表中,数据也是B+树的一部分

         数据也放到了主索引的位置,所以叫聚簇索引。

3.1.2、辅助索引 Secondary Index

1、每张表可以有多个辅助索引。
2、叶子节点并不包含行数据。
3、叶子节点记录了行数据的主键,用来指示数据位置。

3.1.3、回表

辅助索引存的是主键的地址,我们根据主键id的地址,在去聚簇索引中搜索这一条数据。

3.2、总结

1、InnoDB索引分为聚族索引(主索引) 和辅助索引。
2、在同层B+树节点之间,为双向链表。
3、在B+树节点之内,数据条目之间为单向链表。
4、所谓索引即数据,是把数据直接记录在了主索引里。

4、InnoDB数据表是如何存储的?

1、InnoDB的逻辑存储结构为表空间、段、区、页、行。
2、InnoDB的逻辑存储结构充分考虑了以基于B+树的表结构。
3、InnoDB中的页是lnnoDB自身的逻辑概念,与硬件的页无关。

4.1、表空间 (tablespace    也叫idb文件)

1、表空间指的是数据表在硬盘上的存储空间。
2、默认,所有表的数据都存在共享表空间。
3、每个表的数据也可以放在独占表空间(ibd文件)。

        配置独占表空间:当表崩溃、进行恢复的时候就会很方便。

4.2、段 (segment)

InnoDB中,段由存储引擎自动管理。

4.3、 区 (extent)

1、区是由连续页组成的空间,大小为1MB。
2、一次从磁盘申请4~5个区。
3、一般来讲含有64个页 (Page)。

 4.4、页 (page)

1、页是InnoDB中磁盘读写的最小逻辑单位,默认16KB。
2、一个数据页就是一个B+树的节点 (B+ Tree Node)。
3、的大小充分考虑了机械硬盘和SSD的最小单元 (512B和4KB)。

4、page与page之间使用指针进行关联。

5、为什么页不能太大,比如16MB?

> 一次将磁密空间16MB读到内存中,磁盘压力太大;

> 16MB的数据量大大,因为这个页是链表结构,如果找一条数据太困难。
6、为什么页不能太小,比如16B?

        机械硬盘和SSD的最小单元(512B和4KB),如果页太小的话,这个页就占不满机械硬盘和SSD的最小单元,就会照成浪费。

4.5、 数据行

4.5.1、InnoDB中的变长列

1、长度不固定的数据类型:
VARCHAR, VARBINARY(存的二进制), BLOB(二进制), TEXT
不常用

> 占用空间大于768Byte的不变长类型: CHAR
> 变长编码下的 CHAR

4.5.2、行溢出数据

1、由于InnoDB每个数据页容量有限,导致数据字段也是有限的。
2、当数据字段过大时,InnoDB会使用行溢出机制。
3、行溢出机制会把超长字段放入单独开辟的BLOB页。

 解决方案:

4.6、InnoDB行记录格式 Row Format

1、InnoDB行记录格式主要分为两个时代:
Redundant / Compact (Antelope 文件格式)了解
Dynamic / Compressed (Barracuda 文件格式)

2、行记录格式进化的核心需求是节约行记录空间。
3、节约行记录空间从而增加每个页的数据行数,提高查询效率。

4.6.1、Dynamic

MySQL 5.7之后默认的Row Format。

 4.6.2、Compressed(了解)

物理结构上与Dynamic类似。

5、索引有哪些  "左侧用法"  ?

5.1、联合索引

1、使用两个或以上字段生成的索引。
2、联合索引也可以加速  “最左前缀〞的查询。
3、联合索引可以代替最左侧字段的单独索引。

 5.2、字符串的前缀索引

1、如果字符串过长,可以考虑使用前缀索引节约空间。        比如邮箱地址。
2、如果前缀区分度太小,可以考虑两种变通方法                   比如身份证号码
        > 倒序存储
        > 新建Hash字段,将原来的字段hash到这个字段。
3、创建方式: alter table user add index index2(email(6))

5.3、字符串like

1、( like %关键字% )( like %关键字 )会使索引失效。

        如果数据量大,要就行全局搜索的时候,可以使用es搜索引擎。
2、( like 关键字%)左模糊才可以使用索引。

6、如何约束数据?

InnoDB约束数据的方法:
1、Primary Key / Unique Key
2、Foreign Key
3、Default / NOT NULL
4、触发器

6.1、Primary Key / Unique Key

1、通过将数据字段设置为索引,约束数据内容
2、Primary Key:唯一,不为NULL
3、Unique Key:  唯一

4、唯一约束插入时的性能开销较大,插入数据的时候会进行校验。

6.2、Foreign Key

1、外键可以对数据的正确性实现约束

公司中谨慎使用。数据修复、恢复的时候会有很多问题。

6.3、Default / NOT NULL

1、Default :数据默认值。
2、NOT NULL:数据不为空。

3、如果这个字段要建辅助索引的时候,就要让这个字段不能为null。因为效率会很低。

4、MySQL在严格模式下开启NOT NULL这种行为,不能插入null;不严格模式下这个字段设置为NOT NULL也可以插入null。

查看MySQL是否开启严格模式:SHOW VARIABLES LIKE 'innodb_strict_mode';

6.4、触发器

1、插入、修改数据时,使用触发器校验数据。
2、容易千扰业务,使用很少

7、如何使用不存在的数据表?

7.1、视图 View

1、使用视图可以创建不存在的虚拟表。
2、视图的原理是预设一个SELECT语句。
3、SELECT语句的查询结果作为虚拟表的数据。

7.2、视图算法的选择

1、MERGE, 将视图SQL合并到主查询SQL中。
2、TEMPTABLE,将视图作临时表(中间结果) 来处理。
3、一般来讲,MERGE的性能优 于TEMPTABLE。

eg:数据表my_test如图所示:

 -- 创建视图myView2
CREATE ALGORITHM=MERGE VIEW myView2 AS SELECT * from my_test WHERE c > 20;

-- 查询视图
SELECT * FROM myView2 WHERE a = 11;

实际执行的时候SQL会merge到一起,查询视图执行的SQL语句就相当于:SELECT * from my_test WHERE c > 20 AND a = 11;

7.3、无法使用MERGE的SQL

聚集函数
DISTINCT
GROUP BY
HAVING
UNION, UNION ALL
子查询

8、理论和实际中的规范

1、理论:增加每页(page)数据量:
     实际规范:       

                尽量做到冷热数据分离,减小表的宽度。
                优先选择符合存储需要的最小的数据类型。

2、理论:避免行溢出:
      实际规范:       

                把BLOB 或是 TEXT列分离到单独的扩展表中。
                禁止在数据库中存储图片,文件等大的二进制数据。

3、理论:控制B+树高度:
     实际规范:     

                尽量控制单表数据量的大小,建议控制在 500 万以内。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值