MySQL学习

SQL分类

  1. DDL:操作数据库和表
  2. DML:增删改表中数据
  3. DQL:查询表中数据
  4. DCL:管理用户,授权

启动、停止服务

1.启动命令:

net start mysql

2.停止服务命令:

net stop  mysql

登录、退出

1.登录命令:

mysql -uroot -proot //-u后面是用户的登录的用户名,-p是用户登录密码,方式一,使用此方式在mysql5.6以后会出现警告,但是并没有什么影响,还是能成功进入数据库进行操作。
mysql -uroot -p //按下回车键后输入密码,此时的密码是密文显示的,更安全,方式二   

2.退出命令:

直接关闭cmd窗口  //方式一
exit      //方式二
quit     //方式三  

3.远程连接mysql命令

mysql -h127.0.0.1 -uroot -proot //-h后面输入想要远程连接的ip,-p后面输入的是想要连接的ip的mysql的密码。方式一
mysql --host=127.0.0.1 --user=root --password=root     //方式二,当然也可以选择按下回车键再输入密码。127.0.0.1表示想要远程连接的目标的ip地址,password后面写的是想要远程连接的目标的mysql密码。

注释

方式一:/使用-- 来添加注释

select * from student; -- 这是一个注释示例 
//在sql语句后使用--表示注释,--后必须要空一格,否则会报错,然后写自己想要添加的注释内容。  

方式二:使用#来添加注释

select * from student # 这是一个注释示例2
//使用#来添加注释,在sql语句后使用#,#后面是自己想要添加的注释内容,#后面有无空格都可以。

方式三:使用/* */表示多行注释

select * from student 
    /*
    这是
    多行
    注释。
    */
;

向数据库中插入数据时出现中文乱码的解决方案

1.找到my.ini文件

找到安装目录的根目录下的my.ini文件,如果此目录下没有,可以进入ProgramData文件夹,注意此文件夹是隐藏文件夹,一般情况下my.ini文件就在这两个文件夹的根目录下,如果没有,自己在这两个文件夹中寻找,找不到的话,可以自己去创建。

2.进入my.ini配置文件对其进行修改

修改下方三个地方:

  [client]  
   default-character-set=utf8  
  [mysql]  
   default-character-set=utf8  
  [mysqld]  
  default-character-set=utf8  

以上3个section都要加default-character-set=utf8,平时我们可能只加了mysqld一项。如果没有完全修改可以依旧会出现中文乱码问题。
然后重启mysql,执行SQL语句。

SHOW VARIABLES LIKE 'character%';

确保所有的Value项都是utf8即可,再向数据库中插入数据就不会出现中文乱码问题了。
如果再出现中文乱码,可以直接进入命令行界面,直接写sql语句,查看插入中文数据是否会出现乱码,如果再次出现乱码可能是数据库创建时没有使用utf8的编码字符集,修改数据的编码字符集为utf8一般就可以了。

对数据库操作

创建数据库

创建数据库命令:

create database test1;    //此时创建的数据库名为test1
 /*
此时可能会出现错误,即数据库本来存在,可以在创建数据库之前进行判断数据库是否存在,使用下面的语句可以避免出现上述错误。
 */

create database if not exists test1;

查询数据库中存在的数据库命令:

show databases;   //使用此命令会把所有的数据库查询结果显示出来。

创建数据库时指定数据库的编码字符集命令:

create database test2 character set utf8; //此时创建的数据库名为test2

create database if not exists test2 character set utf8;//在创建数据库之前判断数据库是否存在。

show create database test2 ;  //查看数据库test2的编码字符集

修改数据库

修改数据库的字符集命令:

alter database test2 character set gbk; //修改数据库test2的字符集为gbk

删除数据库

删除数据库命令:

 drop database test2; //删除数据库名为test2的数据库

 drop database if exists test2; //在删除数据库之前判断数据库是否存在,存在则删除,不存在该语句也不会报错。

使用数据库

修改正在使用的数据库的命令:

use test1 ; //修改当前使用的数据库为test1

