MySQL事务、索引、数据恢复和备份

MySQL事务、索引、数据恢复和备份

本章目标

  • 掌握MySQL的事务处理方法
  • 理解MySQL的ACID原则
  • 创建数据库索引
  • 了解MySQL数据库备份和恢复的几种方法
  • 掌握mysqldump命令导出数据
  • 掌握source命令导入数据

1. 使用事务插入多条成绩记录

事务(transaction)是指将一系列数据操作捆绑成为一个整体进行统一管理。如果某一事务执行成功,则在该事务中进行的所有数据更改均会提交,成为数据库中永久组成部分。如果事务执行时遇到错误且必须取消或回滚,则数据将全部恢复到操作前的状态,所有数据的更改均被清除。

1.1 为什么需要事务

在银行业务中有一条记账原则,则有借有贷,借贷相等。为了保证这种原则,每发生一笔银行业务,就必须确保会计账目上借方课程和贷方课程至少各记一笔,并且这两笔账要么同时成功,要么同时失败。如果出现只记录了借方课程,或者只记录了贷方课程的情况,就违反了记账原则,会出现记错账的情况。

为了解决这个问题,MySQL通过事务机制来保证数据的一致性。转账过程就是一个事务,它需要两条UPDATE语句来完成,这两条语句是一个整体。如果其中任何一个环节出现问题,则整个转账业务也应取消,两个账户中的余额应该恢复为原来的数据,从而确保转账前和转账后的余额总和不变。

1.2 什么是事务

事务:是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合(工作逻辑单元);

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

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

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

1.3 如何执行事务

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

2. 使用视图查看成绩记录

视图是基于SQL语句的结果集的可视化的表,是一个虚拟表。对查询执行的大多数操作也可在视图上进行。使用视图的原因有两个:一个是出于安全考虑,用户不必看到整个数据库的结构,而隐藏部分数据;另一个是符合用户日常业务逻辑,使他们更容易理解数据

2.1 为什么需要视图

在实际工作中,不同身份的用户所关注的数据库数据可能也有所不同。例如,企业的员工信息表中保存了该企业所有员工的详细信息,不同职位的人员对该表中查询的数据范围可能是不同的。根据企业的人力资源管理制度要求,企业的老板关注企业员工的全部信息,他可以浏览全体员工的全部记录;企业人力资源主管主要是查询全体员工目前的岗位、薪金和绩效;企业出纳员只能查询每个员工的薪金,不能也无权看到企业员工的其他信息;而作为这家企业的一名员工,只能查看本人记录,不得查看其他员工的任何信息。

如何提高表操作的安全性?我们可以把重复使用的复杂查询结果保存成视图,也可以以某表数据如员工信息表为基础,设定不同访问权限的视图,不同岗位的员工调用不同的视图来获得自己有权查看的相关数据,以保证数据访问的安全性。

2.2 什么是视图

视图是一种查看数据库中一个或多个表中数据的方法。视图是一种虚拟表,通常是作为来自一个或多个表的行货列的子集创建的。当然,它可以包含全部的行和列。但是,视图并不是数据库中存储数据值的集合,它的行和列来自查询引用的表。在执行时,它直接显示来自表中的数据

视图充当着查询中的表筛选器的角色。定义视图的查询可以基于一个或多个表,也可以基于其他视图、当前数据库或其他数据库。

视图通常用来进行以下3中操作:

  • 筛选表中的行
  • 防止未经许可的用户访问敏感数据
  • 将多个物理数据表抽象为一个逻辑数据表

2.3 如何创建和使用视图

(1) 使用SQL语句创建视图

语法格式如下:

CREATE VIEW view_name  
   AS
    <SELECT 语句>;

(2)使用SQL语句删除视图

语法格式如下:

DROP VIEW [IF EXISTS] view_name;

(3)使用SQL语句查看视图数据

语法格式如下:

SELECT 字段1, 字段2, …… FROM view_name;

(4)使用视图的注意事项

  • 每个视图中可以使用多个表
  • 与查询类似,一个视图可以嵌套另一个视图,但最好不要超过3层
  • 对视图数据进行添加、更新和删除操作直接影响原表中的数据
  • 当视图数据来自多个表时,不允许添加和删除数据

3. 创建数据表索引

索引提供指针以指向存储咋表中指定列的数据值,再根据限定的排序次序排列这些指针。数据库使用索引的方式与使用书中的目录很相似;通过搜索索引找到特定的值,在跟随指针到达包含该值的行

3.1 什么是索引

索引是一种有效组合数据的方式,为快速查找到指定记录

在数据库中,由于数据存储在数据表中,因此索引是创建在数据库表对象上的,由表中的一个字段或多个字段生成的键组成,这些键存储在数据结构B-树或哈希表中,通过MySQL可以快速有效的查找与键值相关联的字段,根据索引的存储类型,可以将索引分为B-树索引(BTREE)和哈希索引(HASH)。InnoDB和MyISAM存储引擎支持B-树索引。

