MySQL
1. 基础
1. 什么是关系型数据库?
一种建立在关系模型的基础上的数据库。关系模型表明了数据库中所存储的数据之间的联系(一对一、一对多、多对多)。各种表中(比如用户表),表中的每一行就存放着一条数据(比如一个用户的信息)。
2. 什么是SQL?
一种结构化查询语言,专门用来与数据库打交道,目的是提供一种从数据库中读写数据的简单有效的方法。
3. MySQL的优点
一种关系型数据库,主要用于持久化存储我们的系统中的一些数据比如用户信息,端口默认3306。
成熟稳定,功能完善,开源免费。
文档丰富,既有详细的官方文档,又有非常多优质文章可供参考学习。
开箱即用,操作简单,维护成本低。
兼容性好,支持常见的操作系统,支持多种开发语言。
社区活跃,生态完善。
事务支持优秀, InnoDB 存储引擎默认使用 REPEATABLE-READ 并不会有任何性能损失,并且,InnoDB 实现的 REPEATABLE-READ 隔离级别其实是可以解决幻读问题发生的。
支持分库分表、读写分离、高可用。
4. 基础架构
-
连接器: 身份认证和权限相关(登录 MySQL 的时候)。
-
查询缓存: 执行查询语句的时候,会先查询缓存(MySQL 8.0 版本后移除,因为这个功能不太实用)。
-
分析器: 没有命中缓存的话,SQL 语句就会经过分析器,分析器说白了就是要先看你的 SQL 语句要干嘛,再检查你的 SQL 语句语法是否正确。
-
优化器: 按照 MySQL 认为最优的方案去执行。
-
执行器: 执行语句,然后从存储引擎返回数据。 执行语句之前会先判断是否有权限,如果没有权限的话,就会报错。
分层:
-
Server 层:主要包括连接器、查询缓存、分析器、优化器、执行器等,所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图,函数等,还有一个通用的日志模块 binlog 日志模块。
-
存储引擎:主要负责数据的存储和读取,采用可以替换的插件式架构,支持 InnoDB、MyISAM、Memory 等多个存储引擎,其中 InnoDB 引擎有自有的日志模块 redolog 模块。
SQL执行:
-
查询:权限校验(如果命中缓存)--->查询缓存--->分析器--->优化器--->权限校验--->执行器--->引擎
-
更新:分析器---->权限校验---->执行器--->引擎---redo log(prepare 状态)--->binlog--->redo log(commit 状态)
5. MySQL自增主键不一定连续
自增主键可以让聚集索引尽量地保持递增顺序插入,避免了随机查询,从而提高了查询效率。
-
场景:
-
自增初始值 和 自增步长设置不为 1
-
唯一键冲突
-
事务回滚
-
批量插入(如
insert...select
语句):并不知道到底需要申请多少 id,所以就采用了这种批量申请的策略
-
6. 数据库设计通常分为几步?
-
需求分析 : 分析用户的需求,包括数据、功能和性能需求。
-
概念结构设计 : 主要采用 E-R 模型进行设计,包括画 E-R 图。
-
逻辑结构设计 : 通过将 E-R 图转换成表,实现从 E-R 模型到关系模型的转换。
-
物理结构设计 : 主要是为所设计的数据库选择合适的存储结构和存取路径。
-
数据库实施 : 包括编程、测试和试运行
-
数据库的运行和维护 : 系统的运行与数据库的日常维护。
2. 字段类型
数值(整、浮点、定点)、字符串(CHAR VARCHAR)、日期时间(DATETIME TIMESTAMP)
1. 整数类型的 UNSIGNED 属性有什么用?
表示不允许负值的无符号整数。使用 UNSIGNED 属性可以将正整数的上限提高一倍,因为它不需要存储负数值。对于从 0 开始递增的 ID 列,提供了更多的 ID 值可用。。
2. CHAR 和 VARCHAR 的区别是什么?
CHAR 是定长字符串,VARCHAR 是变长字符串。
CHAR 在存储时会在右边填充空格以达到指定的长度,检索时会去掉空格; VARCHAR 在存储时需要使用 1 或 2 个额外字节记录字符串的长度,检索时不需要处理。
CHAR 更适合存储长度较短或者长度都差不多的字符串,例如 Bcrypt 算法、MD5 算法加密后的密码、身份证号码。VARCHAR 类型适合存储长度不确定或者差异较大的字符串,例如用户昵称、文章标题等。
3. DECIMAL 和 FLOAT/DOUBLE 的区别是什么?
DECIMAL 是定点数,FLOAT/DOUBLE 是浮点数。DECIMAL 可以存储精确的小数值,FLOAT/DOUBLE 只能存储近似的小数值。
在 Java 中,MySQL 的 DECIMAL 类型对应的是 Java 类 java.math.BigDecimal
。
4. 为什么不推荐使用 TEXT 和 BLOB?
TEXT 类型类似于 CHAR(0-255 字节)和 VARCHAR(0-65,535 字节),但可以存储更长的字符串,即长文本数据,例如博客内容。
BLOB 类型主要用于存储二进制大对象,例如图片、音视频等文件。
缺陷:
-
不能有默认值。
-
检索效率较低。
-
不能直接创建索引,需要指定前缀长度。
-
可能会消耗大量的网络和 IO 带宽。
-
可能导致表上的 DML 操作变慢。
5. DATETIME 和 TIMESTAMP 的区别是什么?
DATETIME 类型没有时区信息 8字节,TIMESTAMP 和时区有关 4字节。
DATETIME:1000-01-01 00:00:00 ~ 9999-12-31 23:59:59
Timestamp:1970-01-01 00:00:01 ~ 2037-12-31 23:59:59
6. NULL 和 '' 的区别是什么?
NULL
跟 ''
(空字符串)是两个完全不一样的值:
-
NULL
代表一个不确定的值,就算是两个NULL
,它俩也不一定相等。例如,SELECT NULL=NULL
的结果为 false,但是在我们使用DISTINCT
,GROUP BY
,ORDER BY
时,NULL
又被认为是相等的。 -
''
的长度是 0,是不占用空间的,而NULL
是需要占用空间的。 -
NULL
会影响聚合函数的结果。例如,SUM
、AVG
、MIN
、MAX
等聚合函数会忽略NULL
值。COUNT
的处理方式取决于参数的类型。如果参数是*
(COUNT(*)
),则会统计所有的记录数,包括NULL
值;如果参数是某个字段名(COUNT(列名)
),则会忽略NULL
值,只统计非空值的个数。 -
查询
NULL
值时,必须使用IS NULL
或IS NOT NULLl
来判断,而不能使用 =、!=、 <、> 之类的比较运算符。而''
是可以使用这些比较运算符的。
7. Boolean 类型如何表示?
MySQL 中没有专门的布尔类型,而是用 TINYINT(1) 类型来表示布尔值。TINYINT(1) 类型可以存储 0 或 1,分别对应 false 或 true。
3. 存储引擎
MySQL 当前默认的存储引擎是 InnoDB</