老杜MySQL视频学习记录_笔记

老杜MySQL视频学习记录_笔记

本文是MySQL数据库笔记,是动力节点教学总监杜老师讲述。

视频地址:https://www.bilibili.com/video/BV1fx411X7BD?p=1

文章目录


一、SQL语句分类

DQL:数据查询语句(Data Query Language)

select

DML:数据操作语言(Data Manipulation Language)

对表中的数据进行增删改

insert delete update

主要操作的是表中的数据

DDL:数据定义语言(Data Definition Language)

create、drop、alter

DDL主要操作的表的结构,不是表中的数据。

TCL:事务控制语言(Transactional Control Language)

事务提交:commit

事务回滚:rollback

DCL:数据控制语言(Data Control Language)

授权:grant

撤销:revoke

二、常用命令

1.查看MySQL版本:

mysql -V

mysql --version

select version();

2.创建数据库

create database <数据库名称>;
使用:use <数据库名>;	

3.查看当前使用的数据库

select database();

4.终止一条语句

键入\c

5.退出mysql

exit、quit

三、查看表结构

1.查看现有的数据库

show databases;

2.查看当前缺省的数据库

use <database name>;

3.查看当前使用的数据库

select database();

4.查看当前库中的表

show tables;

5.查看其他库中的表

show tables from <database name>;

6.查看表结构

desc <table name>;

7.查看表的创建语句

show create table <table name>;

四、简单的查询

1.查询一个字段

select <field> from  <table name>;

2.查询多个字段

select <field1>,<field2> from <table name>;

3.查询全部字段

select * from <table name>;

4.计算员工的年薪

select empno, ename, sal*12 from emp;

5.起别名

select empno as '员工编号', ename as '员工姓名', sal*12 as '年薪' from emp;

注意:字符串必须添加单引号 | 双引号

五、条件查询(where)

1.等号操作

查询工资=5000的员工

select empno,ename,sal from emp where sal=5000;

查询字符串必须加上引号

查询job="manager"的员工

select empno, ename from emp where job="manager";

2.<>符操作

查询薪水不等于5000的员工

select empno,ename from emp where sal<>5000;

3.between…and…操作符

查询薪水为1600到3000的员工(第一种方式,采用>=和<=)

select empno,ename from emp where sal>=1600 and sal<=3000;

查询薪水为1600到3000的员工(第一种方式,采用between … and …) 闭区间

select empno,ename from emp where sal between 1600 and 3000;

4.is null

空和空字符串不是一回事,null必须用is来比较

select empno,ename from emp where comm is null;

5.and

工作岗位为MANAGER,薪水大于2500的员工

select * from emp where job="manager" and sal>2500;

6.or

太简单了。略。

7.表达式的优先级

查询薪水大于1800,并且部门代码为20或30的员工

select * from emp where sal>1800 and (deptno=20 or deptno=30);

没把握尽量用括号

8.in

in表示包含的意思,完全可以采用or来表示,采用in会更简洁一些

查询出job为manager或者job为salesman的员工

select * from emp where job in("manager","salesman");

9.not

查询出薪水不包含1600和薪水不包含3000的员工

select * from emp where sal<>1600 and sal<>3000;
select * from emp where not(sal=1600 or sal=3000);
select * from emp where sal not in(1600,3000);

查出津贴不为null的所有员工

select * from emp where comm is not null;

10.like

Like可以实现模糊查询,like支持%和下划线匹配

%匹配任意字符出现的个数

下划线只匹配一个字符

Like 中的表达式必须放到单引号中|双引号中

查询姓名以M开头的所有员工

select * from emp where ename like "M%";

查询姓名以N结尾的所有的员工

select * from emp where ename like "%N";

查询姓名中包含O的所有的员工

select * from emp where ename like "%o%";

查询姓名中第二个字符为A的所有员工

select * from emp where ename like "_a%";

六、排序数据

1.单一字段排序

排序采用order by子句,order by后面跟上排序字段,排序字段可以放多个,多个采用逗号间隔,order by默认采用升序,如果存在where子句那么order by必须放到where语句的后面。

按照薪水由小到大排序(系统默认由小到大)

select * from emp order by sal;

取得job为MANAGER的员工,按照薪水由小到大排序(系统默认由小到大)

select * from emp where job="manager"  order by sal;

按照多个字段排序,如:首先按照job排序,再按照sal排序

