MySQL——黑马

  • MySQL配置文件(my.cnf 或 my.ini) 一般位于 /etc/mysql//etc/ 目录下。
  • MySQL 数据目录 默认情况下是在 /var/lib/mysql/,这里存放了数据库的数据文件。
  • 我安装的mysql
    • ip: 192.168.31.20
    • port: 3306
    • 用户名: root, mysql8_gtc
    • 密码: ROOT, gtc123

第一章: 基础篇

1. 数据类型

1.1 数值类型

1.2 字符串类型

1.3 日期时间类型

2. SQL

2.1 SQL分类

|-----|----------------------------|--------------------------------------|
| 分类 | 全称 | 说明 |
| DDL | Data Definition Language | 数据定义语言, 用来定义数据库字段 |
| DML | Data Manipulation Language | 数据操作语言,用来对数据库表中的数据进行增删改 |
| DQL | Data Query Language | 数据查询语言,用来查询数据库中表的记录 |
| DCL | Data Control Language | 数据控制语言,用来创建数据库用户控制数据库的访问权限 |

2.2 DDL

DDL用来定义,删除和修改数据库字段。

2.2.1 DDL操作数据库

  • 查询所有数据库

    sql 复制代码
    SHOW DATABASES;
  • 查询当前所处数据库

    sql 复制代码
    SELECT DATABASES();
  • 创建数据库

    sql 复制代码
    CREATE DATABASE [IF NOT EXISTS] 数据库名 [DEFAULT CHARSET 字符集] [COLLATE 排序规则]
  • 删除数据库

    sql 复制代码
    DROP DATABASE [IF EXISTS] 数据库名;
  • 使用数据库

    sql 复制代码
    USE 数据库名;

2.2.2 DDL操作表

  • 查询当前数据库所有表

    sql 复制代码
    SHOW TABLES;
  • 查询表结构

    sql 复制代码
    DESC 表名;
  • 查询指定表的建表语句

    sql 复制代码
    SHOW CREATE TABLE 表名;
  • 创建

    sql 复制代码
    CREATE TABLE 表名(
        字段1 字段1类型 [COMMENT 字段1注释],
        字段2 字段1类型 [COMMENT 字段2注释],
        字段3 字段1类型 [COMMENT 字段3注释],
        ......
        字段n 字段1类型 [COMMENT 字段n注释]
    ) [COMMENT 表注释];
  • 修改

    sql 复制代码
    -- 添加字段
    ALTER TABLE 表名 ADD 字段名 字段类型(长度) [COMMENT 注释] [约束];
    
    -- 修改数据类型
    ALTER TABLE 表名 MODIFY 字段名 新数据类型(长度);
    
    -- 修改字段名和字段类型
    ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型(长度) [COMMENT 注释] [约束];
    
    -- 修改表名
    ALTER TABLE 表名 RENAME TO 新表名;
  • 删除

    sql 复制代码
    -- 删除表
    DROP TABLE [IF EXISTS] 表名;
    
    -- 删除指定表,并重新创建该表
    TRUNCATE TABLE 表名;
    
    -- DROP删除表的数据+表的结构,而TRUNCATE只删除表的数据,不删除表的结构

选择使用 DROP TABLE 还是 TRUNCATE TABLE 应基于你是否希望保留表结构以及你需要执行的具体操作类型。如果你只是想清空表内的数据并保留表结构,TRUNCATE TABLE 是更合适的选择。如果你不再需要这个表及其数据,则应使用 DROP TABLE

2.3 DML

DML用来对数据库中表的记录进行增删改操作。

2.3.1 增加-INSERT

  • 给指定字段添加数据

    sql 复制代码
    INSERT INTO 表名(字段1, 字段2, ...) VALUES(值1, 值2, ...);
  • 给全部字段添加数据

    sql 复制代码
    INSERT INTO 表名 VALUES (值1, 值2, ...);
  • 批量添加数据

    sql 复制代码
    -- 批量添加指定字段
    INSERT INTO 表名(字段1, 字段2, ...) VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, 值2, ...);
    
    -- 批量添加全部字段
    INSERT INTO 表名 VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, 值2, ...);
  • 注意:

    • 插入数据时,指定的字段顺序需要与值的顺序是一一对应的。
    • 字符串和日期数据应该包括在引号中。
    • 插入的数据大小,应该在字段的规定范围内。