查询当前正在使用的数据库名称的命令:

select database(); //使用此命令查询显示出当前正在使用的数据库名称。

数据库表的操作

数据库表的查询操作

查询所有表的命令:

show tables;  //注意使用此命令前需要先使用数据库的命令    --->   use  数据库名称,确保当前有数据库正在使用。

查询表结构命令:

desc student;  //student 为表名

创建表命令:

create table 表名(
 列名1   数据类型1,
 列名2   数据类型2,
 列名3   数据类型3,
   ......
 列名n   数据类型n
);
//注意,前面的(不是最后一个)列名和数据类型后需要写一个逗号,最后一个列名和数据类型写完以后,不能再加逗号,加了的话会出错。
例如:
 create table student(
-> id int,
-> name varchar(32),
-> age int,
-> birthday date,
-> insert_time timestamp
-> );

删除表命令:

drop table 表名;
例如:
drop table student;   //这样可以会出现错误,即表不存在,可以在删除之前进行判断。
示例二:
drop table if exists student;

复制表命令:

create table 表名 like 被复制的表名;
示例:
create table stu like student;

修改表命令:
修改表名命令:

alter table student rename to stu; //将表student 重命名为stu

修改表的字符集命令:

alter table stu character set utf8;  //将表stu的字符集修改为utf8   

添加一列命令:

alter table 要修改表名 add  列名 数据类型;
alter table stu add salary double;

修改列名称、类型命令:

同时修改列名和数据类型:
alter table 要修改表名 change 被修改列名  新的列名 新的数据类型;
示例:
alter table stu change salary sex varchar(10);
只修改数据类型:
alter table 要修改的表名 modify 被修改列名 新的数据类型;
示例:
alter table stu modify sex  varchar(20); 

删除列命令:

alter table 表名 drop 要删除的列名;
示例:
alter table stu drop sex;

数据库表中的数据的操作

添加数据命令:

insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n);
示例一:
insert into stu (id,name,age,birthday) values(1,'小明',21,19991011);
示例二:
insert into stu  values(2,'小红',20,'1999-10-11',null);
/*
注意,
1.此时的日期不能写成1999-10-11,会出错,日期之间不能加-。如果想要添加-可以在日期之前使用单或双引号(''或"")包裹。
2.列名和数据值应该一一对应。
3.如果表名之后不定义列名,则默认给所有的列赋值。如果不想给某个数据赋值,可以使用null代替,但是如果缺少数据值(列名和值不对应),则会报错。
4.除了数字类型,其他类型的数据值需要使用单或双引号(''或"")包裹。
5.sql语句中除了中文的数据值之外,其他的都要使用英文格式下的符号。
*/

修改表中数据的命令:

update 表名 set 列名1 = 值1 ,列名2 = 值2; ... where条件
示例:
update stu set name = '小王' ,age = 23 where id = 1; 
//注意,如果不加任何条件,会把表中所有的数据全部修改。

删除表中的数据命令:
删除表中指定数据的命令:

delete from 表名 where 条件
示例:
delete from stu where id = 3;  //删除stu表中id为3的数据

删除表中所有数据的命令:

delete  from 表名;   //方式一
TRUNCATE table 表名;   //方式二
方式一示例:
delete  from stu;  //删除stu表中的所有数据,不推荐使用,效率较低。
方式二示例:
TRUNCATE table stu;  //删除stu表,然后再创建一个一模一样的空表。

基础查询

查询表中所有数据命令:

select * from 表名;
示例:
select * from stu;  //查询stu表中的所有数据。

查询部分数据命令:

select 列名1,列名2,... from 表名;
示例:
select name,age,address from student;  //在student表中查询姓名、年龄、地址

去除重复数据命令:

select distinct 列名1,列名2 ... from 表名;
示例:
select distinct address from student;

练习:计算数学和英语的成绩之和,显示出姓名、数学成绩、英语成绩和数学英语成绩之和