select * from emp order by job,sal;

2.手动指定顺序排序

手动指定按照薪水由小到大排序

select * from  emp order by sal asc;

手动指定按照薪水由大到小排序

select * from emp order by sal desc;

3.多个字段排序

按照job和薪水倒序

select * from emp order by job desc,sal desc;

4.使用字段的位置来排序

按照薪水升序 不建议使用位置

select * from emp order by 6;

七、数据处理函数/单行处理函数

函数名作用
count求和
avg取平均数
max取最大的数
min取最小的数
lower转换小写
upper转换大写
substr取子串(substr(被截取的字符串,起始下标,截取的长度))
length取长度
trim去空格
str_to_date将字符串转换成日期
data_format格式化日期
format设置千分位 format(数字,‘格式’)
round四舍五入
rand()生成随机数
ifnull可以将null转换成一个具体的值

注意:分组函数自动忽略空值,不需要手动的加where条件排除空值。

select count(*) from emp where xxx; 符合条件的所有记录总数。

select count(comm) from emp; comm这个字段中不为空的元素总数。

注意:分组函数不能直接使用在where关键字后面。

mysql> select ename,sal from emp where sal > avg(sal);

ERROR 1111 (HY000): Invalid use of group function

1.count

统计该字段下所有不为NULL的元素的总数

取得所有的员工数

select count(*) from emp;

取得津贴不为null员工数

select count(comm) from emp;

取得工作岗位的个数

select count(distinct job) from emp;

2.sum

sum可以取得某一个列的和,null会被忽略

取得薪水的合计

select sum(sal) from emp;

取得津贴的合计

select sum(comm) from emp;

取得薪水的合计(sal+comm)

select sum(sal+IFNULL(comm,0))) from emp;

3.substr

找出员工名字第一个字母是A的员工信息

select ename from emp where substr(ename,1,1) ="A";

4.trim去前后空格

select ename from emp where ename=trim("  king");

5.round四舍五入

select round(12345.678,1) from emp;

6.ifnull

select ename,(sal+ifnull(comm,0))*12 from emp;

7.case…when…then…when…then…else…end

当员工的工作岗位是MANAGER的时候,工资上调10%,当工作岗位是SALESMAN的时候,工资上调50%,其他正常。 select不会修改原来的数据

select ename,job,(case job when "manager" then sal*1.1 when "salesman" then sal*1.5 else sal end) as newsal from emp;

八、分组函数

必须先进行分组才能使用,否则就是整张表。

分组查询主要涉及到两个子句,分别是:group by 和 having

1.group by

取得每个工作岗位的工资合计,要求显示岗位名称和工资合计?

select job,sum(sal) from emp group by job;

找出每个部门最高薪资大于3000的?

select deptno,max(sal) from emp where sal>3000 group by deptno;

2.having

如果想对分组数据再进行过滤需要使用 having 子句

取得每个岗位的平均工资大于 2000 ?

select job,avg(sal) from emp group by job having avg(sal)>2000;

3.distinct

去除重复记录。如果出现在所有字段的前方表示所有字段联合起来去除重复记录?

select distinct job from emp;

统计工作岗位的数量?

select count(distinct job) from emp;

大总结(单表查询)

执行顺序?

  1. from 从某张表中查询数据
  2. where 先经过where条件筛选出有价值的数据
  3. group by 对这些有价值的数据进行分组
  4. having 分组之后可以使用having进行筛选
  5. select select查询出来
  6. order by 最后排序输出

找出每个岗位的平均薪资,要求显示薪资大于1500的并保留1位小数,除MANAGER岗位之外,要求按照平均薪资降序排

select job,round(avg(sal),1) avgsal from emp where job<>"manager" group by job having avg(sal)>1500 order by avgsal desc;

九、连接查询

连接查询:也可以叫跨表查询,需要关联多个表进行查询

根据表连接的方式:

​ 内连接:

​ 等值连接

​ 非等值连接

​ 自连接

​ 外连接:

​ 左外连接(左连接)

​ 右外连接(右连接)

​ 全连接(略)

如果多表查询没有加条件,就会出现出笛卡尔积现象

笛卡尔乘积是指在数学中,两个集合XY的笛卡尔积(Cartesian product),又称直积,表示为X × Y,第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员 。

1.内连接之等值连接

查询每个员工所在的部门名称,显示员工名和部门名?

