1 数据库基础
1.1 数据库介绍
- 数据库:存储数据的仓库
- 定义:按照某种数据模型,将数据存储到存储器的集合
- 生活中常见数据类型:视频、音频、图片、文本
1.2 常见的数据库软件
配套操作系统:Linux、Windows、Unix
数据库分类与厂商、开源属性:

1.3 数据库类型
- 关系型数据库(RDBMS)
- 存储形式:表格存储数据
- 操作语言:SQL结构化查询语言
- 非关系型数据库(NoSQL,还可以做缓存)
- 存储结构:键值对、文档等
- 适用场景:大数据、高并发业务
- 图形数据库(Graph Database)
- 存储图形关联数据
- 典型场景:社交网络、知识图谱
- 内存数据库
- 数据常驻内存
- 优势:读写速度快、低延迟
- 适用:高读写性能要求业务
- 分布式数据库
- 数据拆分存储在多台节点服务器
- 能力:支持业务水平扩展
补充说明:不同数据库适配不同业务场景,系统设计阶段需结合需求选型。简单讲,数据库没有好与坏之分,只有适合与否
1.4 MySQL介绍
- 定位:全球应用最广泛的开源关系型数据库
- 发展历程
- 最初归属瑞典MySQL AB公司
- 2008.01:MySQL AB被Sun公司收购
- 2009.04:Sun公司被Oracle甲骨文收购
- MariaDB分支
- 诞生原因:规避MySQL闭源风险
- 开发主导:MySQL原作者Widenius
- 特性:与MySQL高度兼容
- MySQL各版本迭代功能
- MySQL 1.x:1995年初代版本,仅基础极简数据库能力
- MySQL 3.x:3.23版本新增InnoDB引擎,完善CRUD、索引基础功能
- MySQL 4.0/4.1:优化字符集、子查询、UNION,不支持存储过程、视图、游标
- MySQL 5.x
- 5.0:新增存储过程、视图、游标、事件调度器
- 5.5:将InnoDB设置为默认存储引擎
- 5.7:原生支持JSON数据类型
- MySQL 8.0:2018发布,主流长期支持版本;新增窗口函数、CTE递归表达式,强化JSON操作、原子DDL、安全认证机制

1.5 MySQL特点及应用
核心特点
- 适配中小规模关系型业务系统
- 跨平台:支持Linux、Unix、Windows
- 多语言兼容:Python、Java、Perl、PHP等主流开发语言
典型部署平台组合
- LAMP平台,与Apache HTTP Server组合:Linux + Apache + MySQL + PHP
- LNMP,与Nginx组合:Linux + Nginx + MySQL + PHP
- LNMJ,与Tomcat/Java应用组合:Linux + Nginx + MySQL + Tomcat/Java
1.6 MySQL数据库结构
MySQL核心软件包
- mysql-server:
- 数据库后台服务 :
mysqld - 默认端口:
3306
(mysql本地连接时使用的是socket文件,跨主机连接数据库读取的是3306端口)
- 数据库后台服务 :
- mysql:客户端连接工具、配套管理命令

2 部署MySQL数据库服务
2.1 实验环境
操作流程:模板机克隆虚拟机,WindTerm远程连接服务器操作

2.2 MySQL完整部署命令
shell
# 安装mysql服务端+客户端软件包
[root@mysql ~]# dnf -y install mysql-server mysql
# 启动mysqld数据库服务
[root@mysql ~]# systemctl start mysqld
# 设置mysqld开机自启
[root@mysql ~]# systemctl enable mysqld
# 查看3306端口监听状态,验证服务正常运行
[root@mysql ~]# ss -nutlp | grep :3306
2.3 MySQL核心目录与配置参数

