数据库基础知识(必读)

参考文章:

事务

1、什么是数据库事务?事务的属性?

事务指单个逻辑单元执行的一系列操作,要么都执行,要么都不执行。

一个逻辑单元要成为事务,必须满足ACID的属性,即原子性、一致性、隔离性、持久性

原子性:

一件事情会有多个动作,必须都执行或都不执行。事务是最小的执行单位,不可分割

一致性:

数据库的数据要在事务前后保持一致。

隔离性:

对同一个表并发进行多个事务,事务间相互隔离。

持久性:

一旦事情commit,不可更改,持久生效。

AUTOCOMMIT

MySQL 默认采用自动提交模式。也就是说,如果不显式使用 START TRANSACTION 语句来开始一个事务,那么每个查询都会被当做一个事务自动提交。

2、并发事务带来哪些问题?

脏读:

一个事务读取到被另一个事务修改当还未提交的数据,依据“脏数据”所做的操作可能是不正确的。

丢失修改:

一个事务修改了被另一个事务修改当还未提交的数据,先提交的事务的修改就会丢失

不可重复读:

指在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务修改了该数据。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。

幻读:

一个事务读取一个范围内的数据,另一个事务向这个范围内插入了一些数据,在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。

不可重复读和幻读区别:

不可重复读的重点是对单条记录的修改,比如多次读取一条记录发现其中某些列的值被修改;幻读的重点在于对多条记录的新增或者删除,比如多次读取一个范围的记录发现记录增多或减少了。

产生并发不一致性问题主要原因是破坏了事务的隔离性,解决方法是通过并发控制来保证隔离性。并发控制可以通过来实现,但是加锁操作需要用户自己控制,相当复杂。数据库管理系统提供了事务的隔离级别,让用户以一种更轻松的方式处理并发一致性问题。

 

3、事务隔离级别有哪些? MySQL的默认隔离级别是?

SQL 标准定义了四个隔离级别:

READ-UNCOMMITTED(未提交读): 

最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读

READ-COMMITTED(提交读): 
允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
REPEATABLE-READ(可重复读):
对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生
SERIALIZABLE(可串行化):
最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读

4、事务隔离级别的RR和RC是怎么实现的

相关语法

1、建表的原则(三大范式)

第一范式(1NF)

    属性不可分

第二范式

符合第一范式,且非主属性完全依赖于码,消除了部分依赖 --> 非主属性不能完全依赖于码的一部分,如(A, B)是码,非主属性 C 依赖于 (A, B), 但是如果同时 A -> C, 即 C 又依赖于 A ,那么就存在部分依赖,这时 C 属性应该从表中脱离出来,与 A共同 成为一张表

第三范式

符合第二范式,且消除传递依赖,也就是每个非主属性都不传递依赖于候选键,即如果存在 A -> B -> C, 这时就存在传递依赖,C 应该从表中脱离出来 与 B 共同形成一张表。

BC范式

符合3NF,并且,消除每一个属性对候选键的传递依赖

2、MySQL外连接知道吗?左外连接和右外连接是什么,有什么区别?什么是内连接,完全连接

外连接分为左外连接和右外连接

左(外)连接,左表(a_table)的记录将会全部表示出来,而右表(b_table)只会显示符合搜索条件的记录。右表记录不足的地方均为NULL

与左(外)连接相反,右(外)连接,左表(a_table)只会显示符合搜索条件的记录,而右表(b_table)的记录将会全部表示出来。左表记录不足的地方均为NULL。

完全连接就是左表和右表都是展示所有记录

内连接是左右表都只显示符合搜索条件的记录

性能优化

1、mysql性能优化



MySQL 索引

索引是在存储引擎层实现的,而不是在服务器层实现的,所以不同存储引擎具有不同的索引类型和实现。

 

索引的优点

1. 通过建立索引树,从上往下搜索索引树大大减少了服务器需要扫描的数据行数。
2. 帮助服务器避免进行排序和分组,以及避免创建临时表(B+Tree 索引是有序的,可以用于 ORDER BY 和 GROUP BY 操作。临时表主要是在排序和分组过程中创建,不需要排序和分组,也就不需要创建临时表)。
3. 将随机 I/O 变为顺序 I/O(B+Tree 索引是有序的,会将相邻的数据都存储在一起)。

为什么不对表的每个列创建一个索引

1. 索引会占内存空间
2. 维护索引和修改索引有一定的开销

