听说Mysql你很豪横?-------------深入解析mysql数据库中的事务!

时间:2022-07-24
本文章向大家介绍听说Mysql你很豪横?-------------深入解析mysql数据库中的事务!,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

一、数据库的三大范式

总结 要有主键 列是唯一不能拆 每一列必须要跟主键有关系 不然不行

1、设置的范式(关系型数据库)

确保每列保持原子性 意思就是不可在分割 对列的定义

2、 确保表中的每列都和主键相关(不然东一句西一句就乱了) 每张表中只有一个主键 建立在第一范式之上的,一个表中只能保存一种数据 不可以把多种数据保存在同一张数据库表中~

3、确保每列都和主键列直接相关

二、事务(重要)

1、事务的重要性

安装软件的时候出现问题后回撤回到安装之前

相当于转账 当 我转给你的时候 需要在数据中 我的减掉10快 你的加上10块钱 结果对方没收到 这时候需要事务 撤回到没转账之前

2、什么是事务

  • 事务是一种机制、一个操作序列,包含了一组数据库操作命令,并且把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么都执行,要么都不执行 三条命令都执行成功 第四条执行不了 那么就会撤回之前的三条
  • 事务是一个不可分割的工作逻辑单元,在数据库系统上执行并发操作时,事务是最小的控制单元 适用于多用户同时操作的数据库系统的场景,如银行、保险公司及证券交易系统等等 通过事务的整体性以保证数据的一致性
  • 如果事务成功了一部分,一部分未成功,则执行回滚,回到事务的起点,重新开始操作

3、事务有什么特点(ACID四个特点)

  • 原子性(Atomicity) 事务是一个完整的操作,事务的各元素是不可分的(原子的) 事务中的所有元素必须作为一个整体提交或回滚 如果事务中的任何元素失败,则整个事务将失败
  • 一致性(Consistency) 当事务完成时,数据必须处于一致状态! 在事务开始之前,数据库中存储的数据处于一致状态; 在正在进行的事务中,数据可能处于不一致的状态;相当于转账过程中 我先减掉10 然后你在加10 总有一个先减一个后加 当事务成功完成时,数据必须再次回到已知的一致状态
  • 隔离性(Isolation) 对数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务 修改数据的事务可以在另一个使用相同数据的事务开始之前访问这些数据,或者在另一个使用相同数据的事务结束之后访问这些数据
  • 持久性(Durability)永久性 事务持久性指不管系统是否发生故障,事务处理的结果都是永久的 一旦事务被提交,事务的效果会被永久地保留在数据库中

4、怎么使用事务呢?

默认情况下 MySQL的事务是自动提交的,当sql语句提交时事务便自动提交

begin:开始一个事务 或者使用start 之后回滚到的状态 commit:提交一个事务 一旦提交就不会回滚了 事务就结束了 rollback:回滚一个事务 使用set命令进行控制 set autocommit=0:禁止自动提交 等同于begin 设置存档点 相当于拍个快照 set autocommit=1:开启自动提交 等同于执行了commit命令 rollback to +存档名字 回滚到某一存档点

(1)如何存档

如何存档?
格式:
savepoint <存档点名称>;
例如:
savepoint s1;
1

(2)如何回档

格式:
rollback  to <存档点名称>;
例如:
rollback to s1;		'//回到s1的存档点'
rollback;	'//回到begin'
'//rollback只能向前回滚,无法向后回滚'
'//commit提交后,事务结束,此时再次使用的rollback属于另一个新的事务,对于已经commit的事务没有任何作用'

(3)如何删档

三种情况 结束事物 1 、conmit 2、set autcommit=1 3、rollback

(4)实验观察

mysql> begin;   '开启事务'
Query OK, 0 row s affected (0.00 sec)

mysql> update zhu set hobby=5 where id=7;   '添加事务的sql'
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> savepoint a;   '保存a点的状态'
Query OK, 0 rows affected (0.00 sec)

mysql> select * from zhu;
+----+----------+-----+----------+-----------+-------+
| id | name     | age | school   | address   | hobby |
+----+----------+-----+----------+-----------+-------+
|  1 | gousehng |  24 | beida    | nanjing   |     1 |
|  2 | goupeng  |  28 | qinghua  | beijing   |     1 |
|  3 | ergouzi  |  27 | nankai   | shenzhen  |     1 |
|  4 | gouyan   |  23 | hafo     | guangzhou |     2 |
|  5 | goushi   |  24 | huangpu  | shanghai  |     2 |
|  6 | gougou   |  24 | lanxiang | hangzhou  |     3 |
|  7 | gouduzi  |  20 | hada     | haerbin   |     5 |
+----+----------+-----+----------+-----------+-------+
7 rows in set (0.00 sec)




