MySQL必备的常见知识点汇总整理

网络编程 2025-04-04 11:16www.168986.cn编程入门

MySQL的奥秘:常见知识点一网打尽

步入数据库的世界,MySQL无疑是首选之一。本文将带你领略MySQL的必备知识点,通过实例形式全方位解读mysql的各种常见操作。无论你是初学者还是资深玩家,本文都能为你提供宝贵的参考。

一、登录与退出

要进入MySQL的大门,首先需要掌握登录的技巧。使用命令“mysql -u root -p12345612”即可开启MySQL之旅。完成操作后,使用“exit;”命令优雅地退出数据库服务器。

二、基本语法指南

三、深入了解建表约束

在创建数据表时,约束的使用至关重要。主键约束能确保表内数据的唯一性,让某个字段既不可重复也不能为空。联合主键则是多个字段组合在一起,共同确保数据的唯一性。自增约束由系统自动分配,为你的主键提供便捷的自增功能。

四、深入解读实例

通过实际案例,我们将更深入地理解这些知识点。例如,创建一个名为“pet”的数据表,包含宠物名称、主人名称、物种、性别、出生日期和去世日期等信息。然后,我们进行基本的增删改查操作,体验MySQL的实际应用。

五、事务处理与更多知识点

除了上述内容,MySQL还有更多知识点等待你去,如事务处理、存储过程、触发器等。这些知识点将帮助你更深入地了解MySQL的奥秘。

本文旨在分享MySQL的常见知识点,希望能对大家有所帮助。感谢原作者hjzCy的辛勤付出,如需了解更多内容,可查看原文链接。如在使用过程中发现错误,欢迎大家共同指正。让我们共同学习,共同进步!

MySQL的海洋深不可测,只有不断学习和实践,才能掌握其精髓。希望本文能为你提供有益的参考,助你在MySQL的世界里畅游!在数据库设计中,表的创建与约束设置是至关重要的环节。下面,我将以生动的语言和丰富的文体,为您阐述关于创建表及设置主键、唯一主键、非空约束、默认约束、外键约束等概念,同时数据库的三大设计范式。

一、关于主键

让我们从“用户表”开始。当我们创建用户表时,通常会设置一个主键来标识每个用户的唯一性。这里,我们以id作为主键。随后,如果我们忘记设置主键,仍可通过SQL语句进行添加或修改。但当我们需要删除主键时,只需使用相应的ALTER TABLE语句即可。除了常见的INT类型主键,我们还可以使用VARCHAR等其他数据类型作为主键。唯一主键是一种特殊的主键,它可以确保表中的每一行数据的唯一性。例如,在用户表中,即使两个用户拥有相同的id,但他们的名字必须是唯一的。

二、关于非空约束和默认约束

三、关于外键约束

外键是用于确保一张表中的数据匹配另一张表中的一行数据。例如,我们创建了一个班级表和一个学生表。在学生表中,class_id是一个外键,它引用了班级表中的id字段。这意味着每个学生都与一个班级相关联。如果班级表中没有相应的数据,学生表中无法添加相应的数据。被引用的主表中的数据不能被删除,除非没有副表中的引用。

四、数据库的三大设计范式

1. 第一范式(1NF):要求数据库表的每一列都是不可分割的原子数据项。也就是说,字段值不能再次拆分。在实际设计中,需要根据项目的实际情况进行设定。

当我们讨论第三范式时,我们需要考虑的是除了主键之外,表中的其他列之间是否存在传递依赖关系。以“myorder”表为例,如果在该表中加入“customer_phone”列,并且这个列的值既依赖于“order_id”又依赖于“customer_id”,那么这就存在传递依赖关系,不符合第三范式的原则。

为了解决这个问题,我们可以将“customer_phone”列移至“customer”表中。这样,“customer”表就包含了客户的所有相关信息,包括他们的联系方式。而订单表则只包含与订单直接相关的信息,如订单ID、产品ID和客户ID。这样的设计确保了每个列都只依赖于主键列,满足了第三范式的要求。

数据库设计的目标是确保数据的完整性、减少数据冗余和提高查询效率。第二范式和第三范式是指导我们进行良好数据库设计的重要原则。遵循这些原则,我们可以创建出结构清晰、逻辑严密的数据库,为数据的存储和管理提供坚实的基础。经过适当的调整和优化,我们确保了数据库的设计既符合实际需求,又能充分发挥其潜力。数据库查询练习

