MySQL5.7基本使用

178 阅读10分钟

MySQL-5.7

1、DBMS描述

DBMS数据库管理软件:Oracle、MySQL、DB2、PostgreSQL...

RDBMS:Relational-关系性数据库。

是以行row和列column形式存在,结合在一起为表table,一组表为库DB。

表和表之间的数据记录有关系,实体和实体之间有关系模型。

E-R模型:entity-relationship。

Oracle、MySQL、SQL Server是行式存储。

列式数据库是将数据按列存储到数据库中:HBase。

1.1、SQL语句定义

SQL语言标准:SQL92SQL99

DDL-definition:数据定义语言,包括CREATE、DROP、ALTER...

DML-Manipulation:数据操作语言。INSERT、UPDATE、DELETE、SELECT...

DCL-Control:数据控制语言。GRANT、REVOKE、COMMIT、ROLLBACK、SAVEPOINT...


2、引号和着重号

 '' 单引号: 字符串、日期时间类型
 "" 双引号: 列名起别名
 ​
 `` 着重号: `order` MySQL中的关键字

3、大小写

Windows环境:大小写不敏感。ANSI码标准。

Linux环境:大小写敏感。

严格区分大小写: 数据库名、表名、表别名、变量名。

忽略大小写: 关键字、函数名、列名、列别名,字符串类型(Oracle是区分大小写)。


4、 建表

4.1、CREATE TABLE

 DROP TABLE IF EXISTS jjc_employee;-- 表存在-删除表
 -- CREATE TABLE IF NOT EXISTS jjc_employee | 表存在-跳过创建表
 CREATE TABLE jjc_employee (
 employee_id BIGINT ( 20 ) NOT NULL AUTO_INCREMENT COMMENT 'id',
 employee_code VARCHAR ( 30 ) NOT NULL COMMENT '工号',
 employee_name VARCHAR ( 30 ) NOT NULL COMMENT '姓名',
 birthdate datetime ( 0 ) NULL DEFAULT NULL COMMENT '生日',
 credential_type VARCHAR ( 10 ) NULL DEFAULT NULL COMMENT '证件类型',
 credential_number VARCHAR ( 30 ) NULL DEFAULT NULL COMMENT '证件号',
 gender CHAR ( 1 ) NULL DEFAULT '0' COMMENT '用户性别(0男 1女 2未知)',
 email_address VARCHAR ( 100 ) NULL DEFAULT NULL COMMENT '邮箱',
 mobile_phone CHAR ( 30 ) UNIQUE NULL DEFAULT NULL COMMENT '手机号',
 detail_address VARCHAR ( 100 ) NULL DEFAULT NULL COMMENT '住址',
 dept_id INT ( 11 ) NOT NULL COMMENT '部门id',
 hire_date datetime ( 0 ) NULL DEFAULT NULL COMMENT '入职日期',
 termination_date datetime ( 0 ) NULL DEFAULT NULL COMMENT '离职日期',
 attend_location VARCHAR ( 30 ) NULL DEFAULT NULL COMMENT '',
 manager_number VARCHAR ( 30 ) NULL DEFAULT NULL COMMENT '上级工号',
 card_type_code CHAR ( 1 ) NULL DEFAULT '1' COMMENT '打卡类型',
 card_type_meaning VARCHAR ( 10 ) NULL DEFAULT NULL COMMENT '打卡方式',
 is_dimission VARCHAR ( 10 ) NULL DEFAULT NULL COMMENT '',
 work_schedule VARCHAR ( 10 ) NULL DEFAULT NULL COMMENT '工作方式',
 probation_date datetime ( 0 ) NULL DEFAULT NULL COMMENT '离职日期',
 bank VARCHAR ( 100 ) NULL DEFAULT NULL COMMENT '开户行',
 bank_number VARCHAR ( 30 ) NULL DEFAULT NULL COMMENT '银行卡号',
 PRIMARY KEY ( employee_id ) USING BTREE
 ) ENGINE = INNODB AUTO_INCREMENT = 1000000000 COMMENT = '用户信息表' ROW_FORMAT = Dynamic;
 ​
 -- 根据原有的表结构,创建表,并导入数据
 CREATE TABLE employee2
 AS
 SELECT employee_id emp_id, last_name lname, salary -- 别名将为新表的字段名
 FROM employees
 WHERE 1=2; -- 不导入数据