sql92语法
select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno;
sql99语法
select e.ename,d.dname from emp e join dept d on e.deptno=d.deptno;

sql92的缺点:结构不清晰,表的连接条件,和后期进一步筛选条件都放到了where后面

sql99的优点:表连接的条件是独立的,连接之后如果还需要进一步的筛选,再往后添加where条件

2.内连接之非等值连接

找出每个员工的薪资等级,要求显示员工名、薪资、薪资等级?

select e.ename,e.sal,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;

3.内连接之自连接

查询员工的上级领导,要求显示员工名和对应的领导名?

select e.ename '员工名',m.ename '领导名' from emp e join emp m on m.mgr=e.empno; 

4.外连接(右外连接)

在外连接当中两张表产生了主次关系

right代表什么: 表示将右边的这张表看成主表,主要是为了将右边这张表的数据全查出来,捎带着关联左边的表。

查询所有部门对应的员工姓名?

select e.ename,d.dname from emp e right join dept d on e.deptno=d.deptno;

5.外连接(左外连接)

带有left的是左外连接

查询每个员工的上级领导,要求显示所有员工的名字和领导名?

select a.ename '员工',b.ename '领导' from emp a left join emp b on a.mgr=b.empno;

6.三张表、四张表连接

语法:

select … from a

​ join b on a和b的连接条件

​ left join c on a 和c的连接条件

​ join d on a和d的连接条件;

找出每个员工的部门名称以及工资等级,要求显示员工名、部门名、薪资、薪资等级、领导名字?

select e.ename,d.dname,e.sal,s.grade,l.ename from emp e join dept d on e.deptno=d.deptno join salgrade s on e.sal between losal and hisal left join emp l on e.mgr=l.empno;

十、子查询

子查询就是嵌套的 select 语句,可以理解为子查询是一张表

1.子查询出现在哪里?

select

​ …(select)

from

​ …(select)

where

​ …(select)

2.where子句中的子查询

找出比最低工资高的员工姓名和工资?

select ename,sal from emp where sal > (select min(sal) from emp);

3.from子句中的子查询

注意:from后面的子查询,可以将子查询的结果当成一张临时表。

找出每个岗位的平均薪资的薪资等级

select t.job,s.grade,t.a from (select job,avg(sal) a from emp group by job) t join salgrade s  on t.a between losal and hisal; 

4.select后面出现的子查询

找出员工的部门名,要求显示员工名,部门名?

select e.ename,(select d.dname from dept d where d.deptno=e.deptno ) as dname from emp e;

十一、union、limit

union的效率更高一些。对于表连接来说,每连接一次新表,则匹配的次数满足笛卡尔积,成倍的翻。但是union可以减少匹配的次数。在减少匹配次数的情况下,还可以完成两个结果集的拼接。

1.union

查询工作岗位是manager或者salesman

select ename,job from emp where job="manager" or job="salesman";
select ename,job from emp where job in("manager","salesman");
select ename,job from emp where job="manager" union select ename,job from emp where job="salesman";

2.limit

limit是将查询结果集的一部分取出来

完整用法:limit startIndex,length

按照薪资降序,取出前5条数据

select ename,sal from emp order by sal desc limit 0,5;

3.分页

每页显示3条记录

​ 第1页: limit 0,3 [0 1 2]

​ 第2页: limit 3,3 [3 4 5]

​ 第3页: limit 6,3 [6 7 8]

每页显示pasgeSize条记录

第pageNo页: limit (pageNo-1)*pageSize,pagesize;

十二、表

1.表的创建(DDL)

语法格式

create table tableName(
 columnName dataType(length),
 ………………
 columnName dataType(length)
);
set character_set_results='gbk';

show variables like '%char%';

2.关于MySQL中的数据类型

部分常用类型:

类型描述
char(长度)定长字符串,存储空间大小固定,适合作为主键或外键
varchar(长度)变长字符串,存储空间等于实际数据空间
double(有效数字位数,小数位)数值型
float(有效数字位数,小数位)数值型
int(长度)整数
bigint(长度)长整型
Date日期型
BLOBBinary Large Object(二进制大对象)
CLOBCharacter Large Object (字符大对象)

3.创建一个学生表

学号、姓名、年龄、性别、邮箱地址

create table t_student(
 no int,
 name varchar(32),
 sex char(1) default('m'),
 age int(3),
 email varchar(255)
);

