2022年SQL经典面试题总结(带解析)

吐血整理了一周SQL面试题,包括了选择题、问答题、实战题。每道题都给大家加了详细的解析。几乎每个知识点都涉及到了。

刷完这套题,关于SQL的面试妥妥的。

题目来源:各大厂面试题、牛客网

一、选择题

(1)基础题

1、要求删除商品表中价格大于3000的商品,下列SQL语句正确的是()

A、DELETE FROM 商品 WHERE 价格>3000
B、DELETE * FROM 商品 WHERE 价格>3000
C、DELETE FROM 商品
D、UPDATE 商品 SET * =NULL WHERE 价格>3000

正确答案: A
答案解析:这道题考察的是delete语法
DELETE FROM table_name
WHERE some_column=some_value;

2、在book表中,将工具书类型(tool)的书的书架序号都减少2,下列语句正确的是()

A、UPDATE books SET shelf = shelf - 2 WHERE type IS ‘tool’;
B、INSERT books SET shelf = shelf - 2 WHERE type IS ‘tool’;
C、UPDATE books SET shelf = shelf - 2 WHERE type = ‘tool’;
D、UPDATE books INTO shelf = shelf - 2 WHERE type = ‘tool’;

正确答案: C
答案解析:这道题考察的是update语法。
UPDATE table_name
SET column1=value1,column2=value2,…
WHERE some_column=some_value;
where后面语句,查找NUll值的时候可以用 type IS NUll,否则要用等于=

3、为职员表添加列,列名为年末奖金,允许为空值,数据类型为货币数据类型。下列SQL语句正确的是()

A、ATER TABLE 职员 ADD 年末奖金 NULL
B、ALTER TABLE 职员 ADD 年末奖金 Money NULL
C、ALTER TABLE 职员 ADD 年末奖金 Money NOT NULL
D、ALTER TABLE 职员 ADD 年末奖金 INT NULL

正确答案: B
答案解析:这道题考察的是alter语法。如果你想在已有的表中,添加、删除或修改列,就需要用到alter语句。
添加列: ALTER TABLE table_name ADD column_name datatype
修改列:在SQL Server中与MySQL中修改列的语句有所差异,这里要注意~
My SQL / Oracle:ALTER TABLE table_name MODIFY COLUMN column_name datatype
SQL Server:ALTER TABLE table_name ALTER COLUMN column_name datatype
删除列:ALTER TABLE table_name DROP COLUMN column_name
mysql没有money类型 sql server才有money类型,所以在读题的时候要注意是否提到在mysql中。
money其实跟float是同类型数据。money类型只是显示在数据表的时候前面多加一个$样式的符号。

4、小李在创建完一张数据表后,发现少创建了一列,此时需要修改表结构,应该用哪个语句进行操作?

A、MODIFY TABLE
B、INSERT TABLE
C、ALTER TABLE
D、UPDATE TABLE

正确答案: C
答案解析:巩固一下上一题,修改已有的表,就用alter语句。
ALTER TABLE 表名 add 字段名

5、SQL语言可以分为多个类别,那么不属于数据操纵语言DML的是()

A、update
B、grant
C、delete
D、insert

正确答案: B
答案解析:grant语句是用来赋予用户权限的,是数据控制语言(DCL)。其他3个都是数据操纵语言(DML)
数据查询语言(DQL):是由SELECT子句,FROM子句,WHERE子句组成的查询块
数据操纵语言(DML): SELECT(查询) INSERT(插入) UPDATE(更新) DELETE(删除)
数据定义语言(DDL):CREATE(创建数据库或表或索引)ALTER(修改表或者数据库)DROP(删除表或索引)
数据控制语言(DCL):GRANT(赋予用户权限) REVOKE(收回权限) DENY(禁止权限)
事务控制语言(TCL):SAVEPOINT (设置保存点)ROLLBACK (回滚) COMMIT(提交)

6、下列选项中使用别名的方法不正确的是()

A、字段名称=别名
B、字段名称 AS 别名
C、字段名称 别名
D、别名=字段名称

正确答案: D
答案解析:给字段名称起别名,B、C选项没有疑义,as可以省略
A选项,字段名称=别名,在SQL Server中可以这样使用,MySQL中则不可以。
如果没有特别指明是在mysql中,我们默认就在SQL Server中。