索引选取类型

    1、越小的数据类型通常更好:越小的数据类型通常在磁盘、内存和CPU缓存中都需要更少的空间,处理起来更快。
    2、简单的数据类型更好:整型数据比起字符,处理开销更小,因为字符串的比较更复杂。
    3、尽量避免NULL:应该指定列为NOT nuLL,在MySQL中, 含有空值的列很难进行查询优化,因为它们使得索引、索引的统计信息以及比较运算更加复杂

什么场景不适合创建索引

    第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因 为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。
    第二,对于那 些只有很少数据值的列也不应该增加索引。因为本来结果集合就是相当于全表查询了,所以没有必要。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比 例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。
    第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。
    第四,当修改开销远远大于检索开销时,不应该创建索 引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因 此,当修改性能远远大于检索性能时,不应该创建索引。
    第五,不会出现在where条件中的字段不该建立索引。

什么样的字段适合创建索引

1、表的主键、外键必须有索引;外键是唯一的,而且经常会用来查询
2、数据量超过300的表应该有索引;
3、经常与其他表进行连接的表,在连接字段上应该建立索引;经常连接查询,需要有索引
4、经常出现在Where子句中的字段,加快判断速度,特别是大表的字段,应该建立索引,建立索引,一般用在select ……where f1 and f2 ,我们在f1或者f2上建立索引是没用的。只有两个使用联合索引才能有用
5、经常用到排序的列上,因为索引已经排序。
6、经常用在范围内搜索的列上创建索引,因为索引已经排序了,其指定的范围是连续的

索引失效:

所谓的索引失效指的是:假如or连接的俩个查询条件字段中有一个没有单列索引的话,引擎会放弃索引而产生全表扫描。

 

索引物理分类

 

聚簇索引和非聚簇索引

所谓聚集和非聚集:非聚集索引叶子页包含一个指向表中的记录的指针地址,记录的物理顺序和索引的顺序不一致;聚集索引则数据行和键值一起保存在叶子页  而且记录的排列顺序与索引的排列顺序一致。
由于InnoDB正式按照 聚集索引的结构来存储表的,聚簇索引的索引是主键,所以只能故一张表只能有一个聚簇索引。辅助索引的存在不影响聚簇索引中数据的组织,所以一张表可以有多个辅助索引
InnoDB 的主键索引是 聚簇索引, 辅助索引是 非聚簇索引,叶子结点存储的的是主键和关键字。
MyISAM 的主键索引和辅助索引都是 非聚簇索引。

聚簇索引的优缺点

优点:
1.数据访问更快,因为聚簇索引将索引和数据保存在同一个B+树中,因此从聚簇索引中获取数据比非聚簇索引更快,
2.  聚簇索引对于主键的排序查找和范围查找速度非常快
缺点:
   1.  插入速度严重依赖于插入顺序,按照主键的顺序插入是最快的方式,否则将会出现页分裂,严重影响性能。因此,对于InnoDB表,我们一般都会定义一个自增的ID列为主键
   2.  更新主键的代价很高,因为将会导致被更新的行移动。因此,对于InnoDB表,我们一般定义主键为不可更新。
   3.二级索引访问需要两次索引查找,第一次找到主键值,第二次根据主键值找到行数据。

索引逻辑分类

mysql的索引分为单列索引(主键索引,唯一索引,普通索引)和组合索引。
单列索引:一个索引只包含一个列,一个表可以有多个单列索引。
组合索引:一个组合索引包含两个或两个以上的列,
 

前缀索引

对于列的值较长,比如BLOB、TEXT、VARCHAR,就必须建立前缀索引,即将值的前一部分作为索引。这样既可以节约空间,又可以提高查询效率。但无法使用前缀索引做 ORDER BY 和 GROUP BY,也无法使用前缀索引做覆盖扫描。

覆盖索引

索引的字段正好是覆盖查询语句[select子句]与查询条件[Where子句]中所涉及的字段。能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了

覆盖索引的优化及限制

 覆盖索引是一种非常强大的工具,能大大提高查询性能,只需要读取索引而不需要读取数据,有以下优点:

 1、索引项通常比记录要小,所以MySQL访问更少的数据。

 2、索引都按值得大小存储,相对于随机访问记录,需要更少的I/O。

 3、数据引擎能更好的缓存索引,比如MyISAM只缓存索引。

 4、覆盖索引对InnoDB尤其有用,因为InnoDB使用聚集索引组织数据,如果二级索引包含查询所需的数据,就不再需要在聚集索引中查找了。

 限制:

 1、覆盖索引也并不适用于任意的索引类型,索引必须存储列的值。

 2、Hash和full-text索引不存储值,因此MySQL只能使用BTree。

 3、不同的存储引擎实现覆盖索引都是不同的,并不是所有的存储引擎都支持覆盖索引。

 4、如果要使用覆盖索引,一定要注意SELECT列表值取出需要的列,不可以SELECT * ,因为如果将所有字段一起做索引会导致索引文件过大,查询性能下降。

 

