环境搭建5.7

1
2
3
4
docker run --name mysql -v ~/docker/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d -p 13306:3306 mysql:5.7

docker exec -it mysql bash
mysql -uroot -p
添加用户与赋权

创建用户

1
2
3
4
CREATE USER 'username'@'host' IDENTIFIED BY 'password';
--username – 你将创建的用户名说明:
--host – 指定该用户在哪个主机上可以登陆,如果是本地用户可用localhost, 如 果想让该用户可以从任意远程主机登陆,可以使用通配符%
--password – 该用户的登陆密码,密码可以为空,如果为空则该用户可以不需要密码登 陆服务

授权

1
2
3
4
GRANT privileges ON databasename.tablename TO 'username'@'host';
--privileges – 用户的操作权限,如SELECT , INSERT , UPDATE 等(详细列表见该文最后面).如果要授予所有的权限则使用ALL说明:
--databasename – 数据库名
--tablename-表名,如果要授予该用户对所有数据库和表的相应操作权限则可用* 表示, 如*.*

设置与更改用户密码

1
2
3
SET PASSWORD FOR 'username'@'host' = PASSWORD('newpassword');
--如果是当前登陆用户用
SET PASSWORD = PASSWORD("newpassword");

撤销用户权限

1
REVOKE privilege ON databasename.tablename FROM 'username'@'host';

删除用户

1
DROP USER ‘username’@'host’;

权限刷新

1
flush privileges;

example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 进⼊mysql
mysql> use mysql;
mysql> update user set authentication_string = password('123456') where user =
‘root’; #修改root密码
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root'
WITH GRANT OPTION; #添加权限
# 添加用户
create user test identified by 'test';
create database testdb;
grant all privileges on testdb.* to test@'%' identified by 'test';
flush privileges;
select user,host from mysql.user;
show grants for test;
show variables like 'validate_password%';
权限说明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
ALTER : Allows use of ALTER TABLE. 
ALTER ROUTINE : Alters or drops stored routines.
CREATE : Allows use of CREATE TABLE.
CREATE ROUTINE : Creates stored routines.
CREATE TEMPORARY TABLE : Allows use of CREATE TEMPORARY TABLE.
CREATE USER : Allows use of CREATE USER, DROP USER, RENAME USER, and REVOKE ALL PRIVILEGES.
CREATE VIEW : Allows use of CREATE VIEW.
DELETE : Allows use of DELETE.
DROP : Allows use of DROP TABLE.
EXECUTE : Allows the user to run stored routines.
FILE : Allows use of SELECT… INTO OUTFILE and LOAD DATA INFILE.
INDEX : Allows use of CREATE INDEX and DROP INDEX.
INSERT : Allows use of INSERT.
LOCK TABLES : Allows use of LOCK TABLES on tables for which the user also has SELECT privileges.
PROCESS : Allows use of SHOW FULL PROCESSLIST.
RELOAD : Allows use of FLUSH.
REPLICATION : Allows the user to ask where slave or master
CLIENT : servers are.
REPLICATION SLAVE : Needed for replication slaves.
SELECT : Allows use of SELECT.
SHOW DATABASES : Allows use of SHOW DATABASES.
SHOW VIEW : Allows use of SHOW CREATE VIEW.
SHUTDOWN : Allows use of mysqladmin shutdown.
SUPER : Allows use of CHANGE MASTER, KILL, PURGE MASTER LOGS, and SET GLOBAL SQL statements. Allows mysqladmin debug command. Allows one extra connection to be made if maximum connections are reached.
UPDATE : Allows use of UPDATE.
USAGE : Allows connection without any specific privileges.

8.0以上

随机密码

5.7以后安装mysql以后 系统会自动生成随机密码,需要使用随机密码 登陆 ,登陆成功后再修改MySQL的密码,随机密码在 MySQL安装路径下 data 文件夹中的SYZ.err中

修改密码

在MySQL 8.04前