select name, math,english ,math + english from student; //当出现某个数据为null时,数据之和也会为null的情况,是不合理的。
select name, math,english ,ifnull (math,0) + ifnull (english,0) from student;   //如果数学成绩或者英语成绩为null的话将其数据改为0进行计算。

给数据取别名,例如,将math + english 取别名为 总分
select name, math,english ,ifnull (math,0) + ifnull (english,0) as 总分 from student;  //方式一
select name 姓名, math 数学,english 英语,ifnull (math,0) + ifnull (english,0) 总分 from student;  //方式二,不使用as,直接加一个空格,再写别名也可以。

条件查询

示例一:查询student表中年龄大于20岁的数据
select * from student where age > 20;  //注意:此时查询的数据不包括年龄等于20的数据。

示例二:查询student表中年龄等于20岁的数据
select * from student where age = 20; 

示例三:查询student表中年龄不等于20岁的数据
select * from student where age != 20; //方式一
select * from student where age <> 20; //方式二

示例三:查询student表中年龄大于20岁,小于25岁的数据
select * from student where age > 20 and age < 25 ; //方式一
select * from student where age between 20 and 25 ; //方式二,此方式包括20岁和25岁的数据。
select * from student where age > 20 && age < 25 ; //方式三 ,不推荐使用

示例四:查询student表中年龄为20岁、22岁的数据
select * from student where age = 20 or age = 22 ; //方式一
select * from student where age in (20 , 22) ; //方式二

示例五:查询student表中英语成绩为null的数据
select * from student where english is null; //注意,查询数据为null时不能使用等号。需要使用is。

示例六:查询student表中英语成绩不为null的数据
select * from student where english is  not null;

模糊查询

示例一:查询student表中姓为 小 的数据
select * from student where name like '小%' ; // % 号表示任意字符,下划线(_)表示单个字符。

示例二:查询student表中姓名中第二个字为 三 的数据
select * from student where name like '_三%' ;

示例三:查询student表中姓名为两个字的数据
select * from student where name like '__' ;   //在引号内写上两个英文格式下的_即可。 

示例一:查询student表中姓名中包含 小 的数据
select * from student where name like '%小%' ;

排序查询

select * from 表名 order by 需要排序的列名1 排序方式,需要排序的列名2 排序方式2 ... ;
注意,默认情况下,即不写排序方式或者写成 asc ,按照升序进行排序,使用desc来表示降序的排序方式。当有多个字段进行排序时,只有前面需要排序的字段的的数据相同时,才会去判断后面的数据。

示例一:将student表中的数据按照math的成绩进行升序排序
select * from student order by math ;  

示例二:将student表中的数据按照math的成绩进行降序排序
select * from student order by math desc ;  

示例三:将student表中的数据按照math的成绩进行升序排序,如果数学成绩相同,则按照英语成绩进行降序排序。
select * from student order by math , english desc ; 

示例四:将student表中的数据按照math的成绩进行降序排序,如果数学成绩相同,则按照英语成绩进行降序排序。
select * from student order by math desc , english desc ; 

聚合函数:将一列数据作为一个整体,进行纵向的计算

  1. count:计算数量
  2. max:计算最大值
  3. min: 计算最小值
  4. sum:计算和
  5. avg:计算平均值。

注意:聚合函数的计算排除了字段为null的值。

示例一:计算student表中name字段的总数量。
select count(name) 学生总数 from student;

示例二:计算student表中english字段的总数量,解决count计算数量时排除字段为null的问题。
select count(ifnull (english,0)) from student;

示例三:计算student表中math字段的最大值。
select max(math)  from student;

示例四:计算student表中math字段的最小值。
select min(math)  from student;

示例五:计算student表中math字段的和。
select sum(math)  from student;

示例六:计算student表中english字段的和(english字段中存在数据值为null的数据)。
select sum(english)  from student;  //默认会排除数据值为null的数据值

示例七:计算student表中math字段的平均值。
select avg(math)  from student;

分组查询

注意:
分组之后查询的数据只能是聚合函数或者分组字段,加上其他的字段没有任何意义。