1. 主键自增重新赋值

 -- 第一个值库名,第二值表名
 SELECT auto_increment FROM information_schema.TABLES WHERE table_schema = "jjc" AND table_name = "jjc_employee";
 -- 修改自增的值从哪里开始,要注意字段长度,BIGINT 默认有符号19个值
 ALTER TABLE jjc_employee auto_increment = 1000000000000000000;
 -- 查看表结构
 DESC jjc_employee;

2. 表信息

 -- 查看表信息
 SHOW CREATE TABLE 表名;
 ​
 -- 查看表结构
 DESCRIBE 表名;

4.2、删除表

 -- 删除表
 DROP TABLE IF EXISTS employees_copy_re;
 ​
 -- 清空表数据
 TRUNCATE TABLE employees_copy_re; -- 不能ROLLBACK
 ​
 DELETE FROM employees_copy_re; -- 能ROLLBACK

4.3、修改表字段

 -- 表重命名
 RENAME TABLE employees_copy TO employee_copy_re;
 ​
 -- 添加字段默认在最后一位
 ALTER TABLE employees_copy ADD comm DECIMAL(10,2) 
 -- 第一位
 FIRST;
 ​
 ALTER TABLE employees_copy ADD email varchar(64)
 -- 在指定字段后面
 AFTER job;
 ​
 -- 修改长度 | 一般不改数据类型
 ALTER TABLE employees_copy MODIFY first_name varchar(50) DEFAULT '';
 ​
 -- 重命名字段
 ALTER TABLE employees_copy CHANGE salary mon_salary DECIMAL(10,2);
 ​
 -- 删除字段
 ALTER TABLE employees_copy DROP COLUMN mon_salary;

4.4、约束

约束关键字
primary key主键、非空且唯一。
not null非空 字段名 数据类型 not null
unique唯一 可以设置多字段组合唯一,在建表的最后 unique key(phone_number,id_card
check检查约束,5.7不支持,8.0支持。 gender char(2) check (sex in('男','女')), age int check(age>=0 and age<200)
default 默认值not null default '' 或 defalut 0,不想用null为值,会影响索引查询效率。
foreign key外键不建议使用,会影响数据库性能
 -- 添加唯一键
 ALTER TABLE city_details ADD CONSTRAINT uk_city_details_phone_number UNIQUE (phone_number);
 -- 删除约束:
 DROP INDEX uk_city_details_phone_number ON city_details;
 ​
 -- 查询所有键、索引:
 SHOW INDEX FROM city_details;

1. 唯一约束查询重复数据

 -- 添加唯一键
 ALTER TABLE city_details
 ADD CONSTRAINT uk_city_details_phone_number UNIQUE (phone_number);
 -- > 1062 - Duplicate entry '025-025' for key 'uk_city_details_phone_number'
 -- 说明该列有重复数据 025-025
 ​
 -- <> 就是 != | <=>为NULL而生
 -- 查询电话号码是否有重复:
 SELECT
     c1.id,
     c1.phone_number,
     c2.id,
     c2.phone_number 
 FROM
     city_details c1,
     city_details c2 
 WHERE
     c1.id <> c2.id 
     AND c1.phone_number = c2.phone_number

5、字段属性

字段描述
int(11)-2147483648-2147483647,0-4294967295。 这里11的意思:显示宽度,(- 负号 2147483648 )一共11位。 id int(5) 此时的5无意义,插入123就是123,123456也是123456。 但是 id int(5) zerofill 就表示用0填充,如插入123不足5位,为00123。
tinyint(4)1个字节,有符号-128-127,无符号UNSIGEED: 0-255。
bigint(20)8个字节,-9223372036854775808-9223372036854775807,0-18446744073709551615
decimal(m,d)大小取决m,d,m指精度(总长度包含小数点)d表示小数点的位数(大于bigint) decimal(5,2) :m最大65,d最大30(m省略,d默认时10;d省略,默认是0)
char()0~255字符,定长(不设定值时,插入2个字符,也会占4个字符), char(4) ,表示占4个字符,中英文只能放4个。
varchar()变长(不设定值时,插入2个字符,就2个字符), varhcar(255) :0~65535(utf-8(最大21844字符,65535/3)、utf8mb4(最大16383字符))
text0~2^16-1,不能有默认值,如果varchar不够用
lontext当varchar的长度超过5000,建议创建一个新表用主键来对应,数据用text类型。 最大长度4G。存储原文本内容
blob二进制字符串 blob的IO读取速度比longtext速度快(blob字段不存储原文本内容,无法对文本进行搜索功能)
date3个字节,1000-01-01 ~ 9999-12-03
datetime8个字节,1000-01-91 00:00:00 ~ 9999 register_date DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)
timestamp有时区需求使用 set time_zone = '+9:00' 东九区。 4个字节,1970-01-01 00:00:00 ~ 2038-01-19 03:14:07 UTC login_time timestamp not null default current_timestamp on update current_timestamp