mysql> update zhu set hobby=4 where id=7;   '在进行b点的操作'
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> savepoint b;       '保存b点的状态'
Query OK, 0 rows affected (0.00 sec)

mysql> rollback a;     '此时回滚到a'
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'a' at line 1
mysql> rollback to ^C
mysql> select * from zhu;   '检查表  发现已经回到了a的状态'
+----+----------+-----+----------+-----------+-------+
| id | name     | age | school   | address   | hobby |
+----+----------+-----+----------+-----------+-------+
|  1 | gousehng |  24 | beida    | nanjing   |     1 |
|  2 | goupeng  |  28 | qinghua  | beijing   |     1 |
|  3 | ergouzi  |  27 | nankai   | shenzhen  |     1 |
|  4 | gouyan   |  23 | hafo     | guangzhou |     2 |
|  5 | goushi   |  24 | huangpu  | shanghai  |     2 |
|  6 | gougou   |  24 | lanxiang | hangzhou  |     3 |
|  7 | gouduzi  |  20 | hada     | haerbin   |     4 |
+----+----------+-----+----------+-----------+-------+
7 rows in set (0.00 sec)

mysql> rollback to b;  ' 回滚到b'
Query OK, 0 rows affected (0.00 sec)

mysql> select * from zhu;   '查看b状态'
+----+----------+-----+----------+-----------+-------+
| id | name     | age | school   | address   | hobby |
+----+----------+-----+----------+-----------+-------+
|  1 | gousehng |  24 | beida    | nanjing   |     1 |
|  2 | goupeng  |  28 | qinghua  | beijing   |     1 |
|  3 | ergouzi  |  27 | nankai   | shenzhen  |     1 |
|  4 | gouyan   |  23 | hafo     | guangzhou |     2 |
|  5 | goushi   |  24 | huangpu  | shanghai  |     2 |
|  6 | gougou   |  24 | lanxiang | hangzhou  |     3 |
|  7 | gouduzi  |  20 | hada     | haerbin   |     4 |
+----+----------+-----+----------+-----------+-------+
7 rows in set (0.00 sec)

mysql> rollback to a;    '回滚到a状态也就是hobby=5的时候'
Query OK, 0 rows affected (0.00 sec)

mysql> select * from zhu;  '验证想法'
+----+----------+-----+----------+-----------+-------+
| id | name     | age | school   | address   | hobby |
+----+----------+-----+----------+-----------+-------+
|  1 | gousehng |  24 | beida    | nanjing   |     1 |
|  2 | goupeng  |  28 | qinghua  | beijing   |     1 |
|  3 | ergouzi  |  27 | nankai   | shenzhen  |     1 |
|  4 | gouyan   |  23 | hafo     | guangzhou |     2 |
|  5 | goushi   |  24 | huangpu  | shanghai  |     2 |
|  6 | gougou   |  24 | lanxiang | hangzhou  |     3 |
|  7 | gouduzi  |  20 | hada     | haerbin   |     5 |
+----+----------+-----+----------+-----------+-------+
7 rows in set (0.00 sec)

mysql> rollback to b;  '回滚到此时向后回滚  ,回滚到b发现回不去了 '
ERROR 1305 (42000): SAVEPOINT b does not exist
mysql> conmit;               '因为之前已经进行过回滚了,所以此时时间已经结束了 所以conmit会报错'
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'conmit' at line 1

三、Mysql存储引擎

1、什么是存储引擎?

MySQL中的数据用各种不同的技术存储在文件中,每一种技术都使用不同的存储机制、索引技巧、锁定水平并最终提供不同的功能和能力,这些不同的技术以及配套的功能在 MySQL中称为存储引擎 存储引擎就是 MySQL将数据存储在文件系统中的存储方式或者存储格式 目前 MySQL常用的两种存储引擎

  • MyISAM
  • InnoDB

MySQL系统中,存储引擎处于文件系统之上,在数据保存到数据文件之前会传输到存储引擎,之后按照各个存储引擎的存储格式进行存储

  • 从程序开发角度来说: 不同语言安装不同的驱动创建不同的connector connection pool中有多个对象(空闲的进程/线程) connector和connection pool的对象连接MySQL server
  • 连接池作用:优化连接效率 从系统角度: 依靠进程或者线程链接数据库的对象,就需要.sock文件创建pid去连接 具体文件内容通过存储引擎存储在硬盘上,通过各种管理工具(Management Server)管理

2、mysql数据库中常用的两种引擎

(1)MyISAM存储引擎

1、大文件(达到63位文件长度)在支持大文件的文件系统和操作系统上被支持

