MYSQL数据类型、范式及索引总结

MySQL的数据类型

MySQL数据类型简介

整数类型、浮点数类型和定点数类型

整数:
不一样数据类型字节数、取值范围的对比 如上表所示INT和INTEGER的字节数与取值范围相同,其实,在MySQL中INT类型和INTEGE类型是同样的。TYNYINT类型占用的字节数最小为1个字节,取值范围最小;BIGIYNT类型占用的字节数最大,须要八个字节,取值范围最大。
容易看出,不一样整数类型的字节数不一样,根据不一样类型所占的字节数能够推算出该类型的取值范围。

sql

默认整数数据类型宽度以下:
Field Type
a tinyint(4)
b smallint(6)
c mediumint(9)
d int(11)
e bigint(20)

MySQL各类数据类型的字段都有宽度限制,默认数据类型宽度刚好为显示该数据类型全部的值的宽度。数据库

1、在整数类型使用时,还可搭配zerofill参数。zerofill参数在数字显示不足的空间由0来填充。须要注意的是,使用zerofill参数时,MySQL会自动加上UNSIGNED属性。也就是说该整数类型就只能表示无符号数,期限是宽度比默认宽度小1。
2、以上数据类型的字段能够设置显示宽度,可是依然能够插入大于显示宽度的值。前提是不超过对应数据类型的默认宽度,由于该数据类型的最大值宽度是小于等于默认宽度的,超过默认宽度至关于超过该数据类型可显示的最大值,显然这个值是不可插入的。
3、整数类型还有一个AUTO_INCREMENT属性。该属性但是字段变成自增字段,对该字段,每插入一条新的纪录,该字段都会自增1,自增的初值默认从1开始自增,若是第一条记录设置了初值就从该记录开始。(技巧:加上AUTO_INCREMENT的字段,其每一个值都是自动增长的。所以,这个字段不可能出现相同的值;因此,一般用于表中ID字段的约束,ID做为表的主键)。

安全

浮点类型和顶点类型:
浮点和定点的取值范围 由上表可知,DECIMALl类型和DOUBLE类型的取值范围同样,可是DECIMAL的有效取值范围由 M和D决定,并且DICIMAL 字节数是M+2。也就是说,定点数的存储空间是根据其精度肯定的。MySQL中能够指定浮点数和定点数的精度。其基本形式以下
数据类型 (M,D)
数据类型为float或double;M参数为精度,是数据的总长度,小数点不占位置;D参数是标度,指小数点后的长度为D。


函数

1、虽然以上指定小数精度方法都适合于浮点数和定点数,但不是浮点数的通用标准,除非必要不要使用于浮点数,不然可能会影响数据库的迁移。
2、若是没有指定精度,浮点数和定点数都有其默认精度,float和double类型谁都会保存其实际精度。DECIMAL类型的整数位默认是10位,小数位为0,即默认为整数。
3、在MySQL中,定点数以字符串的方式存储。所以,其精度比浮点数要高。并且浮点数会出现偏差,若是要求精度比较高,仍是选择定点数(DECIMAL)比较安全。

性能

日期与时间类型

五种日期与时间类型的字节数,取值范围和零值的对比一、YEAR
若是插入的年份信息超出范围就回插入‘0000’;若是插入‘24’,‘86’,‘0’,‘00’,实际插入的值分别是‘2024’,‘1986’,‘2000’
学习

使用YEAR类型时,要区分0和‘0’。若是插入的是0,存入的年份是0000。若是插入的是‘0’,存入的年份则是2000。‘00’和‘0’的效果相同。编码

二、TIME类型spa

TIME字段赋值及表示方法以下:设计

‘D HH:MM:SS’格式的字符串;向表中插入‘2 23:50:50’,‘11:11’,‘30’结果以下:code

a
71:50:50
11:11:00
00:00:30

HHMMSS格式的字符串或者HHMMSS格式的数值表示;向表中插入1212十二、‘131313’、‘0’和0。

a
12:12:12
13:13:13
00:00:00
00:00:00