6、索引

常见索引包含:主键索引、唯一索引、普通索引(单列、组合)。

6.1、命令操作

 -- 查询该查询sql语句的执行效率:
 EXPLAIN select * from pms_category where parent_cid = 1;
 ​
 -- 查询该表的所有的索引列。
 SHOW INDEX FROM pms_category;
 ​
 -- 添加普通索引:
 CREATE INDEX pms_category_parend_cid_index ON pms_category ( parent_cid );
 ​
 -- 联合索引用, 逗号隔开:
 CREATE INDEX t_name_index ON teacher ( t_name, t_age );
 ​
 -- 【索引无法修改,只能删除重新创建】。
 ​
 -- 删除索引:
 DROP INDEX pms_category_parend_cid_index ON pms_category;

6.2、索引优化

添加索引优化
group by + order by两个条件添加联合索引,把分组的条件放在最左边,满足最左匹配原则
update、delete的where条件字段可以添加索引或联合索引
distinct字段添加索引
区分度高的字段适合添加索引,如id,name 重复度大于10%区分度低的字段:gender只包含0、1、2。
多表join连接时,where条件 + 连接条件创建索引 小表驱动大表。 如:t_type t left join t_book b on t.card = b.card,由于左外连接t_type的全表数据都需要的,我们使用t_book是被驱动表。 建议两个都可以加索引。多字段都要创建索引的情况下,联合索引优于单列索引
单张表索引不要超过6个。
数据量小1000行的表不要使用索引,优化器直接不走索引。
不建议使用无序列的值索引,如身份证、uuid。
开启慢查询日志:set global slow_query_log = on; 设置long_query_time的阈值:show variables like '%long_query_time%'; 默认10s。 set long_query_time =1;

6.3、索引失效

场景描述演示
where:or使用UNION ALL
where:NOT != <> !< !> /NOT IN/NOT LIKE但不是绝对,看优化器选择
where:使用了内置函数索引列login_time上使用了函数,会索引失效select * from user where DATE_ADD(login_time, INTERVAL 1 DAY) = 7;
where age+1
where字段属性隐式转换 (原来是字符查询时变成了字)user_id varchar(20)where user_id = 12;
where like '%' 开头可以使用'x%'
where 多条件,联合索引没有遵循最左匹配原则假设联合索引(k1,k2,k3), 相当于创建了(k1)、(k1,k2)、(k1,k2,k3), 这就是最左匹配。不会命中索引 select * from t where k2=2; select * from t where k3=3; select * from t where k2=k2 and k3=3; 只会命中k1 select * from t where k1=1 and k3=k3;
排序时`ASCDESC`混用

6.4、执行效率EXPLAIN

TYPE描述
ALL全表扫描
index索引全扫描
range索引范围扫描,常用语< <= >= between in等操作
ref非唯一索引扫描或唯一索引前缀扫描,返回单条记录,常出现在关联查询中
eq_ref类似ref,区别在于使用的是唯一索引,使用主键的关联查询
const主键或唯一索引
EXTRA描述
Using temporary使用了临时表保存中间结果,性能特别差,需要重点优化
Using index相应的 select 操作中使用了覆盖索引(Coveing Index),避免访问了表的数据行,效率不错 同时出现 using where,意味着无法直接通过索引查找来查询到符合条件的数据
Using filesort额外的一次传递,以找出如何按排序顺序检索行,通过根据联接类型浏览所有行并为所有匹配WHERE子句的行保存排序关键字和行的指针来完成排序。
Using index condition在存储引擎层进行数据过滤,而不是在服务层过滤,利用索引现有的数据减少回表的数据。

