MySQL数据库(一)

MySQL数据库(一)

    • 1.为什么要使用数据库
    • 2.什么是SQL?什么是MySQL?
    • 3.mysql的存储引擎
    • 4.MySQL存储引擎MyISAM与InnoDB区别?
    • 5.MyISAM索引与InnoDB索引的区别?
    • 6.InnoDB引擎的4大特性
    • 7.如何选择存储引擎
    • 8.什么是索引?
    • 9.索引有哪些优缺点?
    • 10.索引使用场景
    • 11.索引有哪几种类型?
    • 12.索引算法有哪些?
    • 13.创建索引的原则
    • 14.使用索引查询一定能提高查询的性能吗?为什么
    • 15.百万级别或以上的数据如何删除
    • 16.B树和B+树的区别
    • 17.Hash索引和B+树所有有什么区别或者说优劣呢?
    • 18.数据库为什么使用B+树而不是B树
    • 19.什么是聚簇索引?何时使用聚簇索引与非聚簇索引
    • 20.B+树在满足聚簇索引和覆盖索引的时候为什么不需要回表查询数据?
    • 21.非聚簇索引一定会回表查询吗?
    • 22.联合索引是什么?为什么需要注意联合索引中的顺序?

1.为什么要使用数据库

(1)数据保存在内存

优点:存取速度快

缺点:数据不能永久保存

(2)数据保存在文件

优点:数据永久保存

缺点:1)速度比内存操作慢,频繁的IO操作。2)查询数据不方便

(3)数据保存在数据库

1)数据永久保存

2)使用SQL语句,查询方便效率高。

3)管理数据方便

2.什么是SQL?什么是MySQL?

结构化查询语言(Structured Query Language)简称SQL,是一种数据库查询语言。

MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。在Java企业级开发中非常常用,因为 MySQL 是开源免费的,并且方便扩展。MySQL的默认端口号是3306。

3.mysql的存储引擎

存储引擎的概念是MySQL里面才有的,不是所有的关系型数据库都有存储引擎这个概念。我们都知道录制一个视频文件,可以转换成不同的格式,例如mp4,avi,wmv等,而存在我们电脑的磁盘上也会存在于不同类型的文件系统中如windows里常见的ntfs、fat32。那么数据库表里的数据存储在数据库里及磁盘上和上述的视频格式及存储磁盘文件的系统格式特征类似,也有很多种存储方式。

所以存储引擎就是在如何存储数据、提取数据、更新数据等技术方法的实现上,底层的实现方式不同,那么就会呈现出不同存储引擎有着一些自己独有的特点和功能,对应着不同的存取机制。

关系型数据库:关系型数据库存储数据是以表的形式,数据之间是通过二维表的形式联系起来的。
优点:支持SQL,查询方便。
缺点:在数据量较大时,查询效率很低。无法支持高并发的场景。

非关系型数据库:它不是以表的形式存储的,通常是以键值对的方式存储。比如redis数据库。
优点:查询性能较好,因为是存储在内存中的。
支持的并发量较大

查看MySQL提供的所有存储引擎

mysql> show engines;

我们可以查看出 MySQL 当前默认的存储引擎是InnoDB,并且在5.7版本所有的存储引擎中只有 InnoDB 是事务性存储引擎,也就是说只有 InnoDB 支持事务。

4.MySQL存储引擎MyISAM与InnoDB区别?

(1)Innodb引擎:Innodb引擎提供了对数据库ACID事务的支持。并且还提供了行级锁和外键的约束。它的设计的目标就是处理大数据容量的数据库系统。

(2)MyIASM引擎(原本Mysql的默认引擎):不提供事务的支持,也不支持行级锁和外键。

5.MyISAM索引与InnoDB索引的区别?

MySQL索引使用的数据结构主要有BTree索引 和 哈希索引 。我们经常使用的InnoDB存储引擎的默认索引实现为:B+树索引。对于哈希索引来说,底层的数据结构就是哈希表,因此在绝大多数需求为单条记录查询的时候,可以选择哈希索引,查询性能最快;其余大部分场景,建议选择BTree索引。