示例一:按照性别分组,分别查询男、女同学的英语成绩的平均分。
select sex , avg(english) from student group by sex;

示例二:按照性别分组,分别查询男、女同学的英语成绩的平均分和人数。
select sex , avg(english),count(id) from student group by sex;

示例三:按照性别分组,分别查询男、女同学的英语成绩的平均分和人数,英语成绩低于60分的同学不参与分组。
select sex , avg(english),count(id) from student where english > 60 group by sex;

示例四:按照性别分组,分别查询男、女同学的英语成绩的平均分和人数,英语成绩低于60分的同学不参与分组,要求分组后的成员数量要大于2人。
select sex , avg(english),count(id) from student where english > 60 group by sex having count(id) > 2;

where 和 having 的区别?

  1. where 在分组之前进行限定,如果不满足分组,则不参与分组,having 在分组之后进行限定,如果不满足条件,数据不会显示出来。

  2. where 后不可以进行聚合函数的判断,having 后可以进行聚合函数的判断。

分页查询

select from 表名 limit 开始的索引,每页要显示的数量

开始的索引计算方式: 开始的索引 = (当前的页码 -1 ) * 每页要显示的数量

示例一:
select * from student limit 0,5; -- 第一页  //当前为第一页,每页要显示5条数据。

limit是mysql的分页显示数据的语法。其他的数据库则不是limit

约束

概念:对数据库表中的数据进行限定,保证数据的正确性、完整性、有效性。

分类:

  1. 主键约束 --> primary key

  2. 非空约束 --> not null

  3. 唯一性约束 --> unique

  4. 外键约束 --> foreign key

主键约束并使其自动增长

注意:
1.包含主键约束的字段非空且唯一。
2.一张表中只能有一个字段作为主键。
3.主键是表中记录的唯一性标识。

示例一:在创建表时为字段id添加主键约束,创建表的SQL语句如下:
create table stu(
id int primary key ,
name varchar(20)
);

示例二:在创建表时为字段id添加主键约束并使其自动增长,创建表的SQL语句如下:
create table stu(
id int primary key auto_increment ,
name varchar(20)
);

示例三:删除字段的主键约束
alter table stu drop primary key ; 

示例四:删除字段的自动增长,并不能删除主键约束:
alter table stu modify id int;  //方式一
alter table stu change id id int;  //方式二

示例五:创建表完成之后再为字段添加主键约束
alter table stu modify id int primary key;  //方式一
alter table stu change id id int primary key;  //方式二


示例六:创建表完成之后再为字段添加自动增长
alter table stu modify id int auto_increment;  //方式一
alter table stu change id id int auto_increment;  //方式二

非空约束

示例一:在创建表时为字段name添加非空约束,创建表的SQL语句如下:
create table stu(
id int, 
name varchar(20) not null
);

示例二:删除字段name的非空约束
alter table stu modify name varchar(20);  //方式一
alter table stu change name  name varchar(20);  //方式二

示例三:创建表完成之后再为字段name添加非空约束
alter table stu modify name varchar(20) not null;  //方式一
alter table stu change name  name varchar(20) not null;  //方式二

唯一性约束

注意:mysql中,在没有非空约束的字段下,唯一性约束的字段的数据中可以有多个null,不会报错。

示例一:在创建表时为字段name添加唯一性约束,创建表的SQL语句如下:
create table stu(
id int, 
name varchar(20) not null,unique
);

示例二:删除字段name的唯一性约束
alter table stu drop index name ;

示例三:创建表完成之后再为字段name添加唯一性约束
alter table stu modify name varchar(20) unique ;  //方式一
alter table stu change name  name varchar(20) unique ;  //方式二

外键约束

外键约束:让表与表之间产生关系,从而保证了数据的正确性。

create table 表名(
  ......
外键列名 外键列数据类型,
constraint 外键名称 foreign key (外键列名) references 需要关联的主表名(需要关联的主表的列名)
);