7、INSERT、UPDATE、DELETE

 -- 关闭自动提交
 SET autocommit = FALSE
 -- 根据查询表的数据进行插入 | 注意两个表字段的长度属性要匹配
 INSERT INTO employees_copy SELECT * FROM employees
 ​
 ROLLBACK;
 COMMIT;
 ​
 -- 插入多条数据
 INSERT INTO employees_copy ( last_name, email, job_id, hire_date )
 VALUES
     ( 'zhangsan', 'zhangsan@123.com', 'IT_PROG', now( ) ),
     ( 'lisi', 'lisi@qq.com', 'IT_PROG', now( ) )
     
 -- 修改
 UPDATE 表名 SET 列名 WHERE 条件;
 ​
 -- 删除
 DELETE FROM 表名 WHERE 条件;

7.1、UPDATE+JOIN配合关联表修改

 UPDATE `stud_personal_profile` spp
 JOIN `stud_personal_basic` spb ON spp.`ID` = spb.`profile_id` 
 SET spb.`birthday` = CONCAT(
     SUBSTR( spp.`id_card`, 7, 4 ),'-',
     SUBSTR( spp.`id_card`, 11, 2 ),'-',
     SUBSTR( spp.`id_card`, 13, 2 ) 
 ),
 spb.update_date = NOW( ),
 spb.update_id = 1 
 WHERE
     ( spb.`birthday` IS NULL OR spb.`birthday` = '' ) 
     AND LENGTH( spp.`id_card` ) = 18;

8、查询SELECT

完成的查询语句:SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ... LIMIT ...

聚合函数 max、min、count、sum、avg 不能在where条件中使用。

8.1、分组查询GROUP BY

当使用分组查询,SELECT查询只能包含分组条件和聚合函数。

 -- 查询部门下工资最低的 员工名字和工资
 SELECT
     e1.ename,
     e2.min_sal,
     e2.deptno 
 FROM
     emp e1
     INNER JOIN ( SELECT min( sal ) min_sal, deptno FROM emp GROUP BY deptno ) e2 ON e1.deptno = e2.deptno 
     AND e1.sal = e2.min_sal 
 ORDER BY
     e2.min_sal
     
 -- 查询每个部门工资大于平均工资的 员工
 SELECT
     e.* 
 FROM
     emp e
     INNER JOIN ( SELECT avg( sal ) avg_sal, deptno FROM emp GROUP BY deptno ) t1 ON e.sal > t1.avg_sal 
     AND e.DEPTNO = t1.DEPTNO

1. HAVING

group by + having。用于分组之后替代WHERE条件进行过滤,必须配合使用。

 -- 查询职位人数大于3的,职位
 SELECT job,count( job ) FROM emp GROUP BY JOB HAVING count( job ) > 3
 ​
 -- 查询10、20、30部门中最高工资大于10000的部门信息    
 SELECT department_id,MAX( e.salary ) FROM employees e
 WHERE e.department_id in (10,20,30)
 GROUP BY e.department_id HAVING MAX( e.salary ) > 10000;
 ​
 -- 查询部门中平均工资大于5000的 所有员工信息
 SELECT
     e.*,
     t.* 
 FROM
     employees e
     RIGHT JOIN (
 SELECT
     e.department_id,
     AVG( e.salary ) avg_salary 
 FROM
     employees e 
 GROUP BY
     e.department_id 
 HAVING
     AVG( e.salary ) > 5000 
     ) t ON e.department_id = t.department_id 
     AND e.salary >= t.avg_salary

8.2、分组统计GROUP_CONCAT

 -- separator '_' 表示以下滑线为分割符
 SELECT
     ssav.attr_id attr_id,
     ssav.attr_name attr_name,
     ssav.attr_value,
     group_concat( DISTINCT info.sku_id separator '_' ) sku_ids
 FROM
     pms_sku_info info
 LEFT JOIN pms_sku_sale_attr_value ssav ON
     ssav.sku_id = info.sku_id
 WHERE
     info.spu_id = 11
 GROUP BY
     ssav.attr_id,
     ssav.attr_name,
     ssav.attr_value;

image-20230409154500601.png


8.3、分页LIMIT

 -- 第一页: 0 从0开始该值为offset偏移量,20 每页数量
 -- 第二页:20,20
 SELECT * FROM jjc_employee
 LIMIT 0,20
 -- LIMIT pageSize*(pageNum-1) , pageSize

8.4、表连接JOIN ON

MySQL的SQL99语法不支持FULL JOIN 满外连接语法的,但是可以通过UNION ALL + LFET JOIN、RIGHT JOIN 拼接。

image-20230421174531813.png

8.5、交集UNION、UNION ALL

union all并集。

 -- 交集,可自动去重:
 SELECT ename, sal, job FROM emp WHERE sal > 2500
 UNION
 SELECT ename,sal,job FROM emp WHERE job = 'MANAGER';
 ​
 -- 并集:(推荐使用)
 SELECT ename,sal,job FROM emp WHERE sal > 2500
 UNION ALL 
 SELECT ename,sal,job FROM emp WHERE job = 'MANAGER';

8.6、多列子查询、ALL、ANY

 -- 查询和SMITH 相同部门、工作的员工,不包含SMITH自己
 SELECT
     * 
 FROM
     emp e1 
 WHERE
     ( e1.deptno, e1.job ) = ( SELECT e.deptno, e.job FROM emp e WHERE e.ename = 'SMITH' ) 
     AND e1.ename != 'SMITH';
     
 -- ALL 查询工资比30部门,所有员工都高的员工
 SELECT e.ename,e.sal,e.deptno FROM `emp` e
 WHERE e.sal > ALL ( SELECT sal FROM `emp` WHERE deptno = 30 );
 -- 方法2:
 SELECT e.ename,e.sal,e.deptno FROM `emp` e
 WHERE e.sal > ( SELECT MAX(sal) FROM `emp` WHERE deptno = 30 );
 ​
 -- ANY 查询工资比30部门,其中一个员工高的员工
 SELECT e.ename,e.sal,e.deptno FROM `emp` e
 WHERE e.sal > ANY ( SELECT sal FROM `emp` WHERE deptno = 30 );
 -- 方法2:
 SELECT e.ename,e.sal,e.deptno FROM `emp` e
 WHERE e.sal > ( SELECT min(sal) FROM `emp` WHERE deptno = 30 );

8.7、EXISTS

exists包含,not exists不包含。

 SELECT * FROM A WHERE EXISTS ( SELECT * FROM B WHERE B.id = A.id );

可代替子查询 in

 -- 查询入职日期大于1985年的
 SELECT * FROM emp 
 WHERE empno IN ( SELECT empno FROM emp WHERE HIREDATE > TO_DATE( '1985', 'yyyy' ) );
 ​
 SELECT * FROM emp t1 
 WHERE EXISTS ( SELECT empno FROM emp WHERE t1.HIREDATE > TO_DATE( '1985', 'yyyy' ) );

9、正则REGEXP

 -- ^s 以s开头 | r$ 以r结尾 | . 表示任何一个单字符 | [abc] 包含abc 
 -- 查询id包含非数字的行
 SELECT
     ( t.AgentID REGEXP '[^0-9.]' ),
     t.* 
 FROM
     Call_Info2 t 
 WHERE
     t.StartTime > '2022-02-22 02:59:36' 
     AND t.HandleFlag = 0 
     AND ( t.AgentID REGEXP '[^0-9.]' ) = 1 
     LIMIT 1000;

10、函数

10.1、字符串函数

 -- 字符串拼接
 concat(列名1,'is a',列名2)
 SELECT concat( '1996', '-', '04', '-', '14' ) birthday_date FROM DUAL;
 ​
 -- 字符串分割符
 SELECT CONCAT_WS('-','table','order','details') FROM DUAL
 ​
 substr(列名,1,4)-- 字符串截取:从第 1 位开始,到后 4 位(不包含)
 ​
 REPLACE(job,'MANAGER','经理')-- 字符串替换
 ​
 lcase(列名)、ucase(列名)-- 小写、大写
 ​
 trim(列名), ltrim(), rtrim()-- 去空格
 ​
 left(列名,2)--从左边取字符串,取到第2位:
 right(列名,2)
 ​
 length(列名)--字段长度