a是TIME 数据类型。使用CURRENT_TIME和NOW()插入系统当前时间。

a
11:48:00
11:48:05

若是插入的TIME值是无效的,系统会提示错误,就算插入表中也会被转换为00:00:00。

三、DATE类型
‘YYYY-MM-DD’或‘YYYYMMDD’格式的字符串表示;这种方式能够表达的范围是‘1000-01-01’~‘9999-12-31;MySql还支持一些不严格的语法格式,任何标点均可以用爱作分隔符。
a是DATE数据类型,向表中插入‘1949-10-01’、‘1950#2#3’、‘1951@3@4’和‘19520101’。结果以下

a
1949-10-01
1950-02-03
1951-03-04
1952-01-01

若是向表中插入‘53-01-01’、‘78@1@10’、‘540101’和‘790101’。显示结果以下

a
2053-01-01
1978-01-01
2054-01-01
1979-01-01

虽然MySQL支持不严格语法格式,可是为了统一通常状况用‘-’作日期分隔符,‘:’作时间分隔符。一样可使用CURRENT_DATE()和NOW()插入当前系统的信息。例如:2020-01-02

四、DATETIME类型
DATETIME类型使用8个字节来表示日期和时间。MySQL中以‘YYYY-MM-DDHH:MM:SS’的形式显示DATETIME类型的值。从其形式能够看出,DATETIME类型能够直接用DATE类型和TIME类型组合而成。给DATETME类型的字段赋值的表示方法以下:
‘YYYY-MM-DD HH:MM:SS’或‘YYYYMMDDHHMMSS’格式的字符串表示。
这种方式能够表达的范围是‘1000-01-01 00:00:00’~‘9999-12-3123:59:59’。


五、TIMESTAMP类型
TIMESTAMP类型使用4个字节来表示日期和时间。TIMESTAMP类型的范围是从1970-01-01 08:00:01~2038-01-19 11:14:07。
值得注意的是,TIMESTAMP类型范围比较小,没有 DATETIME类型的范围大。所以,输入值时要保证在 TIMESTAMP类型的有效范围内。
下面介绍 TIMESTAMP类型的几种与DATETIME类型不一样的形式。内容以下:
(1)使用 CURRENT_TIMESTAMP来输入系统当前日期与时间。
(2)输入NULL时,系统会输入系统当前日期与时间。
(3)无任何输入时,系统会输入系统当前日期与时间。
TIMESTAMP类型还有一个很大的特殊点,就是时间是根据时区来显示的。例如,在东八区插入的TIMESTAMP类型为2009-09-30 14:21:25。在东七区显示时,时间部分就变成了13:21:25。在东九区显示时,时间部分就变成了15:21:25。
若要选择的时间范围较大仍是选择DATETIME合适。







字符串类型

字符串类型包括:CHAR、VARCHAR、BLOB、TEXT、ENUM和SET。
一、CHAR和VARCHAR
CHAR类型的长度是固定的,在建立表时就指定了。其长度能够是0~255的任意值。例如,CHAR(10O)就是指定CHAR类型的长度为100。
VARCHAR类型的长度是可变的,在建立表时指定了最大长度。定义时,其最大值能够取0~~65535之间的任意值。指定VARCHAR类型的最大值之后,其长度能够在0到最大长度之间。例如,VARCHAR(100)的最大长度是100。可是,不是每条记录都要占用100个字节。而是在这个最大值范围内,使用多少分配多少。VARCHAR类型实际占用的空间为字符串的实际长度加1。这样,便可有效节约系统的空间。


须要注意的是,CHAR类型和VARCHAR类型在空格的存储上有区别,例如存储‘123*’,*表明空格,VARCHAR会把空格也保存下来,CHAR类型却把空格舍弃了。

二、TEXT
TEXT 类型是一种特殊的字符串类型。TEXT只能保存字符数据,如新闻的内容等。TEXT类型包括TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。

4种 TEX类型容许的长度和存储空间进行对比
从表4.5能够看出,各类TEXT类型的区别在于容许的长度和存储空间不一样。所以在这几种 TEXT类型中,根据需求选取既能知足须要又最节约空间的类型便可。