1
SET PASSWORD=PASSWORD('[新密码]')

MySQL8.0.4后,这样默认是不行的。因为之前,MySQL的密码认证插件是“mysql_native_password”,而现在使用的是“caching_sha2_password”。

可以使用以下的方法修改root密码,新密码即要修改的密码

1
2
3
use mysql;
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '新密码';
FLUSH PRIVILEGES;

另一种修改密码的方式,新密码即要修改的密码,回车之后会要求输入原始密码

1
mysqladmin -u root -p password 新密码

类型

  1. 数值数据类型
    整数类型: TINYINT、SMALLINT、MEDIUMINT、INT、
    BIGINT
    浮点数类型:FLOAT、DOUBLE
    定点⼩数: DECIMAL
  2. ⽇期/时间类型
    YEAR、TIME、DATE、DATETIME、TIMESTAMP
  3. 字符串类型,其中字符串又可以分为⽂本字符串和⼆进制字符串
    ⽂本字符串:
    CHAR、VARCHAR、TEXT、ENUM、SET等 
    ⼆进制字符串
    BIT、BINARY、VARBINARY、BLOB

DDl

定义数据库对象:库、表、列列(Create,Drop,Alter,Show,Rename)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CREATE TABLE `users` (
`empno` int(10) NOT NULL,
`name` varchar(50) NOT NULL,
`birth` date DEFAULT NULL,
`sex` char(1) DEFAULT NULL,
`salary` decimal(8,2) DEFAULT NULL,
`regtime` datetime DEFAULT
CURRENT_TIMESTAMP,
PRIMARY KEY (`empno`)
) ENGINE=InnoDB DEFAULT
CHARSET=utf8;
# 修改表字段类型
ALTER TABLE users MODIFY age date ;
# 修改字段名和类型
ALTER TABLE users change age birthday date ;
SHOW TABLES;
# 重命名表
RENAME TABLE users TO pay_users;
# 删除表
DROP TABLE IF EXISTS users;
# 删除所有信息
TRUNCATE users;

DML

数据操作,增、删、改、查数据库记录(insert,delete,update)

1
2
3
4
5
6
# 插⼊单条数据
INSERT INTO tbl_name (col1,col2) VALUES (value1,value2);
# 删除数据
DELETE FROM tbl_name;
# 更新数据
update users1 set birth ='1989-01-31' where name=‘fang'

简单查询

1.选择所有数据
2.选择特定⾏
3.选择特定列
4.排序⾏
5.模糊查询
6.⽇期函数

1
2
3
4
5
6
7
8
9
10
11
1.精确查询:= <>
2.别名:as
3.限制⾏:limit m,n
4.⽐较运算符:>,>=,<,<=
5.逻辑运算符:and 两条件同时满⾜,or⼀个条件满⾜就⾏ and优先级⾼于or
6.去重 distinct
7.区间运算
8.排序 order by desc降序,asc 升序
9.模糊查询:like % _ notlike
10.集合运算 in , not in
11.⾮空运算 is null,is not null
聚合函数

count,sum,avg,max,min

分组筛选
1
2
3
4
5
SELECT <列列名>
FROM <表名>
[WHERE <查询表达式>]
[GROUP BY <分组列列名>]
[HAVING <分组后的查询表达式>]

WHERE⼦子句句从数据源中去掉不不符合其搜索条件的数据
GROUP BY⼦子句句搜集数据⾏行行到各个组中,统计函数为各个组计算统计值
HAVING⼦子句句去掉不不符合其组搜索条件的各组数据⾏

多表联接

1
2
3
4
5
6
7
8
9
10
11
12
13
# WHERE(等值连接)
select 列名 from 表A a ,表B b where a.key=b.key
# 内联接(INNER JOIN)
select 列列名 from 表A a inner join 表B b on a.key=b.key
# 外联接(OUTER JOIN)
# 左外联接:
select 列名 from 表A a left join 表B b on a.key=b.key
# 右外联接:
select 列名 from 表A a right join 表B b on a.key=b.key
# CROSS JOIN(笛卡尔积):
SELECT t1.id, t2.id FROM t1 CROSS JOIN t2;
# Union :
SELECT * FROM t1 union select * from t2;