示例一:在创建表时添加外键约束,
create table employee(
id int primary key auto_increment ,
name varchar(20),
age int ,
dep_id int ,
constraint emp_dept_fk foreign key (dep_id) references department(id)
);

示例二:删除表的外键约束
alter table employee drop foreign key emp_dept_fk;  //emp_dept_fk外外键名称。

示例三:创建表完成之后再添加外键约束
alter table employee add constraint emp_dept_fk foreign key (dep_id) references department(id);

示例四:添加外键,并设置级联更新
alter table employee add constraint emp_dept_fk foreign key (dep_id) references department(id) on update cascade;

示例五:添加外键,并设置级联更新,级联删除 ,一般不会设置级联删除。
alter table employee add constraint emp_dept_fk foreign key (dep_id) references department(id) on update cascade on delete cascade;

多表操作

多表之间的关系:
      一对一
      一对多
      多对多

多表查询

笛卡尔积:有两个集合A,B .取这两个集合的所有组成情况。要完成多表查询,需要消除无用的数据。
多表查询的分类:
  1. 内连接查询
      1.隐式内连接
      2.显式内连接

内连接查询需要明确的:
1. 想要从哪些表中查询数据?
2. 查询的条件是什么?
3. 需要查询哪些字段

示例一(隐式内连接):查询所有的员工信息及其对应的部门信息:
 select * from emp,dept where emp.dept_id = dept.id;

示例二(隐式内连接):查询员工表的姓名、性别、工资及其对应的部门名称:
 select 
 emp.name,
 emp.gender,
 emp.salary,
 dept.name 
 from 
 emp,dept 
 where 
 emp.dept_id = dept.id;

 示例三(隐式内连接):查询员工表的姓名、性别、工资及其对应的部门名称,为表取别名,简化sql语句:
 select 
 e.name,
 e.gender,
 e.salary,
 d.name 
 from 
 emp e,dept d 
 where 
 e.dept_id = d.id;

//显式内连接: select 字段列表 from 表名1 inner join 表名2 on 条件
    //注意 inner 可以省略不写
示例四(显式内连接):查询所有的员工信息及其对应的部门信息:
 select * from emp inner join dept on emp.dept_id = dept.id;
 select * from emp join dept on emp.dept_id = dept.id;

 示例五(显式内连接):查询员工表的姓名、性别、工资及其对应的部门名称,为表取别名,简化sql语句:
 select 
 e.name,
 e.gender,
 e.salary,
 d.name 
 from 
 emp e
 join
 dept d 
 on
 e.dept_id = d.id;

  2. 外连接查询
      1.左外连接
      2.右外连接

左外连接查询:select 字段列表 from 表1 left [outer] join 表2 on 条件;
查询的是左表所有数据以及其交集部分。

示例一(左外连接):查询所有的员工信息,如果员工有部门显示出部门名称,没有部门则不显示部门名称。
select
e.*,
d.name
from 
emp e 
left join
dept d
on
e.dept_id = d.id;

示例二(左外连接):查询员工表中员工的姓名、性别、工资,如果员工有部门显示出部门名称,没有部门则不显示部门名称。
select
e.name,
e.gender,
e.salary,
d.name
from 
emp e 
left join
dept d
on
e.dept_id = d.id;

右外连接:select 字段列表 from 表1 right [outer] join 表2 on 条件;
查询的是右表所有数据以及其交集部分。

示例一(右外连接):查询员工表中员工的姓名、性别、工资,如果员工有部门显示出部门名称,没有部门则不显示部门名称。
select
d.name,
e.name,
e.gender,
e.salary
from
dept d
right join
emp e
on
e.dept_id = d.id;

  3. 子查询

   1. 子查询的结果是单行单列的:

      子查询可以作为条件,使用运算符 > >= < <= = 去判断。
   2. 子查询的结果是多行单列的:

      子查询可以作为条件,使用运算符in来判断。
   3. 子查询的结果是多行多列的:

      子查询可以作为一张虚拟表参与查询。

示例一(结果是单行单列的):查询工资最高的员工的信息:
select * from emp where salary = (
    select max(salary) from emp
    );