(多选题)7、在MySql中进行数据查询时,如果要对查询结果的列名重新命名,将sno列重新命名为学号,则下列语句正确的是( )

A、select sno as 学号 from T
B、select 学号= sno from T
C、select sno 学号 from T
D、select sno=学号 from T

正确答案: A C
答案解析:巩固一下上一题,在SQL Server 中可以使用’=’,MySQL中则不可以

8、在SQL中用条件表示价格在在30至40之间,应该如何表达?

A、in (30,40)
B、BETWEEN 30 AND 40
C、BETWEEN 30 OR 40
D、BETWEEN 30 TO 40

正确答案: B
答案解析:这道题考察的是BETWEEN … AND …知识点

9、SQL语句中与Having子句同时使用的语句是?()

A、Group By
B、联盟链
C、left Join
D、Where

正确答案: A
答案解析:having和where作用差不多,都是用来筛选数据的。
having作用在分组之后,也就是要放在group by的后面

10、已知数据表STU,现需创建视图view_s,显示所有男同学的信息。下列SQL语句正确的是()

A、CREATE VIEW AS SELECT * FROM STU
B、CREATE VIEW view_s AS SELECT * FROM STU WHERE 性别=‘男’
C、CREATE view_s SELECT * FROM STU WHERE 性别=‘男’
D、CREATE view_s AS SELECT * FROM STU

正确答案: B
答案解析:这道题考察的是VIEW 创建视图知识点
将查询语句放在create views view_name as 后面,这样查询语句的结果就会存储在视图中,后面可以继续调用这个视图数据,或者直接在视图中查询。
视图可以当成表格来用。
CREATE VIEW view_name AS
SELECT column_name(s) FROM table_name
WHERE condition
CREATE后面要加上VIEW,不然数据库怎么知道你要创建啥~

11、Mysql中表student_info(id,name,birth,sex),字段类型都是varchar,插入如下记录:(‘1014’ , ‘张三’ , ‘2002-01-06’ , ‘男’); 下面SQL错误的是()?

A、insert into student_info values(‘1014’ , ‘张三’ , ‘2002-01-06’ , ‘男’);
B、insert into table student_info values(‘1014’ , ‘张三’ , ‘2002-01-06’ , ‘男’);
C、insert into student_info(id,name,birth,sex) values(‘1014’ , ‘张三’ , ‘2002-01-06’ , ‘男’);
D、insert into student_info(id,name,sex,birth,) values(‘1014’ , ‘张三’ , ‘男’,‘2002-01-06’ );