作用

  • 大大提高数据库的检索速度

  • 改善数据库性能

3.2 索引分类

MySQL中常用的索引有以下6类:

(1)普通索引

普通索引是MySQL中的基本索引类型,允许在定义索引的列中插入重复值和空值。它的唯一任务是加快对数据的访问速度。因此,应该只为那些最常出现在查询条件(WHERE)或排序条件(ORDER BY)中的数据列创建索引

(2)唯一索引

唯一索引不允许两行具有相同的索引值

如果现有数据中存在重复的键值,则一般情况下多数数据库不允许创建唯一索引。若已创建了唯一索引,则当插入心数据表中的键值重复时,数据库将拒绝接受此数据。例如,如果在trainee表中实习生的身份证号(Identity Card)列上创建了唯一索引,则所有实现的身份证号不能重复。创建了唯一索引的允许有空值。

提示:

若创建了唯一约束,则将自动创建唯一索引。尽管唯一索引有助于找到信息,但为了获得最佳性能,仍建议使用主键约束

(3)主键索引

在数据库中为表定义主键时将自动创建主键索引,主键索引是唯一索引的特殊类型。

主键索引要求主键中的每个值是非空、唯一的。当在查询中使用主键索引时,它还允许快速访问数据。

(4)复合索引

在创建索引时,并不是只能对其中一列创建索引,与创建主键一样,可以将多个列组合作为索引,这种索引称为复合索引。

需要注意的是,只有在查询中使用组合索引最左边的字段时,索引才会被使用,即第一个字段作为前缀的集合

(5)全文索引

全文索引的作用是在定义索引的列上支持值的全文查找,允许在这些索引列中插入重复值和空值。

全文索引可以在CHAR、VARCHAR或TEXT类型的列上创建,主要用于在大量文本文字中搜索字符串,此时使用全文索引的效率将大大高于使用SQL的LIKE关键字的效率。MySQL中只有MyISAM存储引擎支持全文索引。

(6)空间索引

空间索引是对空间数据类型的列建立的索引,如GEOMETRY、POINT等。创建空间索引的列,必须将其声明为NOT NULL,空间索引只能在存储引擎为MyISAM的表中创建

3.3 创建索引

创建索引语法格式如下:

CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
       ON table_name (column_name[length]);

其中:

  • UNIQUE|FULLTEXT|SPATIAL:分别表示唯一索引、全文索引和空间索引,为可选参数
  • index_name:指定索引名
  • table_name:指定创建索引的表名
  • column_name:指定需要创建索引的列
  • length:指定索引长度,可选参数,只有字符串类型才能指定索引长度

3.4 删除索引

删除索引的语法格式如下:

DROP  INDEX index_name ON table_name;

关于索引的删除需要注意以下两点:

  1. 删除表时,该表的所有索引将同时被删除
  2. 删除表中的列时,如果要删除的列时索引的组成部分,则该列也会从索引中删除。如果组成索引的所有列都被删除,则整个索引被删除

3.5 查看索引

在MySQL中,可以使用SHOW INDEX语句查看已创建的索引。语法格式如下:

SHOW INDEX FROM table_name;

例如,查看学生表中索引信息的代码如下:

SHOW INDEX FROM student\G;

执行结果如图所示:

在这里插入图片描述

其中各主要参数的含义如下:

  • Table:表示创建索引的表
  • Non_unique:表示索引是否是唯一,1代表是非唯一索引,0代表唯一索引
  • Key_name:表示索引的名称
  • Seq_in_index:表示该列在索引中的位置,如果索引是单列的,该值为1,组合索引为每列在索引定义中的顺序
  • Column_name:表示定义索引的列字段
  • Sub_part:表示索引的长度
  • Null:表示该列是否为空值
  • Index_type:表示索引类型

提示:

在查询语句后加“\G”,表示将结果集按列显示。这个功能在表中列较多,需要看表中各列的值时非常有用

3.6 创建索引的指导原则

按照下列标准选择建立索引的列

  • 频繁搜索的列可以作为索引
  • 经常排序,分组的列可作为索引
  • 经常用作连接的列(主键/外键) 可作为索引
  • 将索引放在一个单独的表空间中,不要放在有退役,临时段和临时表的表空间中
  • 对大型索引而言,考虑使用NOLOGGING子句创建大型索引
  • 根据业务数据发生的频率,定期重新生成或重新组织索引,并进行碎片整理
  • 仅包含几个不同值的列不可以创建为B树索引,可根据需要创建位图索引
  • 不要在仅包含几行的表中创建索引

请不要使用下面的列创建索引

  • 仅包含几个不同值的列
  • 表中仅包含几行