2.3.2 修改-UPDATE

  • 修改数据

    sql 复制代码
    UPDATE 表名 SET 字段名1=值1, 字段名2=值2, ... [WHERE 条件];

    注意:修改语句的条件可以有,也可以没有,如果没有条件,则会修改整张表的所有数据。

2.3.3 删除-DELETE

  • 删除数据

    sql 复制代码
    DELETE FROM 表名 [WHERE 条件];

    注意:DELETE语句的条件可以有,也可以没有,如果没有条件,则会删除整张表的所有数据。DELETE语句是按照行删除的,不能删除某一个字段的值(可以使用UPDATE)

2.4 DQL

2.4.1 单表查询

(1)基础查询
  • 查询多个字段
sql 复制代码
-- 查询指定字段
SELECT 字段1, 字段2, 字段3, ... FROM 表名;

-- 查询所有字段
SELECT * FROM 表名;
  • 设置别名
sql 复制代码
SELECT 字段1 [AS 别名1], 字段2 [AS 别名2], ... FROM 表名;
  • 去除重复记录
sql 复制代码
SELECT DISTINCT 字段列表 FROM 表名;
(2)条件查询
  • 语法
sql 复制代码
SELECT 字段列表 FROM 表名 WHERE 条件列表;
  • 条件

|---------------------|------------------------|
| 比较运算符 | 功能 |
| > | 大于 |
| >= | 大于等于 |
| < | 小于 |
| <= | 小于等于 |
| = | 等于 |
| <>或!= | 不等于 |
| BETWEEN ... AND ... | 在某个范围之内(含最大,最小值) |
| IN(...) | 在in之后的列表中的值, 多选一 |
| LIKE 占位符 | 模糊匹配(_是单个字符, %匹配任意个字符) |
| IS NULL | 是NULL |

|------------|----------------|
| 逻辑运算符 | 功能 |
| AND 或 && | 并且(多个条件同时成立) |
| OR 或 || | 或者(多个条件任意一个成立) |
| NOT 或 ! | 非 |

(3)聚合函数
  • 介绍:将一列数据作为一个整体,进行纵向计算。注意:NULL值不参与运算
  • 常见聚合函数
    • count:统计数量
    • max:统计最大值
    • min:统计最小值
    • avg:平均值
    • sum:求和
  • 语法
sql 复制代码
SELECT 聚合函数(字段列表) FROM 表名;
(4)分组查询⭐️⭐️⭐️

分组查询 === 一组一行数据 === 聚合函数也是得到一行数据

分组查询使用的关键字是GROUP BY,通常要和聚合函数与HAVING一起。SELECT 列表中的所有字段,要么是 GROUP BY 中出现的字段,要么必须是聚合函数(如 MAX、MIN、COUNT、SUM 等)的参数。

GROUP BY 子句在 SQL 查询中并不强制要求与聚合函数一起使用,但通常情况下它们是搭配使用的。这是因为 GROUP BY 的主要作用是将数据按照一个或多个列的值进行分组,而聚合函数(如 COUNT(), SUM(), AVG(), MAX(), MIN() 等)则用于对每个分组计算汇总值。

  • 语法
sql 复制代码
SELECT 字段列表 FROM 表名 [WHERE 条件] GROUP BY 分组字段名 [HAVING 分组后过滤条件];
  • where和having区别
    • 执行时机不同:where是分组之前进行过滤,不满足where条件不参与分组;而having是分组之后对结果进行过滤。
    • 判断条件不同:where不能对聚合函数进行判断,而having可以。

分组查询案例:

有如下一个部门表:

分析执行:

sql 复制代码
select deptno,sum(sal)  AS total  from employee where sal>1000 group by  deptno having sum(sal) >9000 
order by sum(sal) asc;

分析过程:

该SQL的书写顺序:

select, from, where, group by, having, order by

实际的执行顺序:

from, where, group by, having, select, order by

一: 执行from employee

sql 复制代码
select * from employee;

二: 执行where sal > 1000

sql 复制代码
select * from employee where sal > 1000;

三: 执行group by deptno

sql 复制代码
select deptno from employee where sal > 1000 group by deptno;

四: 执行having sum(sal) > 9000

对每个分组,分别求sum(sal),只有sum(sal) > 9000 的分组才会显示。

五: 执行select deptno, sum(sal) as total

计算每个分组的sum(sal)

六: 执行order by

(5)排序查询
  • 语法
sql 复制代码
SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式1, 字段2 排序方式2;
  • 排序方式
    • ASC:升序(默认)
    • DESC:降序
  • 注意:如果是多字段排序,当第一个字段值相同时,才会根据第二个字段进行排序。
