MySQL:基础语法-3
MySQL:基础语法-3
记录一下 MySQL 基础的一些语法,便于查询,该部分内容主要是参考:bilibili 上 黑马程序员 的课程而做的笔记,由于时间有点久了,课程地址忘记了
上文MySQL:基础语法-1,MySQL:基础语法-2 主要记录了 DDL、DML、DCL、DQL 相关操作,该文主要记录一下数据库的事物,及数据库设计等内容
事物
概述
事务执行是一个整体, 所有的 SQL 语句都必须执行成功。如果其中有 1 条 SQL 语句出现异常, 则所有的 SQL 语句都要回滚,整个业务执行失败
MYSQL 中可以有两种方式进行事务的操作 :
手动提交事务
自动提交事务(默认)
MySQL 默认每一条 DML(增删改)语句都是一个单独的事务,每条语句都会自动开启一个事务,语句执行完毕自动提交事务,MySQL 默认开始自动提交事务
手动提交
SQL 语句:
- 开启事物:
start transaction;
- 提交事务:
commit;
- 回滚事务:
rollback;
执行成功的情况: 开启事务--->执行多条 SQL 语句--->成功提交事务
执行失败的情况: 开启事务--->执行多条 SQL 语句--->事务的回滚
事务原理
事务开启之后,所有的操作都会临时保存到事务日志中,事务日志只有在得到 commit 命令才会同步到数据表中,其他任何情况都会清空事务日志(rollback,断开连接)
事务的步骤:
- 客户端连接数据库服务器,创建连接时创建此用户临时日志文件
- 开启事务以后,所有的操作都会先写入到临时日志文件中
- 所有的查询操作从表中查询,但会经过日志文件加工后才返回
- 如果事务提交则将日志文件中的数据写到表中,否则清空日志文件。
回滚点
在某些成功的操作完成之后, 后续的操作有可能成功有可能失败, 但是不管成功还是失败, 前面操作都已经成功, 可以在当前成功的位置设置一个回滚点。可以供后续失败操作返回到该位置, 而不是返回所有操作, 这个点称之为回滚点。
回滚点的操作语句:
- 设置回滚点:
savepoint 回滚点名字
- 回到回滚点:
rollback to 回滚点名字
事务的隔离级别
事务的四大特性 ACID
事务特性 | 含义 |
---|---|
原子性:Atomicity | 每个事务都是一个整体,不可再拆分,事务中所有的 SQL 语句要么都执行成功, 要么都失败。 |
一致性:Consistency | 事务在执行前数据库的状态与执行后数据库的状态保持一致。 如:转账前2个人的总金额是 2000,转账后 2 个人总金额也是 2000 |
隔离性:Isolation | 事务与事务之间不应该相互影响,执行时保持隔离的状态。 |
持久性:Durability) | 一旦事务执行成功,对数据库的修改是持久的。就算关机,也是保存下来的。 |
事务的隔离级别
事务在操作时的理想状态: 所有的事务之间保持隔离,互不影响。因为并发操作,多个用户同时访问同一个数据。可能引发并发访问的问题:
并发访问的问题 | 含义 |
---|---|
脏读 | 一个事务读取到了另一个事务中尚未提交的数据 |
不可重复读 | 一个事务中两次读取的数据内容不一致,要求的是一个事务中多次读取时数据是一致的, 这是事务 update 时引发的问题 |
幻读 | 一个事务中两次读取的数据的数量不一致,要求在一个事务多次读取的数据的数量是一致的,这是 insert 或 delete 时引发的问题 |
MySQL 数据库的四种隔离级别
级别 | 名字 | 隔离级别 | 脏读 | 不可重复读 | 幻读 | 数据库默认隔离级别 |
---|---|---|---|---|---|---|
1 | 读未提交 | read uncommitted |
是 | 是 | 是 | |
2 | 读已提交 | read committed |
否 | 是 | 是 | Oracle 和 SQL Server |
3 | 可重复读 | repeatable read |
否 | 否 | 是 | MySQL |
4 | 串行化 | serializable |
否 | 否 | 否 |
隔离级别越高,性能越差,安全性越高
MySQL 事务隔离级别相关的命令
查询全局事务隔离级别
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)
设置事务隔离级别,需要退出 MySQL 再重新登录才能看到隔离级别的变化
set global transaction isolation level 级别字符串; -- 上面的隔离级别
事物隔离级别演示
前置准备
-- 创建数据表,并往里面添加相应数据
CREATE TABLE account (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10),
balance DOUBLE
);
-- 加入数据
INSERT INTO account (NAME, balance) VALUES ('zhangsan', 1000), ('lisi', 1000);
-- 查看数据
select * from account;
+----+----------+---------+
| id | NAME | balance |
+----+----------+---------+
| 1 | zhangsan | 1000 |
| 2 | lisi | 1000 |
+----+----------+---------+
2 rows in set (0.00 sec)
需要注意的是,后面的演示,起初数据都恢复成最开始的状态
脏读演示
问题描述:一个事务读取到了另一个事务中尚未提交的数据
解决脏读的问题:将全局的隔离级别进行提升,read commit 及其以上的隔离级别,即可阻止脏读发生
-- 设置数据库的隔离级别为最低
mysql> set global transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.00 sec)
-- 查看现在的隔离级别
mysql> select @@tx_isolation;
+------------------+
| @@tx_isolation |
+------------------+
| READ-UNCOMMITTED |
+------------------+
1 row in set (0.00 sec)
-- 窗口1:选择数据库,开启事物
mysql> use db1;
Database changed
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
-- 窗口2:选择数据库,开启事物
mysql> use db1;
Database changed
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
-- 窗口1:更新zhangsan和lisi的账户数据,但是不提交
mysql> update account set balance=balance-500 where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> update account set balance=balance+500 where id=2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
-- 窗口2:查看数据,居然发现数据变了!!!!
mysql> select * from account;
+----+----------+---------+
| id | NAME | balance |
+----+----------+---------+
| 1 | zhangsan | 500 |
| 2 | lisi | 1500 |
+----+----------+---------+
2 rows in set (0.00 sec)
-- 窗口1:回滚数据
mysql> rollback;
Query OK, 0 rows affected (0.03 sec)
-- 窗口2:再查看数据,数据又变了!!!
mysql> select * from account;
+----+----------+---------+
| id | NAME | balance |
+----+----------+---------+
| 1 | zhangsan | 1000 |
| 2 | lisi | 1000 |
+----+----------+---------+
2 rows in set (0.00 sec)
不可重复读的演示
问题描述:一个事务中两次读取的数据内容不一致,要求的是一个事务中多次读取时数据是一致的, 这是事务 update 时引发的问题
解决不可重复读的问题:将全局的隔离级别进行提升为 repeatable read 及其以上,才能保证在同一个事务中为了保证多次查询数据一致
-- 设置数据库的隔离级别为最低
mysql> set global transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)
-- 查看现在的隔离级别
mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| READ-COMMITTED |
+----------------+
1 row in set (0.00 sec)
-- 窗口2:选择数据库,开启事物
mysql> use db1;
Database changed
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
-- 窗口1:选择数据库,开启事物,并更新数据后提交
mysql> use db1;
Database changed
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> update account set balance=balance+500 where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> commit;
Query OK, 0 rows affected (0.01 sec)
-- 窗口2:查看数据,发现数据变了,在B窗口开启的同一个事物中,两次查询一个数据结果不同!
mysql> select * from account;
+----+----------+---------+
| id | NAME | balance |
+----+----------+---------+
| 1 | zhangsan | 1500 |
| 2 | lisi | 1000 |
+----+----------+---------+
2 rows in set (0.00 sec)
两次查询输出的结果不同,到底哪次是对的?不知道以哪次为准。 很多人认为这种情况就对了,无须困惑,当然是后面的为准。
但是:我们可以考虑这样一种情况, 比如银行程序需要将查询结果分别输出到电脑屏幕和发短信给客户, 结果在一个事务中针对不同的输出目的地进行的两次查询不一致, 导致文件和屏幕中的结果不一致, 银行工作人员就不知道以哪个为准了
幻读的演示
问题描述:一个事务中两次读取的数据的数量不一致,要求在一个事务多次读取的数据的数量是一致的,这是 insert 或 delete 时引发的问题
解决:使用 serializable 隔离级别,一个事务没有执行完,其他事务的 SQL 执行不了,可以挡住幻读,即:使用 serializable 隔离级别,一个事务没有执行完,其他事务的 SQL 执行不了,可以挡住幻读
但是,在 MySQL 中无法看到幻读的效果?
后续通过只是展示一下 serializable 隔离级别的效果
-- 设置数据库的隔离级别为最低
mysql> set global transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)
-- 查看现在的隔离级别
mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| SERIALIZABLE |
+----------------+
1 row in set (0.00 sec)
-- 窗口1:选择数据库,开启事物,查询记录
mysql> use db1;
Database changed
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select count(*) from account;
+----------+
| count(*) |
+----------+
| 2 |
+----------+
1 row in set (0.00 sec)
-- 窗口2:选择数据库,开启事物,添加一条记录,会等待,直到超时
mysql> use db1;
Database changed
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into account (name, balance) values ('wangwu', 1000);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
-- 窗口1:接着查询,发现数据不变
mysql> select count(*) from account;
+----------+
| count(*) |
+----------+
| 2 |
+----------+
1 row in set (0.00 sec)
-- 窗口1:提交事物
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
-- 窗口2:窗口1提交事物后,等待的语句马上执行,返回结果
mysql> insert into account (name, balance) values ('wangwu', 1000);
Query OK, 1 row affected (3.33 sec)
-- 窗口1:继续查询,发现还是没有变,这才是正常的!
mysql> select count(*) from account;
+----------+
| count(*) |
+----------+
| 2 |
+----------+
1 row in set (0.00 sec)
-- 窗口2:提交事物
mysql> commit;
Query OK, 0 rows affected (0.01 sec)
-- 窗口1:再次查询,这回终于变了
mysql> select count(*) from account;
+----------+
| count(*) |
+----------+
| 3 |
+----------+
1 row in set (0.00 sec)
数据库设计
数据规范化
范式:好的数据库设计对数据的存储性能和后期的程序开发, 都会产生重要的影响。建立科学的, 规范的数据库就需要满足一些规则来优化数据的设计和存储,这些规则就称为范式
目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。
满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF),其余范式以次类推。一般说来,数据库只需满足第三范式(3NF)就行了。
第一范式:1NF
数据库表的每一列都是不可分割的原子数据项,不能是集合、数组等非原子数据项。即表中的某个列有多个值时,必须拆分为不同的列。 简而言之,第一范式每一列不可再拆分,称为原子性。
以下的表格就不满足 1NF :
对其进行修改,令其满足 1NF:
第二范式:2NF
在满足第一范式的前提下,表中的每一个字段都完全依赖于主键。
所谓完全依赖是指不能存在仅依赖主键一部分的列。 简而言之, 第二范式就是在第一范式的基础上所有列完全依赖于主键列。
当存在一个复合主键包含多个主键列的时候, 才会发生不符合第二范式的情况。比如有一个主键有两个列,不能存在这样的属性,它只依赖于其中一个列,这就是不符合第二范式。
第二范式的特点:
- 一张表只描述一件事情。
- 表中的每一列都完全依赖于主键
有如下:
第三范式:3NF
在满足第二范式的前提下,表中的每一列都直接依赖于主键,而不是通过其它的列来间接依赖于主键。
简而言之,第三范式就是所有列不依赖于其它非主键列,也就是在满足 2NF 的基础上, 任何非主列不得传递依赖于主键。 所谓传递依赖, 指的是如果存在"A → B → C"的决定关系, 则 C 传递依赖于 A。因此, 满足第三范式的数据库表应该不存在如下依赖关系:主键列 → 非主键列 x → 非主键列 y
有如下:
三大范式小结
范式 | 特点 |
---|---|
1NF | 原子性:表中每列不可再拆分。 |
2NF | 不产生局部依赖,一张表只描述一件事情 |
3NF | 不产生传递依赖,表中每一列都直接依赖于主键; 而不是通过其它列间接依赖于主键。 |
MySQL:基础语法-3的更多相关文章
- MYSQL基础语法的使用
喜欢的朋友可以关注下,粉丝也缺. MYSQL介绍 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之 ...
- MYSQL从入门到放弃系列:mysql基础语法
Mysql基本语法 启动MySQL net start mysql 连接与断开服务器 mysql -h 地址 -P 端口 -u 用户名 -p 密码 跳过权限验证登录MySQL mysqld --ski ...
- mysql基础语法之(全文索引)
1.概要 InnoDB引擎对FULLTEXT索引的支持是MySQL5.6新引入的特性,之前只有MyISAM引擎支持FULLTEXT索引.对于FULLTEXT索引的内容可以使用MATCH()…AGAIN ...
- Mysql 基础语法1
MySQL的软件架构 1.开启MySQL服务器:以windows服务的形式开启,在cmd下net startmysql|net stop mysql,在cmd下使用mysqld –default-fi ...
- 一. MySQL基础语法
1. 案例库表 2. DQL语言(数据查询) 2.1 基础查询 -- 进入指定的库 USE myemployees; DESC employees; -- 使用SELECT查询字段 # 1.查询表中的 ...
- mysql基础语法及拓展到web中的sql注入
本来是想写下javaweb的mvc(tomcat, spring, mysql)的搭建, 昨天搭到凌晨3点, 谁知道jdbcTemplate的jar包不好使, 想死的心都有了, 想想还是休息一下, ...
- mysql 基础语法
以下为自己学习mysql 的一些笔记,以方便查询 目录 一. ALTER的 语法 二. 表的完整性约束 三. 索引的操作(mysql 数据库支持至少 16 个索引) 四. 视图的操作 五. 触发器的操 ...
- MySQL基础语法命令
1. 建表 创建MySQL数据表需要以下信息: 表名 表字段名 定义每个表字段 通用语法: CREATE TABLE table_name (column_name column_type); 实例: ...
- Mysql基础语法-建库-建表(增、删、改、查、表关联及子查询)
前言:MySQL是一个数据库管理系统,也是一个关系数据库.它是由Oracle支持的开源软件,MySQL可以在各种平台上运行UNIX,Linux,Windows等.可以将其安装在服务器甚至桌面系统上. ...
- Mysql基础语法
mysql SELECT VERSION(), CURRENT_DATE, now();select user(); create database pets;show databases; use ...
随机推荐
- VSCode一些设置
//每次保存后自动格式化 "editor.formatOnSave": true, // #每次保存的时候将代码按eslint格式进行修复 "editor.codeAct ...
- Reader字符输入流和InputStreamReader和FileReader
1.FileReader extends InputStreamReader extends Reader 其中,Reader字符输入流和InputStreamReader和FileReader为字 ...
- linu命令进阶篇
预备知识: 本实验要求实验者具备如下的相关知识. 前面我们学习了linux的文件系统,了解的文件系统的结构,也学了linux档案的属性和权限,以及其设定. 当我们执行命令操作一个文件的时候,却不知道这 ...
- tomcat快速发布备份脚本
一.说明 我们每次在tomcat中发布新war包,总是要经历[备份-停机-上传-启动]这几个部分,其中上传的环节和网速有极大相关性,要是网速很慢,那么整个发布的时间就会很长. 如果我们不借助于自动化发 ...
- 微信公众号jssdk分享接口onMenuShareAppMessage自定义的参数无效,微信分享失败原因
使用jssdk为jweixin-1.4.0.js updateTimelineShareData,安全域名接口也设置正确,可就是分享,转发朋友圈不成功. 解决方案:采用<script src=& ...
- mac的vssh用sftp连不上,报unexpected SSH2_MSG_UNIMPLEMENTED packet
- seo执行步骤
第一个金字塔策略这个很适用于大型网站,我想做过大型网站,特别是关键词比较多比较杂乱的站长来说,这个图太熟悉不过了,就算是没有见过,但实际操作中早就用到了这些手法.如果能把这个图领会透并实际应用,做一个 ...
- 启动Jenkins后无法访问,如何排错
做IT工作,使用各种工具的时候,遇到错误都是一堆英文,对于英语不好的人,看到报错可能就会心烦,我刚开始就是这种状态.后来,遇到问题,首先复制报错信息到百度上搜索,没有人请教的时候,你不能坐等问题自己解 ...
- 定要过python二级 选择题第5套
1. 2.. 3. https://zhidao.baidu.com/question/1952133724016713828.html 4. 5. 6. 7. 8. 9. 10. 11.
- YbtOJ#732-斐波那契【特征方程,LCT】
正题 题目链接:http://www.ybtoj.com.cn/contest/125/problem/2 题目大意 给出\(n\)个点的一棵树,以\(1\)为根,每个点有点权\(a_i\).要求支持 ...