我们来准备一些数据。在名为 `select_test` 的数据库中,我们有关于学生、教师、课程和成绩的数据表。接下来的查询练习将基于这些表进行。

准备数据

查询练习 1 到 10

1. 查询 student 表的所有行

SQL语句:

`SELECT FROM student;`

解释:选择学生表中的所有字段和所有行。

2. 查询 student 表中的 name、sex 和 class 字段的所有行

SQL语句:

`SELECT name, sex, class FROM student;`

解释:从学生表中选取名字、性别和班级字段。

3. 查询 teacher 表中不重复的 department 列

SQL语句:

`SELECT DISTINCT department FROM teacher;`

解释:从教师表中选取唯一的部门信息。

4. 查询 score 表中成绩在60-80之间的所有行

SQL语句(使用BETWEEN):

`SELECT FROM score WHERE degree BETWEEN 60 AND 80;`

或 SQL语句(使用AND):

`SELECT FROM score WHERE degree > 60 AND degree < 80;`

解释:从成绩表中选取成绩在60到80之间的所有行。BETWEEN用于指定范围查询,AND用于连接两个条件。两者效果相同。

5. 查询 score 表中成绩为 85, 86 或 88 的行

SQL语句:

SELECT student.name, score.c_no, score.degree

FROM student

JOIN score ON student.s_no = score.s_no;

这将返回一个包含所有学生姓名、课程编号和对应成绩的列表。通过使用 JOIN 操作,我们可以轻松地从两个相关的表中获取所需的信息。

进一步地,如果我们想得知具体是哪门课程和这门课程的成绩,就需要引入第三个表:课程表(course)。这个表中包含了课程的编号(no)和课程名称(name)。通过再次使用多表查询,我们可以将成绩表中的c_no替换为课程表中的课程名称,从而得到完整的查询结果:学生的姓名、课程名称和对应的成绩。这样,我们便能轻松地从数据库中提取出我们需要的信息。

多表查询是数据库查询中的一项重要技能。通过合理的查询语句,我们可以将分散在多个表中的数据信息整合在一起,以直观、清晰的方式呈现出来。这不仅提高了我们处理数据的效率,还使我们能够从数据中获取更多有价值的信息。在今后的工作中,掌握多表查询的技巧将为我们带来无尽的便利和惊喜。在深入数据库的奥秘时,我们经常需要跨表查询以获取更丰富的信息。这次,我们来如何从三张表——score、course和student中,获取学生的名字、课程名和成绩。

想象一下,我们正在处理一个教育数据库,其中有学生的信息、课程的详情以及他们之间的成绩关联。为了获取全面的数据,我们需要进行三表关联查询。

让我们关注score表,它记录了每个学生的学号(s_no)、课堂号(c_no)和成绩(degree)。这里,c_no是连接course表的桥梁,而s_no则是连接student表的纽带。

为了获取学生的名字和课程的名称,我们需要将score表与student表和course表进行关联。我们可以使用以下查询来实现:

```sql

SELECT student.name as student_name, course.name as course_name, score.degree

FROM score

JOIN student ON score.s_no = student.no

JOIN course ON score.c_no = course.no;

```

这个查询将返回学生的名字、课程名和对应的成绩。通过JOIN操作,我们能够将不同的表通过共同的字段连接起来,从而获取完整的信息。

为了更清晰地理解,让我们看一个具体的例子。假设我们有一个课程表,其中包含课程的编号和名称:

```sql

-- 课程表

SELECT no, name FROM course;

```

输出结果可能是:

```diff

+-+--+

| no | name |

+-+--+

| 3-105 | 计算机导论 |

| 3-245 | 操作系统 |

| ... | ... |

+-+--+

```

通过这种方式,我们能够充分利用数据库的关联功能,从多个表中提取信息,并将其整合到一个查询结果中,从而方便我们进行数据分析和处理。这种查询方式不仅提高了数据的可读性,还使我们能够更深入地了解数据之间的关系。为了完成这个任务,我们需要进行多层嵌套子查询。假设教师表为teacher,教师任课表为teacher_course,学生成绩表为score。我们需要找到张旭教师任教的课程编号,然后找到这些课程对应的学生成绩记录。以下是查询语句:

```sql

SELECT s_no, c_no, degree

FROM score

WHERE c_no IN (

SELECT course_no

FROM teacher_course

WHERE teacher_name = '张旭'

);

```

