MySQL事务机制、导入导出、数据表设计案例(六)

目录

    • 一、数据库事务机制
      • 1.1 undo和redo日志
      • 1.2 开启事务、提交事务、回滚事务
      • 1.3 事务的ACID属性
      • 1.4 事务的并发性
        • 1.4.1 业务案例1:抢车票
        • 1.4.2 业务案例2:转账
        • 1.4.3 业务案例3 电商涨价
        • 1.4.4 事务的序列化
    • 二、数据导出与导入
      • 2.1 SQL文件的导出与导入
      • 2.2 TXT文档的导入与导出
    • 三、综合案列:新闻管理系统数据库设计(表结构)
      • 3.1 功能分析
      • 3.2 数据表字段分析
      • 3.3 密码的加解密
      • 3.4 数据表的实现

一、数据库事务机制

事务机制: 避免写入直接操作数据文件,如果数据的写入直接操作数据 文件是非常危险的事情。例如:给员工涨工资,如果UPDATE语句执行过程中,系统重启了,那么就分不清哪个已经修改了,哪个还没修改。

  • RDBMS = SQL语句 + 事务(ACID)
  • 事务是一个或者多个SQL语句组成的整体,要么全部执行成功,要么全都执行失败。

1.1 undo和redo日志

利用日志来实现间接写入: MySQL共有5种日志文件,其中只有redo日志和undo日志与事务有关

MySQL事务机制、导入导出、数据表设计案例(六)_第1张图片

1.2 开启事务、提交事务、回滚事务

管理事务:

  1. 默认情况下,MySQL执行每条SQL语句都会自动开启和提交事务
  2. 为了让多条SQL语句纳入到一个事务之下,可以手动管理事务
# 开启事务
START TRANSACTION;
SQL语句
[COMMIT | ROLLBACK];
# COMMOT将操纵持久化到数据文件,提交事务;ROLLBACK事务回滚

例子:

# 开启事务
START TRANSACTION;

DELETE FROM t_emp;
DELETE FROM t_dept;

SELECT * FROM t_emp;
SELECT * FROM t_dept;

此时查询到的t_empt_dept都是空的,但是现在SELECT查询实际上是到redo日志文件中查询的。此时的表中的数据仍然存在,只要不提交事务,就不会和数据文件做同步。

# 提交事务,就会同步数据文件
# 将结果提交
COMMIT;
# 回滚,所有修改记录一起回滚。MySQL将日志文件打上标记
ROLLBACK;

1.3 事务的ACID属性

  1. 原子性

    一个事务中的所有操作要么全部完成,要么全部失败。事务执行后,不允许停留在中间某个状态。

  2. 一致性

    不管在任何给定的时间、并发事务有多少,事务必须保持运行结果的一致性。要求事务在并发的情况下不会数据的歧义。阻止事务之间相互读取临时数据。

    比如:A、B、C、D四人相互转账总和不变

  3. 隔离性

    隔离性要求事务不受其他并发事务的影响,如同在给定时间内,该事务是数据库唯一运行的事务。

    undo和redo日志中数据会被标记属于哪个事务

    默认情况下A事务,只能看到日志中该事务的相关数据。

  4. 持久性

    事务一旦提交,结果便是永久性的。即便发生宕机,仍然可以依靠事务日志完成数据的持久化。

1.4 事务的并发性

事务并发执行的情况下,由于事务的隔离性会给某些业务带来问题,因此要修改事务的隔离级别

事务的四个隔离级别

序号 隔离级别 功能
1 read uncommitted 读取未提交数据
2 read committed 读取已提交数据
3 repeatable read 重复读取
4 serializable 序列化

1.4.1 业务案例1:抢车票

MySQL事务机制、导入导出、数据表设计案例(六)_第2张图片

A事务先购买G8047车次1车厢1A坐席,还未提交订单。此时B事务应该能够读取到A事务的状态,即读取未提交数据,才不会发生冲突和A事务争抢该坐席。

