MySQL索引、事务与存储引擎

目录

1、索引

1.1、索引的概念

1.2、索引的作用

索引的副作用

1.3索引的应用场景

1.4创建索引的原则

1.5索引的分类

MySQL的事务具有ACID四大特性

脏读(读取未提交数据):

幻读

丢失更新:

mysql及事务隔离级别(四种)

创建索引全过程


1、索引

1.1、索引的概念

数据库索引

是一个排序的列表,存储着索引值和这个值所对应的物理地址

无须对整个表进行扫描,通过物理地址就可以找到所需数据

是表中一列或者若千列值排序的方法

需要额外的磁盘空间

索引是一个排序的列表,在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址(类似于c语言的链表通过指针指向数据记录的内存地址)

使用索引后可以不用扫描全表来定位某行的数据,而是先通过索引表找到该行数据对应的物理地址然后访问相应的数据,因此能加快数据库的查询速度。

索引就好比是一本书的目录,可以根据目录中的页码快速找到所需的内容。

索引是表中一列或者若千列值排序的方法

建立索引的目的是加快对表中记录的查找或排序

当我们想要在一本书中找到特定的内容时,我们通常会使用目录或索引来帮助我们快速定位。在数据库中,索引的作用类似于书的目录,它是为了提高查询效率而创建的一种数据结构。

索引可以被看作是对数据库表中某个列(0或多个列)的快速引用,它类似于一个目录页,列出了表中数据的关键信息和对应的位置。通过创建索引,数据库可以更有效地搜索和过滤数据,从而加快查询操作的速度。

换句话说,索引就像是在数据库表上建立的一个引导,告诉数据库在哪里可以快速找到某个特定的数据行。它提供了一种快速访问数据的方式,避免了每次查询都需要扫描整个数据表的开销。使用索引,数据库可以直接跳转到包含所需数据的位置,大大减少了查询的时间和资源消耗。

然而,索引也并非没有代价。索引需要占用额外的存储空间,并且当数据发生变化时,索引也需要进行更新,增加了写入操作的开销。因此,在设计索引时需要平衡查询性能和存储成本之间的权衡。

总的来说,索引就是一种数据库中的引导结构,用于快速定位和访问数据,提高查询操作的效率。它可以加速数据检索,提升数据库的性能,但需要适当地进行设计和管理以获得最佳的效果。

1.2、索引的作用

数据库利用各种快速定位技术,能够大大加快查询速率

当表很大或查询涉及到多个表时,可以成干上万倍地提高查询速度

可以降低数据库的IO成本,并且还可以降低数据库的排序成本

通过创建唯一性索引保证数据表数据的唯一性

可以加快表与表之间的连接

在使用分组和排序时,可大大减少分组和排序时间

索引的副作用

索引需要占用额外的磁盘空间。 对于 MyISAM 引擎而言,索引文件和数据文件是分离的,索引文件用于保存数据记录的地址。而InnoDB引擎的表数据文件本身就是索引文件。当表很大或查询涉及到多个表时,可以成干上万倍地提高查询速度

在插入和修改数据时要花费更多的时间,因为索引也要随之变动

1.3索引的应用场景

  1. 加快查询速度:索引最常见的用途就是提高查询操作的速度。当数据库表中的数据量庞大时,通过在查询经常使用的列上创建索引,可以极大地减少数据的扫描和比较次数,从而加速查询操作。

  2. 约束唯一性:索引可以用作唯一性约束,确保某个列或多个列的值在表中是唯一的。这样可以防止重复的数据插入,并且在查询和关联操作时提供了更高效的方式。

  3. 支持排序和分组:当需要对某个列进行排序或分组时,索引可以为这些操作提供更高效的执行方式。通过索引,数据库可以直接按照索引顺序获取数据,无需进行额外的排序操作。

  4. 加速连接操作:当进行多表连接查询时,索引可以极大地提升连接操作的效率。通过在连接列上创建索引,数据库可以更快地定位和匹配连接条件,从而减少连接操作的时间消耗。

  5. 提供快速的范围查询:当需要查询某个范围内的数据时,索引可以帮助数据库快速定位所需的数据块,提供快速的范围查询功能,例如日期范围查询、价格区间查询等。