MySQL的BTree索引使用的是B树中的B+Tree,但对于主要的两种存储引擎的实现方式是不同的。

  • MyISAM: B+Tree叶节点的data域存放的是数据记录的地址。在索引检索的时候,首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其 data 域的值,然后以 data 域的值为地址读取相应的数据记录。这被称为“非聚簇索引”。
  • InnoDB: 其数据文件本身就是索引文件。相比MyISAM,索引文件和数据文件是分离的,其表数据文件本身就是按B+Tree组织的一个索引结构,树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。这被称为“聚簇索引(或聚集索引)”。而其余的索引都作为辅助索引,辅助索引的data域存储相应记录主键的值而不是地址,这也是和MyISAM不同的地方。在根据主索引搜索时,直接找到key所在的节点即可取出数据;在根据辅助索引查找时,则需要先取出主键的值,再走一遍主索引。 因此,在设计表的时候,不建议使用过长的字段作为主键,也不建议使用非单调的字段作为主键,这样会造成主索引频繁分裂。

(1)InnoDB索引是聚簇索引,MyISAM索引是非聚簇索引。

(2)InnoDB的主键索引的叶子节点存储着行数据,因此主键索引非常高效。

(3)MyISAM索引的叶子节点存储的是行数据地址,需要再寻址一次才能得到数据。

(4)InnoDB非主键索引的叶子节点存储的是主键和其他带索引的列数据,因此查询时做到覆盖索引会非常高效。

6.InnoDB引擎的4大特性

(1)插入缓冲(insert buffer)

(2)二次写(double write)

(3)自适应哈希索引(ahi)

(4)预读(read ahead)

7.如何选择存储引擎

如果没有特别的需求,使用默认的Innodb即可。

MyISAM:以读写插入为主的应用程序,比如博客系统、新闻门户网站。

Innodb:更新(删除)操作频率也高,或者要保证数据的完整性;并发量高,支持事务和外键。比如OA自动化办公系统。

8.什么是索引?

索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。

索引是一种数据结构。数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B+树。

更通俗的说,索引就相当于目录。为了方便查找书中的内容,通过对内容建立索引形成目录。索引是一个文件,它是要占据物理空间的。

索引用来快速地寻找那些具有特定值的记录。如果没有索引,一般来说执行查询时遍历整张表。

9.索引有哪些优缺点?

(1)索引的优点

可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。

(2)索引的缺点

时间方面:创建索引和维护索引要耗费时间,具体地,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,会降低增/改/删的执行效率;

空间方面:索引需要占物理空间。

10.索引使用场景

(1)where

//向表t_user添加主键索引PRIMARY KEY id
ALTER TABLE `t_user ` ADD PRIMARY KEY ( `id` ) 
select * from t_user where id < 20

根据id查询记录,因为id字段仅建立了主键索引,因此此SQL执行可选的索引只有主键索引,如果有多个,最终会选一个较优的作为检索的依据。
(2)order by

当我们使用order by将查询结果按照某个字段排序时,如果该字段没有建立索引,那么执行计划会将查询出的所有数据使用外部排序。这个操作是很影响性能的,因为需要将查询涉及到的所有数据从磁盘中读到内存(如果单条数据过大或者数据量过多都会降低效率),更无论读到内存之后的排序了。

但是如果我们对该字段建立索引,

alter table 表名 add index(字段名)

那么由于索引本身是有序的,因此直接按照索引的顺序和映射关系逐条取出数据即可。而且如果分页的,那么只用取出索引表某个范围内的索引对应的数据,而不用像上述那取出所有数据进行排序再返回某个范围内的数据。

11.索引有哪几种类型?

(1)主键索引: 数据列不允许重复,不允许为NULL,一个表只能有一个主键。

(2)唯一索引: 数据列不允许重复,允许为NULL值,一个表允许多个列创建唯一索引。

ALTER TABLE table_name ADD UNIQUE (column);

可以通过 ALTER TABLE table_name ADD UNIQUE (column1,column2); 创建唯一组合索引

(3)普通索引: 基本的索引类型,没有唯一性的限制,允许为NULL值。

ALTER TABLE table_name ADD INDEX index_name (column);

可以通过ALTER TABLE table_name ADD INDEX index_name(column1, column2, column3);创建组合索引

(4)全文索引:是目前搜索引擎使用的一种关键技术。

ALTER TABLE table_name ADD FULLTEXT (column);

12.索引算法有哪些?

(1)BTree算法

BTree是最常用的mysql数据库索引算法,也是mysql默认的算法。因为它不仅可以被用在=,>,>=,<,<=和between这些比较操作符上,而且还可以用于like操作符,只要它的查询条件是一个不以通配符开头的常量, 例如:

-- 只要它的查询条件是一个不以通配符开头的常量
select * from user where name like 'jack%'; 
-- 如果一通配符开头,或者没有使用常量,则不会使用索引,例如: 
select * from user where name like '%jack'; 

(2)Hash算法

Hash索引只能用于对等比较,例如=,<=>(相当于=)操作符。由于是一次定位数据,不像BTree索引需要从根节点到枝节点,最后才能访问到页节点这样多次IO访问,所以检索效率远高于BTree索引。

13.创建索引的原则

索引虽好,但也不是无限制的使用,最好符合一下几个原则

1) 最左前缀匹配原则,组合索引非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。

2)较频繁作为查询条件的字段才去创建索引

3)更新频繁字段不适合创建索引

4)若是不能有效区分数据的列不适合做索引列(如性别,男女未知,最多也就三种,区分度实在太低)

5)尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。

6)定义有外键的数据列一定要建立索引。

7)对于那些查询中很少涉及的列,重复值比较多的列不要建立索引。

8)对于定义为text、image和bit的数据类型的列不要建立索引。

14.使用索引查询一定能提高查询的性能吗?为什么

通常,通过索引查询数据比全表扫描要快。但我们也要注意到它的代价。

(1)索引需要空间来存储,也需要定期维护, 每当有记录在表中增减或索引列被修改时,索引本身也会被修改。这意味着每条记录的INSERT,DELETE,UPDATE将为此多付出4,5 次的磁盘I/O。因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢。

(2)使用索引查询不一定能提高查询性能,索引范围查询(INDEX RANGE SCAN)适用于两种情况:

基于一个范围的检索,一般查询返回结果集小于表中记录数的30%

基于非唯一性索引的检索

15.百万级别或以上的数据如何删除

我们删除数据库百万级别数据的时候,查询MySQL官方手册得知删除数据的速度和创建的索引数量是成正比的。

(1)可以先删除索引(此时大概耗时三分多钟)

(2)然后删除其中无用数据(此过程需要不到两分钟)

(3)删除完成后重新创建索引(此时数据较少了)创建索引也非常快,约十分钟左右。

与之前的直接删除绝对是要快速很多,万一删除中断,一切删除会回滚。

16.B树和B+树的区别

(1)在B树中,你可以将键和值存放在内部节点和叶子节点;但在B+树中,内部节点都是键,没有值,叶子节点同时存放键和值。

(2)B+树的叶子节点有一条链相连,而B树的叶子节点各自独立。
MySQL数据库(一)_第1张图片

17.Hash索引和B+树所有有什么区别或者说优劣呢?

首先要知道Hash索引和B+树索引的底层实现原理:

hash索引底层就是hash表,进行查找时,调用一次hash函数就可以获取到相应的键值,之后进行回表查询获得实际数据。B+树底层实现是多路平衡查找树。对于每一次的查询都是从根节点出发,查找到叶子节点方可以获得所查键值,然后根据查询判断是否需要回表查询数据。

那么可以看出他们有以下的不同:

(1)hash索引进行等值查询更快(一般情况下),但是却无法进行范围查询。因为在hash索引中经过hash函数建立索引之后,索引的顺序与原顺序无法保持一致,不能支持范围查询。而B+树的的所有节点皆遵循(左节点小于父节点,右节点大于父节点,多叉树也类似),天然支持范围。

(2)hash索引不支持使用索引进行排序,原理同上。

(3)hash索引不支持模糊查询以及多列索引的最左前缀匹配。原理也是因为hash函数的不可预测。AAAA和AAAAB的索引没有相关性。

(4)hash索引任何时候都避免不了回表查询数据,而B+树在符合某些条件(聚簇索引,覆盖索引等)的时候可以只通过索引完成查询。

(5)hash索引虽然在等值查询上较快,但是不稳定。性能不可预测,当某个键值存在大量重复的时候,发生hash碰撞,此时效率可能极差。而B+树的查询效率比较稳定,对于所有的查询都是从根节点到叶子节点,且树的高度较低。

因此,在大多数情况下,直接选择B+树索引可以获得稳定且较好的查询速度。而不需要使用hash索引。

18.数据库为什么使用B+树而不是B树

(1)B树只适合随机检索,而B+树同时支持随机检索和顺序检索;