4.插入数据insert (DML)

语法格式:

​ inser into 表名(字段名1,字段名2,字段名3) values(值1,值2,值3);

注意:

​ 字段名和值要一一对应

​ insert语句但凡执行成功,那么必然会多一条记录

​ 字段名省略的话,就相当于都写上了~ 所以值也要都写上!

insert into t_student(no,name,sex,age,email) values(1,'jack','m',21,'test@163.com');
insert into t_student values(2,'tom','m',22,'test1@163.com');

一次插入多条记录:
insert into t_student values(2,'tom','m',22,'test1@163.com'),(3,'zs','m','9','test2@163.com');

将查询结果插入到一张表当中

create table dept_bak as select * from dept;
查询结果必须符合表的结构
insert into dept_bak select * from dept;

5.insert插入日期

数字格式化:format(数字,‘格式’)

str_to_date: 将字符串varchar类型转换为date类型,具体格式 str_to_date (字符串,匹配格式)

date_format:将date类型转换成具有一定格式的字符串类型

create table t_user(
	id int,
    name varchar(32),
    birth date
);

插入数据

insert into t_user(id,name,birth) values(1,'jack',str_to_date('12-06-2021','%d-%m-%Y'));
如果输入的字符串是YYYY-mm-dd,还可以自动转换
insert into t_user(id,name,birth) values(2,'tom','2021-6-12');

查询的时候还可以以某个特定的日期格式展示

​ date_format

select id,name,date_format(birth,'%m/%d/%Y') as birth from t_user;

6.date和datetime两个类型的区别

date是短日期:只包括年月信息

datetime是长日期:包括年月日时分秒信息

drop table if exists t_user;
create table t_user(
	id int,
    name varchar(32),
    birth date,
    create_time datetime
);

mysql短日期默认格式:%Y-%m-%d

mysql长日期格式:%Y-%m-%d %h:%i:%s

now()函数可以获取当前系统时间,是datetime类型的格式

insert into t_user(id,name,birth,create_time) values(1,'jack','2021-6-12','2021-6-12 19:50:22');
insert into t_user(id,name,birth,create_time) values(2,'tom','2021-6-12',now());

7.修改update语句(DML)

语法格式:

​ update 表名 set 字段名1=值1,字段名2=值2,字段名3=值3 where 条件;

update t_user set name="zhangsan",birth="2020-01-01" where id=1;

注意:如果不加where条件默认更新表中的所有数据。

8.删除delete语句(DML)

语法格式:

​ delete from 表名 where 条件

delete from t_user where id=2;

注意:如果不加where条件默认删除表中的所有数据。

9.表快速复制

原理:

将一个查询结果当做一张表创建

​ 这个可以完成表的快速复制

​ 表创建出来,同时表中的数据也存在了

create table t_user_bak as select * from t_user;

10.删除表

drop table t_student;  //如果存在就删除
drop table if exists t_student;  //如果不存在就不会报错

11.快速删除表中的数据

不支持回滚

truncate table 表名;

12.对表结构的增删改查

采用 alter table 来增加/删除/修改表结构,不影响表中的数据

一般不用,实际开发中,需求一旦确定之后,表结构确定之后,很少进行表的修改。因为开发进行中的时候,修改表结构,成本比较高。这里简单了解一下,如果修改结构可以用可视化工具。

1.添加字段

如需求发生改变,需要向t_user中加入联系电话字段,字段名称为:contact_tel类型为varchar(40)

alter table t_user add contact_tel varchar(40);

2.修改字段

如:name 无法满足需求,长度需要更改为 100

alter table t_user modify name varchar(100);

如 sex 字段名称感觉不好,想用 gender 那么就需要更爱列的名称

alter table t_user change sex gender char(2) not null;

3.删除字段

如:删除联系电话字段

alter table t_user drop contact_tel;

十三、约束

约束对应的单词:constraint

在创建表的时候,我们可以给表中的字段加上一些约束,来保证表中的数据完整性、有效性

约束的作用就是为了保证:表中的数据有效!!

1.常见的约束?

非空约束:not null

唯一性约束:unique

主键约束:primary key

外键约束:foreign key

检查约束:check(mysql不支持,oracle支持)

1.1非空约束:not null

非空约束not null约束的字段不能为NULL。

