安装MySQL小帮手

126 阅读6分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

在 Ubuntu 18 中在线安装 MySQL

# 请从 https://dev.mysql.com/downloads/repo/apt/ 中取得最新的源
$ wget -c https://repo.mysql.com//mysql-apt-config_0.8.22-1_all.deb  
# ...
$ dpkg -i mysql-apt-config_0.8.22-1_all.deb  
# ...
# 选择第四行 `ok`, 回车, 将默认源设置为 `mysql-8.0`
# ...
$ apt update
# ...
$ apt-get install mysql-server
# ...
# 要求设置密码, 例如设置为12qw!@QW
# 选择默认的认证方式为 Use Legacy Authentication Method (Retain MySQL 5.x Compatibility)
# ...
# MySQL服务已经启动, 并且 root@localhost 认证方式为 mysql_native_password, 密码为 12qw!@QW

在 CentOS 7 中在线安装 MySQL

# 请从 https://dev.mysql.com/downloads/repo/yum/ 中取得最新的源
$ wget -i -c https://dev.mysql.com/get/mysql80-community-release-el7-5.noarch.rpm
# ...
$ yum -y install mysql80-community-release-el7-5.noarch.rpm
# ...
$ yum -y install mysql-community-server
# ...
# 这里结果与Ubuntu不同

在 CentOS 7 中离线安装 MySQL

# 请从 https://dev.mysql.com/downloads/mysql/ 中取得最新的源, **注意: 需要自行检查perl环境**  
# 检查是否存在冲突的 mariadb
$ yum list installed | grep mariadb
# 删除 mariadb
$ yum -y remove mariadb*
# 安装 mysql, 根据实际情况可能需要调整
$ rpm -ivh mysql-community-icu-data-files-8.0.28-1.el7.x86_64.rpm
$ rpm -ivh mysql-community-common-8.0.28-1.el7.x86_64.rpm
$ rpm -ivh mysql-community-client-plugins-8.0.28-1.el7.x86_64.rpm
$ rpm -ivh mysql-community-libs-8.0.28-1.el7.x86_64.rpm
$ rpm -ivh mysql-community-client-8.0.28-1.el7.x86_64.rpm
$ rpm -ivh mysql-community-server-8.0.28-1.el7.x86_64.rpm

首次安装需要进行数据库的配置

# 启动 mysql
$ systemctl start mysqld
# 查询初始密码
$ grep 'temporary password' /var/log/mysqld.log
# 进行初始化
$ mysql_secure_installation

配置远程访问

默认情况下, MySQL拒绝root远程登录, 需要对以下部分进行配置

# 远程访问
$ mysql -h 192.168.1.243 -P 3306 -u root -p

云服务供应商的安全策略

在阿里云实例安全组中配置MySQL的访问端口

服务器主机的防火墙

① 可以选择关闭防火墙

$ systemctl stop firewalld

② 在不关闭防火墙的情况下, 允许某端口的外来链接

# 查看3306端口是否开启
$ firewall-cmd --query-port=3306/tcp  
no
# 开启3306端口
$ firewall-cmd --zone=public --add-port=3306/tcp --permanent  
success
# 重启防火墙
$ firewall-cmd --reload  
success
# 查看3306端口是否开启
$ firewall-cmd --query-port=3306/tcp  
yes
# 端口33060同理

新增一个远程用户

$ mysql -u root -p
# Enter password: 
# Welcome to the MySQL monitor.  Commands end with ; or \g.
mysql> USE mysql;
mysql> SELECT Host, User, plugin, authentication_string FROM user;
# +-----------+------------------+-----------------------+------------------------------------------------------------------------+
# | host      | user             | plugin                | authentication_string                                                  |
# +-----------+------------------+-----------------------+------------------------------------------------------------------------+
# | localhost | mysql.infoschema | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
# | localhost | mysql.session    | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
# | localhost | mysql.sys        | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
# | localhost | root             | caching_sha2_password | $A$005$2ML2cG]vp,j *2td|%pmfxg7D19RlbbVQGtDIqs0w0A1tYTW7To2iCnLglT79   |
# +-----------+------------------+-----------------------+------------------------------------------------------------------------+
# 4 rows in set (0.00 sec)

# mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '12qw!@QW';
# Query OK, 0 rows affected (0.001 sec)

mysql> CREATE USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '12qw!@QW'; 
# Query OK, 0 rows affected (0.001 sec)

mysql> GRANT ALL ON *.* TO 'root'@'%'; 
# Query OK, 0 rows affected (0.001 sec)

mysql> FLUSH PRIVILEGES; 
# Query OK, 0 rows affected (0.00 sec)

mysql> EXIT;
# Bye

可能会遇到的问题

忘记 'root'@'localhost' 的密码