最左前缀原则:

顾名思义是最左优先,以最左边的为起点任何连续的索引都能匹配上,
注:如果第一个字段是范围查询需要单独建一个索引
注:在创建联合索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。这样的话扩展性较好,比如 userid 经常需要作为查询条件,而 mobile 不常常用,则需要把 userid 放在联合索引的第一位置,即最左边

同时存在联合索引和单列索引(字段有重复的),这个时候查询mysql会怎么用索引呢?

这个涉及到mysql本身的查询优化器策略了,当一个表有多条索引可走时, Mysql 根据查询语句的成本来选择走哪条索引;

联合索引本质:

 

当创建(a,b,c)联合索引时,相当于创建了(a)单列索引,(a,b)联合索引以及 (a,b,c)联合索引,想要索引生效的话,只能使用 a和a,b和a,b,c三种组合;当然,我们上面测试过,a,c组合也可以,但实际上只用到了a的索引,c并没有用到!

通俗理解:

利用索引中的附加列,您可以缩小搜索的范围,但使用一个具有两列的索引 不同于使用两个单独的索引。复合索引的结构与电话簿类似,人名由姓和名构成,电话簿首先按姓氏对进行排序,然后按名字对有相同姓氏的人进行排序。如果您知道姓,电话簿将非常有用;如果您知道姓和名,电话簿则更为有用,但如果您只知道名不姓,电话簿将没有用处。

所以说创建复合索引时,应该仔细考虑列的顺序。对索引中的所有列执行搜索或仅对前几列执行搜索时,复合索引非常有用;仅对后面的任意列执行搜索时,复合索引则没有用处。

复合索引与单列索引的比较:

1. 如果表中大多数都是单条件查询,那用单列索引更划得来

2. 有多条件联合查询时最好建联合索引,多个单列索引在多条件查询时优化器会选择最优索引策略,可能只用一个索引,也可能将多个索引全用上! 但多个单列索引底层会建立多个B+索引树,比较占用空间,也会浪费一定搜索效率,

其他知识点:

 

1、需要加索引的字段,要在where条件中
2、数据量少的字段不需要加索引;因为建索引有一定开销,如果数据量小则没必要建索引(速度反而慢)
3、避免在where子句中使用or来连接条件,因为如果俩个字段中有一个没有索引的话,引擎会放弃索引而产生全表扫描
4、联合索引比对每个列分别建索引更有优势,因为索引建立得越多就越占磁盘空间,在更新数据的时候速度会更慢。另外建立多列索引时,顺序也是需要注意的,应该将严格的索引放在前面,这样筛选的力度会更大,效率更高

索引的底层实现

btree、b+tree

1. B+Tree 索引

是大多数 MySQL 存储引擎的默认索引类型。

因为不再需要进行全表扫描,只需要对树进行搜索即可,所以查找速度快很多。

因为 B+ Tree 的有序性,所以除了用于查找,还可以用于排序和分组。

可以指定多个列作为索引列,多个索引列共同组成键。

适用于全键值、键值范围和键前缀查找,其中键前缀查找只适用于最左前缀查找。如果不是按照索引列的顺序进行查找,则无法使用索引。

InnoDB 的 B+Tree 索引分为主索引和辅助索引。主索引的叶子节点 data 域记录着完整的数据记录,这种索引方式被称为聚簇索引。因为无法把数据行存放在两个不同的地方,所以一个表只能有一个聚簇索引。

辅助索引的叶子节点的 data 域记录着主键的值,因此在使用辅助索引进行查找时,需要先查找到主键值,然后再到

主索引中进行查找。

2. 哈希索引

哈希索引能以 O(1) 时间进行查找,但是失去了有序性:

无法用于排序与分组;

只支持精确查找,无法用于部分查找和范围查找。

InnoDB 存储引擎有一个特殊的功能叫“自适应哈希索引”,当某个索引值被使用的非常频繁时,会在 B+Tree 索引之

