索引

  • 索引特点:创建与维护索引会消耗很多时间与磁盘空间,但查询速度大大提高!

  • 在关系数据库中,如果有上万甚至上亿条记录,在查找记录的时候,想要获得非常快的速度,就需要使用索引。

  • 索引是关系数据库中对某一列或多个列的值进行预排序的数据结构。通过使用索引,可以让数据库系统不必扫描整个表,而是直接定位到符合条件的记录,这样就大大加快了查询速度。

例如,对于students表:

idclass_idnamegenderscore
11小明M90
21小红F95
31小军M88

如果要经常根据score列进行查询,就可以对score列创建索引:

1
2
ALTER TABLE students
ADD INDEX idx_score (score);

使用ADD INDEX idx_score (score)就创建了一个名称为idx_score,使用列score的索引。索引名称是任意的,索引如果有多列,可以在括号里依次写上,例如:

1
2
ALTER TABLE students
ADD INDEX idx_name_score (name, score);
  • 索引的效率取决于索引列的值是否散列,即该列的值如果越互不相同,那么索引效率越高。反过来,如果记录的列存在大量相同的值,例如gender列,大约一半的记录值是M,另一半是F,因此,对该列创建索引就没有意义。

  • 可以对一张表创建多个索引。索引的优点是提高了查询效率,缺点是在插入、更新和删除记录时,需要同时修改索引,因此,索引越多,插入、更新和删除记录的速度就越慢。

对于主键,关系数据库会自动对其创建主键索引。使用主键索引的效率是最高的,因为主键会保证绝对唯一。

MySQL索引的类型

1. 普通索引

  • 这是最基本的索引,它没有任何限制,比如上文中为title字段创建的索引就是一个普通索引,MyIASM中默认的BTREE类型的索引,也是我们大多数情况下用到的索引。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
01  –直接创建索引
02  CREATE INDEX index_name ON table(column(length))

03  –修改表结构的方式添加索引
04  ALTER TABLE table_name ADD INDEX index_name ON (column(length))

05  –创建表的时候同时创建索引
06  CREATE TABLE `table` (
07      `id` int(11) NOT NULL AUTO_INCREMENT ,
08      `title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
09      `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
10      `time` int(10) NULL DEFAULT NULL ,
11       PRIMARY KEY (`id`),
12       INDEX index_name (title(length))
13  )

14  –删除索引
15  DROP INDEX index_name ON table

2. 唯一索引

  • 与普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值(注意和主键不同)
  • 如果是组合索引,则列值的组合必须唯一,创建方法和普通索引类似。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
01  –创建唯一索引
02  CREATE UNIQUE INDEX indexName ON table(column(length))

03  –修改表结构
04  ALTER TABLE table_name ADD UNIQUE indexName ON (column(length))

05  –创建表的时候直接指定
06  CREATE TABLE `table` (
07      `id` int(11) NOT NULL AUTO_INCREMENT ,
08      `title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
09      `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
10      `time` int(10) NULL DEFAULT NULL ,
11      PRIMARY KEY (`id`),
12      UNIQUE indexName (title(length))
13  );

3. 全文索引(FULLTEXT

  • MySQL从3.23.23版开始支持全文索引和全文检索,FULLTEXT索引仅可用于 MyISAM 表;
  • 他们可以从CHARVARCHARTEXT列中作为CREATE TABLE语句的一部分被创建,或是随后使用ALTER TABLE CREATE INDEX被添加。
  • 对于较大的数据集,将你的资料输入一个没有FULLTEXT索引的表中,然后创建索引,其速度比把资料输入现有FULLTEXT索引的中速度更为快。
  • 不过切记对于大容量的数据表,生成全文索引是一个非常消耗时间非常消耗硬盘空间的做法。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
01  –创建表的适合添加全文索引
02  CREATE TABLE `table` (
03    `id` int(11) NOT NULL AUTO_INCREMENT ,
04    `title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
05    `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
06    `time` int(10) NULL DEFAULT NULL ,
07    PRIMARY KEY (`id`),
08    FULLTEXT (content)
09  );

10  –修改表结构添加全文索引
11  ALTER TABLE article ADD FULLTEXT index_content(content)

12  –直接创建索引
13  CREATE FULLTEXT INDEX index_content ON article(content)

4. 单列索引、多列索引

  • 多个单列索引与单个多列索引的查询效果不同,因为执行查询时,MySQL只能使用一个索引,会从多个索引中选择一个限制最为严格的索引。

5. 组合索引(最左前缀)

  • 平时用的SQL查询语句一般都有比较多的限制条件,所以为了进一步榨取MySQL的效率,就要考虑建立组合索引。例如上表中针对title和time建立一个组合索引:ALTER TABLE article ADD INDEX index_titme_time (title(50),time(10))
  • 建立这样的组合索引,其实是相当于分别建立了下面两组组合索引:
1
2
–title,time
–title

为什么没有time这样的组合索引呢?这是因为MySQL组合索引“最左前缀”的结果。简单的理解就是只从最左面的开始组合。并不是只要包含这两列的查询都会用到该组合索引,如下面的几个SQL所示:

1
2
3
4
5
6
1   –使用到上面的索引
2   SELECT * FROM article WHREE title='测试' AND time=1234567890;
3   SELECT * FROM article WHREE utitle='测试';

4   –不使用上面的索引
5   SELECT * FROM article WHREE time=1234567890;

小结

  • 通过对数据库表创建索引,可以提高查询速度。

  • 通过创建唯一索引,可以保证某一列的值具有唯一性。

  • 数据库索引对于用户和应用程序来说都是透明的。

有几个索引就有几组排序,索引越多占用空间越大,插入速度越慢查询的时候数据库自动分析然后挑一个最合适的索引

MySQL 事务

事务指逻辑上的一组操作,组成这个操作的各个单元,要么都成功,要么都不成功

MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!

  • 在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。
  • 事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。
  • 事务用来管理 insert,update,delete 语句

一般来说,事务是必须满足4个条件(ACID)::原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

  • **原子性:**一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
  • **一致性:**在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
  • **隔离性:**数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
  • **持久性:**事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显式地开启一个事务务须使用命令 BEGIN START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。

事务控制语句

  • BEGINSTART TRANSACTION 显式地开启一个事务;
  • COMMIT 也可以使用 COMMIT WORK,不过二者是等价的。COMMIT 会提交事务,并使已对数据库进行的所有修改成为永久性的;
  • ROLLBACK 也可以使用 ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;
  • SAVEPOINT identifierSAVEPOINT 允许在事务中创建一个保存点,一个事务中可以有多个 SAVEPOINT
  • RELEASE SAVEPOINT identifier 删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;
  • ROLLBACK TO identifier 把事务回滚到标记点;
  • SET TRANSACTION 用来设置事务的隔离级别。InnoDB 存储引擎提供事务的隔离级别有READ UNCOMMITTEDREAD COMMITTEDREPEATABLE READ SERIALIZABLE

MYSQL 事务处理方法

1、用 BEGIN, ROLLBACK, COMMIT来实现

  • BEGIN 开始一个事务
  • ROLLBACK 事务回滚
  • COMMIT 事务确认

2、直接用 SET 来改变 MySQL 的自动提交模式:

  • SET AUTOCOMMIT=0 禁止自动提交
  • SET AUTOCOMMIT=1 开启自动提交