drop table if exists t_user;
create table t_user(
	id int,
	name varchar(255) not null
);
insert into t_user(id,name) values(1,'zhangsan');
insert into t_user(id,name) values(2,'lisi');
---------------------------------------------------
insert into t_user(id,name) values(2);
ERROR 1136 (21S01): Column count doesn't match value count at row 1
1.2唯一性约束:unique

唯一性约束的unique约束的字段不能重复,但是可以为null

drop table if exists t_user;
create table t_user(
	id int,
	name varchar(255) unique
);
insert into t_user(id,name) values(1,'zs');
insert into t_user(id,name) values(2,'ls');
insert into t_user(id) values(3);
insert into t_user(id) values(4);
--------------------------------------------------------
insert into t_user(id,name) values(3,'zs');
ERROR 1062 (23000): Duplicate entry 'zs' for key 'name'

name和email联合起来具有唯一性

​ 如果约束没有添加到字段后面,成为表级约束

drop table if exists t_user;
create table t_user(
	id int,
	name varchar(255),
 	email varchar(255),
    unique(name,email)
);
insert into t_user(id,name,email) values(1,'zhangsasn','123@qq.com');
insert into t_user(id,name,email) values(2,'zhangsasn','1234@qq.com');
-------------------------------------------------------------------
insert into t_user(id,name,email) values(2,'zhangsasn','1234@qq.com');
ERROR 1062 (23000): Duplicate entry 'zhangsasn-1234@qq.com' for key 'name'

在mysql中,如果一个字段同时被not null和unique约束,自动变成主键字段。

1.3主键约束:primary key

相关术语:主键约束、主键字段、主键值

主键值是每一行记录的唯一标识

任何一张表都应该有主键,建议使用int、bigint、char等类型

主键值不能是null同时也不能重复

drop table if exists t_user;
create table t_user(
	id int primary key,
	name varchar(255) 
);
insert into t_user(id,name) values(1,'zs');
insert into t_user(id,name) values(2,'ls');
---------------------------------------------------------
insert into t_user(id,name) values(1,'wz');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'

可以俩主键联合起来做表级约束,这样的主键叫复合主键,比较复杂。建议单一主键。

主键除了单一主键和复合主键之外,还可以这样分类:

​ 自然主键:主键值是一个自然数,和业务没关系

​ 单一主键:主键值和业务紧密相连,例如银行卡号。

主键值可以采用auto_increment自动维护

drop table if exists t_user;
create table t_user(
	id int primary key auto_increment,
	name varchar(255) 
);
insert into t_user(name) values('zs');
insert into t_user(name) values('ls');
select * from t_user;
+----+------+
| id | name |
+----+------+
|  1 | zs   |
|  2 | ls   |
+----+------+
1.4外键约束:foreign key

相关术语:外键约束、外键字段、外键值

子表中的一个字段引用父表中的一个字段。如果删除表,应该先删子表。

这里学生表中的cno字段引用班级表中的classno字段

drop table if exists t_student;
drop table if exists t_class;
create table t_class(
	classno int primary key,
    classname varchar(255)
);
create table t_student(
	id int primary key auto_increment,
    name varchar(255),
    cno int,
    foreign key(cno) references t_class(classno)
);
insert into t_class(classno,classname) values(100,'某高级中学1班');
insert into t_class(classno,classname) values(101,'某高级中学2班');
insert into t_student(name,cno) values('zhhangsan',100);
insert into t_student(name,cno) values('lisi',100);
insert into t_student(name,cno) values('wangwu',100);
insert into t_student(name,cno) values('tom',101);
insert into t_student(name,cno) values('jack',101);
insert into t_student(name,cno) values('jreey',101);
------------------------------------------------------------
insert into t_student(name,cno) values('wangwu',109);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`learn`.`t_student`, CONSTRAINT `t_student_ibfk_1` FOREIGN KEY (`cno`) REFERENCES `t_class` (`classno`))

字表中的外键引用父表中的某个字段,被引用的字段不一定是主键,至少具有unique约束(唯一性)。

外键值可以为null。

2.增加/删除/修改表约束

2.1删除约束
删除外键约束:alter table 表名 drop foreign key 外键 (区分大小写);
删除主键约束:alter table 表名 drop primary key;
删除约束:alter table 表名 drop key 约束名称;
2.2添加约束
添加外键约束:alter table 从表 add constraint 约束名称 foreign key 从表(外键字段) references 主表(主键字段);
添加主键约束:alter table 表 add constraint 约束名称 primary key 表(主键字段);
添加唯一性约束:alter table 表 add constraint 约束名称 unique 表(字段)
2.3修改约束,其实就是修改字段
alter table t_student modify student_name varchar(30) unique;