正确答案:B
答案解析:这道题比较简单,考察的知识点是:insert插入数据的语法。
insert into 后面直接跟表名。
insert into table,这种语法就不对。
有些同学可能会选择D,觉得顺序不对。但前面指明的列顺序,与后面是对应的(id,name,sex,birth,) values(‘1014’ , ‘张三’ , ‘男’,'2002-01-06’ )

12、将成绩表(grade)按成绩(point)升序排列,下列语句错误的是()

A、SELECT * FROM grade ORDER BY point;
B、SELECT point FROM grade ORDER BY point;
C、SELECT * FROM grade ORDER BY point ASC;
D、SELECT * FROM grade ORDER BY point DESC;

正确答案: D
答案解析:这道题考察的是group by语句中是升序,降序
A、B选项没有特意指定,默认是升序。
ASC 表示升序,DESC 表示降序,所以D是错的

(2)进阶题

1、Mysql中表student_table(id,name,birth,sex),插入如下记录:

(‘1001’ , ‘’ , ‘2000-01-01’ , ‘男’);
(‘1002’ , null , ‘2000-12-21’ , ‘男’);
(‘1003’ , NULL , ‘2000-05-20’ , ‘男’);
(‘1004’ , ‘张三’ , ‘2000-08-06’ , ‘男’);
(‘1005’ , ‘李四’ , ‘2001-12-01’ , ‘女’);
查询2001年及之后出生的男生、女生总数,正确的SQL是()?

A、select sex,count() from student_table group by sex where birth >=‘2001’ ;
B、select count(
) from student_table where birth >=‘2001’ group by sex ;
C、select sex,count() from student_table where birth >=‘2001’ group by sex ;
D、select sex,count(
) from student_table group by sex having birth >='2001’ ;

正确答案: C
答案解析:这道题考察的是select语句中group by分组知识点。
where应该放在group by 的前面,排除A
group by后面的字段都要在select后面出现,B选择中的sex,没有在select后面出现,排除B
Having后面可以跟字段和聚合函数,having后面的字段,也是只能使用在select后面出现的字段。排除D

2、某IT公司人事管理采用专门的人事管理系统来实现。后台数据库名为LF。新来的人事部张经理新官上任,第一件事是要对公司的员工做全面的了解。可是他在访问员工信息表EMPL里的工资和奖金字段的时被拒绝,只能查看该表其他字段。作为LF的开发者你将如何解决这一问题:( )

A、废除张经理的数据库用户帐户对表EMPL里的工资列和奖金列的SELECT权限
B、添加张经理到db_datareader角色
C、添加张经理到db_accessadmin角色
D、授予张经理的数据库用户帐户对表EMPL里的工资列和奖金列的SELECT权限。

正确答案: D
db_accessadmin
可以添加、删除用户的用户
db_datareader
可以从所有数据表中读取所有数据,人事经理只是想访问员工信息表,不需要给这么大权限。

3、下列函数语句得不到相同数值结果的选项是()

A、SELECT ROUND(2.35)
B、SELECT ROUND(1.96,1)
C、SELECT TRUNCATE(1.99,1)
D、SELECT TRUNCATE(2.83,0)

正确答案: C
ROUND() 函数用于把数值字段舍入为指定的小数位数,第二个参数表示保留几位小数。ROUND(2.35)结果为2,ROUND(1.96,1)结果为2.0
TRUNCATE() 函数是按照小数位数进行数值截取,没有四舍五入。第二个参数表示保留几位小数。TRUNCATE(1.99,1)结果为1.9,TRUNCATE(2.83,0)结果为2

4、在STUDENT表中按class_type统计数据行数分组情况后,筛选出数据行数为大于10行的组

A、SELECT class_type,COUNT() FROM STUDENT GROUP BY class_type HAVING COUNT()>10
B、SELECT class_type,COUNT() FROM STUDENT GROUP BY class_type WHERE COUNT()=10
C、SELECT class_type,COUNT() FROM STUDENT HAVING COUNT()>10 GROUP BY class_type
D、SELECT class_type,COUNT() FROM STUDENT WHERE COUNT()>10 GROUP BY class_type

正确答案:A
答案解析:这道题是根据class_type分组后,找出每组大于10行的数据,考察的知识点是:where和having的区别。
where和having作用差不多,都是用来筛选数据的。
having作用在分组之后,也就是要放在group by的后面,where放在group by的前面。这样就排除了B、C
count(*)是聚合函数,意思是查询每组有多少条数据记录。having后面可以跟聚合函数,where后面不能跟聚合函数。排除了D

5、查询语句select stuff(‘lo ina’,3, 1, ‘ve ch’)结果为?
A、love
B、love china
C、china love
D、china

正确答案: B
答案解析:stuff(原字符, 开始位置, 删除长度, 插入字符)
stuff函数是从指定的起点处开始删除指定长度的字符,并在此处插入另一组字符

6、已知某期刊信息库中有作家信息表author(作者编号aid,作者姓名aname,作者笔名ausername,作者邮箱aemail,备注remarks),稿件表manuscript(稿件编号mid,标题mtitle,作者编号aid,交稿时间mtime)现需要设置外键作者编号,下列语句正确的是()

A、ALTER TABLE manuscript
ADD CONSTRAINT FK_aid
FOREIGN KEY (aid) REFERENCES author (aid)

B、ALTER TABLE manuscript
ADD CONSTRAINT FK_aid
FOREIGN KEY (manuscript.aid) REFERENCES author (aid)

C、ALTER TABLE manuscript
ADD FOREIGN KEY (manuscript.aid)
REFERENCES author (aid)

D、ALTER TABLE manuscript
ADD FOREIGN KEY (aid)
REFERENCES author (aid)

正确答案: B
答案解析:这道题考察的是设置外键的语法。
alter table 表名 add constraint FK_ID foreign key(你的外键字段名) REFERENCES 外表表名(对应的表的主键字段名);

(多选题)7、使用SQL语句建个存储过程proc_stu,然后以student表中的学号Stu_ID为输入参数@s_no,返回学生个人的指定信息。下面创建存储过程语句正确的是:( )

A、CREATE PROCEDURE [stu].[proc_student]
@s_no AS int
AS
BEGIN
select * from stu.student where Stu_ID=@s_no
END

B、CREATE PROCEDURE [stu].[proc_student]
@s_no int
AS
BEGIN
select * from stu.student where Stu_ID=@s_no
END

C、CREATE PROCEDURE [stu].[proc_student]
@s_no int
AS
BEGIN
select * from stu.student where s_no=@s_no
END

D、CREATE PROCEDURE [stu].[proc_student]
@s_no AS int
AS
BEGIN
select * from stu.student where Stu_ID=@Stu_ID
END

正确答案: A B
答案解析:这道题主要考的是where后面跟的参数怎样赋值。where 表字段=参数。Stu_ID是表格字段,@s_no是参数。

8、请取出 BORROW表中日期(RDATE字段)为当天的所有记录?(RDATE字段为datetime型,包含日期与时间)。SQL语句实现正确的是:( )
A、select * from BORROW where datediff(dd,RDATE,getdate())=0
B、select * from BORROW where RDATE=getdate()
C、select * from BORROW where RDATE-getdate()=0
D、select * from BORROW where RDATE > getdate()

正确答案:A
答案解析:这道题考察的是datediff() 函数。datediff() 函数的意思是返回两个日期之间的时间差。
datediff(dd,RDDATE,getdate())==0是意思是表中日期(RDDATE)与当前日期(getdate())这两个日期相同,就为true。就会取出这天的记录。
dd是日,ww是周,mm是月,hh小时,mi分钟,ss秒

9、Mysql中表student_table(id,name,birth,sex),插入如下记录:
(‘1001’ , ‘’ , ‘2000-01-01’ , ‘男’);
(‘1004’ , ‘张三’ , ‘2000-08-06’ , ‘男’);
(‘1005’ , NULL , ‘2001-12-01’ , ‘女’);
(‘1006’ , ‘张三’ , ‘2001-12-02’ , ‘女’);
执行
select t1.name from
(select * from student_table where sex = ‘女’)t1
left join
(select * from student_table where sex = ‘男’)t2
on t1.name = t2.name;
的结果行数是()?

A、4
B、3
C、2
D、1

正确答案:C
答案解析:这道题考察的是left join 左连接,
左连接就是不管有没有符合条件的数据,都会将左边表的数据全部展示。
这里左边的表是t1 ,查出了所有性别为女的数据,就是两条。后面不管跟上面查询条件,这两条数据都会显示出来。

(多选题)10、下面有关sql 语句中 delete、truncate的说法正确的是?()(多选题)
A、论清理表数据的速度,truncate一般比delete更快
B、truncate命令可以用来删除部分数据。
C、truncate只删除表的数据不删除表的结构
D、delete能够回收高水位(自增ID值)

正确答案:A、C
答案解析:这道题考察的是trustcate与delete的区别
在处理效率方面:drop>trustcate>delete
删除记录方面:drop删除整个表、trustcate删除全部记录但不删除表、delete删除部分记录高高水线方面delete不影响所用extent,高水线保持原位置不动;trustcate会将高水线复位。

11、检索销量表中销量最好的商品id和销量,下列SQL语句正确的是()
A、SELECT 商品id,销量 FROM 销量表 WHERE 销量=MAX(销量)
B、SELECT 商品id,MAX(销量) FROM 销量表 GROUP BY 销量
C、SELECT 商品id,MAX(销量) FROM 销量表 GROUP BY 商品id
D、SELECT 商品id,销量 FROM 销量表 WHERE 销量=(SELECT MAX(销量) FROM 销量表)

正确答案:D
答案解析:最后表格输出的结果最好的商品id和销量,
A选项语法错了,where后面不能跟聚合函数,having后面可以跟
B选项语法错了,group by后面的字段,需要再select后面字段中提到
C选项把商品id字段分类,再对销量取最大值,实际作用是将商品id去重+查询商品id和对应销量,如果分类字段没有重复数据,效果等同‘ select * from 销量表 ’,不符合题意。
D选项是对的,先用子查询找到最大的销量的具体值,在找对应具体值的商品名。

12、Mysql中表student_table(id,name,birth,sex),查询不重复的姓名总数,错误的是()?
A、select count(distinct name) from student_table ;
B、select count(name) from (select distinct name from student_table) t1
C、select count(name) from (select name,count(*) as c1 from student_table group by name having c1 > 1)t1
D、select count(name) from (select name from student_table group by name) t1;

正确答案:C
答案解析:因为我们要查询不重复的表名,having c1>1这里错了,c1 >1不就相当于有多个姓名,这里应该是c1 = 1。

(多选题)13、在SQL中语法规范中,having子句的使用下面描述正确的是:( )

A、having子句即可包含聚合函数作用的字段也可包括普通的标量字段
使用having的同时不能使用where子句
B、having子句必须于group by 子句同时使用,不能单独使用
使用having子句的作用是限定分组条件
C、having子句和where子句是等同的
D、having子句后面必须使用聚合函数

正确答案: A C
答案解析:
D选项,group by的作用限定分组条件,不是having
E选项:having子句和where子句作用差不多,但是也有区别,并不是等同的。
F选择:没有函数,也可以使用having,但是要注意,having里面包含的字段,必须在select语句中提到。

14、假设创建新用户nkw,现在想对于任何IP的连接,仅拥有user数据库里面的select和insert权限,则列表语句中能够实现这一要求的语句是()

A、grant select ,insert on . to ‘nkw’@‘%’
B、grant select ,insert on user.* to ‘nkw’@‘%’
C、grant all privileges on . to ‘nkw’@‘%’
D、grant all privileges on user.* to ‘nkw’@‘%’

正确答案: B
答案解析:这道题考察知识点是数据库授权命令:
GRANT<权限> on 表名(或列名) to 用户
补充知识点-回收权限
REVOKE <权限> on 表名(或列名) FROM 用户

15、下列关于数据库系统三级模式结构的表述正确的是()

A、内模式是面向数据库用户或应用程序的局部数据视图
B、索引的组织方式是B+树索引,还是Hash索引与数据库的内模式有关
C、逻辑模式是数据库在逻辑级上的视图,涉及数据的物理存储细节
D、外模式/模式映像保证了数据库具有较高的物理独立性

正确答案: B
答案解析:这道题主要考察的是数据库的设计步骤,以及对应的内模式、外模式、逻辑模式
数据库设计步骤主要分为以下几方面:
1)需求分析,需求分析是通过用户需求,将数据流程图、数据字典描述出来
2)数据库设计,这种设计和具体的数据库管理系统没有之间关联,而是抽象出各用户所需要的数据视图,对应外模式概念
3)将用ER模型或对象模型表示的数据视图,转换为关系模式,并对所得关系模式进行优化处理,这就是所谓的数据库逻辑设计(这一步仍然对应于外模式和模式)
4)第四步,在逻辑设计的基础上,将所得的数据模式组织存储到物理介质上,这就是数据库的物理设计(这一步对应于内模式)