三、ENUM
ENUM类型又称为枚举类型。在建立表时,ENUM类型的取值范围就以列表的形式指定了。其基本形式以下:
属性名ENUM(‘值1,值2然,值n’)
其中,属性名参数指字段的名称;“值n”参数表示列表中的第 n个值,这些值末尾的空格将会被系统直接删除。ENUM类型的值只能取列表中的一个元素。其取值列表中最多能有65535个值。列表中的每一个值都有一个顺序排列的编号,MySQL中存入的是这个编号,而不是列表中的值。


若是ENUM类型加上了NOT NULL属性,其默认值为取值列表的第一个元素。若是不加 NOT NULL属性,ENUM类型将容许插入NULL,并且NULL为默认值。

四、SET
在建立表时,SET类型的取值范围就以列表的形式指定了。其基本形式以下。属性名 SET(值1,值2,值n)
其中,“属性名”参数指字段的名称;“值n”参数表示列表中的第n个值,这些值末尾的空格将会被系统直接删除。其基本形式与ENUM类型同样。SET类型的值能够取列表中的一个元素或者多个元素的组合。取多个元素时,不一样元素之间用逗号隔开。SET类型的值最多只能是有64个元素构成的组合。
同ENUM类型同样,列表中的每一个值都有一个顺序排列的编号。MySQL 中存入的是这个编号,而不是列表中的值。
插入记录时,SET字段中的元素顺序可有可无。存入MySQL 数据库后,数据库系统会自动按照定义时的顺序显示。



SET 和ENUM类型,在插入的值不为空,且该字段已有指定的元素时,插入的元素如不在预设范围内就都会报错。

二进制类型

二进制类型是在数据库中存储二进制数据的数据类型。二进制类型包括 BINARY、VARBINARY、BIT、TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。
各类二进制类型进行对比1.BINARY和VARBINARY类型
BINARY类型和 VARBINARY类型都是在建立表时指定了最大长度,其基本形式以下:
字符串类型 (M)
其中,“字符串类型”参数指定了数据类型为BINARY类型仍是VARBINARY类型;M参数指定了该二进制数的最大字节长度为M。这与CHAR类型和VARCHAR类型类似。例如,BINARY (10)就是指数据类型为BINARY类型,其最大长度为10。
BINARY类型的长度是固定的,在建立表时就指定了。不足最大长度的空间由“O”补全。例如,BINARY (50)就是指定BINARY类型的长度为50。
VARBINARY 类型的长度是可变的,在建立表时指定了最大长度。指定好了VARBINARY类型的最大值之后,其长度能够在0到最大长度之间。例如,VARBINARY(50)的最大字节长度是50。可是,不是每条记录的字节长度都是50。在这个最大值范围内,使用多少分配多少。VARBINARY类型实际占用的空间为实际长度加1。这样,能够有效的节约系统的空间。
在这里插入图片描述






2.BIT类型
BIT类型也是在建立表时指定了最大长度,其基本形式以下:
BIT( M)
其中,“M”指定了该二进制数的最大字节长度为M,M的最大值为64。例如,BIT(4)就是数据类型为BIT类型,长度为4。若字段的类型BIT(4),存储的数据是从0~15。由于,变成二进制之后,15的值为1111,其长度为4。若是插入的值为16,其二进制数为10000,长度为5,超过了最大长度。所以,大于等于16 的数是不能插入到BIT(4)类型的字段中的。
在查询BIT类型类型的数据时,要用BIN(字段名+0)来将值转换为二进制显示。



在这里插入图片描述
3. BLOB类型
BLOB类型是一种特殊的二进制类型。BLOB能够用来保存数据量很大的二进制数据,如图片等。BLOB类型包括TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。这几种 BLOB 类型最大的区别就是可以保存的最大长度不一样。LONGBLOB 的长度最大,TINYBLOB的长度最小。
BLOB类型与TEXT类型很相似。不一样点在于BLOB类型用于存储二进制数据,BLOB类型数据是根据其二进制编码进行比较和排序。而 TEXT类型是文本模式进行比较和排序的。