我们需要知道每位老师所教的课程。通过查询teacher表,我们得到了每位老师的编号和姓名。接着,在course表中,我们可以找到每门课程的教师编号。

然后,我们需要知道哪些课程被更多的学生选修。这就需要我们查询score表,按照课程号(c_no)进行分组,并统计每个课程号下的学生数量。这一步可以使用GROUP BY和HAVING语句来实现,具体为:

```sql

SELECT c_no, COUNT() as student_count

FROM score

GROUP BY c_no

HAVING COUNT() >= 5;

```

这个查询会返回所有被至少5个学生选修的课程号。然后,我们可以根据这些课程号在course表中找到对应的教师编号,再在teacher表中找到教师的姓名。以下是查询结果:

```sql

SELECT name

FROM teacher

WHERE no IN (

SELECT DISTINCT t_no

FROM course

WHERE c_no IN (

SELECT c_no

FROM score

GROUP BY c_no

HAVING COUNT() >= 5

)

);

```

子查询结合 UNION 和 NOT IN 的奇妙运用

不同职称的教师

当我们想要找出计算机系与电子工程系中不同职称的教师时,SQL查询的魔力就显现出来了。想象一下,我们在庞大的数据海洋中,通过几条简单的指令,就能精准地提取出我们想要的信息。

让我们分别找出两个系的所有教师编号。这就像是筛选出两个列表中的独特标识。

```sql

-- 找出计算机系的教师编号

SELECT no FROM teacher WHERE department = '计算机系'

UNION

-- 找出电子工程系的教师编号

SELECT no FROM teacher WHERE department = '电子工程系';

```

接下来,我们要根据这些编号,进一步获取他们的职称。但在这之前,我们需要确保每个系的教师编号都是唯一的,这就用到了UNION操作,它能合并两个查询的结果,并且自动去除重复项。

现在,我们有了两个系的教师编号列表,接下来要找出他们的职称。我们还需要确保这两个系中每个职称都是独特的,这时就需要用到NOT IN了。

```sql

-- 查询计算机系教师的职称

SELECT name, title FROM teacher WHERE department = '计算机系'

-- 减去电子工程系已有的职称,得到计算机系独有的职称

NOT IN (SELECT title FROM teacher WHERE department = '电子工程系');

```

通过这样的查询,我们就能得到计算机系中独有的职称列表。同样的方法,也可以用于查询电子工程系中独有的职称。这样,我们就能全面而准确地了解这两个系中不同职称的教师情况了。

数据库中的信息——深入理解SQL查询语句

在数据库的海洋中,我们像航海者一样,通过SQL语句查询我们需要的信息。今天,我们将聚焦于一些特定的查询,深入如何提取我们所需的数据。

让我们看看两个关于教师信息的查询。我们需要从教师表中筛选出属于计算机系的教师,他们的专业不在电子工程系的教师列表中。接着,再筛选出属于电子工程系的教师,他们的专业不在计算机系的教师列表中。这看似复杂,但其实可以通过SQL的NOT IN和UNION语句轻松实现。这两个操作都能够帮助我们从数据库中筛选出符合特定条件的数据。

接下来,我们来讨论一个关于学生成绩的场景。假设我们有两门课程,课程号为3-105和3-245。我们想要找出在课程3-105中成绩至少比课程3-245中的任何一个学生高的学生记录,并按成绩降序排列。在这里,“至少”的概念用SQL中的ANY表示。简单来说,只要课程3-105中的任何一个学生的成绩高于课程3-245中的任何学生,就满足条件。这个查询可以通过子查询和比较运算符来实现。

我们来一个类似的场景,但条件稍有不同。我们要查询课程3-105中所有学生的成绩都高于课程3-245中所有学生的记录。在这里,“所有”的概念用SQL中的ALL表示。这意味着课程3-105中的每一个学生都必须比课程3-245的所有学生都高才满足条件。这个查询同样可以通过子查询和比较运算符来完成。

成绩背后的秘密:条件查询与数据分析

在庞大的数据海洋中,我们时常需要筛选出符合特定条件的记录。下面我们将深入如何利用SQL查询,挖掘出特定课程的成绩数据。

条件查询:复制表数据作为筛选基础

想象一下,你有一份成绩表(score),里面记录了不同课程(c_no)的成绩(degree)。现在,你想找出那些成绩低于某门课程的平均成绩的学生。你需要计算出这门课程的平均分,然后对比每个学生的成绩。这个过程可以通过SQL的子查询来实现。