上再创建一个哈希索引,这样就让 B+Tree 索引具有哈希索引的一些优点,比如快速的哈希查找。

3、BST(二叉查找树)

  1.vs二分查找,BST在左右子树节点个数差不多时,查找性能逼近二分查找,但在增删节点时,BST需要的内存比二分查找少。2.缺点:平衡性差,动态增删节点可能导致退化为链表,查找效率降低。
3.4AVL树vsRBtree: avl树是严格平衡树,而rbtree是弱平衡树,都是通过旋转来保持平衡,而在增删节点时,严格平衡树旋转的次数比弱平衡旋转的次数多,当搜索节点的次数远远大于增删节点的次数时,旋转AVL树,当搜索节点的次数与增删节点的次数差不多时选择RBtree效率高。

4、磁盘读取及预读的过程及时间消耗?

定位柱面时间(最长)、旋转至扇区时间、读写扇区时间

5、btree定义?

1.每个节点最多有 m 个子树
2.若根不是叶子结点,则根节点至少有两个子树
3.分支节点至少拥有m/2棵子树(除根和叶子)
4.所有叶子节点都在同一层,这些叶子结点不存储有效的信息
5. 每个节点最多可以有m-1个 key 并且升序排列,相同数量的 key 在btree中生成的节点要远远小于二叉搜索树节点,相差的节点数目正比于树的高度正比与磁盘io的次数,达到一定数量时,性能差异明显。

6、为什么btree查找效率高?

多路查找-->降低树的高度-->减少磁盘io的次数-->节省磁盘访问的时间-->更快定位到数据库文件
查找效率高有两个原因,一是多路性,每个结点有若干个关键字,相同数量的 key 在btree中生成的节点要远远小于二叉搜索树节点,相差的节点数目正比于树的高度正比与磁盘io的次数,达到一定数量时,性能差异明显。二是平衡性,所以他效率稳定,不像二叉查找树那样会退化成链表。

7、btree节点如何定义?vs二叉搜索树 

二叉搜索树:key、value、left指针、right指针  
btree节点:多个key key1 key2..多个value value1 value2..多个pointer指针 pointer1、pointer2..

8、 b+tree 与B树的区别

1. 叶子节点包含了所有关键字信息以及指向这些关键字记录的指针,并且叶子节点大小本身就是从小到大的顺序链接。
2. 所有的非终端结点可以看成是索引部分,不含有效信息 (而B 树的非终节点也包含需要查找的有效信息)

9、 为什么b+tree比btree更适合做文件的索引、数据库索引?

1.btree在提高磁盘 io 性能同时并没有解决元素遍历效率低下的问题,b+tree只要遍历叶子节点就可遍历整棵树。
2.在数据库中基于范围的查找很频繁,btree每次都要从根节点查,效率低。b+tree只要找到范围左边界的叶子结点,可以顺着叶子结点,找到相应范围的所有元素。
3. B+-tree的查询效率更加稳定

由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当

补充

真实数据库中的B+树应该是非常扁平的,也就是说高度非常小,也就说叉数非常多,每个结点的字树非常多,而且B+树的索引节点是非常小的,一次性可以加载到内存,这样就可以用少量的内存换取只需一次访存即可获取到数据的恐怖效率。

B+树的叉数可以达到1000多叉,存储 22G 容量的表高度也才3层,一次访存即可获取数据。

 

10、b+树和b树分别有什么应用

 
B树和B+树大量应用在数据库和文件系统当中。但是多采用B+树,文件系统和数据库的索引都是存在硬盘上的,并且如果数据量大的话,不一定能一次性加载到内存中。
mongoDB数据库用的是B树

11、hashmap为什么用红黑树不用b树

因为如果采用b树的话,在数据量不是很多的情况下,数据都会“挤在”一个结点里面。这个时候遍历效率就退化成了链表。

4. 解释一下什么是池化设计思想。什么是数据库连接池?为什么需要数据库连接池?

池话设计应该不是一个新名词。我们常见的如java线程池、jdbc连接池、redis连接池等就是这类设计的代表实现。这种设计会初始预设资源,解决的问题就是抵消每次获取资源的消耗,如创建线程的开销,获取远程连接的开销等。就好比你去食堂打饭,打饭的大妈会先把饭盛好几份放那里,你来了就直接拿着饭盒加菜即可,不用再临时又盛饭又打菜,效率就高了。除了初始化资源,池化设计还包括如下这些特征:池子的初始值、池子的活跃值、池子的最大值等,这些特征可以直接映射到java线程池和数据库连接池的成员属性中。——这篇文章对池化设计思想介绍的还不错,直接复制过来,避免重复造轮子了。

