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

news2024/7/6 20:15:24

 🔥个人主页: 中草药

🔥专栏:【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.coloradmin.cn/o/1687487.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【虚拟机软件】 VMware Workstation Pro 17 新建 Linux 虚拟机教程(CentOS 7 版本)

文章目录 下载安装 VMware Workstation Pro 17 软件下载 Linux 的 ISO 映像文件Linux版本选择 新建虚拟机准备配置新建安装 后续设置文章导航 我是一名立志把细节说清楚的博主&#xff0c;欢迎【关注】&#x1f389; ~ 原创不易&#xff0c; 如果有帮助 &#xff0c;记得【点赞…

css动画之hamburgers

动效1 代码如下&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><body><div><label class"hamburger"><input type"checkbox"><…

Redis主从、哨兵、集群讲解

一、Redis主从 大家在面试中可能经常会被问到Redis的高可用问题。Redis高可用回答包括两个层面&#xff0c;一个就是数据不能丢失&#xff0c;或者说尽量减少丢失 ;另外一个就是保证Redis服务不中断 。 对于尽量减少数据丢失&#xff0c;可以通过AOF和RDB保证。 对于保证服务…

捷报频传 | 北京讯通喜获中国信通院2023“Zero Trust Ready SDP解决方案”证书

中国信息通信研究院&#xff08;以下简称“中国信通院”&#xff09;算网融合团队联合各生态伙伴&#xff0c;共同发起“Zero Trust Ready”项目&#xff0c;推动零信任&#xff08;Zero Trust&#xff09;技术与产业发展。该项目旨在从垂直行业的网络安全需求出发&#xff0c;…

『大模型笔记』从头开始代码构建GPT!

从头开始代码构建GPT! 文章目录 一. 从头开始代码构建GPT!二. 参考文献一. 从头开始代码构建GPT! 我们构建了一个生成式预训练Transformer (GPT),遵循论文《Attention is All You Need》和OpenAI的GPT-2 / GPT-3的方法。我们讨论了与ChatGPT的联系,ChatGPT已经风靡全球。我…

牛马真的沉默了,入职第一天就干活

入职第一天就干活的&#xff0c;就问还有谁&#xff0c;搬来一台N手电脑&#xff0c;第一分钟开机&#xff0c;第二分钟派活&#xff0c;第三分钟干活&#xff0c;巴适。。。。。。 打开代码发现问题不断 读取配置文件居然读取两个配置文件&#xff0c;一个读一点&#xff0c;…

掌握Go语言中的net/http包:编写高性能Web服务

掌握Go语言中的net/http包&#xff1a;编写高性能Web服务 引言HTTP服务器构建基础服务器设置路由与处理函数中间件使用高级配置&#xff08;如TLS/SSL&#xff09; HTTP客户端开发创建与使用HTTP客户端处理响应 高级客户端特性 处理JSON与表单数据接收与解析JSON接收与解析表单…

Langchain:数据连接封装、缓存封装和LCEL学习和探索

&#x1f335; 目录 &#x1f335; &#x1f60b; 数据连接封装 &#x1f354; 文档加载器&#xff1a;Document Loaders 文档处理器&#xff1a;TextSplitter 向量数据库与向量检索 总结 &#x1f349; 缓存封装&#xff1a;Memory &#x1f3d6;️ 对话上下文&#xf…

Docker | 基础指令

环境&#xff1a;centos8 参考&#xff1a; 安装 Docker | Docker 从入门到实践https://vuepress.mirror.docker-practice.com/install/ 安装Docker 卸载旧版本&#xff0c;安装依赖包&#xff0c;添加yum软件源&#xff0c;更新 yum 软件源缓存&#xff0c;安装 docker-ce…

保研笔试复习——nju

文章目录 一、单选计算机网络计算机组成原理数字逻辑电路数据结构操作系统微机系统 多选题计算机网络计算机系统结构操作系统 免责声明&#xff1a;题目源自于网络&#xff0c;侵删。 就在今天2024-5-18&#xff0c;考的题下面的只有一道AVL的原题&#xff0c;其他都不是原题&a…

Python操作MySQL数据库的工具--sqlalchemy

