当前位置: 首页 > news >正文

MySQL基础02

一. 函数

在 MySQL 中,函数是用于对数据进行特定处理或计算的工具,根据作用范围和返回结果的不同,主要分为单行函数聚合函数(又称分组函数)。以下是详细介绍:

1.单行函数

单行函数对每一行数据单独处理,每行返回一个结果,常见类型包括字符串函数、数值函数、日期函数、流程控制函数等。

1.) 字符串函数

用于处理字符串类型数据,常见函数如下:

函数功能描述示例结果
CONCAT(str1, str2,...)拼接多个字符串(若有一个参数为NULL,结果为NULLCONCAT('MySQL', ' ', '函数')MySQL 函数
CONCAT_WS(sep, str1, str2,...)用分隔符sep拼接字符串(忽略NULLCONCAT_WS('-', '2023', '10', '05')2023-10-05
LENGTH(str)返回字符串的字节数(受字符集影响,UTF-8 中汉字占 3 字节)LENGTH('中国')6
CHAR_LENGTH(str)返回字符串的字符数(与字符集无关)CHAR_LENGTH('中国')2
UPPER(str)将字符串转为大写UPPER('mysql')MYSQL
LOWER(str)将字符串转为小写LOWER('MYSQL')mysql
SUBSTRING(str, pos, len)pos位置(起始为 1)截取长度为len的子串(省略len则取到末尾)SUBSTRING('HelloWorld', 7, 3)orl
TRIM(str)去除字符串两端的空格(TRIM(指定字符 FROM str)可去除指定字符)TRIM(' MySQL ')MySQL
REPLACE(str, old, new)str中所有old子串替换为newREPLACE('abc123abc', 'abc', 'x')x123x
INSTR(str, substr)返回substrstr中首次出现的位置(无则返回 0)INSTR('abcde', 'cd')3
2.) 数值函数

用于数值计算,常见函数如下

函数功能描述示例结果
ABS(x)返回x的绝对值ABS(-10)10
CEIL(x)向上取整(返回大于等于x的最小整数)CEIL(3.2)4
FLOOR(x)向下取整(返回小于等于x的最大整数)FLOOR(3.8)3
ROUND(x, d)四舍五入保留d位小数(d默认 0)ROUND(3.1415, 2)3.14
MOD(x, y)返回x除以y的余数(同x % yMOD(10, 3)1
POWER(x, y)返回xy次方POWER(2, 3)8
SQRT(x)返回x的平方根SQRT(16)4
3. )日期函数

用于处理日期和时间类型数据,常见函数如下:

函数功能描述示例结果(假设当前时间为 2023-10-05 15:30:00)
NOW()返回当前日期和时间(YYYY-MM-DD HH:MM:SSNOW()2023-10-05 15:30:00
CURDATE()返回当前日期(YYYY-MM-DDCURDATE()2023-10-05
CURTIME()返回当前时间(HH:MM:SSCURTIME()15:30:00
YEAR(date)提取日期中的年份YEAR('2023-10-05')2023
MONTH(date)提取日期中的月份MONTH('2023-10-05')10
DAY(date)提取日期中的日DAY('2023-10-05')5
HOUR(time)提取时间中的小时HOUR('15:30:00')15
DATEDIFF(date1, date2)返回date1 - date2的天数差DATEDIFF('2023-10-05', '2023-10-01')4
DATE_ADD(date, INTERVAL expr unit)给日期添加指定时间间隔(unit:YEAR、MONTH、DAY 等)DATE_ADD('2023-10-05', INTERVAL 3 DAY)2023-10-08
DATE_FORMAT(date, format)将日期按format格式转换为字符串(%Y年、%m月、%d日等)DATE_FORMAT('2023-10-05', '%Y年%m月%d日')2023-10-05
4. )流程控制函数

用于实现条件判断逻辑,类似编程语言中的if-else

函数功能描述示例结果
IF(expr, v1, v2)expr为真(非 0/NULL),返回v1,否则返回v2IF(10 > 5, '是', '否')
IFNULL(v1, v2)v1不为NULL,返回v1,否则返回v2(处理 NULL 值)IFNULL(NULL, '空值')空值
CASE多条件判断(类似switch-caseCASE 分数<br>WHEN 90 THEN '优秀'<br>WHEN 80 THEN '良好'<br>ELSE '及格'<br>END(根据分数返回对应等级)

2.聚合函数(分组函数)

聚合函数用于对一组数据进行汇总计算,返回单一结果,通常与GROUP BY配合使用(若不分组,则默认对全表数据聚合)。常见聚合函数如下:

函数功能描述示例(表students含字段score结果
COUNT(expr)统计非NULL值的数量(COUNT(*)统计所有行,包括NULLCOUNT(score)分数非空的行数
SUM(expr)计算数值型字段的总和SUM(score)所有分数的总和
AVG(expr)计算数值型字段的平均值AVG(score)分数的平均值
MAX(expr)求字段的最大值MAX(score)最高分数
MIN(expr)求字段的最小值MIN(score)最低分数
注意事项:
  1. 聚合函数会自动忽略NULLCOUNT(*)除外)。

  2. 若使用聚合函数时未加GROUP BY,则整个表视为一组。

  3. SELECT子句中若有聚合函数,其他非聚合字段需出现在GROUP BY中(避免歧义)。

3.函数使用示例

  1. 字符串拼接与日期格式化

    SELECT CONCAT('姓名:', name) AS 姓名,DATE_FORMAT(birthday, '%Y年%m月%d日') AS 生日
    FROM students;
  2. 聚合函数统计

    SELECT COUNT(*) AS 总人数,AVG(score) AS 平均分,MAX(score) AS 最高分
    FROM students;
  3. 条件判断

    SELECT name AS 姓名,score AS 分数,CASE WHEN score >= 90 THEN '优秀'WHEN score >= 80 THEN '良好'ELSE '及格'END AS 等级
    FROM students;

二. 约束

在 MySQL 中,约束(Constraints)是用于限制表中数据的规则,确保数据的完整性、一致性和准确性。常见的 MySQL 约束包括以下几种:

主键约束(PRIMARY KEY)

  • 唯一标识表中的每条记录

  • 不能有重复值,且不能为 NULL

  • 一个表只能有一个主键

CREATE TABLE students (id INT PRIMARY KEY,name VARCHAR(50)
);

外键约束(FOREIGN KEY)

  • 用于关联两个表,确保参照完整性

  • 外键列的值必须匹配另一个表的主键列的值或为 NULL

CREATE TABLE orders (order_id INT PRIMARY KEY,student_id INT,FOREIGN KEY (student_id) REFERENCES students(id)
);

唯一约束(UNIQUE)

  • 确保列中的所有值都是唯一的

  • 允许 NULL 值,但 NULL 只能出现一次

CREATE TABLE users (id INT PRIMARY KEY,email VARCHAR(100) UNIQUE
);

非空约束(NOT NULL)

  • 确保列不能包含 NULL 值

CREATE TABLE employees (id INT PRIMARY KEY,name VARCHAR(50) NOT NULL,age INT
);

检查约束(CHECK)

  • 确保列中的值满足指定的条件

  • MySQL 8.0.16 及以上版本支持

CREATE TABLE products (id INT PRIMARY KEY,price DECIMAL(10,2) CHECK (price > 0)
);

默认约束(DEFAULT)

  • 为列指定默认值,如果插入数据时未指定该列的值,则使用默认值

CREATE TABLE customers (id INT PRIMARY KEY,country VARCHAR(50) DEFAULT 'China'
);

三. 多表查询

多表查询是数据库操作中常用的技术,用于从两个或多个相关联的表中获取数据。在 MySQL 中,实现多表查询主要有以下几种方式:

多表关系

1. 一对一关系(One-to-One)

  • 特点:两个表中的记录一一对应,一个表的一条记录只能与另一个表的一条记录关联。

  • 适用场景:常用于拆分表结构(如将用户基本信息和详细信息分开存储),或关联具有强归属关系的数据。

  • 实现方式:在任意一个表中添加外键,关联另一个表的主键,并设置外键为唯一(UNIQUE)。

-- 示例:用户表(基本信息)
CREATE TABLE users (id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(50) UNIQUE NOT NULL,email VARCHAR(100) UNIQUE NOT NULL
);
​
-- 用户详情表(一对一关联 users 表)
CREATE TABLE user_profiles (id INT PRIMARY KEY AUTO_INCREMENT,user_id INT UNIQUE NOT NULL, -- 唯一外键,确保一对一real_name VARCHAR(50),phone VARCHAR(20),FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

2. 一对多关系(One-to-Many)

  • 特点:一个表中的一条记录可以对应另一个表中的多条记录,但反向只能对应一条。

  • 适用场景:最常见的关系(如 “部门 - 员工”“订单 - 订单项”)。

  • 实现方式:在 “多” 的一方添加外键,关联 “一” 的一方的主键。

-- 示例:部门表(一的一方)
CREATE TABLE departments (id INT PRIMARY KEY AUTO_INCREMENT,dept_name VARCHAR(50) NOT NULL
);
​
-- 员工表(多的一方,关联部门表)
CREATE TABLE employees (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50) NOT NULL,dept_id INT, -- 外键关联部门表FOREIGN KEY (dept_id) REFERENCES departments(id) ON DELETE SET NULL
);

3. 多对多关系(Many-to-Many)

  • 特点:两个表中的记录可以互相对应多条记录(如 “学生 - 课程”:一个学生可选多门课,一门课可被多个学生选)。

  • 适用场景:需要双向一对多的业务关系。

  • 实现方式:通过中间表关联两个表,中间表至少包含两个外键,分别指向两个表的主键。

-- 示例:学生表
CREATE TABLE students (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50) NOT NULL
);
​
-- 课程表
CREATE TABLE courses (id INT PRIMARY KEY AUTO_INCREMENT,course_name VARCHAR(100) NOT NULL
);
​
-- 中间表(关联学生和课程,实现多对多)
CREATE TABLE student_courses (id INT PRIMARY KEY AUTO_INCREMENT,student_id INT NOT NULL,course_id INT NOT NULL,-- 联合唯一约束,避免重复关联UNIQUE KEY (student_id, course_id),FOREIGN KEY (student_id) REFERENCES students(id) ON DELETE CASCADE,FOREIGN KEY (course_id) REFERENCES courses(id) ON DELETE CASCADE
);

关系设计的注意事项

  1. 外键约束

    强制关联关系,可选参数:

    • ON DELETE CASCADE:主表记录删除时,从表关联记录也删除

    • ON DELETE SET NULL:主表记录删除时,从表外键设为 NULL(需外键允许 NULL

  2. 避免循环依赖:多表关联时避免形成闭环(如 A 依赖 B,B 依赖 C,C 依赖 A),可能导致数据操作异常。

  3. 中间表设计:多对多的中间表可额外添加字段(如 “学生选课表” 可加 score 字段记录成绩)。

1. 交叉连接(CROSS JOIN)

返回两个表的笛卡尔积(所有可能的组合),通常需要配合 WHERE 条件过滤无意义的记录。

-- 语法
SELECT 列名 FROM 表1 CROSS JOIN 表2 [WHERE 条件];
​
-- 示例:查询学生和他们的课程(未过滤前是所有学生与所有课程的组合)
SELECT students.name, courses.course_name
FROM students CROSS JOIN courses
WHERE students.id = courses.student_id; -- 过滤出有效的关联记录

2. 内连接(INNER JOIN)

只返回两个表中满足连接条件的记录(即匹配的记录),是最常用的连接方式。

-- 语法
SELECT 列名 FROM 表1 INNER JOIN 表2 ON 连接条件;-- 示例:查询学生及其选修的课程(只显示有选课记录的学生)
SELECT students.name, courses.course_name
FROM students
INNER JOIN courses ON students.id = courses.student_id;

3. 外连接(OUTER JOIN)

返回一个表的所有记录,以及另一个表中满足条件的匹配记录。外连接分为:

  • 左外连接(LEFT JOIN / LEFT OUTER JOIN):返回左表所有记录 + 右表匹配记录

  • 右外连接(RIGHT JOIN / RIGHT OUTER JOIN):返回右表所有记录 + 左表匹配记录

  • 全外连接(FULL JOIN):返回两个表的所有记录(MySQL 不直接支持,需用 UNION 模拟)

-- 左外连接示例:查询所有学生及其选修的课程(包括未选课的学生)
SELECT students.name, courses.course_name
FROM students
LEFT JOIN courses ON students.id = courses.student_id;
​
-- 右外连接示例:查询所有课程及选修该课程的学生(包括无学生选修的课程)
SELECT students.name, courses.course_name
FROM students
RIGHT JOIN courses ON students.id = courses.student_id;

4. 自连接(SELF JOIN)

将表与自身进行连接,通常用于查询表中具有层级或关联关系的数据(如员工与上司)。

-- 示例:查询员工及其直属上司的姓名(假设 employees 表中有 manager_id 关联上司ID)
SELECT e.name AS 员工, m.name AS 上司
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id;

5. 联合查询(UNION / UNION ALL)

用于合并多个 SELECT 语句的结果集,要求列数和数据类型一致。

  • UNION:去除重复记录

  • UNION ALL:保留所有记录(包括重复)

-- 示例:合并两个查询结果(查询10岁以下和20岁以上的学生)
SELECT name, age FROM students WHERE age < 10
UNION
SELECT name, age FROM students WHERE age > 20;

子查询(Subquery)是嵌套在另一个 SQL 语句中的查询,也称为内部查询,而包含子查询的语句称为外部查询。子查询通常用于为主查询提供数据或条件,可使复杂查询逻辑更清晰。

子查询的基本特点

  • 子查询必须用括号 () 包裹

  • 子查询通常放在 WHEREFROMSELECT 子句中

  • 子查询的结果可以是单个值、一行、一列或多行

常见子查询类型及示例

1. 返回单个值的子查询(标量子查询)

常用于 WHERE 子句中,配合比较运算符(=, >, <, >=, <= 等)使用。

-- 示例:查询与"张三"同龄的学生
SELECT name, age 
FROM students 
WHERE age = (SELECT age FROM students WHERE name = '张三');
2. 返回一列值的子查询(列子查询)

通常与 INNOT INANYALL 等关键字配合使用

-- 示例1:查询选修了"数学"课程的学生(使用IN)
SELECT name 
FROM students 
WHERE id IN (SELECT student_id FROM courses WHERE course_name = '数学'
);
​
-- 示例2:查询年龄大于所有女生的男生(使用ALL)
SELECT name, age 
FROM students 
WHERE gender = '男' AND age > ALL (SELECT age FROM students WHERE gender = '女');
3. 返回多行多列的子查询(表子查询)

可作为一个临时表,用于 FROM 子句中(通常需要起别名)。

-- 示例:查询每个班级的平均年龄及班级信息
SELECT classes.class_name, avg_ages.avg_age
FROM classes
JOIN (SELECT class_id, AVG(age) AS avg_age FROM students GROUP BY class_id
) AS avg_ages ON classes.id = avg_ages.class_id;
4. EXISTS 子查询

用于判断子查询是否返回结果,返回 TRUEFALSE,不关心具体数据。

-- 示例:查询有选修课程的学生(存在选课记录)
SELECT name 
FROM students s 
WHERE EXISTS (SELECT 1 FROM courses c WHERE c.student_id = s.id
);
5. 嵌套子查询

子查询中可以再包含子查询,形成多层嵌套(但建议层数不宜过多,以免影响性能)。

-- 示例:查询选修了"张三"所选全部课程的学生
SELECT DISTINCT s.name
FROM students s
JOIN courses c ON s.id = c.student_id
WHERE c.course_name IN (SELECT course_name FROM courses WHERE student_id = (SELECT id FROM students WHERE name = '张三')
)
GROUP BY s.name
HAVING COUNT(c.course_name) = (SELECT COUNT(*) FROM courses WHERE student_id = (SELECT id FROM students WHERE name = '张三')
);

子查询的注意事项

  1. 性能问题:复杂子查询可能影响效率,可尝试用 JOIN 改写(部分场景下 JOIN 性能更优)。

  2. 关联子查询与非关联子查询

    • 非关联子查询:独立于外部查询,只执行一次

    • 关联子查询:依赖外部查询的字段,可能执行多次(每行一次)

  3. SELECT 子句中的子查询:只能返回单个值,用于为结果集增加计算列。

多表查询的注意事项

  1. 表别名:使用 AS 为表起别名(可省略 AS),简化 SQL 语句。

  2. 列名冲突:当多表中有同名列时,需用 表名.列名别名.列名 区分(如 students.id)。

  3. 性能优化:对连接条件中的列建立索引,避免不必要的 SELECT *,减少数据扫描量。

四. 事务

在 MySQL 中,事务(Transaction)是一组数据库操作的集合,这些操作要么全部成功执行,要么全部失败回滚,以此保证数据的一致性和完整性。事务是数据库管理系统(DBMS)处理并发操作和故障恢复的核心机制。

MySQL 事务的 ACID 特性

事务必须满足以下四个基本特性,即 ACID 特性

  1. 原子性(Atomicity) 事务中的所有操作要么全部执行成功,要么全部失败回滚(Rollback),不会出现部分执行的情况。 例如:转账操作中,“A 账户扣款” 和 “B 账户到账” 必须同时成功或同时失败。

  2. 一致性(Consistency) 事务执行前后,数据库从一个一致的状态转变为另一个一致的状态,数据规则(如约束、逻辑关系)不会被破坏。 例如:转账前后,A 和 B 的账户总金额保持不变。

  3. 隔离性(Isolation) 多个事务并发执行时,一个事务的操作不会被其他事务干扰,各事务之间相互隔离。 MySQL 通过隔离级别控制并发事务的交互程度(见下文)。

  4. 持久性(Durability) 事务一旦提交(Commit),其对数据的修改会永久保存到数据库中,即使系统崩溃也不会丢失。

MySQL 事务的操作语法

MySQL 中,事务的基本操作通过以下 SQL 命令实现:

  1. 开启事务 关闭自动提交模式,后续操作将纳入事务管理:

    START TRANSACTION;  -- 或 BEGIN;
  2. 执行操作 执行一系列 SQL 语句(如 INSERT、UPDATE、DELETE 等):

    UPDATE accounts SET balance = balance - 100 WHERE id = 1;  -- A账户扣款
    UPDATE accounts SET balance = balance + 100 WHERE id = 2;  -- B账户到账
  3. 提交事务 确认所有操作成功,将修改永久保存到数据库:

    COMMIT;
  4. 回滚事务 若操作失败,撤销所有已执行的修改,恢复到事务开始前的状态:

    ROLLBACK;
  5. 设置保存点(可选) 在事务中设置中间点,可回滚到指定保存点(而非整个事务):

    SAVEPOINT sp1;  -- 创建保存点 sp1
    ROLLBACK TO sp1;  -- 回滚到 sp1

MySQL 事务的隔离级别

多个事务并发执行时,可能出现 脏读不可重复读幻读 等问题。MySQL 定义了四种隔离级别(从低到高),用于平衡隔离性和并发性能:

  1. 读未提交(READ UNCOMMITTED) 最低隔离级别,一个事务可读取另一个未提交的修改。可能导致 脏读(读取到未提交的无效数据)。

  2. 读已提交(READ COMMITTED) 一个事务只能读取另一个已提交的修改,避免 脏读,但可能出现 不可重复读(同一事务中多次读取同一数据,结果不一致)。 这是大多数数据库的默认级别(如 Oracle)。

  3. 可重复读(REPEATABLE READ) MySQL 的默认隔离级别。保证同一事务中多次读取同一数据的结果一致,避免 脏读不可重复读,但可能出现 幻读(事务执行中,其他事务新增的数据被读取到)。

  4. 串行化(SERIALIZABLE) 最高隔离级别,强制事务串行执行(类似单线程),避免所有并发问题,但性能最差。

查看和设置隔离级别

  • 查看当前隔离级别

    -- 查看全局隔离级别
    SELECT @@GLOBAL.transaction_isolation;
    -- 查看当前会话隔离级别
    SELECT @@SESSION.transaction_isolation;
  • 设置隔离级别(需有足够权限):

    -- 设置全局隔离级别(对新会话生效)
    SET GLOBAL transaction_isolation = 'READ COMMITTED';
    -- 设置当前会话隔离级别
    SET SESSION transaction_isolation = 'REPEATABLE READ';

注意事项

  1. 存储引擎支持:MySQL 中,只有 InnoDB 存储引擎支持事务,MyISAM 等引擎不支持。

  2. 自动提交:MySQL 默认开启 AUTOCOMMIT=1(每条 SQL 自动作为一个事务提交),开启事务后需手动提交或回滚。

  3. 锁机制:事务的隔离性通过 InnoDB 的锁机制(如行锁、表锁)和 MVCC(多版本并发控制)实现。

http://www.dtcms.com/a/296762.html

相关文章:

  • JavaScript 入门教程
  • 【MySQL】MySQL 事务和锁详解
  • Linux应用开发基础知识——进程学习2(exec函数、system函数、popen函数)(三)
  • C语言:20250724笔记(函数-指针)
  • S7-200 SMART 编程基础详解:从语言、数据结构到寻址方式
  • Spring Bean生命周期七步曲:定义、实例化、初始化、使用、销毁
  • C语言(十)
  • 面试150 寻找峰值
  • Leetcode-.42接雨水
  • 【Linux基础知识系列】第六十四篇 - 了解Linux的硬件架构
  • 【学习】数字化车间与智能工厂如何推进制造业转型
  • 放款需要注意的事项
  • C++实战:人脸识别7大核心实例
  • 【Java】空指针(NullPointerException)异常深度攻坚:从底层原理到架构级防御,老司机的实战经验
  • 网络测试工具
  • UE 加载本地Json文件
  • 【Servo】裸机还是RTOS驱动架构如何选?
  • C++核心编程学习--对象特性--对象的初始化和清理
  • MCU(微控制器)中的高电平与低电平?
  • 基于LiteOS的OTA组件实现对终端固件的差分升级和全量升级
  • Rust与YOLO目标检测实战
  • 【redis其它面试问题】
  • 【OD机试】矩阵匹配
  • JavaScript高级特性与优化全解析
  • JManus Plan-Act模式:如何对用户的需求进行规划和执行
  • 【第五节】列表渲染
  • p5.js 椭圆的用法:从基础到创意应用
  • Java 实现 B/S 架构详解:从基础到实战,彻底掌握浏览器/服务器编程
  • 北京-4年功能测试2年空窗-报培训班学测开-第五十九天-模拟面试前
  • 前端学习日记(十二)