(6)分页查询
  • 语法
sql 复制代码
SELECT 字段列表 FROM 表名 LIMIT 起始索引, 查询记录数;
  • 注意
    • 起始索引从0开始,起始索引 = (查询页码 - 1) * 每页显示记录数
    • 分页查询是数据库的方言,不同的数据库有不同的实现,MySQL中是LIMIT
    • 如果查询的是第一页数据,起始索引可以省略,直接简写为limit 10
(7)执行顺序⭐️⭐️⭐️
  • 书写顺序
  1. select
  2. from
  3. where
  4. group by
  5. having
  6. order by
  7. limit
  • 执行顺序
  1. from -- 行过滤
  2. where
  3. group by
  4. having
  5. select -- 列过滤
  6. order by
  7. limit

一句话:select在分组查询group by ... having ...之后。

where是分组之前过滤,having是分组之后过滤。

2.4.2 多表查询

多表查询见第5小节: 多表查询。

2.5 DCL

DCL是数据控制语言,用来管理数据库用户控制数据库的访问权限

2.5.1 DCL用户管理

(1)查询用户

sql 复制代码
USE mysql;
SELECT * FROM user;

mysql中,用户信息保存在mysql数据库的user表里。

(2)创建用户

sql 复制代码
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';

(3)修改用户密码

sql 复制代码
ALTER USER '用户名'@'主机名' IDENTIFIED WITH mysql_native_password BY '新密码';

(4)删除用户

sql 复制代码
DROP USER '用户名'@'主机名';

案例

sql 复制代码
-- 创建用户itcast, 只能够在当前主机localhost访问, 密码123456
create user 'itcast'@'localhost' identified by '123456';

-- 创建用户heima, 可以在任意主机访问该数据库, 密码123456
create user 'heima'@'%' identified by '123456';

-- 修改用户heima的访问密码 1234;
alter user 'heima'@'%' identified with mysql_native_password by '1234';

-- 删除itcast@localhost用户
drop user 'itcast'@'localhost';

注意:

  • 主机名可以使用%通配
  • 这类SQL开发人员操作的比较少,主要是DBA(Database Administrator数据库管理员)使用。

2.5.2 DCL权限控制

mysql数据库可以被不同用户登陆,但是不同用户对于数据库的操作权限可能不一样。

权限: mysql登陆用户操作某数据库的权限。

|---------------------|------------|
| 权限 | 说明 |
| ALL, ALL PRIVILEGES | 所有权限 |
| SELECT | 查询数据 |
| INSERT | 插入数据 |
| UPDATE | 更新数据 |
| DELETE | 删除数据 |
| ALTER | 修改表 |
| DROP | 删除数据库/表/视图 |
| CREATE | 创建数据库/表 |

(1)查询权限

sql 复制代码
SHOW GRANTS FOR '用户名'@'主机名';

(2)授予权限

sql 复制代码
GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名';

(3)撤销权限

sql 复制代码
REVOKE 权限列表 ON 数据库.表名 FROM '用户名'@'主机名';

3. 函数

函数 是指一段可以直接被另一段程序调用的程序或代码。函数是mysql内置的。

3.1 字符串函数

|----------------------------|--------------------------------------|
| 函数 | 功能 |
| CONCAT(s1,s2,...) | 字符串拼接 |
| LOWER(str) | 将字符串str全部转为小写 |
| UPPER(str) | 将字符串str全部转为大写 |
| LPAD(str, n, pad) | 左填充, 用字符串pad对str的左边进行填充, 达到n个字符串长度 |
| RPAD(str, n, pad) | 右填充, 用字符串pad对str的左、右边进行填充, 达到n个字符串长度 |
| TRIM(str) | 去掉字符串头部和尾部的空格 |
| SUBSTRING(str, start, len) | 返回从字符串str从start位置起的len个长度的字符串 |
[Mysql常用内置字符串函数]

案例:

sql 复制代码
SELECT CONCAT('Hello', ' MySQL'); -- 得到'Hello MySQL'

SELECT LOWER('Hello'); -- 得到'hello'

SELECT UPPER('Hello'); -- 得到'HELLO'

SELECT LPAD('01',5,'-'); -- 得到'---01'

SELECT RPAD('01',5,'-'); -- 得到'01---'

SELECT TRIM(' Hello MySQL ') -- 得到'Hello MySQL'