10.2、时间

 CURRENT_DATE()-- 2022-02-24
 CURRENT_TIME()-- 02:55:39
 CURRENT_TIMESTAMP()-- 2022-02-24 02:56:20
 ​
 now()
 YEAR()
 MONTH() 
 DAY()
 ​
 -- 查询十分钟内发布的信息
 SELECT * FROM mes WHERE DATE_ADD( send_mes, INTERVAL 10 MINUTE ) >= now();
 ​
 -- 同理date_sub也行
 SELECT * FROM mes WHERE DATE_SUB( now( ), INTERVAL 10 MINUTE ) <= send_mes; 
 ​
 interval 10 year -- 后面可以跟year、day、minute、second
 -- 类型可以是:date、datetime、timestamp
 ​
 -- 从今天算活到80岁,还有多少天
 SELECT date_add( '1996-4-14', INTERVAL 80 YEAR )FROM DUAL;
 -- 19773天
 SELECT datediff(date_add('1996-4-14', INTERVAL 80 YEAR), now())FROM DUAL;
 ​
 -- 查询员工入职满30年
 SELECT e.last_name,YEAR ( e.hire_date )
 FROM employees e 
 WHERE YEAR ( now( ) ) - YEAR ( e.hire_date ) >= 30
 ​
 -- 日期格式的隐式转化 | 只要字符串和日期格式一致就行
 SELECT *
 FROM employees e
 WHERE e.hire_date = '1999-02-07'
 ​
 -- 时间戳
 SELECT FROM_UNIXTIME( 1673112902, '%Y-%m-%d %H:%i:%s' ) FROM DUAL;
 ​
 -- 转uinx时间戳
 SELECT UNIX_TIMESTAMP( '2022-09-13 23:48:22' ) FROM DUAL;

10.3、去重distinct

SELECT只能跟一个字段。

select distinct e.sal from emp e;


11、流程控制

如果为空设置0值。

IFNULL(employees.commission_pct,0)

 -- if...else if...else
 SELECT
     e.last_name,
     e.salary,
 CASE
     WHEN e.salary >= 20000 THEN '牛逼' 
     WHEN e.salary >= 15000 THEN '腻害' 
     WHEN e.salary >= 10000 THEN '不错' 
     WHEN e.salary >= 5000 THEN '行吧' 
     ELSE '不行啊' 
     END "工资描述" 
 FROM
     employees e;
     
 -- switch case
 SELECT
     e.last_name,
     e.salary,
     e.department_id,
 CASE e.department_id 
     WHEN 10 THEN e.salary * 1.1 
     WHEN 20 THEN e.salary * 1.2 
     WHEN 30 THEN e.salary * 1.3 
     ELSE e.salary * 1.05 
     END "调薪" 
 FROM
     employees e;

12、死锁

死锁
innoDB1、两个以上的线程(事务),双方都在等待对方释放已持有的锁。 2、或者加锁顺序不一样导致循环等待锁释放。
支持行锁、表锁行锁:只针对当前操作进行加锁。 事务中行锁通过给索引上的索引项加锁实现。 SELECT ... FROM UPDATE 是表锁还是行锁,看WHERE条件是否命中索引。
MyISAM不会死锁。

报错:Deadlock found when trying to get lock ...

解决:查看正在被锁的事务的trx_id,然后杀死。

select * from INFORMATION_SCHEMA.INNODB_TRX;

kill trx_id;


13、库DB

 show databases;
 show create database 库名;
 ​
 -- 字符集:utf8(3个字节)、utf8mb4(英文占用1个字节,一般汉字占用3个字节,emoji表情占4个字节)、gbk
 show charset;
 -- 排序规则:utf8mb4_general_ci(不区分大小写);utf8mb4_bin(区分大小写,存拼音,日文)
 show collation;
 ​
 -- 创建数据库:create database if not exists 库名
 create database if not exists liuxx character set utf8mb4 collate utf8mb4_general_ci;
 ​
 -- 删除数据库:
 drop database if exists 库名
 ​
 -- 修改数据库:alter database 库名
 alter database liuxx character set utf8mb4 collate utf8mb4_general_ci;

14、系统 、用户权限

 -- 查询用户登录 user()
 select user() from dual;
 ​
 -- create uesr '用户名'@'允许登录的位置' identified by '密码';
 create user zhangsan@'10.0.0.%' identified by '123321';
 ​
 -- alter user '用户名'@'允许登录的位置' identified by '密码'
 alter user zhangsan@'%' identified by '123456';
 ​
 -- 刷新
 flush privileges;
 ​
 -- drop user  '用户名'@'允许登录的位置';
 drop user zhangsan@'%';
 ​
 -- 授权 (给超级用户权限:all *.* '用户名'@'%')
 grant all privileges on *.* to lisi@'%' identified by '111111' with grant option;
 ​
 grant 权限 on 库.表 to 用户 identified by 密码 with grant option;
 ​
 -- 一般的开发权限:
 grant select,update,delete,insert on *.* to wangwu@'10.0.0.%' identified by '123' with grant option;
 ​
 -- 回收权限:
 revoke delete on mydb.* from 'zhangsan'@'10.0.0.%';
 ​
 -- 查看用户权限:
 show grant for 'zhangsan'@'10.0.0.%';