数据库连接本质就是一个 socket 的连接。数据库服务端还要维护一些缓存和用户权限信息之类的 所以占用了一些内存。我们可以把数据库连接池是看做是维护的数据库连接的缓存,以便将来需要对数据库的请求时可以重用这些连接。为每个用户打开和维护数据库连接,尤其是对动态数据库驱动的网站应用程序的请求,既昂贵又浪费资源。在连接池中,创建连接后,将其放置在池中,并再次使用它,因此不必建立新的连接。如果使用了所有连接,则会建立一个新连接并将其添加到池中。连接池还减少了用户必须等待建立与数据库的连接的时间。

   这种设计会初始预设资源,解决的问题就是抵消每次获取资源和释放资源造成的开销。连接池也是这样,预先创建好一个连接池,在池中创建一定数量的连接,每当用户需要连接数据库,就从池中取出一个连接,使用完毕之后放回池中,这既可以减少连接创建和释放的开销,便于连接的管理,也可以降低用户等待数据库的延迟。

攻击

 

sql注入攻击

简介:

SQL注入是普通常见的网络攻击方式之一,它的原理是通过在参数中输入特殊符号,来篡改并通过程序SQL语句的条件判断。
比如:
用户名:1
密  码:1' OR '1'='1
那么程序接收到参数后,SQL语句就变成了:SELECT * FROM user WHERE name = '1' and password= '1' OR '1'='1 ';
或者
用户名:1'; DROP DATABASE root;--
密码:1
那么程序接收到参数后,SQL语句就变成了:SELECT * FROM user WHERE name = '1'; DROP DATABASE root;--and password= '1';

解决办法:

1. 不允许带有特殊字符
2. 对单引号或双引号进行转义
3. 对 sql 语句进行预编译,因为SQL注入攻击只对SQL语句的编译过程有破坏作用,进行预编译后,传入的参数只作为字符串,不会再进行一次编译,SQL注入攻击也就失效了

MySQL 的体系结构

MySQL是由连接池、管理工具和服务、SQL接口、解析器、优化器、缓存、存储引擎、文件系统组成。

连接池:

由于每次建立连接需要消耗很多时间,连接池的作用就是将这些连接缓存下来,下次可以直接用已经建立好的连接,提升服务器性能。

管理工具和服务:

系统管理和控制工具,例如备份恢复、Mysql复制、集群等

SQL接口:

接受用户的SQL命令,并且返回用户需要查询的结果。比如select from就是调用SQL Interface

解析器: 

SQL命令传递到解析器的时候会被解析器验证和解析。比如验证是否符合语法树等
解析器是由Lex和YACC实现的,是一个很长的脚本, 主要功能:
a . 将SQL语句分解成数据结构,并将这个结构传递到后续步骤,以后SQL语句的传递和处理就是基于这个结构的
b. 如果在分解构成中遇到错误,那么就说明这个sql语句是不合理的

优化器:

查询优化器,SQL语句在查询之前会使用查询优化器对查询进行优化。他使用的是“选取-投影-联接”策略进行查询。
用一个例子就可以理解: select uid,name from user where gender = 1;
这个select 查询先根据where 语句进行选取,而不是先将表全部查询出来以后再进行gender过滤
这个select查询先根据uid和name进行属性投影,而不是将属性全部取出以后再进行过滤
将这两个查询条件联接起来生成最终查询结果

缓存器: 

查询缓存,如果查询缓存有命中的查询结果,查询语句就可以直接去查询缓存中取数据。
通过LRU算法将数据的冷端溢出,未来得及时刷新到磁盘的数据页,叫脏页。
这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key缓存,权限缓存等

存储引擎

通过 show engines; 可以查看数据库的储引擎插件
负责MySQL中数据的存储与提取。 服务器中的查询执行引擎通过API与存储引擎进行通信,通过接口屏蔽了不同存储引擎之间的差异。关系数据库中数据的存储是以表的形式存储的,所以说存储的一张张的表,而不是一个个的数据库。MySQL采用插件式的存储引擎,所以只要给数据库提供插件,就可以增加存储引擎,MySql数据库提供了多种存储引擎。用户可以根据不同的需求为数据表选择不同的存储引擎,用户也可以根据自己的需要编写自己的存储引擎。甚至一个库中不同的表使用不同的存储引擎,这些都是允许的。