3.7 使用索引时注意事项

经验:

  • 查询时减少使用*返回全部列,不要返回不需要的列
  • 索引应该尽量小,在字节数小的列上建立索引
  • WHERE子句中有多个条件表达式时,包含索引列的表达式应置于其他条件表达式之前
  • 避免在ORDER BY子句中使用表达式

4. 数据库的备份和恢复

在任何数据库环境中,计算机系统的各种软硬件故障或者人为误操作导致的数据损害都是男避免的,为了防止数据丢失,将损失降到最低,定期对数据库进行备份是非常必要的,以便发生意外情况后可以及时恢复数据

4.1 使用mysqldump

mysqldump命令是MySQL中一个常用的备份命令,执行此命令会将包含数据的表结构和数据内容转换成相应的CREATE语句和INSERT INTO语句保存在文本文件中,将来如果需要还原数据,只需执行该文本文件中的SQL语句即可

(1)mysqldump命令格式

语法格式如下:

mysqldump [options] –u username –h host –ppassword 
dbname[tbname1[,tbname2……]]>filename.sql

其中:

  • username:表示用户名

  • host:表示登录用户的主机名称,如本机为主机可省略

  • password:表示登录密码

  • dbname:表示备份的数据库

  • tbname:表示需要备份的数据表,可指定多张表,为可选项,如备份整个数据库则此项省略

  • filename.sql:表示备份文件的名称

    以下示例为使用root账户登录到MySQL服务器,备份myschool数据库下的student表。

mysqldump -u root -p myschool student > C:\Users\Frank\student.sql

文件内容如下:

-- MySQL dump 10.13  Distrib 5.7.28, for Win64 (x86_64)
--
-- Host: localhost    Database: myschool
-- ------------------------------------------------------
-- Server version	5.7.28

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `student`
--