2.4 MySQL客户端连接方式
- 命令行连接(基础):
mysql -h数据库服务器IP -u数据库用户名 -p'密码'
- 图形化工具:软件自带客户端图形页面、Web管理页面
- 代码脚本连接:PHP、Java、Python等程序代码连接数据库
2.5 SQL命令通用语法规范
- SQL关键字(库、表名除外)不区分大小写
- 每条SQL语句必须以英文分号
;或\g结尾 - MySQL客户端不支持SQL语句自动补齐
2.6 SQL四大语言分类(了解)
- DDL 数据定义语言 :负责库、表结构创建修改删除
关键字:CREATE、ALTER、DROP - DML 数据操作语言 :操作表内数据
关键字:INSERT、UPDATE、DELETE - DCL 数据控制语言 :用户权限管理
关键字:GRANT、REVOKE - DTL 数据事务语言 :事务回滚、提交
关键字:COMMIT、ROLLBACK、SAVEPOINT
数据库基础操作SQL
sql
-- 查看服务器所有数据库
SHOW DATABASES;
-- 查看当前登录用户,user()是函数
SELECT user();
-- 切换至指定数据库
USE 库名;
-- 查看当前正在使用的数据库
SELECT database();
-- 创建新数据库
CREATE DATABASE 库名;
-- 查看当前库下所有数据表
SHOW TABLES;
-- 删除指定数据库
DROP DATABASE 库名;
补充概念:数据库等同于文件夹,用于存放多张数据表,一台MySQL可创建多个独立库,通过库名区分。
2.7 数据库命名规则
- 可用字符:数字、字母、下划线,不能纯数字命名
- 区分大小写,同一服务器库名唯一
- 禁止使用SQL关键字 、特殊符号命名
2.8 root管理员密码管理
设置/修改root密码命令
- 修改密码通用语法:
mysqladmin -uroot [-p'旧密码'] password '新密码' - 将数据库管理员root的密码设置为:1234.com
shell
# 无旧密码时设置root密码,无需指定-p
[root@mysql ~]# mysqladmin -uroot password '1234.com'
# 使用新密码登录数据库
[root@mysql ~]# mysql -uroot -p'1234.com'
注意:-u,-p后面不要有空格,直接接上参数,password后面有空格
2.9 破解root密码完整流程
有时候密码没记住,登录不进去了,可以进行破解
(注意!实际生产环境不建议这么做,且千万不要为了查看别人的数据而破解密码)
步骤1:修改配置文件跳过密码验证
shell
# 编辑mysql服务配置文件
[root@mysql ~]# vim /etc/my.cnf.d/mysql-server.cnf
# 在[mysqld]段落添加配置
skip-grant-tables
# 重启数据库服务生效
[root@mysql ~]# systemctl restart mysqld
这一步做完就可以免密进入数据库,但权限受限。
因此我们需要更进一步,修改密码,让我们能正常登录正常使用
步骤2:免密登录修改授权表
shell
# 直接免密进入mysql
[root@mysql ~]# mysql
# 修改授权表记录,清空root原有密码字段
mysql> UPDATE mysql.user set authentication_string="" WHERE user="root";
# 刷新权限表,使修改生效
mysql> FLUSH PRIVILEGES;
# 退出数据库
mysql> EXIT;
这样一来,就恢复了刚安装时无密码的阶段,下一步正常添加密码即可
步骤3:移除免密配置,重置正式密码
shell
# 重新编辑配置文件,注释掉跳过验证参数
[root@mysql ~]# vim /etc/my.cnf.d/mysql-server.cnf
[mysqld]
#skip-grant-tables
# 重启服务
[root@mysql ~]# systemctl restart mysqld
# 再次免密登录,修改授权添加正式密码
[root@mysql ~]# mysql
mysql> ALTER USER root@localhost IDENTIFIED BY '1234.com';
# 使用新密码正常登录验证
[root@mysql ~]# mysql -uroot -p'1234.com'
3 基础查询
3.1 导入测试数据
- 准备工作:将
company.sql文件上传至MySQL服务器/root目录 - 命令行导入SQL测试数据
shell
[root@mysql ~]# mysql -uroot -p'1234.com' < /root/company.sql
3.2 三张测试数据表结构详解
使用DESC可以查看表的结构(表头)
1. departments 部门表
sql
mysql> DESC tarena.departments;
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| dept_id | int(4) | NO | PRI | NULL | auto_increment |
| dept_name | varchar(10) | YES | | NULL | |
+-----------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
- dept_id:部门编号,主键、自增
- dept_name:部门名称
2. employees 员工表
sql
mysql> DESC tarena.employees;
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| employee_id | int(6) | NO | PRI | NULL | auto_increment |
| name | varchar(10) | YES | | NULL | |
| hire_date | date | YES | | NULL | |
| birth_date | date | YES | | NULL | |
| email | varchar(25) | YES | | NULL | |
| phone_number | char(11) | YES | | NULL | |
| dept_id | int(4) | YES | MUL | NULL | |
+--------------+-------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)
- employee_id:员工编号,主键自增
- name:员工姓名
- hire_date:入职日期
- birth_date:生日
- email:邮箱
- phone_number:手机号
- dept_id:所属部门编号,外键关联部门表
3. salary 工资表
sql
mysql> DESC salary;
+-------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| date | date | YES | | NULL | |
| employee_id | int(6) | YES | MUL | NULL | |
| basic | int(6) | YES | | NULL | |
| bonus | int(6) | YES | | NULL | |
+-------------+---------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
- id:薪资记录主键
- date:薪资月份日期
- employee_id:员工编号,关联员工表
- basic:基本工资
- bonus:绩效奖金
查看表内全部数据
sql
-- 查询部门表全部数据
mysql> SELECT * FROM tarena.departments;
-- 查询员工表全部数据
mysql> SELECT * FROM tarena.employees;
-- 查询工资表全部数据
mysql> SELECT * FROM tarena.salary;
3.3 表格业务数据说明
- departments部门表:共8个部门数据