备份恢复

1
2
3
4
5
6
7
8
mysqldump -help
# 备份:
mysqldump -u ⽤户名 -p --databases db > 备份⽂件名.sql
# 恢复:
通过mysqldump备份的⽂件,如果⽤了--all-databases或--databases选项,则在备份⽂件中包含 CREATE DATABASE和 USE语句,不需要指定⼀个数据库名去恢复备份⽂件。
shell> mysql –u ⽤户名 –p < 备份⽂件.sql
mysql> source备份⽂件.sql;
如果通过mysqldump备份的是单个数据库,且没有使⽤--databases选项,则备份⽂件中不包含 CREATE DATABASE和 USE语句,那么在恢复的时候必须先创建数据库。

存储过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 删除存储过程,如果这个名字的已存在
DROP PROCEDURE if exists insert_data_pro;
# 由于语句较多,使⽤这个告诉mysql,看看$$就表⽰语句结束了。
DELIMITER $$
# 建⽴存储过程名字叫 insert_data_pro
CREATE
PROCEDURE insert_data_pro()
BEGIN # 开始
DECLARE i INT; #定义 i
SET i=0; # 设置初始值为0
WHILE i>=0 && i<= 10000 DO # 循环 插⼊10000条数据,可以变化。
INSERT INTO
big_data(name1,age,email)values(concat(‘bq’,i),rand()*50,concat('bq',i,'@qq.com'));
# 写的sql,concat是将多个str连在⼀起。
SET i=i + 1;
END WHILE; #结束循环
END$$ #存储过程结束
DELIMITER ; #恢复设置
# 下⾯是调⽤存储过程
call insert_data_pro();

索引,慢查询

1
2
3
CREATE INDEX index_name ON big_data(name);
explain + 查询SQL - ⽤于显⽰SQL执⾏信息参数
# MySQL Explain详解 https://www.cnblogs.com/tufujie/p/9413852.html

存储引擎

1
2
3
4
5
6
7
8
9
10
show ENGINES;
# InnoDB:MySQL 5.7中的默认存储引擎。 InnoDB是⼀种适⽤于MySQL的事务安全(ACID兼容)存储引擎,具有提交,回滚和崩溃恢复功能,可保护⽤户数据。 InnoDB⾏级锁定(没有升级到更粗略的粒度锁)和Oracle风格的⼀致⾮锁定读取增加了多⽤户并发性和性能。InnoDB将⽤户数据存储在聚簇索引中,以减少基于主键的常见查询的I / O. 为了保持数据完整性, InnoDB还⽀持FOREIGN KEY参照完整性约束。
# MyISAM:这些表占⽤空间⼩。 表级锁定 限制了读/写⼯作负载的性能,因此它通常⽤于Web和数据仓库配置中的只读或⼤部分读取⼯作负载。
# Memory:将所有数据存储在RAM中,以便在需要快速查找⾮关键数据的环境中快速访问。这台发动机以前被称为HEAP发动机。它的⽤例正在减少; InnoDB其缓冲池存储区提供了⼀种通⽤且持久的⽅式来将⼤部分或全部数据保存在内存中,并 NDBCLUSTER为⼤型分布式数据集提供快速键值查找。
# CSV:它的表实际上是以逗号分隔值的⽂本⽂件。CSV表允许您以CSV格式导⼊或转储数据,以便与读取和写⼊相同格式的脚本和应⽤程序交换数据。由于CSV表未编制索引,因此通常InnoDB在正常操作期间将数据保留在表中,并且仅在导⼊或导出阶段使⽤CSV表。
# Archive:这些紧凑的⽆索引表⽤于存储和检索⼤量很少引⽤的历史,存档或安全审计信息。
# Blackhole:Blackhole存储引擎接受但不存储数据
# NDB(也称为 NDBCLUSTER) - 该集群数据库引擎特别适⽤于需要尽可能⾼的正常运⾏时间和可⽤性的应⽤程序
# Merge:适⽤于数据仓库等VLDB环境。
# Federated:提供链接单独的MySQL服务器以从许多物理服务器创建⼀个逻辑数据库的功能。⾮常适合分布式或数据集市环境。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
SELECT * 
FROM employees;