十四、存储引擎(了解)

存储引擎是MySQL中特有的术语。

存储引擎是一个表存储/组织数据的方式。

不同的存储引擎,表存储数据的方式不同。

数据库中的各表均被(在创建表时)指定的存储引擎来处理。

CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

在建表的时候可以在最后的")"的右边使用:

​ engine来指定存储引擎 。默认是InnoDB

​ charset来指定这张表的字符编码方式。默认是:utf-8

为了解当前服务器中有哪些存储引擎可用,可使用 SHOW ENGINES 语句 。

1.常用存储引擎

MyISAM

它管理的表具有以下特征:

​ – 使用三个文件表示每个表:

​ • 格式文件 — 存储表结构的定义(mytable.frm)

​ • 数据文件 — 存储表行的内容(mytable.MYD)

​ • 索引文件 — 存储表上索引(mytable.MYI)

​ – 灵活的 AUTO_INCREMENT 字段处理

​ – 可被转换为压缩、只读表来节省空间

InnoDB

它管理的表具有下列主要特征:

​ – 每个 InnoDB 表在数据库目录中以.frm 格式文件表示

​ – InnoDB 表空间 tablespace 被用于存储表的内容

​ – 提供一组用来记录事务性活动的日志文件

​ – 用 COMMIT(提交)、SAVEPOINT 及 ROLLBACK(回滚)支持事务处理

​ – 提供全 ACID 兼容

​ – 在 MySQL 服务器崩溃后提供自动恢复

​ – 多版本(MVCC)和行级锁定

​ – 支持外键及引用的完整性,包括级联删除和更新

MEMORY

使用 MEMORY 存储引擎的表,其数据存储在内存中,且行的长度固定,这两个特点使得 MEMORY 存储引擎非 常快。

• MEMORY 存储引擎管理的表具有下列特征:

​ – 在数据库目录内,每个表均以.frm 格式的文件表示。

​ – 表数据及索引被存储在内存中。

​ – 表级锁机制。

​ – 不能包含 TEXT 或 BLOB 字段。

• MEMORY 存储引擎以前被称为 HEAP 引擎

2.选择合适的存储引擎

• MyISAM 表最适合于大量的数据读而少量数据更新的混合操作。MyISAM 表的另一种适用情形是使用压缩的只 读表。

• 如果查询中包含较多的数据更新操作,应使用 InnoDB。其行级锁机制和多版本的支持为数据读取和更新的混合 操作提供了良好的并发机制。

• 可使用 MEMORY 存储引擎来存储非永久需要的数据,或者是能够从基于磁盘的表中重新生成的数据。

十五、事务(重点)

事务就是一个完整的业务逻辑,是一个最小的工作单元。

假如转账:从A账户向b账户转10000.

​ 将A账户的钱减去10000(update语句)

​ 将B账户的钱加上10000(update语句)

​ 这就是一个完整的业务逻辑。

以上就是最小的业务单元,不可再分。要么同时成功,要么同时失败。

只有DML语句才有事务:insert update delete。一旦涉及增删改查就要考虑安全问题。
事务是怎么做到多条DML语句同时成功或同时失败的呢?

​ InnoDB存储引擎: 提供一组用来记录事务性活动的日志文件

事务开启:

​ insert

​ insert

​ delete

​ update

​ insert

事务结束!

在事务的执行过程中,每一条DML的操作都会记录到“事务性活动的日志文件”。

我们可以提交事务,可以回滚事务。

提交事务:清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中。标志着事务全部成功结束。

回滚事务:将之前所有的DML操作全部撤销,并清空事务性活动的日志文件。标志着事务全部失败的结束。

2.提交/回滚事务

提交事务:commit; 语句 (MySQL默认自动提交事务)

回滚事务:rollback; 语句 (回滚永远只能回滚到上一次的提交点)

关闭自动提交事务

start transaction;

3.事务四个特性

​ A:原子性

​ 说明事务是最小的工作单元。不可再分。

​ C:一致性

​ 所有事物要求,在同一个事务中,所有操作必须同时成功,或者同时失败,以保证数据的一致性。

​ I:隔离性