文章目录 一、pymysql和sqlalchemy的区别二、sqlalchemy的详细使用1.安装库2.核心思想3.整体思路4.sqlalchemy需要连接数据库5.使用步骤1.手动提前创建数据库2.使用代码创建数据表3.用代码操作数据表3.1 增加数据3.2 查询数据3.3 删除数据3.4 修改数据 一、pymysql和sqlalchemy…

mysql 按区间统计 3 分钟维度

根据 UNIX_TIMESTAMP 去掉分钟后的的位数 思路如下select UNIX_TIMESTAMP(now()) 当前时间 秒,now() 当前时间,FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(CURRENT_TIMESTAMP) / (3 * 60)) * (3 * 60)) 3分钟为分隔去掉多余位数当前时间 秒 当前时间 3分钟为分隔去掉多余…

电磁仿真软件CST六面体网格和六面体TLM网格的区别【仿真入门】

六面体网格&#xff08;1&#xff09; Time Domain Solver中使用的Hexahedral Mesh&#xff01; 网格可以说是为了Maxwell方程式计算&#xff0c;将仿真结构分割成许多小的网格单元。因此&#xff0c;仿真计算中识别的结构是网格结构。 Time Domain Solver中使用的Hexahedra…

什么是线程安全?如何保证线程安全?

目录 一、引入线程安全 &#x1f447; 二、 线程安全&#x1f447; 1、线程安全概念 &#x1f50d; 2、线程不安全的原因 &#x1f50d; 抢占式执行&#xff08;罪魁祸首&#xff0c;万恶之源&#xff09;导致了线程之间的调度是“随机的” 多个线程修改同一个变量 修改…

每日一题《leetcode--116.填充每个结点的下一个右侧结点》

https://leetcode.cn/problems/populating-next-right-pointers-in-each-node/ 题目要求给每个结点的next指针进行填充&#xff0c;使每个结点的next指针指向其下一个右侧结点。如果右侧没有结点&#xff0c;则将next指针设置为空。 struct Node* connect(struct Node* root) {…

OpenP2P使用分享

软件介绍 大家好&#xff0c;今天我跟大家分享另一种内网穿透的方式。说起内网穿透&#xff0c;可能大家首先想到的是VPN&#xff0c;它是一种常见的内网穿透技术&#xff0c;能够让我们在远程访问内网资源。但是&#xff0c;VPN需要公网IP和服务器&#xff0c;而且配置相对复…

智能的PHP开发工具PhpStorm v2024.1全新发布——支持PHPUnit 11.0

PhpStorm是一个轻量级且便捷的PHP IDE&#xff0c;其旨在提高用户效率&#xff0c;可深刻理解用户的编码&#xff0c;提供智能代码补全&#xff0c;快速导航以及即时错误检查。可随时帮助用户对其编码进行调整&#xff0c;运行单元测试或者提供可视化debug功能。 立即获取PhpS…

路由聚合和VRRP技术

实验拓扑图&#xff1a; 实验需求 1、内网IP地址使用172.16.0.0/16 2、SW1和SW2之间互为备份&#xff1b; 3、VRRP/stp/vlan/eth-trunk均使用&#xff1b; 4、所有pc均通过DHCP获取IP地址&#xff1b; 5、ISP只配置IP地址&#xff1b; 6、所有电脑可以正常访问ISP路由器环…

什么是云计算安全?如何保障云计算安全

云计算彻底改变了数据存储的世界&#xff0c;它使企业可以远程存储数据并随时随地从任何位置访问数据。存和取变得简单&#xff0c;也使得云上数据极易造成泄露或者被篡改&#xff0c;所以云计算安全就显得非常重要了。那么什么是云计算安全&#xff1f; 其实&#xff0c;云计…

EN6347QI 开关稳压器 4A 贴片QFN-38 参数资料 应用案例 相关型号

EN6347QI 是一款直流/直流开关转换器。它是一款高效率的 buck (降压) 转换器&#xff0c;内置了电感器&#xff0c;能够提供高达 4A 的输出电流。其工作电压范围为 4.5V 至 12V&#xff0c;输出电压可调&#xff0c;最高可达 15V。EN6347QI 适合于各种电子设备中&#xff0c;用…