16、Mysql(版本8.0.25)中表student_table(id,name,birth,sex),插入如下记录:
(‘1004’ , ‘张三’ , ‘2000-08-06’ , ‘男’);
(‘1005’ , NULL , ‘2001-12-01’ , ‘女’);
(‘1006’ , ‘张三’ , ‘2000-08-06’ , ‘女’);
(‘1007’ , ‘王五’ , ‘2001-12-01’ , ‘男’);
(‘1008’ , ‘李四’ , NULL, ‘女’);
(‘1009’ , ‘李四’ , NULL, ‘男’);
(‘1010’ , ‘李四’ , ‘2001-12-01’, ‘女’);
执行
select count(t2.birth) as c1
from (
select * from student_table where sex = ‘男’ ) t1
full join
(select * from student_table where sex = ‘女’) t2
on t1.birth = t2.birth and t1.name = t2.name ;
的结果行数是()?

A、2
B、3
C、执行报错
D、4

正确答案: C
答案解析:mysql不支持full join,应该用outer join

17、积分result表中有A B C D四列,要求:
1)当A列值大于等于B列时,选择A列否则选择B列
2)当C列值大于等于D列时,选择C列否则选择D列
用SQL语句实现正确的是:( )

A、select ( when A>=B then A else B ) MAX_AB, ( when C>=D then C else D ) MAX_CD from result
B、select (case when A>=B then A else B ) MAX_AB, (case when C>=D then C else D ) MAX_CD from result
C、select (case when A>=B then A else B end) MAX_AB, (case when C>=D then C else D end) MAX_CD from result
D、select case when A>=B then A else B end MAX_AB, case when C>=D then C else D end MAX_CD from result

