武汉加油!!!
背景
数据库是什么? 这个问题大家都知道吧, 用来存放数据的, 生活中你在银行中存的金额, 或者一个户籍所中存放的户籍以及个人信息, 在比如一个学校的学生信息等等, 这些都存放在我们的数据库里面. 对不数据库中的数据一般采用一些DML语句
(insert, update, delete)来进行数据操作. 想要查看数据库里面的数据使用select语句进行数据的查询.
对于数据在数据库里面的存放, 可以简单理解为类似Excel表格
, 表格里面每一行代表一条数据. 一个Sheet页
来代表一类数据.一个例子
现在我们有一张excel表格, 里面存放了一个学校的学生信息, 包含学号, 姓名, 班级,年级等等信息
- 如果, 如果这张表里面只存放了较少的数据(
几十条, 或者十几条
), 那现在让你找到关于张三学生的信息
, 我们便开始从上到下或者从下到上开始浏览每一行数据, 直到找到张三
, 便完成了数据的查询. - 但是, 数据量大了, 这个excel存放了成千上万条数据, 再让你找出来张三, 你还是需要从上到下, 或者从下到上开始找
张三
, 这一次因为数据变多了, 导致你可能一眼找到张三, 可能要浏览一段时间才能找出来张三.
上面的例子, 便是一个数据查询经典的问题, 那么如何解决这个问题呢? 通过索引即可
另一个例子
张三买了一本书《钢铁是怎样炼成的》看完了一遍之后, 时隔半年突然想起了人最宝贵的东西是生命.生命对人来说只有一次.因此,人的一生应当这样度过:当一个人回首往事时,不因虚度年华而悔恨,也不因碌碌无为而羞愧..
但是忘记了后半句, 只记得是在某一章(我记得是好像是在整书结尾来着
), 然后张三通过目录找到了这一章, 很快便从这一章里面找到了这句话的后半句.
那么这个目录便可以理解为一个索引
, 最主要的目的就是加快查询的速度
索引
在上面通过两个生活中的例子, 描述了
索引是什么以及索引的功能
, 在我们的数据库中, 道理也是一样的,索引
: 索引用于快速找出在某个列中有一特定值的行,不使用索引,MySQL必须从第一条记录开始读完整个表,直到找出相关的行,表越大,查询数据所花费的时间就越多,如果表中查询的某列有一个索引,MySQL能够快速到达一个位置去搜索数据文件,那么将会节省很大一部分时间索引存储类型
: 当把某一列作为索引的时候, 数据查询就变成了 先找索引, 再根据索引找这一条数据. 为了进一步提升所以的查询效率, 就引入了一些数据结构算法来提升效率MySQL中的索引的存储类型有两种:BTREE、HASH。 也就是用树或者Hash值来存储该字段
优点
:- 理论上任何字段类型都可以被建立索引.
- 显著提高查询的速度
缺点
:- 索引的创建需要消耗时间, 并且索引也需要维护, 维护的也会增加工作量
何时使用
:- 对于经常作为查询条件的字段优先建立索引
- 数据经常变动的表避免过多建立索引
- 数据量较小的表, 尽可能不去建立索引, 因为由于数据较少可能查询全部花费的时间比遍历索引时间更少.
存储引擎
对于Mysql首先要知道的是:索引是在存储引擎中实现的,也就是说不同的存储引擎,会使用不同的索引
, 所以先来认识一下mysql几种存储引擎.
MySQL有一个被称为“Pluggable Storage Engine Architecture”(可替换存储引擎架构)的特性,也就意味着MySQL数据库提供了多种存储引擎。用户可以根据不同的需求为数据表选择不同的存储引擎,用户也可以根据自己的需要编写自己的存储引擎。
存储引擎种类
引擎名称 | 解释 |
---|---|
CSV | 基于 CSV 格式文件存储数据(应用于跨平台的数据交换) |
Archive | 将数据压缩后进行存储,非常适合存储大量的独立的,作为历史记录的数据,但是只能进行插入 和查询 操作 |
Falcon | 一种新的存储引擎,支持事物处理 |
Memory | 内存存储引擎,拥有极高的插入,更新和查询效率。但是会占用和数据量成正比的内存空间。只在内存上保存数据,意味着数据可能会丢失 |
MRG_MyISAM(MERGE) | 将多个表联合成一个表使用,在超大规模数据存储时很有用 |
ISAM | MyISAM的前身,MySQL5.0以后不再默认安装 |
MyISAM | 高速引擎,拥有较高的插入,查询速度,但不支持事务 |
InnoDB | 5.5版本后MySQL的默认数据库,支持事务和行级锁定,比MyISAM处理速度稍慢 |
表格中列举的是Mysql支持的几种存储引擎的, 其中后两种是生产开发中使用最多的方案, 下面我们重点介绍一下.
MyISAM引擎
这种引擎又可以细分为动态
, 静态
, 压缩
三种:
-
静态MyISAM
:如果数据表中的各数据列的长度都是预先固定好的,服务器将自动选择这种表类型。因为 数据表中每一条记录所占用的空间都是一样的,所以这种表存取和更新的效率非常高。 -
动态MyISAM
:如果数据表中出现varchar
、xxxtext或xxxBLOB
字段时,服务器将自动选择这种表类型。相对于静态MyISAM,这种表存储空间比较小,但由于每条记录的长度不一,所以多次修改数据后,数据表中的数据就可能离散的存储在内存中,进而导致执行效率下降。同时,内存中也可能会出现很多碎片。因此,这种类型的表要经常用optimize table 命令或优化工具来进行碎片整理
。 -
压缩MyISAM
:以上说到的两种类型的表都可以用myisamchk工具压缩。这种类型的表进一步减小了占用的存储,但是这种表压缩之后不能再被修改。另外,因为是压缩数据,所以这种表在读取的时候要先时行解压缩。 -
优点:
有着较高的查询和写入速度, 独立于操作系统, 不受 win 和linux的限制- 适用于选择密集型的表。MyISAM存储引擎在
筛选大量数据时非常迅速
,插入密集型的表。MyISAM的并发插入特性允许同时选择和插入数据。
- 适用于选择密集型的表。MyISAM存储引擎在
-
缺点:
不支持事务
InnoDB引擎
InnoDB表类型可以看作是对MyISAM的更新产品,它提供了事务
、行级锁机制
和外键约束
的功能, 而且还支持子等增加列AUTO_INCREMENT属性.
不过, 因为它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引, 所以InnoDB的表比MyISAM需要更多的内存和存储.
==备注, 即便在同一个数据库中, 也可以将多种存储引擎混用, 如果需要支持事务, 可以选择InnoDB, 如果该数据库需要一个用于查询的临时表,可以选择MEMORY存储引擎 ==
索引方式
在mysql中 InnoDB和MyISAM引擎默认存储索引的结构为B+Tree, 并且此处B+树索引又分为了两类
-
聚集索引:指索引项的排序方式和表中数据记录排序方式一致的索引,
每张表只能有一个聚集索引
,聚集索引的叶子节点存储了整个行数据。一个例子
: 新华字典, 大家都用过吧, 把字典看做一张具体的数据表, 那么字典的目录就是聚集索引
, 并且字典中的拼音目录是根据从a到z来进行排列的, 而且字典中每个字也是按照拼音的首部a-z进行排列的, 这就是索引项的排序方式和表中数据记录排序方式一致。真实场景
对于InnoDB引擎表, 通常我们会设置一个主键, 并且多数时候主键是自增的, 那此刻主键便是一个聚集索引
, 如果我们对一张数据表没有明确设定主键的时候, 对于InnoDB引擎表又怎么处理呢?- 首先, 如果一张表主键被定义了, 那么这个主键就是一个聚集索引
- 其次, 如果主键没有被显示的定义, 那个该表的第一个
唯一非空索引
会作为聚集索引 - 最后, 如果没有主键, 并且
唯一索引
里面里面也没有合适的, 那么innodb内部会生成一个隐藏的主键作为聚集索引,这个隐藏的主键是一个6个字节的列,该列的值会随着数据的插入自增。
-
非聚集索引:非聚集索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同,一个表中可以拥有多个非聚集索引。叶子节点并不包含行记录的全部数据。叶子节点除了包含键值以外,还存储了一个指向改行数据的聚集索引建的书签。
在这里我们引入了一个词, 唯一索引
有人可能会看不懂, 这个下面即将说到的索引类型的中的一种, 相信看完后续篇幅应该就明白了.
索引类型
为了提高查询的效率, 我们才使用了索引, 但是索引为了应对不同的场景又分为如下几种
- 单列索引
- 普通索引
- 唯一索引
- 主键索引
- 组合索引
- 全文索引
- 空间索引
单列索引之普通索引
首先要明白的是, 单列索引是指, 一个索引只包含一个列, 但是一个表中可以建立多个单列索引
下面在来看普通索引, 顾名思义, 就是把在某一张数据表中的某一列作为索引,是Mysql中最基本的索引类型, 没有什么限制并且允许在定义索引的列中插入重复值和空值
创建方式
- 直接创建索引
CREATE INDEX index_name ON table(column(length));
- 修改表结构方式创建索引
ALTER TABLE table_name ADD INDEX index_name ON (column(length));
- 创建表的时候创建索引
CREATE TABLE `table` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`column1` char(255) CHARACTER NOT NULL ,
`column2` text CHARACTER NULL ,
PRIMARY KEY (`id`),
INDEX index_name (column1(length))
)
单列索引之唯一索引
普通索引类似,不同的就是:索引列的
值必须唯一
,但允许有空值
。如果是组合索引,则列值的组合必须唯一
, 也就是类似A+B, B+C, C+D这种, 一个数据表中不能出现两个A+B。
创建方式
- 直接创建索引
CREATE UNIQUE INDEX indexName ON table(column(length));
- 修改表结构方式创建索引
ALTER TABLE table_name ADD UNIQUE indexName ON (column(length));
- 创建表的时候创建索引
CREATE TABLE `table` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`column1` char(255) CHARACTER NOT NULL ,
`column2` text CHARACTER NULL ,
PRIMARY KEY (`id`),
UNIQUE indexName (column1(length))
)
单列索引之主键索引
可以看做是唯一索引的变种,一个表只能有
一个主键
,不允许有空值
。一般是在建表的时候同时创建主键索引
创建方式
- 直接创建索引
CREATE TABLE `table` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`column1` char(255) CHARACTER NOT NULL ,
`column2` text CHARACTER NULL ,
PRIMARY KEY (`id`)
)
组合索引
指多个字段上创建的索引,只有在查询条件中使用了
创建索引时的第一个字段
,索引才会被使用。使用组合索引时遵循最左前缀集合
解说说明最左前缀集合
一个例子
一张表中, 我们把 name
, age
, address
创建索引, 那么索引中就按照name/age/address
的顺序放置,
我们在使用的时候可以使用(name, age, address)
, 或者(name, age)
又或者(name, address)
可以看到name就被看做我们的最左前缀.
如果查询的时候使用(age, address)
, 或者(age, name)
这样的顺序是不会根据索引进行查询数据的.也就是称作一种无效查询.
创建方式
ALTER TABLE `table` ADD INDEX name_age_address ((name, age, address);
全文索引
主要用来查找文本中的关键字,而不是直接与索引中的值相比较, 用在一堆文字中,通过其中的某个关键字等,就能找到该字段所属的记录行, 例如
武汉加油
, 通过武汉
,汉
, 等等关键字可以搜到对应的整条数据.
这种索引方式在很多非关系型的数据库中都有体现, 例如ES, 或者MongoDB
特别注意在mysql中
全文索引只有在MyISAM引擎
才可以使用, 并且只有char、varchar,text
列上可以创建全文索引
空间索引
空间索引是对空间数据类型的字段建立的索引,MySQL中的空间数据类型有四种,GEOMETRY、POINT、LINESTRING、POLYGON
mysql5.7及以后版本支持, 创建时候使用SPATIAL关键字, 并且涉及的列不能为空.
这种索引, 笔者在目前的生产开发中, 没有遇到过, 避免说的不完整误导大家, 如果有需要的同学可以去参考下面一些文档
空间索引和 ST_Geometry
MySQL5.7版本空间数据参考文档
MySQL支持的空间数据格式
ST_Within
总结
- 为什么使用索引?
- 加快查询效率
- 索引的类别有?
- 单列索引
- 普通索引
- 唯一索引
- 主键索引
- 组合索引
- 全文索引
- 空间索引
- 单列索引
说到了索引
, 就不得不提起视图
, 那视图又是怎么回事, 移步《视图那些事儿----基于Mysql》
来源:CSDN
作者:Felix_XY
链接:https://blog.csdn.net/qq_32060101/article/details/104194468