MyISAM存储引擎

由于该存储引擎不支持事务、也不支持外键,所以访问速度较快。因此当对事务完整性没有要求并以访问为主的应用适合使用该存储引擎。

 

文件:
.frm文件:与表相关的元数据信息都存放在frm文件,包括表结构的定义信息等。
.MYD文件:MyISAM存储引擎专用,用于存储MyISAM表的数据
.MYI文件:MyISAM存储引擎专用,用于存储MyISAM表的索引相关信息

InnoDB存储引擎

mysql 5.5版本以后默认的存储引擎
由于该存储引擎在事务上具有优势,即支持具有提交、回滚及崩溃恢复能力等事务特性,他在运行时会在内存中建立缓冲池,用于缓冲数据和索引。支持行锁,并发度高。主键索引为聚簇索引,所以比MyISAM存储引擎占用更多的磁盘空间。因此当需要频繁的更新、删除操作,同时还对事务的完整性要求较高,需要实现并发控制,建议选择。

 

文件:
.frm文件:与表相关的元数据信息都存放在frm文件,包括表结构的定义信息等。

.ibd文件:存放innodb表的数据文件。

MEMORY

MEMORY存储引擎存储数据的位置是内存,因此访问速度最快,但是安全上没有保障。适合于需要快速的访问或临时表。

BLACKHOLE

黑洞存储引擎,写入的任何数据都会消失,可以应用于主备复制中的分发主库。

存储引擎的另一个知识总结

InnoDB 和 MyISAM 的区别:

目前比较普及的存储引擎是MyISAM和InnoDB。MyISAM与InnoDB的主要的不同点在于性能和事务控制上。MyISAM是早期ISAM(Indexed Sequential Access Method 索引顺序存取法,MySQL5.0之后已经不支持ISAM了)的扩展实现
ISAM被设计为适合处理读频率远大于写频率这样的情况,因此ISAM以及后来的MyISAM都没有考虑对事物的支持,排除了TPM,不需要事务记录,ISAM的查询效率相当可观,而且内存占用很少。
MyISAM在继承了这类优点的同时,与时俱进地提供了大量实用的新特性和相关工具。例如考虑到并发控制,提供了表级锁
InnoDB被设计成适用于高并发读写的情况,支持兼容ACID的事务(类似于PostgreSQL),以及参数 完整性(即对外键的支持)。一般来说,如果需要事务支持,并且有较高的并发读写频率,InnoDB是不错的选择。

InnoDB引擎

InnoDB是一个事务型的存储引擎,支持回滚,设计目标是处理大量数据时提供高性能的服务,它在运行时会在内存中建立缓冲池,用于缓冲数据和索引

InnoDB引擎优点

1、支持事务处理、ACID事务特性;
2、实现了SQL标准的四种隔离级别;
3、支持行级锁和外键约束,行锁优点是粒度小,适用于高并发的频繁表修改,高并发使性能优于 MyISAM。缺点是系统消耗较大。4、可以利用事务日志进行数据恢复。

InnoDB引擎缺点

1. 因为它没有保存表的行数,当使用COUNT统计时会扫描全表。
2、索引不仅缓存自身,也缓存数据,相比 MyISAM 需要更大的内存。

MyISAM引擎

MyISAM 是 MySQL 5.5.5 之前的默认引擎,它的设计目标是快速读取。

MyISAM引擎优点

1.高性能读取;
2.因为它保存了表的行数,当使用COUNT统计时不会扫描全表;

MyISAM引擎缺点

1、锁级别为表锁,表锁优点是开销小,加锁快;缺点是锁粒度大,发生锁冲动概率较高,容纳并发能力低,这个引擎适合查询为主的业务。
2、此引擎不支持事务,也不支持外键。
3、INSERT和UPDATE操作需要锁定整个表;

适用场景

MyISAM适合:(1)做很多count 的计算;(2)插入不频繁,查询非常频繁;(3)没有事务。
InnoDB适合:(1)可靠性要求比较高,或者要求事务;(2)表更新和查询都相当的频繁,并且表锁定的机会比较大的情况。

补充:

OLTP(联机事务处理)和OLAP(联机分析处理)

OLTP用于存储和管理日常操作的数据;

OLAP用于分析这些数据

posted @ 2020-12-18 11:38  Lucky小黄人^_^  阅读(837)  评论(0编辑  收藏  举报