$ brew services stop mysql # 停止mysql
# Stopping `mysql`... (might take a while)
# ==> Successfully stopped `mysql` (label: homebrew.mxcl.mysql)
# 安全启动mysql                                              
$ /usr/local/Cellar/mysql/8.0.25_1/bin/mysqld_safe --skip-grant-tables & 
# [1] 4121
# $ 2021-11-05T09:38:31.6NZ mysqld_safe Logging to '/usr/local/var/mysql/Weizhens-Mac-mini.local.err'.
# 2021-11-05T09:38:31.6NZ mysqld_safe Starting mysqld daemon with databases from /usr/local/var/mysql
# 
$ mysql  # 进入mysql
# Welcome to the MySQL monitor.  Commands end with ; or \g.
# Your MySQL connection id is 7
# Server version: 8.0.25 Homebrew

# Copyright (c) 2000, 2021, Oracle and/or its affiliates.

# Oracle is a registered trademark of Oracle Corporation and/or its
# affiliates. Other names may be trademarks of their respective
# owners.

# Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use mysql; # 切换数据库
# Reading table information for completion of table and column names
# You can turn off this feature to get a quicker startup with -A

# Database changed
mysql> flush privileges;
# Query OK, 0 rows affected (0.01 sec)

mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'Whmx0319';
# Query OK, 0 rows affected (0.01 sec)

mysql> exit;
# Bye
$ brew services start mysql
# ==> Successfully started `mysql` (label: homebrew.mxcl.mysql)

在 BASH 使用的命令

# 查询初始密码
$ grep 'temporary password' /var/log/mysqld.log
# 运行配置向导
$ mysql_secure_installation 
# 查找 mysqld 的路径
$ which mysqld
# 查找 mysqld 的配置文件
$ /usr/local/mysql/bin/mysqld --verbose --help |grep -A 1 'Default options'
# 通常情况下, 配置文件位于:
# /etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf

# 这个是远程登录的命令, 使用账号 root 和密码连接 MySQL
$ mysql -h 192.168.1.100 -P 3306 -u root -p 
# 这个是本机登录的命令, 使用账号 root 和密码连接 MySQL
$ mysql -u root -p 
# 这个是本机登录的命令, 可以将密码混入命令中
$ mysql -uroot -pMyPassword
$ mysql --user=MyUser --password=MyPassword

# 启动 MySQL
$ mysql.server start
# 停止 MySQL 
$ mysql.server stop 
# 查看 MySQL 运行状态
$ mysql.server status 
# 停止并重启 MySQL
$ mysql.server restart 

在 MySQL 客户端中使用的语句

-- 返回可用数据库的一个列表
SHOW DATABASES;

-- 选择指定的数据库 
USE mysql;

-- 返回当前选择的数据库内可用表的列表
SHOW TABLES;

-- 显示表的列
SHOW COLUMNS FROM mysql; 
-- 等效的另一种表达 
DESCRIBE mysql;

-- 显示广泛的服务器状态信息
SHOW STATUS;

-- 显示创建数据库SQL
SHOW CREATE DATABASE mxt21d05;

-- 显示创建表的SQL
SHOW CREATE TABLE part_entity;

-- 用来显示授予用户(所有用户或特定用户)的安全权限
SHOW GRANTS;
SHOW GRANTS FOR 'root';
SHOW GRANTS FOR 'root'@'%';
SHOW GRANTS FOR 'root'@'localhost';

-- 用来显示服务器错误消息
SHOW ERRORS;

-- 用来显示服务器警告消息
SHOW WARNINGS;

-- 查询时区
SHOW VARIABLES LIKE '%time_zone%';

-- 查看密码安全策略
SHOW VARIABLES LIKE '%validate_password%';

-- 密码策略: 密码长度最少为6
SET GLOBAL validate_password.length=6;

-- 密码策略: 特殊字符最少0个
SET GLOBAL validate_password.special_char_count=0;

-- 显示所有活动进程, 以及它们的线程ID和执行时间
SHOW PROCESSLIST;

-- 查看当前版本
SELECT @@VERSION;

-- 查看当前用户
SELECT CURRENT_USER;
-- 删除用户
DROP USER 'zhang'@'%';

-- 新增一个用户zhang, 密码为12345678, 可以从任何IP访问
CREATE USER 'zhang'@'%' IDENTIFIED BY '12345678'; 
CREATE USER 'zhang'@'%' IDENTIFIED WITH caching_sha2_password BY '12345678'; 

-- 修改认证方式
ALTER USER 'zhang'@'%' IDENTIFIED BY '88888888';
ALTER USER 'zhang'@'%' IDENTIFIED WITH mysql_native_password BY '88888888';
-- 数据控制语言(DCL)

-- 在使用 GRANT 和 REVOKE 时, 用户账号必须存在, 但对所涉及的对象没有这个要求. 这允许管理员在创建数据库和表之前设计和实现安全措施. 
-- 这样做的副作用是, 当某个数据库或表被删除时(用 DROP 语句), 相关的访问权限仍然存在. 而且, 如果将来重新创建该数据库或表, 这些权限仍然起作用. 

-- 设置zhang的权限为ALL(除 GRANT OPTION 外的所有权限), 可以访问任意库的任意表
GRANT ALL ON *.* TO 'zhang'@'%'; 

