MySQL:事务、索引、用户管理、备份、数据库设计(三大范式)

news2025/2/27 21:00:44

文章目录

  • Day 03:
  • 一、事务
    • 1. 原则
    • 2. 测试实现
  • 二、索引
    • 1. 分类
    • 2. 创建索引
    • 3. 分析 sql 执行的状况
    • 4. 测试索引
    • 5. 索引原则
  • 三、数据库用户管理
  • 四、备份
  • 五、规范数据库设计
    • 1. 三大范式
  • 注意:

Day 03:

一、事务

事务(transaction):要么都成功,要么都失败。

核心:将一组 SQL 放在一个批次中去执行。

1. 原则

原则 ACID:原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)。

  • 原子性:一个事务中的所有步骤要么都成功,要么都失败,不能只成功一个步骤。
  • 一致性:包括最终一致性和过程一致性,一个事务操作前后的数据完整性保持一致
  • 持久性:事务结束后的数据不会因为外界原因(如服务器断电后重启)而导致数据丢失(一旦提交不可逆)。分为事务提交前和事务提交后。
情形结果
事务提交前恢复到原状
事务提交后持久化到数据库(成为文件)

注意事务一旦提交不可逆,被持久化到数据库中。

  • 隔离性:针对多个用户同时操作时,排除其他事务对本次事务的影响(多个进程互不干扰)。隔离失败会出现以下情形。
名词情形
脏读一个事务读取了另外一个事务未提交的数据
不可重复读在一个事务内读取表中的某一行数据,多次读取的结果不同
幻读(虚读)一个事务内读取到了别的事务插入的数据,导致前后读取不一致(一般是行影响,多了一行)

2. 测试实现

格式

-- 手动处理事务
SET autocommit = 0;   -- 关闭自动提交

START TRANSACTION;    -- 开启一个事务,这是标记一个事务的开始,从这之后的 sql 都在同一个事务内

UPDATE xxx;
INSERT xxx;   -- 事务内的操作

COMMIT;       -- 操作执行成功后 --> 提交事务
ROLLBACK;     -- 操作执行失败后 --> 回滚,回到原来的样子

SET autocommit = 1;   -- 恢复自动提交,事务结束

-- 了解
SAVEPOINT 保存点名;                -- 设置一个事务的保存点
ROLLBACK TO SAVEPOINT 保存点名;    -- 回滚到保存点
RELEASE SAVEPOINT 保存点名;        -- 撤销保存点

注意:MySQL 是默认开启事务自动提交的,即:autocommit = 1,所以在手动处理事务时,要关闭事务自动提交。

图解

需求:用事务实现转账操作

-- 用事务实现转账操作

-- 创建数据库 shop
CREATE DATABASE IF NOT EXISTS `shop` CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
USE `shop`;