假设我们正在查询的课程编号为 '3-105',我们可以首先计算出该课程的平均分,然后将这个平均分与每个学生的成绩进行比较。这个过程可以通过以下SQL语句实现:

```sql

SELECT FROM score WHERE c_no = '3-105' AND degree < (SELECT AVG(degree) FROM score WHERE c_no = '3-105');

```

这样,我们就能得到所有该课程成绩低于平均分的学生的记录。这种查询方式在数据分析中非常常见,能够帮助我们快速定位到不符合预期的记录。

子查询进阶:从相关表中提取信息

接下来,我们进一步如何通过子查询从相关表中提取信息。假设我们有一个教师表(teacher)和一个课程表(course),我们想找出所有有课程的教师的姓名(name)和所属系别(department)。这个问题可以通过以下SQL语句解决:

```sql

SELECT name, department FROM teacher WHERE no IN (SELECT t_no FROM course);

```

这个查询的逻辑是:从课程表中提取所有教师的编号(t_no);然后,根据这些编号,从教师表中提取对应的姓名和系别。通过这种方式,我们可以快速获取到所有有课程的教师的信息。这种跨表查询的能力是SQL的强大之处。

条件加组筛选:挖掘更多信息

我们来解决一个更具挑战性的问题:在student表中,找出至少有2名男生的班级。这个问题需要我们首先按班级分组,然后统计每个班级的男生数量。这个过程可以通过GROUP BY语句和聚合函数COUNT来实现。假设性别字段为gender,男性为'male',我们可以这样写SQL语句:

```sql

SELECT class, COUNT()

FROM student

WHERE gender = 'male'

GROUP BY class

HAVING COUNT() >= 2;

```这个查询的逻辑是:按班级(class)对student表进行分组;然后,统计每个班级的男生数量;通过HAVING子句筛选出至少有2名男生的班级。通过这种方式,我们能够快速找到满足条件的班级。这种查询方式在数据分析中非常有用,能够帮助我们深入了解数据的分布情况。

在数据库中,记录着学生的基本信息,其中包含了他们的出生日期。下面,我们将使用SQL查询语句来找出表中最早的生日和最晚的生日。

我们来查看一下表中的生日信息:

-- 查看所有学生的生日信息:

```sql

SELECT name, birthday FROM student;

```

这将列出每个学生的姓名和对应的生日日期。

接下来,为了找出最早的生日和最晚的生日,我们将使用MAX和MIN函数来查询最大的日期(最晚的生日)和最小的日期(最早的生日)。

-- 使用MAX函数查询最晚的生日:

```sql

SELECT MAX(birthday) AS latest_birthday FROM student;

```

这将返回表中最晚的生日日期。

-- 使用MIN函数查询最早的生日:

```sql

SELECT MIN(birthday) AS earliest_birthday FROM student;

```

这将返回表中最早的生日日期。

通过这些查询,我们可以清晰地了解到学生表中生日信息的分布情况,从而获取关于学生年龄分布的一些初步了解。查询与"李军"同性别所有同学的姓名

我们需要确定"李军"的性别,然后基于这个性别去查询其他同学的姓名。假设我们的学生表中有性别这一列,其值可能为'男'或'女'。以下是一个可能的SQL查询:

```sql

SELECT name

FROM student

WHERE sex = (SELECT sex FROM student WHERE name = '李军');

```

这个查询首先会找到"李军"的性别(假设为'男'),然后在整个学生表中寻找所有性别为'男'的学生,并返回他们的姓名。这样,我们就可以得到与"李军"同性别的所有同学的姓名了。

数据库中的学生信息——以李军为线索

当我们想要聚焦某个特定学生的信息时,数据库中的子查询功能就显得尤为重要。假设我们正在查询名为李军的学生信息,并得知其性别为男。那么,如何进一步查询与他同性别且同班的同学名单呢?让我们一起深入。

我们从学生表中选取李军的性别信息:

SQL查询语句:

```sql

SELECT sex FROM student WHERE name = '李军';

```

得知李军的性别为“男”后,我们可以进一步查询与他同性别且同班的同学名单。以下是相应的SQL查询语句:

```sql

SELECT name, sex, class

FROM student

WHERE sex = (SELECT sex FROM student WHERE name = '李军')

AND class = (SELECT class FROM student WHERE name = '李军');

```