-- 取消zhang@%的这些权限: 任意库的任意表上的 SELECT 和 INSERT
REVOKE SELECT, INSERT ON *.* FROM 'zhang'@'%'; 

-- 使权限设置生效, 不需要重启 MySQL
FLUSH PRIVILEGES; 

-- 退出 `mysql client`
EXIT; 
-- 事务处理语言(DPL)
-- 数据定义语言(DDL)

-- 删除数据库
DROP DATABASE world;

-- 销毁表
DROP TABLE user;

-- 截断表, 相当于 DELETE FROM users
TRUNCATE TABLE users;

-- 创建表
CREATE TABLE IF NOT EXISTS user (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER);
CREATE TABLE user (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER);
CREATE TABLE user (id INTEGER, name TEXT, age INTEGER, PRIMARY KEY(id, name));

-- 修改表, 增加一列
ALTER TABLE tab_name ADD COLUMN col_name TEXT;

-- 修改表, 修改表名
ALTER TABLE tab_name RENAME TO new_tab_name;

-- 修改列, 修改列名和类型
ALTER TABLE sys_session 
CHANGE COLUMN `session`     `id`   varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL FIRST,
CHANGE COLUMN `create_time` `ct`   datetime NOT NULL AFTER `id`,
CHANGE COLUMN `update_time` `ut`   datetime NOT NULL AFTER `ct`,
CHANGE COLUMN `id`          `user` int      NOT NULL AFTER `update_time`,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`) USING BTREE;
-- 数据操纵语言 (DML:Data Manipulation Language)

-- 删除行
DELETE FROM user WHERE name = 'saber';

-- 添加行
INSERT INTO user(name, age) VALUES('saber', 18);
INSERT INTO user(name, age) VALUES('saber', 18), ('baserker', 22);
INSERT INTO user SET name = 'saber', age = 18;
INSERT INTO user_map (userid, deptid) SELECT u.id, u.deptid FROM user u;

-- 修改行
UPDATE user SET age = 16 WHERE name = 'saber';
-- 数据查询语言(DQL: Data Query Language)

-- 查询行
SELECT * FROM user;

-- 查询表的默认值
SELECT COLUMN_NAME, COLUMN_DEFAULT FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'library_name' AND TABLE_NAME = 'table_name';

-- 分组并按照组内字段排序, 取得最大(最小)值所在的行, 请注意与 GROUP BY 的区别
SELECT *, ROW_NUMBER() OVER(PARTITION BY product_sn ORDER BY start_time ASC) AS rn FROM test_general WHERE name = 'saber';

-- 从组内排序的结果中, 选择符合条件的行
SELECT * FROM (SELECT *, ROW_NUMBER() OVER(PARTITION BY product_sn ORDER BY start_time ASC) AS rn FROM test_general WHERE name = 'saber') b WHERE rn = 1 AND state = 'PASS' ORDER BY start_time;

-- 按照 name 分组取 val 最大
SELECT a.* FROM tb a WHERE val = (SELECT MAX(val) FROM tb WHERE name = a.name) ORDER BY a.name;

-- DISTINCT关键字应用于所有列。`backup, code` 都相同时, 只输出一行
SELECT DISTINCT backup, code FROM part_entity ORDER BY code LIMIT 10;

-- 正则匹配: MySQL 的正则表达式没有完全实现, 并且不能区分大小写
SELECT * FROM part_entity WHERE code REGEXP '1100001';
SELECT * FROM part_entity WHERE code REGEXP '1100001|1100002';
SELECT * FROM part_entity WHERE code REGEXP '110000[123]';
SELECT * FROM part_entity WHERE code REGEXP '^[a-z]0000[0-9]{2,}$';

-- 计算字段
SELECT CONCAT(code, '(', version, ')'), LTRIM(description), price * stock FROM part_entity LIMIT 10;

-- 条件, 分组, 过滤, 排序
SELECT pcode, COUNT(scode) AS total FROM part_formula WHERE backup = '' GROUP BY pcode HAVING total > 10 ORDER BY total DESC LIMIT 10;

-- 子查询. 如果子查询的结果不是一列并且一行, 会报错
SELECT *, (SELECT value FROM opts_entity WHERE class = 'default_baud' LIMIT 1) AS default_baud FROM opts_entity WHERE class = 'burning_mode';
SELECT * FROM part_formula WHERE pcode = (SELECT code FROM part_entity WHERE code = '2200016' LIMIT 1);

-- 多表查询, 叉联结, 内部联结, 等值联结. 
-- 它基于两个表之间的相等测试, 这几种表达方式等效, 但是推荐 INNER JOIN 写法
SELECT a.*, b.* FROM sess_entity a, user_entity b WHERE a.id = b.id;
SELECT a.*, b.* FROM sess_entity a CROSS JOIN user_entity b ON a.id = b.id;
SELECT a.*, b.* FROM sess_entity a INNER JOIN user_entity b ON a.id = b.id;