☆* o(≧▽≦)o *☆嗨~我是小奥🍹
📄📄📄个人博客:小奥的博客
📙📙📙Github:传送门
📅📅📅面经分享(牛客主页):传送门
🍹文章作者技术和水平有限,如果文中出现错误,希望大家多多指正!
📜 如果觉得内容还不错,欢迎点赞收藏关注哟! ❤️
MySQL面试题汇总
基础
数据库三大范式
第一范式:数据库的每一列都是不可分割的原子项。
第二范式:在第一范式的基础上,非主键列完全依赖于主键,而不能是依赖于主键的一部分。
第三范式:在第二范式的基础上,非主键只依赖于主键,不依赖于其他非主键,即不存在依赖传递。
char和varchar的区别
(1)存储方式:char
类型的数据是定长的,当存储时,MySQL会将所有的字符都填充到定长,检索时会去掉空格,因此存储时占用的空间固定;而varchar
类型的数据是变长的,它只会存储实际使用的字符,因此存储时占用的空间是可变的。
(2)**查找效率:**char的查找效率比varchar要高。
(3)**字符串长度:**char类型的数据长度是固定的,可以存储0到255个字符,而varchar类型的数据长度是可变的,可以存储0到65535个字符。
(4)**使用场景:**通常,char类型的数据适合存储长度固定的数据,例如国家代码、邮编等;而varchar类型的数据适合存储长度不固定的数据,例如用户名、地址等。
drop、truncate和delete的区别
(1)作用范围:drop会删除整张表和表结构,以及表的索引、约束和触发器;truncate只删除全部表数据,表的结构、索引、约束等会被保留;delete只删除表的全部或者部分数据,表结构、约束、索引等会被保留。
(2)作用方式:delete是DML(data maintain language)语句,执行删除操作的过程是每次从表中删除一行,并同时将该行的删除操作作为事务记录在日志中保存以便于进行回滚操作;truncate、drop是DLL(data define language)语句,删除行是不能恢复的,并且在删除过程中不会激活与表有关的触发器,执行速度比较块,原数据不放到rollback segment中,不能回滚。
(3)条件限制:truncate和drop不支持添加where条件,而delete支持where条件。
(4)执行速度:执行速度drop > truncate > delete,delete是逐行执行的,并且在执行时会把操作日志记录下来,以备日后回滚使用,所以delete的执行速度是比较慢的;而truncate的操作是先复制一个新的表结构,然后删除掉原来的表,所以它的执行速度居中,而drop的执行速度最快。
select from a,b和join的区别
(1)select from a,b
使用的是SQL隐式连接(也被称为笛卡尔积),对于表a中的每一行,都会将表b中的所有行与之匹配,生成一个新的结果集。这种连接通常会导致结果集非常大,因为它将两个表中的所有数据都组合在一起,而且没有经过任何的筛选或者限制。
(2)join
使用的SQL的显示连接,它使用on
子句来指定连接条件,只有满足条件的数据行才会被返回,这种连接方式可以减少结果集的大小,同时还可以更加精细的筛选和限制。
left join 和 inner join的区别
- left join会返回左表中的所有记录和右表中满足连接条件的记录;而inner join只会返回两个表中满足连接条件的记录。
- left join右表关联不上的数据会用null表示;而inner join关联不上的数据直接舍弃。
left join和right join
外连接通过outer join来实现,它将返回两张表中满足连接条件的数据,同时返回不满足条件的数据。
外连接有两种形式:左连接和右连接。
-
左外连接
left join on
:简称为左连接,它会返回左表中的所有记录和右表中满足连接条件的记录。- 两表关联,左表全部保留,右表关联不上用null表示。
select 字段列表 from 表1 left [outer] join 表2 on 条件 ...;
-
右外连接
right join on
:简称为右连接,它会返回右表中的所有记录和左表中满足连接条件的记录。- 两表关联,右表全部保留,左表关联不上用null表示。
select 字段列表 from 表1 right [outer] join 表2 on 条件 ...;
-
全连接
union
:两表的内容均保留,没有关联的字段用null表示。在mysql中使用union表示。select 字段列表 from 表A union [ALL] select 字段列表 from 表B
对于联合查询的多张表的列表必须要保持一致,字段类型也要保持一致。
union all 会将全部的数据直接合并在一起,union会对合并之后的数据去重。
group by的用法
group by一般用于分组统计,就是可以根据一个或者多个字段,对查询到的数据进行分组。
group by如果单独使用的话,会返回每组第一行的数据。
group by的常规用法就是配合聚合函数,利用分组信息进行统计,同时还可以配合having进行筛选过滤。
另一方面,having子句中不能使用除了分组字段和聚合函数之外的其他字段。
Limit分页的用法
limit子句可以用于强制select语句返回指定的记录数。
select 字段 from 表名 limit 参数1,参数2;
select 字段 from 表名 limit 参数2 offset 参数1;(为了与 PostgreSQL 兼容)
参数1:指定第一个返回记录行的偏移量,从0开始
参数2:指定返回记录行的最大数目
如果只给定一个参数,那么表示返回的最大记录行数目。
如果第二个参数为-1,表示第一个参数的偏移量之后的所有的数据
where和having的区别
(1)where是一个约束声明,在对查询结果返回之前将不符合where条件的数据给去掉,where是在结果返回之前起作用的,where中不能使用聚合函数,即使用where条件过滤出特定的行。
(2)having是一个过滤声明,是在查询返回结果集以后对查询结果进行的过滤操作,在having中可以使用聚合函数。另一方面,having子句中不能使用除了分组字段和聚合函数之外的其他字段。
从性能的角度来说,HAVING子句中如果使用了分组字段作为过滤条件,应该替换成WHERE子句。因为WHERE可以在执行分组操作和计算聚合函数之前过滤掉不需要的数据,性能会更好。
一般情况下:
- where用于过滤数据行,而having用于过滤分组;
- where查询条件中不可以使用聚合函数,而having查询条件中<