• 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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    ​ 这时我们可以直接使用 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
    • 2
    • 3
    • 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表
    
    • 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

    数据导入导出

    导出数据: 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之间的
    
    • 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
    • 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);
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    表关联

    用来查询多个表中的数据, 关联的表之间必须有相同的字段(列, 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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    如果连接没有指定条件或者条件不正确, 就会产生笛卡尔积, 表连接的本质就是笛卡尔积再加上条件过滤。

    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);
    # 还可以在创建表的时候创建索引
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    视图

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

    # 创建视图
    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;	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    手写useState与useEffect
    微信小程序--自定义组件(超详细 从新建到使用)
    Monaco Editor教程(四):设置或获取内容,并监听内容的改变
    一幅长文细学JavaScript(一)——一幅长文系列
    【算法100天 | 3】筑基二分查找(含LeetCode 34题 在排序数组中查找元素的第一个和最后一个位置)
    金属材料/多肽/多糖/化合物/抗体/量子点/黑磷量子点修饰水凝胶
    Torch 数据集放到网络训练(六)
    京东零售大数据云原生平台化实践
    Java21 + SpringBoot3使用Spring Security时如何在子线程中获取到认证信息
    史上最强 Java 学习路线图!
  • 原文地址:https://blog.csdn.net/cosx_/article/details/134304445