​ A事务和B事务之间具有一定的隔离

​ D:持久性

​ 失误最终结束的一个保障。事务提交,就相当于没有保存到硬盘上的数据保存到硬盘上。

隔离性

当多个客户端并发地访问同一个表时,可能出现下面的一致性问题:

​ – 脏读取(Dirty Read) 一个事务开始读取了某行数据,但是另外一个事务已经更新了此数据但没有能够及时提交,这就出现了脏读取。

​ – 不可重复读(Non-repeatable Read) 在同一个事务中,同一个读操作对同一个数据的前后两次读取产生了不同的结果,这就是不可重复读。

​ –幻像读(Phantom Read) 幻像读是指在同一个事务中以前没有的行,由于其他事务的提交而出现的新行。

InnoDB 实现了四个隔离级别,用以控制事务所做的修改,并将修改通告至其它并发的事务:

​ – 读未提交(READ UMCOMMITTED) 允许一个事务可以看到其他事务未提交的修改。(最低的隔离级别)

 – 读已提交(READ COMMITTED) 允许一个事务只能看到其他事务已经提交的修改,未提交的修改是不可见的。 

​ – 可重复读(REPEATABLE READ) 确保如果在一个事务中执行两次相同的 SELECT 语句,都能得到相同的结果,不管其他事务是否提交这些修改。(银 行总账) 该隔离级别为 InnoDB 的缺省设置。

​ – 串行化(SERIALIZABLE) 【序列化】 将一个事务与其他事务完全地隔离。 (最高的隔离级别)

十六、索引

十七、视图

视图可以看成是一张新表。

视图修改的是表的原数据,可以直接操作表。

视图的创建

create view 视图名 as DQL语句;

可以对视图进行CRUD,修改的是表的数据。

十八、DBA命令

1.创建用户

CREATE USER username IDENTIFIED BY 'password';

2.授权

命令详解
mysql> grant all privileges on dbname.tbname to 'username'@'login ip' identified by 'password' with grant option;
1) dbname=*表示所有数据库
2) tbname=*表示所有表
3) login ip=%表示任何 ip
4) password 为空,表示不需要密码即可登录
5) with grant option; 表示该用户还可以授权给其他用户
  细粒度授权
首先以 root 用户进入 mysql,然后键入命令:grantselect,insert,update,delete on *.* to p361 @localhost Identified by "123";
如果希望该用户能够在任何机器上登陆 mysql,则将 localhost 改为 "%"。
  粗粒度授权
我们测试用户一般使用该命令授权,
GRANT ALL PRIVILEGES ON *.* TO 'p361'@'%' Identified by "123";
注意:用以上命令授权的用户不能给其它用户授权,如果想让该用户可以授权,用以下命令:
GRANT ALL PRIVILEGES ON *.* TO 'p361'@'%' Identified by "123" WITH GRANT OPTION;
privileges 包括:
1) alter:修改数据库的表
2) create:创建新的数据库或表
3) delete:删除表数据
4) drop:删除数据库/表
5) index:创建/删除索引
6) insert:添加表数据
7) select:查询表数据
8) update:更新表数据
9) all:允许任何操作
10) usage:只允许登录

3.回收权限

命令详解
revoke privileges on dbname[.tbname] from username;
revoke all privileges on *.* from p361;
use mysql
select * from user
进入 mysql 库中
修改密码;
update user set password = password('qwe') where user = 'p646';
刷新权限;
flush privileges

4.导出

导出整个数据库

在 windows 的 dos 命令窗口中执行:mysqldump bjpowernode>D:\bjpowernode.sql -uroot -p123

导出指定库下的指定表

在 windows 的 dos 命令窗口中执行:mysqldump bjpowernode emp> D:\ bjpowernode.sql -uroot –p123

5.导入

登录 MYSQL 数据库管理系统之后执行:source D:\ bjpowernode.sql;

十九、数据库设计的三范式

第一:要求任何一张表必须有主键,每一个字段原子性不可再分。

​ 口诀:一对一,外键唯一。

第二:建立在第一范式的基础之上,要求所有非主键字段完全依赖主键,不要产生部分依赖。

​ 口诀:多对多,三张表,关系表,两个外键。

第三:建立在第二范式的基础之上,要求所有非主键字段直接依赖主键,不要产生传递依赖。

​ 口诀:一对多,两张表,多的表加外键。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值