MySQL引擎有哪些
MySQL 支持多种存储引擎,不同引擎适合不同的场景和需求。以下是 MySQL 常见的存储引擎及其特点:
InnoDB
特点:
- 默认存储引擎(MySQL5.5开始)
- 支持事务(ACID)
- 支持行级锁,提高并发性能
- 支持外键约束
- 支持崩溃恢复(通过redo log和nudo log实现)
- 数据存储类型为聚簇索引,主键索引和数据保存在一起
适用场景:
- 高并发,需要支持事务的场景
MyISAM
特点:
- 不支持事务
- 支持表级别锁(并发性能较差)
- 访问数据速度快,适合只读或者多读写少的环境
- 不支持外键
- 不支持崩溃恢复,数据可靠性差
适用场景:
- 数据库主要以读操作为主,如日志数据存储,查询统计等
外键
外键(Foreign Key) 是关系型数据库中用来建立和加强两个表之间连接的一种约束。它是一列(或多列)字段,其值引用另一张表中的主键,用于维护数据的完整性和一致性。
外键的作用:
建立表之间的关系:
- 外键可以关联两张表,从而形成父子表的形式,例如订单表中的customer_id可以是客户表的主键Id的外键
保证数据一致性:
- 外键可以确保子表中的值必须在父表中存在。例如,不能插入一个不存在的 customer_id 到订单表中
维护数据的完整性:
- 外键可以定义删除或更新父表记录时对关联子表的影响(CASCADE、SET NULL、NO ACTION 等)。
外键的使用场景
约束关系
- 一个订单必须关联一个存在的客户
- 学生选课表必须引用存在的学生和课程
保证引用完整性
- 避免孤立记录,比如某个订单关联的客户被删除后,订单中的 customer_id 仍然存在
MySQL数据类型
- 数值类型
整数类型
数据类型 | 存储范围(有符号) | 存储范围(无符号) | 字节数 |
---|---|---|---|
TINYINT | -128到127 | 0到255 | 1 |
SMALLINT | -32768到32767 | 0到65,535 | 2 |
MEDIUMINT | -8,388,608到8,388,607 | 0 到 16,777,215 | 3 |
INT/INTEGER | -2,147,483,648到2,147,483,647 | 0到4,294,967,295 | 4 |
BIGINT | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | 0 到 18,446,744,073,709,551,615 | 8 |
- 特点: 默认情况下是有符号的,使用 UNSIGNED 修饰表示无符号。
- 用途: 适合用于存储整数,如年龄、ID 等。
浮点类型
数据类型 | 存储范围 | 字节数 | 精度| |
---|---|---|---|
FLOAT(p) | -3.402823466E+38 到 3.402823466E+38 | 4 | 24位有效数字 |
DOUBLE / REAL | -1.7976931348623157E+308 到 1.7976931348623157E+308 | 8 | 53位有效数字(双精度) |
DECIMAL(p, d) / NUMERIC(p, d) | 用户定义范围,精确存储 | 可变|用户定义,最多 65 位数字| |
特点
- FLOAT 和 DOUBLE 是近似值存储,可能会有精度丢失。
- DECIMAL 是精确值存储,适合用于财务数据等场景。
- 字符串类型
定长字符串
数据类型 | 描述 | 最大长度 |
---|---|---|
CHAR(n) | 定长字符串,长度为 n(0 到 255)。 | 255 |
变长字符串
数据类型 | 描述 | 最大长度 |
---|---|---|
VARCHAR(n) | 可变长度字符串,长度为 n(1 到 65,535,受行大小限制)。 | 65,535 |
文本类型
数据类型 | 描述 | 最大长度 |
---|---|---|
TINYTEXT | 非常小的文本数据 | 255 |
TEXT | 小文本数据 | 65,535 |
MEDIUMTEXT | 中等长度文本数据 | 16,777,215 |
LONGTEXT | 非常大的文本数据 | 4,294,967,295 |
日期和时间类型
数据类型 描述 格式 范围 DATE 日期 YYYY-MM-DD 1000-01-01 到 9999-12-31 DATETIME 日期和时间 YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00 到 9999-12-31 23:59:59 TIMESTAMP 时间戳 YYYY-MM-DD HH:MM:SS 1970-01-01 00:00:01 UTC 到 2038-01-19 03:14:07 UTC TIME 时间 HH:MM:SS -838:59:59 到 838:59:59 YEAR 年 YYYY 1901 到 2155 - JSON 和空间数据类型
JSON
- 类型: JSON
- 特点: 存储 JSON 格式的数据,支持快速的查询和操作。
空间数据类型
- GEOMETRY、POINT、LINESTRING、POLYGON 等。
- 用途: 用于存储和操作地理空间数据。
CHAR和VARCHAR的区别
定义
CHAR:
- 是定长的字符串类型
- 无论实际存储多少字符,都会占用固定长度的存储空间
- 不足部分用空格填充
- 适合存储长度固定或者接近的字符串,如身份证号、邮政编码
VARCHAR
- 是变长的字符串类型
只占用实际存储的字符长度,加上一个或者两个字节用于记录长度
- 若长度 > 255,则额外占用2个字节
- 若长度 <= 255,则额外占用1个字节
- 适合存储长度变化较大的字符串,如用户名、地址等。
存储方式
CHAR:
- 存储在表的固定长度区域,读取效率比较高
- 即使存储的字符比较少,也会占用固定的空间,例如CHAR(10),存储abc仍会占用10个字节
VARCHAR:
- 存储在表的变长区域,只占用实际字符所需空间外加字段长度
- 空间利用率高,但由于需要记录长度,存储和读取的性能略低于CHAR
查询和比较
CHAR:
- 存储时会在尾部补空格,但在比较时会自动去掉尾部空格。
- 如 CHAR(5) 存储 abc,查询 WHERE column = 'abc' 仍然匹配。
VARCHAR:
- 存储和查询时不会自动补空格,比较时会严格匹配字符的长度。
性能差异
CHAR:
- 由于是定长,存储时的性能较好,适合频繁查询或更新的字段
- 读取速度较快,因为数据存储位置固定,不需要额外计算偏移量
VARCHAR:
- 性能稍低于 CHAR,因为是变长类型,存储和读取时需要处理长度字段
- 但节省了存储空间,尤其在存储长字符串时效果显著
索引
索引是数据库中一种特殊的存储结构,保存了表中一部分字段的值及对应记录的指针。通过索引,可以高效地执行 SQL 查询语句中的 SELECT、UPDATE、DELETE 等操作。
- 索引的类型
(1) 普通索引
- 特点: 提供基本的查询加速功能。
- 适用场景: 单字段的高频查询。
(2) 唯一索引
- 特点: 确保索引列的值唯一。
- 适用场景: 需要唯一值的字段,如身份证号、邮箱等。
(3) 主键索引
- 特点: 是一种特殊的唯一索引,不允许空值,自动创建在主键列上。
- 每张表通常有且仅有一个主键索引。
(4) 组合索引
- 特点: 将多个字段组合为一个索引,加速多条件查询。
- 适用场景: 多个字段组合查询频繁,如 (province, city)。
(5) 全文索引
- 特点: 用于全文搜索功能,支持模糊查询。
- 适用场景: 适合存储大量文本数据的场景,如博客、文章。
(6) 聚簇索引
- 特点:表数据和索引存储在同一结构中
- 适用场景: 用于高效存取与主键顺序相关的数据。
索引的作用
- 加速查询: 通过索引快速定位目标记录,避免全表扫描。
- 保证数据唯一性: 通过唯一索引约束,防止重复数据插入
- 加速排序和分组: 使用索引优化 ORDER BY、GROUP BY 等操作。
- 加速关联查询: 索引提升 JOIN 操作的效率。
索引的缺点
- 占用存储空间: 索引本身需要额外存储空间
- 降低写入性能: 每次插入、更新或删除数据,需同步更新索引。
- 不适用全部查询: 对于范围查询、大量重复值,索引效果有限。
索引的使用场景
- 经常在 WHERE 子句中使用的字段。
- 需要排序或分组的字段。
- 用于多表连接中的字段。
不适合创建索引的场景
- 数据更新频繁但查询较少。
- 字段值重复较多(如性别字段)。
- 小表中记录量很少。
- 索引的原理
(1) 数据结构
B+数:
- 大多数索引底层采用B+数
- 平衡数结构
哈希索引
- 通过哈希函数计算位置,适合等值查询
- 不支持范围查询
(2) 索引的存储
- InnoDB: 主键索引为聚簇索引,其他索引为非聚簇索引。
- MyISAM: 所有索引为非聚簇索引。
MySQL中NULL(空值)和空字符串('')
- NULL和空字符串区别
NULL:表示一个值不存在或未知。它不是一个值,而是一个状态。
例如,SELECT NULL = NULL; 返回 NULL,因为 NULL 无法用来比较。
空字符串 (''):表示一个长度为零的字符串
例如,SELECT '' = ''; 返回 TRUE,因为空字符串是一个明确的值。
- NULL 的判断
使用 IS NULL 判断是否为 NULL:
- 示例:SELECT * FROM table_name WHERE column_name IS NULL;
使用 IS NOT NULL 判断是否不为 NULL
- 示例:SELECT * FROM table_name WHERE column_name IS NOT NULL;
- 注意:不能用 = 或 != 判断 NULL 值
- 空字符串的判断
使用 = 判断空字符串:
- 示例:SELECT * FROM table_name WHERE column_name = '';
使用 != 判断非空字符串:
- 示例:SELECT * FROM table_name WHERE column_name != '';
空字符串与 NULL 的区别
- column_name = '' 会匹配存储了空字符串的行
- column_name IS NULL 会匹配存储了 NULL 的行。
- 同时判断 NULL 和空字符串
事务
事务的四个特性(ACID)
- Atomicity(原子性)
事务中的操作要么全部执行成功,要么全部回滚失败,不会出现部分成功、部分失败的情况。
- Consistency(一致性)
事务执行前后,数据库必须从一个一致的状态转变为另一个一致的状态。事务结束后,所有数据都必须满足完整性约束。
- Isolation(隔离性)
多个事务并发执行时,一个事务的执行不应影响其他事务,表现得像是事务是串行执行的。
- Durability(持久性)
事务一旦提交,其对数据库的修改是永久的,即使系统崩溃也不会丢失。
事务的隔离级别
- 读未提交(Read Uncommitted)事务可以读取其他未提交事务修改的数据
- 读已提交(Read Committed)事务只能读取其他事务已经提交的数据。
- 可重复读(Repeatable Read)确保在同一事务中,多次读取同一数据时,数据是一致的。
- 可序列化(Serializable)强制事务顺序执行,避免所有并发问题(脏读、不可重复读、幻读)。
%会走索引吗
- % 在字符串的结尾(会)
- % 在字符串的开头(不会)
- % 在字符串的中间(不会)
- 纯 % 查询(不会)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。