示例二(结果是单行单列的):查询员工工资小于平均工资的员工信息
select * from emp where salary < (select avg(salary) from emp); 

示例三(结果是多行单列的):查询财务部和市场部的所有员工信息
select * from emp where dept_id in (select id from dept where name = '财务部' or name = '市场部'); 

示例四(结果是多行多列的):查询员工的入职时间在2011年11月11日之后的员工信息和部门信息
select * from dept  d ,(select * from emp where join_date > 20111111) e1 where e1.dept_id = d.id ;   //方式一,使用子查询
select * from dept d , emp e where e.dept_id = d.id and join_date > '2011-11-11' ;   //方式二,使用普通内连接查询

多表查询练习

练习1:查询所有员工信息。查询员工编号,员工姓名,工资,职务名称,职务描述
select 
e.id,
e.ename,
e.salary,
j. jname,
j.description
from 
emp e,
job j 
where 
e.job_id = j.id; 

练习2:查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置
select 
e.id ,
e.ename ,
e.salary ,
j.jname,
j.description,
d.dname,
d.loc 
from 
emp e,
job j,
dept d
where
e.job_id = j.id 
and 
e.dept_id = d.id;

练习3:查询员工姓名,工资,工资等级
select 
e.ename ,
e.salary ,
s.grade
from 
emp e ,
salarygrade s 
where 
e.salary 
between 
losalary 
and 
hisalary;

练习4:查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
select 
e.ename ,
e.salary ,
j.jname,
j.description ,
d.loc ,
s.grade
from 
emp e,
job j, 
dept d,
salarygrade s
where 
e.job_id = j.id 
and 
e.dept_id = d.id 
and 
e.salary 
between
losalary
and 
hisalary ;

练习5:查询出部门编号、部门名称、部门位置、部门人数
select 
d.id,
d.dname,
d.loc , 
t.total 
from 
dept d ,
(select dept_id , count(id) total from emp group by dept_id ) t 
where 
dept_id = d.id ;

练习6:查询所有员工的姓名及其直接上级的姓名,没有领导的员工也需要查询。
//emp表中mgr 和emp表中的id进行自关联,为emp表取别名查询两次,相当于是两个表
select 
e1.ename 姓名,  -- 员工姓名
e1.mgr ,    -- 员工的管理者 ,可以不查询
e2.id ,     -- 员工的id  ,可以不查询
e2.ename 管理者    -- 管理者姓名
from 
emp e1 
left 
join 
emp e2 
on  
e1.mgr = e2.id;

数据库范式

设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。
目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。

分类

  1. 第一范式(1NF):即数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项,第一范式就是无重复的域。在任何一个关系数据库中,第一范式(1NF)是对关系模式的设计基本要求,一般设计中都必须满足第一范式(1NF)。
  2. 第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)。
  3. 第三范式(3NF):在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)。
  4. 巴斯-科德范式(BCNF):在3NF基础上,任何非主属性不能对主键子集依赖(在3NF基础上消除对主码子集的依赖)

参考:函数依赖百度百科

参考:数据库范式百度百科

数据库的备份还原

1.命令行的方式:

备份:mysqldump -u用户名 -p用户密码  需要备份的数据库名称 > 保存的文件路径  
还原: 
     1.登录mysql数据库
     2.创建数据库
     3.使用数据库
     4.执行保存的原数据库文件 命令:source 保存的文件路径。
示例:
    数据库备份 :mysqldump -uroot -proot  test > e://DataBase//haha.sql
    数据库还原: 1. mysql -uroot -proot
                2. create database haha;
                3. use haha;
                4. source  e://DataBase//haha.sql

2.图形化工具的方式

此处以使用Navicat for MySQL 图形化界面为例:
        1.选择要备份的数据库名称,
        2.右键,选择 -->转储SQL文件
        3.选择要保存的路径
        4.新建数据库
        5.在新建的数据库右键选择 --->运行SQL文件
        6.在弹出的界面选择转储sql文件保存的文件路径,点击开始
        7.在新建的数据库中进行刷新,数据库还原成功。