修改事务的隔离级别

READ UNCOMMITTED 代表可以读取其他事务未提交的数据

MySQL事务机制、导入导出、数据表设计案例(六)_第3张图片

不设置隔离级别,默认读不到其他事务的临时数据。如下:

MySQL事务机制、导入导出、数据表设计案例(六)_第4张图片

修改隔离级别,如下:

MySQL事务机制、导入导出、数据表设计案例(六)_第5张图片

1.4.2 业务案例2:转账

只能读取其他业务提交以后的数据

在这里插入图片描述

A事务开启,还未操作。B事务将余额改为4900元,A事务转账在余额上加1000即可5900元,如果AB事务都COMMIT没问题。但如果B事务是错误的消费,需要退回,B事务执行ROLLBACK, 如果允许A事务读取B事务的临时数据,那就是4900+1000=5900,少了100块就不对了。

READ COMMITED 代表只能读取其他事务提交的数据

用法同上

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

1.4.3 业务案例3 电商涨价

在这里插入图片描述

A事务购买某商品,还未支付,B事务执行该商品涨价,所以客户下单购买应该是涨价之前的价格购买。因此当前的事务就不能受其他的事务影响。

事务执行之前会把数据拷贝到undo日志中,当repeatable read隔离级别只去读取undo日志中属于自己的那部分数据,因此不会收到其他事务的影响

REPEATABLE READ 代表事务在执行中反复读取数据,得到的结果是一致的,不会收到其他事务的影响。(默认的隔离级别)

用法同上

SET SESSION TRANSACTION  ISOLATION LEVEL REPEATABLE READ;

注意: 第一个session在commit之前,第二个session要启动事务设置,隔离并去查询才会将查询数据加载undo日志中,然后第一个session执行commit后在去第二个session查询数据,数据不受第一session的影响。

1.4.4 事务的序列化

由于事务并发执行所带来的各种问题,前三种隔离级别只适用在某些业务场景中,但是序列化的隔离性,让事务逐一执行,就不会产生上述问题。这种隔离级别使数据库的并发性极具下降,一般不用。

SET SESSION TRANSACTION  ISOLATION LEVEL SERIALIZABLE;

二、数据导出与导入

数据导出与备份的区别:

  • 数据导出,导出的纯粹是业务数据

  • 数据备份,备份的是数据文件、日志文件、索引文件等等

    备份第一次是全量备份,有了全量备份后以后的备份就是增量备份。

2.1 SQL文件的导出与导入

导出SQL文件:

导出sql文件,文件包含了表结构和业务数据

命令行方式:

# no-data可写可不写,表示是否要导出数据文件
# 逻辑库就是要导出的数据库,敲回车后然后输入密码,OK
mysqldump -uroot -p [no-data] 逻辑库 > 导出路径

图形化界面: 双击选中逻辑库—>右键存储SQL文件…

导入SQL文件:

命令行方式:

# 先进入要导入的逻辑库
USE demo;
# 然后导入,source后加路径和文件名
SOURCE 文件路径;

2.2 TXT文档的导入与导出

导出只有纯粹的文档,而不是SQL语句

等再次导入的时候,由于文本文档无SQL语句,MySQL执行导入的时候会跳过词法分析和语法优化,直接把文本文档里的数据写入到MySQL的数据文件中,导入的速度非常快,因此数据量大的时候很适合。

导出文本文件:

导出文本文档,把文本文档拿到其他的MySQL数据库上因不知道表结构没法还原,因此先备份表结构

图形化界面:

  1. 备份表结构: 选中某个表—>右键转储SQL文件—>仅结构
  2. 导出该表的数据: 选中该表—>右键导出向导—>.txt文本文件—> 选择要导出的数据表 …

导入文本文件:

图形化界面:

  1. 选中—>运行SQL文件—> 导入表结构(找到路径)

  2. 选中表—> 导入向导—> 选中.txt文档…跟着提示做。

    注意点: 第一个数据行 , 将txt文档的数据与表结构的映射关系选好