技巧:BLOB类型主要用来存储图片、PDF文档等二进制文件。一般状况下,能够将图片、PDF文档均可以存储在文件系统中,而后在数据库中存储这些文件的路径。这种方式存储比直接存储在数据库中简单,可是访问速度比存储在数据库中慢。

MySQL数据类型选择

整数类型与浮点类型的选择:

是否须要表达小数,要表达小数就用浮点型,反之就用整数类型

浮点数与定点数的选择:

FLOAT,须要小数时通常使用float类型
DOUBLE,须要小数而且要求精度时使用double类型
DECIMAL,须要自定义精度时使用定点数类型,要求更高精度时也可使用定点数(由于MySQL中定点数以字符串存储)。

日期与时间数据类型的选择:

YEAR仅用到年份信息就是用YEAR类型

DATE不使用时分秒,仅用于日期

TIME 类型专门用来存储时间数据(时分秒), 并且仅占三个字节。若是须要记录时间,TIME类型最合适。

DATETIME类型用于记录日期和时间,其做用等价于DATE类型和TIME类型的组合。一个DATETIME类型的字段能够用一个DATE类型的字段和一个TIME类型的字段代替。可是,若是须要同时记录日期和时间,选择DATETIME类型是个不错的选择。

虽然TIMESTAMP表示范围较DATETIME小,可是TIMESTAMP是根据时区显示,若是跨时区使用时间TIMESTAMP较好。

CHAR类型和VARCHAR类型的选择:

CHAR类型的长度是固定的,而 VARCHAR类型的长度是在范围内可变的。所以,VARCHAR类型占用的空间比CHAR类型小。并且,VARCHAR类型比CHAR类型灵活。对于长度变化比较大的字符串类型,最好是选择VARCHAR类型。
虽然CHAR类型占用的空间比较大,可是CHAR类型的处理速度比VARCHAR快。所以,对于长度变化不大和查询速度要求较高的字符串类型,最好选择CHAR类型。

ENUM类型和SET类型的选择:

ENUM类型最多能够有65535个成员,而SET类型最多只能包含64个成员。二者的取值只能在成员列表中选取。ENUM类型只能从成员中选择一个,而SET类型能够选择多个。
所以,对于多个值中选取一个的,能够选择ENUM类型。例如,“性别”字段就能够定义成ENUM类型,由于只能在“男”和“女”中选其中一个。对于能够选取多个值的字段,能够选择SET类型。例如,“爱好”字段就能够选择SET 类型,由于可能有多种爱好。

TEXT类型和BLOB类型:
TEXT类型与BLOB类型很相似。TEXT类型存储只能存储字符数据。而BLOB类型能够用于存储二进制数据。若是要存储文章等纯文本的数据,应该选择TEXT类型。若是须要存储图片等二进制的数据,应该选择BLOB类型。
TEXT类型包括TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。这4者最大的不一样是内容的长度不一样。TINYTEXT类型容许的长度最小,LONGTEXT 类型容许的长度最大。BLOB类型也是如此。

MySQL范式

MySQL范式介绍

应用数据库范式能够带来许多益处,大概总结为三点:
1)减小数据冗余(这是最主要的好处,其余好处都是由此而附带的)
2)消除异常(插入异常,更新异常,删除异常)
3)让数据组织的更加简介简洁便利


可是数据库范式绝对不是越高越好;由于范式越高,意味着表越多,多表联合查询的概率就越大,SQL查询的效率就变低了。
通常开发中只听从第三范式就好,是具体状况而定。

第一范式:每个数据项都是不可再分的,即表中每一列具备原子性

列都是基本数据项,不可以再进行分割,不然设计成一对多的实体关系。例如表中的地址字段,能够再细分为省,市,区等不可再分割(即原子特性)的字段,以下:
列是基本数据项、不能再进行擦缝,不然设计成一对多的关系
不知足第一范式不能称之为关系型数据库
在这里插入图片描述


