MySQL 作为目前最流行的开源关系型数据库管理系统之一,广泛应用于 Web 开发、数据分析等领域。对于初学者而言,掌握其核心基础概念和操作,是搭建数据存储层的第一步。本文将跳过安装环节(安装环节点此跳转),从核心概念、数据类型、基本操作、约束与索引等维度,带你快速入门 MySQL 基础。
一、MySQL 核心概念先知晓
在动手操作前,先理清几个关键概念,能让你对 MySQL 的工作模式有整体认知:
1. 数据库(Database)
数据库是数据表的集合 ,用于按特定规则组织和存储相关数据。比如一个博客系统,可创建名为 blog_system 的数据库,存放用户表、文章表、评论表等。
2. 数据表(Table)
数据表是数据库的核心组成单位,采用行(Row)和列(Column) 的二维结构存储数据:
- 列(字段 / Column) :代表数据的属性,比如用户表的
id、username、age等; - 行(记录 / Row) :代表一条具体的数据,比如某一个用户的信息就是一行记录。
3. 数据类型(Data Type)
MySQL 为不同类型的数据定义了专属的数据类型,用于约束字段的存储内容,选择合适的数据类型能提升存储效率和查询性能。
4. 主键(Primary Key)
唯一标识数据表中每一行记录的字段,具有唯一性 和非空性 ,比如用户表的 id 通常设为主键。
5. 索引(Index)
用于加速数据表的查询操作,类似书籍的目录,能让 MySQL 快速定位到目标数据,避免全表扫描。
二、DDL:定义表结构时,嵌入 MySQL 的核心设计逻辑
DDL(数据定义语言)负责数据库和表的结构创建与修改,而在 MySQL 中,表结构的设计直接决定了后续性能和数据完整性,我们需要将存储引擎、字符集、约束、索引设计融入 DDL 操作中。
1. 数据库创建
MySQL 的字符集选择是基础且关键的设计,utf8mb4作为真正的 UTF-8 编码,支持 emoji 和所有生僻字,是开发的首选,需在创建数据库时直接指定:
sql
-- 创建博客系统数据库,嵌入MySQL的字符集配置
CREATE DATABASE IF NOT EXISTS blog_system
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
2.什么是约束
- 约束:约束是作用于表中字段上的规则,用于限制存储在表中的数据。
- 目的:保证数据库中数据的正确性、有效性和完整性。

3. 数据表创建
创建表时不仅要定义字段,还要结合 MySQL 的自增主键、外键约束和索引设计,这是 MySQL 表结构设计的核心:
sql
-- auto_increment:设置主键自增长,默认从1开始,每次插入一条数据id值递增1,要求字段类型必须是数字类
-- 数据类型:varchar(50),可变长度字符串,字符串长度可以使0~50个字符
-- 数据类型:char(1),固定长度字符串,字符串只有1个字符
create table emp(
id int primary key auto_increment comment '主键',
username varchar(50) not null unique comment '用户账号',
name varchar(50) unique comment '姓名',
age int comment '年龄',
gender char(1) default '男' comment '性别'
)comment '员工表';
4. 操作表结构
sql
-- DDL操作表结构
-- 查询所有表
show tables ;
-- 查询指定表详细信息
desc emp;
-- 查看建表语句
show create table emp;
-- 添加address字段
alter table emp add address varchar(200) comment '地址' not null ;
-- 修改字段类型,将 varchar(200)修改varchar(500)
alter table emp modify address varchar(500);
-- 修改字段名与字段类型
alter table emp change address adr varchar(200) comment '地址' not null ;
-- 删除字段
alter table emp drop column adr;
-- 修改表名
alter table emp rename emp2;
-- 删除表
drop table if exists emp2;
二、DML:操作数据时,结合 MySQL 的性能与事务特性
DML(数据操作语言)负责增删改数据,在 MySQL 中,数据操作的效率和安全性依赖于批量操作、事务控制、索引利用等特性,需将这些特性与 DML 语法深度结合。
1. INSERT:利用 MySQL 批量插入提升性能
MySQL 的单条插入会频繁触发日志写入和网络交互,而批量插入能大幅减少开销,这是 MySQL 优化插入性能的核心技巧:
sql
-- DML : 数据操作语言
-- DML : 插入数据 - insert
-- 添加password
alter table employee add password varchar(50) default '123456' comment '密码';
-- 1. 为 emp 表的 username, password, name, gender, phone 字段插入值
insert into employee(username, password, name, gender, phone) values
('zhangsan',null,'张三',1,'15012345678');
-- 2. 为 emp 表的 所有字段插入值
-- 注意:如果没有指定字段,就插入全部,顺序必须按照字段列表顺序插入
insert into employee values (null,'lisi','李四',2,'15012345671',1,8015.31,'1.png',
2025-12-18,null,'123345678');
-- 3. 批量为 emp 表的 username, password, name, gender, phone 字段插入数据
insert into employee(username, password, name, gender, phone) values
('zhangsan2',null,'张三2',1,'15012345672'),
('zhangsan3',null,'张三3',1,'15012345673');
2. UPDATE/DELETE:结合 MySQL 的事务和索引,保证安全与效率
- 安全层面:利用 MySQL 的事务特性,在批量更新 / 删除前开启事务,出错时可回滚;
- 效率层面:通过索引字段作为 WHERE 条件,让 MySQL 快速定位数据,避免全表扫描。
sql
-- DML : 更新数据 - update
-- 1. 将 emp 表的ID为1员工 用户名更新为 'zhangsan', 姓名name字段更新为 '张三'
update employee set username='zhangsan4' ,name='张三4' where id = 1;
-- 2. 将 emp 表的所有员工的入职日期更新为 '2010-01-01'
update employee set entry_date = '2010-01-01';
-- DML : 删除数据 - delete
-- 1. 删除 emp 表中 ID为1的员工
delete from employee where id = 1;
-- 2. 删除 emp 表中的所有员工
delete from employee;
核心注意点:
- 避免无 WHERE 条件的 UPDATE/DELETE,这会导致 MySQL 全表更新 / 删除,性能极低且数据风险大;
三、DQL:查询数据时,深度利用 MySQL 的索引和查询特性
DQL(数据查询语言)是 MySQL 使用最频繁的操作,查询效率的高低直接取决于是否利用索引、是否遵循 MySQL 的查询优化规则,需将查询语法与 MySQL 的索引、函数、分页特性深度融合。
1. 基础查询
查询之前先创建一个user表并初始化表的数据
sql
create table emp
(
id int unsigned primary key auto_increment comment 'ID,主键',
username varchar(20) not null unique comment '用户名',
password varchar(32) not null comment '密码',
name varchar(10) not null comment '姓名',
gender tinyint unsigned not null comment '性别, 1:男, 2:女',
phone char(11) not null unique comment '手机号',
job tinyint unsigned comment '职位, 1:班主任,2:讲师,3:学工主管,4:教研主管,5:咨询师',
salary int unsigned comment '薪资',
image varchar(300) comment '头像',
entry_date date comment '入职日期',
create_time datetime comment '创建时间',
update_time datetime comment '修改时间'
) comment '员工表';
-- 准备测试数据
INSERT INTO emp(id, username, password, name, gender, phone, job, salary, image, entry_date, create_time, update_time)
VALUES (1, 'shinaian', '123456', '施耐庵', 1, '13309090001', 4, 15000, '1.jpg', '2000-01-01', '2024-04-11 16:35:33',
'2024-04-11 16:35:35'),
(2, 'songjiang', '123456', '宋江', 1, '13309090002', 2, 8600, '2.jpg', '2015-01-01', '2024-04-11 16:35:33',
'2024-04-11 16:35:37'),
(3, 'lujunyi', '123456', '卢俊义', 1, '13309090003', 2, 8900, '3.jpg', '2008-05-01', '2024-04-11 16:35:33',
'2024-04-11 16:35:39'),
(4, 'wuyong', '123456', '吴用', 1, '13309090004', 2, 9200, '4.jpg', '2007-01-01', '2024-04-11 16:35:33',
'2024-04-11 16:35:41'),
(5, 'gongsunsheng', '123456', '公孙胜', 1, '13309090005', 2, 9500, '5.jpg', '2012-12-05', '2024-04-11 16:35:33',
'2024-04-11 16:35:43'),
(6, 'huosanniang', '123456', '扈三娘', 2, '13309090006', 3, 6500, '6.jpg', '2013-09-05', '2024-04-11 16:35:33',
'2024-04-11 16:35:45'),
(7, 'chaijin', '123456', '柴进', 1, '13309090007', 1, 4700, '7.jpg', '2005-08-01', '2024-04-11 16:35:33',
'2024-04-11 16:35:47'),
(8, 'likui', '123456', '李逵', 1, '13309090008', 1, 4800, '8.jpg', '2014-11-09', '2024-04-11 16:35:33',
'2024-04-11 16:35:49'),
(9, 'wusong', '123456', '武松', 1, '13309090009', 1, 4900, '9.jpg', '2011-03-11', '2024-04-11 16:35:33',
'2024-04-11 16:35:51'),
(10, 'lichong', '123456', '林冲', 1, '13309090010', 1, 5000, '10.jpg', '2013-09-05', '2024-04-11 16:35:33',
'2024-04-11 16:35:53'),
(11, 'huyanzhuo', '123456', '呼延灼', 1, '13309090011', 2, 9700, '11.jpg', '2007-02-01', '2024-04-11 16:35:33',
'2024-04-11 16:35:55'),
(12, 'xiaoliguang', '123456', '小李广', 1, '13309090012', 2, 10000, '12.jpg', '2008-08-18',
'2024-04-11 16:35:33', '2024-04-11 16:35:57'),
(13, 'yangzhi', '123456', '杨志', 1, '13309090013', 1, 5300, '13.jpg', '2012-11-01', '2024-04-11 16:35:33',
'2024-04-11 16:35:59'),
(14, 'shijin', '123456', '史进', 1, '13309090014', 2, 10600, '14.jpg', '2002-08-01', '2024-04-11 16:35:33',
'2024-04-11 16:36:01'),
(15, 'sunerniang', '123456', '孙二娘', 2, '13309090015', 2, 10900, '15.jpg', '2011-05-01', '2024-04-11 16:35:33',
'2024-04-11 16:36:03'),
(16, 'luzhishen', '123456', '鲁智深', 1, '13309090016', 2, 9600, '16.jpg', '2010-01-01', '2024-04-11 16:35:33',
'2024-04-11 16:36:05'),
(17, 'liying', '12345678', '李应', 1, '13309090017', 1, 5800, '17.jpg', '2015-03-21', '2024-04-11 16:35:33',
'2024-04-11 16:36:07'),
(18, 'shiqian', '123456', '时迁', 1, '13309090018', 2, 10200, '18.jpg', '2015-01-01', '2024-04-11 16:35:33',
'2024-04-11 16:36:09'),
(19, 'gudasao', '123456', '顾大嫂', 2, '13309090019', 2, 10500, '19.jpg', '2008-01-01', '2024-04-11 16:35:33',
'2024-04-11 16:36:11'),
(20, 'ruanxiaoer', '123456', '阮小二', 1, '13309090020', 2, 10800, '20.jpg', '2018-01-01', '2024-04-11 16:35:33',
'2024-04-11 16:36:13'),
(21, 'ruanxiaowu', '123456', '阮小五', 1, '13309090021', 5, 5200, '21.jpg', '2015-01-01', '2024-04-11 16:35:33',
'2024-04-11 16:36:15'),
(22, 'ruanxiaoqi', '123456', '阮小七', 1, '13309090022', 5, 5500, '22.jpg', '2016-01-01', '2024-04-11 16:35:33',
'2024-04-11 16:36:17'),
(23, 'ruanji', '123456', '阮籍', 1, '13309090023', 5, 5800, '23.jpg', '2012-01-01', '2024-04-11 16:35:33',
'2024-04-11 16:36:19'),
(24, 'tongwei', '123456', '童威', 1, '13309090024', 5, 5000, '24.jpg', '2006-01-01', '2024-04-11 16:35:33',
'2024-04-11 16:36:21'),
(25, 'tongmeng', '123456', '童猛', 1, '13309090025', 5, 4800, '25.jpg', '2002-01-01', '2024-04-11 16:35:33',
'2024-04-11 16:36:23'),
(26, 'yanshun', '123456', '燕顺', 1, '13309090026', 5, 5400, '26.jpg', '2011-01-01', '2024-04-11 16:35:33',
'2024-04-11 16:36:25'),
(27, 'lijun', '123456', '李俊', 1, '13309090027', 5, 6600, '27.jpg', '2004-01-01', '2024-04-11 16:35:33',
'2024-04-11 16:36:27'),
(28, 'lizhong', '123456', '李忠', 1, '13309090028', 5, 5000, '28.jpg', '2007-01-01', '2024-04-11 16:35:33',
'2024-04-11 16:36:29'),
(29, 'songqing', '123456', '宋清', 1, '13309090029', 5, 5100, '29.jpg', '2020-01-01', '2024-04-11 16:35:33',
'2024-04-11 16:36:31'),
(30, 'liyun', '123456', '李云', 1, '13309090030', NULL, NULL, '30.jpg', '2020-03-01', '2024-04-11 16:35:33',
'2024-04-11 16:36:31');
基础查询演示
sql
-- =================== DQL: 基本查询 ======================
-- 1. 查询指定字段 name,entry_date 并返回
select name, emp.entry_date
from emp;
-- 2. 查询返回所有字段
select *
from emp;
-- 注意:在企业开发中不推荐使用*,企业推荐需要多少个字段就查询多少个字段,不要查询所有浪费空间
-- 3. 查询所有员工的 name,entry_date, 并起别名(姓名、入职日期)
select emp.name as 名字, emp.entry_date as 入职日期
from emp;
select emp.name 名字, emp.entry_date 入职日期
from emp;
-- 4. 查询已有的员工关联了哪几种职位(不要重复)
select distinct emp.job
from emp;
2. 条件查询
sql
-- =================== DQL: 条件查询 ======================
-- 1. 查询 姓名 为 柴进 的员工
select *
from emp
where name = '柴进';
-- 2. 查询 薪资小于等于5000 的员工信息
select *
from emp
where salary <= 5000;
-- 3. 查询 没有分配职位 的员工信息
# select * from emp where job = null ;错误的
select *
from emp
where job is null;
-- 4. 查询 有职位 的员工信息
# select * from emp where job != null;错误的
select *
from emp
where job is not null;
-- 5. 查询 密码不等于 '123456' 的员工信息
select *
from emp
where password != '123456';
-- 6. 查询 入职日期 在 '2000-01-01' (包含) 到 '2010-01-01'(包含) 之间的员工信息
select *
from emp
where entry_date >= '2000-01-01'
and entry_date <= '2010-01-01';
select *
from emp
where entry_date between '2000-01-01' and '2010-01-01';
-- 7. 查询 入职时间 在 '2000-01-01' (包含) 到 '2010-01-01'(包含) 之间 且 性别为女 的员工信息
select *
from emp
where entry_date between '2000-01-01' and '2010-01-01'
and gender = 2;
-- 8. 查询 职位是 2 (讲师), 3 (学工主管), 4 (教研主管) 的员工信息
select *
from emp
where job in (2, 3, 4);
select *
from emp
where job = 2
or job = 3
or job = 4;
-- 9. 查询 姓名 为两个字的员工信息
select *
from emp
where name like '__';
-- like 模糊匹配 _代表任意一个字符
-- 10. 查询 姓 '李' 的员工信息
select *
from emp
where name like '李%';
-- 11. 查询 姓名中包含 '二' 的员工信息
select *
from emp
where name like '%二%';
3. 分组查询
sql
-- =================== DQL: 分组查询 ======================
-- 聚合函数
-- 1. 统计该企业员工数量
select count(*)
from emp;
select count(100)
from emp;
select count(job)
from emp;
-- count聚合函数其他用户
-- count(*) 统计所有符合的记录数
-- count(数字) 功能与count(*),例如 count(0)
-- count(字段) 统计该字段非空的数量
-- 2. 统计该企业员工的平均薪资
select avg(emp.salary)
from emp;
-- 3. 统计该企业员工的最低薪资
select min(emp.salary)
from emp;
-- 4. 统计该企业员工的最高薪资
select max(emp.salary)
from emp;
-- 5. 统计该企业每月要给员工发放的薪资总额(薪资之和)
select sum(emp.salary)
from emp;
-- 分组
-- 1. 根据性别分组 , 统计男性和女性员工的数量
-- 注意:sql规范,要求分组查询字段只能包含:分组字段和聚合函数
select emp.gender 性别, count(*) 数量
from emp
group by gender;
-- case when 条件判断返回不同的值
-- 用法1
select case emp.gender
when 1 then '男'
when 2 then '女'
else '保密' end
性别,
count(*) 数量
from emp
group by gender;
-- 用法2
select case
when emp.gender = 1 then '男'
when emp.gender = 2 then '女'
else '保密' end
性别,
count(*) 数量
from emp
group by gender;
-- 2. 先查询入职时间在 '2015-01-01' (包含) 以前的员工 , 并对结果根据职位分组 , 获取员工数量大于等于2的职位
select job 职位, count(*) 数量
from emp
where entry_date <= '2015-01-01'
group by job;
select job 职位, count(*) 数量
from emp
where entry_date <= '2015-01-01'
group by job
having count(*) >= 2;
select job 职位, count(*) 数量
from emp
where entry_date <= '2015-01-01'
group by job
having 数量 >= 2;
select case job
when 1 then '班主任'
when 2 then '讲师'
when 3 then '学工主管'
when 4 then '教研主管'
when 5 then '咨询师'
else '其他' end
职位,
count(*) 数量
from emp
where entry_date <= '2015-01-01'
group by job
having 数量 >= 2;
4.排序查询
sql
-- =================== 排序查询 ======================
-- 1. 根据入职时间, 对员工进行升序排序
select *
from emp
order by entry_date;
-- 默认升序
-- 2. 根据入职时间, 对员工进行降序排序
select *
from emp
order by entry_date desc;
-- 3. 根据 入职时间 对公司的员工进行 升序排序 , 入职时间相同 , 再按照 更新时间 进行降序排序
-- 如果是多字段排序,当第一个字段值相同时,才会根据第二个字段进行排序
select *
from emp
order by entry_date, update_time desc;
5.分页查询
sql
-- =================== 分页查询 ======================
-- 1. 需求:从起始索引0开始查询员工数据, 每页展示5条记录
-- 2. 查询 第1页 员工数据, 每页展示5条记录
select *
from emp
limit 0,5;
-- 开始索引 = (1-1)* 5 = 0
-- 3. 查询 第2页 员工数据, 每页展示5条记录
select *
from emp
limit 5,5;
-- 开始索引 = (2-1)* 5 = 0
-- 4. 查询 第3页 员工数据, 每页展示5条记录
select *
from emp
limit 10,5;
-- 开始索引 = (3-1)* 5 = 0
-- 已知条件,查询第几页page和每页显示多少条pageSize,求 limit 开始索引,查询多少条
-- 开始索引 = (page-1)* pageSize
-- 查询多少条 = pageSize
-- 注意:limit是方言,其他关系型数据库没有。
四、核心总结:SQL 与 MySQL 特性融合的关键原则
- 结构设计阶段 :DDL 需结合 MySQL 的
InnoDB引擎、utf8mb4字符集、索引和约束,从源头保证数据存储的高效性和完整性; - 数据操作阶段:DML 需利用 MySQL 的批量操作、事务控制,兼顾性能和数据安全;
- 数据查询阶段 :DQL 需深度利用 MySQL 的索引特性、内置函数和分页语法,通过
EXPLAIN工具优化查询。
MySQL 的使用本质是SQL 语法 与数据库自身特性的结合,脱离特性的语法操作会导致性能低下,而脱离语法的特性则无法落地。只有将两者深度融合,才能在实际开发中发挥 MySQL 的最大价值。