#Linux数据库管理Day01:MySQL数据库基础(过滤与查询)

1 数据库基础

1.1 数据库介绍

  1. 数据库:存储数据的仓库
  2. 定义:按照某种数据模型,将数据存储到存储器的集合
  3. 生活中常见数据类型:视频、音频、图片、文本

1.2 常见的数据库软件

配套操作系统:Linux、Windows、Unix

数据库分类与厂商、开源属性:

1.3 数据库类型

  1. 关系型数据库(RDBMS)
    • 存储形式:表格存储数据
    • 操作语言:SQL结构化查询语言
  2. 非关系型数据库(NoSQL,还可以做缓存)
    • 存储结构:键值对、文档等
    • 适用场景:大数据、高并发业务
  3. 图形数据库(Graph Database)
    • 存储图形关联数据
    • 典型场景:社交网络、知识图谱
  4. 内存数据库
    • 数据常驻内存
    • 优势:读写速度快、低延迟
    • 适用:高读写性能要求业务
  5. 分布式数据库
    • 数据拆分存储在多台节点服务器
    • 能力:支持业务水平扩展

补充说明:不同数据库适配不同业务场景,系统设计阶段需结合需求选型。简单讲,数据库没有好与坏之分,只有适合与否

1.4 MySQL介绍

  1. 定位:全球应用最广泛的开源关系型数据库
  2. 发展历程
    • 最初归属瑞典MySQL AB公司
    • 2008.01:MySQL AB被Sun公司收购
    • 2009.04:Sun公司被Oracle甲骨文收购
  3. MariaDB分支
    • 诞生原因:规避MySQL闭源风险
    • 开发主导:MySQL原作者Widenius
    • 特性:与MySQL高度兼容
  4. 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特点及应用

核心特点
  1. 适配中小规模关系型业务系统
  2. 跨平台:支持Linux、Unix、Windows
  3. 多语言兼容:Python、Java、Perl、PHP等主流开发语言
典型部署平台组合
  1. LAMP平台,与Apache HTTP Server组合:Linux + Apache + MySQL + PHP
  2. LNMP,与Nginx组合:Linux + Nginx + MySQL + PHP
  3. LNMJ,与Tomcat/Java应用组合:Linux + Nginx + MySQL + Tomcat/Java

1.6 MySQL数据库结构

MySQL核心软件包
  1. mysql-server:
    • 数据库后台服务 :mysqld
    • 默认端口:3306
      (mysql本地连接时使用的是socket文件,跨主机连接数据库读取的是3306端口)
  2. 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客户端连接方式

  1. 命令行连接(基础):

mysql -h数据库服务器IP -u数据库用户名 -p'密码'

  1. 图形化工具:软件自带客户端图形页面、Web管理页面
  2. 代码脚本连接:PHP、Java、Python等程序代码连接数据库

2.5 SQL命令通用语法规范

  1. SQL关键字(库、表名除外)不区分大小写
  2. 每条SQL语句必须以英文分号 ;\g 结尾
  3. MySQL客户端不支持SQL语句自动补齐

2.6 SQL四大语言分类(了解)

  1. DDL 数据定义语言 :负责库、表结构创建修改删除
    关键字:CREATEALTERDROP
  2. DML 数据操作语言 :操作表内数据
    关键字:INSERTUPDATEDELETE
  3. DCL 数据控制语言 :用户权限管理
    关键字:GRANTREVOKE
  4. DTL 数据事务语言 :事务回滚、提交
    关键字:COMMITROLLBACKSAVEPOINT
数据库基础操作SQL
sql 复制代码
-- 查看服务器所有数据库
SHOW DATABASES;
-- 查看当前登录用户,user()是函数
SELECT user();
-- 切换至指定数据库
USE 库名;
-- 查看当前正在使用的数据库
SELECT database();
-- 创建新数据库
CREATE DATABASE 库名;
-- 查看当前库下所有数据表
SHOW TABLES;
-- 删除指定数据库
DROP DATABASE 库名;

补充概念:数据库等同于文件夹,用于存放多张数据表,一台MySQL可创建多个独立库,通过库名区分。

2.7 数据库命名规则

  1. 可用字符:数字、字母、下划线,不能纯数字命名
  2. 区分大小写,同一服务器库名唯一
  3. 禁止使用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 导入测试数据

  1. 准备工作:将company.sql文件上传至MySQL服务器 /root 目录
  2. 命令行导入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 表格业务数据说明

  1. departments部门表:共8个部门数据
  1. employees员工表:共133位员工,归属不同部门
  1. 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 '通配符';

通配符规则:

  1. _:匹配任意一个字符
  2. %:匹配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 '正则表达式'

常用正则元字符:

  1. ^内容:以指定内容开头
  2. 内容$:以指定内容结尾
  3. [abc]:匹配括号内任意单个字符
  4. *:前一个字符重复任意次数
  5. |:或逻辑
  6. .:任意单个字符
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 别名、字符串拼接、去重

  1. 别名 AS :给字段或表格设置显示别名,AS 关键字可省略
  2. CONCAT():拼接多个字段/字符串;任意字段为NULL,整体返回NULL
  3. 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 本章整体总结

  1. 掌握MySQL完整部署流程:dnf安装服务、启动、开机自启、端口验证
  2. 掌握MySQL管理员root密码设置、重置、忘记密码破解全流程
  3. 掌握SQL基础查询语法 SELECT
  4. 掌握全部筛选条件语法:数值比较、字符比较、范围匹配、模糊LIKE、正则REGEXP、多逻辑AND/OR/NOT
  5. 掌握查询辅助功能:字段别名、字符串拼接CONCAT、DISTINCT去重
  6. 掌握MySQL内置普通函数:VERSION、USER、DATABASE
  7. 掌握五大聚合统计函数:AVG、SUM、MIN、MAX、COUNT