- employees员工表:共133位员工,归属不同部门

- salary工资表:存储员工每月基本工资、奖金数据

主键和外键
- 主键(Primary Key)
- 一张表里唯一标识每一行数据的字段
- 特点:不能重复、不能为空,一张表只能有1个主键。
- 作用:区分每条记录,快速定位数据
- 外键(Foreign Key)
- 一张表里,引用另一张表主键的字段
- 特点:值必须来自另一张表的主键,可以重复、可以为空。
- 作用:把两张表关联起来,保证数据对应关系不乱。
简单讲:
- 主键:本表独一无二的身份证;
- 外键:用来连接另一张表身份证的纽带。
以上述三张表举例:
departments 部门表的主键就是dept_id,同时dept_id是员工表的外键
employee_id是员工表的主键,employee_id是工资表的外键。

3.4 SELECT 查询基础语法
语法1:无条件查询(查看对应字段信息)
sql
SELECT 字段列表 FROM 库名.表名;
语法2:带条件筛选查询
sql
SELECT 字段列表 FROM 库名.表名 WHERE 筛选条件;
基础查询示例
sql
-- 仅查询name字段
mysql> SELECT name FROM tarena.user;
-- 查询name、uid两个字段
mysql> SELECT name,uid FROM tarena.user;
-- 查询表内所有字段
mysql> SELECT * FROM tarena.user;
-- 精准匹配name等于root的数据
mysql> SELECT * FROM tarena.user WHERE name="root";
-- 匹配uid等于2的数据
mysql> SELECT * FROM tarena.user WHERE uid=2;
4 筛选条件全类型
4.1 数值比较
适用场景:字段为数字类型,使用数值比较符号

sql
-- 查询uid大于5的所有数据
mysql> SELECT * FROM tarena.user WHERE uid>5;
-- 查询gid小于2的所有数据
mysql> SELECT * FROM tarena.user WHERE gid<2;
4.2 字符比较
适用场景:字段为字符串/字符类型,支持空值判断