SELECT *
FROM employees
LIMIT 100;

SELECT *
FROM employees
WHERE last_name='Facello';

SELECT *
FROM employees
WHERE last_name<>'Facello' and emp_no<10020;

SELECT last_name 姓,first_name 名
FROM employees
WHERE hire_date>'2000-01-01';

SELECT *
FROM employees t
WHERE t.gender='M' AND t.last_name='Pettey';

SELECT *
FROM employees t
WHERE t.gender='M' AND t.last_name='Pettey' or t.gender='M' AND t.last_name='Hutton';

SELECT DISTINCT (last_name)
FROM employees t
ORDER BY t.last_name DESC;

SELECT last_name,hire_date
FROM employees
WHERE hire_date>='2000'
ORDER BY hire_date DESC ,last_name ASC;

SELECT last_name,hire_date
FROM employees
WHERE last_name NOT IN ('Facello','Hutton');

SELECT last_name,hire_date
FROM employees
WHERE last_name IN ('Facello','Hutton');

SELECT last_name,hire_date
FROM employees
WHERE hire_date is NULL;


SELECT EXTRACT(YEAR FROM CURDATE());

SELECT last_name,EXTRACT(YEAR FROM CURDATE()),EXTRACT(YEAR FROM hire_date)
FROM employees
WHERE EXTRACT(YEAR FROM CURDATE())-EXTRACT(YEAR FROM hire_date)>20;

SELECT last_name,hire_date
FROM employees
WHERE hire_date<DATE_SUB(CURDATE(),INTERVAL 20 YEAR);

SELECT DISTINCT(emp_no)
FROM salaries
WHERE salary BETWEEN 20000 AND 50000;

SELECT last_name 姓,first_name 名
FROM employees
WHERE first_name LIKE 'b%';

SELECT last_name 姓,first_name 名
FROM employees
WHERE first_name REGEXP '^b';

SELECT last_name 姓,first_name 名
FROM employees
WHERE first_name LIKE '%nd';

SELECT last_name 姓,first_name 名
FROM employees
WHERE first_name REGEXP 'nd$';

SELECT last_name 姓,first_name 名
FROM employees
WHERE first_name LIKE '%we%';

SELECT last_name 姓,first_name 名
FROM employees
WHERE first_name REGEXP 'we';

SELECT last_name 姓,first_name 名
FROM employees
WHERE first_name LIKE '_____';

SELECT last_name 姓,first_name 名
FROM employees
WHERE LENGTH(first_name)=5;

SELECT last_name 姓,first_name 名
FROM employees
WHERE first_name REGEXP '^.....$';


SELECT COUNT(salary)
FROM salaries
WHERE emp_no=10001;

SELECT SUM(salary)
FROM salaries
WHERE emp_no=10001;

SELECT MAX(salary)
FROM salaries
WHERE emp_no=10001;

SELECT MIN(salary)
FROM salaries
WHERE emp_no=10001;

SELECT ROUND(AVG(salary),2)
FROM salaries
WHERE emp_no=10001;

SELECT MAX(hire_date),gender
FROM employees
GROUP BY gender;

SELECT emp_no,AVG(salary) 平均薪资,MAX(salary) 最高薪资,MIN(salary) 最低薪资
FROM salaries
GROUP BY emp_no;

SELECT emp_no
FROM dept_emp
GROUP BY emp_no
HAVING COUNT(emp_no)>1;