DROP TABLE IF EXISTS `student`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `student` (
  `studentNo` int(4) NOT NULL COMMENT '学号',
  `loginPwd` varchar(20) NOT NULL COMMENT '密码',
  `studentName` varchar(50) NOT NULL COMMENT '学生姓名',
  `sex` char(2) NOT NULL DEFAULT '男' COMMENT '性别',
  `gradeId` int(4) DEFAULT NULL,
  `phone` varchar(50) DEFAULT NULL COMMENT '联系电话',
  `address` varchar(255) DEFAULT NULL COMMENT '地址',
  `bornDate` datetime DEFAULT NULL COMMENT '出生时间',
  `email` varchar(50) DEFAULT NULL COMMENT '邮件账号',
  `identityCard` varchar(18) DEFAULT NULL COMMENT '身份证号码',
  PRIMARY KEY (`studentNo`),
  KEY `fk_student_grade` (`gradeId`),
  CONSTRAINT `fk_student_grade` FOREIGN KEY (`gradeId`) REFERENCES `grade` (`gradeID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `student`
--

LOCK TABLES `student` WRITE;
/*!40000 ALTER TABLE `student` DISABLE KEYS */;
INSERT INTO `student` VALUES (1,'1234','Tom','男',1,'13211111111',NULL,'1996-05-08 00:00:00',NULL,NULL);
/*!40000 ALTER TABLE `student` ENABLE KEYS */;
UNLOCK TABLES;

可以看到上述内容包含两种注释信息:

  • 以“–”开头:关于SQL语句的注释信息
  • “/*”开头、"*/"结尾:与MySQL服务相关的注释。这些语句可以被MySQL执行,但在其他数据库管理系统中将作为注释被忽略,可以提高数据库的可移植性

从备份文件中可以获取以下信息:

  • 备份文件使用的mysqldump工具的版本号
  • 备份账户的名称和主机信息以及备份的数据库名称
  • MySQL的服务器版本,这里是5.7.28
  • SET语句将当前系统变量的值赋给用户定义变量

mysqldump还有一些其他参数可以用来定制备份过程,如下表所示

参数描述
-add-drop-table在每个CREATE TABLE语句前添加DROP TABLE语句,默认是打开的,可以用-skip-add-drop-table来取消
–add-locks该选项会在INSERT 语句中捆绑一个LOCK TABLE 和UNLOCK TABLE 语句 好处:防止记录被再次导入时,其他用户对表进行的操作
-t或-no-create-info只导出数据,而不添加CREATE TABLE语句
-c或–complete-insert在每个INSERT语句的列上加上列名,在数据导入另一个数据库时有用
-d或–no-data不写表的任何行信息,只转储表的结构
-opt该选项是速记参数,等同于指定如下参数项:
–add-drop-tables–add-locking
–create-option
–disable-keys–extended-insert
–lock-tables–quick
–set-charset
它可以快速进行转储操作并产生一个能很快装入MySQL服务器的转储文件

提示:

mysqldump提供了许多参数,包括用于调试和压缩的参数,这里只列出部分常用参数,运行一下帮助命令可以获得当前版本的完整选项列表。

如法格式如下:

mysqldump --help

4.2 使用MySQL命令恢复数据库

对于备份数据库后生成包含有建库、建表、插入数据等SQL语句的文本文件,可以通过mysql命令还原到新的数据库中,实现数据库的恢复。该命令的语法格式如下:

mysql -u username -p [dbname] < filename.sql

其中:

  • username 表示用户名
  • dbname 表示数据库名
  • filename.sql 为执行数据库备份后生成的文件

该命令执行成功后,备份文件中的语句将在指定的数据库中恢复原有的数据

注意:

在执行该语句之前,必须在MySQL服务器中创建新数据库,如果不存在新数据库,恢复过程将会出错

现在使用上个示例中生成的student.sql文件,将myschool数据库中的student表信息恢复到schoolDB数据库中。需要执行的语句如下所示:

mysql -u root -p schoolDB < C:\Users\Frank\student.sql

在未创建schoolDB数据库时执行以上语句将会报错,使用CREATE创建之后,恢复数据库执行成功。

mysql命令是DOS环境下的恢复数据库命令,如果已经登录了MySQL服务器,也可以使用source命令恢复数据库。预防格式如下:

source filename;

其中,filename为数据库备份文件。

在执行source命令之前,同样需要先创建数据库,并且使用USE语句选择该数据库,否则将会出现错误。现将student.sql备份到myschoolDB2中,语句如下所示:

/*-- 创建数据库 --*/
CREATE DATABASE myschoolDB2;
USE myschoolDB2;
/*-- 恢复数据库 --*/
SOURCE C:/Users/Frank/student.sql

4.3 通过复制文件实现数据库备份和恢复

MySQL服务器中的数据在磁盘中是以文件形式保存的,所以可以直接复制MySQL数据库的存储目录以及文件进行备份。MySQL默认的数据库文件存储目录在不同的操作系统下有所不同,可以通过查看my.ini文件来找到本机数据库文件的存储目录,如图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传在这里插入图片描述

由于MySQL服务器的数据文件在服务运行期间总是处于打开和使用状态,这样会导致文件备份不一定有效。因此,在复制数据文件之前,需要先停止MySQL服务

这种方法虽然简单,但并不是最好的方法。一般情况下,MySQL服务在使用过程中不允许被停止,并且这种方法对InnoDB存储引擎的表不适用。使用这种方法备份的数据最好还原到相同版本的服务器中,不同的版本可能不兼容

注意:

使用此方法备份数据库时,为了保证所备份数据的完整性,在停止MySQL数据库服务器之前,需要先执行FLUSH TABLES语句将所有数据写入到数据文件中

4.4 表数据导出到文件文件

导出/导入数据——可实现数据库服务器间移动数据

导出操作是指将数据从MySQL数据表复制到文本文件。数据导出的方法有多种,这里主要介绍使用SELECT…INTO OUTFILE语句导出数据。其语法格式如下:

SELECT  [field_name]  FROM tablename 
 [WHERE contion]
  INTO OUTFILE 'filename' [OPTION]

从上述语法中可以看出,该导出语句分成以下两部分:

  1. 普通的数据查询语句,主要用来获取所要导出到文本文件中的数据
  2. 通过参数filename指定导出数据的目标文件

以下示例实现了将成绩表中Logic Java课程的成绩信息导出到result_Java.txt中,代码如下:

SELECT * FROM `result`
WHERE `subjectNo` = 
(SELECT `subjectNo` FROM `subject` 
WHERE `subjectName` = 'Logic Java')
INTO OUTFILE 'd:/backup/result_Java.txt;

打开d:/backup/result_Java.txt文件,内容如图所示:

在这里插入图片描述

4.5 文本文件导入到数据表

所谓导入操作,是指将数据从文件文件加载到MySQL数据库表里。同样,导入数据的方式也有很多种。本小节介绍使用LOAD DATA INFILE语句实现数据的导入,语法格式如下:

 LOAD DATA INFILE filename INTO TABLE tablename [OPTION]

其中:

  • filename:用来指定文本文件的路径和文件名
  • tablename:用来指定导入表的名称

以下示例实现了将上个示例中生成的文本文件导入到myschoolDB2的rensult表中。在导入数据之前,先创建result表结构,代码如下所示:

/*-- 创建result表结构 --*/
CREATE TABLE myschoolDB2.result AS SELECT * FROM myschool.`result` r WHERE 1=2;
/*-- 导入数据 --*/
LOAD DATA INFILE 'd:/backup/result_Java.txt' INTO TABLE myschooldb2.result;
/*-- 查看result表数据 --*/
SELECT * FROM myschooldb2.`result`;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值