正确答案: C
答案解析:case when 判断条件 then 成功结果 then 不成功结果 end

18、Mysql中表student_table(id,name,birth,sex),插入如下记录:
(‘1001’ , ‘’ , ‘2000-01-01’ , ‘男’);
(‘1002’ , null , ‘2000-12-21’ , ‘男’);
(‘1003’ , NULL , ‘2000-05-20’ , ‘男’);
(‘1004’ , ‘张三’ , ‘2000-08-06’ , ‘男’);
(‘1005’ , ‘李四’ , ‘2001-12-01’ , ‘女’);
执行 select * from student_table where length(name) >= 0 的结果行数是()?
A、1
B、2
C、3
D、4

正确答案:C
答案解析:1001和1002是不一样的,一个是空字符串,一个是NULL。针对这两种数据使用length()函数结果是不相同的。
针对1001 length(name)结果是0,针对1002、1003 length(name)结果是空值NULL
因此题干where length(name) >= 0 会筛选出 1001、1004、1005三条数据

19、有一张Person表包含如下信息:
Id Name Address Career
1 Bob China Town Chef
2 Carter Oxford Street Teacher
3 Anna Fourteen Avenue Dancer
现要选取居住地址Address不以’C’或’O’开头的人员信息,下列MySQL查询语句正确的是:

A、SELECT * FROM Person Address REGEXP ‘[CO]’;
B、SELECT * FROM Person Address LIKE ‘[!CO]%’;
C、SELECT * FROM Person Address LIKE ‘[^CO]%’;
D、SELECT * FROM Person Address REGEXP ‘1’;

正确答案: A
答案解析:此题考的是SQL里的正则表达式查询:
SELECT * FROM Person Address REGEXP ‘^[^CO]’;
[^]匹配不在括号中的任何字符,'[^CO]‘匹配任何不包含’C’或’O’的字符,其实就是匹配除了’C’或’O’之外的所有字符。
^匹配文本的开始字符,’^[^CO]’ 匹配不以’C’或’O’之外开头的所有字符。

20、”确保事务可以多次从一个字段中读取相同的值,在此事务持续期间,禁止其他事务对此字段的更新”是对下列选项哪一个事务隔离级别的描述()

A、Read uncommitted
B、Read committed
C、Repeatable Read
D、Serializable

正确答案:C
答案解析:这道题考察的是4个事务隔离级别,面试中经常考。
确保事务可以多次从一个字段中读取相同的值,就是要保证可重复读取,可重复读取的意思是,一端在读取数据的同时,另一端在修改数据。在高并发环境中,很容易出现,读取数据的一方,两次读取结果不一致的情况。
要防止这种情况,就是要在读取数据事务存续时,禁止写事务,用人话说就是“可读,不可修改”。这样保证重复读取数据的结果是一样的。
这一事务级别就是可重复读取(Repeatable Read)。
具体的4个事务隔离级别,可以查看问答题第12题

21、关于解决事务的脏读的最简单的方法,下列选项正确的是()
A、修改时加排他锁,直到事务提交后释放,读取时加共享锁
B、读取数据时加共享锁,写数据时加排他锁,都是事务提交才释放锁
C、修改时加共享锁,直到事务提交后释放,读取时加排他锁
D、读取数据时加排他锁,写数据时加共享锁,都是事务提交才释放锁

正确答案: A
答案解析:共享锁是立即释放的。排除B、D
脏读是意思是一个数据还没有提交,就会出现在读取结果中,万一数据因为异常原因没有成功提交,查询结果中就会出现不存在的数据。可以通过在修改时加“排他写锁”实现。

二、问答题

1、如何优化MySQL?

按照以下顺序优化:
优化查询语句
优化索引、事务处理
优化数据表结构
优化系统配置
优化硬件

2、如何优化SQL查询语句?

(1)对查询进行优化,首先应尽量避免全表扫描,在比较频繁使用的字段上面加上索引。
(2)尽量避免在 where 子句中对索引列使用计算或者进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描
(3)Where子句中:where表之间的连接必须写在其他 Where 条件之前,那些可以过滤掉最大数量
(4)用EXISTS替代IN,用NOT EXISTS替 NOT IN。

3、什么情况下设置了索引但无法使用?

(1)在 where 子句中使用 or 来连接没有同时使用索引的条件,会使引擎放弃使用索引而进行全表扫描
(2)在 where 子句中对索引列使用计算或者进行 null 值判断
(3)在 where 子句中,使用以“%”开头的 LIKE 语句,进行模糊匹配
(4)数据类型出现隐式转化(如 varchar 不加单引号的话可能会自动转换为 int 型)