SELECT * FROM employees
WHERE emp_no in(
SELECT emp_no FROM dept_emp
GROUP BY emp_no
HAVING COUNT(emp_no)>1);

SELECT * FROM employees
WHERE emp_no=(
SELECT emp_no FROM salaries
WHERE to_date='9999-01-01'
ORDER BY salary DESC LIMIT 1);

SELECT * FROM salaries
WHERE emp_no in(
SELECT emp_no FROM salaries
GROUP BY emp_no HAVING COUNT(emp_no)>=18);


SELECT a.emp_no,a.first_name,b.dept_no
FROM employees a,dept_emp b
WHERE a.emp_no=b.emp_no;

SELECT a.emp_no,a.first_name,b.dept_no,c.dept_name
FROM employees a,dept_emp b,departments c
WHERE a.emp_no=b.emp_no AND b.dept_no=c.dept_no;

SELECT a.emp_no,a.first_name
FROM employees a
INNER JOIN dept_emp b ON a.emp_no=b.emp_no
INNER JOIN departments c ON b.dept_no=c.dept_no
WHERE c.dept_name='Customer Service'

SELECT COUNT(a.emp_no)
FROM employees a
LEFT JOIN dept_emp b ON a.emp_no=b.emp_no
LEFT JOIN departments c ON b.dept_no=c.dept_no
WHERE c.dept_name='Customer Service'

SELECT COUNT(a.emp_no)
FROM employees a
RIGHT JOIN dept_emp b ON a.emp_no=b.emp_no
RIGHT JOIN departments c ON b.dept_no=c.dept_no
WHERE c.dept_name='Customer Service'

SELECT *
FROM departments UNION ALL
SELECT * FROM departments ORDER BY dept_no;

SELECT emp_no,MD5(salary) 薪水保密
FROM salaries WHERE to_date='9999-01-01'
ORDER BY salary ASC LIMIT 10;

SELECT emp_no,MD5(salary) 薪水保密
FROM salaries WHERE to_date='9999-01-01'
ORDER BY salary ASC LIMIT 10;

SELECT emp_no,MD5(salary) 薪水保密
FROM salaries WHERE to_date>CURDATE()
ORDER BY salary LIMIT 10;

UPDATE salaries SET salary=salary+3000
WHERE emp_no IN(
SELECT DISTINCT(emp_no) FROM dept_emp
WHERE EXTRACT(YEAR FROM from_date)=2002
AND to_date>CURDATE()
)


CREATE TABLE `testdata`(
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`payload` json DEFAULT NULL,
`response` json DEFAULT NULL,
PRIMARY KEY(`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
DESC testdata;

INSERT INTO testdata (payload,response)
VALUES('{"id":1,"name":"test"}','{"code":40000,"msg":"ok"}');

INSERT INTO testdata (payload,response)
VALUES(JSON_OBJECT("id",3,"name","dev1"),
JSON_ARRAY(1,3,5));

SELECT id,payload->'$.id',payload->'$.name',response->'$[0]',response->'$[2]' FROM testdata;

SELECT * FROM testdata WHERE payload->'$.name'='test';


存储过程

DROP TABLE IF EXISTS big_data;

CREATE TABLE big_data(
id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
name1 VARCHAR(16) DEFAULT NULL,
age INT(11),
email VARCHAR(64) DEFAULT NULL
)ENGINE=MYISAM DEFAULT CHARSET=utf8;

DROP PROCEDURE if exists insert_data_pro;

DELIMITER $$
CREATE
PROCEDURE insert_data_pro()
BEGIN
DECLARE i INT;
SET i=0;
WHILE i>=0 && i<= 10000 DO
INSERT INTO
big_data(name1,age,email)values(concat('test',i),rand()*50,concat('test',i,'@qq.com'));
SET i=i + 1;
END WHILE;
END$$
DELIMITER ;

call insert_data_pro();

ALTER TABLE big_data ENGINE=INNODB;