现在,让我们再进一步,查询所有选修“计算机导论”课程的男同学的成绩表。这需要我们从课程表中找到与“计算机导论”对应的课程编号,并从学生表中筛选出性别为男的学生的编号。以下是相应的SQL查询语句:

```sql

SELECT s_no, c_no, degree

FROM score

WHERE c_no = (SELECT no FROM course WHERE name = '计算机导论')

AND s_no IN (SELECT no FROM student WHERE sex = '男');

```

创建成绩等级表:

```sql

CREATE TABLE grade (low INT(3), upp INT(3), grade char(1));

```

```sql

区间查询:寻找学生成绩所在的区间

在数据库中,我们有时需要查询某个特定范围内的数据。例如,我们想要知道哪些学生的成绩在某个特定的区间内。这时,我们可以使用SQL中的区间查询功能。具体来说,假设我们有一个包含学生成绩的数据表grade,其中包含了每门课程的最低分数low和最高分数upp。我们可以通过使用BETWEEN关键字来查询成绩落在该区间内的学生名单。以下是具体的SQL查询语句:

```sql

SELECT s_no, c_no, grade

FROM score, grade

WHERE degree BETWEEN low AND upp;

```

假设执行上述查询后,我们得到了以下的结果:

```lua

++-+-+

| s_no | c_no | grade |

++-+-+

|多种学生及课程组合|

++-+-+

```

接下来,让我们深入了解连接查询。

创建测试数据库与表结构

分析两张表的关系后,我们可以发现它们之间存在某种关联。为了查询这两张表中有关系的数据,我们可以使用INNER JOIN(内连接)将它们拼接在一起。通过这种方式,我们可以轻松地获取满足特定条件的数据。以下是具体的SQL查询语句:

```sql

SELECT FROM person INNER JOIN card on person.cardId = card.id;

```执行上述查询后,我们会得到如下结果:

```lua

++--+--++--+

| id | name | cardId | card.id | card.name |

++--+--++--+

|相关人员的详细信息与所持的卡的信息|

++--+--++--+

```通过内连接,我们可以轻松地获取两张表中存在关联的数据。我们还可以省略INNER关键字,查询语句依然有效。数据库查询语言为我们提供了强大的工具来处理和检索数据,使得我们能够更高效地管理大量的信息。事务:MySQL中的业务完整性守护者

在MySQL数据库中,事务是一个最小的、不可分割的工作单元。它确保了一系列的操作要么完全执行,要么完全不执行,从而保证了业务的完整性。

想象一下,你在一个银行应用中进行转账操作。你需要从用户的账户中扣除一定的金额,并增加到接收者的账户中。这一操作包括两个步骤:扣除和增加。如果这两个步骤中的任何一个失败,那么整个转账操作就应该失败,并且用户的账户应该保持不变。这就是事务的用途:确保业务的逻辑完整性。

当你在MySQL中进行事务处理时,你可能会使用到以下关键词:

`START TRANSACTION`:开始一个新的事务。

`COMMIT`:提交当前事务,使其生效。

`ROLLBACK`:撤销当前事务的所有操作,返回到事务开始前的状态。

事务的四大特性(ACID属性)确保了数据的可靠性和一致性:

1. 原子性(Atomicity):事务是一个不可分割的工作单元,事务中的操作要么全部完成,要么全部不完成。

2. 一致性(Consistency):事务必须使数据库从一个一致性状态变换到另一个一致性状态。

3. 隔离性(Isolation):并发执行的事务不会彼此干扰。

4. 持久性(Durability):一旦事务被提交,其结果就是永久的,即使系统崩溃也不会丢失。

当在MySQL中使用事务时,开发者应确保每个事务都满足这些属性,以确保数据的完整性和可靠性。通过合理地使用事务,开发者可以确保数据库始终处于一个一致的状态,即使面临各种挑战,如系统故障、网络问题等。当我们谈论银行转账这样的金融交易时,数据的准确性和一致性至关重要。在实际项目中,如果只有一条SQL语句执行成功,而另一条执行失败,可能会出现数据前后不一致的情况。为了确保数据的完整性和准确性,我们需要引入事务的概念。

事务是一系列SQL语句的集合,这些语句要么全部成功执行,要么全部不执行。这样的设计保证了数据的一致性。在执行涉及金钱交易等关键业务时,我们可以通过事务来控制数据的完整性。

在MySQL中,事务的自动提交状态默认是开启的。这意味着当我们执行一条SQL语句时,其效果会立即体现在数据库中。但有时候,我们可能希望撤销某些已经执行的SQL语句,这就需要用到回滚操作。

回滚操作可以撤销所有已经执行的SQL语句,使数据库回到某个特定状态。在默认开启自动提交的情况下,回滚操作并不能撤销已经提交的数据。为了让数据可以进行回滚,我们需要关闭自动提交功能。

当自动提交被关闭后,所有执行的SQL语句都不会立即提交到数据库,而是在一张虚拟的临时数据表中展示。这样,我们就可以在确认所有SQL语句都执行无误后再进行提交,或者在出现问题时进行回滚操作。

通过这种方式,我们可以确保金融交易等关键业务的准确性,避免因为部分SQL语句执行失败而导致的数据不一致问题。事务控制和回滚操作为我们提供了一种强大的工具,确保数据的完整性和准确性。数据库操作中的事务处理:从提交到回滚的完整流程

假设我们有一个用户表“user”,其中包含了用户的ID、姓名和余额等信息。为了更好地理解事务的提交和回滚,我们先进行以下操作:

```sql

