1.安装 MySql
-
安装命令:
sduo apt install mysql-server
-
安装完成之后会自动启动 MySql 的服务, 可以使用命令
systemctl status mysql
查看服务的状态. 如果没有启动, 可以使用systemctl start mysql
启动服务 -
root 用户密码问题, linux 下安装完是有密码的, 使用命令
sudo cat /etc/mysql/debian.cnf
来查看默认用户名和密码. 使用命令mysql -u debian-sys-maint -p
来连接 MySql, 复制一下[mysql_upgrade]
里边的密码进行连接 -
修改 root 用户密码
1)直接使用 root 用户来连接
alter user 'root'@'%' identified with mysql_native_password by '3333';
有可能显示 error 1396(HY000) , 这时可以先将 user 表中的 root, localhost 改成 %
mysql
# 错误是由于root 用户默认是没有开放远程权限的
# localhost 表示这个用户只能在本地访问, 改成 % 后就可以在任何地方访问了
use mysql;
select user, host from user;
update user set host = '%' where user = 'root';
flush privileges;
这时我们可以直接使用 mysql -u root -p
, 然后输入修改后的密码, 进行连接 MySQL
2)修改密码策略
mysql
show variables like 'validate_password%';
# 根据显示表格里的变量名进行修改即可, mysql更新变量名形式可能会稍微变动
set global validate_password.policy=LOW;
set global validate_password.length = 4;
-
MySql 服务的监听地址
1)无法连接 MySql 服务器, 把服务器放开 3306 端口地址 或者在开发环境下关闭防火墙
2)配置文件的监听地址问题, 默认 MySQL 服务只监听本地 IP 地址, 外部是无法连接 MySQL 服务的, 把配置文件的
bind-address
和mysqlx-bind-addess
都修改为0.0.0.0
即可. 重启服务systemctl restart mysql
SQL 基础
DDL 数据定义语言: 定义数据库对象, 比如数据库表, 列 CREATE DROP ALTER TRUNCATE
DML 数据操作语言: 对数据库中的记录进行增删改 INSERT UPDATE DELETE CALL
DQL 数据查询语言: 查询数据库记录 SELECT
DCL 数据控制语言: COMMIT SAVEPOINT GRANT REVOKE
创建数据库
MySQL
数据大类型: 数值, 日期, 时间类型, 字符串类型, JSON 类型, 空间类型
mysql
SHOW DATABASES; # 查看当前已经存在的数据库
CREATE DATABASE game; # 创建game数据库
USE game; # 选择game数据库
CREATE TABLE player(
id INT,
name VARCHAR(100),
level INT,
exp INT,
gold DECIMAL(10, 2)
);
SHOW TABLES: # 查看当前数据库中的表
INSERT INTO player(id, name, level, exp, gold) VALUES(1, '张三', 1,1,1); #向 player 表中插入一条数据
SELECT * FROM player; # 查看表的所有列, * 可以表示 player 的所列
INSERT INTO player(id, name) VALUES(3, '王五');
ALTER TABLE player MODIFY COLUMN level INT DEFAULT 1; # 默认等级设为 1
INSERT INTO player(id, name) VALUES(4, '麻子'); # 不进行设置的列默认为null
UPDATE player SET level = 1 WHERE name = '王五';
UPDATE player SET level = 1, exp = 0, gold = 0; # 全部进行修改
DELETE FROM player where gold = 0;
DESC player; # 查看表的结构, DESC 是 description 的缩写
# 修改表结构
ALTER TABLE player MODIFY COLUMN name VARCHAR(200);
ALTER TABLE player RENAME COLUMN name to nick_name;
ALTER TABLE player ADD COLUMN last_login DATETIME; # 增加 last_login 列
ALTER TABLE player DROP COLUMN last_login; # 删除 last_login 列
DROP TABLE player; # 删除player表
数据导入导出
导出数据: mysqldump -u root -p game player > game.sql
, -u
指定用户名, -p
指定密码, game
数据库名, player
表名, > gmae.sql
指定要导入数据的文件名. 其中表名可以省略, 如果省略就会导出整个数据库的所有数据
导入数据: mysql -u root -p game < game.sql
, 把 game.sql
数据导入 game
常用语句
mysql
# where 限定条件
# 1.逻辑判断语句
# 逻辑运算符有 AND, OR 和 NOT, 优先级: NOT > AND > OR
SELECT * FROM player WHERE level = 1;
SELECT * FROM player WHERE level >= 1 AND level <= 5;
# 2.IN
SELECT * FROM player WHERE level IN(1, 3, 5); # 查找等级为1 或 3 或 5 的玩家
# 3.BETWEEN AND
SELECT * FROM player WHERE level BETWEEN 1 AND 10; # 查找等级 1 到 10 级的玩家
SELECT * FROM player WHERE level NOT BETWEEN 1 AND 10; # 查找除等级为 1 到 10 级以外的玩家
# 注意: NOT 可以加在任何一个条件语句前面
# 3.LIKE, 模糊查询, 通配符: % 匹配任意个字符, _(下划线) 匹配任意一个字符
SELECT * FROM player WHERE name LIKE '王%'; # 姓王
SELECT * FROM player WHERE name LIKE '%王%'; # 名字中包含王
SELECT * FROM player WHERE name LIKE '王_'; # 王某
SELECT * FROM player WHERE name LIKE '王__'; # 王某某
# 4.使用 REGEXP 来匹配(正则表达式)
# . 匹配任意一个字符, ^ 匹配开头, $ 匹配结尾, [acdg] 匹配a 或 c 或 d 或 g 其中一个字符
# [a-z] 任意一个小写字母, A|B 匹配 A 或 B
SELECT * FROM player WHERE name REGEXP '王'; # 名字中包含王
SELECT * FROM player WHERE name REGEXP '^王.$'; # 王某
SELECT * FROM player WHERE name REGEXP '^王..$'; # 王某某
SELECT * FROM player WHERE name REGEXP '[王张]'; # 名字中包含王或张
SELECT * FROM player WHERE name REGEXP '王|张'; # 名字中包含王或张
# 练习题
# 1) 查找邮件地址以 zhangsan 开头的玩家
SELECT * FROM player WHERE email LIKE 'zhangsan%';
SELECT * FROM player WHERE email REGEXP '^zhangsan';
# 2) 查找邮件地址以 a/b/c 开头的玩家
SELECT * FROM player WHERE email REGEXP '^[abc]';
SELECT * FROM player WHERE email REGEXP '^[a-c]';
# 3) 查找邮件地址以 net 结尾的玩家
SELECT * FROM player WHERE email LIKE '%net';
SELECT * FROM player WHERE email REGEXP 'net$';
# 5. 查找某个列的值为空(NULL)的数据
SELECT * FROM player WHERE email is null;
SELECT * FROM player WHERE email is NOT null; # 查找email不为空的数据
SELECT * FROM player WHERE email is null OR email = ''; # null 数据和空串不是一个概念
# ORDER BY 排序
SELECT * FROM player ORDER BY level; # 按等级升序排列
SELECT * FROM player ORDER BY level DESC; # 按等级降序排列, descrease
SELECT * FROM player ORDER BY 5 DESC; # 按等级降序排列, 第五列是 level
SELECT * FROM player ORDER BY level DESC, exp; # 按等级降序, 经验升序排列
# 也可以在exp后加ASC表示升序, 默认就是 ASC
# 聚合函数, 对某一列进行一些计算, 常用聚合函数: AVG() 返回集合的平均值, SUM() 求和
# COUNT() 返回集合中的项目数, MAX() 返回最大值, MIN() 返回最小值
SELECT COUNT(*) FROM player; # 玩家总人数
SELECT AVG(level) FROM player; # 所有玩家平均等级
SELECT SUM(gold) FROM player; # 所有玩家总金币
SELECT MAX(gold) FROM player;
SELECT MIN(gold) FROM player;
# GROUP BY, 对查询结果进行分组, 后边跟一个或多个列名, 表示按照这些列来分组
SELECT sex, COUNT(*) FROM player GROUP BY sex;
SELECT level, COUNT(level) FROM player GROUP BY level;
SELECT level, COUNT(level) FROM player GROUP BY level HAVING COUNT(level) > 4;
SELECT level, COUNT(level) FROM player GROUP BY level HAVING level > 80;
SELECT level, COUNT(level) FROM player GROUP BY level HAVING level > 80 ORDER BY COUNT(level) DESC;
SELECT level, COUNT(level) FROM player GROUP BY level HAVING level > 80 ORDER BY level DESC;
# 练习题
# 统计每个姓氏玩家的数量, 并将结果按降序显示, 只显示数量大于等于 5 的姓氏
SELECT SUBSTR(name, 1, 1), count(SUBSTR(name, 1, 1)) FROM player
GROUP BY SUBSTR(name, 1, 1) # 按SUSSTR(name, 1, 1) 的结果分组
HAVING COUNT(SUBSTR(name, 1, 1)) >= 5 # 只统计数量大于 5 的
ORDER BY COUNT(SUBSTR(name, 1, 1)) DESC # 降序排列
LIMIT 3; # 限制只显示3个数据, 也就是前3名.
# 关于LIMIT, 如果写成 3,3 , 就显示 4 到 6 名
# 第一个参数是偏移量,就是从第一个数据往后偏移多少个
# 第二个参数是行数,就是从偏移终点开始显示多少行
# DISTINCT, 去重
SELECT DISTINCT sex FROM player;
# UNION, 合并两个查询的结果, 取并集, 会自动去重
# UNION ALL, 不进行去重操作
SELECT * FROM player WHERE level BETWEEN 1 AND 3
UNION
SELECT * FROM player WHERE exp BETWEEN 1 AND 3;
# INTERSECT, 取查询结果的交集
SELECT * FROM player WHERE level BETWEEN 1 AND 3
INTERSECT
SELECT * FROM player WHERE exp BETWEEN 1 AND 3;
# EXCEPT, 取合并结果的差集, 差集是相对的
SELECT * FROM player WHERE level BETWEEN 1 AND 3
EXCEPT
SELECT * FROM player WHERE exp BETWEEN 1 AND 3;
# 查询结果1相对于查询结果2的差集, 也就是等级在1到3级, 但是经验不在1到3之间的
LENGTH()
函数,计算字符串的长度,其实本质是计算字符串字节数,只有中文字符(汉字,中文标点)不是一个字节的,因此可以用来检验是否含有中文字符。
子查询
有的时候我们需要使用一个查询的结果作为另一个查询的条件, 这个时候就可以使用子查询了.
mysql
# 查找等级大于平均等级的玩家
SELECT * FROM player WHERE level > (SELECT AVG(level) FROM player);
# 所有玩家的等级和平均等级的差值, AS 关键字能给列起别名, 在查询出的表中就以别名显示
SELECT level, ROUND((SELECT AVG(level) FROM player)) as average,
level - ROUND((SELECT AVG(level) FROM player)) as diff
FROM player;
# 使用子查询创建一个新表
CREATE TABLE new_player SELECT * FROM player WHERE level < 5;
SELECT * FROM new_player;
# 使用子查询向表中插入数据
INSERT INTO new_player SELECT * FROM player WHERE level BETWEEN 6 AND 10;
# EXISTS 返回查询是否有结果, 返回值只有0 和 1两种
SELECT EXISTS 返回查询(SELECT * FROM player WHERE level > 90);
表关联
用来查询多个表中的数据, 关联的表之间必须有相同的字段(列, Field), 一般使用表的主键和外键来关联, 分为以下几种类型 :
内连接: 只返回两个表中都有的数据
左连接: 返回左表中所有的数据和右表中匹配的数据, 右表中没有的数据用 NULL 来填充
右连接同左连接相似
mysql
# 内连接查询
SELECT * FROM player
INNER JOIN equip
ON player.id = equip.player_id; # ON 指定关键字段
SELECT * FROM player p, equip e # 指定别名, 下边代码可以直接使用
WHERE p.id = e.player_id; # WHERE 指定关键字段
# 左连接查询 右连接改为RIGHT即可
SELECT * FROM player
LEFT JOIN equip
ON player.id = equip.player_id;
如果连接没有指定条件或者条件不正确, 就会产生笛卡尔积, 表连接的本质就是笛卡尔积再加上条件过滤。
LENGTH()
函数,计算字符串的长度,其实本质是计算字符串字节数,只有中文字符(汉字,中文标点)不是一个字节的,因此可以用来检验是否含有中文字符。
索引
当数据非常大的时候, 遍历寻找数据的方法效率太低, 索引应运而生
mysql
SELECT * FROM player;
# 唯一索引 全文索引 空间索引
CREATE [UNIIQUE][FULLTEXT][SPATIAL] INDEX index_name
ON tbl_name(index_col_name)... # 对()里边的字段创建索引
# fast 和 slow 两张数量庞大的表
DESC fast;
SELECT COUNT(*) FROM fast;
CREATE INDEX email_index ON fast(email); # 对email创建索引
SHOW INDEX FROM fast; # 查询索引
SELECT * FROM slow WHERE email LIKE 'abcd%' ORDER BY id;
SELECT * FROM fast WHERE email LIKE 'abcd%' ORDER BY id;
DROP INDEX email_index ON fast; # 删除索引
# 修改表结构时创建索引
ALTER TABLE fast ADD INDEX name_index (name);
# 还可以在创建表的时候创建索引
视图
视图是一种虚拟存在的表, 它本身并不包含数据, 而是作为一个查询语句, 保存在数据字典中, 当我们查询视图的时候, 它会根据查询语句的定义, 来动态地生成数据
mysql
# 创建视图
CREATE VIEW top10
AS
SELECT * FROM player ORDER BY level DESC LIMIT 10;
# 查询视图
SELECT * FROM top10;
# 视图的数据是动态的, 对player表中的数据进行修改, 也会在top10中看到
# 修改视图
ALTER VIEW top10
AS
SELECT * FROM player ORDER BY level LIMIT 10;
# 删除视图
DROP VIEW top10;