【MySQL数据库】CRUD 增 删 改 查 超详解,有这一篇就够了!

 🔥个人主页: 中草药

🔥专栏:【MySQL】探秘:数据库世界的瑞士军刀


目录

⚗️一.CRUD

🧪二.新增(Create)

🧫1.基本操作

🧬2.使用SELECT插入

🔬3.总结

🔭三.查询(Retrieve) (重点)*

📡1.基本查询

🍇2.别名

🍈3.条件查询

3.1.比较运算符

3.2逻辑运算符

3.3案例

🍉4.排序查询

🍊5.去重查询

 🍋6.分页查询

🍌 7.聚合查询*

7.1聚合函数

7.3 GROUP BY子句

7.4 HAVING子句

7.5 WITH ROLLUP

🥭 8.关联查询

8.1 关联条件与笛卡尔积

 8.2 内连接(INNER JOIN)

8.3 外连接 

🍍9.合并查询

9.1. UNION

9.2. UNION ALL

🍎10.子查询(了解)

🍒四. 修改(Update)

🍓1.基本操作

🫐2. 修改表结构(ALTER TABLE)

🥝3.注意事项

🍅五. 删除(Delete)

💐1.基本操作 

🌸2.快速清空表(TRUNCATE)

🍀3. 删除表或数据库对象(DROP)

🧬4.注意事项

🪥六.约束条件

🧽1.非空约束 (NOT NULL)

🧻2.唯一约束 (UNIQUE)

🪣3.主键约束 (PRIMARY KEY)

🫧4.外键约束 (FOREIGN KEY)

🛒5.检查约束 (CHECK - MySQL 8.0.16及以上版本支持)--了解

🪤七.总结与反思


⚗️一.CRUD

        MySQL的CRUD操作指的是数据库操作中的四个基本动作:Create(创建)、Read(读取)、Update(更新)和Delete(删除)。这些操作构成了数据库管理系统中最核心的数据操作集合,用于管理关系型数据库中的记录。

        CRUD操作是数据库管理的基础,它们共同构成了数据生命周期管理的闭环,从数据的产生到数据的最终废弃,每一步都离不开这四个操作。它们的重要性在于:

  • 灵活性:使得数据库能够适应不断变化的数据需求,支持动态数据管理。
  • 数据完整性:通过精确的增删改查操作,维护数据库数据的准确性与一致性。
  • 性能优化:合理的CRUD操作策略可以提升查询速度,减少资源消耗,优化数据库性能。
  • 数据安全:通过权限控制CRUD操作,确保数据的访问和修改符合安全策略。

在MySQL中,通过优化CRUD操作的执行效率和安全性,可以极大地提升数据库应用的性能和用户体验。

注释:在SQL中可以使用“--空格+描述”来表示注释说明

🧪二.新增(Create

        在MySQL中,"新增操作"通常指的是向数据库中插入新的记录,这主要通过INSERT语句来完成。新增操作是数据库管理中的基本操作之一,对于维护和更新数据库内容至关重要。以下是关于MySQL中新增操作的一些关键点和示例:

🧫1.基本操作

--插入单行数据
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);

--插入多行数据
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...),
       (value4, value5, value6, ...),
       (...);
  • table_name是要插入数据的表的名称。
  • (column1, column2, column3, ...)是表中的列名列表,列出你要插入数据的列。这可以省略,如果你插入所有列的值,并且顺序与表定义一致。
  • (value1, value2, value3, ...)是你希望插入的具体值,与列名一一对应。

举例:

-- 创建一张学生表
drop table if exist student;
create table student (
   id int,
   sn int comment '学号',
   name varchar(20) comment '姓名',
   qq_mail varchar(20) comment 'QQ邮箱'
);

-- 单行数据+全列插入  插入两条记录,value_list 数量必须和定义表的列的数量及顺序一致
insert into student values (100, 10000, '唐三藏', NULL);
insert into student values (101, 10001, '孙悟空', '11111');

-- 多行数据+指定列插入  插入两条记录,value_list 数量必须和指定列数量及顺序一致
insert into student (id, sn, name) values
 (102, 20001, '曹孟德'),
 (103, 20002, '孙仲谋');

🧬2.使用SELECT插入

你还可以从另一个查询的结果插入数据,这在复制表数据或更新表结构时特别有用:

INSERT INTO table_name (column1, column2, column3, ...)
SELECT columnA, columnB, columnC, ...
FROM source_table
WHERE some_condition;

🔬3.总结

        新增操作在MySQL中是数据录入和数据库内容管理的核心部分,它支持数据库的动态增长和数据的实时更新。通过灵活运用INSERT语句的各种形式,开发者可以高效地实现数据的批量插入、条件插入和冲突处理,满足不同场景下的数据管理需求。

