70道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
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’;
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
4、小李在创建完一张数据表后,发现少创建了一列,此时需要修改表结构,应该用哪个语句进行操作?
A、MODIFY TABLE
B、INSERT TABLE
C、ALTER TABLE
D、UPDATE TABLE
5、SQL语言可以分为多个类别,那么不属于数据操纵语言DML的是()
A、update
B、grant
C、delete
D、insert
6、下列选项中使用别名的方法不正确的是()
A、字段名称=别名
B、字段名称 AS 别名
C、字段名称 别名
D、别名=字段名称
(多选题)7、在MySql中进行数据查询时,如果要对查询结果的列名重新命名,将sno列重新命名为学号,则下列语句正确的是( )
A、select sno as 学号 from T
B、select 学号= sno from T
C、select sno 学号 from T
D、select sno=学号 from T
8、在SQL中用条件表示价格在在30至40之间,应该如何表达?
A、in (30,40)
B、BETWEEN 30 AND 40
C、BETWEEN 30 OR 40
D、BETWEEN 30 TO 40
9、SQL语句中与Having子句同时使用的语句是?()
A、Group By
B、联盟链
C、left Join
D、Where
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
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’ );
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;
(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’ ;
2、某IT公司人事管理采用专门的人事管理系统来实现。后台数据库名为LF。新来的人事部张经理新官上任,第一件事是要对公司的员工做全面的了解。可是他在访问员工信息表EMPL里的工资和奖金字段的时被拒绝,只能查看该表其他字段。作为LF的开发者你将如何解决这一问题:( )
A、废除张经理的数据库用户帐户对表EMPL里的工资列和奖金列的SELECT权限
B、添加张经理到db_datareader角色
C、添加张经理到db_accessadmin角色
D、授予张经理的数据库用户帐户对表EMPL里的工资列和奖金列的SELECT权限。
3、下列函数语句得不到相同数值结果的选项是()
A、SELECT ROUND(2.35)
B、SELECT ROUND(1.96,1)
C、SELECT TRUNCATE(1.99,1)
D、SELECT TRUNCATE(2.83,0)
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
5、查询语句select stuff(‘lo ina’,3, 1, ‘ve ch’)结果为?
A、love
B、love china
C、china love
D、china
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)
(多选题)7、使用SQL语句建个存储过程proc_stu,然后以student表中的学号Stu_ID为输入参数@s_no,返回学生个人的指定信息。下面创建存储过程语句正确的是:( )
A、CREATE PROCEDURE proc_stu
@s_no AS int
AS
BEGIN
select * from stu.student where Stu_ID=@s_no
END
B、CREATE PROCEDURE proc_stu
@s_no int
AS
BEGIN
select * from stu.student where Stu_ID=@s_no
END
C、CREATE PROCEDURE proc_stu
@s_no int
AS
BEGIN
select * from stu.student where s_no=@s_no
END
D、CREATE PROCEDURE proc_stu
@s_no AS int
AS
BEGIN
select * from stu.student where Stu_ID=@Stu_ID
END
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()
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
(多选题)10、下面有关sql 语句中 delete、truncate的说法正确的是?()
A、论清理表数据的速度,truncate一般比delete更快
B、truncate命令可以用来删除部分数据。
C、truncate只删除表的数据不删除表的结构
D、delete能够回收高水位(自增ID值)
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 销量表)
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;
(多选题)13、在SQL中语法规范中,having子句的使用下面描述正确的是:( )
A、having子句即可包含聚合函数作用的字段也可包括普通的标量字段
使用having的同时不能使用where子句
B、having子句必须于group by 子句同时使用,不能单独使用
使用having子句的作用是限定分组条件
C、having子句和where子句是等同的
D、having子句后面必须使用聚合函数
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’@’%’
15、下列关于数据库系统三级模式结构的表述正确的是()
A、内模式是面向数据库用户或应用程序的局部数据视图
B、索引的组织方式是B+树索引,还是Hash索引与数据库的内模式有关
C、逻辑模式是数据库在逻辑级上的视图,涉及数据的物理存储细节
D、外模式/模式映像保证了数据库具有较高的物理独立性
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
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
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
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’;
20、”确保事务可以多次从一个字段中读取相同的值,在此事务持续期间,禁止其他事务对此字段的更新”是对下列选项哪一个事务隔离级别的描述()
A、Read uncommitted
B、Read committed
C、Repeatable Read
D、Serializable
21、关于解决事务的脏读的最简单的方法,下列选项正确的是()
A、修改时加排他锁,直到事务提交后释放,读取时加共享锁
B、读取数据时加共享锁,写数据时加排他锁,都是事务提交才释放锁
C、修改时加共享锁,直到事务提交后释放,读取时加排他锁
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)简化查询
视图可以将原本复杂的 SQL 语句简化。比如前面讲的子查询,我们可以将被嵌套的子查询保存为视图,然后主查询直接在视图中查询就可以了。这样就不会有查询语句的嵌套,SQL语句会更加易读。视图就像模块化编程一样,不仅会使语句结构更加清晰,还提升了代码的复用率。
(2)安全性
使用视图可以保护原始数据表的安全性,视图可以对原始表的行和列进行筛选,如果我们禁止了对原始表的访问权限,用户只能通过视图来修改数据,他们就无法修改视图中未返回的那些字段和记录。
(3)更易维护
如果没有视图,所有的查询直接指向原始数据表,一旦更改原表设计,就要相应的更改该表所有的查询语句。如果有视图,我们只需要修改视图的查询语句,使其能保持原有查询结果即可,基于视图的查询我们就不需要再修改了。
15、什么是存储过程?用什么来调用?
存储过程是一组SQL语句,用作访问数据库的函数。如果将sql代码与Python代码写在一起,或很混乱并且难以维护,用存储过程来代替,管理维护更加方便。
可以用一个命令对象来调用存储过程,比如call。
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之后的
所以如果这些语句,需要用到窗口函数作为条件,需要在窗口函数外面套⼀层查询。
26、维护数据库的完整性和一致性,你喜欢用触发器还是自写业务逻辑?为什么?
首先考虑使用约束,效率最高也最方便,如check,主键,外键,非空字段等。
其次使用触发器,这种方法可以保证,无论什么业务系统访问数据库都可以保证数据的完整新和一致性。
最后考虑自写业务逻辑,但这样会使编程复杂,效率低下。
选择题和问答题都更新完了,有不完善的地方可以留言我们一起探讨~
实战题包括次日留存率、列转行、窗口函数等,这些大厂几乎必考的问题。
篇幅比较长,放在下面这两篇里面了,给大家整理了详细的独家解析~
SQL 注入面试题精选!25 道题及答案带你轻松应对面试
1. 什么是SQL注入?
答案:SQL注入是利用应用程序未能正确验证用户输入的数据而向数据库查询中插入或“注入”任意SQL代码的一种攻击技术。
2. 如何防止SQL注入?
答案:防止SQL注入的最佳实践包括使用预编译语句(Prepared Statements)和参数化查询,限制数据库用户的权限,验证和清理所有用户输入,使用存储过程,并定期更新和修补数据库系统。
3. 为什么使用预编译语句可以防止SQL注入?
答案:预编译语句将SQL代码与数据分离,这样即使用户输入了SQL语法,也会被作为普通的字符串处理,而不是执行为命令。
4. 举例说明一个典型的SQL注入攻击场景。
答案:如果一个登录表单直接将用户名和密码拼接到SQL查询中,攻击者可以通过输入`\’ OR \’1\’=\’1`来绕过认证逻辑,因为这会使条件永远为真。
5. 什么是盲注(Blind SQL Injection),它是如何工作的?
答案:盲注是指当攻击者无法看到错误信息时使用的SQL注入形式。攻击者通过发送特定的查询并观察应用的行为(如响应时间、页面内容的变化等)来推断出有关数据库结构的信息。
6. 如何检测网站是否存在SQL注入漏洞?
答案:检测SQL注入漏洞的方法包括手动测试输入点(例如搜索框、登录表单)、自动化扫描工具(如sqlmap),以及审查代码以查找不安全的数据库查询构造方式。
7. 什么是第二阶SQL注入(Second Order SQL Injection),它与传统的SQL注入有何不同?
答案:第二阶SQL注入指的是攻击者提供的输入最初不会被执行,而是存储在数据库中,然后在稍后的某个时间点被另一个查询触发执行。它不同于传统的即时执行型SQL注入。
8. 如何保护基于Web的应用程序免受SQL注入攻击?
答案:除了上述提到的预防措施外,还应该实施最小权限原则,确保应用程序只拥有完成其工作所需的最少数据库访问权限;同时要加密敏感数据,部署Web应用防火墙(WAF)等。
9. 如果已经遭受了SQL注入攻击,应采取哪些步骤?
答案:发现SQL注入后,首先应立即隔离受影响的系统,评估损害程度,修复漏洞,更改所有可能受影响的账户密码,并通知相关方(如用户、管理层)。还要考虑聘请安全专家进行彻底的安全审查。
10. 什么是时间盲注(Time-based Blind SQL Injection),它有什么特点?
答案:时间盲注是一种特殊的盲注类型,其中攻击者通过发送会导致数据库延迟响应的特殊查询来确定查询的结果。根据延迟的时间长短,攻击者可以判断某些条件是否为真。
11. 在使用ORM框架的情况下,如何防止SQL注入?
答案:大多数现代的ORM(对象关系映射)框架都内置了防止SQL注入的功能。它们通过参数化查询或预编译语句来构建SQL查询,避免直接拼接字符串。开发者应当遵循框架的最佳实践,确保所有查询都是通过安全的方法构造的,并且不绕过ORM直接执行原始SQL。
12. 什么是NoSQL注入,它与SQL注入有何不同?
答案:NoSQL注入是指针对非关系型数据库(如MongoDB、Cassandra等)的注入攻击。由于NoSQL数据库的查询语法和结构不同于传统的SQL,所以其注入方式也有所区别。例如,在MongoDB中,注入可能涉及到操控JSON/BSON文档中的查询条件。防御NoSQL注入也需要采用特定于该类型数据库的技术,如正确地验证和清理输入数据,以及使用相应的驱动程序提供的安全特性。
13. 描述一种高级的SQL注入技术,如联合查询注入(Union Query Injection)。
答案:联合查询注入是利用`UNION`操作符将攻击者的查询结果附加到原始查询的结果集中。攻击者构造一个与原查询列数相同且兼容的数据类型的子查询,从而可以获取额外的信息,比如从其他表中读取敏感数据。防御这种攻击需要严格限制用户输入的内容,并确保即使在出现错误时也不会泄露关于数据库结构的信息。
14. 解释如何利用布尔盲注(Boolean-based Blind SQL Injection)推断出数据库的内容。
答案:布尔盲注是基于应用程序响应的变化来进行判断的一种技术。攻击者可以通过发送会返回真假两种不同页面内容或行为的查询来逐步确定数据库中的信息。例如,通过逐个字符猜测表名、列名或数据值,每次尝试不同的字符直到找到正确的那个,以此类推,最终可以获得完整的数据集。
15. 当应用部署在云环境中时,应采取哪些额外步骤来保护免受SQL注入攻击?
答案:除了常规的安全措施外,云环境下的应用还应该利用云服务提供商的安全功能,如网络级防火墙规则、数据库审计日志、自动补丁更新和配置管理工具。此外,应该实施严格的IAM(身份和访问管理)策略,控制谁能访问数据库实例,并启用加密以保护静态和传输中的数据。
16. 如何通过HTTP头部进行SQL注入攻击,举例说明。
答案:有时Web应用程序不仅会在URL参数或表单字段中处理用户输入,还会根据HTTP头部(如User-Agent, Referer等)来执行某些逻辑或查询。如果这些头部没有被妥善处理,也可能成为SQL注入的入口点。例如,一个应用程序可能会根据Referer头来记录来源网站,而这个过程中的SQL查询如果没有正确处理,就可能导致SQL注入。
17. 描述一次SQL注入攻击成功后,攻击者能获得的最大权限是什么?
答案:成功的SQL注入攻击可以使攻击者获得对整个数据库的完全控制权,包括但不限于读取、修改或删除任意数据;获取存储过程、触发器和其他数据库对象的定义;甚至在某些情况下,如果数据库配置不当,攻击者还可以通过xp_cmdshell等扩展存储过程执行操作系统级别的命令,进而可能控制服务器。
18. 请解释如何利用错误消息进行SQL注入攻击,并说明为什么这很重要。
答案:详细的错误消息可以为攻击者提供有关数据库内部工作方式的重要线索,如数据库类型、版本、表结构等。通过诱导应用程序抛出包含有用信息的错误,攻击者能够更快地识别和利用漏洞。因此,生产环境中的应用程序应当配置为只显示通用的错误消息,而不透露任何敏感的技术细节。
19. 什么是多语句SQL注入(Multi-statement SQL Injection),它有什么风险?
答案:多语句SQL注入允许攻击者在一个查询中插入多个独立的SQL命令。如果数据库配置允许执行多条语句,那么攻击者就可以通过这种方式执行一系列恶意操作,如创建新用户、更改密码或执行破坏性命令。为了防止这种情况,应该禁止在应用程序中执行多语句查询,并始终限制用户的权限。
20. 解释如何在代码审查过程中发现潜在的SQL注入漏洞。
答案:在代码审查期间,重点应该是寻找所有与数据库交互的地方,特别是那些直接或间接使用用户输入构建SQL查询的地方。检查是否正确使用了预编译语句、参数化查询或ORM方法,以及是否有适当的输入验证和清理逻辑。同时,还要注意任何异常处理机制,确保它们不会意外地暴露出敏感信息。
21. 如何在不返回任何错误信息的情况下,利用时间延迟盲注(Time-based Blind SQL Injection)确定数据库版本?
答案:即使应用程序被配置为不显示任何错误信息,攻击者仍然可以使用时间延迟盲注技术来推测数据库版本。例如,在MySQL中,可以通过`IF`语句或`SLEEP()`函数构造查询,使得如果某个条件成立,则查询会延迟特定的时间。通过二分法逐字符猜测数据库版本字符串中的每个字符,并根据响应时间判断猜测是否正确,最终可以完整地推断出数据库版本。
22. 在SQL注入漏洞修复后,为什么还需要进行回归测试?请详细解释。
答案:回归测试是在修复软件缺陷后重新运行以前的测试用例,以确保新的更改没有引入新的问题或导致现有功能失效。对于SQL注入修复而言,回归测试可以帮助确认修复确实有效,防止其他地方存在类似的问题,并且验证修复不会影响应用程序的正常功能。此外,它还可以帮助发现那些可能被忽视的边缘情况或复杂的输入场景。
23. 描述一个场景,在这个场景中,尽管使用了预编译语句和参数化查询,但应用程序仍然容易受到SQL注入攻击。
答案:即使使用了预编译语句和参数化查询,如果应用程序逻辑允许动态构建查询的一部分(如表名、列名),并且这部分是由用户输入控制的,那么就可能存在SQL注入风险。例如,如果开发者基于用户提供的排序字段名称来构建查询,而这些字段名称没有经过严格的白名单验证,攻击者就可以操纵输入来执行任意查询。因此,除了参数化查询外,所有动态生成的SQL部分都应严格限制并验证。
24. 解释如何利用SQL注入绕过基于角色的访问控制(RBAC)。
答案:基于角色的访问控制是通过分配给用户的权限来限制他们能够执行的操作。然而,如果应用程序在检查用户权限时依赖于从数据库检索的信息,而这些查询又存在SQL注入漏洞,攻击者就可以操控查询结果,使自己看起来拥有更高的权限。例如,通过修改查询条件让所有用户都被认为具有管理员权限。为了防止这种情况,应该确保权限检查逻辑是安全的,并且与用户身份验证过程紧密结合,避免直接在查询中包含权限相关的逻辑。
25. 假设你在一个受限环境中,无法使用自动化工具,如何手动检测并验证SQL注入漏洞的存在?
答案:在没有自动化工具的情况下,可以采取以下步骤手动检测SQL注入:
(1) 分析应用程序源代码,寻找潜在的SQL注入点,特别是那些直接拼接用户输入到SQL查询的地方。
(2)在输入框或其他可输入区域尝试简单的SQL注入测试字符串,如单引号 `\’` 或闭合括号 `)`,观察应用的行为变化。
(3)尝试使用布尔盲注方法,通过改变查询条件来观察页面内容或行为是否有意料之外的变化。
(4)如果支持,尝试使用联合查询注入,通过附加额外的查询结果来获取更多信息。
(5)对于时间延迟盲注,可以通过发送会导致数据库延迟响应的查询,然后根据响应时间来判断是否存在漏洞。
(6)仔细分析应用程序返回的所有数据,包括HTTP头部、状态码、Cookie等,因为有时候非直观的地方也可能是SQL注入的入口点。
欢迎评论区留言讨论!❤️
SQL基本语句练习(基础版)
最近在学习SQL基本语句的练习,在此分享一下笔者做过的练习以及个人的解决教程:
首先是基本练习表格的搭建,具体内容如下表所示:
学生表
选课表
课程表
建立以上表格框架的代码如下:
给出相应的INSERT语句来完成题中给出的数据的插入,如:
具体完成以下例题。将它们转换为SQL语句表示,在学生选课库中实现其数据更新操作1)将一新学生记录(‘S007’,’陈冬’,’男’,’18’,’13600524567’,’计算机系’)插入学生表中2)插入一条选课记录(‘S002’,’C1’)到选课表中3)对每一个系,求学生的平均年龄,并把结果存入数据库4)将学生S001的年龄改为22岁5)将所有学生的年龄增加一岁6)将计算机系全体学生的成绩置零7)删除学号为S006的学生记录8)删除计算机系所有学生的选课记录9)删除所有的学生选课记录10)在已经存在的学生表中增加一个邮件地址“Email”的新属性列,允许为空11)修改学生表中“姓名”的数据类型为VARCHAR(20)
以下是SQL语句基本语法的使用
下面的运算符可在 WHERE 子句中使用,同时WHERE语句中还可以配合AND&OR运算符进行进一步地设置条件条件
以下是增删改的基本语法
最后为笔者的示例代码,仅供参考:
本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com
文章为作者独立观点不代本网立场,未经允许不得转载。