MySQL 学习笔记

b站1小时学MySQL

1.安装 MySql

  1. 安装命令: sduo apt install mysql-server

  2. 安装完成之后会自动启动 MySql 的服务, 可以使用命令 systemctl status mysql 查看服务的状态. 如果没有启动, 可以使用 systemctl start mysql 启动服务

  3. root 用户密码问题, linux 下安装完是有密码的, 使用命令 sudo cat /etc/mysql/debian.cnf 来查看默认用户名和密码. 使用命令 mysql -u debian-sys-maint -p 来连接 MySql, 复制一下 [mysql_upgrade] 里边的密码进行连接

  4. 修改 root 用户密码

    1)直接使用 root 用户来连接 alter user 'root'@'%' identified with mysql_native_password by '3333';

    有可能显示 error 1396(HY000) , 这时可以先将 user 表中的 root, localhost 改成 %

# 错误是由于root 用户默认是没有开放远程权限的
# localhost 表示这个用户只能在本地访问, 改成 % 后就可以在任何地方访问了
use mysql;
select user, host from user;
update user set host = '%' where user = 'root';
flush privileges;

​ 这时我们可以直接使用 mysql -u root -p, 然后输入修改后的密码, 进行连接 MySQL

​ 2)修改密码策略

show variables like 'validate_password%';
# 根据显示表格里的变量名进行修改即可, mysql更新变量名形式可能会稍微变动
set global validate_password.policy=LOW;
set global validate_password.length = 4;
  1. MySql 服务的监听地址

    1)无法连接 MySql 服务器, 把服务器放开 3306 端口地址 或者在开发环境下关闭防火墙

    2)配置文件的监听地址问题, 默认 MySQL 服务只监听本地 IP 地址, 外部是无法连接 MySQL 服务的, 把配置文件的 bind-addressmysqlx-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 类型, 空间类型

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

常用语句

# 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() 函数,计算字符串的长度,其实本质是计算字符串字节数,只有中文字符(汉字,中文标点)不是一个字节的,因此可以用来检验是否含有中文字符。

子查询

有的时候我们需要使用一个查询的结果作为另一个查询的条件, 这个时候就可以使用子查询了.

# 查找等级大于平均等级的玩家
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 来填充

右连接同左连接相似

# 内连接查询
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() 函数,计算字符串的长度,其实本质是计算字符串字节数,只有中文字符(汉字,中文标点)不是一个字节的,因此可以用来检验是否含有中文字符。

索引

当数据非常大的时候, 遍历寻找数据的方法效率太低, 索引应运而生

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);
# 还可以在创建表的时候创建索引

视图

视图是一种虚拟存在的表, 它本身并不包含数据, 而是作为一个查询语句, 保存在数据字典中, 当我们查询视图的时候, 它会根据查询语句的定义, 来动态地生成数据

# 创建视图
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;	

你可能感兴趣的:(mysql,学习,笔记)