赞
踩
原理:
将一个查询结果当做一张表新建
这个可以完成表的快速复制
create table emp2 as select * from emp;
mysql> select * from emp2;
+-------+--------+-----------+------+------------+---------+---------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+--------+-----------+------+------------+---------+---------+--------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 |
| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |
+-------+--------+-----------+------+------------+---------+---------+--------+
//将查询结果创建成表
creat table dept_bak as select * from dept;
//将查询结果插入到表
insert into dept_bak select * from dept;
//删除dept_bak表中的数据
delete from dept_bak;
delete语句删除数据的原理?(delete属于DML语句)
表中的数据被删除了,但是这个数据在硬盘上的真实存储空间不会被释放
这种删除的缺点是:删除效率比较低
这种删除的优点是:支持回滚,后悔了可以在恢复数据
truncate语句删除数据的原理?
这种删除效率比较高,表被一次截断,物理删除
这种删除缺点:不支持回滚
这种删除优点:快速
用法:truncate table dept_bak
删除表操作?
drop table 表名;//这不是删除表中的数据,这是把表删除
约束对应的英语单词:constraint
在创建表的时候,我们可以给表中的字段加上一些约束,来保证这个表中数据的完整性、有效性
约束的作用就是为了保证:表中的数据有效
非空约束:not null
唯一约束:nuique
主键约束:primary key
外键约束:foreign key
检查约束:check(mysql不支持,oracle支持)
非空约束not null约束的字段不能为null
create table t_vip(
id int,
name varchar(255) not null
);
insert into t_vip values(01,'zhangsan');
insert into t_vip values(02,'lisi');
insert into t_vip(id) values(3); //报错
Field 'name' doesn't have a default value
小插曲:
xxx.sql这种文件被称为sql脚本文件
sql脚本文件中编写了大量的sql语句
我们执行sql脚本文件的时候,该文件中所有的sql语句会全部执行
批量的执行sql语句,可以使用sql脚本文件
在mysql中怎么执行sql脚本呢?
source 文件拖过来 但一定注意不能有中文
唯一性约束unique约束的字段不能重复,但是可以为null
drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255) unique, //unique 添加在列的后面时,这种约束被称为列级约束
email varchar(255)
);
insert into t_vip values(1,'zhangsan','zhangsan@123.com');
insert into t_vip values(2,'lisi','lisi@123.com');
insert into t_vip values(3,'wangwu','wangwu@123.com');
insert into t_vip values(4,'wangwu','wangwu@123.com');
ERROR 1062 (23000): Duplicate entry 'wangwu' for key 'name'
//unique不能重复 但是可以为null
insert into t_vip(id) values(4);
mysql> select * from t_vip;
+------+----------+------------------+
| id | name | email |
+------+----------+------------------+
| 1 | zhangsan | zhangsan@123.com |
| 2 | lisi | lisi@123.com |
| 3 | wangwu | wangwu@123.com |
| 4 | NULL | NULL |
+------+----------+------------------+
新需求:name和email两个字段联合起来具有唯一性!!!
意思是 只有name和email不同时相等 就可以插入进去数据
drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255),
email varchar(255),
unique(name,email) 没有添加到列的后面,这种约束被称为表级约束
);
insert into t_vip values(1,'zhangsan','zhangsan@123.com');
insert into t_vip values(2,'zhangsan','zhangsan@qq.com');
//ERROR 1062 (23000): Duplicate entry 'zhangsan-zhangsan@qq.com' for key 'name'
insert into t_vip values(3,'zhangsan','zhangsan@123.com');
需要给多个字段联合起来添加某一个约束的时候,需要使用表级约束
unique可以和not null 联合吗
drop table if exists t_vip;
create table t_vip(id int,name varchar(255) not null unique);
mysql> desc t_vip;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(255) | NO | PRI | NULL | |
+-------+--------------+------+-----+---------+-------+
主键约束的相关属于?
主键约束:就是一种约束
主键字段:该字段上添加了主键约束,这样的字段就叫做主键字段
主键值:主键字段中的每一个值都叫做:主键值
什么是主键?有什么用
主键值是每一行记录的唯一标识
主键值是每一行记录的身份证号
记住:任何一张表都应该有主键,没有主键,表无效
主键的特征:not null + unique(主键值不能是null,同时也不能重复)
怎么给字段设置主键呢?
drop table if exists t_vip;
create table t_vip(
id int primary key,
name varchar(255)
);
insert into t_vip(id,name) values(1,'zhangsan');
insert into t_vip(id,name) values(2,'zhangsan');
//报错
insert into t_vip(id,name) values(2,'zhangsan');
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'
使用表及约束添加主键可以吗?
drop table if exists t_vip;
create table t_vip(
id int ,
name varchar(255),
primary key(id,name)
);
insert into t_vip(id,name) values(1,'zhangsan');
insert into t_vip(id,name) values(2,'zhangsan');
insert into t_vip(id,name) values(2,'lisi');
insert into t_vip(id) values(2);
在实际开发中不建议使用:符合主键。建议使用单一主键
复合主键比较复杂,不建议使用
一个表中主键只能有一个,不能出现多个
主键除了:单一主键和复合主键之外,还额可以这样进行分类?
自然主键:主键值是一个自然数,和业务没关系
业务主键:主键值和业务紧密关联,例如拿银行卡账号做主键值,这就是业务主键
在实际开发中使用业务主键比较多,还是使用自然主键多一些呢?
自然主键使用比较好,因为主键只要做到不重复就行,不需要有意义
业务主键不好,因为主键一旦和业务挂钩,那么当业务发生变动的时候,可能会影响到主键值,所以业务
主键不建议使用。尽量使用自然主键
drop table if exists t_vip;
create table t_vip(
id int primary key auto_increment,
name varchar(255)
);
insert into t_vip(name) values('zhangsan');
insert into t_vip(name) values('zhangsan');
insert into t_vip(name) values('zhangsan');
insert into t_vip(name) values('zhangsan');
+----+----------+
| id | name |
+----+----------+
| 1 | zhangsan |
| 2 | zhangsan |
| 3 | zhangsan |
| 4 | zhangsan |
+----+----------+
* 关于外键约束的相关术语:
外键约束: foreign key
外键字段:添加有外键约束的字段
外键值:外键字段中的每一个值。
* 业务背景:
请设计数据库表,用来维护学生和班级的信息?
第一种方案:一张表存储所有数据
no(pk) name classno classname
-------------------------------------------------------------------------------------------
1 zs1 101 北京大兴区经济技术开发区亦庄二中高三1班
2 zs2 101 北京大兴区经济技术开发区亦庄二中高三1班
3 zs3 102 北京大兴区经济技术开发区亦庄二中高三2班
4 zs4 102 北京大兴区经济技术开发区亦庄二中高三2班
5 zs5 102 北京大兴区经济技术开发区亦庄二中高三2班
缺点:冗余。【不推荐】
第二种方案:两张表(班级表和学生表)
t_class 班级表
cno(pk) cname
--------------------------------------------------------
101 北京大兴区经济技术开发区亦庄二中高三1班
102 北京大兴区经济技术开发区亦庄二中高三2班
t_student 学生表
sno(pk) sname classno(该字段添加外键约束fk)
------------------------------------------------------------
1 zs1 101
2 zs2 101
3 zs3 102
4 zs4 102
5 zs5 102
* 将以上表的建表语句写出来:
t_student中的classno字段引用t_class表中的cno字段,此时t_student表叫做子表。t_class表叫做父表。
顺序要求:
删除数据的时候,先删除子表,再删除父表。
添加数据的时候,先添加父表,在添加子表。
创建表的时候,先创建父表,再创建子表。
删除表的时候,先删除子表,在删除父表。
drop table if exists t_student;
drop table if exists t_class;
create table t_class(
cno int,
cname varchar(255),
primary key(cno)
);
create table t_student(
sno int,
sname varchar(255),
classno int,
primary key(sno),
foreign key(classno) references t_class(cno)
);
insert into t_class values(101,'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
insert into t_class values(102,'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy');
insert into t_student values(1,'zs1',101);
insert into t_student values(2,'zs2',101);
insert into t_student values(3,'zs3',102);
insert into t_student values(4,'zs4',102);
insert into t_student values(5,'zs5',102);
insert into t_student values(6,'zs6',102);
select * from t_class;
select * from t_student;
insert into t_student values(7,'lisi',103);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`bjpowernode`.INT `t_student_ibfk_1` FOREIGN KEY (`classno`) REFERENCES `t_class` (`cno`))
* 外键值可以为NULL?
外键可以为NULL。
* 外键字段引用其他表的某个字段的时候,被引用的字段必须是主键吗?
注意:被引用的字段不一定是主键,但至少具有unique约束。
存储引擎是mysql中特有的一个术语,其他数据库中没有。(Oracle中有,但是不叫这个名字)
实际上存储引擎是一个表存储/组织数据的方式。
不同的存储引擎,表存储数据的方式不同
| t_vip | CREATE TABLE `t_vip` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 |
在创建表的时候 我们可以在最后面的小括号输入:
engine = InnoDB default charset = utf8;
engine是来指定存储引擎
charset来指定这张表的字符编码方式
结论:
mysql默认的存储引擎是InnoDB
mysql默认的字符编码方式是:utf8
show engines \G
*************************** 1. row ***************************
Engine: FEDERATED
Support: NO
Comment: Federated MySQL storage engine
Transactions: NULL
XA: NULL
Savepoints: NULL
*************************** 2. row ***************************
Engine: MRG_MYISAM
Support: YES
Comment: Collection of identical MyISAM tables
Transactions: NO
XA: NO
Savepoints: NO
*************************** 3. row ***************************
Engine: MyISAM
Support: YES
Comment: MyISAM storage engine
Transactions: NO
XA: NO
Savepoints: NO
*************************** 4. row ***************************
Engine: BLACKHOLE
Support: YES
Comment: /dev/null storage engine (anything you write to it disappears)
Transactions: NO
XA: NO
Savepoints: NO
*************************** 5. row ***************************
Engine: CSV
Support: YES
Comment: CSV storage engine
Transactions: NO
XA: NO
Savepoints: NO
*************************** 6. row ***************************
Engine: MEMORY
Support: YES
Comment: Hash based, stored in memory, useful for temporary tables
Transactions: NO
XA: NO
Savepoints: NO
*************************** 7. row ***************************
Engine: ARCHIVE
Support: YES
Comment: Archive storage engine
Transactions: NO
XA: NO
Savepoints: NO
*************************** 8. row ***************************
Engine: InnoDB
Support: DEFAULT
Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
XA: YES
Savepoints: YES
*************************** 9. row ***************************
Engine: PERFORMANCE_SCHEMA
Support: YES
Comment: Performance Schema
Transactions: NO
XA: NO
Savepoints: NO
myisam存储引擎?
他管理的表具有一下特征:
使用三个文件表示每个表:
格式文件 - 存储表结构的定义(mytable.frm)
数据文件 - 存储表行的内容(mytable.MYD)
索引文件 - 存储表上索引(mytable.MYI):索引是一本书的目录,缩小扫描范围,提高效率
可被转换为压缩、只读表来节省空间
对于一张表来说,只要是主键或者加有unique约束的字段会自动创建索引
MyISAM存储引擎特点:
可被转换为压缩,只读表来节省空间
这是这种存储引擎的优势
InnoDB存储引擎?
这是mysql默认的存储引擎,同时也是一个重量级的存储引擎
InnoDB支持事物,支持数据可崩溃后自动回复机制
InnoDB存储引擎最主要的特点是:非常安全
InnoDB最大的特点就是支持事务:
以保证数据的安全。效率不是很高,并且也不能压缩,不能转换为只读
不能很好的节省存储空间
MEMORY存储引擎?
使用MEMORY存储引擎的表,其数据存储在内存中,且行的长度固定,这两个特点
使得MEMORY存储引擎非常快
MEMORY存储引擎管理的表具有下列特征:
在数据库目录内,每个表均以.frm格式的文件表示
表数据及索引被存储在内存中。(目的就是快)
表级锁机制
不能包含TEXT或BLOB字段
MEMORY存储引擎以前被称为HEAP引擎
MEMORY引擎优点:查询效率是最高的。不需要和硬盘交互
MEMORY引擎缺点:不安全,关机之后数据消失。因为数据和索引都是在内存当中
一个事物其实就是一个完整的业务逻辑。
是一个最小的工作单元。不可再分
什么是一个完整的业务逻辑?
假设转账,从A账户向B账户中转账10000
将A账户的钱减去10000(uptate语句)
将B账户的钱加上10000(uptate语句)
这就是一个完整的业务逻辑。
以上的操作是最小的工作单元,要么同时成功,要么同时失败,不可再分
这两个uptate语句要求必须同时成功或者同时失败
insert
delete
update
只有以上三个语句和事务有关系,其他的都没有关系
因为只有以上的三个语句是数据库表中的数据进行增、删、改的
只要你的操作一旦涉及到数据的增、删、改,那么就一定要考虑安全问题
数据安全放在第一位
正是因为要做某件事的时候,需要多条DML语句共同联合起来才能完成
所有需要事物的存在。如果任何一件复杂的事都能一条DML语句搞定,那么
事物就没有存在的价值了
到底什么是事务呢?
说到底,说到本质上,一个事物其实就是多条DML语句同时成功,同时失败。
事物:就是批量的DML语句同时成功,或者同时失败
InnoDB存储引擎:提供一组用来记录事务性活动的日志文件
事务开启了:
insert
insert
delete
update
insert
update
事务结束了
在事务的执行过程中,每一条DML的操作都会记录到“事务性活动的日志文件”中
在事务的执行过程中,我们可以提交事务,也可以回滚事务。
提交事务?
清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中
提交事务标志着,事务的结束。并且是一种全部成功的结束
回滚事务?
将之前所有的DML操作全部撤销,并且清空事务性活动的日志文件
回滚事务标志着,事务的结束,并且是一种全部失败的结束
提交事务:rommit; 语句
回滚事务:rollback;
事务对应的英语单词是:transaction
测试一下,在mysql当中默认的事务行为是怎么样的?
mysql默认情况下是支持自动提交事务的。(自动提交)
什么是自动提交?
每执行一条DML语句,就提交一次
怎么将mysql的自动提交机制关闭掉呢?
先执行这个命令:start transaction;
演示事务:
------------------------------回滚事务-------------------------
mysql> show tables;
+-----------------+
| Tables_in_zheng |
+-----------------+
| dept |
| dept_bak |
| emp |
| emp2 |
| salgrade |
| t_protect |
| t_user |
| t_vip |
+-----------------+
8 rows in set (0.01 sec)
mysql> select * from emp2;
+-------+--------+-----------+------+------------+---------+---------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+--------+-----------+------+------------+---------+---------+--------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 |
| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |
+-------+--------+-----------+------+------------+---------+---------+--------+
14 rows in set (0.01 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> delete from emp2;
Query OK, 14 rows affected (0.00 sec)
mysql> select * from emp2;
Empty set (0.00 sec)
mysql> insert into emp2 values(1111,'aaa','aaa',2222,'1984-1-5',744,0,10);
Query OK, 1 row affected (0.00 sec)
mysql> select * from emp2;
+-------+-------+------+------+------------+--------+------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+-------+------+------+------------+--------+------+--------+
| 1111 | aaa | aaa | 2222 | 1984-01-05 | 744.00 | 0.00 | 10 |
+-------+-------+------+------+------------+--------+------+--------+
1 row in set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from emp2;
+-------+--------+-----------+------+------------+---------+---------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+--------+-----------+------+------------+---------+---------+--------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 |
| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |
+-------+--------+-----------+------+------------+---------+---------+--------+
------------------------------提交事务--------------------------------------
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from emp2;
+-------+--------+-----------+------+------------+---------+---------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+--------+-----------+------+------------+---------+---------+--------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 |
| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |
+-------+--------+-----------+------+------------+---------+---------+--------+
14 rows in set (0.00 sec)
mysql> detele from emp2 ;
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 'detele from emp2' at line 1
mysql> delete from emp2 ;
Query OK, 14 rows affected (0.00 sec)
mysql> select * from emp2;
Empty set (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from emp2;
Empty set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from emp2;
Empty set (0.00 sec)
A:原子性:
说明事务是最小的工作单元,不可再分
C:一致性:
所有事务要求,在同一个事务当中,所有操作必须同时成功,或者同时失败
以保证数据的安全性
I:隔离性:
A事务和B事务之间具有一定的隔离
教室A和教室B之间有一道墙,这道墙就是隔离性
A事务在操作一张表的时候,另一个事务B也操作这张表会怎么样?
D:持久性:
事务最终结束的一个保证。事务提交,就相当于将没有保存到硬盘上的数据保存到硬盘上
A教室和B教室中间有一道墙,这道墙可以很厚,也可以很薄。这就是事务的隔离级别
这道墙越厚,表示隔离级别就越高
事务和事务之间的隔离级别有哪些呢?
读未提交:read uncommitted(最低的隔离级别)《没有提交就读取到了》
什么是读未提交?
事务A可以读取事务B还没有提交的数据
这种隔离级别存在的问题就是:
脏读现象(Dirty read)
我们称为脏数据
读已提交:read committed《提交之后才可以读取到》
什么是读已提交?
事务A可以读取事务B已经提交的数据
这种隔离级别解决了什么问题?
解决了脏读现象
这种隔离级别存在什么问题?
不可重复读取数据
什么是不可重复读取数据呢?
在事务开启之后,第一次读取到的数据是3条,当前事务还没有结束
可能第二次在读取的时候,读到的数据就是4条了,3不等于4,称为
不可重复读取(就是事务B在执行的时候读取了两次A事务中的数据,
事务A可能变化了多次,数据也就不一样了)
这种隔离级别是比较真实的数据,每一次读到的数据是绝对的真实
oracle数据库默认的隔离级别是:read committed
可重复读:repeatable read《提交之后也读不到,永远读取的都是刚开启事务时的数据》
什么是可重复读取?
事务A开启之后,不管是多久,每一次事务A读取到的数据都是一致的,即使事务B将数据
已经修改,并且提交了,事务A读取到的数据还是没有发生改变,这就是可重复读
可重复读解决了什么问题呢?
解决了不可重复读取数据
可重复读存在的问题是什么?
可能会出现幻影读
每一次读取到的数据都是幻象。不够真实
早晨9点开始开启了事务,只要事务不结束,到晚上9点,读到的数据还是那样
例子:比如银行要进行总账,执行过程从1点到3点结束,如果中途有人存取钱的话,数据就不正确了,所以使用
可重复读,,事务A进行读取总账,事务B进行存取钱,事务A的数据一直都是1点那个数据,事务B进行提交了,事务A
也不变化,而读已提交就不行,他会将数据进行更新,对应出现的问题是:不可重复读取数据
序列化/串行化:serializable(最高的隔离级别):
这是最高隔离级别,效率最低。解决了所有的问题
这种级别表示事务排队,不能并发
每一次读取到的数据都是最真实的,并且效率是最低的
查看隔离级别:select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
mysql中默认的隔离级别
验证:read uncommit
设置全局的隔离级别:set global transaction isolation level read uncommitted;
改完之后退出一下重新进入
事务A 事务B
--------------------------------------------------------------------------------------------
use zheng;
use zheng;
start transaction;
select * from t_user;
start transaction;
insert into t_user values('zhangsan');
select * from t_user;
验证:read committed
设置全局的隔离级别:set global transaction isolation level read committed;
改完之后退出一下重新进入
事务A 事务B
--------------------------------------------------------------------------------------------
use zheng;
use zheng;
start transaction;
start transaction;
select * from t_user;
insert into t_user values('zhangsan');
select * from t_user;
commit;
select * from t_user;
验证:repeatable read
设置全局的隔离级别:set global transaction isolation level repeatable read;
改完之后退出一下重新进入
事务A 事务B
--------------------------------------------------------------------------------------------
use zheng;
use zheng;
start transaction;
start transaction;
select * from t_uesr;
insert into t_uesr values('lisi');
insert into t_uesr values('wangwu');
select * from t_user;
commit;
select * from t_user;
验证:serializable
设置全局的隔离级别:set global transaction isolation level repeatable read;
改完之后退出一下重新进入
事务A 事务B
--------------------------------------------------------------------------------------------
use zheng;
use zheng;
start transaction;
start transaction;
select * from t_uesr;
insert into t_user values('abc');
select *from t_user;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。