第426集数据库基本操作
数据库基本操作
1. 数据库连接方式
1.1 本地连接
使用mysql -u root -p可以连接数据库,但这只是本地连接数据库的方式。
1 | # 本地连接数据库 |
1.2 远程连接
在生产很多情况下都是连接网络中某一个主机上的数据库。
连接参数:
-P: 指定连接远程数据库端口-h: 指定连接远程数据库地址-u: 指定连接远程数据库账户-p: 指定连接远程数据库密码
1 | # 远程连接数据库 |
1.3 连接选项
常用连接选项:
| 选项 | 说明 | 示例 |
|---|---|---|
-h |
指定主机地址 | -h192.168.56.11 |
-P |
指定端口号 | -P3306 |
-u |
指定用户名 | -uroot |
-p |
指定密码 | -p 或 -p'password' |
-S |
指定Socket文件 | -S /tmp/mysql.sock |
-e |
执行SQL语句后退出 | -e "SHOW DATABASES;" |
-D |
指定默认数据库 | -D testdb |
连接示例:
1 | # 连接并执行SQL |
1.4 配置文件连接
创建客户端配置文件:
1 | # 创建客户端配置文件 |
1 | [client] |
1 | # 使用配置文件连接 |
2. 数据库基本操作
2.1 查看数据库版本
1 | -- 查看MySQL版本 |
2.2 创建数据库(DDL)
语法: CREATE DATABASE [IF NOT EXISTS] database_name [CHARACTER SET charset_name] [COLLATE collation_name];
1 | -- 创建数据库 |
数据库命名规范:
- 数据库名称严格区分大小写(Linux系统)
- 数据库名称必须是唯一
- 数据库名称不允许使用数字开头
- 数据库名称不能使用关键字命名(如:create、select等)
- 建议使用小写字母、数字、下划线
- 建议使用有意义的名称
注意: 执行命令不区分大小写,但数据库名称区分大小写。
2.3 查看数据库
1 | -- 查看所有数据库 |
系统数据库说明:
| 数据库 | 说明 |
|---|---|
| information_schema | 虚拟库,存储用户表信息、列信息、权限信息、字符信息等 |
| performance_schema | 主要存储数据库服务器的性能参数 |
| mysql | 授权库,主要存储系统用户的权限信息 |
| sys | 优化库,主要存储数据库服务器的性能参数 |
| bgx | 业务库,主要存放业务所需要的库和表 |
2.4 删除数据库
1 | -- 删除数据库 |
删除库下的表:
1 | -- 删除指定库下的表 |
警告: 删除数据库会永久删除所有数据,请谨慎操作!
2.5 选择数据库
1 | -- 使用USE进入对应库 |
2.6 查看表
1 | -- 列出当前库下面的表 |
2.7 查看表结构
1 | -- 查询某个库下的表结构 |
查看建表语句:
1 | -- 查看某张表的建表语句 |
3. 数据库增删查改(CRUD)
在MySQL管理软件中,可以通过SQL语句中的DML语言来实现数据的操作,包括:
- INSERT: 数据插入
- UPDATE: 数据更新
- DELETE: 数据删除
- SELECT: 数据查询(将在第4节详细讲解)
3.1 准备操作环境数据表
1 | -- 创建数据库 |
3.2 插入数据INSERT语句
方式1: 插入完整数据(顺序插入)
语法: INSERT INTO 表名(字段1,字段2,字段n) VALUES (值1,值2,值n);
1 | -- 指定字段插入 |
方式2: 插入完整数据(推荐方式)
语法: INSERT INTO 表名 VALUES (值1,值2,值n);
1 | -- 按字段顺序插入(推荐方式) |
方式3: 指定字段插入
语法: INSERT INTO 表名(字段2,字段3…) VALUES (值2,值3…);
1 | -- 只插入部分字段 |
方式4: 插入多条记录
语法: INSERT INTO 表名 VALUES (值1,值2,值n),(值1,值2,值n);
1 | -- 批量插入多条记录 |
查看插入结果
1 | -- 查看所有数据 |
INSERT最佳实践:
- 使用批量插入提高性能
- 明确指定字段名,避免字段顺序错误
- 使用事务保证数据一致性
- 检查数据类型和约束
3.3 更新数据UPDATE语句
语法: UPDATE 表名 SET 字段1=值1, 字段2=值2 WHERE 条件;
更新步骤:
- 查看需要修改的表的字段
DESC - 查询对应的字段
SELECT - 更新对应的表字段
UPDATE - 添加对应的WHERE条件,精准修改
示例1: 更新单个字段
1 | -- 将t1表中,name字段等于bgx的改为update_bgx |
示例2: 更新多个字段
1 | -- 同时更新多个字段 |
示例3: 修改密码示例
1 | -- 查看表字段内容 |
UPDATE注意事项:
- 必须使用WHERE条件,否则会更新所有记录
- 更新前先使用SELECT验证条件
- 使用事务保证数据一致性
- 注意PASSWORD()函数在MySQL 5.7.6+中已废弃
3.4 删除数据DELETE
语法: DELETE FROM 表名 WHERE 条件;
删除指定记录
1 | -- 删除字段包含update_bgx的记录 |
清空表数据
1 | -- 使用TRUNCATE清空表数据(速度快,不可回滚) |
DELETE vs TRUNCATE:
| 操作 | DELETE | TRUNCATE |
|---|---|---|
| 速度 | 慢 | 快 |
| 可回滚 | 是 | 否 |
| 可带WHERE | 是 | 否 |
| 重置AUTO_INCREMENT | 否 | 是 |
| 触发触发器 | 是 | 否 |
DELETE注意事项:
- 必须使用WHERE条件,否则会删除所有记录
- DELETE是逐行删除,大数据量时较慢
- TRUNCATE是DDL操作,速度快但不可回滚
- 删除前先备份重要数据
4. 数据库查询语句
4.1 单表查询
在学习查询前,需要定义好对应数据进行查询。
表结构定义:
- 编号
idINT - 姓名
nameVARCHAR(30) - 性别
sexENUM - 日期
timeDATE - 职位
postVARCHAR(50) - 描述
jobVARCHAR(100) - 薪水
salaryDOUBLE(15,2) - 部门编号
dep_idINT
创建表
1 | -- 创建表 |
插入数据
1 | -- 插入测试数据 |
1. 简单查询
查看表字段与表信息
1 | -- 查看表结构 |
查询所有数据
1 | -- 查询所有数据 |
指定字段查询
1 | -- 查询指定字段 |
避免重复查询字段(DISTINCT)
1 | -- 查询所有职位(有重复) |
通过四则运算查询
1 | -- 计算每个人的年薪 |
定义显示格式(CONCAT函数)
1 | -- CONCAT()函数用于连接字符串 |
2. 单条件查询
单条件查询
1 | -- 查询职位为hr的员工 |
多条件查询
1 | -- 查询职位为hr且薪水大于5000的员工 |
关键字BETWEEN AND(区间查询)
1 | -- 查找薪资范围在8000-20000之间 |
关键字IS NULL(空值查询)
1 | -- 查找部门为NULL,没有部门的员工 |
NULL vs 空字符串:
NULL: 表示没有值'': 表示空字符串- 使用
IS NULL检查NULL值 - 使用
=''检查空字符串
关键字IN(集合查询)
1 | -- 使用OR方式 |
关键字LIKE(模糊查询)
1 | -- 通配符%:匹配任意多个字符 |
LIKE通配符:
%: 匹配任意多个字符(0个或多个)_: 匹配单个字符\%: 转义%,匹配%字符\_: 转义_,匹配_字符
性能提示: LIKE ‘%pattern%’ 无法使用索引,性能较差。
3. 查询排序
单列排序
1 | -- 按薪水从低到高排序(默认ASC) |
多列排序
1 | -- 先按入职时间,再按薪水排序 |
4. 限制查询的记录数
1 | -- 查询薪资最高前5名同事(默认初始位置为0) |
LIMIT语法:
LIMIT n: 返回前n条记录LIMIT offset, count: 从offset开始返回count条记录LIMIT count OFFSET offset: 标准SQL语法
分页查询:
1 | -- 每页10条,第1页 |
5. 使用集合函数查询
COUNT(计数)
1 | -- 统计当前表总共多少条数据 |
MAX/MIN(最大值/最小值)
1 | -- 薪水最高 |
AVG(平均值)
1 | -- 平均薪水 |
SUM(求和)
1 | -- 总共发放多少薪水 |
子查询应用
1 | -- 哪个部门哪个人薪水最高 |
6. 分组查询
GROUP BY和GROUP_CONCAT()
1 | -- GROUP BY 和 GROUP_CONCAT()函数一起使用 |
GROUP BY和集合函数
1 | -- GROUP BY 和集合函数一起使用 |
HAVING子句
1 | -- 筛选分组后的结果 |
WHERE vs HAVING:
WHERE: 在分组前过滤,不能使用聚合函数HAVING: 在分组后过滤,可以使用聚合函数
7. 使用正则表达式查询
1 | -- 使用正则表达式查询(以ali开头) |
正则表达式元字符:
^: 匹配字符串开始$: 匹配字符串结束.: 匹配任意字符*: 匹配0个或多个+: 匹配1个或多个?: 匹配0个或1个[]: 字符集|: 或
字符串匹配方式对比:
WHERE name = 'trf': 精确匹配WHERE name LIKE 'ha%': 模式匹配WHERE name REGEXP 'gx$': 正则匹配
4.2 多表查询
准备数据表
1 | -- 准备表1 |
1. 交叉连接(不使用任何匹配条件)
交叉连接会产生笛卡尔积,结果集为两个表行数的乘积。
1 | -- 交叉连接(笛卡尔积) |
结果: 6行 × 4行 = 24行
2. 内连接(只连接匹配的行)
内连接只返回两个表中匹配的行。
1 | -- 只找出有部门的员工(部门表中没有natasha所在的部门) |
3. 外连接
左连接(LEFT JOIN)
左连接返回左表的所有记录,右表没有匹配的显示NULL。
1 | -- 左连接 |
右连接(RIGHT JOIN)
右连接返回右表的所有记录,左表没有匹配的显示NULL。
1 | -- 右连接 |
全连接(FULL OUTER JOIN)
MySQL不支持FULL OUTER JOIN,使用UNION实现。
1 | -- 使用UNION实现全连接 |
4. 符合条件连接查询
1 | -- 以内连接的方式查询t3和t4表,找出公司所有部门中年龄大于25岁的员工 |
4.3 子查询
子查询是将一个查询语句嵌套在另一个查询语句中。内层查询语句的查询结果,可以为外层查询语句提供查询条件。
子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS和NOT EXISTS等关键字,还可以包含比较运算符:=、!=、>、<等。
带IN关键字的子查询
1 | -- 查询t3表,但dept_id必须在t4表中出现过 |
带比较运算符的子查询
1 | -- 查询年龄大于等于25岁员工所在部门(查询老龄化的部门) |
带EXISTS关键字的子查询
EXISTS关键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录,而是返回一个真假值。True或False,当返回True时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询。
1 | -- t4表中存在dep_id=203,返回True,所以查询t3表所有记录 |
子查询类型
标量子查询:
1 | -- 返回单个值 |
行子查询:
1 | -- 返回一行 |
列子查询:
1 | -- 返回一列 |
表子查询:
1 | -- 返回多行多列 |
5. SQL优化最佳实践
5.1 查询优化
**避免SELECT ***:
1 | -- 不推荐 |
使用索引列:
1 | -- 确保WHERE子句中的列有索引 |
避免在WHERE子句中使用函数:
1 | -- 不推荐 |
5.2 索引优化
1 | -- 为经常查询的列创建索引 |
5.3 分页优化
1 | -- 大数据量分页优化 |
6. 常见问题排查
6.1 查询性能问题
1 | -- 使用EXPLAIN分析查询计划 |
6.2 数据类型问题
1 | -- 检查数据类型 |
实战优化