三、综合案列:新闻管理系统数据库设计(表结构)

3.1 功能分析

主要功能:

选择你要执行的操作

  1. 新闻列表
  2. 新建新闻
  3. 编辑新闻
  4. 退出

用例图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PCKcrFJ3-1690034255061)(C:\Users\zhao\AppData\Roaming\Typora\typora-user-images\1690018319575.png)]

3.2 数据表字段分析

新闻的属性:

MySQL事务机制、导入导出、数据表设计案例(六)_第6张图片

数据库的ER图:

:主键

◇: 唯一性约束

MySQL事务机制、导入导出、数据表设计案例(六)_第7张图片

3.3 密码的加解密

数据加密:

密码不能存储为明文,要进行加密

对称加密: 加密解密都是一个,加密速度快,可以短时间对大量数据加密,但是加密强度不如非对称加密,多用于文件加密。DES加密已被淘汰

非对称加密: 公钥和私钥,两把密钥都可以用来加密和解密,一个加密,另一个解密。加密强度高,加密的速度慢,主要用于互联网和电信领域。

MySQL事务机制、导入导出、数据表设计案例(六)_第8张图片

MySQL数据库提供了AES加密和解密的函数,所以数据的加密解密很容易实现

AES加密解密用法:

AES_ENCRYPT(原始数据, 密钥字符串)

例子:

# HEX()将二进制转换为十六进制
SELECT HEX(AES_ENCRYPT("你好世界", "ABC123456"));
# 输出结果:E85A104B6142A7375E53C0545CAD48EE

AES解密函数用法:

AES_DECRYPT(加密结果, 密钥字符串)

例子:

# UNHEX()是将十六进制转换为二进制
SELECT AES_DECRYPT(UNHEX("E85A104B6142A7375E53C0545CAD48EE"),"ABC123456");

3.4 数据表的实现

类型表的创建:

CREATE DATABASE vaga;
USE vaga;
CREATE TABLE t_type(
	id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
	type varchar(20) NOT NULL UNIQUE
);
INSERT INTO t_type(type) VALUES("要闻"), ("体育"), ("科技"), ("娱乐"), ("历史");

角色表的创建:

CREATE TABLE t_role(
	id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
	role VARCHAR(20) NOT NULL UNIQUE
);
INSERT INTO t_role(role)  VALUES("管理员"), ("新闻编辑");

用户表的创建:

CREATE TABLE t_user(
	id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
	username VARCHAR(20) NOT NULL UNIQUE,
	password VARCHAR(500) NOT NULL,
	email VARCHAR(100) NOT NULL,
	role_id INT UNSIGNED NOT NULL,
	INDEX (username)
);

插入两条数据:

INSERT INTO t_user(username, password, email, role_id) 
VALUES("admin", HEX(AES_ENCRYPT("123456","HelloWorld")), "[email protected]", 1);

INSERT INTO t_user(username, password, email, role_id) 
VALUES("scott", HEX(AES_ENCRYPT("123456","HelloWorld")), "[email protected]", 2);

新闻表的创建:

CREATE TABLE t_news(
	id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
	title VARCHAR(40) NOT NULL,
	editor_id INT UNSIGNED NOT NULL,
	type_id INT UNSIGNED NOT NULL,
	content_id CHAR(12) NOT NULL,
	is_top TINYINT UNSIGNED NOT NULL,
	create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
	update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
	state ENUM("草稿", "待审批", "已审批", "隐藏") NOT NULL,
	INDEX(editor_id),
	INDEX(type_id),
	INDEX(state),
	INDEX(create_time),
	INDEX(is_top)
);

新闻内容用MongoDB存,MongoDB用来存储大量低价值数据,速度快效率高

MongoDB中主键都是12个字符的字符串

你可能感兴趣的:(MySQL,mysql,数据库)