Mysql经典面试题
1. 如何选择更高效的数据类型?
答:1)更小的:一般情况下,应该尽量使用较小的数据类型,更小的数据类型占用较少的磁盘空间,内存和CPU缓存,处理时候需要的CPU周期更短。
2)更简单的:简单的数据类型占用较少的CPU周期,整形比字符串类型代价低很多,因为字符集和校验规则时字符串比较更加复杂。
3)尽量避免NULL:很多表都包含可以为NULL的列,即使应用程序并不需要保存NULL也是如此,因为可为NULL是列的默认属性,通常情况下,最好指定列为非NULL,查询可为NULL的列,是的MySQL更难优化,因为我NULL的列使得索引、索引统计和值的比较都更复杂,可为NULL的列占用更多的存储空间,在MySQL里也需要特殊处理。
2. Orcale中有哪些主要的数据类型,请列表并简要描述每一种数据类型的基本特征和使用场景?
答:1)字符串类型:CHAR和VARCHAR2,NCHAR, NVARCHAR2。
2)数字类型:NUMBER(n, m) 其中n是有效位数,m是小数位数。
3)日期类型:DATE TIMESTAP, TIMESTAP WITH TIME ZONE
4)LOB类型:包括BLOB CLOB NCLOB,用于存储大型对象,比如文件文档,图片或者音频内容等。
5)RAW类型:RAW类型用于存储二进制类型,比如图像,文件文件的内容。
6)ROWID或者UROWID类型:ROWID是一个伪列,它包含每行在数据库中的唯一标识。
3. 为什么建议where中使用默认值代替null?
答:1)并不是说使用了is null或者is not null就不会走索引了,走不走索引是跟MySQL的版本以及查询优化相关的。
2)如果M有SQL发现走索引比不走索引成本还高,那么M有SQL就会发起索引,这些条件!= <> isnull, is not null经常被认为让索引失效。
3)其实是因为一般情况下,使用索引查询的成本高,优化器自动放弃使用索引的。
4)如果把null值换成默认值,那么让走索引变成可能,同时,表达意思也相当清晰一点。
4. 为什么避免在where语句中使用!= < >?
答:1)在where语句中使用!= < > 很可能让索引失效。
2)应尽量避免在where语句中使用!= < >操作符,否则引擎将放弃使用索引而进行全表扫描。
3)实现业务优先,实在没办法了,就只能使用,并不是不能使用。
5. MySQL中有哪些字符集?
答:字符集规定了字符在内存中的存储格式,不同的字符集占用的存储空间大小不同,支持的字符集列表不同。在运维和使用MySQL数据库中,选取合适的字符集非常重要,如果选择不恰当,轻则影响数据库性能,重则导致存储的数据乱码。
GBK | 2Byte | 支持中文,但不是国际通用字符集(可以在中国区使用) |
UTF-8 | 3Byte | 支持中英文混合场景,是国际通用字符集(国际包含中文的通用编码方式) |
latin1 | 1Byte | MySQL默认字符集 |
utf8mb4 | 4Byte | 完全兼容UTF-8,用四个字节存储更多的字符(同UTF-8) |
MySQL数据库在开发运维中,字符集选用规则如下所示:
1)如果系统开发面临世界业务,需要处理不同国家,不同地区语言,则应该选用UTF-8或者utf8mb4.
2)如果只需要支持中文,没有国外业务,则为了性能考虑,可以采用GBK。
6. MySQL中有那些基础函数?
答:1)LEFT(s, n), 返回字符串s的前n个字符,如果s是null,返回null值,如果n是负数,则返回一个空字符串,如果n长度大于s的长度,则返回整个s。
2)LOWER(s),将字符串s的所有大写字母转换成小写字母。
3)LPAD(s1,len, s2),在字符串s1的开始处填充字符串s2,使字符串长度达到len。如果len小于s1的长度,则返回s1缩短到len的长度,
4)LTRIM(s),去掉s左值的空格。
5)MID(s, n , len),从字符串s的n位置截取长度为len的字符串。
6)POSITION(s1 in s),从字符串s中获取s1的位置。
7)REPEAT(s, n),将字符串s重复n次。
8)REPLACE(s, s1, s2),将字符串s中的字符串s1替换为s2.
9)REVERSE(s), 将字符串的顺序翻转过来。
10)RIGHT(s, n),返回字符串s中的后n个字符
11)RPAD(s1, len, s2),在字符串s1的右侧填充s2,使得其长度达到len。
12)RTIM(s),去掉字符串s结尾处的空字符串。
13)SPACE(n),返回n个空格。
14)STRCMP(s1, s2)比较字符串s1和s2,如果s1与s2相等返回0,瑞共s1>s2返回1, 如果s1<s2,返回-1.
15)SUBSTR(s, start,length), 从字符串s的start位置截取length的子字符串
16)SUBSTRING(s, start, length),从字符串s的start位置截取length的子字符串。等同于SUBSTR(s, start, length).
17)SUBSTRING_INDEX(s, delimiter, number),返回从字符串s的第number个分隔符delimiter之后的字串,如果number是正数,返回第number个字符左边的字符串,如果number是负数,返回第number个字符右边的字符串。
18)TRIM(s),去掉字符串s开始和结尾的空字符。
19)UCASE(s), 将字符串转换为大写。
20)UPPER(s), 将字符串转换为大写。
21)CONCAT(a, b...n),合并字符串。
CONCAT_WS(x, a,b...n),合并字符串,每个字符串之间添加分隔符x。
22)ASCII(s),返回字符串s第一个字符的ASCII码值。
23)CHAR_LENGTH(s)、CHARACTER_LENGTH(s),返回字符串s的字符数量。
24)FORMAT(x, n),将x进行格式化,保留n位小数,最后进行四舍五入返回。
25)INSERT(s1,x,len, s2),将s1从x位置长度为len的字符串替换为s2.
26)LCASE(s),将字符串中的大写字母转换为小写字母。
7. MySQL中有哪些常见的数字函数?
答:1)ABS(x), 返回x的绝对值。
2)ACOS(x),返回x的余弦值(弧度制)
3)ASIN(x),返回x的反正弦值(弧度制)。
4)ATAN(x),返回x的反余弦值(弧度制)。
5)CEIL(x),返回x的向上取整。
6)EXP(x),返回x的指数。
7)FLOOR(x),返回x的向下取整。
8)ROUND(x, y),返回x四舍五入到y位。
9)SIGN(x):返回 x 的符号(正数为正,负数为负,0为 0);
10)SIN(x):返回 x 的正弦值(弧度制);
11)TAN(x):返回 x 的余弦值(弧度制);
12)POW(x, y):返回 x 的 y 次方;
8. MySQL中有哪些常见的日期函数?
答:1)日期格式化函数:DATE_FORMAT()和STR_TO_DATE()。
2)日期加减函数,DATE_ADD()和DATE_SUB().
3)时间函数NOW()和SYSDATE()
4)时间比较函数DATE_CPM()和STR_CMP()
6)日期和时间函数,CURDATE() CURTIME() CURTIMESTAMP()
7)数学函数ABS() CEIL() EXP() FLOOR() LOG() LOG10() SIN() COS() TAN() TRUNCATE() CEILING()
9. MySQL有哪些运算符?
答:1)算术运算符: + - * 、%
2)比较运算符: > < = >= >=
3)逻辑运算符: AND OR NOT
4)位运算符:&(按位与),|(安位或),(安位异或), <<(左移), >>(右移) >>>(位移)
10. 说说MySQL的执行过程?
答:只有了解Mysql是如何执行SQL语句的,才能知道如何优化SQL。
1)客户端发起连接请求到服务器。
2)服务器查询本地缓存,如果缓存命中,则直接返回结果。
3)如果缓存未命中,MySQL通过关键字将SQL语句解析,并生成一颗对应的解析树,MySQL将使用语法进行解析和验证。
4)预处理是根据一些规则检查解析树是否合理,比如检查表和列是否存在,还会解析名字和别名,然后验证权限。
5)根据执行计划查询执行引擎,调用API接口调用存储引擎查询数据。
6)将结果返回给缓存和客户端。
11. 数据库常见规范有哪些?
答:1)所有数据库对象的名称必须使用小写字母并用下划线分割。
2)所有数据库对象名称禁止使用mysql关键字。
3)数据库对象的名称要做到见名释义,并且最好不要超过32个字符。
4)临时表已tmp_为前缀并以日期后后缀,备份表必须以bak_为前缀并以日期为后缀。
5)所有存储相同数据的列和列类型必须一致。
12. 说说MySQL的三层逻辑架构图?
答:如下图所示,MySQL将数据的查询与处理与数据的存储/提取分离。
1)第一层负责连接管理、授权认证、安全等等:每个客户端的连接都对应着服务器上的一个线程。服务器上维护了一个线程池,避免为每个连接都创建销毁一个线程。当客户端连接到MySQL服务器时,服务器对其进行认证。可以通过用户名和密码的方式进行认证,也可以通过SSL证书进行认证。登录认证通过后,服务器还会验证该客户端是否有执行某个查询的权限。
2)第二层负责解析查询:编译SQL,并对其进行优化(如调整表的读取顺序,选择合适的索引等)。对于SELECT语句,在解析查询前,服务器会先检查查询缓存,如果能在其中找到对应的查询结果,则无需再进行查询解析、优化等过程,直接返回查询结果。存储过程、触发器、视图等都在这一层实现。
3)第三层是存储引擎:存储引擎负责在MySQL中存储数据、提取数据、开启一个事务等等。存储引擎通过API与上层进行通信,这些API屏蔽了不同存储引擎之间的差异,使得这些差异对上层查询过程透明。存储引擎不会去解析SQL。
13. MyISAM和InnoDB有哪些区别?
答:
功能 | MyISAM | InnoDB |
事务 | 不支持 | 支持 |
锁机制 | 表级锁 | 全局锁,表锁,行级锁 |
外键 | 不支持 | 支持 |
表主键 | 不必须有 | 必须有 |
全文搜索功能 | 支持 | 不直接支持,但可通过插件或第三方工具实现 |
崩溃恢复 | 不支持 | 支持,通过日志文件恢复数据 |
读写优化 | 无缓冲合并,写操作时全表锁定 | 无缓冲合并,写操作时全表锁定 |
缓存 | 依赖MySQL的key buffer | 有自己的缓冲池 |
行数统计 | 需要全表扫描来计算行数 | 存储了每张表的具体行数,无需全表扫描 |
适用场景 | 适合读密集型应用,对事务要求不高的场景 | 适合写密集型应用,特别是需要事务支持和数据完整性保证的场景 |
主键(primary key):是一个列或者字段,其值能够唯一标识数据库表中的每条记录,主键的值必须是唯一的,并且不为null。
外键(Forrign key): 外键是一个表中的列,它引用了另一个表的主键,通过外键,可以建立两个表中的关系。
14. 了解InnoDB的底层数据分布吗?
答:
1)因为InnoDB是聚簇索引,索引使用非常不同的方式存储数据。聚簇索引的叶子节点都包含一个主键值、事务ID、用于事务和回滚的MVCC指针,其他列。
2)InnoDB的二级索引和聚簇索引不同,InnoDB的叶子节点存储的不是行指针,而是主键值,并以此作为指向行的指针。这样的策略减少了当出现行移动或者数据页分裂时候二级索引的维护工作。
3)在InnoDB中,最好按照主键的顺序插入行,对于根据主键做关联操作的性能更好。
15. MyISAM的底层数据分布吗?
答: