MySQL 概述
数据库相关概念
- 数据库:存储数据的仓库,数据时有组织的进行存储,简称 DataBase(DB)
- 数据库管理系统:操纵和管理数据库的大型软件,简称 DataBase Management System(DBMS)
- SQL:操作关系型数据库的编程语言,定义了一套操作关系型数据库统一标准,简称 Structured Query Language(SQL)
MySQL 数据库
版本
- 社区版 免费,MySQL 不提供任何技术支持
- 商业版 收费,可以试用 30 天,官方提供技术支持
启动与停止
- 启动
net start mysql
- 停止
net stop mysql
客户端连接
方法一:MySQL 提供的客户端命令行工具
方法二:系统自带的命令行工具执行命令 mysql [-h 127.0.0.1] [-P 3306] -u root -p
(需要配置环境变量)
-h 指定连接地址
-P 指定连接端口
-u 指定连接用户名
-p 指定密码
关系型数据库(RDBMS)
概念:建立在关系模型基础上,由多张相互连接的二维表组成的数据库

特点:
- 使用表存储数据,格式统一,便于维护
- 使用 SQL 语言操作,标准统一,使用方便
数据模型

SQL
SQL 通用语法
- SQL 语句可以单行或多行书写,以分号结尾
- SQL 语句可以使用空格/缩进来增强语句的可读性
- MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用大写
- 注释:
- 单行注释: -- 注释内容 或 # 注释内容(MySQL特有)
- 多行注释: /* 注释内容 */
SQL 分类
- DDL 全称 Data Definition Language 数据定义语言,用来定义数据库对象(数据库,表,字段)
- DML 全称 Data Manipulation Language 数据操作语言,用来对数据库表中的数据进行增删改
- DQL 全称 Data Query Language 数据查询语言,用来查询数据库中表的记录
- DCL 全称 Data Control Language 数据控制语言,用来创建数据库用户、控制数据库的访问权限
DDL
数据库操作
查询
查询所有数据库
查询当前数据库
创建
| CREATE DATABASE [IF NOT EXISTS] 数据库名 [DEFAULT CHARSET 字符集] [COLLATE 排序规则]; |
删除
| DROP DATABASE [IF EXISTS] 数据库名; |
使用
DDL-表操作-查询
查询当前数据库所有表
查询表结构
查询指定表的建表语句
DDL-表操作-创建
| CREATE TABLE 表名 ( |
| 字段1 字段1类型 [COMMENT 字段1注释], |
| 字段2 字段2类型 [COMMENT 字段2注释], |
| 字段3 字段3类型 [COMMENT 字段3注释], |
| ...... |
| 字段n 字段n类型 [COMMENT 字段n注释] |
| )[COMMENT 表注释]; |
注意:[...]为可选参数,最后一个字段后面没有逗号
DDL-表操作-数据类型

例:123.45 精度 5, 标度 2
| age TINYINT UNSIGNED |
| score double(4, 1) |

| char(10) 占用十个字符的空间,未占用的字符,用空格补位 / 性能好 |
| varchar(10) 存几位,占用几位字符的空间 / 性能较差 |
| 例: |
| 用户名 username : 使用 varchar(50) 更好一些 |
| 姓别 gender : 使用 char(1) 更好一些 |

创建员工表
| create table emp ( |
| id int comment '编号', |
| workno varchar(10) comment '工号', |
| name varchar(10) comment '姓名', |
| gender char(1) comment '性别', |
| age tinyint unsigned comment '年龄', |
| idcard char(18) comment '身份证号', |
| entrydate date comment '入职时间' |
| ) comment '员工表'; |
DDL-表操作-修改
添加字段
| ALTER TABLE 表名 ADD 字段名 类型(长度) [comment 注释] [约束]; |
案例
为 emp 表增加一个新的字段“昵称”为 nickname,类型为 varchar(20)
| alter table emp add nickname varchar(20) comment '昵称'; |
修改数据类型
| ALTER TABLE 表名 MODIFY 字段名 新数据类型(长度); |
修改字段名和字段类型
| ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型(长度) [comment 注释] [约束]; |
案例
将 emp 表的 nickname 字段修改为 username,类型为 varchar(30)
| alter table emp change nickname username varchar(30) comment '用户名'; |
删除字段
案例
| alter table emp drop username; |
修改表名
| ALTER TABLE 表名 RENAME TO 新表名; |
案例
将 emp 表的表名修改为 employee
| alter table emp rename to employee; |
删除表
| DROP TABLE [IF EXISTS] 表名; |
删除指定表,并重新创建该表
注意:在删除表时,表中的全部数据也会被删除
DML
添加数据(INSERT)
给指定字段添加数据
| INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...); |
给全部字段添加数据
| INSERT INTO 表名 VALUES (值1, 值2, ...); |
批量添加数据
| INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, 值2, ...); |
| INSERT INTO 表名 VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, 值2, ...); |
注意
- 插入数据时,指定的字段顺序需要与值的顺序是一一对应的
- 字符串和日期型数据应该包含在引号中
- 插入的数据大小,应该在字段的规定范围内
修改数据(UPDATE)
- 若MySql运行在safe-updates模式下,该模式会导致非主键条件下无法执行update或者delete命令,使用如下语句关闭
| show variables like 'SQL_SAFE_UPDATES'; |
| set sql_safe_updates=off; |
| UPDATE 表名 SET 字段名1=值1, 字段名2=值2, ... [WHERE 条件]; |
注意:修改语句的条件可以有,也可以没有,如果没有条件,则会修改整张表的所有数据
案例
| |
| update employee set name = 'itheima' where id = 1; |
| |
| update employee set name = '小昭', gender = '女' where id = 1; |
| |
| update employee set entrydate = '2008-01-01'; |
删除数据(DELETE)
| DELETE FROM 表名 [WHERE 条件]; |
注意
- DELETE 语句的条件可以有,也可以没有,如果没有条件,则会删除整张表的所有数据
- DELETE 语句不能删除某一个字段的值(可以使用 UPDATE)
案例
| |
| delete from employee where gender = '女'; |
| |
| delete from employee; |
DQL
DQL-语法
| SELECT |
| 字段列表 |
| FROM |
| 表名列表 |
| WHERE |
| 条件列表 |
| GROUP BY |
| 分组字段列表 |
| HAVING |
| 分组后条件列表 |
| ORDER BY |
| 排序字段列表 |
| LIMIT |
| 分页参数 |
- 基本查询
- 条件查询(WHERE)
- 聚合函数(count、max、min、avg、sum)
- 分组查询(GROUP BY)
- 排序查询(ORDER BY)
- 分页查询(LIMIT)
基本查询
查询多个字段
| SELECT 字段1, 字段2, 字段3 ... FROM 表名; |
设置别名
| SELECT 字段1 [AS 别名1], 字段2 [AS 别名2] ... FROM 表名; |
去除重复记录
| SELECT DISTINCT 字段列表 FROM 表名; |
数据
| create table emp ( |
| id int comment '编号', |
| workno varchar(10) comment '工号', |
| name varchar(10) comment '姓名', |
| gender char(1) comment '性别', |
| age tinyint unsigned comment '年龄', |
| idcard char(18) comment '身份证号', |
| workaddress varchar(50) comment '工作地址', |
| entrydate date comment '入职时间' |
| ) comment '员工表'; |
| |
| insert into emp (id,workno,name,gender,age,idcard ,workaddress,entrydate) values |
| (1,'1','柳岩','女',20,'123456789012345678','北京','2000-01-01'), |
| (2,'2','张无忌','男',18,'123456789012345670','北京','2005-09-01'), |
| (3,'3','韦一笑','男',38,'123456789712345670','上海','2005-08-01'), |
| (4,'4','赵敏','女',18,'123456757123845670','北京','2009-12-01'), |
| (5,'5','小昭','女',16,'123456769012345678','上海','2007-07-01') , |
| (6,'6','杨逍','男',28,'12345678931234567X','北京','2006-01-01'), |
| (7,'7','范瑶','男',40,'123456789212345670','北京','2005-05-01'), |
| (8,'8','黛绮丝','女',38,'123456157123645670','天津','2015-05-01'), |
| (9,'9','范凉凉','女',45,'123156789012345678','北京','2010-04-01'), |
| (10,'10','陈友谅','男',53,'123456789012345670','上海','2011-01-01'), |
| (11,'11','张士诚','男',55,'123567897123465670','江苏','2015-05-01'), |
| (12,'12','常遇春','男',32,'123446757152345670','北京','2004-02-01'), |
| (13,'13','张三丰','男',88,'123656789012345678','江苏','2020-11-01'), |
| (14,'14','灭绝','女',65,'123456719012345670','西安','2019-05-01'), |
| (15,'15','胡青牛','男',70,'12345674971234567X','西安','2018-04-01'), |
| (16,'16','周芷若','女',18,null,'北京','2012-06-01'); |
| |
| |
| select name, workno, age from emp; |
| |
| select id, workno, name, gender, age, idcard, workaddress, entrydate from emp; |
| select * from emp; |
| |
| select workaddress as '工作地址' from emp; |
| select workaddress '工作地址' from emp; |
| |
| select distinct workaddress as '上班地址' from emp; |
条件查询
语法
| SELECT 字段列表 FROM 表名 WHERE 条件列表; |
条件
| 比较运算符 功能 |
| > 大于 |
| >= 大于等于 |
| < 小于 |
| <= 小于等于 |
| = 等于 |
| <> 或 != 不等于 |
| BETWEEN ... AND ... 在某个范围之内(含最小、最大值) |
| IN(...) 在 in 之后的列表中的值,多选一 |
| LIKE 占位符 模糊匹配(_匹配单个字符,%匹配任意个字符) |
| IS NULL 是 NULL |
| AND 或 && 并且(多个条件同时成立) |
| OR 或 || 或者(多个条件任意一个成立) |
| NOT 或 ! (非,不是) |
案例
| |
| select * from emp where age = 88; |
| |
| |
| select * from emp where age < 20; |
| |
| |
| select * from emp where age <= 20; |
| |
| |
| select * from emp where idcard is NULL; |
| |
| |
| select * from emp where idcard is not null; |
| |
| |
| select * from emp where age != 88; |
| select * from emp where age <> 88; |
| |
| |
| select * from emp where age >= 15 && age <= 20; |
| select * from emp where age >= 15 and age <= 20; |
| select * from emp where age between 15 and 20; |
| |
| |
| select * from emp where gender = '女' && age < 25; |
| select * from emp where gender = '女' and age < 25; |
| |
| |
| select * from emp where age = 18 || age = 20 || age = 40; |
| select * from emp where age = 18 or age = 20 or age = 40; |
| select * from emp where age in(18, 20, 40); |
| |
| |
| select * from emp where name like '__'; |
| |
| |
| select * from emp where idcard like '%X'; |
| select * from emp where idcard like '_________________X'; |
聚合函数
介绍
常见聚合函数
| 函数 功能 |
| count 统计数量 |
| max 最大值 |
| min 最小值 |
| avg 平均值 |
| sum 求和 |
语法
| SELECT 聚合函数(字段列表) FROM 表名; |
注意:NULL 值不参与所有聚合函数运算。
案例
| |
| select count(*) from emp; |
| select count(id) from emp; |
| select count(idcard) from emp; |
| |
| |
| select avg(age) from emp; |
| |
| |
| select max(age) from emp; |
| |
| |
| select min(age) from emp; |
| |
| |
| select sum(age) from emp where workaddress = '西安'; |
分组查询
语法
| SELECT 字段列表 FROM 表名 [WHERE 条件] GROUP BY 分组字段名 [HAVING 分组后过滤条件]; |
where 与 having 区别
- 执行时机不同:where 是分组之前进行过滤,不满足 where 条件,不参与分组;而 having 是分组之后对结果进行过滤
- 判断条件不同:where 不能对聚合函数进行判断,而 having 可以
注意
- 执行顺序 :where > 聚合函数 > having
- 分组之后,查询的字段一般为聚合函数和分组字段,查询其他字段无任何意义
案例
| |
| select gender, count(*) from emp group by gender; |
| |
| |
| select gender, avg(age) from emp group by gender; |
| |
| |
| select workaddress, count(*) as address_count from emp where age < 45 |
| group by workaddress having address_count >= 3; |
排序查询
语法
| SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式, 字段2 排序方式2; |
排序方式
| |
| select * from emp order by age asc; |
| select * from emp order by age; |
| |
| |
| select * from emp order by entrydate desc; |
| |
| |
| select * from emp order by age asc, entrydate desc; |
分页查询
语法
| SELECT 字段列表 FROM 表名 LIMIT 起始索引, 查询记录数; |
注意:
- 起始索引从 0 开始,起始索引 = (查询页码 - 1)* 每页显式记录数
- 分页查询是数据库的方言,不同的数据库有不同的实现,MySQL 中是 LIMIT
- 如果查询的是第一页数据,起始索引可以省略,直接简写为 limit 10
案例
| |
| select * from emp limit 0, 10; |
| select * from emp limit 10; |
| |
| |
| select * from emp limit 10, 10; |
练习
| |
| select * from emp where gender = '女' and age in(20, 21, 22, 23); |
| |
| |
| select * from emp where gender = '男' and age between 20 and 40 and name like '___'; |
| |
| |
| select gender, count(*) from emp where age < 60 group by gender; |
| |
| |
| select name, age from emp where age <= 35 order by age asc, entrydate desc; |
| |
| |
| select * from emp where age between 20 and 40 and gender = '男' order by age asc, entrydate asc limit 0, 5; |
执行顺序

DCL
管理用户
查询用户
| USE mysql |
| SELECT * FROM user; |
创建用户
| CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码'; |
修改用户密码
| ALTER USER '用户名'@'主机名' IDENTIFIED WITH mysql_native_password BY '新密码'; |
删除用户
注意
- 主机名可以使用 % 通配
- 这类 SQL 开发人员操作的比较少,主要是 DBA(Database Administrator 数据库管理员)使用
案例
| |
| create user 'itcast'@'localhost' identified by '123456'; |
| |
| |
| create user 'heima'@'%' identified by '123456'; |
| |
| |
| alter user 'heima'@'%' identified with mysql_native_password by '1234'; |
| |
| |
| drop user 'itcast'@'localhost'; |
权限控制
MySQL 中定义了很多种权限,但是常用的就以下几种:
| 权限 说明 |
| ALL, ALL PRIVILEGES 所有权限 |
| SELECT 查询数据 |
| INSERT 插入数据 |
| UPDATE 修改数据 |
| DELETE 删除数据 |
| ALTER 修改表 |
| DROP 删除数据库/表/视图 |
| CREATE 创建数据库/表 |
权限控制
查询权限
| SHOW GRANTS FOR '用户名'@'主机名'; |
授予权限
| GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名'; |
撤销权限
| REVOKE 权限列表 ON 数据库名.表名 FROM '用户名'@'主机名'; |
注意:
- 多个权限之间,使用逗号分隔
- 授权时,数据库名和表名可以使用 * 进行通配,代表所有
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!