在数据库里,空格不代表空,null才代表空
sql
-- 匹配name等于root的数据
mysql> SELECT * FROM tarena.user WHERE name="root";
-- shell字段不等于/bin/bash
mysql> SELECT * FROM tarena.user WHERE shell != "/bin/bash";
-- 查询shell为空的数据
mysql> SELECT * FROM tarena.user WHERE shell is null;
-- 查询shell不为空的数据
mysql> SELECT * FROM tarena.user WHERE shell is not null;
注意字符串要加双引号
4.3 范围匹配

注意between只能用来表述两个数字之间的范围
sql
-- uid匹配1/3/5/7/9任意一个
mysql> SELECT name,uid FROM tarena.user WHERE uid in (1,3,5,7,9);
-- name排除root、bin两个值
mysql> SELECT name,uid FROM tarena.user WHERE name not in ("root","bin");
-- uid范围10~30之间
mysql> SELECT name,uid FROM tarena.user WHERE uid between 10 and 30;
4.4 模糊匹配 LIKE
语法:SELECT 字段 FROM 表 WHERE 字段 LIKE '通配符';
通配符规则:
_:匹配任意一个字符%:匹配0个或多个任意字符
sql
-- 查询name以a开头的数据
mysql> SELECT name FROM tarena.user WHERE name like 'a%';
-- 查询name恰好3个字符的数据(3个下划线)
mysql> SELECT name FROM tarena.user WHERE name like '___';
4.5 正则匹配 REGEXP
语法:WHERE 字段 REGEXP '正则表达式'
常用正则元字符:
^内容:以指定内容开头内容$:以指定内容结尾[abc]:匹配括号内任意单个字符*:前一个字符重复任意次数|:或逻辑.:任意单个字符
sql
-- 匹配以a开头 或者 以t结尾的name
mysql> SELECT name FROM tarena.user WHERE name REGEXP '^a|t$';
-- 匹配以a/r/t任意字符开头的name
mysql> SELECT name FROM tarena.user WHERE name REGEXP '^[art]';
-- 匹配以a开头以t结尾中间是任意单个字符的的name
mysql> SELECT name FROM tarena.user WHERE name REGEXP '^a.t$';
4.6 逻辑匹配 AND / OR / NOT
优先级:多条件判断时,AND 高于 OR

sql
-- uid小于3 或者 uid大于1000
mysql> SELECT name,uid FROM tarena.user WHERE uid < 3 OR uid > 1000;
-- uid大于5 并且 uid小于10
mysql> SELECT name,uid FROM tarena.user WHERE uid > 5 AND uid < 10;
-- 取反:uid不大于5
mysql> SELECT name,uid FROM tarena.user WHERE NOT uid > 5;
-- 括号提升优先级:uid=0或uid=1,同时name必须是root
mysql> SELECT name,uid FROM tarena.user WHERE (uid = 1 OR uid = 0) AND name = "root";
4.7 别名、字符串拼接、去重
- 别名 AS :给字段或表格设置显示别名,
AS关键字可省略 - CONCAT():拼接多个字段/字符串;任意字段为NULL,整体返回NULL
- DISTINCT:去除查询结果的重复数据。用的较少

