一、什么是数据库?
1.1 概念
数据库(Database,简称 DB) 是长期存放在计算机内、有组织、可共享的大量数据的集合,是一个数据"仓库"。
1.2 作用
存放和管理数据。
1.3 分类
| 类型 | 说明 | 代表 |
|---|
| 关系型数据库 | 使用表格存储数据,数据之间有关联关系 | MySQL、Oracle、SQL Server | | NoSQL 数据库 | 非关系型数据库,适合大数据、高并发场景 | MongoDB、Redis |
二、为什么选择 MySQL?
MySQL 是目前最流行的开源关系型数据库之一,具有以下特点:
- ✅ 操作便捷:SQL 语法简单易学
- ✅ 小巧、功能齐全:体积小但功能强大
- ✅ 免费开源:社区版完全免费
- ✅ 跨平台:可运行在 Windows 或 Linux 系统
三、数据库结构概览
| 概念 | 说明 |
|---|
| 数据库(Database) | 以文件形式存放在磁盘上,对应一个或多个物理文件 | | 数据表(Table) | 由一组数据记录组成,数据库中的数据以表为单位进行组织 | | 字段(Field) | 也称"域",表中的每一列称为一个字段 | | 记录(Record) | 表中的每一行称为一个记录,由若干字段组成 | | 索引(Index) | 含有关键字段的值和指向实际记录位置的指针,可提高访问效率 | | SQL 语句 | 结构化查询语言,用于操作数据库 |
四、SQL 语句分类
| 分类 | 全称 | 作用 | 常用命令 |
|---|
| DDL | 数据定义语言(Data Definition Language) | 定义和管理数据对象,如数据库、数据表 | CREATE、DROP、ALTER | | DML | 数据操作语言(Data Manipulation Language) | 操作数据库对象中包含的数据 | INSERT、UPDATE、DELETE | | DQL | 数据查询语言(Data Query Language) | 查询数据库数据 | SELECT | | DCL | 数据控制语言(Data Control Language) | 管理权限及数据更改 | GRANT、COMMIT、ROLLBACK |
五、DDL 操作数据库
5.1 创建数据库- CREATE DATABASE [IF NOT EXISTS] dbname;
复制代码- IF NOT EXISTS:可选,如果数据库不存在则创建
- dbname:数据库名称
5.2 删除数据库- DROP DATABASE [IF EXISTS] dbname;
复制代码5.3 查看所有数据库
⚠️ 注意:不要省略末尾的 S
5.4 选择数据库
六、DDL 创建数据表
6.1 基本语法- CREATE TABLE 表名 (
- 字段名1 类型 [属性],
- 字段名2 类型 [属性],
- ...
- 字段名n 类型 [属性] -- 最后一个字段不带逗号
- );
复制代码6.2 示例- CREATE TABLE student (
- stu_name VARCHAR(10),
- stu_age TINYINT,
- stu_birthday DATETIME,
- stu_id CHAR(18),
- stu_score DECIMAL(4,1)
- );
复制代码
七、数据类型详解
7.1 字符串类型
| 类型 | 说明 | 取值范围 | 存储需求 |
|---|
| CHAR(M) | 固定长度字符串,检索快但费空间 | 0 ≤ M ≤ 255 | M 字符 | | VARCHAR(M) | 可变长度字符串 | 0 ≤ M ≤ 65535 | 变长度 | | TINYTEXT | 微型文本串 | 16777215 长度 + 3 字节 | tinytext | | TEXT | 文本串(约 4G 大小) | 4294967295 长度 + 4 字节 | text |
💡 CHAR vs VARCHAR 选择建议:
- CHAR:适用于长度固定、查询频繁的场景(如手机号、身份证号)
- VARCHAR:适用于长度不固定、节省空间的场景(如姓名、地址)
7.2 数值类型
| 类型 | 说明 | 取值范围 | 存储需求 |
|---|
| TINYINT | 非常小的数据 | 有符号:-2⁷ ~ 2⁷-1;无符号:0 ~ 2⁸-1 | 1 字节 | | SMALLINT | 较小的数据 | 有符号:-2¹⁵ ~ 2¹⁵-1;无符号:0 ~ 2¹⁶-1 | 2 字节 | | MEDIUMINT | 中等大小的数据 | 有符号:-2²³ ~ 2²³-1;无符号:0 ~ 2²⁴-1 | 3 字节 | | INT | 标准整数 | 有符号:-2³¹ ~ 2³¹-1;无符号:0 ~ 2³²-1 | 4 字节 | | BIGINT | 较大的整数 | 有符号:-2⁶³ ~ 2⁶³-1;无符号:0 ~ 2⁶⁴-1 | 8 字节 | | FLOAT | 单精度浮点数 | ±1.1754351e-38 | 4 字节 | | DOUBLE | 双精度浮点数 | ±2.2250738585072014e-308 | 8 字节 | | DECIMAL(M,D) | 精确小数(适用于金额) | 由 M 和 D 决定 | M 个字节 |
⚠️ DECIMAL 使用注意:
- M 指字节长度,D 指小数位数
- 例如 DECIMAL(4,1) 最多存储 999.9
- 适用于需要精确计算的场景(如金额)
7.3 NULL 类型
- 理解为"没有值"或"未知值"
- 不要用 NULL 进行算术运算,结果仍为 NULL
- MySQL 中,0 或 NULL 都意味着为假,1 为真
八、字段注释
给字段增加注释,方便后续维护: - CREATE TABLE student (
- stu_id INT(4) COMMENT 'ID',
- stu_name VARCHAR(10) COMMENT '姓名',
- stu_age INT(2) COMMENT '年龄',
- stu_sex CHAR(2) COMMENT '性别'
- );
复制代码
九、查看表结构
方式一:desc 命令- DESC student;
- -- 或
- DESCRIBE student;
复制代码方式二:查看建表语句- SHOW CREATE TABLE student;
复制代码
十、修改和删除表结构
10.1 修改表名- ALTER TABLE 旧表名 RENAME AS 新表名;
- -- 示例
- ALTER TABLE student RENAME AS xuesheng;
复制代码10.2 添加字段- ALTER TABLE 表名 ADD 字段名 类型 [属性];
- -- 示例
- ALTER TABLE xuesheng ADD stu_qq VARCHAR(20) COMMENT '这是学生的QQ号';
复制代码10.3 删除字段(⚠️ 危险操作)- ALTER TABLE 表名 DROP 字段名;
- -- 示例
- ALTER TABLE xuesheng DROP stu_age;
复制代码10.4 修改字段
方式一:MODIFY(只改类型和属性)- ALTER TABLE 表名 MODIFY 字段名 新类型 [新属性];
- -- 示例:将 stu_name 长度改为 100
- ALTER TABLE xuesheng MODIFY stu_name VARCHAR(100);
复制代码方式二:CHANGE(可改字段名、类型和属性)- ALTER TABLE 表名 CHANGE 旧字段名 新字段名 新类型 [新属性];
- -- 示例:将 stu_qq 改名为 qq
- ALTER TABLE xuesheng CHANGE stu_qq qq VARCHAR(20) COMMENT '这是学生的QQ号';
复制代码10.5 删除表(⚠️ 危险操作)- DROP TABLE [IF EXISTS] 表名;
复制代码
十一、存储引擎
11.1 InnoDB(MySQL 5.5+ 默认)
特点:
- ✅ 支持事务处理(ACID)
- ✅ 支持外键约束
- ✅ 支持行级锁,适合高并发
- ✅ 崩溃后可安全恢复
适用场景: 需要频繁增删改查、高并发、事务处理的场景
文件结构:
- 表名.ibd:存储数据和索引(MySQL 8.0 合并了表结构)
11.2 MyISAM(MySQL 5.5 之前默认)
特点:
- ✅ 访问速度快
- ✅ 支持全文索引、压缩、空间函数
- ❌ 不支持事务
- ❌ 不支持外键
- ❌ 不支持行级锁(表级锁)
- ❌ 崩溃后无法安全恢复
适用场景: 只读应用或以读为主的业务
文件结构:
- 表名.frm:存储表结构
- 表名.MYD:存储数据(MYData)
- 表名.MYI:存储索引(MYIndex)
11.3 InnoDB vs MyISAM 对比
| 对比项 | MyISAM | InnoDB |
|---|
| 外键 | ❌ 不支持 | ✅ 支持 | | 事务 | ❌ 不支持 | ✅ 支持 | | 锁机制 | 表锁 | 行锁 | | 缓存 | 只缓存索引 | 缓存索引 + 真实数据 | | 默认使用 | ❌ 否(5.5 之前是) | ✅ 是(5.5+) | | 关注点 | 性能:节省资源、消耗少 | 事务:并发写、更大资源 |
十二、数据库三大范式
12.1 什么是范式?
为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循的规则。
12.2 第一范式(1NF):确保每列保持原子性
- 每一列属性都是不可再分的属性值
- 两列属性相近或相似时,尽量合并
反例: 地址字段存"北京市海淀区",应拆分为省、市、区三列。
12.3 第二范式(2NF):确保每列都和主键相关
- 在满足 1NF 的基础上建立
- 每个实例或行必须可以被唯一区分
- 需要添加主键作为唯一标识
12.4 第三范式(3NF):确保每列都和主键直接相关
- 数据不能存在传递关系
- 即每个属性都跟主键有直接关系,而不是间接关系
反例: - 学生表(学号,姓名,年龄,性别,所在院校,院校地址,院校电话)
复制代码存在传递关系:学号 → 所在院校 → (院校地址,院校电话)
应拆分为:
- 学生表(学号,姓名,年龄,性别,所在院校)
- 院校表(所在院校,院校地址,院校电话)
💡 注意:三大范式是一般设计数据库的基本理念,但需求 > 性能 > 表结构,不能一味追求范式。
十三、约束
13.1 什么是约束?
约束是表中数据的限制条件,目的是保证表中的记录完整和有效。
13.2 约束种类
| 约束 | 说明 |
|---|
| NOT NULL | 非空约束 | | UNIQUE | 唯一性约束 | | PRIMARY KEY | 主键约束 | | FOREIGN KEY | 外键约束 | | CHECK | 检查约束(MySQL 不支持,Oracle 支持) |
13.3 约束示例
非空约束- CREATE TABLE tb1 (
- username VARCHAR(10) NOT NULL, -- 非空约束
- userage INT DEFAULT NULL
- );
- -- 带默认值的非空约束
- CREATE TABLE tb2 (
- username VARCHAR(10) NOT NULL DEFAULT '无名',
- userage INT
- );
复制代码唯一约束- -- 行级约束(单列唯一)
- CREATE TABLE tb3 (
- username VARCHAR(10) UNIQUE,
- userage INT
- );
- -- 联合唯一约束(多列组合唯一)
- CREATE TABLE tb4 (
- username VARCHAR(10),
- userage INT,
- UNIQUE(username, userage)
- );
- -- 给约束起名字
- CREATE TABLE tb5 (
- username VARCHAR(10),
- userage INT,
- CONSTRAINT name_age_unique UNIQUE(username, userage)
- );
复制代码
💡 注意:唯一约束可以为 NULL,并且可以有多个 NULL(因为 NULL 是一个类型)。
主键约束- -- 单列主键
- CREATE TABLE tb6 (
- username VARCHAR(10) PRIMARY KEY,
- userage INT
- );
- -- 联合主键
- CREATE TABLE tb7 (
- username VARCHAR(10),
- userage INT,
- PRIMARY KEY(username, userage)
- );
- -- 自增主键(推荐)
- CREATE TABLE tb8 (
- tid INT PRIMARY KEY AUTO_INCREMENT, -- 主键自增,不会回补
- username VARCHAR(10),
- userage INT
- );
复制代码
💡 主键特点:每张表必须有且只有一个主键;主键值唯一且不能为 NULL。
外键约束- -- 父表(主表)
- CREATE TABLE a (
- aid INT PRIMARY KEY AUTO_INCREMENT,
- aname VARCHAR(10)
- );
- -- 从表
- CREATE TABLE b (
- bid INT PRIMARY KEY AUTO_INCREMENT,
- bname VARCHAR(10),
- aid INT,
- FOREIGN KEY(aid) REFERENCES a(aid)
- );
复制代码
💡 外键特点:
- 外键值可以重复
- 外键值可以为 NULL
- 外键值必须是父表中存在的值
- 父表的关联字段必须具有唯一性
- 一个表中可以有多个外键,但只能有一个主键
13.4 删除约束- -- 删除 NOT NULL 约束
- ALTER TABLE 表名 MODIFY 列名 类型;
- -- 删除 UNIQUE 约束
- ALTER TABLE 表名 DROP INDEX 唯一约束名;
- -- 删除 PRIMARY KEY 约束
- ALTER TABLE 表名 DROP PRIMARY KEY;
- -- 删除 FOREIGN KEY 约束
- ALTER TABLE 表名 DROP FOREIGN KEY 外键名;
复制代码
十四、面试常问
Q1:CHAR() 和 VARCHAR() 的区别?
答:
- CHAR(M):固定长度字符串;VARCHAR(M):可变长度字符串
- 超过最大长度谁都存不下
- VARCHAR 不浪费空间但效率低,适用于姓名等变长数据;CHAR 浪费空间但效率高,适用于手机号、身份证号等定长数据
Q2:InnoDB 与 MyISAM 的区别?
答:
- InnoDB:支持事务、外键、行级锁;擅长增删改查,适用于高并发和事务处理场景
- MyISAM:不支持事务、外键、行级锁;擅长读取,崩溃后无法恢复;优点是存取快、资源消耗少,适用于查询密集型场景
Q3:INT(1) 与 INT(11) 的区别?
答: 区别仅在于显示宽度。
- INT(1) 中"1"表示显示宽度为 1 位
- INT(11) 中"11"表示显示宽度为 11 位
- 但它们的存储范围和存储空间完全相同(4 字节,-2147483648 ~ 2147483647)
- 显示宽度只影响显示效果,不影响存储内容
Q4:三大范式是什么?
答:
- 第一范式:确保每列保持原子性
- 第二范式:确保每列都和主键相关
- 第三范式:确保每列都和主键直接相关,而不是间接相关
Q5:外键约束和外键关系是一回事吗?
答: 不是。
- 外键关系:两个表通过外键建立的关联
- 外键约束:保障外键关系完整性、一致性的规则(如确保外键值在父表的主键或唯一键中存在)
Q6:DELETE / TRUNCATE / DROP 的区别?
答:
| 命令 | 作用 | 是否可回滚 | 速度 |
|---|
| DELETE | 删除表中数据,保留表结构 | ✅ 可回滚 | 慢 | | TRUNCATE | 清空表中所有数据,保留表结构 | ❌ 不可回滚 | 快 | | DROP | 删除整个表(结构和数据) | ❌ 不可回滚 | 最快 |
只想删除数据用 DELETE 或 TRUNCATE;彻底删除表用 DROP。
十五、总结
本文从数据库基础概念出发,系统梳理了 MySQL 的核心知识点:
- ✅ 数据库基本概念与 SQL 分类
- ✅ DDL 操作(数据库和表的增删改查)
- ✅ 常用数据类型及选择建议
- ✅ 存储引擎对比(InnoDB vs MyISAM)
- ✅ 三大范式与数据库设计
- ✅ 约束的创建与删除
- ✅ 面试高频问题
希望这篇文章能帮助你快速入门 MySQL,欢迎在评论区交流讨论!
如果对你有帮助,欢迎 点赞 👍 + 收藏 ⭐ + 关注 🔖,持续分享更多技术干货! |