4、锁的优化策略?

(1)多个线程尽量以相同的顺序去获取资源。
(2)不能将锁的粒度过于细化,不然可能会出现线程的加锁和释放次数过多,反而效率不如一次加一把大锁。
(3)尽量减少锁持有的时间
(4)分段加锁
(5)读写分离

5、索引对数据库系统的负面影响是什么?

索引需要占用物理空间,增加数据库的大小,降低正常的运行速度
当对表进行增、删、改、的时候索引也要动态维护,这样就降低了数据的维护速度。

6、什么情况下不适合建立索引?

(1)对于查询中很少涉及的列或者重复值比较多的列,不宜建立索引。
(2)对于一些特殊的数据类型,不宜建立索引,比如文本字段(text)等

7、为数据表建立索引的原则有哪些?

(1)在最频繁使用的、用以缩小查询范围的字段上建立索引
(2)不应该基于表来创建索引,应该基于查询来创建索引

8、索引的底层实现原理和优化?

索引的底层实现原理是B+树,优化是经过优化的 B+树。主要是在所有的叶子结点中增加了指向下一个叶子节点的指针,因此 InnoDB 建议为大部分表使用默认自增的主键作为主索引。

9、简单描述 MySQL 中索引、唯一索引、主键、联合索引的区别,对数据库的性能有什么影响(从读写两方面)?

索引可以极大的提高数据的查询速度,但是会降低插入、删除、更新表的速度,因为在执行这些写操作时,还要操作索引文件。
(1)普通索引的唯一任务是加快对数据的访问速度,允许被索引的数据列包含重复的值。
(2)唯一索引中,每条数据记录都是唯一的,创建唯一索引用关键字 UNIQUE
(3)主键是一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯一标识一条记录,使用关键字PRIMARY KEY来创建。
(4)联合索引可以覆盖多个数据列,如像INDEX(columnA, columnB)索引。

10、什么是事务

数据库事务( transaction)是一个数据库操作序列,这些操作要么全部成功,要么全部失败,是一个不可分割的工作单位。

11、什么是数据库的ACID原则

这个是数据库事务标准、ACID,表示原子性(Atomicity) 、一致性(Consistency)、隔离性(Isolation)、持久化(Durability)。
(1)原子性是指在一个数据库事务中所有的操作要么全部都做完,要么全部都不做。
(2)一致性是指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏,比如小明有1500元,小红有100元,小明给小红转账100元,转账完成后,小明和小红一共有1600元这个不能变。
(3)隔离性:各事务之间的操作不受影响
(4)持久化:事务一旦成功提交成功后,所有这个事务对数据库的更改全部被保留下来

12、4个事务隔离级别,分别是什么?
隔离级别从低到高。
(1)未授权读取(Read Uncommitted):允许脏读,脏读的意思是,一个数据还没有提交,就会出现在读取结果中,万一数据因为异常原因没有成功提交,查询结果中就会出现不存在的数据。该隔离级别可以通过“排他写锁”实现。
(2)授权读取(Read Committed):允许不可重复读取,但不允许脏读。不可重复读取的意思是,允许一端在读取数据的同时,另一端在修改数据,读取数据的一方重复读取时,数据结果不同是被允许的。可以通过“瞬间共享读锁”和“排他写锁”实现。
(3)可重复读取(Repeatable Read):禁止不可重复读取和脏读,但是有时可能出现幻读。幻读的意思是一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的数据行。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
(4)序列化(Serializable):提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。

隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed,它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、虚读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。

13、SQL中的视图是什么?

视图可以当成表格来用,可以将查询结果存储在视图中,后面可以直接调用这个视图数据,或者继续在视图中查询。
查询语句放在create views 后面,就可以建立视图

14、视图的优点有哪些?

(1)视图可以限定访问表格的列。
(2)视图可以访问多个表格。

15、什么是存储过程?用什么来调用?
存储过程是一组SQL语句,用作访问数据库的函数。如果将sql代码与Python代码写在一起,或很混乱并且难以维护,用存储过程来代替,管理维护更加方便。
可以用一个命令对象来调用存储过程。

16、什么是Trigger(触发器)?