-- 创建表 account
CREATE TABLE IF NOT EXISTS `account` (
    `id` INT(5) NOT NULL auto_increment COMMENT '序号', 
    `name` VARCHAR(10) NOT NULL DEFAULT 'Sun3285' COMMENT '姓名', 
    `money` DECIMAL(7, 2) NOT NULL DEFAULT 20000.85 COMMENT '余额', 
    PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT charset=utf8mb4;

-- 添加数据
INSERT INTO `account` (`id`, `name`, `money`) VALUES 
(1, 'Sun1234', 15000.12), 
(2, 'Sun3285', 26000.70), 
(3, 'Sun1478', 23000.93);

-- 模拟转账:事务
SET autocommit = 0;   -- 关闭自动提交

START TRANSACTION;    -- 开启一个事务

UPDATE `account` SET `money`=`money`-2000.12 WHERE `name`='Sun1234';
UPDATE `account` SET `money`=`money`+2000.12 WHERE `name`='Sun3285';  -- Sun1234 给 Sun3285 转账 2000.12

COMMIT;  -- 提交事务
ROLLBACK;  -- 回滚

SET autocommit = 1;   -- 恢复自动提交

注意:

  • DECIMAL(M,D) 中,M 是最大位数,D 是小数点右边的位数,D 不大于 M。如:DECIMAL(5,2) 可存储范围是从 -999.99 到 999.99,超出存储范围会报错,使用 DECIMAL 时,建议参数 M 和 D 手动指定,并按需分配。
  • 事务一旦提交不可逆,被持久化到数据库中


二、索引

索引(Index):是帮助 MySQL 高效获取数据的数据结构

索引的本质是数据结构。

1. 分类

索引分为:主键索引(PRIMARY KEY)、唯一索引(UNIQUE KEY)、常规索引(KEY/INDEX)以及全文索引(FULLTEXT KEY)。

索引说明
主键索引 PRIMARY KEY唯一标识,不可重复,只能有一个列作为主键
唯一索引 UNIQUE KEY避免重复的列出现,可以重复,多个列都可以标识为唯一索引
常规索引 KEY/INDEX默认,用 KEY 或 INDEX 关键字来设置
全文索引 FULLTEXT KEY快速定位数据

注意:一个表中主键索引只能有一个,而唯一索引可以有多个。

2. 创建索引

创建索引可以有两种方法

  • 创建表的时候给字段增加索引

  • 创建表完毕后,增加索引
SHOW INDEX FROM `表名`;  -- 显示所有的索引信息

ALTER TABLE `表名` ADD FULLTEXT/UNIQUE/PRIMARY INDEX/KEY `索引名` (`字段名`);  -- 改变表,增加一个索引

3. 分析 sql 执行的状况

EXPLAIN 关键字可以分析 sql 执行的状况,分为非全文索引全文索引

  • 非全文索引
EXPLAIN SELECT xxx;

  • 全文索引
EXPLAIN SELECT * FROM `表名` WHERE MATCH(`全文索引字段`) against('查找的内容');

4. 测试索引

创建 app_user 表,并插入百万条数据,查询信息。

-- 创建数据库 use
CREATE DATABASE IF NOT EXISTS `use` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE `use`;

-- 创建表 app_user 
CREATE TABLE IF NOT EXISTS `app_user` (
	`id` BIGINT(20) UNSIGNED NOT NULL auto_increment COMMENT '用户id', 
	`name` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '用户昵称', 
	`email` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '用户邮箱', 
	`phone` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '手机号', 
	`gender` TINYINT(4) UNSIGNED NOT NULL DEFAULT 0 COMMENT '性别(0:男; 1:女)', 
	`password` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '密码', 
	`age` TINYINT(4) NOT NULL DEFAULT 0 COMMENT '年龄', 
	`creat_time` DATETIME DEFAULT CURRENT_TIMESTAMP, 
	`update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
	PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT charset=utf8mb4 COMMENT='app用户表';

-- 百万数据插入
DROP FUNCTION IF EXISTS mock_data; 
DELIMITER $$  -- 写函数之前必须要写,标志:$$
CREATE FUNCTION mock_data()
RETURNS INT -- 注意returns,否则报错。
DETERMINISTIC -- 8.0版本需要多这么一行
BEGIN
	DECLARE num INT DEFAULT 1000000; -- num 作为截止数字,定义为百万,
	DECLARE i INT DEFAULT 0;
	WHILE i < num DO
		INSERT INTO app_user (`name`, `email`, `phone`, `gender`, `password`, `age`) VALUES 
		(CONCAT('用户', i), '123456789@qq.com', CONCAT('13', FLOOR(RAND()*(999999999-100000000)+100000000)), FLOOR(RAND()*2), 
		UUID(), (FLOOR(RAND()*100))+1);
		SET i = i + 1;
	END WHILE;
	RETURN i;
END;
SELECT mock_data();

  • 未设置索引时,查询某一条数据,用 EXPLAIN 分析执行情况;

  • 设置索引后,再次查询同一条数据,用 EXPLAIN 分析执行情况;

注意:索引在小数据量的时候,用处不大,但是在大数据量的时候,效果明显(查询时间减少)。

5. 索引原则

  • 索引不是越多越好;
  • 不要对经常变动的数据增加索引;
  • 小数据量的表不需要加索引;
  • 索引一般加在常用来查询的字段上。

三、数据库用户管理

  • Navicat 可视化操作

注意

  1. 用户名可以随便设置,一个用户对应一个密码主机是指在哪个地方登录,为 localhost127.0.0.1
  2. 新建连接(数据库管理系统与数据库之间的连接)时,连接名可以随便设置,每个用户都可以新建多个连接。
  • SQL 命令操作
-- 创建用户:CREATE
CREATE USER '用户名'@'%' IDENTIFIED BY '密码';    -- 所有 IP 都可用账号
CREATE USER '用户名'@'localhost' IDENTIFIED BY '密码';   -- 本地可用账号
CREATE USER '用户名'@'指定 IP' IDENTIFIED BY '密码';      -- 指定 IP 可用账号

-- 修改用户密码:ALTER
ALTER USER '用户名'@'localhost' IDENTIFIED BY '新密码';

-- 修改用户名或主机:RENAME
RENAME USER '用户名'@'localhost' TO '新用户名'@'127.0.0.1';  -- 同时也可以修改主机

-- 用户授权:除了给用户授权(GRANT),其他都可以干:GRANT
GRANT ALL PRIVILEGES ON *.* TO '用户名'@'127.0.0.1';
GRANT ALL PRIVILEGES ON *.* TO '用户名'@'127.0.0.1' WITH GRANT OPTION;

-- 刷新权限:FLUSH
FLUSH PRIVILEGES;

-- 查询权限:SHOW
SHOW GRANTS FOR '用户名'@'127.0.0.1';

-- 撤销权限:REVOKE
REVOKE 某个权限 ON *.* FROM '用户名'@'127.0.0.1';            -- 撤销某个权限
REVOKE ALL PRIVILEGES ON *.* FROM '用户名'@'127.0.0.1';     -- 撤销全部权限

-- 删除用户:DROP
DROP USER '用户名'@'127.0.0.1';

注意

  1. 表示方式用户名@主机 ,如:Sun3285@localhost
  2. 用户授权后,除了给用户授权(GRANT OPTION),其他都可以干,若仍想要给用户授权功能,则用 WITH GRANT OPTION
  3. 用户授权时,*.* 表示 所有数据库.所有表 ,指对所有的表生效。

四、备份

备份的目的:保证重要数据不丢失;数据转移(把数据库给别人)。

备份的内容:表结构和数据,不包括查询和报表。

三种方式:直接拷贝物理文件、在可视化工具中(Navicat)手动导出、使用命令行导出。

  • 方式一:直接拷贝物理文件 data

  • 方式二:在可视化工具中(Navicat)手动导出,选择要导出的库或表,右键选择 转储 SQL 文件 以及 结构和数据

  • 方式三:使用命令行(Win + R 打开)导出。
-- 导出:mysqldump -h主机 -u用户名 -p 数据库 表名1 表名2 表xx > 导出路径(物理磁盘位置/文件名)
mysqldump -hlocalhost -uroot -p exercise > E:/sql_file/a.sql  -- 导出整个数据库
mysqldump -hlocalhost -uroot -p exercise1 grade subject > E:/sql_file/b.sql  -- 导出某个数据库的某几张表

-- 导入:source sql文件路径
mysql -uroot -p;      -- 先登录 mysql
use exercise1;        -- 选中要导入的数据库
source E:/sql_file/b.sql;     -- 导入指定的 sql 文件

注意

  1. 导出路径中不能有中文,否则乱码报错;
  2. 导出路径中的斜杠为正斜杠/ ,并且需要写导出后的文件名;
  3. 导出时-h 表示主机、-u 表示用户名、-p 表示密码、> 表示导出;
  4. 在命令行中,导出的语句不能以分号 ; 结尾,否则报错;
  5. 在导入 sql 文件时,要登录数据库,source 将指定的 sql 文件导入;
  6. 如果导入的是数据库,则不需要第二步,即不用选中要导入的数据库。


五、规范数据库设计

目的:节省内存空间、保证数据的完整性、方便开发系统。

软件开发中,关于数据库的设计步骤

  1. 收集信息、分析需求(用户表、分类表、文章表等等);
  2. 概要设计(设计关系图 E-R 图);
  3. 标识实体、把需求落地到每一个字段;
  4. 标识实体之间的关系。

注意:前台的每一个位置,对应的都是数据库里面的一个字段

1. 三大范式

  • 第一范式(1NF)

内容:原子性:保证每一列不可再分

  • 第二范式(2NF)

前提:满足第一范式

内容:每张表只描述一件事情

  • 第三范式(3NF)

前提:满足第一范式和第二范式

内容:确保数据表中的每一列数据都和主键直接相关,而不能间接相关

注意:规范数据库的设计需要考虑规范性性能的问题,两者寻求平衡

阿里手册规范:关联查询不能超过三张表

  • 考虑商业化的需求和目标(成本、用户体验等)时,数据库的性能更加重要;但考虑性能的时候,也需要适当考虑一下规范性
  • 考虑性能的做法
    • 故意给某些表增加一些冗余的字段,可以将多表查询变为单表查询;
    • 故意增加一些计算列(如统计总数),可以从大数据量降低为小数据量的查询。

注意:

  1. 事务 ACID 理解参考链接:点此进入。

  2. MySQL 索引的参考资料:CodingLabs - MySQL索引背后的数据结构及算法原理

  3. 在测试索引部分,查询男生人数总数的 sql 语句为:

SELECT SUM(1) FROM `app_user` WHERE `gender`=0;  -- 用 count(1)、count(*) 或 count(列名) 也可以
  1. InnoDB 的默认数据结构为:Btree。
  2. 数据库命名一般不用驼峰命名规则,因为数据库不区分大小写,而采用下划线

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/415655.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

含光热电站、有机有机朗肯循环、P2G的综合能源优化调度(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

『pyqt5 从0基础开始项目实战』04. 表格数据的初始化(保姆级图文)

目录导包和框架代码准备json数据文件表格数据接入1. 准备文件路径2. 读取json数据3. 将得到的json数据放入table设置单元格不可修改把数据中的数字转为映射内容完整代码总结欢迎关注 『pyqt5 从0基础开始项目实战』 专栏&#xff0c;持续更新中 欢迎关注 『pyqt5 从0基础开始项…

TiDB实战篇-备份恢复策略

简介 简要说明TiDB备份恢复策略。 备份的类型 热备 TiDB使用MVCC机制实现设备的。 冷备 需要停机备份。 温备 备份的时候只能读不能够写。 备份技术 逻辑备份 物理备份 物理备份的限制 基于复制的备份 复制恢复是最快的。&#xff08;TiDB CDC,TiDB Binlog&#xff…

【C语言】函数详解(嵌套调用和链式访问、声明及定义、递归)

简单不先于复杂&#xff0c;而是在复杂之后。 目录 1.函数的嵌套调用和链式访问 1.1 嵌套调用 1.2 链式访问 2. 函数的声明和定义 2.1 函数声明 2.2 函数定义 3. 函数递归 3.1 什么是递归&#xff1f; 3.2 递归的两个必要条件 3.2.1 练习1&#xff08;需要画图…

Spring Security实战(三)—— 自动登录与注销登录

目录 一、实现自动登录 1. 散列加密方案 2. 持久化令牌方案 二、注销登录 一、实现自动登录 自动登录是将用户的登录信息保存在用户浏览器的cookie中&#xff0c;当用户下次访问时&#xff0c;自动实现校验并建立登录态的一种机制。 Spring Security 提供了两种非常好的令牌&a…

C ++ 基础入门。加强变量、指针、结构体理解

1、 const放外面&#xff0c;值不可以改。只读 同理于指针 看const右侧紧跟着的是指针还是常量, 是指针就是常量指针&#xff0c;是常量就是指针常量 const 放外面&#xff0c;值不可以改 2、 所有的指针类型&#xff0c;包括结构体指针 double * int *都是和操作系统位数…

补充——spark RDD序列化和持久化

目录 RDD序列化 闭包检查&#xff1a; 序列化方法和属性 Kryo序列化框架&#xff1a; RDD持久化&#xff08;RDD persistence&#xff09; RDDCache缓存 RDD persist缓存 什么时候使用persist()? RDD CheckPoint 检查点 缓存和检查点区别 RDD序列化 闭包检查&#x…

JavaScript 的基础函数有哪些?

1、在 JavaScript 中将数组本地转换为对象 JavaScript 有一个原生函数 Object.fromEntries&#xff0c;可用于将任何输入数组转换为对象。 1.const anArray [ 2. [firstname, Paul], 3. [surname, Knulst], 4. [address, worldwide], 5. [role, Senior Engineer], 6. […

Java中的异常Exception和捕获,自定义异常

文章目录1. 异常概述1.1 什么是程序的异常1.2 异常的抛出机制1.3 如何对待异常2. Java异常体系2.1 Throwable2.2 Error 和 Exception2.3 编译时异常和运行时异常3. 常见的错误和异常3.1 Error3.2 运行时异常3.3 编译时异常4. 异常的处理4.1 异常处理概述4.2 捕获异常&#xff0…

springboot整合websocket

1.创建springboot项目&#xff0c;引入spring-boot-starter-websocket依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>全部依赖如下&#xff1a; &l…

JDBC之DAO层封装思想超详解

Mysql版本&#xff1a;8.0.26 可视化客户端&#xff1a;sql yog 编译软件&#xff1a;IntelliJ IDEA 2019.2.4 x64 运行环境&#xff1a;win10 家庭中文版 jdk版本&#xff1a;1.8.0_361 目录一、DAO是什么&#xff1f;二、案例演示2.1 准备数据2.2 创建bean包2.3 建立DAO包2.2…

Houdini>RBD(搅拌大米效果)并导出FBX到unity

Houdini&#xff1e;RBD(搅拌大米效果) 效果展示&#xff1a; 动图录制软件&#xff1a;Cockos Incorporated | LICEcap 参考链接&#xff1a;导出除了ABC外&#xff0c;比较小的FBX文件用法 目录&#xff1a; 一、引用模型的处理&#xff1a; 1、大米 模型创建 多层复制 …

Mybatis(六)缓存

缓存是Mybatis中非常重要的特性&#xff0c;Mybatis的一级缓存基于SqlSession实现&#xff0c;二级缓存基于Mapper实现。 一、缓存的使用 一级缓存默认开启&#xff0c;Mybatis提供了一个配置参数localCacheScope来控制一级缓存的级别&#xff0c;该参数的取值可以是session、…

【机器学习】P10 从头到尾实现一个线性回归案例

这里写自定义目录标题&#xff08;1&#xff09;导入数据&#xff08;2&#xff09;画出城市人口与利润图&#xff08;3&#xff09;计算损失值&#xff08;4&#xff09;计算梯度下降&#xff08;5&#xff09;开始训练&#xff08;6&#xff09;画出训练好的模型&#xff08;…

参加Matlab与AI讲座:使用深度强化学习训练走路机器人观后感

时间&#xff1a;2023年4月12日&#xff0c;周三&#xff0c;天气晴 地址&#xff1a;大连理工大学研教楼303 前言&#xff1a;Matlab其实有很多功能&#xff0c;我们所用的只是最基础最简单的部分&#xff0c;例如矩阵计算&#xff0c;画图等等。 随着强化学习的发展&#xff…

一般形式的S曲线公式推导

文章目录一、背景二、目标三、计算3.1 S曲线基本形式3.2 S曲线变换3.3 参数计算3.4 S曲线中心对称条件四、总结五、附件一、背景 S曲线因具备良好可控的平滑性、单调性、连续可导性等优点&#xff0c;常作为各类电机升降速曲线。当前多数S曲线的介绍文章未给出推导过程&#x…

SpringCloud微服务技术栈.黑马跟学(五)

SpringCloud微服务技术栈.黑马跟学 五今日目标1.初识elasticsearch1.1.了解ES1.1.1.elasticsearch的作用1.1.2.ELK技术栈1.1.3.elasticsearch和lucene1.1.4.为什么不是其他搜索技术&#xff1f;1.1.5.总结1.2.倒排索引1.2.1.正向索引1.2.2.倒排索引1.2.3.正向和倒排1.3.es的一些…

SpringMVC基本注解的使用和理解

SpringMVC基本注解的使用和理解 RequestParam注解 使用在方法入参位置&#xff0c;用于指定请求参数名称&#xff0c;将该请求参数绑定到注解参数位置。 属性&#xff1a;name:指定要绑定的请求参数名称&#xff1b; name属性和value属性互为别名。 required 和&#xff1a;指…

Java并发编程(8) —— AQS抽象同步队列详解

上一篇&#xff1a;Java并发编程(7) —— 锁的分类概述 在上一篇中我们提到并发包中的ReentrantLock类是一种可重入独占锁&#xff0c;其锁机制是基于AQS实现的。实际上&#xff0c;并发包java.util.concurrent.locks中的锁都是基于AQS 实现的。 一、AQS是什么 AbstractQueued…

13. unity粒子特效--发射模块、各种发射器形状、粒子渐变(颜色/大小)

1. 发射模块&#xff08;Emission&#xff09; 匀速发射&#xff1a; Rate over Time&#xff1a;每秒钟发射的粒子数 Rate over Distance&#xff1a;每移动一米发射的粒子个数 两者可指定其一&#xff1a;若仅指定Rate over Time&#xff0c;则粒子根据时间的变化进行发射&a…