暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL索引和表结构

MySQLDBA修炼之路 2019-05-12
954

MySQL的innodb采用索引组织表,索引是树结构

二叉树概念每个父节点的子节点个数都为2顶端的节点:根节点树的高度:根节点到叶子节点的高度叶子节点:最下面的节点是树的叶子节点

二分法查找:必须要求数据是有序的

假如有⼀组数为3,12,24,36,55,68,75,88要查给定的值24那么⼆分法查找是怎么做的呢3,12,24,36,55,68,75,883,12,24,3624 3624

二叉树

B-tree

B+tree

B*tree

二叉树的缺点:二叉树的每个父节点的子节点都需要有2个,最多也是2个;1、二叉树的高度不可控2、查询的过程中IO不可控在树结构中,每个高度需要一次IOBTree叶子节点和最下面的非叶子节点,最大的高度差不超过1在叶子节点和非叶子节点都存储数据不是二叉树

B+Tree mysql使用的结构1、只在叶子节点存储数据2、叶子节点数据必须要经过排序3、叶子节点之间有指针

B*Tree在非叶子节点之间,也有横向的指针

MySQL表结构Innodb这块--聚簇索引表(由索引构成的表结构)整个表就是一个索引,构成表的索引叫聚簇索引(cluster-index)聚簇索引的构成 ,基础的数据结构--B+TREE  balanace + btree

构建条件1.有主键的情况下,是通过主键进行构建的,会对主键进行排序2.如果没有主键,如果有唯一性非空索引,就通过索引构建3.如果都没有,mysql innodb会自动创建一个隐藏列(6字节)来构建聚簇索引

主键的优化1、尽量使用自增主键,避免排序,可以提高数据页的空间利用率,提高查询效率2、如果不能使用自增主键,那么可以使用int类的主键类型3、尽量避免使用char或者varchar text等字符类型的主键

自增主键

建表直接设置create table tb1( id int auto_increment, name varchar(11), primary key (id));alter table test modify id integer auto_increment;

| auto_increment_increment    | 1     |步长| auto_increment_offset       | 1     |起始值

MySQL innodb和myisam的自增的区别innodb不会持久化自增数据myisam会持久化自增数据

1234。。。--15--16--17重启再次插入数据innodb 插入的是15myisam         18

数据⻚定位数据记录的过程在⾮叶⼦节点查找数据到叶⼦节点后,并⽆法定位数据,在数据⻚中有⼀部分叫做page directory,该部分记录了每个数据⽬录在数据⻚中的偏移量,知道偏移量后,进⾏⼆分法查找,就可以找到了具体的数据记录

辅助索引优点:可以索引非主键列的数据,在使用非主键列作为筛选条件的时候,提供索引支持辅助索引的叶子节点:索引列的值+主键值使用到辅助索引的sql,查询场景select name from emp where name='cjr'可以直接通过辅助索引进行查询返回结果,不需要通过主键索引进行查询只通过辅助索引就可以返回数据的这种情况,叫做覆盖索引,(扫描情况,不是索引类型)select * from emp where name='cjr';1、首先通过name=‘cjr’在辅助索引上定位数据,定位数据完成后,在叶子节点获取到name=‘cjr'的对应的主键值2、获取完成后,根据在辅助索引上获取的主键值,返回聚簇索引,然后进行查询 create table t1 ( id int not null, name varchar(11), primary key (id) );

使用主键索引,如下却进行了全表扫描

在name上构建索引,也就是辅助索引,实际上走的时覆盖索引,因为辅助索引上有主键值,只有2列Extra: Using index表示使用了覆盖索引key表示使用索引

普通索引alter table t1 add index idx_t1(name);alter table t1 drop index idx_t1;

唯一索引alter table t add unique idx_t1(name);唯一索引室友唯一性的,就有唯一约束,不能插入相同的数据

全⽂索引,不⽀持中⽂,使⽤较少alter table t1 add fulltext idx_t1(name);

索引的优点1.可以优化某些查询语句,提高查询效率,避免全表扫描2.可以优化某些dml语句的定位的阶段,可以使用索引update 定位数据 where id=1缺点在dml或者ddl操作,不仅仅要操作原表的数据,而且要操作索引

查看索引数据

sql mode

mysql5.6如下show variables like '%sql_mode%';+---------------+--------------------------------------------+| Variable_name | Value                                      |+---------------+--------------------------------------------+| sql_mode      | NO_ENGINE_SUBSTITUTION                     |+---------------+--------------------------------------------+5.7如下

ONLY_FULL_GROUP_BY 如果出现在select中的列、having或者order by子句的非聚合列,没有在group by中出现,那么这个sql语法检查报错

不在group内的列,必须要有max,count,min等列进行包裹

set session/global/persist sql_mode= ‘’

常用的sql mode

ONLY_FULL_GROUP_BY 如果出现在select中的列、having或者order by子句的非聚合列,没有在group by中出现,那么这个sql语法检查报错

ANSI_QUOTES 禁止用双引号来引用字符串

REAL_AS_FLOAT  real作为float的同义词

PIPES_AS_CONCAT ||视为字符串的链接符而非或运算符

STRICT_TRANS_TABLES/STRICT_ALL_TABLES 在事务存储引擎/所有存储引擎上启用严格模式出现,那么这个SQL语法检查报错,在该模式下,如果⼀个值不能插⼊到⼀个事务表中,则中断当前的操作,对⾮事务表不做限制 

ERROR_FOR_DIVISION_BY_ZERO 不允许0作为除数

NO_ENGINE_SUBSTITUTION  当指定的存储引擎不可用时报错

NO_ZERO_IN_DATE:在严格模式下,不允许⽇期和⽉份为零

NO_ZERO_DATE:设置该值,mysql数据库不允许插⼊零⽇期,插⼊零⽇期会抛出错误⽽不是警告。

NO_AUTO_VALUE_ON_ZERO:该值影响⾃增⻓列的插⼊。默认设置下,插⼊0或NULL代表⽣成下⼀个⾃增⻓值。如果⽤户 希望插⼊的值为0,⽽该列⼜是⾃增⻓的,那么这个选项就有⽤了。   ERROR_FOR_DIVISION_BY_ZERO:在INSERT或UPDATE过程中,如果数据被零除,则产⽣错误⽽⾮警告。如 果未给出该模式,那么数据被零除时MySQL返回NULL   NO_AUTO_CREATE_USER:禁⽌GRANT创建密码为空的⽤户

 

在my.cnf添加如下配置[mysqld]sql_mode='ONLY_FULL_GROUP_BY,NO_AUTO_VALUE_ON_ZERO,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,PIPES_AS_CONCAT,ANSI_QUOTES'

文章转载自MySQLDBA修炼之路,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论