2、当把删除和更新及插入操作混合使用的时候,动态尺寸的行产生更少碎片。这要通过合并相邻被删除的块,以及若下一个块被删除,就扩展到下一块自动完成 3、每个MyISAM表最大索引数是64,这可以通过重新编译来改变。每个索引最大的列数是16

4、最大的键长度是1000字节,这也可以通过编译来改变,对于键长度超过250字节的情况,一个超过1024字节的键将被用上 5、BLOB和TEXT列可以被索引

6、NULL被允许在索引的列中,这个值占每个键的0~1个字节 7、所有数字键值以高字节优先被存储以允许一个更高的索引压缩

8、每个MyISAM类型的表都有一个AUTO_INCREMENT的内部列,当INSERT和UPDATE操作的时候该列被更新,同时AUTO_INCREMENT列将被刷新。所以说,MyISAM类型表 9、AUTO_INCREMENT列更新比InnoDB类型的AUTO_INCREMENT更快

10、可以把数据文件和索引文件放在不同目录 11、每个字符列可以有不同的字符集

12、有VARCHAR的表可以固定或动态记录长度 13、VARCHAR和CHAR列可以多达64KB 14、使用MyISAM引擎创建数据库,将产生3个文件。文件的名字以表名字开始,扩展名之处文件类型:frm文件存储表定义、数据文件的扩展名为.MYD(MYData)、索引文件的扩展名时.MYI(MYIndex)

(2) InnoDB存储引擎

1、InnoDB给MySQL提供了具有提交、回滚和崩溃恢复能力的事物安全(ACID兼容)存储引擎。InnoDB锁定在行级并且也在SELECT语句中提供一个类似Oracle的非锁定读。这些功能增加了多用户部署和性能。在SQL查询中,可以自由地将InnoDB类型的表和其他MySQL的表类型混合起来,甚至在同一个查询中也可以混合

2、InnoDB是为处理巨大数据量的最大性能设计。它的CPU效率可能是任何其他基于磁盘的关系型数据库引擎锁不能匹敌的

3、InnoDB存储引擎完全与MySQL服务器整合,InnoDB存储引擎为在主内存中缓存数据和索引而维持它自己的缓冲池。InnoDB将它的表和索引在一个逻辑表空间中,表空间可以包含数个文件(或原始磁盘文件)。这与MyISAM表不同,比如在MyISAM表中每个表被存放在分离的文件中。InnoDB表可以是任何尺寸,即使在文件尺寸被限制为2GB的操作系统上

4、InnoDB支持外键完整性约束,存储表中的数据时,每张表的存储都按主键顺序存放,如果没有显示在表定义时指定主键,InnoDB会为每一行生成一个6字节的ROWID,并以此作为主键

5、InnoDB被用在众多需要高性能的大型数据库站点上

6、InnoDB不创建目录,使用InnoDB时,MySQL将在MySQL数据目录下创建一个名为ibdata1的10MB大小的自动扩展数据文件,以及两个名为ib_logfile0和ib_logfile1的5MB大小的日志文件

(3)二者的区别

1、最大存储限制不同 mylsam最大存储是256Tb ionodb 最大存储 是64db

2、innodb支持事务 mysam不支持 3、如果要提供提交、回滚、崩溃恢复能力的事物安全(ACID兼容)能力,并要求实现并发控制,InnoDB是一个好的选择 如果数据表主要用来插入和查询记录,则MyISAM引擎能提供较高的处理效率

3、MyISAM引擎简介

MyISAM存储引擎是 MySQL关系数据库系统5.5版本之前默认的存储引擎,前身是ISAM ISAM是一个定义明确且历经时间考验的数据表格管理方法,在设计之时就考虑到数据库被查询的次数要远大于更新的次数

不支持事务 表级锁定形式,数据在更新时锁定整个表(不允许两个人同时来查询或更新) 数据库在读写过程中相互阻塞 会在数据写入的过程阻塞用户数据的读取 也会在数据读取的过程中阻塞用户的数据写入 可通过key_buffer_size来设置缓存索引,提高访问性能,减少磁盘I/O的压力 但缓存只会缓存索引文件,不会缓存数据 釆用 MyISAM存储引擎数据单独写入或读取,速度过程较快且占用资源相对少 MyISAM存储引擎它不支持外键约束,只支持全文索引

每个 MyISAM在磁盘上存储成三个文件,每一个文件的名字以表的名字开始,扩展名指出文件类型 MyISAM在磁盘上存储的文件 .frm文件存储表定义 表结构 describe 数据文件的扩展名为.MYD( MYData) 表数据 索引文件的扩展名是.MYI( MYIndex) 索引