INSERT INTO user VALUES (1, 'a', 1000);

```

此时的数据尚未真正提交到数据库,处于“待提交”状态。在这个阶段,我们可以选择对数据进行一些更改或进行其他操作。但由于数据尚未固定,这些更改或操作都是暂时的。如果我们决定不进行任何更改并撤销此次操作,可以使用“ROLLBACK”命令进行回滚:

```sql

ROLLBACK;

```

```sql

COMMIT;

```

我们还可以设置自动提交或手动提交事务。当自动提交功能开启时(通过命令`SET AUTOCOMMIT = 1`),每次数据操作后都会自动提交,无法再进行回滚。在这种情况下,若想进行事务的回滚或其他操作,需要先关闭自动提交功能(`SET AUTOCOMMIT = 0`)。在手动提交模式下,我们可以更灵活地控制数据的提交和回滚。

以银行转账为例,假设我们从用户“a”的账户向用户“b”转账100元。这一过程中涉及两次数据更新操作。如果在这个过程中发生任何意外,如系统崩溃、网络中断等,可能会导致转账不成功但资金已被扣除的情况。我们就可以使用事务的回滚功能,将资金状态恢复到转账前,确保数据的完整性和准确性。反之,如果转账成功且没有其他问题,我们就可以使用“COMMIT”命令将这次转账记录保存到数据库中。

数据库中的事务处理是一个复杂但非常重要的过程。通过深入了解并提交、回滚等命令的使用,我们可以更好地管理数据库中的数据,确保数据的准确性和安全性。在数据库管理的世界中,事务扮演着至关重要的角色。通过手动开启一个事务,我们能够更好地控制数据的变更,确保数据的完整性和准确性。现在,让我们深入了解如何手动开启一个事务,以及事务的ACID特性和隔离性。

使用BEGIN或START TRANSACTION,我们可以手动开启一个事务。在这个事务中,我们执行一系列的数据库操作,如UPDATE语句,来修改数据。由于事务尚未提交,这些更改并不会立即生效,而是被保存在一个临时表中。

以用户资金转移为例,我们从用户'a'的账户中扣除100元,并添加到用户'b'的账户。在这个过程中,我们可能会遇到一种情况:在扣除用户'a'的资金后,系统出现错误,导致无法完成添加用户'b'的资金。这时,如果我们不进行回滚操作,那么用户'a'的资金就会被错误地扣除,而用户'b'并未得到相应的资金。我们需要使用ROLLBACK来撤销这些操作,确保数据的完整性。

一旦我们执行了COMMIT操作,就意味着我们确认这些更改是有效的,并希望它们成为永久性的。即使我们尝试使用ROLLBACK,也无法撤销这些更改。这是因为事务的持久性特征告诉我们,一旦事务结束,就不能再返回了。

除了持久性,事务还有原子性、一致性和隔离性四个重要特征。原子性意味着事务是最小的单位,不可以再分割;一致性要求同一事务中的SQL语句必须保证成功或者失败;隔离性则确保不同事务之间不会相互影响。这些特征共同保证了事务的可靠性和安全性。

关于事务的隔离性,它可分为四种级别:读取未提交、读取已提交、可重复读和串行化。这些级别提供了不同级别的数据隔离和并发性能。例如,在串行化级别,所有的事务都会按照固定顺序执行,这可以确保数据的一致性,但可能会降低并发性能。

我们可以通过查询语句查看当前数据库的默认隔离级别。对于MySQL 8.x,GLOBAL表示系统级别的隔离级别,而不加表示会话级别的隔离级别。

手动开启事务并理解其ACID特性和隔离性,是数据库管理的重要部分。它确保了我们能够安全、有效地管理数据,维护数据库的完整性和准确性。MySQL数据库中的事务隔离级别及其操作

我们来查看MySQL的默认事务隔离级别:

通过执行SQL命令 `SELECT @@GLOBAL.TX_ISOLATION;` 和 `SELECT @@TX_ISOLATION;`,我们可以了解到当前的隔离级别设置。为了深入了解事务隔离,让我们修改隔离级别为“READ UNCOMMITTED”(读取未提交)。执行命令:`SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;`后,查询全局的隔离级别确认是否已更改。

事务隔离级别之READ COMMITTED的深入理解与应用

当我们把数据库的隔离级别设置为`READ COMMITTED`时,意味着每个新接入的事务只能查询到已经提交的事务数据。这一设置确保了数据在事务间的正确性和一致性。

让我们通过一个简单的示例来深入理解这一点。假设我们有一个数据库,里面存储了用户资金的信息。当某个事务正在对某个用户的资金进行更新操作时,如将"狼蚁网络推广"的资金减少800元,同时将"淘宝店"的资金增加800元,这时我们设定数据库的隔离级别为`READ COMMITTED`。

在这一隔离级别下,当前正在进行的事务看到的仍然是数据表中的临时变化,而不是真正已经提交过的数据。也就是说,如果在事务完成提交前,其他事务尝试查询相同的数据,它们将看到的是尚未更新的数据。这确保了每个事务的独立性和数据的完整性。

举个例子,如果在当前事务尚未提交的情况下,另一个远程事务连接到了数据库,这个新事务只能查询到已经提交的数据,而无法看到当前事务尚未完成的更改。这就避免了数据在多个事务间的冲突和不一致性。

这种设置也存在潜在的问题。假设一个事务正在进行数据操作,其他试图访问同一数据的事务可能会被阻塞或产生不可预测的结果。这是因为`READ COMMITTED`隔离级别要求每次读取数据时都要等待之前的所有事务完成并提交,以确保数据的准确性。这种等待可能会导致系统性能的下降或事务的延迟。

小张在进行数据查询时,发现用户表的数据如下:

```sql

