十二、运算符
12.1 导入数据
在命令行客户端登录mysql,使用source指令导入
mysql> source d:\mysqldb.sql
12.2 算术运算符
加:+ 减:- 乘:* 除:/ div(只保留整数部分) 模:% mod
12.3 比较运算符
大于:> 小于:< 大于等于:>= 小于等于:<= 等于: = 不能用于null 不等于: != 或 <>
12.4 逻辑运算符
逻辑与:&& 或 and 逻辑或: || 或 or 逻辑非: ! 或 not 逻辑异或: ^ 或 xor
#查询薪资高于15000的女员工
select * from t_employee where salary > 15000 && gender = '女';
#查询薪资高于15000 或 籍贯是北京的
select * from t_employee where salary > 15000 || native_place = '北京';
#查询薪资不高于15000的员工
select * from t_employee where salary <= 15000;
select * from t_employee where !(salary > 15000);
#查询薪资高于15000的非北京人,或北京的薪资<=15000
select * from t_employee where salary > 15000 ^ native_place = '北京'; #有且只有一个条件满足,不能都不满足,也不能都满足
可以用单词代替运算符:
#查询薪资高于15000的女员工
select * from t_employee where salary > 15000 and gender = '女';
#查询薪资高于15000 或 籍贯是北京的
select * from t_employee where salary > 15000 or native_place = '北京';
#查询薪资不高于15000的员工
select * from t_employee where not(salary > 15000);
#查询薪资高于15000的非北京人,或北京的薪资<=15000
select * from t_employee where salary > 15000 xor native_place = '北京';
12.5 区间范围运算符
区间范围:between x and y / not between x and y
集合范围:in(x,x,x) / not in(x,x,x)
12.6 模糊查询运算符
%:代表任意个字符
_:代表一个字符,如果两个下划线代表两个字符
#查询名字中包含'冰'字
select * from t_employee where ename like '%冰%';
#查询名字以‘雷'结尾的
select * from t_employee where ename like '%雷';
#查询名字以’李'开头
select * from t_employee where ename like '李%';
#查询名字有冰这个字,但是冰的前面只能有1个字
select * from t_employee where ename like '_冰%';
#查询当前mysql数据库的字符集情况show variables like '%character%';
12.7 关于null值的问题
(1)判断时
xx is null ; xx is not null ; xx <=> null
(2)计算时
ifnull( xx , 代替值) 当xx 是 null 时, 用代替值计算
12.8 位运算符
左移:<< 右移: >> 按位与: & 按位或: | 按位异或: ^ 按位取反: ~
十三、系统函数
13.1 单行函数(了解,用的时候查)
调用完函数后,记录数不变,一行计算完之后还是一行。
1、数学函数
2、字符串函数
3、日期时间函数
4、加密函数
5、其他函数
6、流程控制函数
13.2 分组函数
调用完函数后,结果的行数变少了,可能得到一行,可能得到少数几行。
分组函数有合并计算过程。
组函数类型
-
AVG(x) 求平均值
-
SUM(x) 求总和
-
MAX(x) 求最大值
-
MIN(x) 求最小值
-
COUNT(x) 计数
十四、关联查询(联合查询)
14.1 什么是关联查询
关联查询:两个或更多个表一起查询。
前提条件:这些一起查询的表之间是有关系的(一对一、一对多),它们之间一定是有关联字段,这个关联字段可能建立了外键,也可能没有建立外键。
比如:员工表和部门表,这两个表依靠“部门编号”进行关联。
14.2 关联查询结果分为几种情况
(1)A表 ∩ B表
(2)A表全部
(3)A表- A∩B
(4)B表全部
(5)B表-A∩B
(6)A表∪B表
(7)A∪B - A∩B
14.3 关联查询的SQL有几种情况
1、内连接:inner join ... on
结果:A表 ∩ B表
/*
内连接
*/
#查询每一个员工及其所在部门的信息
SELECT *
FROM t_employee INNER JOIN t_department
ON t_employee.did = t_department.did; #关联条件
#问题:笛卡尔积,没写关联条件,那么会出现A表 * B表的记录,这种情况要避免
SELECT *
FROM t_employee INNER JOIN t_department; #没有写关联条件
#内连接的一种变形
SELECT *
FROM t_employee , t_department
WHERE t_employee.did = t_department.did;
2、左连接:A left join B on
(2)A表全部
(3)A表- A∩B
/*
左连接
(2)A
(3)A - A∩B
*/
#查询所有员工信息,以及他们所在的部门信息,包括那些没有分配部门的员工
SELECT *
FROM t_employee LEFT JOIN t_department
ON t_employee.did = t_department.did;
#查询员工信息,只查询没有分配部门的员工
SELECT *
FROM t_employee LEFT JOIN t_department
ON t_employee.did = t_department.did #on后面只写关联条件
WHERE t_employee.did IS NULL; #关联后的筛选条件放到where中
#筛选A-A∩B和B-A∩B的where条件都是使用从表的关联字段is null
#关联条件是 t_employee.did 和 t_department.did
#如果要建外键,是在从表t_employee中的did字段上面建外键
SELECT *
FROM t_employee LEFT JOIN t_department
ON t_employee.did = t_department.did
AND t_employee.did IS NULL; #错误的
SELECT *
FROM t_employee LEFT JOIN t_department
ON t_employee.did = t_department.did
AND gender = '男'; #错误的
3、右连接:A right join B on
(4)B表全部
(5)B表-A∩B
/*
右连接
(2)B
(3)B - A∩B
*/
#查询所有部门信息,以及该部门的所有员工,包括那些没有员工的部门
SELECT *
FROM t_employee RIGHT JOIN t_department
ON t_employee.did = t_department.did;
#查询部门信息,只查询没有员工的部门
SELECT *
FROM t_employee RIGHT JOIN t_department
ON t_employee.did = t_department.did #on后面只写关联条件
WHERE t_employee.did IS NULL; #关联后的筛选条件放到where中
#筛选A-A∩B和B-A∩B的where条件都是使用从表的关联字段is null
#关联条件是 t_employee.did 和 t_department.did
#如果要建外键,是在从表t_employee中的did字段上面建外键
#其实左连接和右连接完全可以互换
#查询所有员工信息,以及他们所在的部门信息,包括那些没有分配部门的员工
SELECT *
FROM t_department RIGHT JOIN t_employee
ON t_employee.did = t_department.did;
#查询员工信息,只查询没有分配部门的员工
SELECT *
FROM t_department RIGHT JOIN t_employee
ON t_employee.did = t_department.did #on后面只写关联条件
WHERE t_employee.did IS NULL; #关联后的筛选条件放到where中
4、全外连接:full outer join ... on,但是mysql不支持这个关键字,mysql使用union(合并)结果的方式代替
(6)A表∪B表: (2) A表结果 union (4)B表的结果
(7)A∪B - A∩B (3)A表- A∩B结果 union (5)B表-A∩B结果
/*
union实现
(6)A∪B
(7)A∪B - A∩B
A-A∩B ∪ B-A∩B
*/
#查询所有员工信息,以及他们所在的部门信息,包括那些没有分配部门的员工
#结果是A
SELECT *
FROM t_employee LEFT JOIN t_department
ON t_employee.did = t_department.did
UNION
#查询所有部门信息,以及该部门的所有员工,包括那些没有员工的部门
#结果是B
SELECT *
FROM t_employee RIGHT JOIN t_department
ON t_employee.did = t_department.did;
#查询员工信息,只查询没有分配部门的员工
#结果是A-A∩B
SELECT *
FROM t_employee LEFT JOIN t_department
ON t_employee.did = t_department.did #on后面只写关联条件
WHERE t_employee.did IS NULL #关联后的筛选条件放到where中
UNION
#查询部门信息,只查询没有员工的部门
#结果是B-A∩B
SELECT *
FROM t_employee RIGHT JOIN t_department
ON t_employee.did = t_department.did #on后面只写关联条件
WHERE t_employee.did IS NULL;
14.4 联合查询字段列表问题
#查询字段的问题
#查询每一个员工及其所在部门的信息
#要求:显示员工的编号,姓名,部门编号,部门名称
SELECT eid,ename,did,dname
FROM t_employee INNER JOIN t_department
ON t_employee.did = t_department.did;
/*
错误代码: 1052
Column 'did' in field list is ambiguous(模糊不清的;引起歧义的)
*/
SELECT eid,ename,t_employee.did,dname
FROM t_employee INNER JOIN t_department
ON t_employee.did = t_department.did;
#查询每一个员工及其所在部门的信息
#要求,显示员工的编号,姓名,部门表的所有字段
SELECT eid,ename,t_department.*
FROM t_employee INNER JOIN t_department
ON t_employee.did = t_department.did;
14.5 自链接
/*
自连接:
自己和自己关联查询,即一张表当成两张表使用。
通过给表取别名的方式,把一张表变为两张表
*/
#查询每一个员工的编号和姓名以及他的领导编号和姓名
SELECT emp.eid,emp.ename,mgr.eid,mgr.ename
FROM t_employee AS emp INNER JOIN t_employee AS mgr #表的别名不能加"",as可以省略
ON emp.mid = mgr.eid;
十五、select的7大子句
七大子句顺序,必须按照(1)-(7)的顺序编写子句。
(1)from:从哪些表中筛选
SELECT 1; #没有任何子句
SELECT 9/2; #没有任何子句
#1、from子句
SELECT *
FROM t_employee; #表示从某个表中筛选数据
(2)on:关联多表查询时,去除笛卡尔积
#2、on子句
/*
(1)on必须配合join使用
(2)on后面只写关联条件
所谓关联条件是两个表的关联字段的关系
(3)有n张表关联,就有n-1个关联条件
两张表关联,就有1个关联条件
三张表关联,就有2个关联条件
*/
SELECT *
FROM t_employee INNER JOIN t_department
ON t_employee.did = t_department.did; #1个关联条件
#查询员工的编号,姓名,职位编号,职位名称,部门编号,部门名称
#需要t_employee员工表,t_department部门表,t_job职位表
SELECT eid,ename,t_job.job_id,t_job.job_name, `t_department`.`did`,`t_department`.`dname`
FROM t_employee INNER JOIN t_department INNER JOIN t_job
ON t_employee.did = t_department.did AND t_employee.job_id = t_job.job_id;
(3)where:从表中筛选的条件
#3、where子句,在查询结果中筛选
#查询女员工的信息,以及女员工的部门信息
SELECT *
FROM t_employee INNER JOIN t_department
ON t_employee.did = t_department.did
WHERE gender = '女';
(4)group by:分组依据
#4、group by分组
#查询所有员工的平均薪资
SELECT AVG(salary) FROM t_employee;
#查询每一个部门的平均薪资
SELECT did,ROUND(AVG(salary),2 )
FROM t_employee
GROUP BY did;
#查询每一个部门的平均薪资,显示部门编号,部门的名称,该部门的平均薪资
SELECT t_department.did,dname,ROUND(AVG(salary),2 )
FROM t_department LEFT JOIN t_employee
ON t_department.did = t_employee.did
GROUP BY t_department.did;
#查询每一个部门的平均薪资,显示部门编号,部门的名称,该部门的平均薪资
#要求,如果没有员工的部门,平均薪资不显示null,显示0
SELECT t_department.did,dname,IFNULL(ROUND(AVG(salary),2),0)
FROM t_department LEFT JOIN t_employee
ON t_department.did = t_employee.did
GROUP BY t_department.did;
#查询每一个部门的女员工的平均薪资,显示部门编号,部门的名称,该部门的平均薪资
#要求,如果没有员工的部门,平均薪资不显示null,显示0
SELECT t_department.did,dname,IFNULL(ROUND(AVG(salary),2),0)
FROM t_department LEFT JOIN t_employee
ON t_department.did = t_employee.did
WHERE gender = '女'
GROUP BY t_department.did;
(5)having:在统计结果中再次筛选(with rollup)
#5、having
/*
having子句也写条件
where的条件是针对原表中的记录的筛选。where后面不能出现分组函数。
having子句是对统计结果(分组函数计算后)的筛选。having可以加分组函数。
*/
#查询每一个部门的女员工的平均薪资,显示部门编号,部门的名称,该部门的平均薪资
#要求,如果没有员工的部门,平均薪资不显示null,显示0
#最后只显示平均薪资高于12000的部门信息
SELECT t_department.did,dname,IFNULL(ROUND(AVG(salary),2),0)
FROM t_department LEFT JOIN t_employee
ON t_department.did = t_employee.did
WHERE gender = '女'
GROUP BY t_department.did
HAVING IFNULL(ROUND(AVG(salary),2),0) >12000;
#查询每一个部门的男和女员工的人数
SELECT did,gender,COUNT(*)
FROM t_employee
GROUP BY did,gender;
#查询每一个部门的男和女员工的人数,显示部门编号,部门的名称,性别,人数
SELECT t_department.did,dname,gender,COUNT(eid)
FROM t_employee RIGHT JOIN t_department
ON t_employee.did = t_department.did
GROUP BY t_department.did,gender;
#查询每一个部门薪资超过10000的男和女员工的人数,显示部门编号,部门的名称,性别,人数
#只显示人数低于3人
SELECT t_department.did,dname,gender,COUNT(eid)
FROM t_employee RIGHT JOIN t_department
ON t_employee.did = t_department.did
WHERE salary > 10000
GROUP BY t_department.did,gender
HAVING COUNT(eid) < 3;
(6)order by:排序
#6、排序 order by
/*
升序和降序,默认是升序
asc代表升序
desc 代表降序
*/
#查询员工信息,按照薪资从高到低
SELECT * FROM t_employee
ORDER BY salary DESC;
#查询每一个部门薪资超过10000的男和女员工的人数,显示部门编号,部门的名称,性别,人数
#只显示人数低于3人,按照人数升序排列
SELECT t_department.did,dname,gender,COUNT(eid)
FROM t_employee RIGHT JOIN t_department
ON t_employee.did = t_department.did
WHERE salary > 10000
GROUP BY t_department.did,gender
HAVING COUNT(eid) < 3
ORDER BY COUNT(eid);
(7)limit:分页
#7、分页limit
/*
limit m,n
m:表示起始的记录下标,第一条从0开始
m = (第几页 - 1) * n
n:每页最多显示的记录数
*/
#查询员工信息,每页显示5条,显示第1页
SELECT * FROM t_employee LIMIT 0,5;
#查询员工信息,每页显示5条,显示第3页
SELECT * FROM t_employee LIMIT 10,5;
/*
第1页,0,1,2,3,4 下标
第2页,5,6,7,8,9
第3页,10,11,12,13,14
m = (第几页 - 1) * n
第1页,m = (1-1)*5 = 0起始下标
第2页,m = (2-1)*5 = 5起始下标
第3页,m = (3-1)*5 = 10起始下标
*/
#查询每一个部门薪资超过10000的男和女员工的人数,显示部门编号,部门的名称,性别,人数
#只显示人数低于3人,按照人数升序排列,每页显示2条,显示第2页
SELECT t_department.did,dname,gender,COUNT(eid)
FROM t_employee RIGHT JOIN t_department
ON t_employee.did = t_department.did
WHERE salary > 10000
GROUP BY t_department.did,gender
HAVING COUNT(eid) < 3
ORDER BY COUNT(eid)
LIMIT 2, 2;
十六、子查询
子查询:
嵌套在其他的sql中的select语句叫做子查询。
形式:
(1)where型,即select语句嵌套在where条件中
子查询是作为where条件的一部分,子查询要用()引起来
①子查询是单值结果,那么可以对其使用(=,>等比较运算符)
②子查询是多值结果,那么可对其使用(【not】in(子查询结果),或 >all(子查询结果),或>=all(子查询结果),<all(子查询结果),<=all(子查询结果),或 >any(子查询结果),或>=any(子查询结果),<any(子查询结果),<=any(子查询结果))
where型的子查询,无论是单值还是多值,最终结果只有一列,
即要么是一列一行(即一个单元格的单值),
要么是一列多行(即一列有多个单元格)。
(2)from型,即select查询语句嵌套在from后面,
from型的子查询,结果是多列。
子查询是作为from的一部分,子查询要用()引起来,并且要给这个子查询去别名,
把它当成一张“临时的虚拟的表”来使用。
(3)其他类型
exists型
嵌套在update、delete语句中等
#(1)where型,即select语句嵌套在where条件中
#查询所有员工中,薪资最高的员工信息
#条件:薪资最高 where salary = (最高薪资)
#子查询:查询全公司的最高薪资
SELECT MAX(salary) FROM t_employee;
#完整的查询
SELECT *
FROM t_employee
WHERE salary = (SELECT MAX(salary) FROM t_employee);
#查询和孙红雷同一个部门的员工
#条件:did = (孙红雷的部门编号)
#子查询:查询孙红雷的部门编号
SELECT did FROM t_employee WHERE ename = '孙红雷';
#完整的查询
SELECT *
FROM t_employee
WHERE did = (SELECT did FROM t_employee WHERE ename = '孙红雷');
#查询比孙红雷的薪资高的员工
#子查询:查询孙红雷的薪资
SELECT salary FROM t_employee WHERE ename = '孙红雷';
#完整的查询
SELECT *
FROM t_employee
WHERE salary > (SELECT salary FROM t_employee WHERE ename = '孙红雷');
#查询和孙红雷、范冰冰、贾乃亮这三个人中有相同job_id的其他员工
#子查询:查询他们三个人的job_id
SELECT job_id FROM t_employee WHERE ename IN('孙红雷','范冰冰','贾乃亮');
#去重
SELECT DISTINCT job_id FROM t_employee WHERE ename IN('孙红雷','范冰冰','贾乃亮');
#完整查询
SELECT *
FROM t_employee
WHERE job_id IN (SELECT DISTINCT job_id FROM t_employee WHERE ename IN('孙红雷','范冰冰','贾乃亮'));
#查询比孙红雷、范冰冰、贾乃亮三个人的薪资都高员工
#子查询:查询孙红雷、范冰冰、贾乃亮三个人的薪资
SELECT salary FROM t_employee WHERE ename IN('孙红雷','范冰冰','贾乃亮');
#完整的查询
SELECT *
FROM t_employee
WHERE salary >ALL(SELECT salary FROM t_employee WHERE ename IN('孙红雷','范冰冰','贾乃亮'));
#(2)from型
#查询每个部门的编号,名称,平均工资
#子查询:查询每个部门的编号和平均薪资,因为这两个数据在t_employee表中都有
SELECT did,AVG(salary) FROM t_employee GROUP BY did;
#完整的查询
#把上面的子查询的结果看成一张表
SELECT t_department.did AS "部门编号", dname AS "部门名称", ROUND(IFNULL(avg_salary,0),2) AS "平均薪资"
FROM t_department LEFT JOIN (SELECT did,AVG(salary) AS avg_salary FROM t_employee GROUP BY did) AS t_avg_salary
ON t_department.did = t_avg_salary.did
ORDER BY t_department.did;
#(3)其他类型
#exists型
#查询那些有员工的部门,使用exist关键字
SELECT did,dname
FROM t_department
WHERE EXISTS (SELECT did FROM t_employee WHERE t_department.did = t_employee.did);
#修改其他员工的薪资,把他们的薪资修改为 和孙红雷一样的薪资
#子查询:查询孙红雷的薪资
SELECT salary FROM t_employee WHERE ename = '孙红雷';
#修改语句
#UPDATE t_employee SET salary = (SELECT salary FROM t_employee WHERE ename = '孙红雷');
#错误 You can't specify target table 't_employee' for update in FROM clause
UPDATE t_employee
SET salary = (SELECT temp.salary FROM (SELECT salary FROM t_employee WHERE ename = '孙红雷') AS temp);
#删除和'孙红雷'同一个部分的员工
#子查询:查询孙红雷的部门编号
SELECT did FROM t_employee WHERE ename = '孙红雷';
#删除
#DELETE FROM t_employee WHERE did = (SELECT did FROM t_employee WHERE ename = '孙红雷');
#错误 You can't specify target table 't_employee' for update in FROM clause
DELETE FROM t_employee
WHERE did = (SELECT temp.did FROM (SELECT did FROM t_employee WHERE ename = '孙红雷') AS temp);
/*子查询嵌套在update,detele等修改表数据的语句中,
需要把子查询的结果用一个临时表来表示,
这样做的目的是为了与原来的表脱离关系。
*/
十七、事务
17.1 事务的特点
1、事务处理(事务操作):保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),那么这些修改就永久地保存下来;要么数据库管理系统将放弃所作的所有修改,整个事务回滚(rollback)到最初状态。
2、事务的ACID属性:
(1)原子性(Automicity) 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
(2)一致性(Consistency) 事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
(3)隔离性(Isolation) 事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
(4)持久性(Durability) 持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响
17.2 事务的开启、提交、回滚
MySQL默认情况下是自动提交事务。 每一条语句都是一个独立的事务,一旦成功就提交了。一条语句失败,单独一条语句不生效,其他语句是生效的。
17.2.1 手动提交模式
MySQL可以开始手动提交事务模式。
set autocommit = false; 或 set autocommit = 0;
上面语句执行之后,它之后的所有sql,都需要手动提交才能生效。
SET autocommit = FALSE;#设置当前连接为手动提交模式
UPDATE t_employee SET salary = 15000
WHERE ename = '孙红雷';
COMMIT;#提交
SET autocommit = FALSE;#设置当前连接为手动提交模式
UPDATE t_employee SET salary = 15000
WHERE ename = '孙红雷';
#后面没有提交,直接关了连接,那么这句修改没有生效
17.2.2 自动提交模式下开启事务
/*
也可以在自动提交模式下,开启一个事务。
(1)start transaction;
....
(3)commit; 或 rollback;
在(1)和(3)之间的语句是属于手动提交模式,其他的仍然是自动提交模式。
*/
START TRANSACTION; #开始事务
UPDATE t_employee SET salary = 0
WHERE ename = '李冰冰';
#下面没有写commit;那么上面这句update语句没有正式生效。
commit;#提交
START TRANSACTION;
DELETE FROM t_employee;
ROLLBACK; #回滚
17.2.3 DDL语句不支持事务
#说明:DDL不支持事务
#DDL:create,drop,alter等创建库、创建表、删除库、删除表、修改库、修改表结构等这些语句不支持事务。
#换句话只对insert,update,delete语句支持事务。
TRUNCATE 表名称; 清空整个表的数据,不支持事务。 把表drop掉,新建一张表。
START TRANSACTION;
TRUNCATE t_employee;
ROLLBACK; #回滚 无效
17.3 事务的隔离级别
/*
mysql支持四个隔离级别:
read-uncommitted:会出现脏读、不可重复读、幻读
read-committed:可以避免脏读,会出现不可重复读、幻读
repeatable-read:可以避免脏读、不可重复读、幻读。但是两个事务不能操作(写update,delete)同一个行。
serializable:可以避免脏读、不可重复读、幻读。但是两个事务不能操作(写update,delete)同一个表。
修改隔离级别:
set tx_isolation='隔离级别';
查看隔离级别:
select @@tx_isolation;
*/
数据库事务的隔离性:数据库系统必须具有隔离并发运行各个事务的能力, 使它们不会相互影响, 避免各种并发问题。一个事务与其他事务隔离的程度称为隔离级别。数据库规定了多种事务隔离级别, 不同隔离级别对应不同的干扰程度, 隔离级别越高, 数据一致性就越好, 但并发性越弱。
数据库提供的 4 种事务隔离级别:
Oracle 支持的 2 种事务隔离级别:READ-COMMITED, SERIALIZABLE。 Oracle 默认的事务隔离级别为: READ COMMITED 。
Mysql 支持 4 种事务隔离级别。 Mysql 默认的事务隔离级别为: REPEATABLE-READ。在mysql中REPEATABLE READ的隔离级别也可以避免幻读了。
十八、用户管理
用户管理的目标
1、登录验证:主机IP地址+用户名+密码三重验证
mysql5.7之前mysql系统库的user表,密码字段名是password
mysql5.7版本mysql系统库的user表,密码字段名是authentication_string
mysql8.0版本mysql系统库的user表,密码字段名是authentication_string,另外用户管理还有角色概念,mysql系统库中有default_roles表。
2、权限管理
-
全局权限
-
数据库权限
-
数据表权限
-
字段权限
对用户的操作进行逐级权限验证,如果上一级有这个权限,下一级就不用验证了。
十九、补充
忘记root用户的密码
1:通过任务管理器结束mysqld(服务进程),或者停止mysql的服务
2:通过命令行+特殊参数开启mysqld
mysql5.5版 : mysqld --skip-grant-tables
mysql5.7版 :mysqld --defaults-file="D:\ProgramFiles\MySQL\MySQLServer 5.7_Data\my.ini" --skip-grant-tables
3:此时,mysqld服务进程已经打开,并且,不需要权限检查.
4: 另启动一个客户端进行登录
此时使用mysql无密码登陆服务器.
mysql -h主机IP地址 -P端口号 -u用户名
5: 修改权限表
(1) use mysql;
(2)mysql5.5版
update user set Password = password('新密码') where User = 'root';
update user set Password = password('123456') where User = 'root';
mysql5.7版
update user set authentication_string=password('新密码') where user='root' and Host='localhost';
update user set authentication_string=password('123456') where user='root' and Host='localhost';
(3)刷新权限 flush privileges;
6:通过任务管理器,关掉mysqld服务进程.
7:再次通过服务管理,打mysql服务。
8:即可用修改后的新密码登陆.