Mysql中有哪些不同的引擎?
共有5种类型的引擎:
- MyISAM
- Heap
- Merge
- INNODB
- ISAM
简述在MySQL数据库中MyISAM和InnoDB的区别
MyISAM:
不支持事务,但是每次查询都是原子的;
支持表级锁,即每次操作是对整个表加锁;
存储表的总行数;
一个MYISAM表有三个文件:索引文件、表结构文件、数据文件;
每个MyISAM表格以三种格式存储在磁盘上:
·“.frm”文件存储表定义
·数据文件具有“.MYD”(MYData)扩展名
索引文件具有“.MYI”(MYIndex)扩展名
采用菲聚集索引,索引文件的数据域存储指向数据文件的指针。辅索引与主索引基本一致,但是辅索引不用保证唯一性。
InnoDb:
支持ACID的事务,支持事务的四种隔离级别;
支持行级锁及外键约束:因此可以支持写并发;
不存储总行数;
一个InnoDb引擎存储在一个文件空间(共享表空间,表大小不受操作系统控制,一个表可能分布在多个文件里),也有可能为多个(设置为独立表空,表大小受操作系统文件大小限制,一般为2G),受操作系统文件大小的限制;
主键索引采用聚集索引(索引的数据域存储数据文件本身),辅索引的数据域存储主键的值;因此从辅索引查找数据,需要先通过辅索引找到主键值,再访问辅索引;最好使用自增主键,防止插入数据时,为维持B+树结构,文件的大调整。
如何选择:
-
是否要支持事务,如果要请选择innodb,如果不需要可以考虑MyISAM;
-
如果表中绝大多数都只是读查询,可以考虑MyISAM,如果既有读写也挺频繁,请使用InnoDB
-
系统奔溃后,MyISAM恢复起来更困难,能否接受;
-
MySQL5.5版本开始Innodb已经成为Mysql的默认引擎(之前是MyISAM),说明其优势是有目共睹的,如果你不知道用什么,那就用InnoDB,至少不会差。
Mysql中有哪几种锁?
1.表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
2.行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
3. 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
Mysql中InnoDB支持的四种事务隔离级别名称,以及逐级之间的区别?
SQL标准定义的四个隔离级别为:
- read uncommited :读到未提交数据
- read committed:脏读,不可重复读
- repeatable read:可重读
- serializable :串行事物
你怎么看到为表格定义的所有索引?
索引是通过以下方式为表格定义的:
SHOW INDEX FROM
<tablename>;
什么是非标准字符串类型?
- TINYTEXT
- TEXT
- MEDIUMTEXT
- LONGTEXT
mysql里记录货币用什么字段类型好
NUMERIC和DECIMAL类型被Mysql实现为同样的类型,这在SQL92标准允许。他们被用于保存值,该值的准确精度是极其重要的值,例如与金钱有关的数据。当声明一个类是这些类型之一时,精度和规模的能被(并且通常是)指定。
例如:
salary DECIMAL(9,2)
在这个例子中,9(precision)代表将被用于存储值的总的小数位数,而2(scale)代表将被用于存储小数点后的位数。
因此,在这种情况下,能被存储在salary列中的值的范围是从-9999999.99到9999999.99。
MySQL数据库作发布系统的存储,一天五万条以上的增量,预计运维三年,怎么优化?
a. 设计良好的数据库结构,允许部分数据冗余,尽量避免join查询,提高效率。
b. 选择合适的表字段数据类型和存储引擎,适当的添加索引。
c. mysql库主从读写分离。
d. 找规律分表,减少单表中的数据量提高查询速度。
e。添加缓存机制,比如memcached,apc等。
f. 不经常改动的页面,生成静态页面。
g. 书写高效率的SQL。比如 SELECT * FROM TABEL 改为 SELECT field_1, field_2, field_3 FROM TABLE.
索引哪些情况会失效
-
查询条件包含or,可能导致索引失效
-
如何字段类型是字符串,where时一定用引号括起来,否则索引失效
-
like通配符可能导致索引失效 'aaa%' 不会失效。
-
联合索引,查询时的条件列不是联合索引中的第一个列,索引失效。
-
在索引列上使用mysql的内置函数,索引失效。
-
对索引列运算(如,+、-、*、/),索引失效。
-
索引字段上使用(!= 或者 < >,not in)时,可能会导致索引失效。
-
索引字段上使用is null, is not null,可能导致索引失效。
-
左连接查询或者右连接查询查询关联的字段编码格式不一样,可能导致索引失效。
-
mysql估计使用全表扫描要比使用索引快,则不使用索引。
索引不适合哪些场景
-
数据量少的不适合加索引
-
更新比较频繁的也不适合加索引
-
区分度低的字段不适合加索引(如性别)
索引的一些潜规则
-
覆盖索引
-
回表
-
索引数据结构(B+树)
-
最左前缀原则
-
索引下推
日常工作中你是怎么优化SQL的?
可以从这几个维度回答这个问题:
-
加索引
-
避免返回不必要的数据
-
适当分批量进行
-
优化sql结构
-
分库分表
-
读写分离
说说分库与分表的设计
分库分表方案,分库分表中间件,分库分表可能遇到的问题
分库分表方案:
-
水平分库:以字段为依据,按照一定策略(hash、range等),将一个库中的数据拆分到多个库中。
-
水平分表:以字段为依据,按照一定策略(hash、range等),将一个表中的数据拆分到多个表中。
-
垂直分库:以表为依据,按照业务归属不同,将不同的表拆分到不同的库中。
-
垂直分表:以字段为依据,按照字段的活跃性,将表中字段拆到不同的表(主表和扩展表)中。
常用的分库分表中间件:
-
sharding-jdbc(当当)
-
Mycat
-
TDDL(淘宝)
-
Oceanus(58同城数据库中间件)
-
vitess(谷歌开发的数据库中间件)
-
Atlas(Qihoo 360)
分库分表可能遇到的问题
-
事务问题:需要用分布式事务啦
-
跨节点Join的问题:解决这一问题可以分两次查询实现
-
跨节点的count,order by,group by以及聚合函数问题:分别在各个节点上得到结果后在应用程序端进行合并。
-
数据迁移,容量规划,扩容等问题
-
ID问题:数据库被切分后,不能再依赖数据库自身的主键生成机制啦,最简单可以考虑UUID
-
跨分片的排序分页问题(后台加大pagesize处理?)
数据库索引的原理,为什么要用 B+树,为什么不用二叉树?
可以从几个维度去看这个问题,查询是否够快,效率是否稳定,存储数据多少,以及查找磁盘次数,为什么不是二叉树,为什么不是平衡二叉树,为什么不是B树,而偏偏是B+树呢?
为什么不是一般二叉树?
如果二叉树特殊化为一个链表,相当于全表扫描。平衡二叉树相比于二叉查找树来说,查找效率更稳定,总体的查找速度也更快。
为什么不是平衡二叉树呢?
我们知道,在内存比在磁盘的数据,查询效率快得多。如果树这种数据结构作为索引,那我们每查找一次数据就需要从磁盘中读取一个节点,也就是我们说的一个磁盘块,但是平衡二叉树可是每个节点只存储一个键值和数据的,如果是B树,可以存储更多的节点数据,树的高度也会降低,因此读取磁盘的次数就降下来啦,查询效率就快啦。
那为什么不是B树而是B+树呢?
1)B+树非叶子节点上是不存储数据的,仅存储键值,而B树节点中不仅存储键值,也会存储数据。innodb中页的默认大小是16KB,如果不存储数据,那么就会存储更多的键值,相应的树的阶数(节点的子节点树)就会更大,树就会更矮更胖,如此一来我们查找数据进行磁盘的IO次数有会再次减少,数据查询的效率也会更快。
2)B+树索引的所有数据均存储在叶子节点,而且数据是按照顺序排列的,链表连着的。那么B+树使得范围查找,排序查找,分组查找以及去重查找变得异常简单。
聚集索引与非聚集索引的区别
-
一个表中只能拥有一个聚集索引,而非聚集索引一个表可以存在多个。
-
聚集索引,索引中键值的逻辑顺序决定了表中相应行的物理顺序;非聚集索引,索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同。
-
索引是通过二叉树的数据结构来描述的,我们可以这么理解聚簇索引:索引的叶节点就是数据节点。而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块。
-
聚集索引:物理存储按照索引排序;非聚集索引:物理存储不按照索引排序;
何时使用聚集索引或非聚集索引?
数据库自增主键可能遇到什么问题。
-
使用自增主键对数据库做分库分表,可能出现诸如主键重复等的问题。解决方案的话,简单点的话可以考虑使用UUID哈
-
自增主键会产生表锁,从而引发问题
-
自增主键可能用完问题。
MVCC熟悉吗,它的底层原理?
MVCC,多版本并发控制,它是通过读取历史版本的数据,来降低并发事务冲突,从而提高并发性能的一种机制。
MVCC需要关注这几个知识点:
-
事务版本号
-
表的隐藏列
-
undo log
-
read view
说一下大表查询的优化方案
-
优化shema、sql语句+索引;
-
可以考虑加缓存,memcached, redis,或者JVM本地缓存;
-
主从复制,读写分离;
-
分库分表;
InnoDB引擎中的索引策略,了解过吗?
-
覆盖索引
-
最左前缀原则
-
索引下推
一条sql执行过长的时间,你如何优化,从哪些方面入手?
-
查看是否涉及多表和子查询,优化Sql结构,如去除冗余字段,是否可拆表等
-
优化索引结构,看是否可以适当添加索引
-
数量大的表,可以考虑进行分离/分表(如交易流水表)
-
数据库主从分离,读写分离
-
explain分析sql语句,查看执行计划,优化sql
-
查看mysql执行日志,分析是否有其他方面的问题
创建索引有什么原则呢?
-
最左前缀匹配原则
-
频繁作为查询条件的字段才去创建索引
-
频繁更新的字段不适合创建索引
-
索引列不能参与计算,不能有函数操作
-
优先考虑扩展索引,而不是新建索引,避免不必要的索引
-
在order by或者group by子句中,创建索引需要注意顺序
-
区分度低的数据列不适合做索引列(如性别)
-
定义有外键的数据列一定要建立索引。
-
对于定义为text、image数据类型的列不要建立索引。
-
删除不再使用或者很少使用的索引
为什么要使用视图?什么是视图?
为什么要使用视图?
为了提高复杂SQL语句的复用性和表操作的安全性,MySQL数据库管理系统提供了视图特性。
什么是视图?
视图是一个虚拟的表,是一个表中的数据经过某种筛选后的显示方式,视图由一个预定义的查询select语句组成。
61. 视图有哪些特点?哪些使用场景?
视图特点:
-
视图的列可以来自不同的表,是表的抽象和在逻辑意义上建立的新关系。
-
视图是由基本表(实表)产生的表(虚表)。
-
视图的建立和删除不影响基本表。
-
对视图内容的更新(添加,删除和修改)直接影响基本表。
-
当视图来自多个基本表时,不允许添加和删除数据。
视图用途: 简化sql查询,提高开发效率,兼容老的表结构。
视图的常见使用场景:
-
重用SQL语句;
-
简化复杂的SQL操作。
-
使用表的组成部分而不是整个表;
-
保护数据
-
更改数据格式和表示。视图可返回与底层表的表示和格式不同的数据。
62. 视图的优点,缺点,讲一下?
-
查询简单化。视图能简化用户的操作
-
数据安全性。视图使用户能以多种角度看待同一数据,能够对机密数据提供安全保护
-
逻辑数据独立性。视图对重构数据库提供了一定程度的逻辑独立性
count(1)、count(*) 与 count(列名) 的区别?
-
count(*)包括了所有的列,相当于行数,在统计结果的时候,不会忽略列值为NULL
-
count(1)包括了忽略所有列,用1代表代码行,在统计结果的时候,不会忽略列值为NULL
-
count(列名)只包括列名那一列,在统计结果的时候,会忽略列值为空(这里的空不是只空字符串或者0,而是表示null)的计数,即某个字段值为NULL时,不统计。
71. varchar(50)中50的涵义
-
字段最多存放 50 个字符
-
如 varchar(50) 和 varchar(200) 存储 "jay" 字符串所占空间是一样的,后者在排序时会消耗更多内存
72. mysql中int(20)和char(20)以及varchar(20)的区别
-
int(20) 表示字段是int类型,显示长度是 20
-
char(20)表示字段是固定长度字符串,长度为 20
-
varchar(20) 表示字段是可变长度字符串,长度为 20
73. drop、delete与truncate的区别
delete | truncate | drop | |
类型 | DML | DDL | DDL |
回滚 | 可回滚 | 不可回滚 | 不可回滚 |
删除内容 | 表结构还在,删除表的全部或者一部分数据行 | 表结构还在,删除表中的所有数据 | 从数据库中删除表,所有的数据行,索引和权限也会被删除 |
删除速度 | 删除速度慢,逐行删除 | 删除速度快 | 删除速度最快 |
共同点:
都可以清空表中的数据。
不同点:
truncate:
1)truncate在使用时,不能加where条件。
2)truncate执行操作时,速度更快 且 不可回滚;是因为:TRUNCATE操作不会记录到事务日志中,而DELETE操作会记录到事务日志中,记录日志会耗时,所以TRUNCATE要快于DELETE 且 truncate不可回滚。
3)truncate删除表数据是:先删除整张表包括数据,再重新创建表,因此,若果表中有自增长,会把自增长id 重置成1开始。 delete删除表数据时, 每次从表中删除一行。
4)表和索引所占空间。 当表被TRUNCATE 后,这个表和索引所占用的空间会恢复到初始大小,而DELETE操作不会减少表或索引所占用的空间。drop语句将表所占用的空间全释放掉。
5)应用范围。TRUNCATE 只能对TABLE;DELETE可以是table和view
6) truncate、drop是DLL(data define language),操作立即生效,不会记录到事务日志中去
7)在没有备份情况下,谨慎使用 drop 与 truncate。要删除部分数据行采用delete且注意结合where来约束影响范围
89. MySQL中DATETIME和TIMESTAMP的区别
存储精度都为秒
区别:
-
DATETIME 的日期范围是 1001——9999 年;TIMESTAMP 的时间范围是 1970——2038 年
-
DATETIME 存储时间与时区无关;TIMESTAMP 存储时间与时区有关,显示的值也依赖于时区
-
DATETIME 的存储空间为 8 字节;TIMESTAMP 的存储空间为 4 字节
-
DATETIME 的默认值为 null;TIMESTAMP 的字段默认不为空(not null),默认值为当前时间(CURRENT_TIMESTAMP)
如何查找慢sql
1.开启慢sql日志
2.执行计划
explain
mysql锁原理
mysql日志分类
参考
mysql
https://www.cnblogs.com/setalone/p/14851000.html
https://www.cnblogs.com/williamjie/p/11081592.html
https://zhuanlan.zhihu.com/p/59838091