别名示例:
sql
mysql> SELECT name as 用户名,homedir as 家目录 FROM tarena.user;
+-----------------+--------------------+
| 用户名 | 家目录 |
+-----------------+--------------------+
| root | /root |
| bin | /bin |
| daemon | /sbin |
| adm | /var/adm |
| lp | /var/spool/lpd |
| sync | /sbin |
| shutdown | /sbin |
| halt | /sbin |
| mail | /var/spool/mail |
| operator | /root |
| games | /usr/games |
| ftp | /var/ftp |
| nobody | / |
| systemd-network | / |
| dbus | / |
| polkitd | / |
| sshd | /var/empty/sshd |
| postfix | /var/spool/postfix |
| chrony | /var/lib/chrony |
| rpc | /var/lib/rpcbind |
| rpcuser | /var/lib/nfs |
| nfsnobody | /var/lib/nfs |
| haproxy | /var/lib/haproxy |
| plj | /home/plj |
| apache | /usr/share/httpd |
| mysql | /var/lib/mysql |
| bob | NULL |
+-----------------+--------------------+
27 rows in set (0.00 sec)
系统命令读取的顺序是先读表再读命令参数
注意,别名不会改变表结构和内容,仅改变本次输出内容
字符串拼接 CONCAT
sql
mysql> SELECT concat(name,"-",uid) FROM tarena.user;
+----------------------+
| concat(name,"-",uid) |
+----------------------+
| root-0 |
| bin-1 |
| daemon-2 |
| adm-3 |
| lp-4 |
| sync-5 |
| shutdown-6 |
| halt-7 |
| mail-8 |
| operator-11 |
| games-12 |
| ftp-14 |
| nobody-99 |
| systemd-network-192 |
| dbus-81 |
| polkitd-999 |
| sshd-74 |
| postfix-89 |
| chrony-998 |
| rpc-32 |
| rpcuser-29 |
| nfsnobody-65534 |
| haproxy-188 |
| plj-1000 |
| apache-48 |
| mysql-27 |
| NULL |
+----------------------+
27 rows in set (0.00 sec)
DISTINCT 去重
sql
#如果shell后面又跟了一个元素,如name,那么去重效果不会生效
mysql> SELECT distinct shell FROM tarena.user;
+----------------+
| shell |
+----------------+
| /bin/bash |
| /sbin/nologin |
| /bin/sync |
| /sbin/shutdown |
| /sbin/halt |
| /bin/false |
| NULL |
+----------------+
7 rows in set (0.01 sec)
4.8 MySQL内置普通函数
调用格式:函数名(),支持单独调用、嵌套调用、搭配数据表使用
- 使用示例
- SELECT 函数名(); //单独使用
- SELECT 函数(函数()); //函数嵌套函数
- SELECT 函数(字段名) FROM 库名.表名; //处理表头数据g

sql
# 查看MySQL版本
mysql> SELECT VERSION();
# 查看登录用户
mysql> SELECT USER();
# 查看当前库
mysql> SELECT DATABASE();
4.9 聚合函数(统计函数)
作用:对查询结果集做数值统计运算
| 函数 | 功能 |
|---|---|
| AVG(字段名) | 计算字段平均值 |
| SUM(字段名) | 计算字段数值总和 |
| MIN(字段名) | 获取字段最小值 |
| MAX(字段名) | 获取字段最大值 |
| COUNT(字段名) | 统计对应字段的行数(会忽略NULL值) |
sql
-- 计算user表uid平均值
mysql> SELECT AVG(uid) FROM tarena.user;
-- 计算uid总和
mysql> SELECT SUM(uid) FROM tarena.user;
-- 查询uid最小值
mysql> SELECT MIN(uid) FROM tarena.user;
-- 查询uid最大值
mysql> SELECT MAX(uid) FROM tarena.user;
-- 统计shell等于/bin/bash的记录行数
mysql> SELECT COUNT(name) FROM tarena.user WHERE shell = "/bin/bash";
-- 统计整个表格中不为空的总行数(所有字段为空才算空)
mysql> SELECT COUNT(*) FROM tarena.user;
5 本章整体总结
- 掌握MySQL完整部署流程:dnf安装服务、启动、开机自启、端口验证
- 掌握MySQL管理员root密码设置、重置、忘记密码破解全流程
- 掌握SQL基础查询语法
SELECT - 掌握全部筛选条件语法:数值比较、字符比较、范围匹配、模糊LIKE、正则REGEXP、多逻辑AND/OR/NOT
- 掌握查询辅助功能:字段别名、字符串拼接CONCAT、DISTINCT去重
- 掌握MySQL内置普通函数:VERSION、USER、DATABASE
- 掌握五大聚合统计函数:AVG、SUM、MIN、MAX、COUNT