事务

1. 事务的基本介绍

1.概念:
事务是用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位。

2.操作:

  1. 开启事务: start transaction;

  2. 回滚:rollback;

  3. 提交:commit;

3.事务提交的两种方式

  1. 自动提交:
      MySQL数据库中事务默认自动提交。
      一条DML(增删改)语句会自动提交一次事务。

  2. 手动提交:
      Oracle 数据库默认是手动提交事务
      需要先开启事务,再提交

  3. 修改事务的默认提交方式:
      查看事务的默认提交方式:SELECT @@autocommit; -- 1 代表自动提交 0 代表手动提交
      改默认提交方式: set @@autocommit = 0;

事务的四大特征

  1. 原子性:事务是数据库的逻辑单位,事务中的操作要么全做,要么全不做。
  2. 持久性:一个事务一旦提交,它对数据库中数据的改变就是永久性的,接下来的其他操作或故障不应该对其执行结果有任何影响。
  3. 隔离性:一个事务的执行不能被其他事务干扰,即一个事务的内部操作及使用的数据对其他并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
  4. 一致性:事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。

事务的隔离级别(了解)

概念:多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。
存在问题:

  1. 读“脏”数据:一个事务,读取到另一个事务中没有提交的数据
  2. 不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。
  3. 丢失修改:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。

隔离级别:

  1. read uncommitted:读未提交。
    产生的问题:脏读、不可重复读、幻读
  2. read committed:读已提交 (Oracle)
    产生的问题:不可重复读、幻读
  3. repeatable read:可重复读 (MySQL默认)
    产生的问题:幻读
  4. serializable:串行化
    可以解决所有的问题
    注意:隔离级别从小到大安全性越来越高,但是效率越来越低
    数据库查询隔离级别:
    select @@tx_isolation;
    数据库设置隔离级别:
    set global transaction isolation level 级别字符串;

DCL --> 管理用户,授权

mysql中忘记root用户的密码解决方案

1. 使用管理员权限打开cmd -- > net stop mysql 停止mysql服务
2. 使用无验证方式启动mysql服务: mysqld --skip-grant-tables
3. 打开新的cmd窗口,直接输入mysql命令,敲回车键。就可以登录成功
4. use mysql;
5. update user set password = password('新密码') where user = 'root';
6. 关闭两个cmd窗口
7. 打开任务管理器,手动结束mysqld.exe 的进程
8. 启动mysql服务
9. 使用新密码登录。

管理用户

1.添加用户:
语法:CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
示例:CREATE USER 'asd'@'localhost' IDENTIFIED BY 'asd';

2. 删除用户:
语法:DROP USER '用户名'@'主机名';
示例:DROP USER 'asd'@'localhost';

3. 修改用户密码:
方式一: UPDATE USER SET PASSWORD = PASSWORD('新密码') WHERE USER = '用户名'; 
方式二: SET PASSWORD FOR '用户名'@'主机名' = PASSWORD('新密码'); 
示例一:UPDATE USER SET PASSWORD = PASSWORD('abc') WHERE USER = 'lisi';
示例二:SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123');

4. 查询用户:
-- 1. 切换到mysql数据库
USE myql;
-- 2. 查询user表
SELECT * FROM USER;

权限管理

1. 查询权限:
SHOW GRANTS FOR '用户名'@'主机名';
示例: SHOW GRANTS FOR 'root'@'localhost';

2. 授予权限:
grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';
示例一:给asd用户授予所有权限。
GRANT ALL ON *.* TO 'asd'@'localhost';
示例二:给asd用户授予查询test数据库中student表的权限。
 GRANT SELECT ON test.student TO 'asd'@'localhost';

3. 撤销权限:
revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';
示例:撤销asd用户对test数据库中student表的权限
REVOKE UPDATE ON test.`student` FROM 'asd'@'localhost';
posted @ 2019-08-02 22:32  难得糊涂1998  阅读(274)  评论(0编辑  收藏  举报