SELECT SUBSTRING('Hello MySQL',1,5); -- 得到'Hello'

3.2 数值函数

|------------|--------------------|
| 函数 | 功能 |
| CEIL(x) | 向上取整 |
| FLOOR(x) | 向下取整 |
| MOD(x,y) | 返回x/y的模 |
| RAND() | 返回0~1内的随机数 |
| ROUND(x,y) | 求参数x的四舍五入的值,保留y位小数 |

3.3 日期函数

|------------------------------------|----------------------------|
| 函数 | 功能 |
| CURDATE() | 返回当前日期 |
| CURTIME() | 返回当前时间 |
| NOW() | 返回当前日期和时间 |
| YEAE(date) | 获取指定date的年份 |
| MONTH(date) | 获取指定date的月份 |
| DAY(date) | 获取指定date的日期 |
| DATE_ADD(date, INTERVAL expr type) | 返回一个日期/时间加上一个时间间隔expr后的时间值 |
| DATEDIFF(date1, date2) | 返回起始时间date1和结束时间date2之间的天数 |

3.4 流程函数

|--------------------------------------------------------------------|----------------------------------------|
| 函数 | 功能 |
| IF(value, t, f) | 如果value为true,则返回t,否则返回f |
| IFNULL(value1, value2) | 如果value==null,返回value2,否则返回value1 |
| CASE WHEN [val1] THEN [res1] ... ELSE [default] END | 如果val1为true, 返回res1, ...否则返回default默认值 |
| CASE [expr] WHEN [val1] THEN [res1] ... ELSE [default] END | 如果expr的值等于val1,返回res1,否则返回default默认值 |

4. 约束

4.1 约束概述

概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据;

目的:保证数据库中数据的正确,有效和完整性。

4.2 约束的分类

|------------------|------------------------------|-------------|
| 约束 | 描述 | 关键字 |
| 非空约束 | 限制该字段的数据不能为null | NOT NULL |
| 唯一约束 | 保证该字段的所有数据都是唯一,不重复的 | UNIQUE |
| 默认约束 | 保存数据时,如果未指定该字段的值,则采用默认值 | DEFAULT |
| 主键约束 | 主键是一行数据的唯一标识,要求非空且唯一 | PRIMARY KEY |
| 外键约束 | 用来让两张表的数据之间建立连接,保证数据的一致性和完整性 | FOREIGN KEY |
| 检查约束(8.0.16版本之后) | 保证字段值满足某一个条件 | CHECK |

注意:约束是作用于表中字段上的,可以在创建表/修改表的时候添加约束。

4.3 约束演示

根据需求,完成表结构的创建。

|---------|----------|-------------|---------------|----------------------------|
| 字段名 | 字段含义 | 字段类型 | 约束条件 | 约束关键字 |
| id | ID唯一标识 | int | 主键,并且自动增长 | PRIMARY KEY,AUTO_INCREMENT |
| name | 姓名 | varchar(10) | 不为空,并且唯一 | NOT NULL,UNIQUE |
| age | 年龄 | int | 大于0,并且小于等于120 | CHECK |
| status | 状态 | char(1) | 如果没有指定该值,默认为1 | DEFAULT |
| gender | 性别 | char(1) | 无 | |

sql 复制代码
CREATE TABLE user(
	id int PRIMARY KEY AUTO_INCREMENT COMMENT '主键',
	name VARCHAR(10) NOT NULL UNIQUE COMMENT '姓名',
	age INT CHECK (age > 0 && age <= 120) COMMENT '年龄',
	status CHAR(1) DEFAULT('1') COMMENT '状态',
	gender CHAR(1) COMMENT '性别'
) COMMENT '用户表';

4.4 外键约束

4.4.1 概念

外键用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性。

注意:目前上述的两张表,在数据库层面,并没有建立外键关联,所以是无法保证数据的一致性和完整性。

4.4.2 外键的建立

  • 添加外键
sql 复制代码
-- 第一种方式
CREATE TABLE 表名(
    字段名 数据类型,
    ...
    [CONSTRAINT] [外键名称] FOREIGN KEY(外键字段名) REFERENCES 主表(主表列名)
);

-- 第二种方式
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY(外键字段名) REFERENCES 主表(主表列名);

当dept_id被设置为外键之后,再去删除dept表的'1研发部'就无法成功删除(因为emp表里还存在dept_id=1的员工)

  • 删除外键
sql 复制代码
ALTER TABLE 表名 DROP FOREIGN KEY 外键;