拆分改造后:
![在这里插入图片描述](https://img-blog.csdnimg.cn/2021010213200410在这里插入图片描述
.png)

学生表(学号、用户名、性别、年龄,地址)
例:陕西省西安市西安工大学
例:陕西省西安市未央区学府中路西安工业大学
地址信息还包含省市区能够拆分
拆分改造后:
学生表(学号、用户名、性别、年龄、地址ID)
地址表(地址ID、省、市、区、街道、学校)





上图的表就是把地址字段分红更详细的city,country,street三个字段,注意,不符合第一范式不能称做关系型数据库。

第二范式:非主属性彻底依赖于主键(主要针对联合主键-》消除部分依赖)
符合第一范式的基础上,非主属性彻底依赖于主关键字,若是不是彻底依赖主键,应该拆分红新的实体,设计成一对多的实体关系。
示例:
假定选课关系表为SelectCourse(学号, 姓名, 年龄, 课程名称, 成绩, 学分),关键字为组合关键字(学号, 课程名称),由于存在以下决定关系:
(学号, 课程名称) → (姓名, 年龄, 成绩, 学分)
这个数据库表不知足第二范式,由于存在以下决定关系:
(课程名称) → (学分)
(学号) → (姓名, 年龄)
即存在组合关键字中的字段决定非关键字的状况。
因为不符合2NF,这个选课关系表会存在以下问题:
(1) 数据冗余:
同一门课程由n个学生选修,”学分”就重复n-1次;同一个学生选修了m门课程,姓名和年龄就重复了m-1次。
(2) 更新异常:
若调整了某门课程的学分,数据表中全部行的”学分”值都要更新,不然会出现同一门课程学分不一样的状况。
(3) 插入异常:
假设要开设一门新的课程,暂时尚未人选修。这样,因为尚未”学号”关键字,课程名称和学分也没法记录入数据库。
(4) 删除异常:
假设一批学生已经完成课程的选修,这些选修记录就应该从数据库表中删除。可是,与此同时,课程名称和学分信息也被删除了。很显然,这也会致使插入异常。
示例2:

















学生选课表(学生ID、学生姓名、学生性别、课程ID、课程成绩)
主键(学生ID、课程Id)
学生姓名-》学生ID -》部分依赖
学生性别-》学生ID -》部分依赖
课程成绩-》(学生ID、课程id)-》彻底依赖
拆分改造后:
学生表(学生ID、学生姓名、学生性别) 主键:学生ID
课程成绩表(课程ID、学生ID、成绩) 主键:(课程ID、学生ID)
示例:选课关系表为SelectCourse(学号, 姓名, 年龄, 课程名称, 成绩, 课程所占学分),(学号,课程名称)是联合主键,可是学分字段只和课程名称有关,和学号无关,至关于只依赖联合主键的其中一个字段,不符合第二范式。







第三范式:属性不依赖于其它非主属性(消除依赖传递)
基于第二范式的基础,非主属性只依赖于主属性
要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。
示例:学生表(学生ID、学生姓名、学生性别、学院id、学院电话)
主键:学生ID
学生姓名-》学生ID
学生性别-》学生ID
学院名称-》学生ID
学院电话 -》 学生ID -》查询学院id-》查询学院电话







数据冗余、更新异常、插入异常和删除异常的状况一样存在。

拆分改造后:
学生表:(学生ID、学生姓名、学生性别、学院ID)主键:学生ID
学院表:(学院ID、学院名称、学院电话) 主键:学院ID

示例:学生关系表为Student(学号, 姓名, 年龄, 课程, 成绩),学号是主键,可是学院 电话只依赖于所在学院,并不依赖于主键学号,所以该设计不符合第三范式,应该把学院专门设计成一张表,学生表和学院表,两个是一对多的关系。

BCNF范式:每个决定属性集都包含候选键,也就是只有一个候选键才能够达到这种状况;

简单的说,BC范式是在第三范式的基础上的一种特殊状况,即每一个表中只有一个候选键(在一个数据库中每行的值都不相同,则可称为候选键);(能够有多个决定属性集,决定属性集中一定含有吗)