1、什么生产场景适合使用MyISAM

  • 公司业务不需要事务的支持
  • 一般单方面读取数据比较多的业务,或单方面写入数据比较多的业务
  • MyISAM存储引擎数据读写都比较频繁场景不适合
  • 使用读写并发访问相对较低的业务
  • 数据修改相对较少的业务
  • 对数据业务一致性要求不是非常高的业务
  • 服务器硬件资源相对比较差- ISAM的特点
  • 优点:ISAM执行读取操作的速度很快
  • 优点:不占用大量的内存和存储资源
  • 缺点:不支持事务处理
  • 缺点:不能够容错

MyISAM管理非事务表,是lSAM的扩展格式 提供ISAM里所没有的索引和字段管理的大量功能 MyISAM使用一种表格锁定的机制,以优化多个并发的读写操作 MyISAM提供高速存储和检索,以及全文搜索能力,受到web开发的青睐

4、 InnoDB简介

InnoDB

(1)InnoDB有什么特点?

支持事务:支持4个事务隔离级别 行级锁定,但是全表扫描仍然会是表级锁定 ( 读写分离是最终解决方案)通过日志文件 读的数据量要大一点slave集群

读写阻塞与事务隔离级别相关 具有非常高效的缓存特性:能缓存索引,也能缓存数据 表与主键以簇(相当于一个个的小格子)的方式存储 支持分区、表空间,类似 oracle数据库 表空间 (是oracle公司外加的从5.7版本以后开始有的) 分为 共享表空间(逻辑层面 操作方面比较简单 容易控制) (表中的数据进而索引分散成多个文件进行存储)删除后会占用磁盘表空间 文件和文件之间的代码也是要占内存的 并且还删不点 独立表空间 (物理层面)(表中的数据和索引就是单独的空间) 支持外键约束 一张表的外建相当于另一张表的主键,5.5以前不支持全文索引,5.5版本以后支持全文索引 对硬件资源要求还是比较高的场合

(2)什么生产场景适合使用InnoDB?

高并发特征 内存大 支持事物 业务需要事务的支持 行级锁定对高并发有很好的适应能力,但需确保查询是通过索引来完成 业务数据更新较为频繁的场景,如:论坛,微博等 业务数据一致性要求较高,例如:银行业务 硬件设备内存较大,利用 Innodb较好的缓存能力来提高内存利用率,减少磁盘I/O的压力

(3)生产环境中依据什么选择存储引擎?

需要考虑毎个存儲引擎提供了哪些不同的核心功能及应用场景 支持的字段和数据类型 ●所有引擎都支持通用的数据类型 ●但不是所有的引擎都支持其它的字段类型,如二进制对象 锁定类型:不同的存储引擎支持不同级别的锁定 ●表锁定 mysam ●行锁定 inodb 索引的支持 ●建立索引在搜索和恢复数据库中的数据的时候能够显著提高性能 ●不同的存储引擎提供不同的制作索引的技术 ●有些存储引擎根本不支持索引 事务处理的支持 ●事务处理功能通过提供在向表中更新和插入信息期间的可靠性 ●可根据企业业务是否要支持事务选择存储引擎

5、如何配置存储引擎?

在企业中选择好合适的存储引擎之后,就可以进行修改了 修改步骤 ●查看数据库可配置的存储引擎 ●查看表正在使用的存储引擎 ●配置存储引擎为所选择的类型

使用 show engines查看系统支持的存储引擎
查看表使用的存储引擎
方法1:show table status from库名 where name=表名;
方法2:show create table表名;'//常用'
例如:
MySQL > show table status from yibiao where name='wangermazi'G 
'//使用G代替分号表示垂直显示结果'

(1)修改存储引擎的三种方法

共有四种方法
方法一:
alter table 修改;
格式:
alter table table_name engine=引擎;
例如:
MySQL> alter table user_info engin=mysam;
方法二:storage  存储
修改my.cnf,指定默认存储引擎并重启服务
格式:
default-storage-engine=InnoDB
例如:
vim my.cnf
default-storage-engine=innodb
1
方法三:
create table 创建表时指定存储引擎
格式:
create table 表名 (字段) engine=引擎
例如:
MySQL> create table yibiao(id int)engine=MyISAM;
1
已经移除!!
Mysql_convert_table_format转化存储引擎
格式:
Mysql_convert_table_format-user=root--password=密码--sock=/tmp/mysql.sock-engine=引擎 库名 表名
例如:
[root@localhost ~]# yum install perl-DBI perl-DBD-MySQL -y
[root@localhost ~]# /usr/local/mysql/bin/by   sql_convert_table_format --user=root --passwork='123' --sock