+-+--+-+

| id | name | money |

+-+--+-+

| 1 | a | 900 |

| 2 | b | 1100 |

| 3 | 狼蚁网络推广 | 200 |

| 4 | 淘宝店 | 1800 |

+-+--+-+

```

```sql

+-+--+-+

| id | name | money |

+-+--+-+

| 1 | a | 900 |

| 2 | b | 1100 |

| 4 | 淘宝店 | 1000(同样被更改)|

+-+--+-+

```

小张再求表中money的平均值时,结果出现了偏差。尽管使用的是READ COMMITTED隔离级别,能够确保读取到的数据是其他事务已经提交的,但在读取同一个表的数据时,仍可能出现前后不一致的情况。这就是所谓的不可重复读现象。

为了解决这个问题,我们可以采取一种名为“串行化”的策略。串行化是一种事务隔离级别,它确保了事务的原子性、一致性、隔离性和持久性(ACID特性)。在这种隔离级别下,所有事务的写入操作都被视为串行执行的。这意味着事务会按照一个固定的顺序执行,确保每次只有一个事务能够写入数据。

串行化隔离级别确保了数据库操作的原子性和一致性,但也带来了性能上的损失,因为它限制了并发操作的能力。在实际应用中,我们需要根据具体需求和场景来选择合适的隔离级别。对于需要高并发写入操作的场景,可能需要考虑其他隔离级别或优化策略。对于MySQL数据库的其他相关内容,读者可以通过阅读相关专题文章来深入了解。希望这篇文章对大家理解和使用MySQL数据库有所帮助。对于进一步的和研究,让我们继续深入这个领域,寻找更多的知识和见解。这样我们能更好地理解和利用这个强大的工具,为我们的生活和工作带来更多的便利和效率。同时提醒一下,实际操作时务必小心谨慎,确保数据的完整性和安全性。

上一篇:PHP实现适用于文件内容操作的分页类 下一篇:没有了

Copyright © 2016-2025 www.168986.cn 狼蚁网络 版权所有 Power by