🔭三.查询(Retrieve (重点)*

        MySQL中的查询操作主要通过SQL语言中的SELECT语句来实现,这是数据查询语言(DQL)的一部分,用于从数据库中检索数据。查询操作是数据库管理中最频繁使用的功能之一,它支持从简单的数据检索到复杂的分析和数据汇总。以下是MySQL中查询操作的几个关键方面和示例:

📡1.基本查询

--单表查询
SELECT column1, column2
FROM table_name;

--全列查询
SELECT *
FROM table_name;
  • column1, column2是要选择的列名。
  • table_name是查询的表名。
  • *表示选择所有列。
  • 通常情况下不建议使用 * 进行全列查询
    -- 1. 查询的列越多,意味着需要传输的数据量越大;
    -- 2. 可能会影响到索引的使用。(索引待后面博客讲解)

举例

-- 创建考试成绩表
DROP TABLE IF EXISTS exam_result;
CREATE TABLE exam_result (
 id INT,
 name VARCHAR(20),
 chinese DECIMAL(3,1),
 math DECIMAL(3,1),
 english DECIMAL(3,1)
);

-- 插入测试数据
INSERT INTO exam_result (id,name, chinese, math, english) VALUES
 (1,'唐三藏', 67, 98, 56),
 (2,'孙悟空', 87.5, 78, 77),
 (3,'猪悟能', 88, 98.5, 90),
 (4,'曹孟德', 82, 84, 67),
 (5,'刘玄德', 55.5, 85, 45),
 (6,'孙权', 70, 73, 78.5),
 (7,'宋公明', 75, 65, 30);
查询字段为表达式
-- 表达式不包含字段
SELECT id, name, 10 FROM exam_result;
-- 表达式包含一个字段
SELECT id, name, english + 10 FROM exam_result;
-- 表达式包含多个字段
SELECT id, name, chinese + math + english FROM exam_resul

🍇2.别名

为查询结果中的列指定别名,表示返回的结果集中,以别名作为该列的名称,语法
SELECT column [AS] alias_name [...] FROM table_name

🍈3.条件查询

使用WHERE子句根据条件筛选数据:

SELECT column1, column2
FROM table_name
WHERE condition;

condition是筛选条件,如column1 = 'value'

3.1.比较运算符

运算符
说明
>, >=, <, <=大于,大于等于,小于,小于等于
=等于,NULL 不安全,例如 NULL = NULL 的结果是 NULL
<=>等于,NULL 安全,例如 NULL <=> NULL 的结果是 TRUE(1)
!=, <>不等于
BETWEEN a0 AND a1范围匹配,[a0, a1],如果 a0 <= value <= a1,返回 TRUE(1)
IN (option, ...)如果是 option 中的任意一个,返回 TRUE(1)
IS NULL NULL
IS NOT NULL不是 NULL
LIKE
模糊匹配。 % 表示任意多个(包括 0 个)任意字符; _ 表示任意一个字符

3.2逻辑运算符

运算符
说明
AND
多个条件必须都为 TRUE(1),结果才是 TRUE(1)
OR任意一个条件为 TRUE(1), 结果为 TRUE(1)
NOT条件为 TRUE(1),结果为 FALSE(0)

3.3案例

ANDOR
-- 查询语文成绩大于80分,且英语成绩大于80分的同学
SELECT * FROM exam_result WHERE chinese > 80 and english > 80;

-- 查询语文成绩大于80分,或英语成绩大于80分的同学
SELECT * FROM exam_result WHERE chinese > 80 or english > 80;

-- 观察AND 和 OR 的优先级:
SELECT * FROM exam_result WHERE chinese > 80 or math>70 and english > 70;
SELECT * FROM exam_result WHERE (chinese > 80 or math>70) and english > 70;
 BETWEEN ... AND ...:
-- 查询语文成绩在 [80, 90] 分的同学及语文成绩
SELECT name, chinese FROM exam_result WHERE chinese BETWEEN 80 AND 90;

-- 使用 AND 也可以实现
SELECT name, chinese FROM exam_result WHERE chinese >= 80 AND chinese 
<= 90;

 IN :

-- 查询数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩
SELECT name, math FROM exam_result WHERE math IN (58, 59, 98, 99);

-- 使用 OR 也可以实现
SELECT name, math FROM exam_result WHERE math = 58 OR math = 59 OR math 
= 98 OR math = 99;
模糊查询:LIKE :
-- % 匹配任意多个(包括 0 个)字符
SELECT name FROM exam_result WHERE name LIKE '孙%';-- 匹配到孙悟空、孙权

-- _ 匹配严格的一个任意字符
SELECT name FROM exam_result WHERE name LIKE '孙_';-- 匹配到孙权
NULL 的查询:IS [NOT] NULL
-- 查询 qq_mail 已知的同学姓名
SELECT name, qq_mail FROM student WHERE qq_mail IS NOT NULL;

-- 查询 qq_mail 未知的同学姓名
SELECT name, qq_mail FROM student WHERE qq_mail IS NULL;

🍉4.排序查询

使用ORDER BY子句对结果排序:

SELECT column1, column2
FROM table_name
ORDER BY column1 ASC|DESC;

ASC升序,DESC降序,且默认为升序。

NULL 数据排序,视为比任何值都小,升序出现在最上面,降序出现在最下面

使用表达式别名排序 

-- 查询同学及总分,由高到低
SELECT name, chinese + english + math FROM exam_result 
 ORDER BY chinese + english + math DESC;
SELECT name, chinese + english + math total FROM exam_result 
 ORDER BY total DESC;

可以对多个字段进行排序,排序优先级随书写顺序 

-- 查询同学各门成绩,依次按 数学降序,英语升序,语文升序的方式显示
SELECT name, math, english, chinese FROM exam_result 
 ORDER BY math DESC, english, chinese;

🍊5.去重查询

使用DISTINCT关键字对某列数据进行去重

-- 98 分重复了
SELECT math FROM exam_result;
+--------+
| math |
+--------+
|     98 |
|     78 |
|     98 |
|     84 |
|     85 |
|     73 |
|     65 |
+--------+
7 rows in set (0.00 sec)

-- 去重结果
SELECT DISTINCT math FROM exam_result;
+--------+
| math |
+--------+
|     98 |
|     78 |
|     84 |
|     85 |
|     73 |
|     65 |
+--------+
6 rows in set (0.00 sec)

 🍋6.分页查询

使用 LIMIT 关键字对某列数据进行去重

语法:

-- 起始下标为 0

-- 从 0 开始,筛选 n 条结果
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n;

-- 从 s 开始,筛选 n 条结果
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT s, n;

-- 从 s 开始,筛选 n 条结果,比第二种用法更明确,建议使用
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n OFFSET s;

案例:按 id 进行分页,每页 3 条记录,分别显示 第 123

-- 第 1 页
SELECT id, name, math, english, chinese FROM exam_result ORDER BY id LIMIT 3
OFFSET 0;

-- 第 2 页
SELECT id, name, math, english, chinese FROM exam_result ORDER BY id LIMIT 3
OFFSET 3;

-- 第 3 页,如果结果不足 3 个,不会有影响
SELECT id, name, math, english, chinese FROM exam_result ORDER BY id LIMIT 3
OFFSET 6

🍌 7.聚合查询*

7.1聚合函数

函数
说明
COUNT([DISTINCT] expr)返回查询到的数据的 数量
SUM([DISTINCT] expr)返回查询到的数据的 总和,不是数字没有意义
AVG([DISTINCT] expr)
返回查询到的数据的 平均值,不是数字没有意义
MAX([DISTINCT] expr)返回查询到的数据的 最大值,不是数字没有意义
MIN([DISTINCT] expr)返回查询到的数据的 最小值,不是数字没有意义

举例

count 

-- 统计班级共有多少同学
SELECT COUNT(*) FROM student;

-- 统计班级收集的 qq_mail 有多少个,qq_mail 为 NULL 的数据不会计入结果
SELECT COUNT(qq_mail) FROM student;

sum 

-- 统计数学成绩总分
SELECT SUM(math) FROM exam_result;

-- 不及格 < 60 的总分,没有结果,返回 NULL
SELECT SUM(math) FROM exam_result WHERE math < 60;

avg 

-- 统计平均总分
SELECT AVG(chinese + math + english) 平均总分 FROM exam_result;

max 

-- 返回英语最高分
SELECT MAX(english) FROM exam_result;

min 

-- 返回 > 70 分以上的数学最低分
SELECT MIN(math) FROM exam_result WHERE math > 70;

7.3 GROUP BY子句

  • 作用:将结果集按照一个或多个列进行分组,每个组内可以应用聚合函数进行统计计算。
  • 语法GROUP BY column1, column2,...

举例

-- 准备测试表及数据:职员表,有id(主键)、name(姓名)、role(角色)、salary(薪水)
create table emp(
 id int primary key auto_increment,
 name varchar(20) not null,
 role varchar(20) not null,
 salary numeric(11,2)
);

insert into emp(name, role, salary) values
('马云','服务员', 1000.20),
('马化腾','游戏陪玩', 2000.99),
('孙悟空','游戏角色', 999.11),
('猪无能','游戏角色', 333.5),
('沙和尚','游戏角色', 700.33),
('隔壁老王','董事长', 12000.66);


-- 查询每个角色的最高工资、最低工资和平均工资
select role,max(salary),min(salary),avg(salary) from emp group by role;

7.4 HAVING子句

  • 作用:对GROUP BY产生的结果进行过滤,类似于WHERE子句,但HAVING作用于分组后的数据。
  • 语法HAVING condition

举例

select role,max(salary),min(salary),avg(salary) from emp group by role 
having avg(salary)<1500;

7.5 WITH ROLLUP

  • 作用:在聚合查询的结果集中额外添加一行,显示所有分组的汇总信息。
  • 语法:在GROUP BY子句末尾加上WITH ROLLUP

举例

mysql> select role, sum(salary) from emp group by role with rollup;

+--------------+-------------+
| role         | sum(salary) |
+--------------+-------------+
| 服务员       |     1000.20 |
| 游戏角色     |     2032.94 |
| 游戏陪玩     |     2000.99 |
| 董事长       |    12000.66 |
| NULL         |    17034.79 |
+--------------+-------------+
5 rows in set (0.00 sec)

🥭 8.关联查询

        关联查询是MySQL中一种重要的查询技术,它允许用户从两个或多个表中同时检索数据,基于这些表之间的某种关联关系。关联查询通常使用 JOIN 语句来完成,通过指定关联条件来确保从不同表中取出的数据行是相互匹配的。下面是关联查询的一些关键概念和类型:

8.1 关联条件与笛卡尔积

        在进行关联查询之前,了解笛卡尔积是很重要的。如果在关联查询中没有指定正确的关联条件,MySQL会执行一个笛卡尔积操作,即将第一个表的每一行与第二个表的每一行进行配对,生成的结果集大小将是两个表行数的乘积。在大多数情况下,这样的结果是没有意义的,因此我们需要通过关联条件来限制结果集,使其只包含有意义的匹配行。

 8.2 内连接(INNER JOIN)

        只返回两个表中匹配的行。如果在一个表中的某行在另一个表中找不到匹配,那么这行不会出现在结果集中。

举例

insert into classes(name, descri) values
('计算机系2019级1班', '学习了计算机原理、C和Java语言、数据结构和算法'),
('中文系2019级3班','学习了中国传统文学'),
('自动化2019级5班','学习了机械自动化');

insert into student(sn, name, qq_mail, classes_id, id) values
('09982','黑旋风李逵','xuanfeng@qq.com',1,1),
('00835','菩提老祖',null,1,2),
('00391','白素贞',null,1,3),
('00031','许仙','xuxian@qq.com',1,4),
('00054','不想毕业',null,1,5),
('51234','好好说话','say@qq.com',2,6),
('83223','tellme',null,2,7);

insert into course values
('Java'),('中国传统文化'),('计算机原理'),('语文'),('高阶数学'),('英文');

insert into score(score, student_id, course_id) values
-- 黑旋风李逵
(70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6),
-- 菩提老祖
(60, 2, 1),(59.5, 2, 5),
-- 白素贞
(33, 3, 1),(68, 3, 3),(99, 3, 5),
-- 许仙
(67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6),
-- 不想毕业
(81, 5, 1),(37, 5, 5),
-- 好好说话
(56, 6, 2),(43, 6, 4),(79, 6, 6),
-- tellme
(80, 7, 2),(92, 7, 6);
-- 查询许仙同学的成绩
 select sco.course_id,sco.score from student stu inner join score sco on stu.id=sco.student_id and stu.name='许仙';
+-----------+-------+
| course_id | score |
+-----------+-------+
|        1  |  67.0 |
|        3  |  23.0 |
|        5  |  56.0 |
|        6  |  72.0 |
+----------+-------+
 -- 成绩表对学生表是多对1关系,查询总成绩是根据成绩表的同学id来进行分组的
SELECT stu.sn, stu.NAME, stu.qq_mail, sum( sco.score )
 FROM student stu join score sco 
ON stu.id = sco.student_id GROUP BY sco.student_id;
+-------+-----------------+-----------------+------------------+
| sn    | NAME            | qq_mail         | sum( sco.score ) |
+-------+-----------------+-----------------+------------------+
|  9982 | 黑旋风李逵      | xuanfeng@qq.com |            300.0 |
|   835 | 菩提老祖        | NULL            |            119.5 |
|   391 | 白素贞          | NULL            |            200.0 |
|    31 | 许仙            | xuxian@qq.com   |            218.0 |
|    54 | 不想毕业        | NULL            |            118.0 |
| 51234 | 好好说话        | say@qq.com      |            178.0 |
| 83223 | tellme          | NULL            |            172.0 |
+-------+-----------------+-----------------+------------------+

8.3 外连接 

  1. 左连接 (LEFT JOIN) / 左外连接: 返回左表的所有行,即使在右表中没有匹配。如果右表中没有匹配,则结果集中右表的部分将包含NULL值。
  2. 右连接 (RIGHT JOIN) / 右外连接: 与左连接相反,返回右表的所有行,即使在左表中没有匹配。左表中没有匹配的行将以NULL值填充。
  3. 全连接 (FULL JOIN) / 全外连接: 返回左表和右表中的所有行。如果某一边没有匹配,则另一边的对应值为NULL。需要注意的是,MySQL本身不直接支持 FULL JOIN,但可以通过 LEFT JOIN 和 UNION 或其他技巧来模拟。
-- 左外连接,表1完全显示
select 字段名  from 表名1 left join 表名2 on 连接条件;

-- 右外连接,表2完全显示
select 字段 from 表名1 right join 表名2 on 连接条件;

举例 

-- “老外学中文”同学 没有考试成绩,也显示出来了
select * from student stu left join score sco on stu.id=sco.student_id;

-- 对应的右外连接为:
select * from score sco right join student stu on stu.id=sco.student_id;

+-------+-----------------+-----------------+------------+------+-------+------------+----------+
| sn    | name            | qq_mail         | classes_id | id   | score | student_id | couse_id |
+-------+-----------------+-----------------+------------+------+-------+------------+----------+
|  9982 | 黑旋风李逵      | xuanfeng@qq.com |          1 |    1 |  70.5 |          1 |        1 |
|  9982 | 黑旋风李逵      | xuanfeng@qq.com |          1 |    1 |  98.5 |          1 |        3 |
|  9982 | 黑旋风李逵      | xuanfeng@qq.com |          1 |    1 |  33.0 |          1 |        5 |
|  9982 | 黑旋风李逵      | xuanfeng@qq.com |          1 |    1 |  98.0 |          1 |        6 |
|   835 | 菩提老祖        | NULL            |          1 |    2 |  60.0 |          2 |        1 |
|   835 | 菩提老祖        | NULL            |          1 |    2 |  59.5 |          2 |        5 |
|   391 | 白素贞          | NULL            |          1 |    3 |  33.0 |          3 |        1 |
|   391 | 白素贞          | NULL            |          1 |    3 |  68.0 |          3 |        3 |
|   391 | 白素贞          | NULL            |          1 |    3 |  99.0 |          3 |        5 |
|    31 | 许仙            | xuxian@qq.com   |          1 |    4 |  67.0 |          4 |        1 |
|    31 | 许仙            | xuxian@qq.com   |          1 |    4 |  23.0 |          4 |        3 |
|    31 | 许仙            | xuxian@qq.com   |          1 |    4 |  56.0 |          4 |        5 |
|    31 | 许仙            | xuxian@qq.com   |          1 |    4 |  72.0 |          4 |        6 |
|    54 | 不想毕业        | NULL            |          1 |    5 |  81.0 |          5 |        1 |
|    54 | 不想毕业        | NULL            |          1 |    5 |  37.0 |          5 |        5 |
| 51234 | 好好说话        | say@qq.com      |          2 |    6 |  56.0 |          6 |        2 |
| 51234 | 好好说话        | say@qq.com      |          2 |    6 |  43.0 |          6 |        4 |
| 51234 | 好好说话        | say@qq.com      |          2 |    6 |  79.0 |          6 |        6 |
| 83223 | tellme          | NULL            |          2 |    7 |  80.0 |          7 |        2 |
| 83223 | tellme          | NULL            |          2 |    7 |  92.0 |          7 |        6 |
+-------+-----------------+-----------------+------------+------+-------+------------+----------+

🍍9.合并查询

        在MySQL中,合并查询通常指的是使用 UNIONUNION ALL 操作符来组合多个 SELECT 语句的结果,从而生成一个统一的结果集。这两种操作提供了灵活的方式来整合不同查询的数据,适用于多种场景,比如报表生成、数据分析等。下面是对这两种合并查询方式的详细说明:

9.1. UNION

UNION 操作符用于合并两个或多个 SELECT 语句的结果集,同时自动去除结果中的重复行。使用 UNION 时,需注意以下几点:

  • 列数相同:所有参与合并的 SELECT 语句必须返回相同数量的列。
  • 列类型兼容:虽然列不需要严格相同类型,但它们之间应能进行类型转换,以便比较和去重。
  • 列顺序一致:各 SELECT 语句中的列顺序需要保持一致。
  • 结果排序与去除重复:MySQL 自动对最终结果进行排序并去除完全相同的行。
  • 列名继承:结果集的列名通常取自第一个 SELECT 语句中指定的列名。
select * from course where id<3
union
select * from course where name='英文';

-- 或者使用or来实现
select * from course where id<3 or name='英文';

9.2. UNION ALL

UNION 类似,UNION ALL 也是用来合并多个 SELECT 语句的结果集,但不同之处在于,UNION ALL 不会去除重复的行,也不会对结果集进行排序,因此它通常比 UNION 执行得更快,尤其是在处理大量数据时。

  • 保留所有行:包括重复行,不进行去重。
  • 效率更高:因为省去了去重和排序的过程,所以性能通常优于 UNION
-- 可以看到结果集中出现重复数据
select * from course where id<3
union all
select * from course where name='英文';

注意事项

  • 性能考量:当确知结果集中不会有重复行或不需要去重时,使用 UNION ALL 可以提高查询性能。
  • 排序与限制:如果需要对最终结果进行排序或限制返回的行数,可以使用 ORDER BY 和 LIMIT 子句,但它们必须放在所有 UNION/UNION ALL 子句之后。
  • 索引与优化:对于大型查询,考虑对涉及的列添加索引,以及合理安排 JOIN 和 WHERE 条件,以进一步优化性能。

通过灵活运用 UNIONUNION ALL,你可以有效地整合数据,满足复杂的数据分析和报告需求。

🍎10.子查询(了解)

子查询是指嵌入在其他 sql 语句中的 select 语句,也叫嵌套查询
单行子查询:返回一行记录的子查询
--查询与“李青” 同学的同班同学
select * from student where 
class_id=(select class_id from student where name ='李青');

多行子查询:返回多行记录的子查询

-- 查询'语文'或'英语'的成绩

-- 使用 IN
select * from score where course_id in (select id from course where
name='语文' or name='英文');

-- 使用 NOT IN
select * from score where course_id not in (select id from course where
name!='语文' and name!='英文');

尽管子查询在MySQL中提供了一种强大的方式来处理复杂的数据检索和分析,但它们也伴随着一些弊端,主要体现在性能和可读性方面:

  1. 性能问题:

    • 资源消耗:执行子查询时,MySQL可能需要创建临时表来存储子查询的结果,这涉及到内存和磁盘I/O的消耗。一旦查询完成,这些临时表会被销毁,这个过程会增加额外的时间成本。
    • 相关子查询的低效:对于相关子查询(即子查询的结果依赖于外部查询的每一行),MySQL可能需要对外层表的每一行都执行一次子查询,这在数据量大时会极度影响性能。
    • 索引利用不足:在某些情况下,子查询可能妨碍优化器使用有效的索引策略,导致全表扫描,特别是在子查询的条件复杂或不明确时。
  2. 可读性和维护困难

    • 复杂性:子查询嵌套过多会使SQL语句变得冗长且难以理解,尤其是对于复杂的逻辑,这会影响代码的可读性和后续的维护工作。
    • 调试困难:子查询可能导致的性能瓶颈较难定位,因为问题可能隐藏在多层嵌套中,调试和优化变得更加困难。
  3. 优化局限性

    • MySQL的查询优化器在处理子查询方面可能不如处理JOIN操作高效,尤其是在处理大数据集时。优化器可能无法有效地重写或优化复杂的子查询结构。
  4. 替代方案

    • 在很多情况下,使用JOIN操作可能提供更好的性能和可读性,尤其是在处理多表关联查询时。JOIN直接在数据行级别进行匹配,减少了临时表的创建和销毁过程,对于大数据量的处理更加高效。
    • 对于简单的子查询,直接在应用程序层面进行数据处理也是一种可行的替代方案,例如先执行子查询获取数据,再用结果去执行主查询,但这增加了应用程序的复杂度。

        综上所述,虽然子查询在灵活性和功能上非常强大,但在设计查询时应权衡其优缺点,根据实际需求和数据规模选择最合适的方法。在数据量较大或性能要求较高的场景下,考虑使用JOIN或直接在应用程序中处理数据可能是更优的选择。

🍒四. 修改(Update

🍓1.基本操作

UPDATE命令用于更新表中的现有记录。你可以更新单行或多行,具体取决于WHERE子句的条件。

UPDATE table_name
SET column1 = new_value1, column2 = new_value2, ...
WHERE condition;

table_name是你要修改的表的名称。

column1 = new_value1, column2 = new_value2, ...指定了要修改的列名及其新值。

WHERE condition是可选的,用于指定哪些行需要更新。如果省略,将更新表中的所有行。

举例:

-- 将孙悟空同学的数学成绩变更为 80 分
UPDATE exam_result SET math = 80 WHERE name = '孙悟空';

-- 将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分
UPDATE exam_result SET math = 60, chinese = 70 WHERE name = '曹孟德';

-- 将总成绩倒数前三的 3 位同学的数学成绩加上 30 分
UPDATE exam_result SET math = math + 30 ORDER BY chinese + math + english LIMIT
3;

-- 将所有同学的语文成绩更新为原来的 2 倍
UPDATE exam_result SET chinese = chinese * 2;

🫐2. 修改表结构(ALTER TABLE)

ALTER TABLE命令用于修改表的结构,包括添加/删除列、修改列属性、添加约束、重命名表等。

  • 添加列:
ALTER TABLE table_name
ADD column_name column_definition [FIRST|AFTER column_name];

column_definition定义新列的类型和属性,如INT(110)

FIRST在表开头添加,AFTER column_name在指定列之后添加。

  • 删除列:
ALTER TABLE table_name
DROP COLUMN column_name;
  • 修改列
ALTER TABLE table_name
MODIFY column_name column_definition;
  •  重命名表
ALTER TABLE old_table_name RENAME TO new_table_name;

🥝3.注意事项

  • 在进行修改操作之前,建议备份数据,以防误操作导致数据丢失。
  • 对于生产数据库的修改操作,最好在低峰期进行,避免影响服务。
  • 修改表结构可能会影响依赖于该表的应用程序,需要进行相应的代码调整和测试。

综上所述,MySQL中的修改操作覆盖了数据记录的更新以及表结构的调整,是数据库管理与开发中不可或缺的一部分。正确理解和应用这些命令,可以有效管理数据库的持续发展和维护。

🍅五. 删除(Delete

        在MySQL中,删除操作主要涉及从数据库中移除数据或数据库对象,如数据表、记录、视图、存储过程等。主要通过DELETETRUNCATEDROP命令来实现。以下是这些操作的详细说明: 

💐1.基本操作 

DELETE FROM  table_name [WHERE ...] [ORDER BY ...] [LIMIT ...]

如果省略WHERE子句,将会删除表中的所有记录。

condition用于指定要删除的行的条件。

举例:

-- 删除孙悟空同学的考试成绩
DELETE FROM exam_result WHERE name = '孙悟空';

-- 删除整张表数据
-- 准备测试表
DROP TABLE IF EXISTS for_delete;
CREATE TABLE for_delete (
 id INT,
 name VARCHAR(20)
);

-- 插入测试数据
INSERT INTO for_delete (name) VALUES ('A'), ('B'), ('C');

-- 删除整表数据
DELETE FROM for_delete;

🌸2.快速清空表(TRUNCATE)

TRUNCATE语句用于快速删除表中的所有数据,它比DELETE更快,因为它不记录每个删除行的日志,也不会触发触发器,且不可回滚。

TRUNCATE TABLE table_name;

这个操作会清空表,但保留表结构。

🍀3. 删除表或数据库对象(DROP)

删除表:

DROP TABLE table_name;

删除数据库:

DROP DATABASE database_name;

🧬4.注意事项

  • 数据安全性DROP操作是永久性的,执行前应确保已备份重要数据。
  • 性能差异TRUNCATEDELETE更快,因为它不记录日志,也不需要逐行处理。
  • 事务与触发器DELETE支持事务处理和触发器,而TRUNCATEDROP不支持。
  • 权限要求:执行DROP操作通常需要更高的权限。
  • 索引和约束DROP TABLE会移除表及其所有索引和约束;TRUNCATEDELETE不影响表结构。

综上,MySQL中的删除操作根据不同的需求和场景提供了不同的命令,使用时需谨慎考虑其对数据的影响和是否可逆性,确保数据安全和操作的正确性。

🪥六.约束条件

MySQL中的约束条件是用来确保数据库表中数据的准确性和一致性的规则。约束条件可以防止不符合业务逻辑或数据完整性的数据被插入到表中。以下是MySQL中常见的几种约束条件

🧽1.非空约束 (NOT NULL)

  • 定义:要求该列的每一行都必须有值,不允许为空(NULL)。
  • 用途:保证表中的某些字段总是有值,适用于必填信息。
-- 重新设置学生表结构
DROP TABLE IF EXISTS student;
CREATE TABLE student (
   id INT NOT NULL,
   sn INT,
   name VARCHAR(20),
   qq_mail VARCHAR(20)
);

🧻2.唯一约束 (UNIQUE)

  • 定义:确保该列中的所有值都是唯一的,可以有一个NULL值
  • 用途:适合用于需要唯一标识但不作为主键的字段,如邮箱地址。
-- 重新设置学生表结构
DROP TABLE IF EXISTS student;
CREATE TABLE student (
   id INT NOT NULL,
   sn INT UNIQUE,
   name VARCHAR(20),
   qq_mail VARCHAR(20)
);

🪣3.主键约束 (PRIMARY KEY)

  • 定义:一个或多个字段的组合,用于唯一标识表中的每一行记录,且不能有NULL值。
  • 用途:是数据库表中最重要的约束之一,用于快速定位记录。
-- 重新设置学生表结构
DROP TABLE IF EXISTS student;
CREATE TABLE student (
   id INT NOT NULL PRIMARY KEY,
   sn INT UNIQUE,
   name VARCHAR(20) DEFAULT 'unkown',
   qq_mail VARCHAR(20)
);

    自增约束 (AUTO_INCREMENT)

  • 定义:主要用于整数类型的列,每当插入新记录时,该列的值自动增加。
  • 用途:简化主键的生成和管理。
-- 重新设置学生表结构
DROP TABLE IF EXISTS student;
CREATE TABLE student (
   id INT PRIMARY KEY auto_increment,
   sn INT UNIQUE,
   name VARCHAR(20) DEFAULT 'unkown',
   qq_mail VARCHAR(20)
);

🫧4.外键约束 (FOREIGN KEY)

  • 定义:建立两个表之间的关联,确保一个表中的值必须参考另一个表中已经存在的值。
  • 用途:维护数据间的引用完整性,常用于实现一对一或一对多的关系。
-- 创建班级表,有使用MySQL关键字作为字段时,需要使用``来标识
DROP TABLE IF EXISTS classes;
CREATE TABLE classes (
id INT PRIMARY KEY auto_increment,
name VARCHAR(20),
`desc` VARCHAR(100)
);

-- 重新设置学生表结构
DROP TABLE IF EXISTS student;
CREATE TABLE student (
   id INT PRIMARY KEY auto_increment,
   sn INT UNIQUE,
   name VARCHAR(20) DEFAULT 'unkown',
   qq_mail VARCHAR(20),
   classes_id int,
 FOREIGN KEY (classes_id) REFERENCES classes(id)
);

🛒5.检查约束 (CHECK - MySQL 8.0.16及以上版本支持)--了解

  • 定义:限制列中的值必须满足特定条件。
  • 用途:对数据的取值范围进行更细致的控制。
drop table if exists test_user;
create table test_user (
   id int,
   name varchar(20),
   sex varchar(1),
   check (sex ='男' or sex='女')
);

🧯6.默认值约束 (DEFAULT)

  • 定义:如果在插入数据时没有指定该列的值,则使用默认值。
  • 用途:简化数据插入,为可选字段提供默认选项。
-- 重新设置学生表结构
DROP TABLE IF EXISTS student;
CREATE TABLE student (
id INT NOT NULL,
sn INT UNIQUE,
name VARCHAR(20) DEFAULT 'unkown',
qq_mail VARCHAR(20)
);

这些约束条件可以在创建表时通过CREATE TABLE语句指定,也可以在表创建后通过ALTER TABLE语句添加或修改。合理使用约束条件能够极大地提高数据库的数据质量、维护数据的一致性和准确性。

🪤七.总结与反思

只要下定决心克服恐惧,便几乎能克服任何恐惧。因为,请记住,除了在脑海中,恐惧无处藏身。--戴尔.卡耐基

经过一段时间对MySQL增删查改(Insert, Delete, Select, Update)四大核心操作的学习与实践,我深刻体会到了数据库管理的复杂性和艺术性。以下是对这一学习过程的深入反思,旨在总结经验,明确改进方向,不断提升数据库操作的效率与安全性。

增(Insert)

  • 数据验证的重要性:在执行插入操作时,我意识到前端或应用层的数据验证虽是第一道防线,但数据库层面的数据约束(如非空检查、唯一性约束)同样至关重要。忽视这一点可能导致数据不一致性,因此,设置合理的数据库约束并确保其有效执行是不可或缺的。
  • 性能考量:对于大批量数据的插入,原生的单条插入方式效率低下。未来应探索使用LOAD DATA INFILE命令或批量插入语句来提升效率,减少数据库的I/O压力。

删(Delete)

  • 安全第一:删除操作的不可逆性让我深刻认识到,在执行前应三思而后行,特别是在生产环境。采用DELETE FROM时务必附加精确的WHERE子句,避免误删整表数据。同时,考虑在执行此类操作前采取备份措施。
  • 事务的妙用:在涉及多步骤的删除操作中,事务的使用可以确保数据的一致性。我需要加强对事务特性的掌握,特别是在并发操作场景下,确保数据的完整性和一致性。

查(Select)

  • SQL优化的艺术:虽然SELECT是最基础的操作,但其背后的优化空间巨大。我认识到,合理利用索引、避免全表扫描、精简查询字段、优化JOIN操作等,对于提升查询效率至关重要。此外,学习如何解读并利用EXPLAIN分析查询计划,对于理解MySQL如何执行SQL语句有着不可估量的价值。
  • 复杂查询的挑战:面对多表联合查询、子查询等复杂情况,我发现自己在理解与编写高效查询语句方面还有很大提升空间。未来,我需要通过更多实践,加深对高级SQL特性的理解和应用,如窗口函数、分析函数等。

改(Update)

  • 精准定位:更新操作同样需要谨慎处理,精确的WHERE子句是避免错误更新的关键。我需要培养在执行更新前进行数据预览的习惯,尤其是在处理影响大量数据的更新时。
  • 性能与锁的影响:大规模更新操作可能引发性能问题,特别是表锁或行锁的应用可能阻塞其他读写操作。学习并掌握如何最小化锁定范围,以及在必要时使用乐观锁或悲观锁机制,是提升并发处理能力的关键。

结语

        通过对MySQL增删查改操作的反思,我深刻认识到了理论知识与实践操作之间的差距,以及数据库管理中细节决定成败的道理。未来的路途中,我将致力于深化理论学习,加强实战演练,同时关注数据库最新技术和最佳实践,以期成为一名更为熟练且负责任的数据库管理员。


🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀

以上,就是本期的全部内容啦,若有错误疏忽希望各位大佬及时指出💐

  制作不易,希望能对各位提供微小的帮助,可否留下你免费的赞呢🌸

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/637537.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

169. Majority Element

文章目录 题目描述(简单难度)解法一解法二 位运算摩尔投票法参考文献 题目描述(简单难度) 给一个数组&#xff0c;存在一个数字超过了半数&#xff0c;找出这个数。 解法一 这种计数问题&#xff0c;直接就会想到 HashMap&#xff0c;遍历过程中统计每个数字出现的个数即可。…

Python入门全系列教程(更新中……)

最近辞职了&#xff0c;有点时间&#xff0c;打算写一套Python入门的全系列教程&#xff0c;需要的人欢迎关注蹲守&#xff01;&#xff01;&#xff01; 【Python基础篇】&#xff1a;入门基础知识—轻松踏上编程巅峰&#xff01;" 【Python基础篇】—基本语句详解 【Py…

jenkins插件之xunit

分析测试工具执行的结果&#xff0c;并图形化&#xff0c;比如phpunit&#xff0c;phpstan,可分析junit格式的结果 安装jenkins插件 搜索xunit并安装 项目配置 配置 - Build Steps 您的项目 - 配置 - Build Steps, 新增 Run with timeout 超时时间根据实际情况配置 Build…

unidbg入门笔记

一、unidbg 介绍 unidbg 是凯神 在 2019 年初开源的一个轻量级模拟器&#xff0c;一个基于Java的跨平台解密引擎&#xff0c;专门用于动态分析和逆向工程应用程序。它可以模拟不同CPU架构、操作系统和指令集&#xff0c;从而使用户能够在一个统一的环境中分析各种不同类型的二…

Mac下QT开发环境搭建详细教程

QT Qt是一个跨平台的C应用程序框架&#xff0c;用于开发具有图形用户界面&#xff08;GUI&#xff09;的应用程序&#xff0c;同时也可用于开发非GUI程序&#xff0c;比如控制台工具和服务器。Qt是设计成通用、可移植和高效的&#xff0c;它广泛应用于全球的企业和开发者社区中…

Codigger编码场景介绍(二):驾驶舱场景(Cockpit)

Codigger&#xff0c;一个专为开发人员设计的工具&#xff0c;致力于为不同的开发场景提供最佳的切换体验。Codigger囊括了多种场景&#xff0c;如传统场景、调试场景、设计器场景、驾驶舱场景以及纯净场景等。在上一篇文章中&#xff0c;我们介绍了传统场景模式&#xff0c;今…

宠物空气净化器:过敏星人的终极武器,让猫毛无处藏身~

猫毛过敏者虽畏惧猫毛&#xff0c;但对猫的热爱让他们选择继续养猫。过敏反应通常由猫的皮屑、唾液和尿液中的蛋白质引发&#xff0c;这些颗粒在空气中传播&#xff0c;导致打喷嚏、咳嗽和皮肤红疹等症状。宠物空气净化器&#xff0c;专为去除猫毛、异味和消毒灭菌设计&#xf…

【Vue3】env环境变量的配置和使用(区分cli和vite)

原文作者&#xff1a;我辈李想 版权声明&#xff1a;文章原创&#xff0c;转载时请务必加上原文超链接、作者信息和本声明。 文章目录 前言一、env文件二、vue3cli加载env1..env配置2..dev配置&#xff08;其他环境参考&#xff09;3.package.json文件4.使用 三、vue3vite加载e…

AI图片过拟合如何处理?答案就在其中!

遇到难题不要怕&#xff01;厚德提问大佬答&#xff01; 厚德提问大佬答8 你是否对AI绘画感兴趣却无从下手&#xff1f;是否有很多疑问却苦于没有大佬解答带你飞&#xff1f;从此刻开始这些问题都将迎刃而解&#xff01;你感兴趣的话题&#xff0c;厚德云替你问&#xff0c;你解…

STM32-按键控制LED

接上篇LED点亮;http://t.csdnimg.cn/9r6z7 目录 一.硬件设计 二.软件设计 三.完整代码 四.结束语 一.硬件设计 按钮接电源插入PB0引脚,如上图所示 二.软件设计 void key_init() {GPIO_InitTypeDef GPIO_InitStruct;//使能时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-19.1讲 串口格式化输出printf

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

JVM(5):虚拟机性能分析和故障解决工具概述

1 工具概述 作为一个java程序员&#xff0c;最基本的要求就是用java语言编写程序&#xff0c;并能够在jvm虚拟机上正常运行&#xff0c;但是在实际开发过程中&#xff0c;我们所有的程序由于各种各样的原因&#xff0c;并不是总能够正常运行&#xff0c;经常会发生故障或者程序…

cocos 写 连连看 小游戏主要逻辑(Ts编写)算法总结

cocos官方文档&#xff1a;节点系统事件 | Cocos Creator 游戏界面展示 一、在cocos编译器随便画个页面 展示页面 二、连连看元素生成 2.1、准备单个方块元素&#xff0c;我这里就是直接使用一张图片&#xff0c;图片大小为100x100&#xff0c;描点围为&#xff08;0&#xf…

某钢铁企业数字化转型规划案例(114页PPT)

案例介绍&#xff1a; 该钢铁企业的数字化转型案例表明&#xff0c;数字化转型是钢铁企业应对市场竞争、提高生产效率、降低成本、优化资源配置和降低能耗排放的重要手段。通过引入先进的技术和管理理念&#xff0c;加强员工培训和人才引进&#xff0c;企业可以成功实现数字化…

数据挖掘实战-基于内容协同过滤算法的电影推荐系统

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

轻松上手ClickHouse:ClickHouse入门

引言 在数字化时代&#xff0c;大数据处理和分析已经成为了各行各业不可或缺的一环。而ClickHouse&#xff0c;作为一款高性能的列式数据库管理系统&#xff0c;以其卓越的查询性能和灵活的扩展性&#xff0c;赢得了众多企业和开发者的青睐。本文将带领大家走进ClickHouse的世…

【数组】Leetcode 452. 用最少数量的箭引爆气球【中等】

用最少数量的箭引爆气球 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points &#xff0c;其中points[i] [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 一支弓箭可以沿着 x 轴从不同点 完全垂直 地…

初识java——javaSE(6)抽象类与接口【求个关注!】

文章目录 前言一 抽象类1.1 抽象类的概念1.2 抽象类的语法&#xff1a;1.3 抽象类与普通类的区别&#xff1a; 二 接口2.1 接口的概念2.2 接口的语法2.2.1 接口的各个组成2.2.2 接口之间的继承 2.3 接口的实现接口不可以实例化对象 2.4 接口实现多态 三 Object类3.1 Object类是…

HCIP【VRRP、MSTP、VLAN综合实验】

目录 一、实验拓扑图&#xff1a; ​编辑二、实验要求 三、实验思路 四、实验步骤 &#xff08;1&#xff09; eth-trunk技术配置 &#xff08;2&#xff09;vlan 技术配置 &#xff08;3&#xff09;配置SW1、SW2、AR1、ISP的IP地址 &#xff08;4&#xff09;在交换机…

Jetbrains插件AI Assistant,终于用上了

ai assistant激活成功后&#xff0c;如图 ai assistant获取&#xff1a;https://web.52shizhan.cn/activity/ai-assistant 主要功能如下