假设仓库管理关系表为StorehouseManage(仓库ID, 存储物品ID, 管理员ID, 数量),且有一个管理员只在一个仓库工做;一个仓库能够存储多种物品。这个数据库表中存在以下决定关系:
主键(仓库ID,管理员ID, 存储物品ID)
(仓库ID,管理员ID, 存储物品ID) → (数量)
可是咱们发现:
(仓库ID, 存储物品ID) →(管理员ID, 数量)
(管理员ID, 存储物品ID) → (仓库ID, 数量)
因此,(仓库ID, 存储物品ID)和(管理员ID, 存储物品ID)都是StorehouseManage的候选关键字,表中的惟一非关键字段为数量,它是符合第三范式的。可是,因为存在以下决定关系:
(仓库ID) → (管理员ID)
(管理员ID) → (仓库ID)
即存在关键字段决定关键字段的状况,因此其不符合BCNF范式。它会出现以下异常状况:
(1)数据冗余
(2)删除异常:
当仓库被清空后,全部”存储物品ID”和”数量”信息被删除的同时,”仓库ID”和”管理员ID”信息也被删除了。
(3)插入异常:
当仓库没有存储任何物品时,没法给仓库分配管理员。
(4)更新异常:
若是仓库换了管理员,则表中全部行的管理员ID都要修改。
把仓库管理关系表分解为二个关系表:
仓库管理:StorehouseManage(仓库ID, 管理员ID);
仓库:Storehouse(仓库ID, 存储物品ID, )。
这样的数据库表是符合BCNF范式的,基本消除了删除异常、插入异常和更新异常。



















第四范式:消除表中的多值依赖

简单来讲,第四范式就是要消除表中的多值依赖,也就是说能够减小维护数据一致性的工做。

对于数据库范式进行分解的过程当中不难看出,应用的范式越高,表越多。表多会带来不少问题:
1 查询时须要链接多个表,增长了SQL查询的复杂度
2 查询时须要链接多个表,下降了数据库查询性能
所以,并非应用的范式越高越好,要看实际状况而定。第三范式已经很大程度上减小了数据冗余,而且基本预防了数据插入异常,更新异常,和删除异常了。




MySQL范式联系与转化

在这里插入图片描述由上图可知,范式越高所包含的范围与小;所以能够理解第几范式能向高级范式分解,以解决数据操做的各类异常。
分解其实就是把可能造成另外一个关系的属性列拿出来建立一个新的表,或者对一些能够继续分解的属性列分解为另外一个关系。

MySQL索引

索引的含义及特色

索引的含义:建立在表上的,对数据库中一列或者多列的值进行排序的一种结构。索引能够提升查询速度。

不一样的存储引擎定义了每一个表的最大索引数和最大索引长度。全部存储引擎对每一个表至少支持16个索引,总索引长度至少为256字节。有些存储引擎支持更多的索引数和更大的索引长度。索引有两种存储类型,包括B型树(BTREE)索引和哈希(HASH)索引。InnoDB和 MyISAM存储引擎支持 BTREE索引,MEMORY存储引擎支持HASH索引和BTREE索引,默认为前者。

索引有其明显的优点,也有其不可避免的缺点。

索引的优势是能够提升检索数据的速度,这是建立索引的最主要的缘由;对于有依赖关系的子表和父表之间的联合查询时,能够提升查询速度;使用分组和排序子句进行数据查询时,一样能够显著节省查询中分组和排序的时间。

索引的缺点是建立和维护索引须要耗费时间,耗费时间的数量随着数据量的增长而增长;索引须要占用物理空间,每个索引要占必定的物理空间;增长、删除和修改数据时,要动态的维护索引,形成数据的维护速度下降了。

索引的分类

1.普通索引
在建立普通索引时,不附加任何限制条件。这类索引能够建立在任何数据类型中,其值是否惟一和非空由字段自己的完整性约束条件决定。创建索引之后,查询时能够经过索引进行查询。例如,在 student表的stu_id字段上创建一个普通索引。查询记录时,就能够根据该索引进行查询。