4.4.3 外键删除/更新行为

|-------------|--------------------------------------------------------------------|
| 行为 | 说明 |
| NO ACTION | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。 |
| RESTRICT | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。 |
| CASCADE | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则删除/更新在子表中的记录。 |
| SET NULL | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为null(这就要求该外键允许取null)。 |
| SET DEFAULT | 父表有变更时,子表将外键列设置成一个默认的值(InnoDB不支持) |

sql 复制代码
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY(外键字段名) REFERENCES 主表(主表列名) ON UPDATE CASCADE ON DELETE CASCADE;

执行这条语句后,若删除dept表id=1的研发部,则emp表中dept_id=1的数据也会删除。

5. 多表查询

前面讲了单表查询的DQL,这一节讲解多表查询的DQL。

5.1 多表关系

5.1.1 一对多

  • 案例:部门与员工的关系
  • 关系:一个部门可以有多个员工,一个员工对应一个部门
  • 实现:在多的一方建立外键,指向一的一方的主键

5.1.2 多对多

  • 案例:学生与课程的关系
  • 关系:一个学生可以选择多个课程,一个课程也可以被多个学生选择
  • 实现:建立第三章中间表,中间表至少包含两个外键,分别关联两方主键

5.1.3 一对一

  • 案例:用户与用户详情的关系
  • 关系:一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率。
  • 实现:在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)

5.2 多表查询概述

  • 概述:指从多张表中查询数据
  • 笛卡尔积:笛卡尔乘积是指在数学中,两个集合A集合和B集合的所有组合情况。(在多表查询时,需要消除无效的笛卡尔积)。

笛卡尔积演示:

sql 复制代码
SELECT * FROM emp, dept;

消除上述笛卡尔积(隐式内连接):

sql 复制代码
SELECT * FROM emp, dept WHERE emp.dept_id = dept.id;

5.3 多表查询分类

  • 连接查询
    • 内连接:查询A, B交集部分数据
    • 外连接
      • 左外连接:查询左表所有数据,以及两张表交集部分数据
      • 右外连接:查询右表所有数据,以及两张表交集部分数据
    • 自连接:当前表与自身的连接查询,自连接必须使用表别名
  • 子查询

5.4 内连接

内连接:查询A, B交集部分数据

  • 隐式内连接
sql 复制代码
SELECT 字段列表 FROM 表1, 表2 WHERE 条件 ...;
  • 显式内连接
sql 复制代码
SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 连接条件 ...;

5.5 外连接

  • 左外连接:表1所有数据+表2部分数据
sql 复制代码
SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 条件...;
  • 右外连接:表2所有数据+表1部分数据
sql 复制代码
SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 条件...;

5.6 自连接

sql 复制代码
SELECT 字段列表 FROM 表A 别名A  JOIN 表A 别名B ON 条件...;

自连接查询,可以是内连接查询,也可以是外连接查询。

5.7 联合查询union

对于union查询,就是把多次查询的结果合并起来,形成一个新的查询结果集。

sql 复制代码
SELECT 字段列表 FROM 表A ...
UNION [ALL]
SELECT 字段列表 FROM 表B ...;

对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。

5.7 子查询

5.7.1 标量子查询

5.7.2 列子查询

5.7.3 行子查询

5.7.4 表子查询

6. 事务

第二章: 进阶篇

第三章: 运维篇

相关推荐
码银1 小时前
什么是逻辑外键?我们要怎么实现逻辑外键?
java·数据库·spring boot
GOTXX2 小时前
【CS创世SD NAND征文】小型夜灯为何需要存储芯片?从基础照明到智能存储的升级密码
数据库·科技·安全·芯片·储存
TDengine (老段)2 小时前
TDengine 中 TDgpt 的模型评估工具
大数据·数据库·机器学习·ai·时序数据库·tdengine·涛思数据
一号IT男3 小时前
MySql MVCC的原理总结
数据库·mysql
我感觉。3 小时前
旅游mcp配置(1)
数据库
Badman4 小时前
Redis与DB的数据一致性问题梳理
数据库·redis·后端
荔枝吻4 小时前
【沉浸式解决问题】mysql-connector-python连接数据库:RuntimeError: Failed raising error.
数据库·python·mysql
一号IT男5 小时前
MySQL聚簇索引与非聚簇索引详解
数据库·mysql
苹果醋35 小时前
react_05create-react-app脚手架详细解析(export)
java·运维·spring boot·mysql·nginx