文章目录
- 1.揭开MySQL的神秘面纱
- 2. SQL的基本命令实操
- 3. 数据库的备份与恢复
- 4. MySQL常用的数据类型(列类型)
- 5. 数据类型之小数类型的使用
- 6. 表的创建
- 7. 表的修改
- 8. mysql事务
- 9. mysql表类型和存储引擎
- 10. mysql的视图
- 11. mysql的管理
1.揭开MySQL的神秘面纱
-
MySQL数据库以及表的本质是什么?
就是存储在本地mysql->data里面的文件
-
SQL命令查询命令的逻辑:
首先将客户中断接收用户输入的命令
然后被3306端口的mysqld.exe程序监听到执行的查询命令
接着就是将命令在数据库管理系统DBMS中进行解析之后执行命令
查询到对应表的数据之后DBMS就将数据返回给命令终端展示
-
如图所示(借用一下韩老师的图)
-
SQL语句的分类
DDL: 数据定义语句 create 表,库…
DML: 数据操作语句 insert, update
DQL: 数据查询语句 select
DCL: 数据控制语句 管理数据库:比如用户权限 grant[授权], revoke[移除]
2. SQL的基本命令实操
-
创建数据库
创建默认的数据库(utf-8的字符集,不区分大小写)
create database if not exists db_test_01;
创建自定义的数据库(utf-8的字符集,区分大小写)
create database if not exists db_test_02 character set utf8 collate utf8mb3_bin;
-
创建表
use db_test_01; create table t1 ( id int auto_increment primary key, name varchar(256) null comment "名字" ) comment '用户信息表';
-
插入数据
insert into t1 (id, name) VALUES (0, 'tom'); insert into t1 (id, name) VALUES (0, 'Tom');
-
删除表或者数据库
drop database db_test_02; drop table t1;
-
不同校验规则的区别就是查询数据的时候是否进行大小写的区分
比如表t1与表t2里面创建的数据如下,在查询的时候t2的数据只会返回一条,表t1会返回所有的[因为表t2进行了大小写的校验]
# 查询语句 use db_test_01; select * from t1 where name = 'tom';
t1的查询结果
t2的查询结果
3. 数据库的备份与恢复
-
备份数据库
在cmd命令窗口中使用以下命令进行备份
# 需要备份的数据库名 db_test_01 db_test_02 文件存储的位置 mysqldump -u root -p -B db_test_01 db_test_02 > d:\\back.sql # 只备份数据库下面的某个表 mysqldump -u root -p 数据库名 表名1 表名2 > 文件存储位置
-
恢复数据命令(必须在mysql的cmd中执行)
4. MySQL常用的数据类型(列类型)
-
数值类型 (有符号可以插入负数,无符号只能插入正数)
tinyint 占1个字节
smallint 占2个字节
mediumint 占3个字节
int 占4个字节
bigint 占8个字节
float 单精度
dobule 双精度
decimal[M, D] 自己定义大小
-
文本类型
char 最大255
varchar() 可以自己指定
blob 可以存储二进制数据
text
-
日期类型
date 日期类型(年月日)
time 时间类型(时分秒)
datetime 日期时间类型(年月日时分秒)
timestamp 时间戳
5. 数据类型之小数类型的使用
-
double存储双精度的浮点数
-
decimal[M, D] M 默认为10, D默认为0
- M表示小数位数的总数,D表示小数点后面的位数
- M最大是65, D最大是30 默认值M是10,D默认是0
- 如果希望精度更高推荐使用decimal
use db_test_02; create table t2( num1 float, num2 double, num3 decimal(30, 20) ); insert into t2 values (80.999999999923423423,80.999999999923423423, 80.999999999923423423);
如图所示
6. 表的创建
use db_test_02;
create table emp (
id int,
name varchar(32),
sex char(1),
birthday date,
entry_date datetime,
job varchar(32),
salary double,
resume text
) comment "员工信息表" character set utf8 collate utf8_bin engine innodb;
insert into emp values (1, '小吴', '女', '2002-11-11', '2024-3-6', '技术支持', 3500, '我是一个小可爱');
7. 表的修改
-
基本命令
# 添加列 alter table 表名 add 列名 字段类型 # 修改列 alter table 表名 modify 列名 字段类型 # 删除列 alter table 表名 drop 列名 # 查看表的结构 desc 表名 # 修改表名 renam table 原始表名 to 新的表名 [不需要添加单引号] # 修改表字符集 alter table 表名 character set 字符集 # 更改列名为新的列名 alter table 表名 change column 原始列名 新列名 字段类型
-
CRUD
-
增
# 创建一张表 create table goods( id int, goods_name varchar(30), price double ) comment '商品信息表'; # 向表中插入数据 insert into goods values (2, '华为手机', 3888.99), (3, '魅族手机', 3888.9); # 查询表数据 select * from goods;
-
删
# 删除表 delete 表名 from 数据库名; # 删除表中的某条记录 delete from where 条件; # 清空表的数据 truncate table 表名;
-
改
# 修改一张表 update 表名 set 列名 = 修改值 where 条件 update employee set salary = salary + 5000 where username = '小吴'; # 修改表的命令里面可以添加多个修改的字段 update employee set salary = salary + 5000, job = '按摩技师1号' where username = '小吴';
-
查
-
单表
-
基本语法
# 查询所有信息 (去重) select (distinct) * from 表名; # 查询所有学生 select * from student_score; # 查询姓名和英语成绩 select name, english from student_score; # 去重(必须是所有的改行内容都相等才会去重成功, 否则是不能够成功去重的) 这里name不相等,尽管english是相等的 select distinct name, english from student_score;
如图所示
# 查询时别名的使用 select name as '姓名', (chinese + english + math) as '总成绩' from student_score;
如图所示
# 查询时的where条件设置 select * from 表名 where 条件; # 查询总成绩大于200并且数学成绩小于语文成绩,同时姓小的同学的所有成绩信息 select * , (chinese + math + english) as total_score from student_score where math + english + chinese > 200 and math < chinese and name like '小%';
如图所示
# 查询时使用order by 子句排序查询结果 select column1, column2... from 表名, order by column asc|desc... # 查询所有学生的数学成绩大于50的,并进行降序输出 select name, math from student_score where math > 50 order by math desc;
如图所示
# 统计函数 count select count(*) as '总人数' from student_score where math + chinese + english > 220; # count(列名) 只统计结果筛选出来之后对应列的和,如果有null的情况不计数 # 统计函数 sum(只能计算数值型的列,如果是字符集的列就会没有作用) select sum(math) as '数学总成绩', sum(chinese) as '语文总成绩', sum(english) as '英语总成绩' from student_score; # 统计函数 avg(同样只对数值型的列起作用) select avg(math) from student_score; # 统计函数 max/min 统计最大值和最小值
# 分组统计group by + having的配合使用 # 创建一张部门表 CREATE TABLE dept ( deptno MEDIUMINT NOT NULL DEFAULT 0, dname VARCHAR(20) NOT NULL DEFAULT '', loc VARCHAR(13) NOT NULL DEFAULT '' ); INSERT INTO dept VALUES (10, '销售部', '重庆'), (20, '技术部', '成都'), (30, '财务部', '深圳'), (40, '设计部', '北京'), (50, '安保部', '黄冈'); drop table dept; truncate table dept; SELECT * FROM dept; # 创建一张员工信息表 CREATE TABLE `emp` ( `empno` mediumint(8) unsigned NOT NULL DEFAULT '0', `ename` varchar(20) COLLATE utf8_bin NOT NULL DEFAULT '""', `job` varchar(9) COLLATE utf8_bin NOT NULL DEFAULT '""', `mgr` mediumint(8) unsigned DEFAULT NULL, `hiredate` date NOT NULL, `sal` decimal(7,2) NOT NULL, `comm` decimal(7,2) DEFAULT NULL, `deptno` mediumint(8) unsigned NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; INSERT INTO emp VALUES(7369,'小黄','设计师',7902,'1990-12-17',800.00,NULL,40), (7499,'小青','设计师',7698,'1991-2-20',1600.00,300.00,40), (7521,'小绿','设计师',7968,'1991-2-22',1250.00,500.00,40), (7566,'二狗','工程师',7839,'1991-4-2',2975.00,NULL,20), (7654,'二哥','工程师',7968,'1991-9-28',1250.00,1400.00,20), (7698,'三弟','工程师',7839,'1991-5-1',2850.00,NULL,20), (7782,'张飞','工程师',7839,'1991-6-9',2450.00,NULL,20), (7788,'关羽','会计',7566,'1991-4-19',3000.00,NULL,30), (7839,'孙二娘','会计',NULL,'1991-11-17',5000.00,NULL,30), (7844,'孙悟空','销售员',7698,'1991-9-8',1500.00,NULL,10), (7900,'至尊宝','销售员',7698,'1991-12-3',950.00,NULL,10), (7902,'紫霞仙子','销售员',7566,'1991-12-3',3000.00,NULL,10), (7934,'二师兄','销售员',7782,'1991-1-23',1300.00,NULL,10); select * from emp; # 创建一张工资级别表 grade 工资级别(1, 2, 3, 4, 5) 改级别下的 low_salary 最低工资 high_salary 最高工资 CREATE TABLE salary_grade( grade MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, low_salary DECIMAL(17,2) NOT NULL, high_salary DECIMAL(17,2) NOT NULL ); INSERT INTO salary_grade VALUES(1,700,1200), (2,1201,1400), (3,1401,2000), (4,2001,3000), (5,3001,9999); select * from salary_grade; # 查找每个部门的平均工资和最高工资 只按照每个部门的deptno分组即可 select avg(sal) as '平均工资', max(sal) as '最高工资', deptno from emp group by deptno; # 查找每个部门的平均工资和最高工资, 按照每个部门的每种岗位的平均工资和最低工资 select avg(sal) as '平均工资', max(sal) as '最高工资', deptno, job from emp group by deptno, job; # 显示平均工资低于2000 的部门号和它的平均工资 + having进行使用 select avg(sal) as avg_salary, deptno, job from emp group by deptno, job having avg_salary < 2000; # 分组就类似于将原本很多条的数据根据某个列值进行了拆分,使其相同的某列的值的数据成为了一条,这样就是将多条数据转变为了根据某列进行拆分的较少的数据,同时还可以搭配having进行过滤使用
-
流程控制函数
(select case when 列名 = '旧值' then '新值' when 列名 = '旧值' then '新值' else 列名/默认值 end) select ename, (select case when job = '设计师' then 'sheji' when job = '工程师' then 'gongcheng' else job end) as '职位' from emp;
如图所示
-
增强查询
# 如何查找2001.1.1后入职的员工 日期格式一定要是两位数 select * from emp where hiredate > '2001-01-01'; # 分页查询 select ... limit (size * (pageNo - 1)), size; select * from emp order by empno limit 0, 3; # 显示没有获取奖金的人数: 两种方法 count非空的值才能进行统计 可以自己给值,不需要传递comm因为comm是空值传递无效 select count(if(comm is null, 1, null)) as '显示没有获取奖金的人数' from emp; select count(*) - count(comm) from emp; # 显示管理者的总人数 去重可以添加到count里面 select count(distinct mgr) from emp; # 显示雇员工资的最大差额 select max(sal) - min(sal) as '雇员工资最大差额' from emp; # [混合使用的顺序] 查询部门平均工资大于2000的部门,并输出前两条记录 select deptno, avg(sal) as avg_salary from emp group by deptno having avg_salary > 2000 order by avg_salary desc limit 0, 2;
总结
如果select语句同时包含group by, having, limit, order by那么它的最后的顺序就是
select colum1, column2 from ‘表名’ group by column having condition order by column limit start, rows;
-
-
多表查询
-
数据准备
# 创建一张部门表 CREATE TABLE dept ( deptno MEDIUMINT NOT NULL DEFAULT 0, dname VARCHAR(20) NOT NULL DEFAULT '', loc VARCHAR(13) NOT NULL DEFAULT '' ); INSERT INTO dept VALUES (10, '销售部', '重庆'), (20, '技术部', '成都'), (30, '财务部', '深圳'), (40, '设计部', '北京'), (50, '安保部', '黄冈'); drop table dept; truncate table dept; SELECT * FROM dept; # 创建一张员工信息表 CREATE TABLE `emp` ( `empno` mediumint(8) unsigned NOT NULL DEFAULT '0', `ename` varchar(20) COLLATE utf8_bin NOT NULL DEFAULT '""', `job` varchar(9) COLLATE utf8_bin NOT NULL DEFAULT '""', `mgr` mediumint(8) unsigned DEFAULT NULL, `hiredate` date NOT NULL, `sal` decimal(7,2) NOT NULL, `comm` decimal(7,2) DEFAULT NULL, `deptno` mediumint(8) unsigned NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; INSERT INTO emp VALUES(7369,'小黄','设计师',7902,'1990-12-17',800.00,NULL,40), (7499,'小青','设计师',7698,'1991-2-20',1600.00,300.00,40), (7521,'小绿','设计师',7968,'1991-2-22',1250.00,500.00,40), (7566,'二狗','工程师',7839,'1991-4-2',2975.00,NULL,20), (7654,'二哥','工程师',7968,'1991-9-28',1250.00,1400.00,20), (7698,'三弟','工程师',7839,'1991-5-1',2850.00,NULL,20), (7782,'张飞','工程师',7839,'1991-6-9',2450.00,NULL,20), (7788,'关羽','会计',7566,'1991-4-19',3000.00,NULL,30), (7839,'孙二娘','会计',NULL,'1991-11-17',5000.00,NULL,30), (7844,'孙悟空','销售员',7698,'1991-9-8',1500.00,NULL,10), (7900,'至尊宝','销售员',7698,'1991-12-3',950.00,NULL,10), (7902,'紫霞仙子','销售员',7566,'1991-12-3',3000.00,NULL,10), (7934,'二师兄','销售员',7782,'1991-1-23',1300.00,NULL,10); select * from emp; # 创建一张工资级别表 grade 工资级别(1, 2, 3, 4, 5) 改级别下的 low_salary 最低工资 high_salary 最高工资 CREATE TABLE salary_grade( grade MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, low_salary DECIMAL(17,2) NOT NULL, high_salary DECIMAL(17,2) NOT NULL ); INSERT INTO salary_grade VALUES(1,700,1200), (2,1201,1400), (3,1401,2000), (4,2001,3000), (5,3001,9999); select * from salary_grade;
-
多表查询练习一:
显示雇员的名字、雇员的工资、以及雇员所在的部门名称
select ename, sal, dname, emp.deptno from emp, dept where emp.deptno = dept.deptno; /** - 如果不添加任何的限制条件就去查询两张表 结果就是先拿第一张表的第一行数据去和另外一张表的每一行数据做组合 这样就导致出现了很多条数据 - 解决多条数据无效,需要进行where条件的过滤 - 如果需要展示表之间连接的关键字时需要使用表.列名 这样才能正确的进行展示 - n张表一起进行数据的查询,它的过滤条件必须是 n - 1个条件组成 */
显示部门号为10的员工名,工资,部门名 和工资级别
select ename, sal, dname, grade from emp, dept, salary_grade where emp.deptno = dept.deptno and emp.deptno = 10 and sal between low_salary and high_salary; /** - where条件需要判断最终结果使用的是那张表的数据,那么条件就使用那张表的条件 - 比员工名,工资,工资级别 就只需要条件后面有sal between low_salary and high_salary即可不需要 emp.deptno = dept.deptno (如果查部门名称才需要) */
多表查询之自连接 查询 (在同一张表里面查询)
eg: 查询表中员工的名字和上级的名字 (通过mgr字段与empno的值判断)
select * from emp; select worker.ename, boss.ename from emp worker, emp boss where worker.mgr = boss.empno; /** 1. 把同一张表看作两张表进行使用 2. 需要给表取别名 表别名 3. 列名不明确可以指定列的别名 */
多表查询之子查询 (将当前sql语句嵌入到其它sql语句中作为过滤条件进行查询)
-
单行子查询(只返回一行数据的子查询语句)
# 查询和员工二狗所在的部门的其他员工信息 select * from emp where deptno = ( select deptno from emp where ename = "二狗" ) and ename != "二狗";
-
多行子查询(返回多行数据的子查询)
# 查询部门员工所有在编号为10的岗位工作的员工的姓名,岗位,工资,部门标号的信息,但是不包括编号为10的自己 select ename,job,sal,deptno from emp where job in (select distinct job from emp where deptno = 10) and deptno != 10;
-
子查询做临时表使用
select goods_id, temp.cat_id, goods_name, shop_price from ( select cat_id, max(shop_price) as max_price from ecs_goods group by cat_id ) temp, ecs_goods where temp.cat_id = ecs_goods.cat_id and temp.max_price = ecs_goods.shop_price /** 总结:查询的时候可以把子查询结果作为临时表使用 然后就是可以给临时表添加别名 同时需要注意如果有两张表都有的字段,必须添加表.字段才能正确的查询,否则会重复 */
-
多表查询之all的使用
# 查员工信息,部门号,工资 比30号部门的所有员工工资高 select deptno, sal, ename from emp where sal > all ( select sal from emp where deptno = 30 ); select sal from emp where deptno = 30; select ename, deptno, sal from emp where sal > ( select max(sal) from emp where deptno = 30 );
-
多表查询之any的使用
# 查询比30号部门工资其中一个高的员工信息:姓名,编号,工资 select ename, deptno, sal from emp where sal > any( select sal from emp where deptno = 30 ); # 只要是比最低的都高,那么就是比其中任意一个都高 select ename, deptno, sal from emp where sal > ( select min(sal) from emp where deptno = 30 );
-
多表查询之多列的子查询(前面是单列多行)
# 查询与小青部门和编号相等的其他雇员,且不包含他自己 select * from emp where (job, deptno) = ( select job, deptno from emp where ename = '小青' ) and emp.ename != '小青'; # 查询和小白各科成绩相同的学生 select * from student_score where (chinese, math, english) = (select chinese, math, english from student_score where name = "小白") and name != "小白";
-
-
综合练习多表查询:
- 查询每个部门工资最高的人的信息
select ename, temp.deptno, job, sal from emp, ( select deptno, max(sal) as max_salary from emp group by deptno ) temp where temp.deptno = emp.deptno and emp.sal = max_salary;
- 查询每个部门的信息(部门编号,名称,地址)和人员数量
select temp.*, dname, loc from dept, ( select count(*) as person_num, deptno from emp group by deptno ) temp where temp.deptno = dept.deptno;
-
表的复制(蠕虫复制)
场景:有时候需要海量的数据来检测当前的sql语句是否执行的效率很高,所以需要大量的数据进行测试,可以通过自我复制的方式实现 [自己查自己,然后将数据插入到表里面]
# 首先创建一个测试表 create table copy_table_test( id int, username varchar(50), job_name varchar(50), address varchar(30) )comment "测试表"; # 然后将另外表的数据拷贝过来 insert into copy_table_test select empno, ename, job, address from emp; # 如果数据还不够就可以进行自我复制 insert into copy_table_test select * from copy_table_test; select count(*) from copy_table_test;
-
表的去重
步骤:
-
首先复制创建一张结构相同的表temp
-
然后将另一张表的数据查出并去重之后复制到temp表
-
接着将表中的数据进行清空
-
同时将temp表的数据复制到目标表
-
最后删除temp表即可
【也可以直接更改表的名字,temp表就充当临时变量的作用】
# 首先复制创建一张结构相同的表temp create table temp like copy_table_test; # 然后将另一张表的数据查出并去重之后复制到temp表 insert into temp select distinct * from copy_table_test; # 接着将表中的数据进行清空 truncate table copy_table_test; select * from copy_table_test; # 同时将temp表的数据复制到目标表 insert into copy_table_test select * from temp; select * from copy_table_test; # 最后删除temp表即可 drop tem;
-
-
查询结果的合并
union 去重
union all 不去重
-
-
外连接查询
-
左外连接(左侧的表全部显示)
# 数据准备 create table student_info ( id int, name varchar(30) ) comment '学生信息表'; create table student_grade ( id int, grade double ) comment '学生成绩'; insert into student_info values (1, '小华'), (2, '小张'), (5, '小青'), (6, '小梦'), (10, '小孩哥'); select * from student_info; insert into student_grade values (1, 20), (2, 30), (11, 99), (12, 33); select * from student_grade;
# 查询所有的学生成绩,即使没有成绩也要显示姓名和id select student_info.id, name, grade from student_info left join student_grade on student_info.id = student_grade.id;
-
右外连接(右侧的表全部显示)
# 右外连接 # 查询所有人的成绩,即使没有对应的姓名也要进行展示 select student_grade.id, grade, name from student_info right join student_grade on student_info.id = student_grade.id;
-
主键约束
主键可以有单个主键也可以有复合主键(必须两个同时相等才不会报错)
# 复合组件 主键不能为空 且id和name不能重复 # 每个表往往都会设计一个组件 create table test01 ( id int, name varchar(30), age int, primary key (id, name) ) comment '测试表1';
-
外键约束
-
当有两张表的时候给a表创建了外键约束那么在插入数据的时候如果b表的id没有你插入的数据的id那么你就会插入失败
-
外键是添加到副表的,且用的是主表的数据
-
外键必须指向表的主键或者unique
-
可以给外键值为空(前提是外键没有not null)
-
删除外键约束的数据时必须先删除从表的数据,然后再删除主表的数据
# 外键测试 create table class_info( id int primary key , classs_name varchar(30) not null default '' ); insert into class_info values (100, 'java'), (200, 'python'), (300, 'php'); create table class_stu( id int primary key , name varchar(30), class_id int, foreign key (class_id) references class_info(id) ); insert into class_stu values (1, '张三', 100); insert into class_stu values (2, '李四', 100); insert into class_stu values (3, '王五', 400); # 这里会插入失败,因为主表里面不存在id数据 select * from class_stu;
-
check(版本必须 > mysql5.7才能使用)
# sex只能插入男或者女这两个字段 # salary工资必须大于10000或者小于5000 create table check_test( id int primary key , name varchar(30) not null default '', sex varchar(10) check ( sex in ('男', '女') ), salary double check ( salary > 1000 and salary < 5000 ) ); insert into check_test values (1, '小吴', '女', 1111);
-
-
索引
作用:使用索引是最廉价的方式来提升数据查询的方法 提升的查询速度非常的快
特点:
- 查询速度只会对创建了索引的列的数据查询速度有提升,如果该列没有创建索引那么查询速度还是很慢的 【创建一个索引不能使得数据库里面所有的数据查询速度提升】
- 索引的创建会导致增加该数据库文件的大小
- 索引的创建会对增删改查造成一些影响
- 实际项目中主要都是对数据的select操作,其他操作只占10%
原理:
-
没有创建索引的时候会依次从上到下(id)进行全表扫描,导致查询的速度比较的慢【没有索引的场景】
-
创建了索引就会生成一个索引的数据结构(二叉树)
# 创建索引的命令 create index 索引名 on 表名(表的主键名);
-
索引的类型
- 主键索引 (primary key)
- 唯一索引 (unique) 不重复
- 普通索引 (index) 重复
- 全文索引 (FullText该方式查询的速度比较慢,使用较多的是ES或者Solr)
-
索引的添加
# 添加普通索引 create index 索引名 on 表名 (需要添加索引的列); alter table 表名 add index 索引名 (需要添加索引的列); # 添加唯一索引 create unique index 索引名 on 表名 (需要添加索引的列); # 添加主键索引 (可以在建表的时候添加) alter table 表名 add primary key (需要添加索引的列);
-
索引的删除
# 删除索引 drop index 索引名称 on 表名; # 删除主键索引 alter table 表名 drop primary key; # 修改索引就是先删除再添加 # 查询某张表里面的索引 show index from 表名;
-
小结:
- 频繁作为查询条件的字段适合创建索引
- 唯一性差的字段不适合创建索引(sex)
- 更新非常频繁的字段不适合创建索引
- 不出现在where条件里面的字段不创建索引
-
-
8. mysql事务
-
含义
场景:希望将多条dml语句作为一个整体,要么全部成功,要么全部失败
需要解决上面的问题,就可以使用事务(transaction)的方法来解决
通过手动的开启事务并且设置了保存点之后,开发者就可以回滚到之前设置的保存点的位置,或者直接回滚到事务开启的位置
-
具体操作
- 事务的流程
- 开启事务 start transaction
- 设置保存点 savepoint a/b/c
- 回滚 rollback to a/b/c
- 回到初始点 rollback
- commit 提交事务,删除了保存点,不能再进行回滚
- 事务的流程
-
事务的隔离级别 (与事务相关)
脏读: 【一个事务读取到另外一个事务尚未提交的改变】
不可重复读: 【一个事务如果提交了删改的操作,但是另一个事务没有提交,结果查看之后的数据是另一个事务删改之后的结果,这就不对】
幻读: 【一个事务新增数据且提交之后,但是当前事务没有提交在查询数据的时候看到了提交的结果,这也是不对的】
正常情况下就是不管任何事务登录进行数据库的操作,它的数据都不应该受到其它事务的影响
-
事务隔离级别
# 查看隔离级别命令 select @@tx_isolation; (默认可重复读) # 查看系统隔离级别 select @@global.tx_isolation # 设置隔离级别 set session transcation isolation level read uncommitted; (读未提交) # 可以在文件my.ini里面设置事务的隔离级别
-
隔离级别
隔离级别 脏读 不可重复读 幻读 是否加锁读 备注 Read uncommitted √ √ √ × Read committed × √ √ × Repeatable read(默认满足大部分项目使用) × × × × Serializable × × × √ 如果有没有提交的事务当前事务查询数据会卡住(加锁) -
事务(ACID)的特性
- 原子性: 事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生
- 一致性:事务必须使数据库从一个一致性状态变换到另外一个一致性状态
- 隔离性:多个用户并发访问数据库的时候不能被其他事务的操作影响,多个事务之间要隔离
- 永久性:事务一旦提交对数据库的操作是永久性的不能进行回滚
-
9. mysql表类型和存储引擎
-
分类(主要)
- Myisam: 不支持事务,外键,访问速度快
- InnoDB(默认): 支持事务安全,支持外键
- Memory: 整个数据在内存,使用经常操作的数据且不需要持久化存储
- Archive
-
选择
- 不需要使用事务,处理的是基本的CRUD就可以选择MyISAM,速度非常快
- 如果需要支持事务选择默认的InnoDB
- Memory将数据存储在内存中,速度极快,服务重启之后数据会丢失(经典用法: 用户的在线状态)
10. mysql的视图
…持续更新中
11. mysql的管理
…持续更新中