(2)B+树空间利用率更高,可减少I/O次数,磁盘读写代价更低。一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。这样的话,索引查找过程中就要产生磁盘I/O消耗。B+树中间节点没有数据,只有索引,而B树每个结点中的每个关键字都有卫星数据;这就意味着同样的大小的磁盘页可以容纳更多节点元素,在相同的数据量下,B+树更加扁平,IO操作更少 。

什么是索引的io操作?为什么不使用平衡二叉树?

B树和B+树的出现是因为另外一个问题,那就是磁盘IO;众所周知,IO操作的效率很低,那么,当在大量数据存储中,查询时我们不能一下子将所有数据加载到内存中,只能逐一加载磁盘页,每个磁盘页对应树的节点。造成大量磁盘IO操作(最坏情况下为树的高度)。平衡二叉树由于树深度过大而造成磁盘IO读写过于频繁,进而导致效率低下。

但是m值也不是越大越好,因为不管是内存中的数据,还是磁盘中的数据,操作系统都是按页(一页大小通常是4KB,这个值可以通过getconfig PAGE_SIZE命令查看)来读取的,一次只会读一页的数据。如果要读取的数据量超过一页的大小,就会触发多次IO操作。所以,我们在选择m大小的时候,要尽量让每个节点的大小等于一个页的大小。读取一个节点,只需要一次磁盘IO操作。

(3)B+树的查询效率更加稳定。B树搜索有可能会在非叶子结点结束,越靠近根节点的记录查找时间越短,只要找到关键字即可确定记录的存在,其性能等价于在关键字全集内做一次二分查找。而在B+树中,顺序检索比较明显,随机检索时,任何关键字的查找都必须走一条从根节点到叶节点的路,所有关键字的查找路径长度相同,导致每一个关键字的查询效率相当。

(4)B树在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题。B+树的叶子节点使用指针顺序连接在一起,只要遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作。

(5)增删文件(节点)时,效率更高。因为B+树的叶子节点包含所有关键字,并以有序的链表结构存储,这样可很好提高增删效率。

19.什么是聚簇索引?何时使用聚簇索引与非聚簇索引

(1)聚簇索引:将数据存储与索引放到了一块,找到索引也就找到了数据

(2)非聚簇索引:将数据存储于索引分开结构,索引结构的叶子节点指向了数据的对应行,myisam通过key_buffer把索引先缓存到内存中,当需要访问数据时(通过索引访问数据),在内存中直接搜索索引,然后通过索引找到磁盘相应数据,这也就是为什么索引不在key buffer命中时,速度慢的原因。

20.B+树在满足聚簇索引和覆盖索引的时候为什么不需要回表查询数据?

在B+树的索引中,叶子节点可能存储了当前的key值,也可能存储了当前的key值以及整行的数据,这就是聚簇索引和非聚簇索引。在InnoDB中,只有主键索引是聚簇索引,如果没有主键,则挑选一个唯一键建立聚簇索引。如果没有唯一键,则隐式的生成一个键来建立聚簇索引。

当查询使用聚簇索引时,在对应的叶子节点,可以获取到整行数据,因此不用再次进行回表查询。

21.非聚簇索引一定会回表查询吗?

不一定,这涉及到查询语句所要求的字段是否全部命中了索引,如果全部命中了索引,那么就不必再进行回表查询。

举个简单的例子,假设我们在员工表的年龄上建立了索引,那么当进行:

select age from employee where age < 20

该查询时,由于只查询age值,而在索引的叶子节点上,已经包含了age信息,不会再次进行回表查询。

22.联合索引是什么?为什么需要注意联合索引中的顺序?

MySQL可以使用多个字段同时建立一个索引,叫做联合索引。在联合索引中,如果想要命中索引,需要按照建立索引时的字段顺序挨个使用,否则无法命中索引

具体原因为:

MySQL使用索引时需要索引有序,假设现在建立了"name,age,school"的联合索引,那么索引的排序为: 先按照name排序,如果name相同,则按照age排序,如果age的值也相等,则按照school进行排序。实际上这就是一个决策树,必须按顺序输入查询条件

因此在建立联合索引的时候应该注意索引列的顺序,一般情况下,将查询需求频繁或者字段选择性高的列放在前面。此外可以根据特例的查询或者表结构进行单独的调整。

你可能感兴趣的:(MySQL)