1.4创建索引的原则

表的主键、外键必须有索引

记录数超过300行的表应该有索引

经常与其他表进行连接的表,在连接字段上应该建立索引

唯一性太差的字段不适合建立索引

更新太频繁地字段不适合创建索引

经常出现在where子句中的字段,特别是大表的字段应该建立索引

索引应该建在选择性高的字段上

索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引

1.5索引的分类

  1. 普通索引:普通索引是最基本的索引类型。它在数据库表的某个列上创建索引,用于加速对该列的查询操作。普通索引允许列中的重复值,并且可以包含空值。

  2. 唯一索引:唯一索引与普通索引类似,但其要求被索引的列中的值必须是唯一的,不允许重复值。唯一索引可以防止重复数据的插入,并提供唯一性约束。当对唯一索引列进行查询时,由于其保证了唯一性,数据库可以更快地定位到所需的行。

  3. 主键索引:主键索引是一种特殊的唯一索引,它对表中的主键列进行索引。主键是一列或一组列,用于唯一标识表中的每一行。主键索引的作用是快速定位到表中的特定行,因此主键索引通常是表中的主键或唯一标识符。

  4. 组合索引:组合索引(也称为复合索引或多列索引)是在多个列上创建的索引。它可以包含表中的多个列,并在这些列的组合上建立索引。组合索引可以加快涉及到索引的查询操作,尤其是对涉及多个列的查询条件。可以是单列上创建的索引,也可以是在多列上创建的索引。需要满足最左原则,因为select语句的where条件是依次人左往右执行的,所以在使用select语句查询时where条件使用的字顺序必须和组合紫引中的排序一致,否则紫引将不会生效。

  5. 全文索引:全文索引用于在文本数据(如文章、博客)中进行全文搜索。它不同于普通索引,可以在文本内容中进行关键字的模糊匹配,而不仅仅是对完整的值进行精确匹配。全文索引使得数据库可以高效地执行全文搜索和文本相关的查询。

对所有理解的索引做出案例演示

创建索引: 在创建表的时候,直接指定index0alter修改表结构的时候,进行add 添加index直接创建案引index0 PS:主键索引一》直接创建主键即可

MySQL的事务具有ACID四大特性

  1. 原子性(Atomicity):事务是一个原子操作单元,要么全部执行成功,要么全部失败回滚。在事务执行期间的任何时刻发生错误,系统会将数据回滚到事务开始之前的状态,确保数据库始终处于一致的状态。

  2. 一致性(Consistency):事务的执行使数据库从一个一致的状态转换到另一个一致的状态。这意味着只有符合数据库定义的规则和约束的数据才能被写入,否则会回滚到事务开始之前的状态。事务在执行过程中对数据进行的修改必须符合所有的约束条件和触发器等。

  3. 隔离性(Isolation):事务的隔离性确保每个事务在封闭的环境中运行,互不干扰。并发执行的多个事务之间应该相互隔离,以避免数据不一致的问题。事务的隔离级别可以通过设置来控制,常见的隔离级别包括读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)。

  4. 持久性(Durability):一旦事务提交成功,其所做的修改将永久保存在数据库中,即使系统发生故障也不会丢失。数据库通过将事务的日志记录写入磁盘来保证持久性。这样即使系统崩溃,一旦恢复正常,数据库可以使用事务日志来重新构建事务执行的结果。

以上是MySQL事务的ACID四大特性。这些特性确保了事务的正确性、可靠性和一致性,保护了数据的完整性,并提供了对并发操作的控制和隔离能力,以满足多用户同时访问数据库时的要求。

脏读(读取未提交数据):

脏读指的是读到了其他事务未提交的数据,未提交意味着这些数据可能会回滚,也就是可能最终不会存到数据库中,也就是不存在的数据。读到了并一定最终存在的数据,这就是脏读

  1. 假设有两个事务:事务A和事务B。

  2. 事务A开始并执行一个更新操作,但还没有提交。该更新操作改变了某个数据的值。

  3. 事务B开始,它需要读取这个数据。

  4. 事务B读取了事务A所做的未提交的修改,得到了被修改后的值。这个值实际上是不一致的,因为事务A还没有完成。

  5. 最后,事务A回滚或提交。如果事务A回滚,那么事务B读取到的数据就是无效的。