2.惟一性索引
使用UNIQUE参数能够设置索引为惟一性索引。在建立惟一性索引时,限制该索引的值必须是惟一的。例如,在 student表的 stu_name字段中建立惟一性索引,那么stu_name字段的值就必需是惟一的。经过惟一性索引,能够更快速地肯定某条记录。主键就是一种特殊惟一性索引。

3.全文索引
使用FULLTEXT参数能够设置索引为全文索引。全文索引只能建立在CHAR、VARCHAR或TEXT类型的字段上。查询数据量较大的字符串类型的字段时,使用全文索引能够提升查询速度。例如,student 表的 information字段是TEXT类型,该字段包含了不少的文字信息。在 information字段上创建全文索引后,能够提升查询information字段的速度。MySQL数据库从3.23.23版开始支持全文索引,但只有MyISAM存储引擎支持全文检索。在默认状况下,全文索引的搜索执行方式不区分大小写。但索引的列使用二进制排序后,能够执行区分大小写的全文索引。

4.单列索引
在表中的单个字段上建立索引。单列索引只根据该字段进行索引。
单列索引能够是普通索引,也能够是惟一性索引,还能够是全文索引。只要保证该索引只对应一个字段便可。

5.多列索引
多列索引是在表的多个字段上建立一个索引。该索引指向建立时对应的多个字段,能够经过这几个字段进行查询。可是,只有查询条件中使用了这些字段中第一个字段时,索引才会被使用。例如,在表中的id、name和 sex字段上创建一个多列索引,那么,只有查询条件使用了id字段时该索引才会被使用。

6.空间索引
使用SPATIAL参数能够设置索引为空间索引。空间索引只能创建在空间数据类型上,这样能够提升系统获取空间数据的效率。MySQL 中的空间数据类型包括GEOMETRY和POINT、LINESTRING和 POLYGON等。目前只有MyISAM存储引擎支持空间检索,并且索引的字段不能为空值。对于初学者来讲,这类索引不多会用到。

MySQL创建索引原则

1.选择惟一性索引
惟一性索引的值是惟一的,能够更快速的经过该索引来肯定某条记录。

2.为常常须要排序、分组和联合操做的字段创建索引
常常须要ORDER BY、GROUP BY、DISTINCT 和 UNION等操做的字段,排序操做会浪费不少时间。若是为其创建索引,能够有效地避免排序操做。

3.为常做为查询条件的字段创建索引
若是某个字段常常用来作查询条件,那么该字段的查询速度会影响整个表的查询速度。所以,为这样的字段创建索引,能够提升整个表的查询速度。

4.限制索引的数目
索引的数目不是越多越好。每一个索引都须要占用磁盘空间,索引越多,须要的磁盘空间就越大。修改表时,对索引的重构和更新很麻烦。越多的索引,会使更新表变得很浪费时间。

5.尽可能使用数据量少的索引
若是索引的值很长,那么查询的速度会受到影响。例如,对一个CHAR(100)类型的字段进行全文检索须要的时间确定要比对CHAR(10)类型的字段须要的时间要多。

6.尽可能使用前缀来索引
若是索引字段的值很长,最好使用值的前缀来索引。例如,TEXT和BLOG类型的字段,进行全文检索会很浪费时间。若是只检索字段的前面的若干个字符,这样能够提升检索速度。
7.删除再也不使用或者不多使用的索引
表中的数据被大量更新,或者数据的使用方式被改变后,原有的一些索引可能再也不须要。数据库管理员应当按期找出这些索引,将它们删除,从而减小索引对更新操做的影响。


注意:选择索引的最终目的是为了使查询的速度变快。上面给出的原则是最基本的准则,但不能拘泥于上面的准则。读者要在之后的学习和工做中进行不断的实践。根据应用的实际状况进行分析和判断,选择最合适的索引方式。.

MySQL建立索引

1.建立表时建立索引
2.在已经存在的表上建立索引
3.用alter table建立索引
在这里插入图片描述