触发器是在插入、更新、删除语句前后自动执行的一堆SQL代码,用于对表执行特定操作。
比如在交易表中添加一条交易,在日志表中就自动添加一条记录,这样就要用到触发器。

17、什么是事件

事件是在特定时刻自动执行任务,操作数据库。
比如我们想在每天都执行删除过期日志,就可以创建一个事件,在每天特定时刻来自动执行这一操作。

18、怎样创建事件?
用 create event 语句来创建事件。

create event 事件名称
on schedule
every 1 year
do begin
删除语句
end

19、下面这条语句怎么优化,MySQL 如何优化 DISTINCT?比如优化 SELECT DISTINCT t1.a FROM t1,t2 where t1.a=t2.a;

在数据量比较大的时候,使用distinct函数加索引列,会使索引失效,并扫描全表。
这个时候,应该将 DISTINCT 在所有列,都转换为 GROUP BY
SELECT t1.a FROM t1,t2 WHERE t1.a=t2.a GROUP BY t1.a;

20、char和varchar的区别

CHAR 和 VARCHAR 类型在存储和检索方面有所不同
存储方面:CHAR 列长度固定,存储为创建表时声明的长度,如果插入的长度小于定义长度,则可以用空格进行填充。而varchar是一种可变长度的类型,当插入的长度小于定义长度时,插入多长就存多长。
查找效率:char查找效率会很高,varchar查找效率会更低

21、如何通俗地理解三个范式,说说范式化设计优缺点?

第一范式(1NF):是对属性的原子性约束,要求属性具有原子性,不可再分解;
第二范式(2NF):是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性;
第三范式(3NF):是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。

范式化的优点: 可以尽量得减少数据冗余,使得更新快,体积小。
缺点:对于查询需要多个表进行关联,减少写操作的效率和增加读操作的效率,更难进行索引优化

22、MySQL 数据库作发布系统的存储,一天五万条以上的增量,预计运维三年,怎么优化?

(1)设计良好的数据库结构,不要过度颗粒化,也不要使数据过渡冗余。
(2)选择合适的表字段数据类型和存储引擎,适当的添加索引。
(3)MySQL 库主从读写分离。
(4)找规律分表,减少单表中的数据量提高查询速度。
(5)添加缓存机制,比如 memcached,apc 等。
(6)不经常改动的页面,生成静态页面。

23、窗口函数是什么?和普通聚合函数的区别有哪些?

窗口函数,也叫OLAP(Online Anallytical Processing,联机分析处理),可以对数据库数据进行实时分析处理
窗口函数和普通聚合函数的区别:
(1)聚合函数是将多条记录聚合为⼀条;窗⼝函数是每条记录都会执行,不会改变记录的行数
(2)聚合函数也可以⽤于窗⼝函数。

24、专用窗口函数有哪些?说一说基本用法

专用窗口函数有:rank、dense_rank、row_number

基本语法:‹窗口函数› over (partition by ‹用于分组的列名› order by ‹用于排序的列名›)

over关键字用来指定函数执⾏的窗⼝范围,若后⾯括号中什么都不写,则意味着窗口包含满足WHERE条件的所有行,窗口函数基于所有行进行计算;如果不为空,则⽀持以下4种语法来设置窗⼝。
(1)partition by子句:窗口按照哪些字段进⾏分组,窗⼝函数在不同的分组上分别执⾏
(2)order by子句:按照哪些字段进⾏排序,窗⼝函数将按照排序后的记录顺序进⾏编号
(3)frame子句:frame是当前分区的⼀个子集,子句⽤来定义子集的规则,通常⽤来作为滑动窗⼝使⽤
(4)window_name:给窗口指定⼀个别名。如果SQL中涉及的窗口较多,采用别名可以看起来更清晰易读

25、使用窗口函数需要注意什么

窗⼝函数的执⾏顺序是在FROM,JOIN,WHERE, GROUP BY,HAVING之后的
所以如果这些语句,需要用到窗口函数作为条件,需要在窗口函数外面套⼀层查询

选择题和问答题都更新完了,有不完善的地方可以留言我们一起探讨~

三、实战题

实战题包括次日留存率、列转行、窗口函数等,这些大厂几乎必考的问题,我给大家整理了详细的解析。

篇幅比较长,放在下面这篇里面了。

2022年SQL大厂高频实战面试题(详细解析)


  1. CO ↩︎

  • 64
    点赞
  • 497
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喵宁一

点赞是最好的赞赏~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值