实时更新
你用过哪些数据库?
mysql 和 redis 的区别?
比较点
Mysql
Redis
数据库类型
关系型
非关系型
作用
持久化层
存储需要持久化的数据,数据存在硬盘中
一般是缓存层
作为缓存数据库的存在
数据存储在内存中
读取速度
较慢
基于内存,所以很快
运行机制
每次请求访问数据库,都存在 I/O 操作
反复访问数据库会造成系统负载过高
优先查询缓存数据库,读取速度快
查不到再查 Mysql 数据库
什么是关系型数据库?
依赖关系模型来创建的数据库
什么是非关系型数据库?
就是非关系模型的数据库
有哪些常见的关系型数据库?
Mysql、Oracle、SQL Server
有哪些常见的非关系型数据库?
Redis、MongoDB、HBASE
关系型数据库中的关系模型是指?
一对一、一对多、多对多都是关系模型,就是二维表格模型
非关系模型有哪些?
- 列模型:Hbase
- 键值对模型:redis
- 文档类模型:mongoDB
关系型数据库的特点和缺点
- 特点:数据存储在磁盘中,安全性高,容易理解
- 缺点:不节省空间
非关系型数据库的特点和缺点
- 特点:数据存储在内存,节省磁盘空间,效率也高
- 缺点:也因为数据没存在磁盘,安全性较低,但目前很多非关系型数据库开始支持将数据转存到磁盘了
Mysql 的 SQL 语句区分大小写吗?
不区分
buffer 和 cache 的区别
exists 和 in 的区别
- 无论哪个表大,用 not exists 都比 not in 快
- 内表比外表大时用 exists,外表比内表大时用 in
Mysql 是如何进行缓存数据的?
将查询的语句、执行结果等进行 hash,并保留在 cache 中
通过 explain,我们可以获取到哪些信息?
- 表的读取顺序
- 数据读取操作的操作类型
- 哪些索引可以使用或实际使用
- 表之间的引用
- 每张表有多少行被优化器查询
Mysql 中,查询语句中,关键字的执行顺序
- from
- on
- join
- where
- group by
- having
- select
- distinct
- order by
- limit
当数据库不存在时创建数据库
create database if not exists test
如何查看有什么数据库?
show databases
当数据库存在时则删除数据库
drop database if exists test
如何选择数据库?
use database_name
如何查看表结构?
desc 表名
如何查看数据表的创建语句?
show create table yytest;
有哪些常见的修改表操作?
- 修改表名
- 修改字段数据类型或字段名
- 增加、删除字段
- 修改字段的排列位置
distinct 关键字有什么用?
去重
distinct 可以在哪里使用?
只能在 select 语句中使用
如果想对多个字段去重,要怎么写?
SELECT DISTINCT <字段名>,<字段名> FROM <表名>;
limit 的初始位置是多少?
0
limit + offset 怎么用?
LIMIT 记录数 offset 初始位置
order by 默认是倒序还是顺序?
升序,asc
倒序是怎么写?
desc
like 关键字中,% 的含义
通配符,代表任意长度的字符
like 匹配的字符串区分大小写吗?
不区分,但可以添加 binary 关键字,这样就可以区分了
group by 多个字段的时候,可以讲下分组原理吗?
- 先按照第一个字段分组,如果第一个字段有相同值,则把分组结果再按第二个字段进行分组,以此类推
- 如果第一个字段分组每个值都是唯一的,则不会再按照第二个字段进行分组了
group_concat 有什么用?
可以将分组后每个组内的值都显示出来
having 可以代替 where 吗?
不可以
什么时候用 having?
group by 后使用 having 来过滤数据
having 和 where 的区别?
where
having
不可以使用聚合函数
可以使用聚合函数
数据 group by 前过滤
数据 group by 后过滤
查询条件中不可以使用字段别名
查询条件中可以使用字段别名
用于过滤数据行
用于过滤分组后的结果集
根据数据表的字段直接过滤
根据已查询出的字段进行过滤
有哪些多表查询
- cross join:交叉连接
- inner join:内连接
- left join:左外连接
- right join:右外连接
- union、union all:全连接
左连接、右连接、全连接的区别
- 左连接会获取左表的所有记录,右表为空时补 null
- 右连接会获取右表的所有记录,左表为空时补 null
- 全连接会获取左右表的所有数据
什么是子查询?
- 将一个查询语句嵌套在另一个查询语句中
- 子查询可以实现多表查询
- 子查询也能在 select、update、delete 语句中使用,还能进行多层嵌套
左右连接跟内连接的区别
左右连接为外连接,而内连接最大的不同在于,匹配成功的数据,只有两个表都有才会返回,相当于交集的关系
补充面试题:和全连接的区别
- 在 mysql 中的全连接可以通过 union 来实现
- 全连接是左连接和右连接的结合,只要有匹配成功的数据,无论两个表是否都有匹配的数据,都会返回,如果没有则显示 null,相当于并集
子查询和内连接、左外连接的区别
- 子查询是指在一个查询语句上嵌套另一个查询语句,会写多条 select 语句
- 内连接、外连接虽然也是多表查询,但是只有写一个 select 关键字
模糊查询的语句
- like:% 代表任意,_ 代表任意单个字符,[ ] 范围内取一个字符
- regexp:正则表达式
Mysql 默认的存储引擎是?
目前最新版的是 InnoDB
Mysql存储引擎有哪些?
InnoDB、MyISAM、Memory、Merge、Archive、CSV、BLACKHOLE
Mysql innodb 存储引擎是什么概念?
- 现在 innodb 是 Mysql 的默认存储引擎
- 它为处理巨大数据量时的最大性能设计
- 它提供了具有事务、回滚、崩溃修复能力、多版本并发控制的事务安全表
如何查看 Mysql 有什么存储引擎
show engines
MyIsam 存储引擎和 InnoDB 存储引擎的区别
比较点
MyIsam
InnoDB
事务
不支持
支持
外键
不支持
支持
全文索引
支持
不支持,但可以通过插件支持,且效果更好
锁
只支持表锁
还支持行锁
可移植性
数据以文件方式存储,移植性好
数据量大的时候移植性一般
主键
允许没有任何索引和主键的表存在
没有设置主键会自动生成一个主键
使用场景
执行大量的 select
执行大量的 insert、update
Mysql 存储引擎语句调优有了解吗?
这个忽略算了
在 Mysql 中什么是事务?
事务就是一组具有原子性的操作,保证这一组数据库操作,要么全部成功,要么全部失败
事务能保证数据库从一种一致性状态转换为另一种一致性状态
事务是在引擎层实现的,也就是说并不是所有引擎都可以使用事务
MyISAM 就不支持事务,这也是为什么会被 InnoDB 取代的原因
比如:银行转账、购买商品
Mysql 事务的四大特性是什么?
什么是索引
索引就是数据表中对一个或多个列的值进行排序的结构,是帮助 Mysql 高效检索数据的数据结构
索引的优势
- 提高数据查询的效率,就像书的目录一样
- 保证行的唯一性
- 加快表之间的连接
- 用来排序或分组的字段添加索引可以加快分组或排序
索引的坏处
- 创建索引和维护索引需要时间成本,成本随数据量增加而增大
- 创建索引和维护索引需要空间成本,每一条索引都要占据数据库的物理存储空间,数据量越大,占用空间也越大
- 加快了查询效率,但降低了增删改效率,因为每次增删改都要动态维护索引,降低了数据的维护速度
什么场景下会用到索引
- 经常需要查询的列,可以加快查询速度
- 经常用在连接的列,可以加快连接速度
- 经常需要排序的列,可以加快排序查询时间
- 经常跟在 where 后的列,可以加快条件的判断速度
- 仅对索引查询,当查询的列都在索引字段中,查询效率会更高
索引在什么场景下会失效?
- 以 % 开头的 like 查询不能利用 B-tree 索引
- 数据类型出现隐式转换的时候不会使用索引
- 如果 Mysql 认为使用索引比全表扫描更慢,则不会使用索引
- 用 or 分割的条件,若 or 前的条件有索引,但 or 后的条件没有索引,则不会使用索引
索引的类型
- 普通索引
- 唯一索引
- 主键索引
- 全文索引
- 联合索引
- 聚集索引
- 覆盖索引
索引的实现方式(索引的模型)
InnoDB 的索引模型是什么?
B+Tree
为什么是 B+ Tree?
它能够很好地配合磁盘的读写特性,减少单次查询的磁盘访问次数
普通索引和主键索引的区别?
- 如果 SQL 语句的查询字段是主键,则只需搜索主键的 B+ 树
- 如果 SQL 语句的查询字段是非主键,需要先搜索该字段的索引数,得到主键值后,再到主键的 B+ 树搜索一次
- 普通索引也称非主键索引,需要多搜索一颗索引树,所以在应用中尽量使用主键索引
组合索引的识别原则了解吗?
- 最左匹配原则,先从最左边的索引开始找,然后依次往后,中间不能跳过
- 一般将使用最频繁的列放在最左边
- 符合最左匹配的 SQL 语句的查询效率将大大提升
索引的建立原则
- 最左匹配原则,先从最左边的索引开始找,然后依次往后,中间不能跳过
- 尽量选择区分度高的列作为索引,比如身份证号码,而不是选择性别
- = 和 in 可以乱序,比如 a = 1 and b = 2 and c = 3,建立 (a,b,c) 索引可以任意顺序,mysql 的查询优化器会帮你优化成索引可以识别的形式
- 索引列不能参与计算,如果索引列参与计算的话,那每次检索的时候,都会先将索引计算一次,再做后续操作,导致成本太大
- 尽量的扩展索引,不要新建索引,比如表中已经有 a 的索引,现在要加 (a,b) 的索引,直接修改原来的索引就行
自增主键的定义是什么?
NOT NULL PRIMARY KEY AUTO_INCREMENT
怎么查询这条sql 是否有慢查询呢?
查看慢查询日志状态
show variables like 'slow_query_log';
开启慢查询日志(重启后失效)
set global slow_query_log = 1
疑问:开启慢查询日志后,什么样的 SQL 才会记录到慢查询日志里?
回答:由参数 long_query_time 控制,默认是 10s
查看慢查询时间阈值
show variables like 'long_query_time';
设置慢查询时间阈值
set global long_query_time=4;
当 SQL 语句执行时间大于 4s 的时候就会记录到慢查询日志中,等于 4s 不会记录哦
你了解 SQL 注入吗?
- SQL 注入也是用户输入的数据,只不过是一串常见的查询或插入 SQL 语句,比如在表单输入框、留言框中输入,然后保存表单
- 因为客户端或者服务端未经校验或未经充分校验用户输入的数据,让 SQL 注入数据变成了真正可执行的 SQL 命令
- 攻击者可以通过 SQL 注入来获取一些敏感数据、插入一些恶意数据,可能会影响使用这个数据库的所有应用程序
怎么规避 SQL 注入吗?
可以从客户端和服务端分别做防御,但更侧重于服务端
对于客户端来说
- 前端限制客户输入 SQL 常见的符号,比如单引号、双引号、等号、空格等等
- 或者将特殊字符进行转义再传参给服务端
对于服务端来说
- 不要用拼接的方式插入参数,使用预编译的 SQL 语句,通过参数化的方式插入参数,比如 preparestatement 语句
- 使用专业的 SQL 注入漏洞扫描工具检查网站
- 对特殊字符进行转义
- 严格控制数据类型
Mysql 要支持 emoji 表情怎么做?
- 设置字段的字符集编码为 utf8mb4
- 设置表的字符集编码为 utf8mb4
常见视图有哪些?
索引和视图的区别有哪些?