MySQL删除索引

删除索引是指将表中已经存在的索引删除掉。一些再也不使用的索引会下降表的更新速度,影响数据库的性能。对于这样的索引,应该将其删除。本节将详细讲解删除索引的方法。
对应已经存在的索引,能够经过DROP语句来删除索引。基本形式以下:

drop INDEX 索引名 on 表名;

MySQL索引的有效性

索引失效:
1.隐式转换致使索引失效。
例:
因为表的字段name定义为varchar(20),但在查询时把该字段做为数字类型,以where条件传给Mysql,这样会致使索引失效.
强转会引发索引失效:
name varchar(20)
index(name);
错误的例子:select * from test where name = 999;






N行数据 把N行数据的name属性分别取出来先强转在比较。
因为须要将每一行数据都拿出来进行强换以后再比较。
强转以后改变了原有字段的比较规则
正确的例子:select * from test where name=‘999’; 能用到索引


2.对索引列进行运算致使索引失效,对索引列进行运算包括(+,-,*,/,! 等)
例:
index(id)
错误的:select * from test where id - 1 < 9;
须要将每个元组中的id值先取出,再减一而后和9再去比较
正确的例子:select * from test where id < 10;能用到索引




3.使用MySQL内部函数致使索引失效.对于这样状况应当建立基于函数的索引。
错误的例子:select * from test where F(id)=10; 说明,此时id的索引已经不起做用了(须要将每个元组中的id值先取出,再经过函数计算,计算以后的值在和10比较)
要使用索引的话须要将:F(x) = y; ----> x = R(y);
正确的例子:select * from test where id= R(10);


4. 如下使用会使索引失效,应避免使用;
a.使用 <> 、not in 、!=
index(id)
select * from … where id not in (12,13,15); 用不到 没有明确查询条件
id
1


999







select * from … where id in (12,13,15); 能用到

b. like “%_” 百分号在前(可采用在创建索引时用reverse(columnName)这种方法处理)
%:任意个任意字符
index(name)
select * from name like ‘%a’; //因为字符串的最左比较法 用不到
字符串的索引是如何创建:从左到右一个字符一个字符进行大小比较而后得出的B+树的结构。



abcdsdsa
abdr
select * from name like ‘a%’; //因为字符串的最左比较法 能用到

五、使用OR关键字查询语句
查询语句的查询条件中只有OR关键字,且OR先后的两个条件中列都是索引时,查询中才会使用索引。不然,查询将不使用索引。

name = “tom” or(或) age < 90; ---->index(name) index(age);

name = “tom” and age < 90; ----> index(name,age)

索引的使用规则

最左前最原则:对带有联合索引的表进行多字段查询时,应将联合索引中的第一个索引字段放在第一位,这样索引才能使用到。
**索引使用时的时间复杂度:**小表决定查询次数,大表决定查询时间。

例:

联合查询中如何使用索引,在表rb1,rb2中均在stu_id 字段上添加索引 index(stu_id)。判断哪张表的索引能用到。

假设rb2是大表,rb1是小表
1.explain select * from rb1 a , rb2 b where a.stu_id = b.stu_id\G
where a.stu_id = b.stu_id
底层处理:把b中的全部的stu_id取出来,分别和a中的stu_id做比较;大表rb2可以使用到索引 而小表rb1用不到索引
在这里插入图片描述



explain select * from rb1 a  join rb2 b 
	on a.stu_id = b.stu_id where a.stu_id < 25\G

rb1使用到索引:where条件
rb2使用到索引:rb2是大表固然用到索引
在这里插入图片描述

3.explain select * from rb1 a join rb2 b
on a.stu_id = b.stu_id where b.stu_id < 25\G
rb2用到了索引由于where条件,同时变成小表,rb1变成大表用到了索引
在这里插入图片描述


4.没给id加索引时:
a表的id上没有索引因此仍是小表不用索引,rb2用索引
在这里插入图片描述

给id加上索引后:
在这里插入图片描述

相关文章
相关标签/搜索