这个过程中,事务B读取到了未提交的数据,也就是脏数据。脏读可能会导致错误的结果和不一致的数据,因为事务A最终可能会回滚,而事务B却已经基于脏数据做了相应的操作。

为了避免脏读,可以使用数据库的隔离级别中的读已提交(Read Committed)或更高的级别,这样事务只能读取到已经提交的数据,而不会读取到未提交的数据。此外,良好的事务设计和合理的并发控制策略也是避免脏读的关键。

幻读

是指在并发事务中,一个事务在相同的查询条件下多次执行同一查询,但是结果集却不同。这是由于其他并发事务在查询之间插入、更新或删除了符合查询条件的数据所导致的。

举个例子:

假设有一个数据库表格,存储着学生的成绩信息。现在我们执行以下两个事务:

事务 A:

  1. 事务 A 首先执行查询操作,统计出学生数目为5。

  2. 在事务 A 执行查询后,事务 B 插入了一条新的学生记录。

事务 B:

  1. 事务 B 在事务 A 执行查询后,插入了一条新的学生记录。

此时,事务 A 再次执行相同的查询操作,但结果变为了6名学生。

这种情况被称为幻读。事务 A 感觉到了“幻觉”,因为在两次查询之间有新的数据插入,导致结果集发生了改变。虽然事务 A 之间没有修改或删除操作,但是由于事务 B 的插入操作,使得事务 A 感觉好像出现了新的数据。

幻读问题一般出现在较低的隔离级别(如可重复读)下,因为这些隔离级别只锁定了读取过的行或页,而没有锁定整个查询范围。为了避免幻读问题,可以使用更高的隔离级别(如串行化),或者在需要的情况下使用锁机制来限制并发操作。

丢失更新:

两个事务同时读取同一条记录,A先修改记录,B也修改记录(B不知道A修改过),B提交数据后B的修改结果覆盖了A的修改结果。

A30->40事务 先完成

B30 ->50 事务 后完成

B的事务结果会覆盖A的事务结果,最终值为50

mysql及事务隔离级别(四种)

  1. 读未提交(Read Uncommitted):最低的隔离级别,在该级别下,一个事务可以读取到其他事务未提交的数据,可能导致脏读、不可重复读和幻读问题。

  2. 读已提交(Read Committed):事务只能读取到已经提交的数据,避免了脏读的问题。但是可能会出现不可重复读和幻读的问题。

  3. 可重复读(Repeatable Read):在一个事务中多次读取同一数据时,保证每次读取的结果都是一致的,即不会出现不可重复读的问题。但可能会出现幻读的问题,即同一事务内多次查询同一个范围的数据时,发现有其他事务插入了新的数据。

  4. 串行化(Serializable):最高的隔离级别,要求事务串行执行,事务之间相互完全隔离,避免了脏读、不可重复读和幻读等问题。但会降低并发性能。

隔离级别的选择需要根据具体的业务需求和数据的一致性要求进行权衡。较高的隔离级别会增加数据的一致性,但可能影响并发性能;而较低的隔离级别则可以提高并发性能,但可能导致一些并发问题。

创建索引全过程

  1. 创建数据库表格:
CREATE DATABASE njzb; USE njzb;
2、创建数据表格并定义内容属性:
CREATE TABLE student ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50), age INT, grade VARCHAR(10) );
3、插入一条记录到表格中:
INSERT INTO student (name, age, grade) VALUES ('Alice', 18, 'A');
4、创建索引:
CREATE INDEX idx_name ON student (name);

 

  • 首先,我们创建了一个名为njzb的数据库,并将其设为当前使用的数据库。
  • 接下来,我们使用CREATE TABLE命令创建了一个名为student的表格。该表格包含了四个字段,分别是id(自增主键)、name(最大长度为50的字符串类型)、age(整数类型)和grade(最大长度为10的字符串类型)。
  • 我们使用INSERT INTO命令将一条记录插入到student表中,包含了姓名为'Alice',年龄为18,成绩为'A'的信息。
  • 最后,我们使用CREATE INDEX命令在student表的name字段上创建了一个名为idx_name的索引。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值