从零开始学 MySQL:SQL 编程、多表查询、用户管理一站式教程

MySQL 基本使用

MySQL 的特性

  • MySQL 是基于开源协议发布的,可以免费使用,也可以基于源码进行二次开发。
  • MySQL 使用标准 SQL 语言进行管理。
  • MySQL 可以运行于多个系统上,具有跨平台特性,并且支持多种语言。
  • MySQL 使用插件式存储引擎,不同的存储引擎有着不同的功能和特性,使用者可以根据需要灵活选择。
  • MySQL 基于单进程、多线程的模式进行工作。
  • MySQL 提供了大量的测试组件和诸多的扩展。

MySQL 多实例

数据库多实例介绍

什么是数据库多实例

拿 MySQL 数据库来说明,就是在一台服务器上运行多个 MySQL 服务端进程,每个进程监听一个端口(3306、3307、3308),维护一套属于其自己的配置和数据,客户端使用不同的端口来连接具体服务端进程,从而实现对不同实例的操作。

多实例的优点

  • 节约硬件资源:在某些场景下(比如说测试、调研、新旧业务并存等),需要配置不同的 MySQL 数据库版本,而又没有足够多的服务器资源,则可以选择在一台服务器上用不同的版本实现多开来满足需求。
  • 便于对比:在一个完全相同的硬件环境中,运行不同的 MySQL 版本,使用相同的参数进行测试、调研时,可以最大程度地减少外部环境因素的影响,便于得出更准确的结论。
  • 便于管理:在一台服务器上运行多个实例,同理,只需要在这一台服务器上配置安全规则,就可以完成对多个实例的访问授权,而且对于数据库的备份、停启等工作,也只需要在这一台服务器上完成。

多实例的缺点

  • 资源抢占:一台服务器上运行多个服务实例,资源总量恒定,一个实例占用的资源无法被另一个实例所使用,在这种情况下,服务性能会受到影响,无法体现 MySQL 服务的实际性能。
  • 存在单点风险:一台服务器上部署多个服务实例,如果该服务器宕机,则这多个服务实例都会受影响。

MySQL 多实例配置方案

可以用不同的 MySQL 版本实现多实例,也可以用相同的 MySQL 版本实现多实例。

MySQL 组成和常用工具

MySQL 主要组成

MySQL 基于 C/S 模式提供服务,主要由客户端程序和服务端程序组成,另外还有一些管理工具。

服务端主要组成

程序 功能
mysqld_safe 安全启动脚本
mysqld 服务端程序,是mysql服务的核心程序
mysqld_multi 多实例工具

客户端主要组成

程序 功能
mysql 基于mysql协议的交互式CLI工具
mysqldump 备份工具
mysqladmin 服务端管理工具
mysqlimport 数据导入工具

MyISAM 存储引擎的管理工具

程序 功能
myisamchk 检测MyISAM库
myisampack 打包MyISAM表,只读

配置文件

不同版本配置文件略有不同

bash 复制代码
[root@localhost ~]# cat /etc/my.cnf
#
# This group is read both both by the client and the server
# use it for options that affect everything
#
[client-server]

#
# include all files from the config directory
#
!includedir /etc/my.cnf.d

[root@localhost ~]# tree /etc/my.cnf.d/
/etc/my.cnf.d/
├── client.cnf                  #客户端配置
├── mysql-default-authentication-plugin.cnf
└── mysql-server.cnf           #服务器端配置

0 directories, 3 files

生效顺序

bash 复制代码
[root@localhost ~]# mysql --help | grep my.cnf
                      order of preference, my.cnf, $MYSQL_TCP_PORT,
/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf

MySQL 中的用户账户

详见 MySQL 用户管理

MySQL 命令类型

MySQL 中的命令分为两类,分别是客户端命令和服务端命令。

客户端命令在本地执行。服务端命令发送到服务端执行,再返回执行结果到客户端上。

客户端命令和服务端命令,都是通过 MySQL 客户端工具进行输入输出。

查看所有客户端命令

mysql 复制代码
mysql> ?

For information about MySQL products and services, visit:
   http://www.mysql.com/
For developer information, including the MySQL Reference Manual, visit:
   http://dev.mysql.com/
To buy MySQL Enterprise support, training, or other products, visit:
   https://shop.mysql.com/

List of all MySQL commands:
Note that all text commands must be first on line and end with ';'
?         (\?) Synonym for `help'.
clear     (\c) Clear the current input statement.
connect   (\r) Reconnect to the server. Optional arguments are db and host.
delimiter (\d) Set statement delimiter.
edit      (\e) Edit command with $EDITOR.
ego       (\G) Send command to mysql server, display result vertically.
exit      (\q) Exit mysql. Same as quit.
go        (\g) Send command to mysql server.
help      (\h) Display this help.
nopager   (\n) Disable pager, print to stdout.
notee     (\t) Don't write into outfile.
pager     (\P) Set PAGER [to_pager]. Print the query results via PAGER.
print     (\p) Print current command.
prompt    (\R) Change your mysql prompt.
quit      (\q) Quit mysql.
rehash    (\#) Rebuild completion hash.
source    (\.) Execute an SQL script file. Takes a file name as an argument.
status    (\s) Get status information from the server.
system    (\!) Execute a system shell command.
tee       (\T) Set outfile [to_outfile]. Append everything into given outfile.
use       (\u) Use another database. Takes database name as argument.
charset   (\C) Switch to another charset. Might be needed for processing binlog with multi-byte charsets.
warnings  (\W) Show warnings after every statement.
nowarning (\w) Don't show warnings after every statement.
resetconnection(\x) Clean session context.
query_attributes Sets string parameters (name1 value1 name2 value2 ...) for the next query to pick up.

For server side help, type 'help contents'

查看所有服务端命令

mysql 复制代码
mysql> help contents
You asked for help about help category: "Contents"
For more information, type 'help <item>', where <item> is one of the following
categories:
   Account Management
   Administration
   Components
   Compound Statements
   Contents
   Data Definition
   Data Manipulation
   Data Types
   Functions
   Geographic Features
   Help Metadata
   Language Structure
   Loadable Functions
   Plugins
   Prepared Statements
   Replication Statements
   Storage Engines
   Table Maintenance
   Transactions
   Utility

查看服务端命令具体项

mysql 复制代码
mysql> help Administration
You asked for help about help category: "Administration"
For more information, type 'help <item>', where <item> is one of the following
topics:
   BINLOG
   CACHE INDEX
   FLUSH
   HELP COMMAND
   KILL
   LOAD INDEX
   RESET
   RESET PERSIST
   RESTART
   SET
   SET CHARACTER SET
   SET CHARSET
   SET NAMES
   SHOW
   SHOW BINARY LOGS
   SHOW BINLOG EVENTS
   SHOW CHARACTER SET
   SHOW COLLATION
   SHOW COLUMNS
   SHOW CREATE DATABASE
   SHOW CREATE EVENT
   SHOW CREATE FUNCTION
   SHOW CREATE PROCEDURE
   SHOW CREATE SCHEMA
   SHOW CREATE TABLE
   SHOW CREATE TRIGGER
   SHOW CREATE USER
   SHOW CREATE VIEW
   SHOW DATABASES
   SHOW ENGINE
   SHOW ENGINES
   SHOW ERRORS
   SHOW EVENTS
   SHOW FIELDS
   SHOW FUNCTION CODE
   SHOW FUNCTION STATUS
   SHOW GRANTS
   SHOW INDEX
   SHOW MASTER LOGS
   SHOW MASTER STATUS
   SHOW OPEN TABLES
   SHOW PLUGINS
   SHOW PRIVILEGES
   SHOW PROCEDURE CODE
   SHOW PROCEDURE STATUS
   SHOW PROCESSLIST
   SHOW PROFILE
   SHOW PROFILES
   SHOW RELAYLOG EVENTS
   SHOW REPLICA STATUS
   SHOW REPLICAS
   SHOW SCHEMAS
   SHOW SLAVE HOSTS
   SHOW SLAVE STATUS
   SHOW STATUS
   SHOW TABLE STATUS
   SHOW TABLES
   SHOW TRIGGERS
   SHOW VARIABLES
   SHOW WARNINGS
   SHUTDOWN

查看详细帮助

mysql 复制代码
mysql> help BINLOG
Name: 'BINLOG'
Description:
Syntax:
BINLOG 'str'

BINLOG is an internal-use statement. It is generated by the mysqlbinlog
program as the printable representation of certain events in binary log
files. (See https://dev.mysql.com/doc/refman/8.0/en/mysqlbinlog.html.)
The 'str' value is a base 64-encoded string the that server decodes to
determine the data change indicated by the corresponding event.

To execute BINLOG statements when applying mysqlbinlog output, a user
account requires the BINLOG_ADMIN privilege (or the deprecated SUPER
privilege), or the REPLICATION_APPLIER privilege plus the appropriate
privileges to execute each log event.

URL: https://dev.mysql.com/doc/refman/8.0/en/binlog.html

MySQL 客户端使用

MySQL 服务基于 C/S 架构,用户主要使用客户端工具来与远程服务端进行连接,从而与 MySQL 服务进行交互。

MySQL 客户端常用选项

格式:

bash 复制代码
[root@localhost ~]# mysql --help
Usage: mysql [OPTIONS] [database]

#常用选项
-V|--version				#显示客户端版本
-u|--user=name				#指定远程连接用户名
-p|--password[=name]		#指定密码,默认为空
-h|--host=host				#指定服务端主机
-P|--port=port				#指定端口,默认3306
-S|--socket=name			#指定连接时使用的socket文件,该文件在服务端启动后生成
-D|--database=db			#指定数据库
-H|--html					#以html格式输出
-X|--xml					#以xml格式输出
-t|--table					#以table格式输出,默认项
-E|--vertical				#垂直显示执行结果
-v|--verbose				#显示详细信息,配合-t选项
-C|--compress				#启用压缩
-G|--named-commands			#启用长命令
-e|--execute=sql			#执行完就退出,非交互式运行
-prompt=name				#修改命令提示符
--line-numbers				#输出行号
--print-defaults			#打印参数列表,放在最前面
--connect-timeout=N			#连接超时时长,单位S
--max-allowed-packet=N		#一次查交互发送或反回数据的大小,默认16MB,最大值为1GB,最小值为4096字节

范例:

bash 复制代码
#免密登录
[root@localhost ~]# mysql -uroot -pHuawei@123
mysql> alter user root@localhost identified by '';        #将mysql root账号密码设置为空
mysql> quit                                               #退出mysql

#显示版本
[root@localhost ~]# mysql -V
mysql  Ver 8.0.26 for Linux on x86_64 (Source distribution)

#指定用户名,主机,端口
[root@localhost ~]# mysql -uroot -h127.0.0.1 -P3306
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 22
Server version: 8.0.26 Source distribution

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>

#使用主机名
[root@localhost ~]# mysql --user=root --host=localhost --port=3306
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 23
Server version: 8.0.26 Source distribution

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>

#默认使用root连接,密码为空
[root@localhost ~]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 24
Server version: 8.0.26 Source distribution

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.

#打印参数列表,并不连接服务端,--print-defaults要放在第一个
[root@localhost ~]# mysql --print-defaults -uroot -hlocalhost --connect-timeout=2
mysql would have been started with the following arguments:
-uroot -hlocalhost --connect-timeout=2

#以html格式显示输出
[root@localhost ~]# mysql -H
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 25
Server version: 8.0.26 Source distribution

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> select version();
<TABLE BORDER=1><TR><TH>version()</TH></TR><TR><TD>8.0.26</TD></TR></TABLE>1 row in set (0.00 sec)

范例:执行完退出,非交互式执行

bash 复制代码
#环境准备
[root@localhost ~]# vim /root/test.sql
show databases;

#执行客户端命令
[root@localhost ~]# mysql -e "source /root/test.sql"
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

#管道执行
[root@localhost ~]# cat test.sql | mysql
Database
information_schema
mysql
performance_schema
sys

#标准输入重定向执行
[root@localhost ~]# mysql -uroot < test.sql
Database
information_schema
mysql
performance_schema
sys

#以table格式输出
[root@localhost ~]# mysql -e "show databases;"
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

#垂直显示
[root@localhost ~]# mysql -e "show databases;" -E
*************************** 1. row ***************************
Database: information_schema
*************************** 2. row ***************************
Database: mysql
*************************** 3. row ***************************
Database: performance_schema
*************************** 4. row ***************************
Database: sys

范例:修改提示符

bash 复制代码
[root@localhost ~]# mysql --prompt=[test]
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 37
Server version: 8.0.26 Source distribution

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.

[test]

范例:指定数据库

bash 复制代码
#默认
[root@localhost ~]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 38
Server version: 8.0.26 Source distribution

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> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

mysql>

#指定数据库
[root@localhost ~]# mysql information_schema
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 41
Server version: 8.0.26 Source distribution

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> SELECT DATABASE();
+--------------------+
| DATABASE()         |
+--------------------+
| information_schema |
+--------------------+
1 row in set (0.01 sec)

mysql>
MySQL 客户端常用命令
bash 复制代码
mysql> ?

For information about MySQL products and services, visit:
   http://www.mysql.com/
For developer information, including the MySQL Reference Manual, visit:
   http://dev.mysql.com/
To buy MySQL Enterprise support, training, or other products, visit:
   https://shop.mysql.com/

List of all MySQL commands:
Note that all text commands must be first on line and end with ';'
?         (\?) Synonym for `help'.
clear     (\c) Clear the current input statement.
connect   (\r) Reconnect to the server. Optional arguments are db and host.
delimiter (\d) Set statement delimiter.
edit      (\e) Edit command with $EDITOR.
ego       (\G) Send command to mysql server, display result vertically.
exit      (\q) Exit mysql. Same as quit.
go        (\g) Send command to mysql server.
help      (\h) Display this help.
nopager   (\n) Disable pager, print to stdout.
notee     (\t) Don't write into outfile.
pager     (\P) Set PAGER [to_pager]. Print the query results via PAGER.
print     (\p) Print current command.
prompt    (\R) Change your mysql prompt.
quit      (\q) Quit mysql.
rehash    (\#) Rebuild completion hash.
source    (\.) Execute an SQL script file. Takes a file name as an argument.
status    (\s) Get status information from the server.
system    (\!) Execute a system shell command.
tee       (\T) Set outfile [to_outfile]. Append everything into given outfile.
use       (\u) Use another database. Takes database name as argument.
charset   (\C) Switch to another charset. Might be needed for processing binlog with multi-byte charsets.
warnings  (\W) Show warnings after every statement.
nowarning (\w) Don't show warnings after every statement.
resetconnection(\x) Clean session context.
query_attributes Sets string parameters (name1 value1 name2 value2 ...) for the next query to pick up.

For server side help, type 'help contents'

范例:显示当前数据库

mysql 复制代码
#显示当前数据库
mysql> \s
--------------
mysql  Ver 8.0.26 for Linux on x86_64 (Source distribution)
 
Connection id:          8                              #连接ID
Current database:                                      #当前使用的数据库
Current user:           root@localhost                 #连接使用的用户名
SSL:                    Not in use                     #是否使用ssl
Current pager:          stdout
Using outfile:          ''
Using delimiter:        ;
Server version:         8.0.26 Source distribution     #版本
Protocol version:       10                             #协议版本
Connection:             Localhost via UNIX socket
Server characterset:    utf8mb4                        #服务器编码
Db     characterset:    utf8mb4                        #数据库编码
Client characterset:    utf8mb4                        #客户端编码
Conn.  characterset:    utf8mb4
UNIX socket:            /var/lib/mysql/mysql.sock      #连接使用的socket文件
Binary data as:         Hexadecimal
Uptime:                 28 min 46 sec                  #服务器运行时长

Threads: 2  Questions: 6  Slow queries: 0  Opens: 117  Flush tables: 3  Open tables: 36  Queries per second avg: 0.003                                             
--------------

范例:切换数据库

mysql 复制代码
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>

范例:调用系统命令

bash 复制代码
mysql> \! hostname          #查看宿主机主机名,!号后面有空格
localhost.localdomain
mysql> \! clear             #清屏

范例:修改提示符

mysql 复制代码
mysql> prompt [\h--\D]
PROMPT set to '[\h--\D]'
[localhost--Mon Sep 15 22:09:09 2025]

[localhost--Mon Sep 15 22:10:01 2025]\R abcd
PROMPT set to 'abcd'
abcd
abcd

在配置文件中修改提示符

bash 复制代码
[root@localhost ~]# vim /etc/my.cnf.d/client.cnf
[client]
prompt=(\\u@\\h) [\\d]>\\
mysql 复制代码
[root@localhost ~]# mysql         #验证效果 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 8.0.26 Source distribution

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.

(root@localhost) [(none)]>       #效果

提示符中可用的变量,全部可用的替换符用 man mysql 查看

bash 复制代码
\C	#计数器
\D	#年月日时分秒
\d	#当前使用的数据库
\h	#服务器主机名
\l  #命令分隔符,默认;
\m	#当前时间,分钟
\n	#换行
\O	#月份,以英文显示
\o	#月份,数字显示
\P	#pm/am
\R	#小时,24小时制
\r	#小时,12小时制
\S	#分号
\s	#秒,数字显示
\t	#tab键
\U	#客户端用户名和主机
\u	#客户端用户名
\v	#服务端版本
\w	#星期几,英文显示
\Y	#年份,四位,数字显示
\y	#年份,两位,数字显示

范例:执行 SQL 脚本

bash 复制代码
[root@localhost ~]# vim test.sql
show databases;

mysql> \. /root/test.sql
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

范例:重连

bash 复制代码
[root@localhost ~]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 19
Server version: 8.0.26 Source distribution

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> \r
Connection id:    20
Current database: *** NONE ***

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> \r
Connection id:    21
Current database: mysql

mysql>

范例:往文件中保存输出结果

bash 复制代码
mysql> tee db.txt                 #设置写到文件db.txt
Logging to file 'db.txt'
mysql> select version();          #执行SQL语句
+-----------+
| version() |
+-----------+
| 8.0.26    |
+-----------+
1 row in set (0.00 sec)

mysql> \t                        #设置不写文件
Outfile disabled.

mysql> show databases;          #执行SQL语句
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

mysql> quit                     #退出
Bye
[root@localhost ~]# cat db.txt         #只记录了\t之前的命令
mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.26    |
+-----------+
1 row in set (0.00 sec)

mysql> \t
[root@localhost ~]#

范例:自定义

bash 复制代码
#两条查询语句,默认用;分隔
mysql> select version();show databases;
+-----------+
| version() |
+-----------+
| 8.0.26    |
+-----------+
1 row in set (0.00 sec)

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.01 sec)


#设置$分隔
mysql> \d $

mysql> select version()$show databases$
+-----------+
| version() |
+-----------+
| 8.0.26    |
+-----------+
1 row in set (0.01 sec)

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

范例:发送语句到服务端

bash 复制代码
mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.26    |
+-----------+
1 row in set (0.01 sec)

mysql> select version()\g
+-----------+
| version() |
+-----------+
| 8.0.26    |
+-----------+
1 row in set (0.00 sec)

mysql> select version()\G
*************************** 1. row ***************************
version(): 8.0.26
1 row in set (0.00 sec)

#开启长命令格式
[root@localhost ~]# mysql --named-commands
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 26
Server version: 8.0.26 Source distribution

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> select version()        #这里要断句
    -> go
+-----------+
| version() |
+-----------+
| 8.0.26    |
+-----------+
1 row in set (0.00 sec)

mysql> select version()       #这里要断句
    -> ego
*************************** 1. row ***************************
version(): 8.0.26
1 row in set (0.00 sec)

范例:只输出不执行

bash 复制代码
mysql> select version()\p
--------------
select version()
--------------

    ->
mysqladmin 工具

mysqladmin 也是用于管理 MySQL 服务的本地工具

格式

bash 复制代码
[root@localhost ~]# mysqladmin --help
mysqladmin  Ver 8.0.26 for Linux on x86_64 (Source distribution)
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.

Administration program for the mysqld daemon.
Usage: mysqladmin [OPTIONS] command command....
  --bind-address=name IP address to bind to.
  -c, --count=#       Number of iterations to make. This works with -i         #总共执行多少次,配合-i选项使用
                      (--sleep) only.
  -#, --debug[=#]     This is a non-debug version. Catch this and exit.
  --debug-check       This is a non-debug version. Catch this and exit.
  --debug-info        This is a non-debug version. Catch this and exit.
  -f, --force         Don't ask for confirmation on drop database; with
                      multiple commands, continue even if an error occurs.
  -C, --compress      Use compression in server/client protocol.           #启用压缩
  --character-sets-dir=name
                      Directory for character set files.
  --default-character-set=name
                      Set the default character set.
  -?, --help          Display this help and exit.            #显示帮助信息
  -h, --host=name     Connect to host.                       #指定服务器地址
  -b, --no-beep       Turn off beep on error.
  -p, --password[=name]                                      #指定连接服务器的密码
                      Password to use when connecting to server. If password is
                      not given it's asked from the tty.
  -P, --port=#        Port number to use for connection or 0 for default to, in    #指定服务器端口,默认3306
                      order of preference, my.cnf, $MYSQL_TCP_PORT,
                      /etc/services, built-in default (3306).
  --protocol=name     The protocol to use for connection (tcp, socket, pipe,       #指定连接方式(tcp\socket\pipe\memory)
                      memory).
  -r, --relative      Show difference between current and previous values when
                      used with -i. Currently only works with extended-status.
  -s, --silent        Silently exit if one can't connect to server.        #如果无法连接,则静默退出
  -S, --socket=name   The socket file to use for connection.               #指定连接时使用socket文件
  -i, --sleep=#       Execute commands repeatedly with a sleep between.   #持续执行命令,间隔N秒执行一次
  --ssl-mode=name     SSL connection mode.
  --ssl-ca=name       CA file in PEM format.
  --ssl-capath=name   CA directory.
  --ssl-cert=name     X509 cert in PEM format.
  --ssl-cipher=name   SSL cipher to use.
  --ssl-key=name      X509 key in PEM format.
  --ssl-crl=name      Certificate revocation list.
  --ssl-crlpath=name  Certificate revocation list path.
  --tls-version=name  TLS version to use, permitted values are: TLSv1, TLSv1.1,
                      TLSv1.2, TLSv1.3
  --ssl-fips-mode=name
                      SSL FIPS mode (applies only for OpenSSL); permitted
                      values are: OFF, ON, STRICT
  --tls-ciphersuites=name
                      TLS v1.3 cipher to use.
  --server-public-key-path=name
                      File path to the server public RSA key in PEM format.
  --get-server-public-key
                      Get server public key
  -u, --user=name     User for login if not current user.             #指定用户名
  -v, --verbose       Write more information.              
  -V, --version       Output version information and exit.             #显示客户端版本
  -E, --vertical      Print output vertically. Is similar to --relative, but
                      prints output vertically.
  -w, --wait[=#]      Wait and retry if connection is down.           #如果连接失败,是否等待重试,如果指定了具体数字,则表示重试几次
  --connect-timeout=#                                          #指定连接超时时长
  --shutdown-timeout=#                                         #指定关机超时时长
  --plugin-dir=name   Directory for client-side plugins.       #客户端插件目录
  --default-auth=name Default authentication client-side plugin to use.
  --enable-cleartext-plugin
                      Enable/disable the clear text authentication plugin.
  --show-warnings     Show warnings after execution
  --compression-algorithms=name
                      Use compression algorithm in server/client protocol.
                      Valid values are any combination of
                      'zstd','zlib','uncompressed'.
  --zstd-compression-level=#
                      Use this compression level in the client/server protocol,
                      in case --compression-algorithms=zstd. Valid range is
                      between 1 and 22, inclusive. Default is 3.

Variables (--variable-name=value)
and boolean options {FALSE|TRUE}  Value (after reading options)
--------------------------------- ----------------------------------------
bind-address                      (No default value)
count                             0
force                             FALSE
compress                          FALSE
character-sets-dir                (No default value)
default-character-set             auto
host                              (No default value)
no-beep                           FALSE
port                              0
relative                          FALSE
socket                            (No default value)
sleep                             0
ssl-ca                            (No default value)
ssl-capath                        (No default value)
ssl-cert                          (No default value)
ssl-cipher                        (No default value)
ssl-key                           (No default value)
ssl-crl                           (No default value)
ssl-crlpath                       (No default value)
tls-version                       (No default value)
tls-ciphersuites                  (No default value)
server-public-key-path            (No default value)
get-server-public-key             FALSE
user                              (No default value)
verbose                           FALSE
vertical                          FALSE
connect-timeout                   43200
shutdown-timeout                  3600
plugin-dir                        (No default value)
default-auth                      (No default value)
enable-cleartext-plugin           FALSE
show-warnings                     FALSE
compression-algorithms            (No default value)
zstd-compression-level            3

Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf
The following groups are read: mysqladmin client
The following options may be given as the first argument:
--print-defaults        Print the program argument list and exit.            #显示运行参数
--no-defaults           Don't read default options from any option file,
                        except for login file. 
--defaults-file=#       Only read default options from the given file #.      #从指定文件中读取选项
--defaults-extra-file=# Read this file after the global files are read.
--defaults-group-suffix=#
                        Also read groups with concat(group, suffix)
--login-path=#          Read this path from the login file.

Where command is a one or more of: (Commands may be shortened)
  create databasename   Create a new database                  #创建新的数据库
  debug                 Instruct server to write debug information to log      #开启调试模式,将调试信息写入log
  drop databasename     Delete a database and all its tables       #删除指定数据库
  extended-status       Gives an extended status message from the server       #显示扩展状态
  flush-hosts           Flush all cached hosts                 #刷新所有缓存的主机
  flush-logs            Flush all logs                         #刷新所有日志    
  flush-status          Clear status variables                 #刷新状态变量
  flush-tables          Flush all tables                       #刷新所有表,会强制关闭已打开的表
  flush-threads         Flush the thread cache                 #刷新线程缓存
  flush-privileges      Reload grant tables (same as reload)   #刷新访问权限                
  kill id,id,...        Kill mysql threads
  password [new-password] Change old password to new-password in current format    #修改密码
  ping                  Check if mysqld is alive               #心跳检测
  processlist           Show list of active threads in server  #显示活动线程列表
  reload                Reload grant tables                    #刷新授权信息
  refresh               Flush all tables and close and open logfiles   #刷新所有数据库表,重新打开日志文件
  shutdown              Take server down                       #关闭服务
  status                Gives a short status message from the server      #简短显示服务端状态
  start-replica         Start replication                     
  start-slave           Deprecated: use start-replica instead            #开启主从同步
  stop-replica          Stop replication       
  stop-slave            Deprecated: use stop-replica instead             #停止主从同步
  variables             Prints variables available                       #显示服务端所有变量
  version               Get version info from server                     #显示客户端和服务端版本

范例:显示版本信息

bash 复制代码
#客户端版本
[root@localhost ~]# mysqladmin -V            
mysqladmin  Ver 8.0.26 for Linux on x86_64 (Source distribution)

#客户端和服务端版本信息
[root@localhost ~]# mysqladmin version
mysqladmin  Ver 8.0.26 for Linux on x86_64 (Source distribution)
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.

Server version          8.0.26
Protocol version        10
Connection              Localhost via UNIX socket
UNIX socket             /var/lib/mysql/mysql.sock
Uptime:                 1 hour 44 min 34 sec

Threads: 4  Questions: 189  Slow queries: 0  Opens: 287  Flush tables: 3  Open tables: 206  Queries per second avg: 0.030

范例:显示状态信息

bash 复制代码
[root@localhost ~]# mysqladmin status
Uptime: 6352  Threads: 4  Questions: 191  Slow queries: 0  Opens: 287  Flush tables: 3  Open tables: 206  Queries per second avg: 0.030

范例:设置连接超时

bash 复制代码
[root@localhost ~]# mysqladmin -h1.2.3.4 --connect-timeout=2 ping
mysqladmin: connect to server at '1.2.3.4' failed
error: 'Can't connect to MySQL server on '1.2.3.4:3306' (110)'
Check that mysqld is running on 1.2.3.4 and that the port is 3306.
You can check this by doing 'telnet 1.2.3.4 3306'
[root@localhost ~]# echo $?
1

#静默退出,不输出错误信息
[root@localhost ~]# mysqladmin -h1.2.3.4 --connect-timeout=2 -s ping
[root@localhost ~]# echo $?
1

范例:持续执行

bash 复制代码
#每秒执行一次ping命令,一直执行下去
[root@localhost ~]# mysqladmin -i 1 ping
mysqld is alive
mysqld is alive
mysqld is alive
......

#每秒执行一次ping命令,总共执行3次
[root@localhost ~]# mysqladmin -i 1 -c 3 ping
mysqld is alive
mysqld is alive
mysqld is alive

范例:关闭服务

bash 复制代码
#mysqladmin只能关闭服务,不能启动服务
[root@localhost ~]# mysqladmin shutdown

[root@localhost ~]# mysqladmin ping
mysqladmin: connect to server at 'localhost' failed
error: 'Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)'
Check that mysqld is running and that the socket: '/var/lib/mysql/mysql.sock' exists!

[root@localhost ~]# echo $?
1

[root@localhost ~]# systemctl start mysqld

范例:创建数据库和删除数据库

bash 复制代码
#创建
[root@localhost ~]# mysqladmin create mysqladmin-db1
[root@localhost ~]# mysqladmin create mysqladmin-db2
[root@localhost ~]# mysql -e 'show databases'
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| mysqladmin-db1     |
| mysqladmin-db2     |
| performance_schema |
| sys                |
+--------------------+

#删除
[root@localhost ~]# mysqladmin drop mysqladmin-db1
Dropping the database is potentially a very bad thing to do.
Any data stored in the database will be destroyed.

Do you really want to drop the 'mysqladmin-db1' database [y/N] y      #回答y确认
Database "mysqladmin-db1" dropped

[root@localhost ~]# mysqladmin -f drop mysqladmin-db2      #强制删除,不需要确认
Database "mysqladmin-db2" dropped

[root@localhost ~]# mysql -e 'show databases'     #验证mysqladmin-db1和mysqladmin-db2已经删除
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
[root@localhost ~]#

范例:修改连接密码

bash 复制代码
#旧密码为空,root用户,localhost主机连接
[root@localhost ~]# mysqladmin password 123456             #设置密码为123456
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
Warning: Since password will be sent to server in plain text, use ssl connection to ensure password safety.

[root@localhost ~]# mysqladmin ping                  #不使用密码不行
mysqladmin: connect to server at 'localhost' failed
error: 'Access denied for user 'root'@'localhost' (using password: NO)'

[root@localhost ~]# mysqladmin -uroot -hlocalhost -p123456 ping       #使用密码123456
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
mysqld is alive

#用旧密码修改新密码
[root@localhost ~]# mysqladmin -uroot -p123456 -hlocalhost password abcde      #更改密码为abcde
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
Warning: Since password will be sent to server in plain text, use ssl connection to ensure password safety.

[root@localhost ~]# mysqladmin -uroot -p123456 -hlocalhost ping         #使用原密码测试不行
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
mysqladmin: connect to server at 'localhost' failed
error: 'Access denied for user 'root'@'localhost' (using password: YES)'

[root@localhost ~]# mysqladmin -uroot -pabcde -hlocalhost ping       #使用新密码测试
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
mysqld is alive
mycli 工具

MyCLI 是基于 Python 开发的 MySQL 命令行工具,具有自动完成和语法高亮显示功能

bash 复制代码
[root@localhost ~]# yum install -y python39
[root@localhost ~]# pip3.9 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
Writing to /root/.config/pip/pip.conf
[root@localhost ~]# pip3 install mycli==1.2.0

#使用
[root@localhost ~]# mycli -uroot -pabcde
Connecting to socket /var/lib/mysql/mysql.sock, owned by user mysql
MySQL
mycli 1.38.4
Home: http://mycli.net
Bug tracker: https://github.com/dbcli/mycli/issues
Thanks to the contributor - Artem Bezsmertnyi
MySQL root@(none):(none)>

SQL 语言

关系型数据库的构成

组件 关键字 说明
数据库 database 表的集合,一个数据库中可以有多个表,在文件系统中表出就是一个目录
table 在数据库中以二维表的形式出现,有行和列,数据库中的数据就是存放于表中的
索引 index 索引通常建立在一个列上,用以加快数据查询速度
视图 view 用SQL语言构建的虚拟表,可以临时把两个或多个表以逻辑关系关联上,对外提供查询
存储过程 procedure 存储过程是一组为了完成特定功能的SQL语句集合,客户端可以直接调用
存储函数 function 存储函数和存储过程一样,都是SQL语句集合,但可以使用参数
触发器 tigger 触发器也是有SQL语句的集合组成,但需要达到触发条件才能调用
事件调度器 event scheduler 数据库中的计划任务
用户 user 连接服务端时的用户名
权限 privilege 每个用户可以对哪些数据库或表进行操作,在什么IP能连接

SQL 语言介绍

SQL:(Structured Query Language)结构化查询语言。

  • SQL 语言是对 IBM 公司 San Jose, California 研究实验室的埃德加·科德的关系模型的第一个商业化语言实现。尽管 SQL 并非完全按照科德的关系模型设计,但其依然成为最为广泛运用的数据库语言
  • 1970 年代初,由埃德加·科德发表将资料组成表格的应用原则(Codd's Relational Algebra)。
  • 1974 年,同一实验室的 D.D.Chamberlin 和 R.F.Boyce 对 Codd's Relational Algebra 在研制关系数据库管理系统 System R 中,研制出一套规范语言 SEQUEL(Structured English Query Language)。
  • 1976 年 11 月的 IBM Journal of R&D 上公布新版本的 SQL(叫 SEQUEL/2)。1980 年改名为 SQL。
  • 1979 年 ORACLE 公司首先提供商用的 SQL,IBM 公司在 DB2 和 SQL/DS 数据库系统中也实现了 SQL。
  • 1986 年 10 月美国国家标准学会 ANSI 采用 SQL 作为关系数据库管理系统的标准语言(ANSI X3.135-1986)。
  • 1987 年成为国际标准化组织(ISO)采纳为国际标准。
  • 1989 年美国 ANSI 采纳在 ANSI X3.135-1989 报告中定义的关系数据库管理系统的 SQL 标准语言,称为 ANSI SQL 89。
  • 后续 SQL 标准经过了一系列的增订,加入了大量新特性,有各种版本:ANSI SQL、SQL-1986、SQL-1989、SQL-1992、SQL-1999、SQL-2003、SQL-2008、SQL-2011。
  • 目前,所有主要的关系数据库管理系统支持某些形式的 SQL,大部分数据库至少遵守 ANSI SQL 89 标准。
  • 虽然有这一标准的存在,但大部分的 SQL 代码在不同的数据库系统中并不具有完全的跨平台性。
  • 业内标准:微软和 Sybase 的 T-SQL,Oracle 的 PL/SQL。

SQL 语言规范

  • 在数据库系统中,SQL 语句不区分大小写,建议用大写。
  • SQL 语句可单行或多行书写,默认以 结尾。
  • 关键词不能跨多行或简写。
  • 用空格和 TAB 缩进来提高语句的可读性。
  • 子句通常位于独立行,便于编辑,提高可读性。
bash 复制代码
#不区分大小写
mysql> select @@hostname;
+-----------------------+
| @@hostname            |
+-----------------------+
| localhost.localdomain |
+-----------------------+
1 row in set (0.00 sec)

mysql> SELect @@HOSTname;
+-----------------------+
| @@HOSTname            |
+-----------------------+
| localhost.localdomain |
+-----------------------+
1 row in set (0.00 sec)

#区分大小写
mysql> SELect user,host from mysql.user;
+------------------+-----------+
| user             | host      |
+------------------+-----------+
| mysql.infoschema | localhost |
| mysql.session    | localhost |
| mysql.sys        | localhost |
| root             | localhost |
+------------------+-----------+
4 rows in set (0.01 sec)

mysql> SELect user,host from mysql.USER;
ERROR 1146 (42S02): Table 'mysql.USER' doesn't exist
mysql> SELect user,HOST from mysql.USER;
ERROR 1146 (42S02): Table 'mysql.USER' doesn't exist

#字段不区分大小写,库名表名区分大小写
mysql> SELect user,HOST from mysql.user;
+------------------+-----------+
| user             | HOST      |
+------------------+-----------+
| mysql.infoschema | localhost |
| mysql.session    | localhost |
| mysql.sys        | localhost |
| root             | localhost |
+------------------+-----------+

范例:跨行

bash 复制代码
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.01 sec)

mysql> show
    -> databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

#关键字不能跨行
mysql> show data
    -> bases;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'data
bases' at line 1

SQL 语言中的注释

SQL 语言中的标准注释

mysql 复制代码
-- select version()\G       #单行注释
/*                            #多行注释
select version()\G
select version()\G
*/
select version()\G

范例:

sql 复制代码
[root@localhost ~]# vim test.sql
-- select version()\G
/*
select version()\G
select version()\G
*/
select version()\G

[root@localhost ~]# mysql < test.sql
*************************** 1. row ***************************
version(): 8.0.26

MySQL 中的注释

bash 复制代码
# select version()\G;           #MySQL中的注释
select version()\G;

范例:

bash 复制代码
[root@localhost ~]# cat test.sql
# select version()\G;
# select version()\G;
select version()\G;

[root@localhost ~]# mysql < test.sql
*************************** 1. row ***************************
version(): 8.0.26

数据库对象和命名

数据库中的组件(对象)

bash 复制代码
数据库、表、索引、视图、用户、存储过程、函数、触发器、事件调度器等

组件命名规则

  • 可以包括字母、数字和三个特殊字符(#_$)
  • 不能使用 MySQL 的保留字

SQL 语句分类

SQL语句类型 说明 具体语句
DDL Data Defination Language数据定义语言 CREATE,DROP,ALTER
DML Data Mainpulation Language数据操纵语言 INSERT,DELETE,UPDATE
DQL Data Query Language数据查询语言 SELECT
DCL Data Control Language数据控制语言 GRANT,REVOKE
TCL Transaction Control Language事务控制语言 BEGIN,COMMIT,ROLLBACK,SAVEPOINT

DDL:定义结构(建库、建表、删表)

DML:操作表中数据(增、删、改)

DQL:查询表中数据(SELECT)

DCL:权限控制(授权、收权)

TCL:事务控制(提交、回滚)

SQL 语句构成

关键字 keyword 组成子句 clause,多条 clause 组成语句

mysql 复制代码
mysql> SELECT host,user,authentication_string FROM mysql.user WHERE authentication_string = '';
+-----------+------+-----------------------+
| host      | user | authentication_string |
+-----------+------+-----------------------+
| localhost | root |                       |
+-----------+------+-----------------------+
1 row in set (0.00 sec)

说明:

bash 复制代码
SELECT host,user,authentication_string        #select子句
FROM mysql.user                               #from子句
WHERE authentication_string = '';             #where子句

命令行下查看帮助

mysql 复制代码
mysql> help contents;
You asked for help about help category: "Contents"
For more information, type 'help <item>', where <item> is one of the following
categories:
   Account Management
   Administration
   Components
   Compound Statements
   Contents
   Data Definition
   Data Manipulation
   Data Types
   Functions
   Geographic Features
   Help Metadata
   Language Structure
   Loadable Functions
   Plugins
   Prepared Statements
   Replication Statements
   Storage Engines
   Table Maintenance
   Transactions
   Utility

mysql> help Data Definition         #查看DDL帮助
You asked for help about help category: "Data Definition"
For more information, type 'help <item>', where <item> is one of the following
topics:
   ALTER DATABASE
   ALTER EVENT
   ALTER FUNCTION
   ALTER INSTANCE
   ALTER LOGFILE GROUP
   ALTER PROCEDURE
   ALTER SCHEMA
   ALTER SERVER
   ALTER TABLE
   ALTER TABLESPACE
   ALTER VIEW
   CREATE DATABASE
   CREATE EVENT
   CREATE FUNCTION
   CREATE INDEX
   CREATE LOGFILE GROUP
   CREATE PROCEDURE
   CREATE SCHEMA
   CREATE SERVER
   CREATE SPATIAL REFERENCE SYSTEM
   CREATE TABLE
   CREATE TABLESPACE
   CREATE TRIGGER
   CREATE VIEW
   DROP DATABASE
   DROP EVENT
   DROP FUNCTION
   DROP INDEX
   DROP PROCEDURE
   DROP SCHEMA
   DROP SERVER
   DROP SPATIAL REFERENCE SYSTEM
   DROP TABLE
   DROP TABLESPACE
   DROP TRIGGER
   DROP VIEW
   FOREIGN KEY
   RENAME TABLE
   TRUNCATE TABLE

mysql> help CREATE DATABASE;
Name: 'CREATE DATABASE'
Description:
Syntax:
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
    [create_option] ...

create_option: [DEFAULT] {
    CHARACTER SET [=] charset_name
  | COLLATE [=] collation_name
  | ENCRYPTION [=] {'Y' | 'N'}
}

CREATE DATABASE creates a database with the given name. To use this
statement, you need the CREATE privilege for the database. CREATE
SCHEMA is a synonym for CREATE DATABASE.

URL: https://dev.mysql.com/doc/refman/8.0/en/create-database.html

字符集和排序

早期 MySQL 版本默认为 latin1,从 MySQL 8.0 开始默认字符集已经为 utf8mb4

查看当前版本可用的字符集

mysql 复制代码
mysql> show CHARACTER SET;                #查看所有支持的字符集
+----------+---------------------------------+---------------------+--------+
| Charset  | Description                     | Default collation   | Maxlen |
+----------+---------------------------------+---------------------+--------+
| armscii8 | ARMSCII-8 Armenian              | armscii8_general_ci |      1 |
| ascii    | US ASCII                        | ascii_general_ci    |      1 |
| big5     | Big5 Traditional Chinese        | big5_chinese_ci     |      2 |
| binary   | Binary pseudo charset           | binary              |      1 |
| cp1250   | Windows Central European        | cp1250_general_ci   |      1 |
| cp1251   | Windows Cyrillic                | cp1251_general_ci   |      1 |
| cp1256   | Windows Arabic                  | cp1256_general_ci   |      1 |
| cp1257   | Windows Baltic                  | cp1257_general_ci   |      1 |
| cp850    | DOS West European               | cp850_general_ci    |      1 |
| cp852    | DOS Central European            | cp852_general_ci    |      1 |
| cp866    | DOS Russian                     | cp866_general_ci    |      1 |
| cp932    | SJIS for Windows Japanese       | cp932_japanese_ci   |      2 |
| dec8     | DEC West European               | dec8_swedish_ci     |      1 |
| eucjpms  | UJIS for Windows Japanese       | eucjpms_japanese_ci |      3 |
| euckr    | EUC-KR Korean                   | euckr_korean_ci     |      2 |
| gb18030  | China National Standard GB18030 | gb18030_chinese_ci  |      4 |
| gb2312   | GB2312 Simplified Chinese       | gb2312_chinese_ci   |      2 |
| gbk      | GBK Simplified Chinese          | gbk_chinese_ci      |      2 |
| geostd8  | GEOSTD8 Georgian                | geostd8_general_ci  |      1 |
| greek    | ISO 8859-7 Greek                | greek_general_ci    |      1 |
| hebrew   | ISO 8859-8 Hebrew               | hebrew_general_ci   |      1 |
| hp8      | HP West European                | hp8_english_ci      |      1 |
| keybcs2  | DOS Kamenicky Czech-Slovak      | keybcs2_general_ci  |      1 |
| koi8r    | KOI8-R Relcom Russian           | koi8r_general_ci    |      1 |
| koi8u    | KOI8-U Ukrainian                | koi8u_general_ci    |      1 |
| latin1   | cp1252 West European            | latin1_swedish_ci   |      1 |
| latin2   | ISO 8859-2 Central European     | latin2_general_ci   |      1 |
| latin5   | ISO 8859-9 Turkish              | latin5_turkish_ci   |      1 |
| latin7   | ISO 8859-13 Baltic              | latin7_general_ci   |      1 |
| macce    | Mac Central European            | macce_general_ci    |      1 |
| macroman | Mac West European               | macroman_general_ci |      1 |
| sjis     | Shift-JIS Japanese              | sjis_japanese_ci    |      2 |
| swe7     | 7bit Swedish                    | swe7_swedish_ci     |      1 |
| tis620   | TIS620 Thai                     | tis620_thai_ci      |      1 |
| ucs2     | UCS-2 Unicode                   | ucs2_general_ci     |      2 |
| ujis     | EUC-JP Japanese                 | ujis_japanese_ci    |      3 |
| utf16    | UTF-16 Unicode                  | utf16_general_ci    |      4 |
| utf16le  | UTF-16LE Unicode                | utf16le_general_ci  |      4 |
| utf32    | UTF-32 Unicode                  | utf32_general_ci    |      4 |
| utf8     | UTF-8 Unicode                   | utf8_general_ci     |      3 |
| utf8mb4  | UTF-8 Unicode                   | utf8mb4_0900_ai_ci  |      4 |
+----------+---------------------------------+---------------------+--------+
41 rows in set (0.00 sec)
 
mysql> show CHARSET;                #查看所有支持的字符集

查看当前默认字符集

bash 复制代码
mysql> show variables like 'character%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8mb4                    |
| character_set_connection | utf8mb4                    |
| character_set_database   | utf8mb4                    |
| character_set_filesystem | binary                     |
| character_set_results    | utf8mb4                    |
| character_set_server     | utf8mb4                    |
| character_set_system     | utf8mb3                    |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.01 sec)

修改 mysql-server 的默认字符集

bash 复制代码
[root@localhost ~]# vim /etc/my.cnf.d/mysql-server.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysql/mysqld.log
pid-file=/run/mysqld/mysqld.pid
character-set-server=latin1                #新加一行

[root@localhost ~]# vim /etc/my.cnf.d/client.cnf
[client]
default-character-set=latin1               #新加一ha

[root@localhost ~]# systemctl restart mysqld        #重启服务

mysql> show variables like 'character%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |
| character_set_connection | latin1                     |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | latin1                     |
| character_set_server     | latin1                     |
| character_set_system     | utf8mb3                    |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

#再改回来,或者还原快照

查看当前版本可用的排序规则

bash 复制代码
mysql> SHOW COLLATION;
+----------------------------+----------+-----+---------+----------+---------+---------------+
| Collation                  | Charset  | Id  | Default | Compiled | Sortlen | Pad_attribute |
+----------------------------+----------+-----+---------+----------+---------+---------------+
| armscii8_bin               | armscii8 |  64 |         | Yes      |       1 | PAD SPACE     |
| armscii8_general_ci        | armscii8 |  32 | Yes     | Yes      |       1 | PAD SPACE     |
| ascii_bin                  | ascii    |  65 |         | Yes      |       1 | PAD SPACE     |
| ascii_general_ci           | ascii    |  11 | Yes     | Yes      |       1 | PAD SPACE     |
| big5_bin                   | big5     |  84 |         | Yes      |       1 | PAD SPACE     |
| big5_chinese_ci            | big5     |   1 | Yes     | Yes      |       1 | PAD SPACE     |
| binary                     | binary   |  63 | Yes     | Yes      |       1 | NO PAD        |
| cp1250_bin                 | cp1250   |  66 |         | Yes      |       1 | PAD SPACE     |
| cp1250_croatian_ci         | cp1250   |  44 |         | Yes      |       1 | PAD SPACE     |
| cp1250_czech_cs            | cp1250   |  34 |         | Yes      |       2 | PAD SPACE     |
| cp1250_general_ci          | cp1250   |  26 | Yes     | Yes      |       1 | PAD SPACE     |
| cp1250_polish_ci           | cp1250   |  99 |         | Yes      |       1 | PAD SPACE     |
| cp1251_bin                 | cp1251   |  50 |         | Yes      |       1 | PAD SPACE     |
| cp1251_bulgarian_ci        | cp1251   |  14 |         | Yes      |       1 | PAD SPACE     |
| cp1251_general_ci          | cp1251   |  51 | Yes     | Yes      |       1 | PAD SPACE     |
| cp1251_general_cs          | cp1251   |  52 |         | Yes      |       1 | PAD SPACE     |
| cp1251_ukrainian_ci        | cp1251   |  23 |         | Yes      |       1 | PAD SPACE     |
| cp1256_bin                 | cp1256   |  67 |         | Yes      |       1 | PAD SPACE     |
| cp1256_general_ci          | cp1256   |  57 | Yes     | Yes      |       1 | PAD SPACE     |
| cp1257_bin                 | cp1257   |  58 |         | Yes      |       1 | PAD SPACE     |
| cp1257_general_ci          | cp1257   |  59 | Yes     | Yes      |       1 | PAD SPACE     |
| cp1257_lithuanian_ci       | cp1257   |  29 |         | Yes      |       1 | PAD SPACE     |
| cp850_bin                  | cp850    |  80 |         | Yes      |       1 | PAD SPACE     |
| cp850_general_ci           | cp850    |   4 | Yes     | Yes      |       1 | PAD SPACE     |
| cp852_bin                  | cp852    |  81 |         | Yes      |       1 | PAD SPACE     |
| cp852_general_ci           | cp852    |  40 | Yes     | Yes      |       1 | PAD SPACE     |
| cp866_bin                  | cp866    |  68 |         | Yes      |       1 | PAD SPACE     |
| cp866_general_ci           | cp866    |  36 | Yes     | Yes      |       1 | PAD SPACE     |
| cp932_bin                  | cp932    |  96 |         | Yes      |       1 | PAD SPACE     |
| cp932_japanese_ci          | cp932    |  95 | Yes     | Yes      |       1 | PAD SPACE     |
| dec8_bin                   | dec8     |  69 |         | Yes      |       1 | PAD SPACE     |
| dec8_swedish_ci            | dec8     |   3 | Yes     | Yes      |       1 | PAD SPACE     |
| eucjpms_bin                | eucjpms  |  98 |         | Yes      |       1 | PAD SPACE     |
| eucjpms_japanese_ci        | eucjpms  |  97 | Yes     | Yes      |       1 | PAD SPACE     |
| euckr_bin                  | euckr    |  85 |         | Yes      |       1 | PAD SPACE     |
| euckr_korean_ci            | euckr    |  19 | Yes     | Yes      |       1 | PAD SPACE     |
| gb18030_bin                | gb18030  | 249 |         | Yes      |       1 | PAD SPACE     |
| gb18030_chinese_ci         | gb18030  | 248 | Yes     | Yes      |       2 | PAD SPACE     |
| gb18030_unicode_520_ci     | gb18030  | 250 |         | Yes      |       8 | PAD SPACE     |
| gb2312_bin                 | gb2312   |  86 |         | Yes      |       1 | PAD SPACE     |
| gb2312_chinese_ci          | gb2312   |  24 | Yes     | Yes      |       1 | PAD SPACE     |
| gbk_bin                    | gbk      |  87 |         | Yes      |       1 | PAD SPACE     |
| gbk_chinese_ci             | gbk      |  28 | Yes     | Yes      |       1 | PAD SPACE     |
| geostd8_bin                | geostd8  |  93 |         | Yes      |       1 | PAD SPACE     |
| geostd8_general_ci         | geostd8  |  92 | Yes     | Yes      |       1 | PAD SPACE     |
| greek_bin                  | greek    |  70 |         | Yes      |       1 | PAD SPACE     |
| greek_general_ci           | greek    |  25 | Yes     | Yes      |       1 | PAD SPACE     |
| hebrew_bin                 | hebrew   |  71 |         | Yes      |       1 | PAD SPACE     |
| hebrew_general_ci          | hebrew   |  16 | Yes     | Yes      |       1 | PAD SPACE     |
| hp8_bin                    | hp8      |  72 |         | Yes      |       1 | PAD SPACE     |
| hp8_english_ci             | hp8      |   6 | Yes     | Yes      |       1 | PAD SPACE     |
| keybcs2_bin                | keybcs2  |  73 |         | Yes      |       1 | PAD SPACE     |
| keybcs2_general_ci         | keybcs2  |  37 | Yes     | Yes      |       1 | PAD SPACE     |
| koi8r_bin                  | koi8r    |  74 |         | Yes      |       1 | PAD SPACE     |
| koi8r_general_ci           | koi8r    |   7 | Yes     | Yes      |       1 | PAD SPACE     |
| koi8u_bin                  | koi8u    |  75 |         | Yes      |       1 | PAD SPACE     |
| koi8u_general_ci           | koi8u    |  22 | Yes     | Yes      |       1 | PAD SPACE     |
| latin1_bin                 | latin1   |  47 |         | Yes      |       1 | PAD SPACE     |
| latin1_danish_ci           | latin1   |  15 |         | Yes      |       1 | PAD SPACE     |
| latin1_general_ci          | latin1   |  48 |         | Yes      |       1 | PAD SPACE     |
| latin1_general_cs          | latin1   |  49 |         | Yes      |       1 | PAD SPACE     |
| latin1_german1_ci          | latin1   |   5 |         | Yes      |       1 | PAD SPACE     |
| latin1_german2_ci          | latin1   |  31 |         | Yes      |       2 | PAD SPACE     |
| latin1_spanish_ci          | latin1   |  94 |         | Yes      |       1 | PAD SPACE     |
| latin1_swedish_ci          | latin1   |   8 | Yes     | Yes      |       1 | PAD SPACE     |
| latin2_bin                 | latin2   |  77 |         | Yes      |       1 | PAD SPACE     |
| latin2_croatian_ci         | latin2   |  27 |         | Yes      |       1 | PAD SPACE     |
| latin2_czech_cs            | latin2   |   2 |         | Yes      |       4 | PAD SPACE     |
| latin2_general_ci          | latin2   |   9 | Yes     | Yes      |       1 | PAD SPACE     |
| latin2_hungarian_ci        | latin2   |  21 |         | Yes      |       1 | PAD SPACE     |
| latin5_bin                 | latin5   |  78 |         | Yes      |       1 | PAD SPACE     |
| latin5_turkish_ci          | latin5   |  30 | Yes     | Yes      |       1 | PAD SPACE     |
| latin7_bin                 | latin7   |  79 |         | Yes      |       1 | PAD SPACE     |
| latin7_estonian_cs         | latin7   |  20 |         | Yes      |       1 | PAD SPACE     |
| latin7_general_ci          | latin7   |  41 | Yes     | Yes      |       1 | PAD SPACE     |
| latin7_general_cs          | latin7   |  42 |         | Yes      |       1 | PAD SPACE     |
| macce_bin                  | macce    |  43 |         | Yes      |       1 | PAD SPACE     |
| macce_general_ci           | macce    |  38 | Yes     | Yes      |       1 | PAD SPACE     |
| macroman_bin               | macroman |  53 |         | Yes      |       1 | PAD SPACE     |
| macroman_general_ci        | macroman |  39 | Yes     | Yes      |       1 | PAD SPACE     |
| sjis_bin                   | sjis     |  88 |         | Yes      |       1 | PAD SPACE     |
| sjis_japanese_ci           | sjis     |  13 | Yes     | Yes      |       1 | PAD SPACE     |
| swe7_bin                   | swe7     |  82 |         | Yes      |       1 | PAD SPACE     |
| swe7_swedish_ci            | swe7     |  10 | Yes     | Yes      |       1 | PAD SPACE     |
| tis620_bin                 | tis620   |  89 |         | Yes      |       1 | PAD SPACE     |
| tis620_thai_ci             | tis620   |  18 | Yes     | Yes      |       4 | PAD SPACE     |
| ucs2_bin                   | ucs2     |  90 |         | Yes      |       1 | PAD SPACE     |
| ucs2_croatian_ci           | ucs2     | 149 |         | Yes      |       8 | PAD SPACE     |
| ucs2_czech_ci              | ucs2     | 138 |         | Yes      |       8 | PAD SPACE     |
| ucs2_danish_ci             | ucs2     | 139 |         | Yes      |       8 | PAD SPACE     |
| ucs2_esperanto_ci          | ucs2     | 145 |         | Yes      |       8 | PAD SPACE     |
| ucs2_estonian_ci           | ucs2     | 134 |         | Yes      |       8 | PAD SPACE     |
| ucs2_general_ci            | ucs2     |  35 | Yes     | Yes      |       1 | PAD SPACE     |
| ucs2_general_mysql500_ci   | ucs2     | 159 |         | Yes      |       1 | PAD SPACE     |
| ucs2_german2_ci            | ucs2     | 148 |         | Yes      |       8 | PAD SPACE     |
| ucs2_hungarian_ci          | ucs2     | 146 |         | Yes      |       8 | PAD SPACE     |
| ucs2_icelandic_ci          | ucs2     | 129 |         | Yes      |       8 | PAD SPACE     |
| ucs2_latvian_ci            | ucs2     | 130 |         | Yes      |       8 | PAD SPACE     |
| ucs2_lithuanian_ci         | ucs2     | 140 |         | Yes      |       8 | PAD SPACE     |
| ucs2_persian_ci            | ucs2     | 144 |         | Yes      |       8 | PAD SPACE     |
| ucs2_polish_ci             | ucs2     | 133 |         | Yes      |       8 | PAD SPACE     |
| ucs2_romanian_ci           | ucs2     | 131 |         | Yes      |       8 | PAD SPACE     |
| ucs2_roman_ci              | ucs2     | 143 |         | Yes      |       8 | PAD SPACE     |
| ucs2_sinhala_ci            | ucs2     | 147 |         | Yes      |       8 | PAD SPACE     |
| ucs2_slovak_ci             | ucs2     | 141 |         | Yes      |       8 | PAD SPACE     |
| ucs2_slovenian_ci          | ucs2     | 132 |         | Yes      |       8 | PAD SPACE     |
| ucs2_spanish2_ci           | ucs2     | 142 |         | Yes      |       8 | PAD SPACE     |
| ucs2_spanish_ci            | ucs2     | 135 |         | Yes      |       8 | PAD SPACE     |
| ucs2_swedish_ci            | ucs2     | 136 |         | Yes      |       8 | PAD SPACE     |
| ucs2_turkish_ci            | ucs2     | 137 |         | Yes      |       8 | PAD SPACE     |
| ucs2_unicode_520_ci        | ucs2     | 150 |         | Yes      |       8 | PAD SPACE     |
| ucs2_unicode_ci            | ucs2     | 128 |         | Yes      |       8 | PAD SPACE     |
| ucs2_vietnamese_ci         | ucs2     | 151 |         | Yes      |       8 | PAD SPACE     |
| ujis_bin                   | ujis     |  91 |         | Yes      |       1 | PAD SPACE     |
| ujis_japanese_ci           | ujis     |  12 | Yes     | Yes      |       1 | PAD SPACE     |
| utf16le_bin                | utf16le  |  62 |         | Yes      |       1 | PAD SPACE     |
| utf16le_general_ci         | utf16le  |  56 | Yes     | Yes      |       1 | PAD SPACE     |
| utf16_bin                  | utf16    |  55 |         | Yes      |       1 | PAD SPACE     |
| utf16_croatian_ci          | utf16    | 122 |         | Yes      |       8 | PAD SPACE     |
| utf16_czech_ci             | utf16    | 111 |         | Yes      |       8 | PAD SPACE     |
| utf16_danish_ci            | utf16    | 112 |         | Yes      |       8 | PAD SPACE     |
| utf16_esperanto_ci         | utf16    | 118 |         | Yes      |       8 | PAD SPACE     |
| utf16_estonian_ci          | utf16    | 107 |         | Yes      |       8 | PAD SPACE     |
| utf16_general_ci           | utf16    |  54 | Yes     | Yes      |       1 | PAD SPACE     |
| utf16_german2_ci           | utf16    | 121 |         | Yes      |       8 | PAD SPACE     |
| utf16_hungarian_ci         | utf16    | 119 |         | Yes      |       8 | PAD SPACE     |
| utf16_icelandic_ci         | utf16    | 102 |         | Yes      |       8 | PAD SPACE     |
| utf16_latvian_ci           | utf16    | 103 |         | Yes      |       8 | PAD SPACE     |
| utf16_lithuanian_ci        | utf16    | 113 |         | Yes      |       8 | PAD SPACE     |
| utf16_persian_ci           | utf16    | 117 |         | Yes      |       8 | PAD SPACE     |
| utf16_polish_ci            | utf16    | 106 |         | Yes      |       8 | PAD SPACE     |
| utf16_romanian_ci          | utf16    | 104 |         | Yes      |       8 | PAD SPACE     |
| utf16_roman_ci             | utf16    | 116 |         | Yes      |       8 | PAD SPACE     |
| utf16_sinhala_ci           | utf16    | 120 |         | Yes      |       8 | PAD SPACE     |
| utf16_slovak_ci            | utf16    | 114 |         | Yes      |       8 | PAD SPACE     |
| utf16_slovenian_ci         | utf16    | 105 |         | Yes      |       8 | PAD SPACE     |
| utf16_spanish2_ci          | utf16    | 115 |         | Yes      |       8 | PAD SPACE     |
| utf16_spanish_ci           | utf16    | 108 |         | Yes      |       8 | PAD SPACE     |
| utf16_swedish_ci           | utf16    | 109 |         | Yes      |       8 | PAD SPACE     |
| utf16_turkish_ci           | utf16    | 110 |         | Yes      |       8 | PAD SPACE     |
| utf16_unicode_520_ci       | utf16    | 123 |         | Yes      |       8 | PAD SPACE     |
| utf16_unicode_ci           | utf16    | 101 |         | Yes      |       8 | PAD SPACE     |
| utf16_vietnamese_ci        | utf16    | 124 |         | Yes      |       8 | PAD SPACE     |
| utf32_bin                  | utf32    |  61 |         | Yes      |       1 | PAD SPACE     |
| utf32_croatian_ci          | utf32    | 181 |         | Yes      |       8 | PAD SPACE     |
| utf32_czech_ci             | utf32    | 170 |         | Yes      |       8 | PAD SPACE     |
| utf32_danish_ci            | utf32    | 171 |         | Yes      |       8 | PAD SPACE     |
| utf32_esperanto_ci         | utf32    | 177 |         | Yes      |       8 | PAD SPACE     |
| utf32_estonian_ci          | utf32    | 166 |         | Yes      |       8 | PAD SPACE     |
| utf32_general_ci           | utf32    |  60 | Yes     | Yes      |       1 | PAD SPACE     |
| utf32_german2_ci           | utf32    | 180 |         | Yes      |       8 | PAD SPACE     |
| utf32_hungarian_ci         | utf32    | 178 |         | Yes      |       8 | PAD SPACE     |
| utf32_icelandic_ci         | utf32    | 161 |         | Yes      |       8 | PAD SPACE     |
| utf32_latvian_ci           | utf32    | 162 |         | Yes      |       8 | PAD SPACE     |
| utf32_lithuanian_ci        | utf32    | 172 |         | Yes      |       8 | PAD SPACE     |
| utf32_persian_ci           | utf32    | 176 |         | Yes      |       8 | PAD SPACE     |
| utf32_polish_ci            | utf32    | 165 |         | Yes      |       8 | PAD SPACE     |
| utf32_romanian_ci          | utf32    | 163 |         | Yes      |       8 | PAD SPACE     |
| utf32_roman_ci             | utf32    | 175 |         | Yes      |       8 | PAD SPACE     |
| utf32_sinhala_ci           | utf32    | 179 |         | Yes      |       8 | PAD SPACE     |
| utf32_slovak_ci            | utf32    | 173 |         | Yes      |       8 | PAD SPACE     |
| utf32_slovenian_ci         | utf32    | 164 |         | Yes      |       8 | PAD SPACE     |
| utf32_spanish2_ci          | utf32    | 174 |         | Yes      |       8 | PAD SPACE     |
| utf32_spanish_ci           | utf32    | 167 |         | Yes      |       8 | PAD SPACE     |
| utf32_swedish_ci           | utf32    | 168 |         | Yes      |       8 | PAD SPACE     |
| utf32_turkish_ci           | utf32    | 169 |         | Yes      |       8 | PAD SPACE     |
| utf32_unicode_520_ci       | utf32    | 182 |         | Yes      |       8 | PAD SPACE     |
| utf32_unicode_ci           | utf32    | 160 |         | Yes      |       8 | PAD SPACE     |
| utf32_vietnamese_ci        | utf32    | 183 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_0900_ai_ci         | utf8mb4  | 255 | Yes     | Yes      |       0 | NO PAD        |
| utf8mb4_0900_as_ci         | utf8mb4  | 305 |         | Yes      |       0 | NO PAD        |
| utf8mb4_0900_as_cs         | utf8mb4  | 278 |         | Yes      |       0 | NO PAD        |
| utf8mb4_0900_bin           | utf8mb4  | 309 |         | Yes      |       1 | NO PAD        |
| utf8mb4_bin                | utf8mb4  |  46 |         | Yes      |       1 | PAD SPACE     |
| utf8mb4_croatian_ci        | utf8mb4  | 245 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_cs_0900_ai_ci      | utf8mb4  | 266 |         | Yes      |       0 | NO PAD        |
| utf8mb4_cs_0900_as_cs      | utf8mb4  | 289 |         | Yes      |       0 | NO PAD        |
| utf8mb4_czech_ci           | utf8mb4  | 234 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_danish_ci          | utf8mb4  | 235 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_da_0900_ai_ci      | utf8mb4  | 267 |         | Yes      |       0 | NO PAD        |
| utf8mb4_da_0900_as_cs      | utf8mb4  | 290 |         | Yes      |       0 | NO PAD        |
| utf8mb4_de_pb_0900_ai_ci   | utf8mb4  | 256 |         | Yes      |       0 | NO PAD        |
| utf8mb4_de_pb_0900_as_cs   | utf8mb4  | 279 |         | Yes      |       0 | NO PAD        |
| utf8mb4_eo_0900_ai_ci      | utf8mb4  | 273 |         | Yes      |       0 | NO PAD        |
| utf8mb4_eo_0900_as_cs      | utf8mb4  | 296 |         | Yes      |       0 | NO PAD        |
| utf8mb4_esperanto_ci       | utf8mb4  | 241 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_estonian_ci        | utf8mb4  | 230 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_es_0900_ai_ci      | utf8mb4  | 263 |         | Yes      |       0 | NO PAD        |
| utf8mb4_es_0900_as_cs      | utf8mb4  | 286 |         | Yes      |       0 | NO PAD        |
| utf8mb4_es_trad_0900_ai_ci | utf8mb4  | 270 |         | Yes      |       0 | NO PAD        |
| utf8mb4_es_trad_0900_as_cs | utf8mb4  | 293 |         | Yes      |       0 | NO PAD        |
| utf8mb4_et_0900_ai_ci      | utf8mb4  | 262 |         | Yes      |       0 | NO PAD        |
| utf8mb4_et_0900_as_cs      | utf8mb4  | 285 |         | Yes      |       0 | NO PAD        |
| utf8mb4_general_ci         | utf8mb4  |  45 |         | Yes      |       1 | PAD SPACE     |
| utf8mb4_german2_ci         | utf8mb4  | 244 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_hr_0900_ai_ci      | utf8mb4  | 275 |         | Yes      |       0 | NO PAD        |
| utf8mb4_hr_0900_as_cs      | utf8mb4  | 298 |         | Yes      |       0 | NO PAD        |
| utf8mb4_hungarian_ci       | utf8mb4  | 242 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_hu_0900_ai_ci      | utf8mb4  | 274 |         | Yes      |       0 | NO PAD        |
| utf8mb4_hu_0900_as_cs      | utf8mb4  | 297 |         | Yes      |       0 | NO PAD        |
| utf8mb4_icelandic_ci       | utf8mb4  | 225 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_is_0900_ai_ci      | utf8mb4  | 257 |         | Yes      |       0 | NO PAD        |
| utf8mb4_is_0900_as_cs      | utf8mb4  | 280 |         | Yes      |       0 | NO PAD        |
| utf8mb4_ja_0900_as_cs      | utf8mb4  | 303 |         | Yes      |       0 | NO PAD        |
| utf8mb4_ja_0900_as_cs_ks   | utf8mb4  | 304 |         | Yes      |      24 | NO PAD        |
| utf8mb4_latvian_ci         | utf8mb4  | 226 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_la_0900_ai_ci      | utf8mb4  | 271 |         | Yes      |       0 | NO PAD        |
| utf8mb4_la_0900_as_cs      | utf8mb4  | 294 |         | Yes      |       0 | NO PAD        |
| utf8mb4_lithuanian_ci      | utf8mb4  | 236 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_lt_0900_ai_ci      | utf8mb4  | 268 |         | Yes      |       0 | NO PAD        |
| utf8mb4_lt_0900_as_cs      | utf8mb4  | 291 |         | Yes      |       0 | NO PAD        |
| utf8mb4_lv_0900_ai_ci      | utf8mb4  | 258 |         | Yes      |       0 | NO PAD        |
| utf8mb4_lv_0900_as_cs      | utf8mb4  | 281 |         | Yes      |       0 | NO PAD        |
| utf8mb4_persian_ci         | utf8mb4  | 240 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_pl_0900_ai_ci      | utf8mb4  | 261 |         | Yes      |       0 | NO PAD        |
| utf8mb4_pl_0900_as_cs      | utf8mb4  | 284 |         | Yes      |       0 | NO PAD        |
| utf8mb4_polish_ci          | utf8mb4  | 229 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_romanian_ci        | utf8mb4  | 227 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_roman_ci           | utf8mb4  | 239 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_ro_0900_ai_ci      | utf8mb4  | 259 |         | Yes      |       0 | NO PAD        |
| utf8mb4_ro_0900_as_cs      | utf8mb4  | 282 |         | Yes      |       0 | NO PAD        |
| utf8mb4_ru_0900_ai_ci      | utf8mb4  | 306 |         | Yes      |       0 | NO PAD        |
| utf8mb4_ru_0900_as_cs      | utf8mb4  | 307 |         | Yes      |       0 | NO PAD        |
| utf8mb4_sinhala_ci         | utf8mb4  | 243 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_sk_0900_ai_ci      | utf8mb4  | 269 |         | Yes      |       0 | NO PAD        |
| utf8mb4_sk_0900_as_cs      | utf8mb4  | 292 |         | Yes      |       0 | NO PAD        |
| utf8mb4_slovak_ci          | utf8mb4  | 237 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_slovenian_ci       | utf8mb4  | 228 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_sl_0900_ai_ci      | utf8mb4  | 260 |         | Yes      |       0 | NO PAD        |
| utf8mb4_sl_0900_as_cs      | utf8mb4  | 283 |         | Yes      |       0 | NO PAD        |
| utf8mb4_spanish2_ci        | utf8mb4  | 238 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_spanish_ci         | utf8mb4  | 231 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_sv_0900_ai_ci      | utf8mb4  | 264 |         | Yes      |       0 | NO PAD        |
| utf8mb4_sv_0900_as_cs      | utf8mb4  | 287 |         | Yes      |       0 | NO PAD        |
| utf8mb4_swedish_ci         | utf8mb4  | 232 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_tr_0900_ai_ci      | utf8mb4  | 265 |         | Yes      |       0 | NO PAD        |
| utf8mb4_tr_0900_as_cs      | utf8mb4  | 288 |         | Yes      |       0 | NO PAD        |
| utf8mb4_turkish_ci         | utf8mb4  | 233 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_unicode_520_ci     | utf8mb4  | 246 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_unicode_ci         | utf8mb4  | 224 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_vietnamese_ci      | utf8mb4  | 247 |         | Yes      |       8 | PAD SPACE     |
| utf8mb4_vi_0900_ai_ci      | utf8mb4  | 277 |         | Yes      |       0 | NO PAD        |
| utf8mb4_vi_0900_as_cs      | utf8mb4  | 300 |         | Yes      |       0 | NO PAD        |
| utf8mb4_zh_0900_as_cs      | utf8mb4  | 308 |         | Yes      |       0 | NO PAD        |
| utf8_bin                   | utf8     |  83 |         | Yes      |       1 | PAD SPACE     |
| utf8_croatian_ci           | utf8     | 213 |         | Yes      |       8 | PAD SPACE     |
| utf8_czech_ci              | utf8     | 202 |         | Yes      |       8 | PAD SPACE     |
| utf8_danish_ci             | utf8     | 203 |         | Yes      |       8 | PAD SPACE     |
| utf8_esperanto_ci          | utf8     | 209 |         | Yes      |       8 | PAD SPACE     |
| utf8_estonian_ci           | utf8     | 198 |         | Yes      |       8 | PAD SPACE     |
| utf8_general_ci            | utf8     |  33 | Yes     | Yes      |       1 | PAD SPACE     |
| utf8_general_mysql500_ci   | utf8     | 223 |         | Yes      |       1 | PAD SPACE     |
| utf8_german2_ci            | utf8     | 212 |         | Yes      |       8 | PAD SPACE     |
| utf8_hungarian_ci          | utf8     | 210 |         | Yes      |       8 | PAD SPACE     |
| utf8_icelandic_ci          | utf8     | 193 |         | Yes      |       8 | PAD SPACE     |
| utf8_latvian_ci            | utf8     | 194 |         | Yes      |       8 | PAD SPACE     |
| utf8_lithuanian_ci         | utf8     | 204 |         | Yes      |       8 | PAD SPACE     |
| utf8_persian_ci            | utf8     | 208 |         | Yes      |       8 | PAD SPACE     |
| utf8_polish_ci             | utf8     | 197 |         | Yes      |       8 | PAD SPACE     |
| utf8_romanian_ci           | utf8     | 195 |         | Yes      |       8 | PAD SPACE     |
| utf8_roman_ci              | utf8     | 207 |         | Yes      |       8 | PAD SPACE     |
| utf8_sinhala_ci            | utf8     | 211 |         | Yes      |       8 | PAD SPACE     |
| utf8_slovak_ci             | utf8     | 205 |         | Yes      |       8 | PAD SPACE     |
| utf8_slovenian_ci          | utf8     | 196 |         | Yes      |       8 | PAD SPACE     |
| utf8_spanish2_ci           | utf8     | 206 |         | Yes      |       8 | PAD SPACE     |
| utf8_spanish_ci            | utf8     | 199 |         | Yes      |       8 | PAD SPACE     |
| utf8_swedish_ci            | utf8     | 200 |         | Yes      |       8 | PAD SPACE     |
| utf8_tolower_ci            | utf8     |  76 |         | Yes      |       1 | PAD SPACE     |
| utf8_turkish_ci            | utf8     | 201 |         | Yes      |       8 | PAD SPACE     |
| utf8_unicode_520_ci        | utf8     | 214 |         | Yes      |       8 | PAD SPACE     |
| utf8_unicode_ci            | utf8     | 192 |         | Yes      |       8 | PAD SPACE     |
| utf8_vietnamese_ci         | utf8     | 215 |         | Yes      |       8 | PAD SPACE     |
+----------------------------+----------+-----+---------+----------+---------+---------------+
272 rows in set (0.01 sec)


#utf8_general_ci 不区分大小写
#utf8_bin        区分大小写

查看当前使用的排序规则

bash 复制代码
mysql> SHOW VARIABLES LIKE 'collation%';
+----------------------+--------------------+
| Variable_name        | Value              |
+----------------------+--------------------+
| collation_connection | utf8mb4_0900_ai_ci |
| collation_database   | utf8mb4_0900_ai_ci |
| collation_server     | utf8mb4_0900_ai_ci |
+----------------------+--------------------+
3 rows in set (0.01 sec)

生产环境中,使用 utf8mb4 编码,使用默认排序规则

管理数据库

查看数据库列表

格式:

mysql 复制代码
SHOW DATABASES;

范例:

bash 复制代码
#默认这四个系统库,不能删除
mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.01 sec)

创建数据库

格式:

bash 复制代码
mysql> help create database;
Name: 'CREATE DATABASE'
Description:
Syntax:
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
    [create_option] ...

create_option: [DEFAULT] {
    CHARACTER SET [=] charset_name
  | COLLATE [=] collation_name
  | ENCRYPTION [=] {'Y' | 'N'}
}

CREATE DATABASE creates a database with the given name. To use this
statement, you need the CREATE privilege for the database. CREATE
SCHEMA is a synonym for CREATE DATABASE.

URL: https://dev.mysql.com/doc/refman/8.0/en/create-database.html

格式:查询数据库创建语句

mysql 复制代码
SHOW CREATE DATABASE DBNAME;

范例:

bash 复制代码
mysql> create database testdb1;
Query OK, 1 row affected (0.00 sec)

#如果已存在,再次创建会报错
mysql> create database testdb1;
ERROR 1007 (HY000): Can't create database 'testdb1'; database exists

#不报错,但也没有创建,if not exists表示如果不存在则创建
mysql> create database if not exists testdb1;
Query OK, 1 row affected, 1 warning (0.00 sec)

#查看数据库列表
mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| testdb1            |
+--------------------+
5 rows in set (0.01 sec)

#查看创建语句,包含默认字符集
mysql> SHOW CREATE DATABASE testdb1;
+----------+-----------------------------------------------------------------------------------------------------------------------------------+
| Database | Create Database                                                                                                                   |
+----------+-----------------------------------------------------------------------------------------------------------------------------------+
| testdb1  | CREATE DATABASE `testdb1` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */ |
+----------+-----------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

#创建时指定字符集
mysql> create database testdb2 DEFAULT CHARACTER SET latin1;
Query OK, 1 row affected (0.01 sec)

#查看创建语句
mysql> show create database testdb2;
+----------+-------------------------------------------------------------------------------------------------------+
| Database | Create Database                                                                                       |
+----------+-------------------------------------------------------------------------------------------------------+
| testdb2  | CREATE DATABASE `testdb2` /*!40100 DEFAULT CHARACTER SET latin1 */ /*!80016 DEFAULT ENCRYPTION='N' */ |
+----------+-------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

创建两个数据库,本质上是在硬盘上创建了两个目录

bash 复制代码
[root@localhost ~]# ls -d /var/lib/mysql/testdb*
/var/lib/mysql/testdb1  /var/lib/mysql/testdb2

修改数据库

bash 复制代码
mysql> help ALTER DATABASE;
Name: 'ALTER DATABASE'
Description:
Syntax:
ALTER {DATABASE | SCHEMA} [db_name]
    alter_option ...

alter_option: {
    [DEFAULT] CHARACTER SET [=] charset_name
  | [DEFAULT] COLLATE [=] collation_name
  | [DEFAULT] ENCRYPTION [=] {'Y' | 'N'}
  | READ ONLY [=] {DEFAULT | 0 | 1}
}

范例:修改字符集

mysql 复制代码
mysql> ALTER DATABASE testdb2 character set utf8mb4 COLLATE utf8mb4_0900_ai_ci;
Query OK, 1 row affected (0.00 sec)

mysql> show create database testdb2\G
*************************** 1. row ***************************
       Database: testdb2
Create Database: CREATE DATABASE `testdb2` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */
1 row in set (0.00 sec)

删除数据库

格式:

bash 复制代码
mysql> help DROP DATABASE
Name: 'DROP DATABASE'
Description:
Syntax:
DROP {DATABASE | SCHEMA} [IF EXISTS] db_name

范例:

bash 复制代码
mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| testdb1            |
| testdb2            |
+--------------------+
6 rows in set (0.00 sec)

#删除数据库
mysql> DROP DATABASE testdb2;
Query OK, 0 rows affected (0.00 sec)

#删除不存在的库
mysql> DROP DATABASE testdb2;
ERROR 1008 (HY000): Can't drop database 'testdb2'; database doesn't exist

#加if exists判断
mysql> DROP DATABASE IF EXISTS testdb2;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| testdb1            |
+--------------------+
5 rows in set (0.00 sec)

#testdb2对应的目录已不存在
[root@localhost ~]# ls -d /var/lib/mysql/testdb* -d
/var/lib/mysql/testdb1

mysqladmin 命令也可以创建和删除数据库

bash 复制代码
#创建数据库db1
[root@localhost ~]# mysqladmin create db1

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| db1                |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| testdb1            |
+--------------------+
6 rows in set (0.00 sec)

#删除数据库db1
[root@localhost ~]# mysqladmin drop testdb1
Dropping the database is potentially a very bad thing to do.
Any data stored in the database will be destroyed.

Do you really want to drop the 'testdb1' database [y/N] y            #回答Y
Database "testdb1" dropped

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| db1                |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

数据类型

核心定义:数据库数据类型,是对数据库表中字段(列)所存储数据的类型、范围、格式进行的规范定义。简单说,就是规定「某一列只能存什么类型的数据」,比如只能存数字、只能存文字,目的是保证数据存储的规范性、节省存储空间、提高查询效率,避免无效数据插入。

核心作用

  • 规范数据:限制字段可存储的数据种类(如手机号字段只能存数字,不能存文字),避免数据混乱;
  • 节省空间:不同数据类型占用存储空间不同(如整数比字符串占用空间小),合理选择可减少资源浪费;
  • 提升效率:数据库可根据数据类型优化查询、排序操作,加快数据处理速度;
  • 保证数据完整性:避免插入不符合要求的数据(如给「年龄」字段插入文字),减少数据错误。

MySQL 中定义数据字段的类型对你数据库的优化是非常重要的。

MySQL 支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。

对于任何一个数据表,每一行的每一列对应的元素都是下列数据类型的一种。

类型 关键字
整数类型 TINYINT SMALLINT MEDIUMINT INT (INTEGER) BIGINT
浮点类型 FLOAT DOUBLE
定点数类型 DECIMAL
位类型 BIT
日期时间类型 YEAR TIME DATE DATETIME TIMESTAMP
文本字符串类型 CHAR VARCHAR TINYTEXT TEXT MEDIUMTEXT LONGTEXT
枚举类型 ENUM
集合类型 SET
二进制字符串类型 BINARY VARBINARY TINYBLOB BLOB MEDIUMBLOB LONGBLOB
JSON 类型 JSON对象 JSON 数组
空间数据类型 (单值类型) GEOMETRY POINT LINESTRING POLYGON
空间数据类型 (集合类型) MULTIPOINT MULTILINESTRING MULTIPOLYGON GEOMETRYCOLLECTION

在创建数据表时,除了可以指定列的数据类型,还可以指定列的属性。

关键字 含义
NULL 数据列可包含 NULL 值
NOT NULL 数据列不允许包含 NULL 值
DEFAULT 默认值
PRIMARY KEY 主键
AUTO_INCREMENT 自动递增,适用于整数类型
UNSIGNED 无符号
CHARACTER SET name 指定一个字符集

常见数据库(MySQL)核心数据类型(必考分类)

  1. 数值类型(存储数字,最常用)

用于存储整数、小数等数值,按范围和精度分为两类:

  • 整数类型:INT(最常用,存储 -2147483648~2147483647,如年龄、学号)、TINYINT(小整数,如性别 0/1)、BIGINT(大整数,如手机号、身份证号);
  • 小数类型:DECIMAL(高精度小数,如金额、价格,推荐使用,避免精度丢失)、FLOAT(单精度小数)、DOUBLE(双精度小数)。
  1. 字符串类型(存储文字、符号,最常用)
  • VARCHAR(n):可变长度字符串,n 表示最大长度(如姓名、地址,推荐使用,节省空间);
  • CHAR(n):固定长度字符串,n 表示固定长度(如身份证号、手机号,长度固定的场景);
  • TEXT:存储长文本(如备注、简介,长度超过 VARCHAR 上限时使用)。
  1. 日期时间类型(存储时间相关数据)
  • DATETIME:存储日期+时间(如注册时间、交易时间,格式:YYYY-MM-DD HH:MM:SS);
  • DATE:只存储日期(如出生日期,格式:YYYY-MM-DD);
  • TIME:只存储时间(如打卡时间,格式:HH:MM:SS);
  • TIMESTAMP:时间戳,自动记录数据插入/更新时间,范围比 DATETIME 小。
  1. 其他常用类型
  • BOOLEAN:布尔类型,存储 TRUE(1)或 FALSE(0),如「是否有效」「是否审核」;
  • ENUM:枚举类型,只能从预设的选项中选择一个值(如性别:'男','女')。

数值型

MySQL 支持所有标准 SQL 数值数据类型。

这些类型包括严格数值数据类型(INTEGER、SMALLINT、DECIMAL 和 NUMERIC),以及近似数值数据类型(FLOAT、REAL 和 DOUBLE PRECISION)。

关键字 INT 是 INTEGER 的同义词,关键字 DEC 是 DECIMAL 的同义词。

BIT 数据类型保存位字段值,并且支持 MyISAM、MEMORY、InnoDB 和 BDB 表。

作为 SQL 标准的扩展,MySQL 也支持整数类型 TINYINT、MEDIUMINT 和 BIGINT。下面的表显示了需要的每个整数类型的存储和范围。

类型 大小 范围(有符号) 范围(无符号) 用途
TINYINT 1 Bytes (-128,127) (0,255) 小整数值
SMALLINT 2 Bytes (-32 768,32 767) (0,65 535) 大整数值
MEDIUMINT 3 Bytes (-8 388 608,8 388 607) (0,16 777 215) 大整数值
INT或INTEGER 4 Bytes (-2 147 483 648,2 147 483 647) (0,4 294 967 295) 大整数值
BIGINT 8 Bytes (-9 223 372 036 854 775 808 ,9 223 372 036 854 775 807) (0,18 446 744 073 709 551 615) 极大整数值
FLOAT 4 Bytes (-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) 0,(1.175 494 351 E-38,3.402 823 466 E+38) 单精度 浮点数值
DOUBLE 8 Bytes (-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 双精度 浮点数值
DECIMAL 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 依赖于M和D的值 依赖于M和D的值 小数值

日期和时间型

表示时间值的日期和时间类型为 DATETIME、DATE、TIMESTAMP、TIME 和 YEAR。

每个时间类型有一个有效值范围和一个「零」值,当指定不合法的 MySQL 不能表示的值时使用「零」值。

TIMESTAMP 类型有专有的自动更新特性,将在后面描述。

类型 大小 ( bytes) 范围 格式 用途
DATE 3 1000-01-01/9999-12-31 YYYY-MM-DD 日期值
TIME 3 '-838:59:59'/'838:59:59' HH:MM:SS 时间值或持续时间
YEAR 1 1901/2155 YYYY 年份值
DATETIME 8 '1000-01-01 00:00:00' 到 '9999-12-31 23:59:59' YYYY-MM-DD hh:mm:ss 混合日期和时间值
TIMESTAMP 4 '1970-01-01 00:00:01' UTC 到 '2038-01-19 03:14:07' UTC结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07 YYYY-MM-DD hh:mm:ss 混合日期和时间值,时间戳

字符串类型

字符串类型指 CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM 和 SET。该节描述了这些类型如何工作以及如何在查询中使用这些类型。

类型 大小 用途
CHAR 0-255 bytes 定长字符串
VARCHAR 0-65535 bytes 变长字符串
TINYBLOB 0-255 bytes 不超过 255 个字符的二进制字符串
TINYTEXT 0-255 bytes 短文本字符串
BLOB 0-65 535 bytes 二进制形式的长文本数据
TEXT 0-65 535 bytes 长文本数据
MEDIUMBLOB 0-16 777 215 bytes 二进制形式的中等长度文本数据
MEDIUMTEXT 0-16 777 215 bytes 中等长度文本数据
LONGBLOB 0-4 294 967 295 bytes 二进制形式的极大文本数据
LONGTEXT 0-4 294 967 295 bytes 极大文本数据

注意:char(n) 和 varchar(n) 中括号中 n 代表字符的个数,并不代表字节个数,比如 CHAR(30) 就可以存储 30 个字符。

CHAR 和 VARCHAR 类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。

BINARY 和 VARBINARY 类似于 CHAR 和 VARCHAR,不同的是它们包含二进制字符串而非非二进制字符串。也就是说,它们包含字节字符串而不是字符字符串。这说明它们没有字符集,并且排序和比较基于列值字节的数值。

BLOB 是一个二进制大对象,可以容纳可变数量的数据。有 4 种 BLOB 类型:TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB。它们区别在于可容纳存储范围不同。

有 4 种 TEXT 类型:TINYTEXT、TEXT、MEDIUMTEXT 和 LONGTEXT。对应的这 4 种 BLOB 类型,可存储的最大长度不同,可根据实际情况选择。

DDL 语句

DDL 语句主要用来操作数据库中的表。

同一个库中不同表可以使用不同的存储引擎,但建议使用同一种存储引擎。

创建表

格式

bash 复制代码
#帮助
mysql> help create table
Name: 'CREATE TABLE'
Description:
Syntax:
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
    (create_definition,...)
    [table_options]
    [partition_options]

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
    [(create_definition,...)]
    [table_options]
    [partition_options]
    [IGNORE | REPLACE]
    [AS] query_expression

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
    { LIKE old_tbl_name | (LIKE old_tbl_name) }
.....

直接创建

bash 复制代码
CREATE TABLE [IF NOT EXISTS] 'tbl_name' (col1 type1 修饰符,col2 type2 修饰符,...)

#字段格式
col type1              #定义字段数据类型
PRIMARY KEY(col1,...)  #将该字段设为主键
INDEX(col1,...)        #设置为索引
UNIQUE KEY(COL1,...)   #设置为联合主键

#表选项
ENGINE [=] engine_name
ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}

范例

mysql 复制代码
CREATE TABLE student (
id int UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
age tinyint UNSIGNED,
#height DECIMAL(5,2),
gender ENUM('M','F') default 'M'
)ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4;

#选择数据库
mysql> use db1;
Database changed

#执行SQL语句
mysql> CREATE TABLE student (
    -> id int UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    -> name VARCHAR(20) NOT NULL,
    -> age tinyint UNSIGNED,
    -> #height DECIMAL(5,2),
    -> gender ENUM('M','F') default 'M'
    -> )ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4;
Query OK, 0 rows affected (0.02 sec)

#查看
mysql> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| student       |
+---------------+
1 row in set (0.00 sec)

#查看结构
mysql> desc student;
+--------+------------------+------+-----+---------+----------------+
| Field  | Type             | Null | Key | Default | Extra          |
+--------+------------------+------+-----+---------+----------------+
| id     | int unsigned     | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20)      | NO   |     | NULL    |                |
| age    | tinyint unsigned | YES  |     | NULL    |                |
| gender | enum('M','F')    | YES  |     | M       |                |
+--------+------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

#插入一条数据
mysql> insert student (name,age)values('xiaoming',20);
Query OK, 1 row affected (0.01 sec)

#查询表中的所有数据
mysql> select * from student;
+----+----------+------+--------+
| id | name     | age  | gender |
+----+----------+------+--------+
| 10 | xiaoming |   20 | M      |
+----+----------+------+--------+
1 row in set (0.00 sec)

#再次插入一条数据
mysql> insert student(name,age,gender)values('xiaohong',18,'f');
Query OK, 1 row affected (0.00 sec)

mysql> select * from student;
+----+----------+------+--------+
| id | name     | age  | gender |
+----+----------+------+--------+
| 10 | xiaoming |   20 | M      |
| 11 | xiaohong |   18 | F      |
+----+----------+------+--------+
2 rows in set (0.00 sec)

通过查询现存表创建,新表会被直接插入查询而来的数据

范例

bash 复制代码
mysql> desc student;
+--------+------------------+------+-----+---------+----------------+
| Field  | Type             | Null | Key | Default | Extra          |
+--------+------------------+------+-----+---------+----------------+
| id     | int unsigned     | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20)      | NO   |     | NULL    |                |
| age    | tinyint unsigned | YES  |     | NULL    |                |
| gender | enum('M','F')    | YES  |     | M       |                |
+--------+------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

#查询其他表创建
mysql> create table student2 select name,age from student;
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

#查看
mysql> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| student       |
| student2      |
+---------------+
2 rows in set (0.00 sec)

#查看结构
mysql> desc student2;
+-------+------------------+------+-----+---------+-------+
| Field | Type             | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| name  | varchar(20)      | NO   |     | NULL    |       |
| age   | tinyint unsigned | YES  |     | NULL    |       |
+-------+------------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

#数据也复制过来了
mysql> select * from student2;
+----------+------+
| name     | age  |
+----------+------+
| xiaoming |   20 |
| xiaohong |   18 |
+----------+------+
2 rows in set (0.00 sec)

通过复制现存的表的表结构创建,但不复制数据

范例

mysql 复制代码
mysql> desc student;
+--------+------------------+------+-----+---------+----------------+
| Field  | Type             | Null | Key | Default | Extra          |
+--------+------------------+------+-----+---------+----------------+
| id     | int unsigned     | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20)      | NO   |     | NULL    |                |
| age    | tinyint unsigned | YES  |     | NULL    |                |
| gender | enum('M','F')    | YES  |     | M       |                |
+--------+------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

mysql> create table student3 like student;
Query OK, 0 rows affected (0.01 sec)

mysql> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| student       |
| student2      |
| student3      |
+---------------+
3 rows in set (0.00 sec)

mysql> desc student3;
+--------+------------------+------+-----+---------+----------------+
| Field  | Type             | Null | Key | Default | Extra          |
+--------+------------------+------+-----+---------+----------------+
| id     | int unsigned     | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20)      | NO   |     | NULL    |                |
| age    | tinyint unsigned | YES  |     | NULL    |                |
| gender | enum('M','F')    | YES  |     | M       |                |
+--------+------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

mysql> select * from student3;
Empty set (0.00 sec)

查看表

格式

bash 复制代码
mysql> help show tables
Name: 'SHOW TABLES'
Description:
Syntax:
SHOW [EXTENDED] [FULL] TABLES
    [{FROM | IN} db_name]
    [LIKE 'pattern' | WHERE expr]

列出数据库中的表

格式

bash 复制代码
SHOW TABLES [FROM db_name]

范例

bash 复制代码
#查看当前库中所有表
mysql> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| student       |
| student2      |
| student3      |
+---------------+
3 rows in set (0.00 sec)

#查看指定库中的表
mysql> show tables from db1;
+---------------+
| Tables_in_db1 |
+---------------+
| student       |
| student2      |
| student3      |
+---------------+
3 rows in set (0.00 sec)

查看建表语句

格式

bash 复制代码
SHOW CREATE TABLE [db_name.]tbl_name

范例

bash 复制代码
mysql> show create table student;
+---------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table   | Create Table                                                                                                                                                                                                                                                                                |
+---------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| student | CREATE TABLE `student` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `age` tinyint unsigned DEFAULT NULL,
  `gender` enum('M','F') DEFAULT 'M',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+---------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)


#查看指定数据库的数据表
mysql> show create table db1.student\G
*************************** 1. row ***************************
       Table: student
Create Table: CREATE TABLE `student` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `age` tinyint unsigned DEFAULT NULL,
  `gender` enum('M','F') DEFAULT 'M',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

查看表结构

格式

bash 复制代码
DESC [db_name.]tbl_name
SHOW COLUMNS FROM [db_name.]tbl_name

范例

bash 复制代码
mysql> desc student;
+--------+------------------+------+-----+---------+----------------+
| Field  | Type             | Null | Key | Default | Extra          |
+--------+------------------+------+-----+---------+----------------+
| id     | int unsigned     | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20)      | NO   |     | NULL    |                |
| age    | tinyint unsigned | YES  |     | NULL    |                |
| gender | enum('M','F')    | YES  |     | M       |                |
+--------+------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

mysql> show columns from student;
+--------+------------------+------+-----+---------+----------------+
| Field  | Type             | Null | Key | Default | Extra          |
+--------+------------------+------+-----+---------+----------------+
| id     | int unsigned     | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20)      | NO   |     | NULL    |                |
| age    | tinyint unsigned | YES  |     | NULL    |                |
| gender | enum('M','F')    | YES  |     | M       |                |
+--------+------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

查看表状态

格式

bash 复制代码
SHOW TABLE STATUS LIKE 'tbl_name'

范例

bash 复制代码
mysql> SHOW TABLE STATUS LIKE 'student';
+---------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
| Name    | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time         | Update_time         | Check_time | Collation          | Checksum | Create_options | Comment |
+---------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
| student | InnoDB |      10 | Dynamic    |    2 |           8192 |       16384 |               0 |            0 |         0 |             12 | 2025-09-18 22:10:21 | 2025-09-18 22:24:45 | NULL       | utf8mb4_0900_ai_ci |     NULL |                |         |
+---------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
1 row in set (0.00 sec)

mysql> SHOW TABLE STATUS LIKE 'student'\G
*************************** 1. row ***************************
           Name: student
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 2
 Avg_row_length: 8192
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: 12
    Create_time: 2025-09-18 22:10:21
    Update_time: 2025-09-18 22:24:45
     Check_time: NULL
      Collation: utf8mb4_0900_ai_ci
       Checksum: NULL
 Create_options:
        Comment:
1 row in set (0.01 sec)

#不能有库名
mysql> SHOW TABLE STATUS LIKE 'db1.student'\G
Empty set (0.00 sec)

查看库中所有表状态

格式

mysql 复制代码
SHOW TABLE STATUS FROM db_name

范例

bash 复制代码
mysql> SHOW TABLE STATUS FROM db1\G
*************************** 1. row ***************************
           Name: student
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 2
 Avg_row_length: 8192
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: 12
    Create_time: 2025-09-18 22:10:21
    Update_time: 2025-09-18 22:24:45
     Check_time: NULL
      Collation: utf8mb4_0900_ai_ci
       Checksum: NULL
 Create_options:
        Comment:
*************************** 2. row ***************************
           Name: student2
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 2
 Avg_row_length: 8192
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2025-09-18 22:35:06
    Update_time: 2025-09-18 22:35:06
     Check_time: NULL
      Collation: utf8mb4_0900_ai_ci
       Checksum: NULL
 Create_options:
        Comment:
*************************** 3. row ***************************
           Name: student3
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 0
 Avg_row_length: 0
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: 1
    Create_time: 2025-09-18 22:49:14
    Update_time: NULL
     Check_time: NULL
      Collation: utf8mb4_0900_ai_ci
       Checksum: NULL
 Create_options:
        Comment:
3 rows in set (0.01 sec)

查看当前 MySQL 服务支持的引擎

格式

mysql 复制代码
SHOW ENGINES

范例

mysql 复制代码
mysql> SHOW ENGINES;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                                        | Transactions | XA   | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| FEDERATED          | NO      | Federated MySQL storage engine                                 | NULL         | NULL | NULL       |
| MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables      | NO           | NO   | NO         |
| InnoDB             | DEFAULT | Supports transactions, row-level locking, and foreign keys     | YES          | YES  | YES        |
| PERFORMANCE_SCHEMA | YES     | Performance Schema                                             | NO           | NO   | NO         |
| MyISAM             | YES     | MyISAM storage engine                                          | NO           | NO   | NO         |
| MRG_MYISAM         | YES     | Collection of identical MyISAM tables                          | NO           | NO   | NO         |
| BLACKHOLE          | YES     | /dev/null storage engine (anything you write to it disappears) | NO           | NO   | NO         |
| CSV                | YES     | CSV storage engine                                             | NO           | NO   | NO         |
| ARCHIVE            | YES     | Archive storage engine                                         | NO           | NO   | NO         |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.01 sec)

mysql> SHOW ENGINES\G
*************************** 1. row ***************************
      Engine: FEDERATED
     Support: NO
     Comment: Federated MySQL storage engine
Transactions: NULL
          XA: NULL
  Savepoints: NULL
*************************** 2. row ***************************
      Engine: MEMORY
     Support: YES
     Comment: Hash based, stored in memory, useful for temporary tables
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 3. row ***************************
      Engine: InnoDB
     Support: DEFAULT
     Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
          XA: YES
  Savepoints: YES
*************************** 4. row ***************************
      Engine: PERFORMANCE_SCHEMA
     Support: YES
     Comment: Performance Schema
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 5. row ***************************
      Engine: MyISAM
     Support: YES
     Comment: MyISAM storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 6. row ***************************
      Engine: MRG_MYISAM
     Support: YES
     Comment: Collection of identical MyISAM tables
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 7. row ***************************
      Engine: BLACKHOLE
     Support: YES
     Comment: /dev/null storage engine (anything you write to it disappears)
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 8. row ***************************
      Engine: CSV
     Support: YES
     Comment: CSV storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 9. row ***************************
      Engine: ARCHIVE
     Support: YES
     Comment: Archive storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
9 rows in set (0.00 sec)

修改和删除表

mysql 复制代码
ALTER TABLE tbl_name
    [alter_option [, alter_option] ...]
    [partition_options]
mysql 复制代码
{ ADD COLUMN <列名> <类型>
| CHANGE COLUMN <旧列名> <新列名> <新列类型>
| ALTER COLUMN <列名> { SET DEFAULT <默认值>丨DROP DEFAULT }
| MODIFY COLUMN <列名> <类型>
| DROP COLUMN <列名>
| RENAME TO <新表名> }

范例

bash 复制代码
#修改表名
mysql> ALTER TABLE student RENAME stu;
Query OK, 0 rows affected (0.01 sec)

mysql> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| stu           |
| student2      |
| student3      |
+---------------+
3 rows in set (0.00 sec)

mysql> desc stu;
+--------+------------------+------+-----+---------+----------------+
| Field  | Type             | Null | Key | Default | Extra          |
+--------+------------------+------+-----+---------+----------------+
| id     | int unsigned     | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20)      | NO   |     | NULL    |                |
| age    | tinyint unsigned | YES  |     | NULL    |                |
| gender | enum('M','F')    | YES  |     | M       |                |
+--------+------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

#添加表字段
mysql> ALTER TABLE stu ADD phone varchar(11) AFTER name;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc stu;
+--------+------------------+------+-----+---------+----------------+
| Field  | Type             | Null | Key | Default | Extra          |
+--------+------------------+------+-----+---------+----------------+
| id     | int unsigned     | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20)      | NO   |     | NULL    |                |
| phone  | varchar(11)      | YES  |     | NULL    |                |
| age    | tinyint unsigned | YES  |     | NULL    |                |
| gender | enum('M','F')    | YES  |     | M       |                |
+--------+------------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

#修改字段类型
mysql> ALTER TABLE stu MODIFY phone int;
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> desc stu;
+--------+------------------+------+-----+---------+----------------+
| Field  | Type             | Null | Key | Default | Extra          |
+--------+------------------+------+-----+---------+----------------+
| id     | int unsigned     | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20)      | NO   |     | NULL    |                |
| phone  | int              | YES  |     | NULL    |                |
| age    | tinyint unsigned | YES  |     | NULL    |                |
| gender | enum('M','F')    | YES  |     | M       |                |
+--------+------------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

#修改字段名称和类型
mysql> ALTER TABLE stu CHANGE COLUMN phone mobile char(11);
Query OK, 2 rows affected (0.02 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> desc stu;
+--------+------------------+------+-----+---------+----------------+
| Field  | Type             | Null | Key | Default | Extra          |
+--------+------------------+------+-----+---------+----------------+
| id     | int unsigned     | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20)      | NO   |     | NULL    |                |
| mobile | char(11)         | YES  |     | NULL    |                |
| age    | tinyint unsigned | YES  |     | NULL    |                |
| gender | enum('M','F')    | YES  |     | M       |                |
+--------+------------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

#删除字段
mysql> ALTER TABLE stu DROP COLUMN mobile;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc stu;
+--------+------------------+------+-----+---------+----------------+
| Field  | Type             | Null | Key | Default | Extra          |
+--------+------------------+------+-----+---------+----------------+
| id     | int unsigned     | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20)      | NO   |     | NULL    |                |
| age    | tinyint unsigned | YES  |     | NULL    |                |
| gender | enum('M','F')    | YES  |     | M       |                |
+--------+------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

#修改表字符集
mysql> ALTER TABLE stu character SET utf8;
Query OK, 0 rows affected, 1 warning (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 1

#同时修改数据类型和字符集,只修改字符集,类型也不能少
mysql> ALTER TABLE stu CHANGE name name char(30) character set utf8;
Query OK, 2 rows affected, 1 warning (0.02 sec)
Records: 2  Duplicates: 0  Warnings: 1

#设置字段默认值
mysql> alter table stu alter column gender set default 'M';
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

#添加字段和修改字段
mysql> ALTER TABLE stu ADD is_del bool DEFAULT false;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> ALTER TABLE stu modify is_del bool DEFAULT true;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

范例

bash 复制代码
mysql> create table stu2 select * from stu;
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> desc stu2;
+--------+------------------+------+-----+---------+-------+
| Field  | Type             | Null | Key | Default | Extra |
+--------+------------------+------+-----+---------+-------+
| id     | int unsigned     | NO   |     | 0       |       |
| name   | char(30)         | YES  |     | NULL    |       |
| age    | tinyint unsigned | YES  |     | NULL    |       |
| gender | enum('M','F')    | YES  |     | M       |       |
| is_del | tinyint(1)       | YES  |     | 1       |       |
+--------+------------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

#添加主键
mysql> ALTER TABLE stu2 ADD PRIMARY KEY (id);
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc stu2;
+--------+------------------+------+-----+---------+-------+
| Field  | Type             | Null | Key | Default | Extra |
+--------+------------------+------+-----+---------+-------+
| id     | int unsigned     | NO   | PRI | 0       |       |
| name   | char(30)         | YES  |     | NULL    |       |
| age    | tinyint unsigned | YES  |     | NULL    |       |
| gender | enum('M','F')    | YES  |     | M       |       |
| is_del | tinyint(1)       | YES  |     | 1       |       |
+--------+------------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

#删除主键
mysql> ALTER TABLE stu2 DROP PRIMARY KEY;
Query OK, 2 rows affected (0.02 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> desc stu2;
+--------+------------------+------+-----+---------+-------+
| Field  | Type             | Null | Key | Default | Extra |
+--------+------------------+------+-----+---------+-------+
| id     | int unsigned     | NO   |     | 0       |       |
| name   | char(30)         | YES  |     | NULL    |       |
| age    | tinyint unsigned | YES  |     | NULL    |       |
| gender | enum('M','F')    | YES  |     | M       |       |
| is_del | tinyint(1)       | YES  |     | 1       |       |
+--------+------------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

删除表

格式

bash 复制代码
DROP [TEMPORARY] TABLE [IF EXISTS]
    tbl_name [, tbl_name] ...
    [RESTRICT | CASCADE]

范例

bash 复制代码
mysql> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| stu           |
| stu2          |
| student2      |
| student3      |
+---------------+
4 rows in set (0.00 sec)

mysql> drop table student2;drop table db1.student3;
Query OK, 0 rows affected (0.01 sec)
Query OK, 0 rows affected (0.01 sec)

mysql> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| stu           |
| stu2          |
+---------------+
2 rows in set (0.00 sec)

DML 语句

DML 语句包括 INSERT、UPDATE、DELETE

插入数据

INSERT 可以一次往表中插入一条或多条记录

格式

bash 复制代码
mysql> help INSERT
Name: 'INSERT'
Description:
Syntax:
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [(col_name [, col_name] ...)]
    { {VALUES | VALUE} (value_list) [, (value_list)] ...
      |
      VALUES row_constructor_list
    }
    [AS row_alias[(col_alias [, col_alias] ...)]]
    [ON DUPLICATE KEY UPDATE assignment_list]

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [AS row_alias[(col_alias [, col_alias] ...)]]
    SET assignment_list
    [ON DUPLICATE KEY UPDATE assignment_list]

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [(col_name [, col_name] ...)]
    [AS row_alias[(col_alias [, col_alias] ...)]]
    {SELECT ... | TABLE table_name}
    [ON DUPLICATE KEY UPDATE assignment_list]

简化格式

bash 复制代码
INSERT tbl_name [(col1,...)] VALUES (val1,...),(val21,...)

范例

bash 复制代码
mysql> select * from stu;
+----+----------+------+--------+--------+
| id | name     | age  | gender | is_del |
+----+----------+------+--------+--------+
| 10 | xiaoming |   20 | M      |      0 |
| 11 | xiaohong |   18 | F      |      0 |
+----+----------+------+--------+--------+
2 rows in set (0.00 sec)

#给出所有字段值(给出所有字段值,可以不用标明字段,只要顺序一一对应即可)
mysql> INSERT INTO stu VALUES(12,'xiaoli',19,'F',0);
Query OK, 1 row affected (0.01 sec)

#只给出部分字段值,因为有些字段值有默认值
mysql> INSERT INTO stu(name,age)VALUES('xiaozhou',20);
Query OK, 1 row affected (0.02 sec)

#一次插入多条
mysql> INSERT INTO stu (name,age)VALUES('test1',20),('test2',21),('test3',22);
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

#有默认值的用默认值,没有默认值的用NULL值
mysql> INSERT stu (age,is_del)VALUES(23,0);
Query OK, 1 row affected (0.00 sec)

#查看
mysql> select * from stu;
+----+----------+------+--------+--------+
| id | name     | age  | gender | is_del |
+----+----------+------+--------+--------+
| 10 | xiaoming |   20 | M      |      0 |
| 11 | xiaohong |   18 | F      |      0 |
| 12 | xiaoli   |   19 | F      |      0 |
| 13 | xiaozhou |   20 | M      |      1 |
| 14 | test1    |   20 | M      |      1 |
| 15 | test2    |   21 | M      |      1 |
| 16 | test3    |   22 | M      |      1 |
| 17 | NULL     |   23 | M      |      0 |
+----+----------+------+--------+--------+
8 rows in set (0.00 sec)

#如果记录不存在就新增,如果存在就更新
mysql> SELECT * FROM stu WHERE id=12;
+----+--------+------+--------+--------+
| id | name   | age  | gender | is_del |
+----+--------+------+--------+--------+
| 12 | xiaoli |   19 | F      |      0 |
+----+--------+------+--------+--------+
1 row in set (0.00 sec)

mysql> INSERT INTO stu (id,name)VALUES(12,'zhangsan');
ERROR 1062 (23000): Duplicate entry '12' for key 'stu.PRIMARY'

mysql> INSERT INTO stu (id,name)VALUES(12,'zhangsan') ON DUPLICATE KEY UPDATE name='zhangsan';
Query OK, 2 rows affected (0.00 sec)

mysql> SELECT * FROM stu WHERE id=12;
+----+----------+------+--------+--------+
| id | name     | age  | gender | is_del |
+----+----------+------+--------+--------+
| 12 | zhangsan |   19 | F      |      0 |
+----+----------+------+--------+--------+
1 row in set (0.00 sec)

#将查询结果当值插入
mysql> insert into stu (name,age,gender) select name,age,gender from stu where id=11;
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> select * from stu;
+----+----------+------+--------+--------+
| id | name     | age  | gender | is_del |
+----+----------+------+--------+--------+
| 10 | xiaoming |   20 | M      |      0 |
| 11 | xiaohong |   18 | F      |      0 |
| 12 | zhangsan |   19 | F      |      0 |
| 13 | xiaozhou |   20 | M      |      1 |
| 14 | test1    |   20 | M      |      1 |
| 15 | test2    |   21 | M      |      1 |
| 16 | test3    |   22 | M      |      1 |
| 17 | NULL     |   23 | M      |      0 |
| 18 | xiaohong |   18 | F      |      1 |
+----+----------+------+--------+--------+
9 rows in set (0.00 sec)

mysql> insert into stu (name,age,gender) select name,age,gender from stu where id in (11,12);
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from stu;
+----+----------+------+--------+--------+
| id | name     | age  | gender | is_del |
+----+----------+------+--------+--------+
| 10 | xiaoming |   20 | M      |      0 |
| 11 | xiaohong |   18 | F      |      0 |
| 12 | zhangsan |   19 | F      |      0 |
| 13 | xiaozhou |   20 | M      |      1 |
| 14 | test1    |   20 | M      |      1 |
| 15 | test2    |   21 | M      |      1 |
| 16 | test3    |   22 | M      |      1 |
| 17 | NULL     |   23 | M      |      0 |
| 18 | xiaohong |   18 | F      |      1 |
| 19 | xiaohong |   18 | F      |      1 |
| 20 | zhangsan |   19 | F      |      1 |
+----+----------+------+--------+--------+
11 rows in set (0.00 sec)

更新数据

更新数据一定要加条件限制,没有条件则会更新表中所有记录。

mysql 复制代码
UPDATE [LOW_PRIORITY] [IGNORE] table_reference
    SET assignment_list
    [WHERE where_condition]
    [ORDER BY ...]
    [LIMIT row_count]

范例

bash 复制代码
#不加条件表示更新所有
mysql> UPDATE stu set age=30,gender='F';
Query OK, 11 rows affected (0.00 sec)
Rows matched: 11  Changed: 11  Warnings: 0

mysql> select * from stu;
+----+----------+------+--------+--------+
| id | name     | age  | gender | is_del |
+----+----------+------+--------+--------+
| 10 | xiaoming |   30 | F      |      0 |
| 11 | xiaohong |   30 | F      |      0 |
| 12 | zhangsan |   30 | F      |      0 |
| 13 | xiaozhou |   30 | F      |      1 |
| 14 | test1    |   30 | F      |      1 |
| 15 | test2    |   30 | F      |      1 |
| 16 | test3    |   30 | F      |      1 |
| 17 | NULL     |   30 | F      |      0 |
| 18 | xiaohong |   30 | F      |      1 |
| 19 | xiaohong |   30 | F      |      1 |
| 20 | zhangsan |   30 | F      |      1 |
+----+----------+------+--------+--------+
11 rows in set (0.00 sec)

#根据条件更新
mysql> update stu set age=31 WHERE id>15;
Query OK, 5 rows affected (0.01 sec)
Rows matched: 5  Changed: 5  Warnings: 0

mysql> select * from stu;
+----+----------+------+--------+--------+
| id | name     | age  | gender | is_del |
+----+----------+------+--------+--------+
| 10 | xiaoming |   30 | F      |      0 |
| 11 | xiaohong |   30 | F      |      0 |
| 12 | zhangsan |   30 | F      |      0 |
| 13 | xiaozhou |   30 | F      |      1 |
| 14 | test1    |   30 | F      |      1 |
| 15 | test2    |   30 | F      |      1 |
| 16 | test3    |   31 | F      |      1 |
| 17 | NULL     |   31 | F      |      0 |
| 18 | xiaohong |   31 | F      |      1 |
| 19 | xiaohong |   31 | F      |      1 |
| 20 | zhangsan |   31 | F      |      1 |
+----+----------+------+--------+--------+
11 rows in set (0.00 sec)

#多个条件,满足任何一个条件都更新 OR 可以写成 ||
mysql> update stu set age=21,gender='M' where (id=15 OR name is null);
Query OK, 2 rows affected (0.01 sec)
Rows matched: 2  Changed: 2  Warnings: 0

mysql> select * from stu;
+----+----------+------+--------+--------+
| id | name     | age  | gender | is_del |
+----+----------+------+--------+--------+
| 10 | xiaoming |   30 | F      |      0 |
| 11 | xiaohong |   30 | F      |      0 |
| 12 | zhangsan |   30 | F      |      0 |
| 13 | xiaozhou |   30 | F      |      1 |
| 14 | test1    |   30 | F      |      1 |
| 15 | test2    |   21 | M      |      1 |
| 16 | test3    |   31 | F      |      1 |
| 17 | NULL     |   21 | M      |      0 |
| 18 | xiaohong |   31 | F      |      1 |
| 19 | xiaohong |   31 | F      |      1 |
| 20 | zhangsan |   31 | F      |      1 |
+----+----------+------+--------+--------+
11 rows in set (0.00 sec)

#多个条件满足,AND 可以写成 &&
mysql> update stu set age=22,gender='M' WHERE (id=17 AND name is null);
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from stu;
+----+----------+------+--------+--------+
| id | name     | age  | gender | is_del |
+----+----------+------+--------+--------+
| 10 | xiaoming |   30 | F      |      0 |
| 11 | xiaohong |   30 | F      |      0 |
| 12 | zhangsan |   30 | F      |      0 |
| 13 | xiaozhou |   30 | F      |      1 |
| 14 | test1    |   30 | F      |      1 |
| 15 | test2    |   21 | M      |      1 |
| 16 | test3    |   31 | F      |      1 |
| 17 | NULL     |   22 | M      |      0 |
| 18 | xiaohong |   31 | F      |      1 |
| 19 | xiaohong |   31 | F      |      1 |
| 20 | zhangsan |   31 | F      |      1 |
+----+----------+------+--------+--------+
11 rows in set (0.00 sec)

#NULL要写 IS NULL
mysql> update stu set gender='F' where name=NULL;
Query OK, 0 rows affected (0.01 sec)
Rows matched: 0  Changed: 0  Warnings: 0

mysql> update stu set gender='F' where name IS NULL;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0

保证无法在没有条件的情况下更新所有

bash 复制代码
-U, --i-am-a-dummy  Synonym for option --safe-updates, -U.
[root@localhost ~]# mysql -U

#该配置还可以写到配置文件中
[root@localhost ~]# vim /etc/my.cnf.d/client.cnf
[client]
safe-updates

#无法完全更新
mysql> update stu set age=22;
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.

mysql> update stu set age=23 where name='test3';
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.

#必须要指定主键
mysql> UPDATE stu SET age=23 WHERE id=17;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from stu;
+----+----------+------+--------+--------+
| id | name     | age  | gender | is_del |
+----+----------+------+--------+--------+
| 10 | xiaoming |   30 | F      |      0 |
| 11 | xiaohong |   30 | F      |      0 |
| 12 | zhangsan |   30 | F      |      0 |
| 13 | xiaozhou |   30 | F      |      1 |
| 14 | test1    |   30 | F      |      1 |
| 15 | test2    |   21 | M      |      1 |
| 16 | test3    |   31 | F      |      1 |
| 17 | NULL     |   23 | F      |      0 |
| 18 | xiaohong |   31 | F      |      1 |
| 19 | xiaohong |   31 | F      |      1 |
| 20 | zhangsan |   31 | F      |      1 |
+----+----------+------+--------+--------+
11 rows in set (0.00 sec)

删除数据

格式

bash 复制代码
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
    tbl_name[.*] [, tbl_name[.*]] ...
    FROM table_references
    [WHERE where_condition]

DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
    FROM tbl_name[.*] [, tbl_name[.*]] ...
    USING table_references
    [WHERE where_condition]

范例

bash 复制代码
#查看全部数据
mysql> select * from stu;
+----+----------+------+--------+--------+
| id | name     | age  | gender | is_del |
+----+----------+------+--------+--------+
| 10 | xiaoming |   30 | F      |      0 |
| 11 | xiaohong |   30 | F      |      0 |
| 12 | zhangsan |   30 | F      |      0 |
| 13 | xiaozhou |   30 | F      |      1 |
| 14 | test1    |   30 | F      |      1 |
| 15 | test2    |   21 | M      |      1 |
| 16 | test3    |   31 | F      |      1 |
| 17 | NULL     |   23 | F      |      0 |
| 18 | xiaohong |   31 | F      |      1 |
| 19 | xiaohong |   31 | F      |      1 |
| 20 | zhangsan |   31 | F      |      1 |
+----+----------+------+--------+--------+
11 rows in set (0.00 sec)

#根据条件删除
mysql> delete from stu where id=10;
Query OK, 1 row affected (0.00 sec)

mysql> select * from stu;
+----+----------+------+--------+--------+
| id | name     | age  | gender | is_del |
+----+----------+------+--------+--------+
| 11 | xiaohong |   30 | F      |      0 |
| 12 | zhangsan |   30 | F      |      0 |
| 13 | xiaozhou |   30 | F      |      1 |
| 14 | test1    |   30 | F      |      1 |
| 15 | test2    |   21 | M      |      1 |
| 16 | test3    |   31 | F      |      1 |
| 17 | NULL     |   23 | F      |      0 |
| 18 | xiaohong |   31 | F      |      1 |
| 19 | xiaohong |   31 | F      |      1 |
| 20 | zhangsan |   31 | F      |      1 |
+----+----------+------+--------+--------+
10 rows in set (0.00 sec)

在真实生产环境中,一般不会对数据做物理删除,而是用字段来标记为逻辑删除,将对应字段值设为某个特定项(is_del),(is_del=1)认为是已删除

bash 复制代码
mysql> UPDATE stu SET is_del=1 WHERE id=11;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1  Changed: 0  Warnings: 0

mysql> select * from stu;
+----+----------+------+--------+--------+
| id | name     | age  | gender | is_del |
+----+----------+------+--------+--------+
| 11 | xiaohong |   30 | F      |      1 |
| 12 | zhangsan |   30 | F      |      0 |
| 13 | xiaozhou |   30 | F      |      1 |
| 14 | test1    |   30 | F      |      1 |
| 15 | test2    |   21 | M      |      1 |
| 16 | test3    |   31 | F      |      1 |
| 17 | NULL     |   23 | F      |      0 |
| 18 | xiaohong |   31 | F      |      1 |
| 19 | xiaohong |   31 | F      |      1 |
| 20 | zhangsan |   31 | F      |      1 |
+----+----------+------+--------+--------+
10 rows in set (0.00 sec)

清空表

bash 复制代码
TRUNCATE TABLE tbl_name;   #DDL语句,不支持事务,效率更高
DELETE FROM tbl_name;      #DML语句

DQL 语句

格式

bash 复制代码
mysql> help select
Name: 'SELECT'
Description:
Syntax:
SELECT
    [ALL | DISTINCT | DISTINCTROW ]
    [HIGH_PRIORITY]
    [STRAIGHT_JOIN]
    [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
    [SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
    select_expr [, select_expr] ...
    [into_option]
    [FROM table_references
      [PARTITION partition_list]]
    [WHERE where_condition]
    [GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]]
    [HAVING where_condition]
    [WINDOW window_name AS (window_spec)
        [, window_name AS (window_spec)] ...]
    [ORDER BY {col_name | expr | position}
      [ASC | DESC], ... [WITH ROLLUP]]
    [LIMIT {[offset,] row_count | row_count OFFSET offset}]
    [into_option]
    [FOR {UPDATE | SHARE}
        [OF tbl_name [, tbl_name] ...]
        [NOWAIT | SKIP LOCKED]
      | LOCK IN SHARE MODE]
    [into_option]

into_option: {
    INTO OUTFILE 'file_name'
        [CHARACTER SET charset_name]
        export_options
  | INTO DUMPFILE 'file_name'
  | INTO var_name [, var_name] ...
}

说明

字段显示可以使用别名:col1 AS alias1, col2 AS alias2,...

WHERE 子句:指明过滤条件以实现「选择」的功能

过滤条件:布尔型表达式

算术操作符:+, -, *, /, %

比较操作符:=, <=>(相等或都为空), <>, !=(非标准 SQL), >, >=, <, <=

范围查询:BETWEEN min_num AND max_num

不连续的查询:IN(element1, element2, ...)

空查询:IS NULL, IS NOT NULL

DISTINCT 去除重复行,范例:SELECT DISTINCT gender FROM students;

模糊查询:LIKE 使用 % 表示任意长度的任意字符,_ 表示任意单个字符

RLIKE:正则表达式,索引失效,不建议使用

REGEXP:匹配字符串可用正则表达式书写模式,同上

逻辑操作符:NOT, AND, OR, XOR

GROUP BY:根据指定的条件把查询结果进行「分组」以用于做「聚合」运算

常见聚合函数:count(), sum(), max(), min(), avg(),注意:聚合函数不对 null 统计

HAVING:对分组聚合运算后的结果指定过滤条件

一旦分组 group by,select 语句后只跟分组的字段、聚合函数

ORDER BY:根据指定的字段对查询结果进行排序

升序:ASC

降序:DESC

LIMIT offset, row_count:对查询的结果进行输出行数数量限制,跳过 offset,显示 row_count 行,offset 默认值为 0。

对查询结果中的数据请求施加「锁」

FOR UPDATE:写锁,独占或排它锁,只有一个读和写操作

LOCK IN SHARE MODE:读锁,共享锁,同时多个读操作

单表操作

范例:查字符串和变量
bash 复制代码
#直接查字符串
mysql> select 123;
+-----+
| 123 |
+-----+
| 123 |
+-----+
1 row in set (0.00 sec)

#指定别名
mysql> select 'gqd' as 'liu';
+--------+
| liu |
+--------+
| gqd    |
+--------+
1 row in set (0.00 sec)

#数学计算
mysql> select 1+2*3;
+-------+
| 1+2*3 |
+-------+
|     7 |
+-------+
1 row in set (0.01 sec)

#查询变量
mysql> select @@port;
+--------+
| @@port |
+--------+
|   3306 |
+--------+
1 row in set (0.01 sec)

#查询函数
mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2025-09-21 20:52:19 |
+---------------------+
1 row in set (0.00 sec)
范例:指定字段和查询条件
bash 复制代码
#全表扫描
mysql>  select * from stu;
+----+----------+------+--------+--------+
| id | name     | age  | gender | is_del |
+----+----------+------+--------+--------+
| 11 | xiaohong |   30 | F      |      1 |
| 12 | zhangsan |   30 | F      |      0 |
| 13 | xiaozhou |   30 | F      |      1 |
| 14 | test1    |   30 | F      |      1 |
| 15 | test2    |   21 | M      |      1 |
| 16 | test3    |   31 | F      |      1 |
| 17 | NULL     |   23 | F      |      0 |
| 18 | xiaohong |   31 | F      |      1 |
| 19 | xiaohong |   31 | F      |      1 |
| 20 | zhangsan |   31 | F      |      1 |
+----+----------+------+--------+--------+
10 rows in set (0.00 sec)

#查询指定字段
mysql> select id as 学号,name as 姓名,age as 年纪 from stu;
+--------+----------+--------+
| 学号   | 姓名     | 年纪   |
+--------+----------+--------+
|     11 | xiaohong |     30 |
|     12 | zhangsan |     30 |
|     13 | xiaozhou |     30 |
|     14 | test1    |     30 |
|     15 | test2    |     21 |
|     16 | test3    |     31 |
|     17 | NULL     |     23 |
|     18 | xiaohong |     31 |
|     19 | xiaohong |     31 |
|     20 | zhangsan |     31 |
+--------+----------+--------+
10 rows in set (0.00 sec)

#根据条件查询
mysql> select id,name from stu where id=11;
+----+----------+
| id | name     |
+----+----------+
| 11 | xiaohong |
+----+----------+
1 row in set (0.00 sec)

#多条
mysql> select id,name from stu where id in(11,15,19);
+----+----------+
| id | name     |
+----+----------+
| 11 | xiaohong |
| 15 | test2    |
| 19 | xiaohong |
+----+----------+
3 rows in set (0.00 sec)

#and 可以写为 &&
mysql> select id,name from stu where id>=11 and id <14;
+----+----------+
| id | name     |
+----+----------+
| 11 | xiaohong |
| 12 | zhangsan |
| 13 | xiaozhou |
+----+----------+
3 rows in set (0.00 sec)

#or 可以写为 ||
mysql> select id,name from stu where id<=12 or id>19;
+----+----------+
| id | name     |
+----+----------+
| 11 | xiaohong |
| 12 | zhangsan |
| 20 | zhangsan |
+----+----------+
3 rows in set (0.00 sec)
范例:NULL 值
bash 复制代码
mysql> select id,name,age from stu where name=NUll;    #语法错误
Empty set (0.01 sec)

#null值
mysql> select id,name,age from stu where name IS NULL;
+----+------+------+
| id | name | age  |
+----+------+------+
| 17 | NULL |   23 |
+----+------+------+
1 row in set (0.00 sec)

#非null值
mysql> select id,name,age from stu where name is not null;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
| 11 | xiaohong |   30 |
| 12 | zhangsan |   30 |
| 13 | xiaozhou |   30 |
| 14 | test1    |   30 |
| 15 | test2    |   21 |
| 16 | test3    |   31 |
| 18 | xiaohong |   31 |
| 19 | xiaohong |   31 |
| 20 | zhangsan |   31 |
+----+----------+------+
9 rows in set (0.00 sec)
范例:模糊匹配
bash 复制代码
#以指定字符开头
mysql> select id,name from stu where name like 'x%';
+----+----------+
| id | name     |
+----+----------+
| 11 | xiaohong |
| 13 | xiaozhou |
| 18 | xiaohong |
| 19 | xiaohong |
+----+----------+
4 rows in set (0.00 sec)

#以指定字符开头
mysql> select id,name from stu where name like 'xiao%';
+----+----------+
| id | name     |
+----+----------+
| 11 | xiaohong |
| 13 | xiaozhou |
| 18 | xiaohong |
| 19 | xiaohong |
+----+----------+
4 rows in set (0.00 sec)

#以指定字符结尾
mysql> select id,name from stu where name like '%ng';
+----+----------+
| id | name     |
+----+----------+
| 11 | xiaohong |
| 18 | xiaohong |
| 19 | xiaohong |
+----+----------+
3 rows in set (0.00 sec)

#包含指定字符串
mysql> select id,name from stu where name like '%ou%';
+----+----------+
| id | name     |
+----+----------+
| 13 | xiaozhou |
+----+----------+
1 row in set (0.00 sec)

#多个LIKE
mysql> select id,name from stu where name like '%n%' or name like '%i%';
+----+----------+
| id | name     |
+----+----------+
| 11 | xiaohong |
| 12 | zhangsan |
| 13 | xiaozhou |
| 18 | xiaohong |
| 19 | xiaohong |
| 20 | zhangsan |
+----+----------+
6 rows in set (0.01 sec)
范例:区间过滤
bash 复制代码
#连续
mysql> select id,name from stu where id between 12 and 15;
+----+----------+
| id | name     |
+----+----------+
| 12 | zhangsan |
| 13 | xiaozhou |
| 14 | test1    |
| 15 | test2    |
+----+----------+
4 rows in set (0.00 sec)

#取反
mysql> select id,name from stu where id not between 12 and 15;
+----+----------+
| id | name     |
+----+----------+
| 11 | xiaohong |
| 16 | test3    |
| 17 | NULL     |
| 18 | xiaohong |
| 19 | xiaohong |
| 20 | zhangsan |
+----+----------+
6 rows in set (0.00 sec)

#不连续
mysql> select id,name from stu where id in(12,15,19);
+----+----------+
| id | name     |
+----+----------+
| 12 | zhangsan |
| 15 | test2    |
| 19 | xiaohong |
+----+----------+
3 rows in set (0.01 sec)

#不连续取反
mysql> select id,name from stu where id not in (12,15,19);
+----+----------+
| id | name     |
+----+----------+
| 11 | xiaohong |
| 13 | xiaozhou |
| 14 | test1    |
| 16 | test3    |
| 17 | NULL     |
| 18 | xiaohong |
| 20 | zhangsan |
+----+----------+
7 rows in set (0.00 sec)
范例:统计和分组
bash 复制代码
#统计表中的记录条数
mysql> select count(*) as total from stu;
+-------+
| total |
+-------+
|    10 |
+-------+
1 row in set (0.00 sec)

#name字段中有null,不统计
mysql> select count(name) from stu;
+-------------+
| count(name) |
+-------------+
|           9 |
+-------------+
1 row in set (0.00 sec)

mysql> select count(id) from stu;
+-----------+
| count(id) |
+-----------+
|        10 |
+-----------+
1 row in set (0.00 sec)

#最大值,最小值,平均值
mysql> select max(id),min(id),avg(age) from stu;
+---------+---------+----------+
| max(id) | min(id) | avg(age) |
+---------+---------+----------+
|      20 |      11 |  28.8000 |
+---------+---------+----------+
1 row in set (0.00 sec)

#求和
mysql> select sum(age) from stu;
+----------+
| sum(age) |
+----------+
|      288 |
+----------+
1 row in set (0.00 sec)

#分组统计
mysql> select sum(age),gender from stu group by gender;
+----------+--------+
| sum(age) | gender |
+----------+--------+
|      183 | F      |
|      105 | M      |
+----------+--------+
2 rows in set (0.00 sec)

#分组统计
mysql> select count(*),gender from stu group by gender;
+----------+--------+
| count(*) | gender |
+----------+--------+
|        6 | F      |
|        4 | M      |
+----------+--------+
2 rows in set (0.00 sec)

#分组带where条件
mysql> select count(*),max(id),avg(age),gender from stu where name is not null group by gender;
+----------+---------+----------+--------+
| count(*) | max(id) | avg(age) | gender |
+----------+---------+----------+--------+
|        6 |      19 |  30.5000 | F      |
|        3 |      20 |  27.3333 | M      |
+----------+---------+----------+--------+
2 rows in set (0.00 sec)

#分组后过滤
mysql> select count(*) as total,max(id),avg(age),gender from stu where name is not null group by gender having total=3;
+-------+---------+----------+--------+
| total | max(id) | avg(age) | gender |
+-------+---------+----------+--------+
|     3 |      20 |  27.3333 | M      |
+-------+---------+----------+--------+
1 row in set (0.00 sec)

#分组统计
mysql> select count(*),max(id),avg(age),gender from stu group by gender;                                            
+----------+---------+----------+--------+
| count(*) | max(id) | avg(age) | gender |
+----------+---------+----------+--------+
|        6 |      19 |  30.5000 | F      |
|        4 |      20 |  26.2500 | M      |
+----------+---------+----------+--------+
2 rows in set (0.00 sec)

mysql> 
范例:排序
bash 复制代码
#默认按ID升序排列
mysql> select id,name,age from stu;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
| 11 | xiaohong |   30 |
| 12 | zhangsan |   30 |
| 13 | xiaozhou |   30 |
| 14 | test1    |   30 |
| 15 | test2    |   21 |
| 16 | test3    |   31 |
| 17 | NULL     |   23 |
| 18 | xiaohong |   31 |
| 19 | xiaohong |   31 |
| 20 | zhangsan |   31 |
+----+----------+------+
10 rows in set (0.00 sec)

mysql> select id,name,age from stu order by id;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
| 11 | xiaohong |   30 |
| 12 | zhangsan |   30 |
| 13 | xiaozhou |   30 |
| 14 | test1    |   30 |
| 15 | test2    |   21 |
| 16 | test3    |   31 |
| 17 | NULL     |   23 |
| 18 | xiaohong |   31 |
| 19 | xiaohong |   31 |
| 20 | zhangsan |   31 |
+----+----------+------+
10 rows in set (0.00 sec)

mysql> select id,name,age from stu order by id asc;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
| 11 | xiaohong |   30 |
| 12 | zhangsan |   30 |
| 13 | xiaozhou |   30 |
| 14 | test1    |   30 |
| 15 | test2    |   21 |
| 16 | test3    |   31 |
| 17 | NULL     |   23 |
| 18 | xiaohong |   31 |
| 19 | xiaohong |   31 |
| 20 | zhangsan |   31 |
+----+----------+------+
10 rows in set (0.00 sec)

#降序
mysql> select id,name,age from stu order by id desc;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
| 20 | zhangsan |   31 |
| 19 | xiaohong |   31 |
| 18 | xiaohong |   31 |
| 17 | NULL     |   23 |
| 16 | test3    |   31 |
| 15 | test2    |   21 |
| 14 | test1    |   30 |
| 13 | xiaozhou |   30 |
| 12 | zhangsan |   30 |
| 11 | xiaohong |   30 |
+----+----------+------+
10 rows in set (0.00 sec)

#降序变升序
mysql> select id,name,age from stu order by -id desc;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
| 11 | xiaohong |   30 |
| 12 | zhangsan |   30 |
| 13 | xiaozhou |   30 |
| 14 | test1    |   30 |
| 15 | test2    |   21 |
| 16 | test3    |   31 |
| 17 | NULL     |   23 |
| 18 | xiaohong |   31 |
| 19 | xiaohong |   31 |
| 20 | zhangsan |   31 |
+----+----------+------+
10 rows in set (0.00 sec)

#用分组结果排序
mysql> select sum(age) as sum_age,avg(age) avg_age,gender 性别 from stu where name is not null group by gender order by sum_age asc;
+---------+---------+--------+
| sum_age | avg_age | 性别   |
+---------+---------+--------+
|      82 | 27.3333 | M      |
|     183 | 30.5000 | F      |
+---------+---------+--------+
2 rows in set (0.00 sec)

mysql> 
范例:去重
bash 复制代码
mysql> select id,name,age from stu order by age desc;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
| 16 | test3    |   31 |
| 18 | xiaohong |   31 |
| 19 | xiaohong |   31 |
| 20 | zhangsan |   31 |
| 11 | xiaohong |   30 |
| 12 | zhangsan |   30 |
| 13 | xiaozhou |   30 |
| 14 | test1    |   30 |
| 17 | NULL     |   23 |
| 15 | test2    |   21 |
+----+----------+------+
10 rows in set (0.00 sec)

#去重
mysql> select distinct age from stu order by age desc;
+------+
| age  |
+------+
|   31 |
|   30 |
|   23 |
|   21 |
+------+
4 rows in set (0.00 sec)

#去重
mysql> select distinct(age) from stu order by age desc;
+------+
| age  |
+------+
|   31 |
|   30 |
|   23 |
|   21 |
+------+
4 rows in set (0.00 sec)
范例:分页
bash 复制代码
mysql> select id,name from stu;
+----+----------+
| id | name     |
+----+----------+
| 11 | xiaohong |
| 12 | zhangsan |
| 13 | xiaozhou |
| 14 | test1    |
| 15 | test2    |
| 16 | test3    |
| 17 | NULL     |
| 18 | xiaohong |
| 19 | xiaohong |
| 20 | zhangsan |
+----+----------+
10 rows in set (0.00 sec)

#第一页,每页3条记录
# 0,3 跳过第0条从第一条开始,显示3条
mysql> select id,name from stu limit 0,3;
+----+----------+
| id | name     |
+----+----------+
| 11 | xiaohong |
| 12 | zhangsan |
| 13 | xiaozhou |
+----+----------+
3 rows in set (0.00 sec)

#第二页,每页3条记录
mysql> select id,name from stu limit 3,3;
+----+-------+
| id | name  |
+----+-------+
| 14 | test1 |
| 15 | test2 |
| 16 | test3 |
+----+-------+
3 rows in set (0.00 sec)

#第三页,每页3条记录
mysql> select id,name from stu limit 6,3;
+----+----------+
| id | name     |
+----+----------+
| 17 | NULL     |
| 18 | xiaohong |
| 19 | xiaohong |
+----+----------+
3 rows in set (0.01 sec)

多表查询

简单案例

准备表:yuangong(员工)、bumen(部门)

创建表(只有员工表、部门表)
sql 复制代码
-- 部门表
CREATE TABLE bumen (
    bumen_id   INT PRIMARY KEY,  -- 部门ID
    bumen_name VARCHAR(20)       -- 部门名称
);

-- 员工表
CREATE TABLE yuangong (
    yuangong_id INT PRIMARY KEY, -- 员工ID
    name        VARCHAR(20),     -- 员工姓名
    bumen_id    INT              -- 所属部门ID(用来关联)
);
插入测试数据
sql 复制代码
-- 部门:技术部、产品部、运营部
INSERT INTO bumen VALUES
(1, '技术部'),
(2, '产品部'),
(3, '运营部');

-- 员工
INSERT INTO yuangong VALUES
(101, '张三', 1),    -- 技术部
(102, '李四', 1),    -- 技术部
(103, '王五', 2),    -- 产品部
(104, '赵六', NULL); -- 没有部门

数据情况:

  • bumen: 1 技术、2 产品、3 运营
  • yuangong: 张三、李四、王五(有部门),赵六(无部门)

多表查询
交叉连接 CROSS JOIN

两张表所有行两两组合 ,不看任何关联条件,叫笛卡尔积

语法

语法介绍

  • 不需要 ON 条件
  • 结果行数 = 表 1 行数 × 表 2 行数
  • 实际开发几乎不用,容易产生巨量数据
sql 复制代码
SELECT 列名
FROM 表1
CROSS JOIN 表2;

完整 SQL

sql 复制代码
SELECT *
FROM bumen
CROSS JOIN yuangong;

结果:3 部门 × 4 员工 = 12 条数据

实际开发极少用。


内连接 INNER JOIN

只显示两边表能匹配上的数据(交集)。

部门存在、员工也归属这个部门,才显示。

语法

语法介绍

  • INNER JOIN:内连接关键字
  • ON必须写关联条件
  • 只保留两边都存在的数据

完整 SQL

sql 复制代码
SELECT *
FROM bumen
INNER JOIN yuangong
ON bumen.bumen_id = yuangong.bumen_id;

结果:

张三、李四、王五 显示

赵六(无部门)、运营部(无人)都不显示


左连接 LEFT JOIN

左边表(bumen)全部保留

右边表(yuangong)能匹配就显示,不能匹配显示 NULL

语法

LEFT JOIN = 左表全部保留

ON 关联条件必须写

左表数据一条都不会少

sql 复制代码
SELECT 列名
FROM 表1
LEFT JOIN 表2
ON 表1.关联字段 = 表2.关联字段;

SQL

sql 复制代码
SELECT *
FROM bumen
LEFT JOIN yuangong
ON bumen.bumen_id = yuangong.bumen_id;

结果:

技术部、产品部、运营部 全部显示

运营部没有员工 → 员工部分为 NULL


右连接 RIGHT JOIN

右边表(yuangong)全部保留

左边表(bumen)能匹配就显示,不能匹配显示 NULL

语法

  • RIGHT JOIN = 右表全部保留
  • 右表数据一条都不会少
sql 复制代码
SELECT 列名
FROM 表1
RIGHT JOIN 表2
ON 表1.关联字段 = 表2.关联字段;

SQL

复制代码
SELECT *
FROM bumen
RIGHT JOIN yuangong
ON bumen.bumen_id = yuangong.bumen_id;

结果:

张三、李四、王五、赵六 全部显示

赵六没有部门 → 部门部分为 NULL


全连接 FULL JOIN(MySQL 模拟)

左边全部 + 右边全部,一条数据都不丢(并集)

MySQL 不支持直接 FULL JOIN,用 LEFT JOIN + UNION + RIGHT JOIN 实现

语法

UNION:合并两个查询结果,自动去重

最终结果:所有部门 + 所有员工,一个不丢

SQL

sql 复制代码
SELECT * FROM bumen LEFT JOIN yuangong ON bumen.bumen_id = yuangong.bumen_id
UNION
SELECT * FROM bumen RIGHT JOIN yuangong ON bumen.bumen_id = yuangong.bumen_id;

结果:

所有部门 + 所有员工,全部显示,缺的部分为 NULL


自连接 SELF JOIN

一张表自己连接自己,把同一张表当两张表用

常用于:员工 - 领导、分类 - 父分类

语法

同一张表:yuangong eyuangong l

必须起不同别名(e 员工,l 领导)

本质还是 JOIN,只是表是同一张

sql 复制代码
SELECT 别名1.列名, 别名2.列名
FROM 表名 别名1
JOIN 表名 别名2
ON 别名1.字段 = 别名2.字段;

先加领导字段:

sql 复制代码
ALTER TABLE yuangong ADD leader_id INT;
UPDATE yuangong SET leader_id = 101 WHERE yuangong_id = 102;

含义:张三是李四的领导

查询:员工姓名 + 领导姓名

sql 复制代码
SELECT
    e.name AS 员工,
    l.name AS 领导
FROM yuangong e
LEFT JOIN yuangong l
ON e.leader_id = l.yuangong_id;

结果:李四 → 领导张三


联合查询 UNION / UNION ALL

不是左右连接,是上下拼接结果

要求:列数相同、类型对应

  • UNION:去重
  • UNION ALL:不去重,速度更快

语法

  • UNION:合并结果,自动去重
  • UNION ALL:合并结果,不去重,速度更快
  • 字段数量必须一样
sql 复制代码
查询1
UNION
查询2

示例:把部门名和员工名合并成一列展示

sql 复制代码
SELECT bumen_name AS name FROM bumen
UNION
SELECT name FROM yuangong;

结果:

技术部、产品部、运营部、张三、李四、王五、赵六

(上下排成一列)


一句话终极总结(必背)

  1. CROSS JOIN:全组合,笛卡尔积
  2. INNER JOIN:两边匹配才显示(交集)
  3. LEFT JOIN:左表全保留
  4. RIGHT JOIN:右表全保留
  5. FULL JOIN:左右都保留(并集)
  6. SELF JOIN:自己连自己(层级关系)
  7. UNION:结果上下拼接
多表查询注意事项
  1. 必须加关联条件:如果忘记加,会产生笛卡尔积,数据量会指数级爆炸。

  2. 优先用 UNION ALL:除非你需要去重,否则用 UNION ALL,效率比 UNION 高很多。

  3. 关联字段加索引:关联的字段(比如 wanjia_id、yingxiong_id)一定要建索引,否则大数据量下查询会很慢。

  4. 注意 NULL 值:左/右连接会产生 NULL 值,写 WHERE 条件的时候要注意,不要误把 NULL 过滤掉。

  5. 表别名简化 SQL:给表起短别名(比如 wj、yx、zj),可以大幅简化 SQL,提高可读性。

MySQL 用户管理

MySQL 服务的账户是独立存在的,只用于 MySQL 服务的登录验证。

虚拟用户:给服务和应用使用的用户账号。

系统用户:Linux 系统使用的用户账号

在 MySQL 服务中,用户组成包括用户名、主机、密码等。

Host 指主机,表示只有在该主机上才能使用对应的账号连接 MySQL 服务器,主机限制了账号可以登录的位置。用户名可以相同,主机也可以相同,用户名和主机组合起来才能标识一个唯一用户。

其它数据库系统,例如 SQL Server、Oracle 等都没有此限制,只要账号和密码能校验通过即可登录。这也是 MySQL 与其它数据库系统的一个不同之处。

Host 可以写成主机名、IP 地址、网段。可以用 %、_ 来表示通配符,% 表示任意长度的任意字符,_ 表示一个字符。

范例:

bash 复制代码
#主机名
gqd@'mysql.liu.cloud'
gqd@'localhost'

#IP地址
gqd@'10.0.0.110'
gqd@'172.16.10.110'

#网段
gqd@′10.0.0.0/255.255.0.0'
gqd@′172.16.10.0/255.255.255.0'

#通配符
gqd@′10.0.%.%
gqd@'172.16.%.%'

MySQL 8.0 中默认没有可以远程登录的用户

bash 复制代码
mysql> use mysql;
#前三个是MySQL服务自身使用
mysql> select User,Host from user;
+------------------+-----------+
| User             | Host      |
+------------------+-----------+
| mysql.infoschema | localhost |
| mysql.session    | localhost |
| mysql.sys        | localhost |
| root             | localhost |
+------------------+-----------+
4 rows in set (0.00 sec)

#现在使用的是第四个
mysql> select user();
+----------------+
| user()         |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

#也可以用status命令来查看
mysql> status
--------------
mysql  Ver 8.0.26 for Linux on x86_64 (Source distribution)

Connection id:          9
Current database:       mysql
Current user:           root@localhost
SSL:                    Not in use
Current pager:          stdout
Using outfile:          ''
Using delimiter:        ;
Server version:         8.0.26 Source distribution
Protocol version:       10
Connection:             Localhost via UNIX socket
Server characterset:    utf8mb4
Db     characterset:    utf8mb4
Client characterset:    utf8mb4
Conn.  characterset:    utf8mb4
UNIX socket:            /var/lib/mysql/mysql.sock
Binary data as:         Hexadecimal
Uptime:                 38 min 22 sec

Threads: 2  Questions: 93  Slow queries: 0  Opens: 199  Flush tables: 3  Open tables: 118  Queries per second avg: 0.040
--------------

#无法在远程主机上连接当前主机的MySQL服务
#192.168.108.128是mysql主机ip地址,自己ip -br a检测
#本地PC打开CMD 远程过来(192.168.108.1)
C:\Users\69466>mysql -uroot -h192.168.108.128 -phuawei
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1130 (HY000): Host '192.168.108.1' is not allowed to connect to this MySQL server

创建用户:CREATE USER

bash 复制代码
#格式
CREATE USER 'USERNAME'@'HOST' [IDENTIFIED BY 'password'];

#范例
create user test@'192.168.108.0/255.255.255.0' identified by '123456';
create user test2@'192.168.108.%' identified by '123456';

重命名用户:RENAME USER

bash 复制代码
RENAME USER 'USERNAME'@'HOST' TO 'USERNAME'@'HOST';

删除用户:DROP USER

bash 复制代码
DROP USER 'USERNAME'@'HOST'

#范例,删除gqd
DROP user test@'192.168.108.0/255.255.255.0'
DROP USER test2@'192.168.108.0.%';

修改密码

新版 MySQL 中用户密码可以保存在 mysql.user 表的 authentication_string 字段中,已经取消了 password 字段。

MariaDB 中某些版本 authentication_string、password 字段共存,旧版以 password 字段为准,新版以 authentication_string 为准。

bash 复制代码
#方式一
SET PASSWORD FOR 'user'@'host' = 'password';


#mysql8.0中取消了PASSWORD方法
mysql> select PASSWORD('123456');
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '('123456')' at line 1
#MariaDB中还有

#在MYSQL8.0中可以使用此写法
#MYSQL8.0中的密码是放在 mysql.user 表中 authentication_string 字段中,但MariaDB中还保留了PASSWORD字段
mysql> select User,Host,authentication_string FROM mysql.user;
+------------------+-----------+------------------------------------------------------------------------+
| User             | Host      | authentication_string                                                  |
+------------------+-----------+------------------------------------------------------------------------+
| mysql.infoschema | localhost | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| mysql.session    | localhost | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| mysql.sys        | localhost | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| root             | localhost |                                                                        |
+------------------+-----------+------------------------------------------------------------------------+
4 rows in set (0.00 sec)

#更新密码
#方式一:
mysql> set password for root@'localhost'='123456';
Query OK, 0 rows affected (0.00 sec)

mysql> select User,Host,authentication_string FROM mysql.user;
+------------------+-----------+------------------------------------------------------------------------+
| User             | Host      | authentication_string                                                  |
+------------------+-----------+------------------------------------------------------------------------+
| mysql.infoschema | localhost | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| mysql.session    | localhost | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| mysql.sys        | localhost | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| root             | localhost | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9                              |
+------------------+-----------+------------------------------------------------------------------------+
4 rows in set (0.00 sec)


#方式二
语法:ALTER USER test@'%' IDENTIFIED BY '123456';
#此方法通用
mysql> ALTER USER root@'localhost' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)

#测试
[root@localhost ~]# mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 16
Server version: 8.0.26 Source distribution

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>

#方法三
[root@localhost ~]# mysqladmin -uroot -p123456 password abcde
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
Warning: Since password will be sent to server in plain text, use ssl connection to ensure password safety.

[root@localhost ~]# mysql -uroot -pabcde
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 19
Server version: 8.0.26 Source distribution

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>

忘记密码

bash 复制代码
#方式一,保留原有数据

#1 启动时添加指定项
--skip-grant-tables
--skip-networking

#2 使用UPDATE命令修改管理员密码
#3 移除配置项重启

#方式一范例
[root@localhost ~]# vim /etc/my.cnf.d/mysql-server.cnf
[mysqld]
skip-grant-tables
skip-networking          #MYSQL8.0不需要

[root@localhost ~]# systemctl restart mysqld.service
[root@localhost ~]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 8.0.26 Source distribution

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>

#步骤1
mysql> update mysql.user set authentication_string='' where user='root' and host='localhost';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

#步骤2
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)

#再执行下面命令
mysql> alter user root@'localhost' identified by 'xiaomi';
Query OK, 0 rows affected (0.00 sec)


[root@localhost ~]# vim /etc/my.cnf.d/mysql-server.cnf
[mysqld]
#pid-file=/run/mysqld/mysqld.pid
#skip-grant-tables

[root@localhost ~]# mysql -uroot -pxiaomi
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.26 Source distribution

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> 

范例:删库跑路之清空 root 密码方法

!!!学完就忘

bash 复制代码
#方式二,会清除所有数据
#停止服务
[root@localhost ~]# systemctl stop mysqld.service
#删除数据目录下所有内容
[root@localhost ~]# rm -rf /var/lib/mysql/*
#重启服务,恢复空密码登陆
[root@localhost ~]# systemctl start mysqld.service
[root@localhost ~]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.26 Source distribution

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>

在当前 MySQL 服务中添加用户

mysql 复制代码
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> create user root@'192.168.108.1' identified by '123456';   #需要远程连接本mysql的客户端地址
Query OK, 0 rows affected (0.00 sec)

mysql> select User,Host from mysql.user;
+------------------+---------------+
| User             | Host          |
+------------------+---------------+
| root             | 192.168.108.1 |
| mysql.infoschema | localhost     |
| mysql.session    | localhost     |
| mysql.sys        | localhost     |
| root             | localhost     |
+------------------+---------------+
5 rows in set (0.00 sec)
bash 复制代码
#查看当前客户端连接时适用的用户名和主机
mysql> select user();
+--------------------+
| user()             |
+--------------------+
| root@192.168.108.1 |
+--------------------+
1 row in set (0.00 sec)

#查看线程
mysql> show processlist;
+----+------+---------------------+-------+---------+------+-------+------------------+
| Id | User | Host                | db    | Command | Time | State | Info             |
+----+------+---------------------+-------+---------+------+-------+------------------+
| 11 | root | localhost           | mysql | Sleep   |  360 |       | NULL             |
| 14 | root | 192.168.108.1:63707 | NULL  | Query   |    0 | init  | show processlist |
+----+------+---------------------+-------+---------+------+-------+------------------+
2 rows in set (0.00 sec)

#查看数据库
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
+--------------------+
1 row in set (0.00 sec)

#没有权限
mysql> use msyql;
ERROR 1044 (42000): Access denied for user 'root'@'192.168.108.1' to database 'msyql'

mysql> create database db1;
ERROR 1044 (42000): Access denied for user 'root'@'192.168.108.1' to database 'db1'

权限管理和 DCL 语句

在 MySQL 服务中,新创建的用户仅仅只能连接,没有操作权限,需要配置相应的权限后才能使用。

权限类别

管理类

CREATE USER, FILE, SUPER, SHOW DATABASES, RELOAD, SHUTDOWN, REPLICATION SLAVE, REPLICATION CLIENT, LOCK TABLES, PROCESS, CREATE TEMPORARY TABLES

程序类针对 FUNCTION、PROCEDURE、TRIGGER

CREATE, ALTER, DROP, EXECUTE

库和表级别针对 DATABASE、TABLE

ALTER, CREATE, CREATE VIEW, DROP INDEX, SHOW VIEW, WITH GRANT OPTION(将自己获得的权限转赠给其他用户)

数据操作

SELECT, INSERT, DELETE, UPDATE

字段级别

SELECT(col1, col2, ...), UPDATE(col1, col2, ...), INSERT(col1, col2, ...)

所有权限

ALL PRIVILEGES 或 ALL

授权

格式

bash 复制代码
 mysql> help grant
Name: 'GRANT'
Description:
Syntax:
GRANT
    priv_type [(column_list)]
      [, priv_type [(column_list)]] ...
    ON [object_type] priv_level
    TO user_or_role [, user_or_role] ...
    [WITH GRANT OPTION]
    [AS user
        [WITH ROLE
            DEFAULT
          | NONE
          | ALL
          | ALL EXCEPT role [, role ] ...
          | role [, role ] ...

#priv_type       要授予的权限ALL [PRIVILEGES]
#object_type     对象的类型TABLE|FUNCTION|PROCEDURE
#priv_level      范围  *|*.*|db_name.*|db_name.tbl_name|tbl_name|db_name.routine_name(指定库的函数,存储过程,触发器)
#with_option   选项
				#GRANT OPTION   可以将自己的权限授权给其它账号
				#MAX_QUERIES_PER_HOUR N    每小时最大查询次数
				#MAX_UPDATES_PER_HOUR N    每小时最大更新次数
				#MAX_CONNECTIONS_PER_HOUR N    每小时最大连接次数
				#MAX_USER_CONNECTIONS N    最大用户连接数
#MAX_USER_CONNECTIONS    指的是瞬间的并发连接数,而MAX_CONNECTIONS_PER_HOUR指的是每小时累计的最大连接次数
#资源限制是对某一账号进行累计的,而不是对账号的一次连接进行累计的,当资源限制到达后,账号的任何一次相关操作都会被拒

范例:

bash 复制代码
#只能查询,插入指定字段
GRANT SELECT(col1),INSERT(col1,col2) ON mydb.mytbl TO 'someuser'@'somehost';

#有指定库的所有权限
GRANT ALL ON wordpress.* TO wordpress '10.0.0.%';

#授予所有权限
GRANT ALL PRIVILEGES ON *.* TO 'root'@'10.0.0.%' WITH GRANT OPTION;

#创建用户和授权同时执行的方式在MySQL8.0取消了
GRANT ALL ON wordpress.* TO wordpress@'192.168.108.%' IDENTIFIED BY 'huawei';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.108.%' IDENTIFIED BY 'huawei' WITH GRANT OPTION;

取消权限

格式

bash 复制代码
REVOKE
    priv_type [(column_list)]
      [, priv_type [(column_list)]] ...
    ON [object_type] priv_level
    FROM user_or_role [, user_or_role] ...

范例

bash 复制代码
REVOKE DELETE ON *.* FROM 'testuser'@'172.16.0.%';
REVOKE ALL ON *.* FROM'testuser'@'172.16.0.%';

查看用户权限

格式

mysql 复制代码
#查看指定用户权限
SHOW GRANTS FOR 'user'@'host';

#查看当前使用中的用户的权限
SHOW GRANTS FOR CURRENT_USER[()];

注意

  • MariaDB 服务进程启动时会读取 mysql 库中所有授权表至内存。
  • GRANT 或 REVOKE 等执行权限操作会保存于系统表中,MariaDB 的服务进程通常会自动重读授权表,使之生效。
  • 对于不能够或不能及时重读授权表的命令,可手动让 MariaDB 的服务进程重读授权表:MySQL>FLUSH PRIVILEGES。

范例

bash 复制代码
#本地操作
#创建用户
mysql> create user 'root'@'192.168.108.%' identified by '123456';
Query OK, 0 rows affected (0.01 sec)

mysql> select user,host from mysql.user;
+------------------+---------------+
| user             | host          |
+------------------+---------------+
| root             | 19            |
| root             | 192.168.108.% |
| root             | 192.168.108.1 |
| mysql.infoschema | localhost     |
| mysql.session    | localhost     |
| mysql.sys        | localhost     |
| root             | localhost     |
+------------------+---------------+
7 rows in set (0.01 sec)


#查看新用户的权限,默认只有 USAGE 权限,只能连接
mysql> show grants for 'root'@'192.168.108.%';
+----------------------------------------------+
| Grants for root@192.168.108.%                |
+----------------------------------------------+
| GRANT USAGE ON *.* TO `root`@`192.168.108.%` |
+----------------------------------------------+
1 row in set (0.00 sec)

#远程连接,远程操作
[root@localhost ~]# mysql -uroot -p123456 -h192.168.108.128
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 14
Server version: 8.0.26 Source distribution

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>

#查看权限,远程操作
mysql> SHOW GRANTS FOR CURRENT_USER;
+----------------------------------------------+
| Grants for root@192.168.108.%                |
+----------------------------------------------+
| GRANT USAGE ON *.* TO `root`@`192.168.108.%` |
+----------------------------------------------+
1 row in set (0.00 sec)

#无权限创建,远程操作
mysql> create database db1;
ERROR 1044 (42000): Access denied for user 'root'@'192.168.108.%' to database 'db1'
bash 复制代码
#本地操作
mysql> create database db1;
mysql> create database db2;
mysql> use db1;
CREATE TABLE student (
id int UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
age tinyint UNSIGNED,
#height DECIMAL(5,2),
gender ENUM('M','F') default 'M'
)ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4;

mysql> insert student (name,age)values('xiaoming',20);

#授权能查看 db1 中的 student 表,本地操作
mysql> grant select on db1.student to root@'192.168.108.%';
Query OK, 0 rows affected (0.00 sec)


#远程用户再次刷新,远程操作
mysql> SHOW GRANTS FOR CURRENT_USER;
+-----------------------------------------------------------+
| Grants for root@192.168.108.%                             |
+-----------------------------------------------------------+
| GRANT USAGE ON *.* TO `root`@`192.168.108.%`              |
| GRANT SELECT ON `db1`.`student` TO `root`@`192.168.108.%` |
+-----------------------------------------------------------+
2 rows in set (0.00 sec)

#能看到数据库,远程操作
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| db1                |
| information_schema |
+--------------------+
2 rows in set (0.00 sec)

#远程操作
mysql> use db1;     
Database changed
mysql> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| student       |
+---------------+
1 row in set (0.00 sec)

#远程操作
mysql> select * from student;
+----+----------+------+--------+
| id | name     | age  | gender |
+----+----------+------+--------+
| 10 | xiaoming |   20 | M      |
+----+----------+------+--------+
1 row in set (0.00 sec)

#没有更新权限,远程操作
mysql> update student set age=25 where id=10;
ERROR 1142 (42000): UPDATE command denied to user 'root'@'192.168.108.1' for table 'student'

#没有删除权限,远程操作
mysql> delete from student where id=10;
ERROR 1142 (42000): DELETE command denied to user 'root'@'192.168.108.1' for table 'student'

#继续授权,本地操作
mysql> grant update,delete on db1.student to root@'192.168.108.%';

#再次查看,远程操作
mysql> SHOW GRANTS FOR CURRENT_USER;
+---------------------------------------------------------------------------+
| Grants for root@192.168.108.%                                             |
+---------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `root`@`192.168.108.%`                              |
| GRANT SELECT, UPDATE, DELETE ON `db1`.`student` TO `root`@`192.168.108.%` |
+---------------------------------------------------------------------------+
2 rows in set (0.00 sec)

#测试,远程操作
mysql> update student set age=25 where id=10;
mysql> select * from student;
+----+----------+------+--------+
| id | name     | age  | gender |
+----+----------+------+--------+
| 10 | xiaoming |   25 | M      |
+----+----------+------+--------+
1 row in set (0.00 sec)

mysql> delete from student where id=10;
mysql> select * from student;
Empty set (0.00 sec)

范例

bash 复制代码
#创建数据库,本地操作
mysql> create database eshop;
Query OK, 1 row affected (0.00 sec)

#创建用户,本地操作
mysql> create user eshoper@'192.168.108.%' identified by '123456';
Query OK, 0 rows affected (0.00 sec)

#授权,本地操作
mysql> grant all on eshop.* to eshoper@'192.168.108.%';
Query OK, 0 rows affected (0.00 sec)

#远程测试
C:\Users\69466>mysql -ueshoper -p123456 -h192.168.108.128
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 17
Server version: 8.0.26 Source distribution

Copyright (c) 2000, 2025, 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> show databases;
+--------------------+
| Database           |
+--------------------+
| eshop              |
| information_schema |
+--------------------+
2 rows in set (0.00 sec)

#创建表
mysql> use eshop;
Database changed

mysql> create table product (id int,name varchar(10));
Query OK, 0 rows affected (0.10 sec)

mysql> show tables;
+-----------------+
| Tables_in_eshop |
+-----------------+
| product         |
+-----------------+
1 row in set (0.00 sec)

MySQL 的备份与恢复

数据备份的重要性

  • 在生产环境中,数据的安全性至关重要

  • 任何数据的丢失都可能产生严重的后果

  • 造成数据丢失的原因

    • 程序错误

    • 人为操作错误

    • 运行错误

    • 磁盘故障

    • 灾难(如火灾、地震)和盗窃

数据库备份的分类

从物理与逻辑的角度,备份可分为

  • 物理备份:对数据库操作系统的物理文件(如数据文件、日志文件等)的备份
    • 物理备份方法
      • 冷备份(脱机备份):是在关闭数据库的时候进行的
      • 热备份(联机备份):数据库处于运行状态,依赖于数据库的日志文件
      • 温备份:数据库锁定表格(不可写入但可读)的状态下进行备份操作
  • 逻辑备份:对数据库逻辑组件(如:表等数据库对象)的备份

常见的备份方法

  • 物理冷备
    • 备份时数据库处于关闭状态,直接打包数据库文件
    • 备份速度快,恢复时也是最简单的
  • 专用备份工具 mysqldump 或 mysqlhotcopy
    • mysqldump 常用的逻辑备份工具
    • mysqlhotcopy 仅拥有备份 MyISAM 和 ARCHIVE 表
  • 启用二进制日志进行增量备份
    • 进行增量备份,需要刷新二进制日志
  • 第三方工具备份
    • 免费的 MySQL 热备份软件 Percona XtraBackup

冷备份

bash 复制代码
# 备份(推荐写法)
[root@mysql01 ~]# systemctl stop mysqld                       # 先停止服务
[root@mysql01 ~]# cd /usr/local/mysql/data
[root@mysql01 data]# mkdir /mysql_bak
[root@mysql01 data]# tar czf /mysql_bak/mysql-backup-$(date +%F).tar.gz *
[root@mysql01 data]# systemctl start mysqld              # 备份完成后启动服务
#测试服务正常

# 删除数据
[root@mysql01 ~]# systemctl stop mysqld  # 先停止服务
[root@mysql01 ~]# rm -rf /usr/local/mysql/data/*            # 清空数据目录(谨慎操作!)
#再次开启测试,发现数据库坏了
[root@mysql01 ~]# systemctl start mysqld

#停止数据库,恢复数据库
[root@mysql01 ~]# systemctl stop mysqld
[root@mysql01 ~]# tar xzf /mysql_bak/mysql-backup-2025-10-15.tar.gz -C /usr/local/mysql/data/
[root@mysql01 ~]# chown -R mysql:mysql /usr/local/mysql/data       # 恢复权限
[root@mysql01 ~]# systemctl start mysqld          # 启动服务
#再次测试,发现数据库恢复了

逻辑备份

bash 复制代码
#备份数据库
[root@mysql01 ~]# systemctl start mysqld
[root@mysql01 ~]# mysqldump -u root -p school > /mysql_bak/school.sql
Enter password:
[root@mysql01 ~]# ls /mysql_bak/school.sql
mysql_bak/school.sql
[root@mysql01 ~]# cat /mysql_bak/school.sql

#备份多个数据库
[root@mysql01 ~]# mysqldump -u root -p --databases school mysql > /mysql_bak/school-mysql.sql
Enter password:
[root@mysql01 ~]# cat /mysql_bak/school-mysql.sql
#备份所有数据库
[root@mysql01 ~]# mysqldump -u root -p --opt --all-databases > /mysql_bak/all.sql
Enter password:
[root@mysql01 ~]# cat /mysql_bak/all.sql 
#备份整个表
[root@mysql01 ~]# mysqldump -u root -p school info  > /mysql_bak/info.sql
Enter password:
[root@mysql01 ~]# cat /mysql_bak/info.sql

恢复数据

bash 复制代码
[root@mysql01 ~]# mysql -u root -p
Enter password:

mysql> use school
mysql> show tables;
+------------------+
| Tables_in_school |
+------------------+
| info             |
+------------------+
1 row in set (0.00 sec)

mysql> drop table info;
Query OK, 0 rows affected (0.01 sec)

mysql> source /mysql_bak/info.sql

mysql> show tables;
+------------------+
| Tables_in_school |
+------------------+
| info             |
+------------------+
1 row in set (0.00 sec)

增量备份

bash 复制代码
[root@mysql01 ~]# vim /etc/my.cnf
------------------------
[mysqld]
log-bin=mysql-bin #这段下面最后加一行

[root@web-server ~]# systemctl restart mysqld.service

[root@mysql01 ~]# ls /usr/local/mysql/data/
auto.cnf    client-cert.pem  ibdata1      ibtmp1            mysql-bin.index     public_key.pem   server-key.pem
ca-key.pem  client-key.pem   ib_logfile0  mysql             performance_schema  school           sys
ca.pem      ib_buffer_pool   ib_logfile1  mysql-bin.000001  private_key.pem     server-cert.pem

#先进行完整性备份
[root@mysql01 ~]# mysqldump -uroot -p school > /opt/school.sql
Enter password:

#日志刷新生效
[root@mysql01 ~]# mysqladmin -uroot -p flush-logs
Enter password:
#新产生的mysql-bin.000002只记录上次刷新后的操作
[root@mysql01 ~]# ls /usr/local/mysql/data/
auto.cnf    client-cert.pem  ibdata1      ibtmp1            mysql-bin.000002    private_key.pem  server-cert.pem
ca-key.pem  client-key.pem   ib_logfile0  mysql             mysql-bin.index     public_key.pem   server-key.pem
ca.pem      ib_buffer_pool   ib_logfile1  mysql-bin.000001  performance_schema  school           sys

[root@mysql01 ~]# mysql -uroot -p
Enter password:
----------------------------------------
mysql> use school;
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> select * from info;
+----+--------+-------+---------+-------+
| id | name   | score | address | hobby |
+----+--------+-------+---------+-------+
|  1 | 唐三   | 90.00 | 广州    |     1 |
|  2 | 叶凡   | 91.00 | 伦敦    |     2 |
|  4 | 曹操   | 66.50 | 合肥    |     4 |
+----+--------+-------+---------+-------+
3 rows in set (0.00 sec)

#再次插入数据生产增量备份
mysql> insert into info (name,score,address,hobby) values ('美猴王',75,'武汉',1);
Query OK, 1 row affected (0.00 sec)

mysql> exit
Bye

[root@mysql01 ~]# mysqladmin -uroot -p flush-log
Enter password:
#新产生mysql-bin.000003日志记录insert操作
[root@mysql01 ~]# ls /usr/local/mysql/data/
auto.cnf    client-cert.pem  ibdata1      ibtmp1            mysql-bin.000002  performance_schema  school           sys
ca-key.pem  client-key.pem   ib_logfile0  mysql             mysql-bin.000003  private_key.pem     server-cert.pem
ca.pem      ib_buffer_pool   ib_logfile1  mysql-bin.000001  mysql-bin.index   public_key.pem      server-key.pem

[root@mysql01 ~]# mysql -uroot -p
Enter password:
---------------------------------------------------------------
mysql> use school;
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> insert into info (name,score,address,hobby) values ('超人',83,'上海',2);
Query OK, 1 row affected (0.00 sec)

mysql> select * from info;
+----+-----------+-------+---------+-------+
| id | name      | score | address | hobby |
+----+-----------+-------+---------+-------+
|  1 | 唐三      | 90.00 | 广州    |     1 |
|  2 | 叶凡      | 91.00 | 伦敦    |     2 |
|  4 | 曹操      | 66.50 | 合肥    |     4 |
|  5 | 美猴王    | 75.00 | 武汉    |     1 |
|  6 | 超人      | 83.00 | 上海    |     2 |
+----+-----------+-------+---------+-------+
5 rows in set (0.00 sec)

mysql> exit
Bye

#刷新日志生效
[root@mysql01 ~]# mysqladmin -uroot -p flush-log
Enter password:

#环境准备
[root@mysql01 ~]# mysql -uroot -p
Enter password:
--------------------------------------------------------------
mysql> use school;
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> delete from info where id=6;
Query OK, 1 row affected (0.00 sec)

mysql> delete from info where id=5;
Query OK, 1 row affected (0.01 sec)

mysql> select * from info;
+----+--------+-------+---------+-------+
| id | name   | score | address | hobby |
+----+--------+-------+---------+-------+
|  1 | 唐三   | 90.00 | 广州    |     1 |
|  2 | 叶凡   | 91.00 | 伦敦    |     2 |
|  4 | 曹操   | 66.50 | 合肥    |     4 |
+----+--------+-------+---------+-------+
3 rows in set (0.00 sec)

mysql> exit
Bye
[root@mysql01 ~]# ls /usr/local/mysql/data/
auto.cnf    client-cert.pem  ibdata1      ibtmp1            mysql-bin.000002  mysql-bin.index     public_key.pem   server-key.pem
ca-key.pem  client-key.pem   ib_logfile0  mysql             mysql-bin.000003  performance_schema  school           sys
ca.pem      ib_buffer_pool   ib_logfile1  mysql-bin.000001  mysql-bin.000004  private_key.pem     server-cert.pem

#查看日志文件,vim看日志是乱码
[root@mysql01 ~]# mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql-bin.000003
[root@mysql01 ~]# mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql-bin.000004

#恢复操作,恢复时如果被拒绝,是有其他mysql进程占用了
[root@mysql01 ~]# mysqlbinlog --no-defaults /usr/local/mysql/data/mysql-bin.000003 | mysql -uroot -p
Enter password:

#验证
[root@web-server ~]# mysql -uroot -p
Enter password:
mysql> use school;
mysql> select * from info;
+----+--------+-------+---------+-------+
| id | name   | score | address | hobby |
+----+--------+-------+---------+-------+
|  1 | 唐三   | 90.00 | 广州    |     1 |
|  2 | 叶凡   | 91.00 | 伦敦    |     2 |
|  4 | 曹操   | 66.50 | 合肥    |     4 |
|  6 | 超人   | 83.00 | 上海    |     2 |
+----+--------+-------+---------+-------+
4 rows in set (0.00 sec)

主从复制和读写分离

主从复制 核心原理

必须记住 3 个核心组件

  1. binlog(二进制日志) ------ 主库
  2. IO 线程 ------ 从库
  3. SQL 线程 ------ 从库

完整流程(一步一步,逐句理解)

  1. 主库执行增删改(insert/update/delete)
  2. MySQL 把这些操作记录到 binlog 日志文件
  3. 从库的 IO 线程连接主库,请求 binlog
  4. 主库的 dump 线程把 binlog 发给从库
  5. 从库 IO 线程将内容写到本地 relay log(中继日志)
  6. 从库 SQL 线程读取中继日志,重放 SQL 语句
  7. 两个 Yes 代表正常:IO_Running、SQL_Running
  8. 从库数据和主库完全一致

使用目标:数据冗余和灾难恢复;提升并发能力、避免锁冲突。

MySQL 读写分离原理

  • 只在主服务器上写,只在从服务器上读

  • 主数据库处理事务性查询,从数据库处理 SELECT 查询

  • 数据库复制用于将事务性查询的变更同步到集群中的从数据库

  • 读写分离方案

    • 基于程序代码内部实现
    • 基于中间代理层实现
      • MySQL-Proxy
      • Amoeba
      • MyCat
  • 在每个事务更新数据完成之前,Master 将这些改变记录进二进制日志。写入二进制日志完成后,Master 通知存储引擎提交事务。
  • Slave 将 Master 的 Binary log 复制到其中继日志(Relay log)。首先,Slave 开始一个工作线程------I/O 线程,I/O 线程在 Master 上打开一个普通的连接,然后开始 Binlog dump process。Binlog dump process 从 Master 的二进制日志中读取事件,如果已经跟上 Master,它会睡眠并等待 Master 产生新的事件。I/O 线程将这些事件写入中继日志。
  • SQL slave thread(SQL 从线程)处理该过程的最后一步。SQL 线程从中继日志读取事件,并重放其中的事件而更新 Slave 数据,使其与 Master 中的数据保持一致。只要该线程与 I/O 线程保持一致,中继日志通常会位于 OS 的缓存中,所以中继日志的开销很小。复制过程有一个很重要的限制,即复制在 Slave 上是串行化的,也就是说 Master 上的并行更新操作不能在 Slave 上并行操作。

实验拓扑图

使用 CentOS-7-template 模板克隆产生应用客户端和 amoeba

使用 mysql 模板 克隆产生 mysql 主服务器、mysql 从节点 1、mysql 从节点 2

根据下表,将 IP 地址、主机名更改好

主机名 IP地址 作用
mysql-master 192.168.108.101 mysql主服务器
mysql-slave01 192.168.108.102 mysql从节点1
mysql-slave02 192.168.108.103 mysql从节点2
amoeba 192.168.108.110 amoeba
mysql-client 192.168.108.111 应用客户端

时间同步

通过时间戳实现业务的一致性

bash 复制代码
# 所有节点
ntpdate ntp.aliyun.com
date -R

systemctl disable firewalld --now
setenforce 0

如果出现故障:使用此方法,对时完成后,无法重启 mysqld 服务

原因:之前在 Windows 端使用 Navicat 连接过 MySQL

解决:pkill -9 MySQL; systemctl restart mysqld

MySQL 主从服务器配置

MySQL 主服务器配置

bash 复制代码
[root@mysql-master ~]# vim /etc/my.cnf
server-id = 11                                #三台myslq id不能一致
log-bin = master-bin                         #主服务器日志文件
log-slave-updates = true                     #从服务器更新二进制日志

[root@mysql-master ~]# systemctl restart mysqld

[root@mysql-master ~]# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.17-log Source distribution

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

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> GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.108.%' IDENTIFIED BY '123456';
Query OK, 0 rows affected, 1 warning (0.01 sec)

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

mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 |      604 |              |                  |                   |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

#检查有没有master-bin.000001
[root@mysql-master ~]# ls /usr/local/mysql/data
auto.cnf        ibdata1      ib_logfile1  master-bin.000001  mysql               sys
ib_buffer_pool  ib_logfile0  ibtmp1       master-bin.index   performance_schema

MySQL 从服务器配置

MySQL-slave01、MySQL-slave02 都要做如下操作

bash 复制代码
#主从是克隆的要做这个操作,否则UUID一致
# mysql-slave
[root@mysql-slave01 ~]# systemctl stop mysqld
[root@mysql-slave01 ~]# rm -f /usr/local/mysql/data/auto.cnf
[root@mysql-slave01 ~]# systemctl start mysqld

[root@mysql-slave01 ~]# vim /etc/my.cnf
server-id = 22                                     #另外一台为23
relay-log = relay-log-bin                          #从主服务器上同步日志文件记录到本地
relay-log-index = slave-relay-bin.index           #定义relay-log的位置和名称

[root@mysql-slave01 ~]# systemctl restart mysqld

[root@mysql-slave01 ~]# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.17 Source distribution

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

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> change master to master_host='192.168.108.101',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=604;              #master_log_file,master_log_pos与前面查询的相同
Query OK, 0 rows affected, 2 warnings (0.03 sec)

mysql> start slave;
Query OK, 0 rows affected (0.02 sec)

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.108.101
                  Master_User: myslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-bin.000001
          Read_Master_Log_Pos: 604
               Relay_Log_File: relay-log-bin.000002
                Relay_Log_Pos: 321
        Relay_Master_Log_File: master-bin.000001
             Slave_IO_Running: Yes                  #Yes
            Slave_SQL_Running: Yes                  #Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 604
              Relay_Log_Space: 526
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 11
                  Master_UUID: 5d895caf-a1e0-11f0-b3ec-000c29866c0f
             Master_Info_File: /usr/local/mysql/data/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 0
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.00 sec)

ERROR:
No query specified

#mysql-slave02
[root@mysql-slave02 ~]# systemctl stop mysqld
[root@mysql-slave02 ~]# rm -f /usr/local/mysql/data/auto.cnf
[root@mysql-slave02 ~]# systemctl start mysqld

[root@mysql-slave02 ~]# vim /etc/my.cnf
server-id = 23
relay-log = relay-log-bin                         
relay-log-index = slave-relay-bin.index

[root@mysql-slave02 ~]# systemctl restart mysqld

[root@mysql-slave02 ~]# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.17 Source distribution

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

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> change master to master_host='192.168.108.101',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=604;
Query OK, 0 rows affected, 2 warnings (0.04 sec)

mysql> start slave;
Query OK, 0 rows affected (0.01 sec)

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.108.101
                  Master_User: myslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-bin.000001
          Read_Master_Log_Pos: 604
               Relay_Log_File: relay-log-bin.000002
                Relay_Log_Pos: 321
        Relay_Master_Log_File: master-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 604
              Relay_Log_Space: 526
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 11
                  Master_UUID: 5d895caf-a1e0-11f0-b3ec-000c29866c0f
             Master_Info_File: /usr/local/mysql/data/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 0
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.00 sec)

ERROR:
No query specified

MySQL-slave01、MySQL-slave02 查询结果如下

验证主从同步

sql 复制代码
# 主服务器上:
[root@mysql-master ~]# mysql -uroot -phuawei
mysql> create database school;
Query OK, 1 row affected (0.01 sec)
mysql> use school;

CREATE TABLE student (
id int UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
age tinyint UNSIGNED,
#height DECIMAL(5,2),
gender ENUM('M','F') default 'M'
)ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4;

mysql> insert student (name,age)values('路飞',20);

# 去从服务器上 show databases;
[root@mysql-slave01 ~]# mysql -uroot -phuawei
mysql> select * from school.student;
+----+--------+------+--------+
| id | name   | age  | gender |
+----+--------+------+--------+
| 10 | 路飞   |   20 | M      |
+----+--------+------+--------+
1 row in set (0.00 sec)

Amoeba 服务器

读写分离 核心原理

基于 主从复制

  1. 主库写入数据 → 自动同步到从库

  2. 应用程序收到 SQL:

    • insert/update/delete → 走主库
    • select → 走从库
    bash 复制代码
    应用程序
        ↓
    读写中间件(或代码判断)
        ↓
    ------------------------------------------------------
    写 → Master(主库)
    读 → Slave 1
         Slave 2
         Slave 3
    ------------------------------------------------------

从库可以有 1 台、2 台、多台,共同分担查询压力

主从复制保证数据一致

读写分离保证性能扩容

Amoeba 是一款基于 Java 开发的 MySQL 数据库代理中间件 ,核心定位是SQL 路由 ,帮你在应用与 MySQL 之间实现读写分离、负载均衡、高可用,对应用透明、配置简单,是早期企业实现 MySQL 读写分离的主流方案。

  • 角色:应用 ↔ Amoeba ↔ MySQL 主从集群,Amoeba 是中间「SQL 路由器」。
  • 核心能力 :自动识别 SQL 类型,写(INSERT/UPDATE/DELETE)走主库,读(SELECT)走从库,并对从库做负载均衡。
  • 依赖前提 :必须先搭好 MySQL 主从复制,Amoeba 只负责路由,不负责数据同步。
  • 优势零代码侵入、配置基于 XML(比 MySQL Proxy 的 Lua 简单)、轻量易运维。

工作流程(读写分离)

  1. 应用连接 Amoeba 代理(默认端口 8066),而非直接连 MySQL。

  2. Amoeba 解析 SQL:

    • 写操作 → 转发到配置的 主库池(writePool)
    • 读操作 → 转发到配置的 从库池(readPool),并按轮询/权重做负载均衡。
  3. 主从复制保证从库数据与主库一致,应用无感知。

核心组件(配置文件)

Amoeba 核心配置在 $AMOEBA_HOME/conf/ 下,共 7 个,最关键 2 个:

配置文件 作用
amoeba.xml 代理核心配置:端口、认证、读写池、路由规则、线程池
dbServers.xml 定义后端 MySQL 节点(主 / 从)、连接信息、连接池

路由规则(读写分离核心)

amoeba.xml 中配置:

  • writePool:指定写操作转发的主库节点池。
  • readPool:指定读操作转发的从库节点池(多从库自动轮询)。
  • 规则优先级:readPools/writePools > defaultPools
bash 复制代码
#普通linux克隆得出amoeba
[root@amoeba ~]# hostnamectl set-hostname amoeba
[root@amoeba ~]# systemctl stop firewalld.service
[root@amoeba ~]# setenforce 0

[root@amoeba ~]# chmod +x jdk-6u14-linux-x64.bin
[root@amoeba ~]# ./jdk-6u14-linux-x64.bin
到yes的时候,输入yes按enter

[root@amoeba ~]# mv jdk1.6.0_14/ /usr/local/jdk1.6

[root@amoeba ~]# vim /etc/profile
最下面加
export JAVA_HOME=/usr/local/jdk1.6                   #java家目录
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib             #类环境和jre
export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin          
export AMOEBA_HOME=/usr/local/amoeba                  #指定amoeba路径
export PATH=$PATH:$AMOEBA_HOME/bin

[root@amoeba ~]# source /etc/profile

[root@amoeba ~]# mkdir /usr/local/amoeba

[root@amoeba ~]# tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/

[root@amoeba ~]# chmod -R 755 /usr/local/amoeba/

#执行结果显示amoeba start|stop说明安装成功
[root@amoeba ~]# /usr/local/amoeba/bin/amoeba
amoeba start|stop

在三台 MySQL 上添加权限开放给 amoeba 访问

bash 复制代码
#amooba访问数据库的账号 
#mysql-master
mysql> grant all on *.* to test@'192.168.108.%' identified by '123.com';

#mysql-slave01
mysql> grant all on *.* to test@'192.168.108.%' identified by '123.com';

#mysql-slave02
mysql> grant all on *.* to test@'192.168.108.%' identified by '123.com';

回到 amoeba 服务器

bash 复制代码
[root@amoeba ~]# cd /usr/local/amoeba/
[root@amoeba amoeba]# vim conf/amoeba.xml
---30行--
 <property name="user">amoeba</property           #客户端访问amoeba账号
----32行---------
 <property name="password">123456</property>        #客户端访问ameoba密码

---117和120-去掉注释-
 115行 <property name="defaultPool">master</property>
 116
 117
 118行<property name="writePool">master</property>
 119行<property name="readPool">slaves</property>
 120

[root@amoeba amoeba]# vim conf/dbServers.xml         #数据库配置
---23--注意!!!(mysql5.7,默认没有test数据库所以需要修改为mysql数据库)-(mysql5.5直接忽略)--
<!-- mysql schema -->
<property name="schema">mysql</property>

--25行到30行,第30行-->移动到28行后面
 25                         <!-- mysql user -->
 26                         <property name="user">test</property>
 27
 28                         <!--  mysql password -->
 29                         <property name="password">123.com</property>
 30

-----45到50行主服务器地址---
45行<dbServer name="master"  parent="abstractServer">
48行<property name="ipAddress">192.168.108.101</property>
--52到57行从服务器主机名-
52行<dbServer name="slave1"  parent="abstractServer">
--55-从服务器地址-
55 <property name="ipAddress">192.168.108.102</property>
 ---52到57行复制一份在58行后面
原52行<dbServer name="slave2"  parent="abstractServer">
--55-从服务器地址-
原55 <property name="ipAddress">192.168.108.103</property>
 
 ---仅跟在上面的配置后面,multiPool行(本来就有,修改)
 <dbServer name="slaves" virtual="true">
 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool   #不改

<property name="poolNames">slave1,slave2</property>
 </poolConfig>           #不改

[root@amoeba ~]# /usr/local/amoeba/bin/amoeba start&
[1] 33499

[root@amoeba ~]# netstat -anpt | grep java
tcp6       0      0 :::8066                 :::*                    LISTEN      33499/java
tcp6       0      0 127.0.0.1:21128         :::*                    LISTEN      33499/java
tcp6       0      0 192.168.108.110:41754   192.168.108.101:3306    ESTABLISHED 33499/java
tcp6       0      0 192.168.108.110:41722   192.168.108.102:3306    ESTABLISHED 33499/java
tcp6       0      0 192.168.108.110:36956   192.168.108.103:3306    ESTABLISHED 33499/java

vim conf/dbServers.xml 结果如下

测试客户端

bash 复制代码
[root@mysql-client ~]# yum install -y mysql
[root@mysql-client ~]# mysql -u amoeba -p123456 -h 192.168.108.110 -P8066     #连接amoeba服务器,8086端口在amoeba上执行netstat -anpt|grep java看
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 927449563
Server version: 5.1.45-mysql-amoeba-proxy-2.2.0

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]>

MASTER

bash 复制代码
[root@mysql-master ~]# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 5.7.17-log Source distribution

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

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 school;
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> insert student (name,age)values('鸣人',20);
Query OK, 1 row affected (0.00 sec)

#此时会同步
#mysql-slave01
mysql> select * from student;
+----+--------+------+--------+
| id | name   | age  | gender |
+----+--------+------+--------+
| 10 | 路飞  |   20 | M      |
| 11 | 鸣人   |   20 | M      |
+----+--------+------+--------+
2 rows in set (0.00 sec)

#mysql-slave02
mysql> select * from student;
+----+--------+------+--------+
| id | name   | age  | gender |
+----+--------+------+--------+
| 10 | 路飞  |   20 | M      |
| 11 | 鸣人   |   20 | M      |
+----+--------+------+--------+
2 rows in set (0.00 sec)

在两台从上

bash 复制代码
# mysql-slave01
mysql> stop slave;

# mysql-slave02
mysql> stop slave;

在客户端上插入数据,内容不会同步

bash 复制代码
#mysql-client上添加,由于不会同步,只有mysql-master192.168.108.101节点有该记录
# mysql-client
MySQL [school]> insert student (name,age)values('卡卡西',30);

在 mysql-slave01 上

bash 复制代码
#mysql-slave01
mysql> use school;
mysql> insert student (name,age)values('卡卡西',31);

MySQL-slave02 上

bash 复制代码
# mysql-slave02
mysql> use school;
mysql> insert student (name,age)values('卡卡西',32);

验证主从复制

在 mysql-slave01 和 mysql-slave02 上查看

bash 复制代码
# mysql-slave01
mysql> select * from student;
+----+-----------+------+--------+
| id | name      | age  | gender |
+----+-----------+------+--------+
| 10 | 路飞      |   20 | M      |
| 11 | 鸣人      |   20 | M      |
| 12 | 卡卡西    |   31 | M      |
+----+-----------+------+--------+
3 rows in set (0.00 sec)

#mysql-slave02
mysql> select * from student;
+----+-----------+------+--------+
| id | name      | age  | gender |
+----+-----------+------+--------+
| 10 | 路飞      |   20 | M      |
| 11 | 鸣人      |   20 | M      |
| 12 | 卡卡西    |   32| M      |
+----+-----------+------+--------+
3 rows in set (0.00 sec)

并没有将客户端写入的 insert student(name,age) values('卡卡西',30); 同步

在 mysql-master 上查看内容发现写入成功:

bash 复制代码
# mysql-master
mysql> select * from student;
+----+-----------+------+--------+
| id | name      | age  | gender |
+----+-----------+------+--------+
| 10 | 路飞      |   20 | M      |
| 11 | 鸣人      |   20 | M      |
| 12 | 卡卡西    |   30 | M      |
+----+-----------+------+--------+
3 rows in set (0.00 sec)

验证读写分离

在客户端上测试,第一次会向从服务器 1 读数据,第二次会向从 2 读取

bash 复制代码
#mysql-client
MySQL [(none)]> select * from school.student;
+----+-----------+------+--------+
| id | name      | age  | gender |
+----+-----------+------+--------+
| 10 | 路飞      |   20 | M      |
| 11 | 鸣人      |   20 | M      |
| 12 | 卡卡西    |   31 | M      |
+----+-----------+------+--------+
3 rows in set (0.02 sec)

MySQL [(none)]> select * from school.student;
+----+-----------+------+--------+
| id | name      | age  | gender |
+----+-----------+------+--------+
| 10 | 路飞      |   20 | M      |
| 11 | 鸣人      |   20 | M      |
| 12 | 卡卡西    |   32 | M      |
+----+-----------+------+--------+
3 rows in set (0.00 sec)
#都是从从节点读取的,读写分离,由实验结果可知:客户端的读取内容会从mysql-slave01和mysql-slave02上轮询得到。

MHA 高可用

MHA(Master High Availability)是专为 MySQL 主从复制设计的开源高可用工具 ,核心解决主库单点故障 问题,实现自动故障转移(0--30 秒),兼顾数据一致性,是中小规模 MySQL 集群的主流高可用方案。


核心概念

  • 是什么 :由日本开发者 Yoshinori Matsunobu 开发,基于 Perl 实现,不改变原生主从复制逻辑,仅解决「故障自动切换」痛点。
  • 解决什么问题 :MySQL 原生主从复制无自动切换能力,主库宕机需人工介入,响应慢、易出错;MHA 自动化全流程,RPO(数据丢失风险)接近 0
  • 核心目标:快速切换、数据不丢、对业务透明(无需修改应用配置)。

传统的 MySQL 主从架构存在的问题

  • 单点故障

案例前置知识点

  • MHA 概述
    • 一套优秀的 MySQL 高可用环境下故障切换和主从复制的软件
    • MySQL 故障过程中,MHA 能做到 0-30 秒内自动完成故障切换
  • MHA 的组成
    • MHA Manager(管理节点)
    • MHA Node(数据节点)
  • MHA 特点
    • 自动故障切换过程中,MHA 试图从宕机的主服务器上保存二进制日志,最大程度地保证数据不丢失
    • 使用半同步复制,可以大大降低数据丢失的风险
    • 目前 MHA 支持一主多从架构,最少三台服务,即一主两从

使用场景:自动故障转移(Failover)和主从切换(Switchover)

实验拓扑图

实验思路

  1. MHA 架构

    1)数据库安装

    2)一主两从

    3)MHA 搭建

  2. 故障模拟

    1)主库失效

    2)备选主库成为主库

    3)从库 2 将备选主库指向为主库

案例环境

  1. 本案例环境

使用 CentOS 7 模板克隆产生 mha 节点

使用 mysql 模板克隆产生 mysql-master、MySQL-slave01、MySQL-slave02

根据下表,将 IP 地址、主机名更改好

主机名 IP地址 作用
mysql-master 192.168.108.131 mysql主服务器,安装node组件
mysql-slave01 192.168.108.132 mysql从节点1,安装node组件
mysql-slave02 192.168.108.133 mysql从节点2,安装node组件
mha 192.168.108.130 mha,安装node组件、manager组件

这里操作系统是 CentOS 7 版本,所以这里下载 MHA 版本是 0.57 版本。

  1. 案例需求
    本案例要求通过 MHA 监控 MySQL 数据库在故障时进行自动切换,不影响业务。
  2. 案例实现思路
    1)安装 MySQL 数据库
    2)配置 MySQL 一主两从
    3)安装 MHA 软件
    4)配置无密码认证
    5)配置 MySQL MHA 高可用
    6)模拟 master 故障切换

在三台 MySQL 节点上分别安装前置环境

bash 复制代码
#主从是克隆的要做这个操作,否则UUID一致
[root@mysql-slave01 ~]# systemctl stop mysqld
[root@mysql-slave01 ~]# rm -f /usr/local/mysql/data/auto.cnf
[root@mysql-slave01 ~]# systemctl start mysqld

[root@mysql-slave02 ~]# systemctl stop mysqld
[root@mysql-slave02 ~]# rm -f /usr/local/mysql/data/auto.cnf
[root@mysql-slave02 ~]# systemctl start mysqld

安装编译依赖的环境

bash 复制代码
#mysql-master,mysql-slave01,mysql-slave02配置
[root@mysql-master ~]# yum -y install perl-Module-Install
[root@mysql-slave01 ~]# yum -y install perl-Module-Install
[root@mysql-slave02 ~]# yum -y install perl-Module-Install

修改 Master 的主配置文件 /etc/my.cnf 文件

bash 复制代码
[root@mysql-master ~]# vim /etc/my.cnf
[mysqld]
server-id = 1                     #三台服务器的 server-id 不能一样
log_bin = master-bin
log-slave-updates = true

配置从服务器:

在 /etc/my.cnf 中修改或者增加下面内容。

bash 复制代码
#mysql-slave01,请注释/etc/my.cnf 中 [client]下 #default-character-set=utf8
[root@mysql-slave01 ~]# vim /etc/my.cnf         #下面只列出了要改的内容
[client]
#default-character-set=utf8

[mysqld]
server-id = 2           
log_bin = master-bin                
relay-log = relay-log-bin 
relay-log-index = slave-relay-bin.index 

#mysql-slave02,请注释/etc/my.cnf 中 [client]下 #default-character-set=utf8
[root@mysql-slave02 ~]# vim /etc/my.cnf
[client]
#default-character-set=utf8

[mysqld]
server-id = 3                    
relay-log = relay-log-bin 
relay-log-index = slave-relay-bin.index 

三节点都要操作

bash 复制代码
[root@mysql-master ~]# ln -s /usr/local/mysql/bin/mysqlbinlog /usr/bin/
[root@mysql-master ~]# ln -s /usr/local/mysql/bin/mysql /usr/bin/
[root@mysql-master ~]# systemctl restart mysqld

[root@mysql-slave01 ~]# ln -s /usr/local/mysql/bin/mysqlbinlog /usr/bin/
[root@mysql-slave01 ~]# ln -s /usr/local/mysql/bin/mysql /usr/bin/
[root@mysql-slave01 ~]# systemctl restart mysqld

[root@mysql-slave02 ~]# ln -s /usr/local/mysql/bin/mysqlbinlog /usr/bin/
[root@mysql-slave02 ~]# ln -s /usr/local/mysql/bin/mysql /usr/bin/
[root@mysql-slave02 ~]# systemctl restart mysqld

!IMPORTANT

MySQL 5.7 注意

请注释 /etc/my.cnf 中【client】下 #default-character-set=utf8

一定要注释,否则报错

ln -s /usr/local/MySQL/bin/mysqlbinlog /usr/bin/

ln -s /usr/local/MySQL/bin/MySQL /usr/bin/

配置 MySQL 一主两从

MySQL 主从配置相对比较简单。需要注意的是授权。步骤如下:

在所有数据库节点上授权两个用户,一个是从库同步使用,另外一个是 manager 使用。

bash 复制代码
#mysql-master
mysql> grant replication slave on *.* to 'myslave'@'192.168.108.%' identified by '123';
mysql> grant all privileges on *.* to 'mha'@'192.168.108.%' identified by 'manager';
mysql> flush privileges;

#mysql-slave01
mysql> grant replication slave on *.* to 'myslave'@'192.168.108.%' identified by '123';
mysql> grant all privileges on *.* to 'mha'@'192.168.108.%' identified by 'manager';
mysql> flush privileges;

#mysql-slave02
mysql> grant replication slave on *.* to 'myslave'@'192.168.108.%' identified by '123';
mysql> grant all privileges on *.* to 'mha'@'192.168.108.%' identified by 'manager';
mysql> flush privileges;

下面三条授权按理论是不用添加的,但是做案例实验环境时候通过 MHA 检查 MySQL 主从有报错,

报两个从库通过主机名连接不上主库,所以所有数据库加上下面的授权。

bash 复制代码
#mysql-master配置(mha@mysql-master与主机名相同)
mysql> grant all privileges on *.* to 'mha'@'mysql-master' identified by 'manager';       
mysql> grant all privileges on *.* to 'mha'@'mysql-slave01' identified by 'manager';
mysql> grant all privileges on *.* to 'mha'@'mysql-slave02' identified by 'manager';
mysql> flush privileges;

#mysql-slave01配置(mha@mysql-master与主机名相同)
mysql> grant all privileges on *.* to 'mha'@'mysql-master' identified by 'manager';       
mysql> grant all privileges on *.* to 'mha'@'mysql-slave01' identified by 'manager';
mysql> grant all privileges on *.* to 'mha'@'mysql-slave02' identified by 'manager';
mysql> flush privileges;

#mysql-slave02配置(mha@mysql-master与主机名相同)
mysql> grant all privileges on *.* to 'mha'@'mysql-master' identified by 'manager';       
mysql> grant all privileges on *.* to 'mha'@'mysql-slave01' identified by 'manager';
mysql> grant all privileges on *.* to 'mha'@'mysql-slave02' identified by 'manager';
mysql> flush privileges;

在 mysql-master 主机上查看二进制文件和同步点

bash 复制代码
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 |     1897 |              |                  |                   |
+-------------------+----------+--------------+------------------+-------------------+

接下来在 MySQL-slave01 和 MySQL-slave02 分别执行同步。

bash 复制代码
#mysql-slave01,命令中的master_log_pos的值,取决于msql-master show master status查看的Position
mysql> change master to master_host='192.168.108.131',master_user='myslave',master_password='123',master_log_file='master-bin.000001',master_log_pos=1897; 
mysql> start slave;

#mysql-slave02
mysql> change master to master_host='192.168.108.131',master_user='myslave',master_password='123',master_log_file='master-bin.000001',master_log_pos=1897; 
mysql> start slave;

查看 IO 和 SQL 线程都是 yes 代表同步是否正常

mysql 复制代码
#mysql-slave01
mysql> show slave status\G;
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

#mysql-slave02
mysql> show slave status\G;
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

必须设置两个从库为只读模式:

bash 复制代码
#mysql-slave01
mysql> set global read_only=1;

#mysql-slave02
mysql> set global read_only=1;

注意:设置完成直接验证主从复制功能

安装 MHA 软件

所有服务器上都安装 MHA 依赖的环境,首先安装 epel 源。

bash 复制代码
#4个节点
# yum install epel-release --nogpgcheck -y

# yum install -y perl-DBD-MySQL \
perl-Config-Tiny \
perl-Log-Dispatch \
perl-Parallel-ForkManager \
perl-ExtUtils-CBuilder \
perl-ExtUtils-MakeMaker \
perl-CPAN

MHA 软件包对于每个操作系统版本不一样,这里 CentOS 7.9 必须选择 0.57 版本,

注意:所有服务器上必须先安装 node 组件,最后在 MHA 节点上安装 manager 组件,

因为 manager 依赖 node 组件。

bash 复制代码
#mysql-master
[root@mysql-master ~]# tar zxvf mha4mysql-node-0.57.tar.gz
[root@mysql-master ~]# cd mha4mysql-node-0.57
[root@mysql-master ~]# perl Makefile.PL
[root@mysql-master ~]# make && make install

#mysql-slave01
[root@mysql-slave01 ~]# tar zxvf mha4mysql-node-0.57.tar.gz
[root@mysql-slave01 ~]# cd mha4mysql-node-0.57
[root@mysql-slave01 ~]# perl Makefile.PL
[root@mysql-slave01 ~]# make && make install


#mysql-slave02
[root@mysql-slave02 ~]# tar zxvf mha4mysql-node-0.57.tar.gz
[root@mysql-slave02 ~]# cd mha4mysql-node-0.57
[root@mysql-slave02 ~]# perl Makefile.PL
[root@mysql-slave02 ~]# make && make install

#mha
[root@mha ~]# tar zxvf mha4mysql-node-0.57.tar.gz
[root@mha ~]# cd mha4mysql-node-0.57
[root@mha ~]# perl Makefile.PL
[root@mha ~]# make && make install

在 MHA 上安装 manager 组件(注意:一定要先安装 node 组件才能安装 manager 组件)

bash 复制代码
#mha
[root@mha ~]# tar zxvf mha4mysql-manager-0.57.tar.gz
[root@mha ~]# cd mha4mysql-manager-0.57
[root@mha mha4mysql-manager-0.57]# perl Makefile.PL
[root@mha mha4mysql-manager-0.57]# make && make install

manager 安装后在 /usr/local/bin 下面会生成几个工具,主要包括以下几个:

masterha_check_ssh 检查 MHA 的 SSH 配置状况

masterha_check_repl 检查 MySQL 复制状况

masterha_manager 启动 manager 的脚本

masterha_check_status 检测当前 MHA 运行状态

masterha_master_monitor 检测 master 是否宕机

masterha_master_switch 控制故障转移(自动或者手动)

masterha_conf_host 添加或删除配置的 server 信息

masterha_stop 关闭 manager

node 安装后也会在 /usr/local/bin 下面生成几个脚本(这些工具通常由 MHA Manager 的脚本触发,无需人为操作)主要如下:

save_binary_logs 保存和复制 master 的二进制日志

apply_diff_relay_logs 识别差异的中继日志事件并将其差异的事件应用于其他的 slave

filter_mysqlbinlog 去除不必要的 ROLLBACK 事件(MHA 已不再使用这个工具)

purge_relay_logs 清除中继日志(不会阻塞 SQL 线程)

配置无密码认证

在 manager 上配置到所有数据库节点的无密码认证

bash 复制代码
[root@mha ~]# ssh-keygen -t rsa             #一路按回车键
[root@mha ~]# ssh-copy-id 192.168.108.131
[root@mha ~]# ssh-copy-id 192.168.108.132
[root@mha ~]# ssh-copy-id 192.168.108.133

在 MySQL-master 上配置到数据库节点 mysql-slave01 和 mysql-slave02 的无密码认证

bash 复制代码
[root@mysql-master ~]# ssh-keygen -t rsa
[root@mysql-master ~]# ssh-copy-id 192.168.108.132
[root@mysql-master ~]# ssh-copy-id 192.168.108.133

在 MySQL-slave01 上配置到数据库节点 mysql-master 和 mysql-slave02 的无密码认证

bash 复制代码
[root@mysql-slave01 ~]# ssh-keygen -t rsa
[root@mysql-slave01 ~]# ssh-copy-id 192.168.108.131
[root@mysql-slave01 ~]# ssh-copy-id 192.168.108.133

在 MySQL-slave02 上配置到数据库节点 mysql-master 和 mysql-slave01 的无密码认证

bash 复制代码
[root@mysql-slave02 ~]# ssh-keygen -t rsa
[root@mysql-slave02 ~]# ssh-copy-id 192.168.108.131
[root@mysql-slave02 ~]# ssh-copy-id 192.168.108.132

配置 MHA

在 manager 节点上复制相关脚本到 /usr/local/bin 目录。

bash 复制代码
[root@mha ~]# cp -ra /root/mha4mysql-manager-0.57/samples/scripts /usr/local/bin

#拷贝后会有四个执行文件
[root@mha ~]# ll /usr/local/bin/scripts/
总用量 32
-rwxr-xr-x 1 mysql mysql 3648 5 月 31 2015 master_ip_failover  #自动切换时 VIP 管理的脚本
-rwxr-xr-x 1 mysql mysql 9872 5 月 25 09:07 master_ip_online_change #在线切换时 vip 的管理
-rwxr-xr-x 1 mysql mysql 11867 5 月 31 2015 power_manager #故障发生后关闭主机的脚本
-rwxr-xr-x 1 mysql mysql 1360 5 月 31 2015 send_report #因故障切换后发送报警的脚本

复制上述的自动切换时 VIP 管理的脚本到 /usr/local/bin 目录,这里使用脚本管理 VIP,

bash 复制代码
[root@mha ~]# cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin

修改内容如下:(删除原有内容,直接复制)

bash 复制代码
#复制时,#号间一段段复制
[root@mha ~]# vim /usr/local/bin/master_ip_failover
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';

use Getopt::Long;

my (
$command, $ssh_user, $orig_master_host, $orig_master_ip,
$orig_master_port, $new_master_host, $new_master_ip, $new_master_port
);
#############################添加内容部分#########################################
my $vip = '192.168.108.200';
my $brdc = '192.168.108.255';
my $ifdev = 'ens33';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";
my $exit_code = 0;
#my $ssh_start_vip = "/usr/sbin/ip addr add $vip/24 brd $brdc dev $ifdev label $ifdev:$key;/usr/sbin/arping -q -A -c 1 -I $ifdev $vip;iptables -F;";
#my $ssh_stop_vip = "/usr/sbin/ip addr del $vip/24 dev $ifdev label $ifdev:$key";
##################################################################################
GetOptions(
'command=s' => \$command,
'ssh_user=s' => \$ssh_user,
'orig_master_host=s' => \$orig_master_host,
'orig_master_ip=s' => \$orig_master_ip,
'orig_master_port=i' => \$orig_master_port,
'new_master_host=s' => \$new_master_host,
'new_master_ip=s' => \$new_master_ip,
'new_master_port=i' => \$new_master_port,
);

exit &main();

sub main {

print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";

if ( $command eq "stop" || $command eq "stopssh" ) {

my $exit_code = 1;
eval {
print "Disabling the VIP on old master: $orig_master_host \n";
&stop_vip();
$exit_code = 0;
};
if ($@) {
warn "Got Error: $@\n";
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "start" ) {

my $exit_code = 10;
eval {
print "Enabling the VIP - $vip on the new master - $new_master_host \n";
&start_vip();
$exit_code = 0;
};
if ($@) {
warn $@;
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "status" ) {
print "Checking the Status of the script.. OK \n";
exit 0;
}
else {
&usage();
exit 1;
}
}
sub start_vip() {
`ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
# A simple system call that disable the VIP on the old_master
sub stop_vip() {
`ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}

sub usage {
print
"Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}

创建 MHA 软件目录并拷贝配置文件。

bash 复制代码
[root@mha ~]# mkdir /etc/masterha
[root@mha ~]# cp /root/mha4mysql-manager-0.57/samples/conf/app1.cnf /etc/masterha/
[root@mha ~]# vim /etc/masterha/app1.cnf
#全部删掉,替换
[server default]
manager_log=/var/log/masterha/app1/manager.log
manager_workdir=/var/log/masterha/app1
master_binlog_dir=/usr/local/mysql/data
master_ip_failover_script=/usr/local/bin/master_ip_failover
master_ip_online_change_script=/usr/local/bin/master_ip_online_change
user=mha
password=manager
ping_interval=1
remote_workdir=/tmp
repl_user=myslave
repl_password=123
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.108.132 -s 192.168.108.133
shutdown_script=""
ssh_user=root

[server1]
hostname=192.168.108.131
port=3306

[server2]
candidate_master=1
check_repl_delay=0
hostname=192.168.108.132
port=3306

[server3]
hostname=192.168.108.133
port=3306

配置文件解析

bash 复制代码
[server default]
manager_workdir=/var/log/masterha/app1               ##manager工作目录
manager_log=/var/log/masterha/app1/manager.log            #manager日志
master_binlog_dir=/usr/local/mysql/data/                #master保存binlog的位置,这里的路径要与master里配置的binlog的路径一致,以便mha能找到
master_ip_failover_script= /usr/local/bin/master_ip_failover    #设置自动failover时候的切换脚本,也就是上边的那个脚本
master_ip_online_change_script= /usr/local/bin/master_ip_online_change  #设置手动切换时候的切换脚本
user=mha        #设置监控用户mha
password=manager      #设置mysql中mha用户的密码
ping_interval=1      #设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行railover
remote_workdir=/tmp    #设置远端mysql在发生切换时binlog的保存位置
repl_user=myslave           #设置复制用户的用户
repl_password=123        #设置复制用户的密码
report_script=/usr/local/send_report      #设置发生切换后发送的报警的脚本
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.108.132 -s 192.168.108.133
shutdown_script=""  #设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机防止发生脑裂,这里没有使用)
ssh_user=root      #设置ssh的登录用户名

[server1]
hostname=192.168.108.131
port=3306

[server2]
hostname=192.168.108.132
port=3306
candidate_master=1    #//设置为候选master,如果设置该参数以后,发生主从切换以后将会将此从库提升为主库,即使这个主库不是集群中事件最新的slave
check_repl_delay=0    #默认情况下如果一个slave落后master 100M的relay logs的话,MHA将不会选择该slave作为一个新的master,因为对于这个slave的恢复需要花费很长时间,通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master

[server3]
hostname=192.168.108.133
port=3306

验证配置

测试 ssh 无密码认证,如果正常最后会输出 successfully,如下所示。

bash 复制代码
#检测SSH无密码认证
[root@mha ~]# masterha_check_ssh -conf=/etc/masterha/app1.cnf
Tue Oct  7 15:16:58 2025 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Tue Oct  7 15:16:58 2025 - [info] Reading application default configuration from /etc/masterha/app1.cnf..
Tue Oct  7 15:16:58 2025 - [info] Reading server configuration from /etc/masterha/app1.cnf..
Tue Oct  7 15:16:58 2025 - [info] Starting SSH connection tests..
Tue Oct  7 15:16:58 2025 - [debug]
Tue Oct  7 15:16:58 2025 - [debug]  Connecting via SSH from root@192.168.108.131(192.168.108.131:22) to root@192.168.108.132(192.168.108.132:22)..
Tue Oct  7 15:16:58 2025 - [debug]   ok.
Tue Oct  7 15:16:58 2025 - [debug]  Connecting via SSH from root@192.168.108.131(192.168.108.131:22) to root@192.168.108.133(192.168.108.133:22)..
Tue Oct  7 15:16:58 2025 - [debug]   ok.
Tue Oct  7 15:16:59 2025 - [debug]
Tue Oct  7 15:16:58 2025 - [debug]  Connecting via SSH from root@192.168.108.132(192.168.108.132:22) to root@192.168.108.131(192.168.108.131:22)..
Tue Oct  7 15:16:58 2025 - [debug]   ok.
Tue Oct  7 15:16:58 2025 - [debug]  Connecting via SSH from root@192.168.108.132(192.168.108.132:22) to root@192.168.108.133(192.168.108.133:22)..
Tue Oct  7 15:16:59 2025 - [debug]   ok.
Tue Oct  7 15:16:59 2025 - [debug]
Tue Oct  7 15:16:59 2025 - [debug]  Connecting via SSH from root@192.168.108.133(192.168.108.133:22) to root@192.168.108.131(192.168.108.131:22)..
Tue Oct  7 15:16:59 2025 - [debug]   ok.
Tue Oct  7 15:16:59 2025 - [debug]  Connecting via SSH from root@192.168.108.133(192.168.108.133:22) to root@192.168.108.132(192.168.108.132:22)..
Tue Oct  7 15:16:59 2025 - [debug]   ok.
Tue Oct  7 15:16:59 2025 - [info] All SSH connection tests passed successfully.

#检测下主从复制
[root@mha ~]# masterha_check_repl -conf=/etc/masterha/app1.cnf
Tue Oct  7 15:30:03 2025 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Tue Oct  7 15:30:03 2025 - [info] Reading application default configuration from /etc/masterha/app1.cnf..
Tue Oct  7 15:30:03 2025 - [info] Reading server configuration from /etc/masterha/app1.cnf..
Tue Oct  7 15:30:03 2025 - [info] MHA::MasterMonitor version 0.57.
Tue Oct  7 15:30:04 2025 - [info] GTID failover mode = 0
Tue Oct  7 15:30:04 2025 - [info] Dead Servers:
Tue Oct  7 15:30:04 2025 - [info] Alive Servers:
Tue Oct  7 15:30:04 2025 - [info]   192.168.108.131(192.168.108.131:3306)
Tue Oct  7 15:30:04 2025 - [info]   192.168.108.132(192.168.108.132:3306)
Tue Oct  7 15:30:04 2025 - [info]   192.168.108.133(192.168.108.133:3306)
Tue Oct  7 15:30:04 2025 - [info] Alive Slaves:
Tue Oct  7 15:30:04 2025 - [info]   192.168.108.132(192.168.108.132:3306)  Version=5.7.17-log (oldest major version between slaves) log-bin:enabled
Tue Oct  7 15:30:04 2025 - [info]     Replicating from 192.168.108.131(192.168.108.131:3306)
Tue Oct  7 15:30:04 2025 - [info]     Primary candidate for the new Master (candidate_master is set)
Tue Oct  7 15:30:04 2025 - [info]   192.168.108.133(192.168.108.133:3306)  Version=5.7.17 (oldest major version between slaves) log-bin:disabled
Tue Oct  7 15:30:04 2025 - [info]     Replicating from 192.168.108.131(192.168.108.131:3306)
Tue Oct  7 15:30:04 2025 - [info] Current Alive Master: 192.168.108.131(192.168.108.131:3306)
Tue Oct  7 15:30:04 2025 - [info] Checking slave configurations..
Tue Oct  7 15:30:04 2025 - [warning]  relay_log_purge=0 is not set on slave 192.168.108.132(192.168.108.132:3306).
Tue Oct  7 15:30:04 2025 - [warning]  relay_log_purge=0 is not set on slave 192.168.108.133(192.168.108.133:3306).
Tue Oct  7 15:30:04 2025 - [warning]  log-bin is not set on slave 192.168.108.133(192.168.108.133:3306). This host cannot be a master.
Tue Oct  7 15:30:04 2025 - [info] Checking replication filtering settings..
Tue Oct  7 15:30:04 2025 - [info]  binlog_do_db= , binlog_ignore_db=
Tue Oct  7 15:30:04 2025 - [info]  Replication filtering check ok.
Tue Oct  7 15:30:04 2025 - [info] GTID (with auto-pos) is not supported
Tue Oct  7 15:30:04 2025 - [info] Starting SSH connection tests..
Tue Oct  7 15:30:06 2025 - [info] All SSH connection tests passed successfully.
Tue Oct  7 15:30:06 2025 - [info] Checking MHA Node version..
Tue Oct  7 15:30:06 2025 - [info]  Version check ok.
Tue Oct  7 15:30:06 2025 - [info] Checking SSH publickey authentication settings on the current master..
Tue Oct  7 15:30:06 2025 - [info] HealthCheck: SSH to 192.168.108.131 is reachable.
Tue Oct  7 15:30:06 2025 - [info] Master MHA Node version is 0.57.
Tue Oct  7 15:30:06 2025 - [info] Checking recovery script configurations on 192.168.108.131(192.168.108.131:3306)..
Tue Oct  7 15:30:06 2025 - [info]   Executing command: save_binary_logs --command=test --start_pos=4 --binlog_dir=/usr/local/mysql/data --output_file=/tmp/save_binary_logs_test --manager_version=0.57 --start_file=master-bin.000002
Tue Oct  7 15:30:06 2025 - [info]   Connecting to root@192.168.108.131(192.168.108.131:22)..
  Creating /tmp if not exists..    ok.
  Checking output directory is accessible or not..
   ok.
  Binlog found at /usr/local/mysql/data, up to master-bin.000002
Tue Oct  7 15:30:06 2025 - [info] Binlog setting check done.
Tue Oct  7 15:30:06 2025 - [info] Checking SSH publickey authentication and checking recovery script configurations on all alive slave servers..
Tue Oct  7 15:30:06 2025 - [info]   Executing command : apply_diff_relay_logs --command=test --slave_user='mha' --slave_host=192.168.108.132 --slave_ip=192.168.108.132 --slave_port=3306 --workdir=/tmp --target_version=5.7.17-log --manager_version=0.57 --relay_log_info=/usr/local/mysql/data/relay-log.info  --relay_dir=/usr/local/mysql/data/  --slave_pass=xxx
Tue Oct  7 15:30:06 2025 - [info]   Connecting to root@192.168.108.132(192.168.108.132:22)..
  Checking slave recovery environment settings..
    Opening /usr/local/mysql/data/relay-log.info ... ok.
    Relay log found at /usr/local/mysql/data, up to relay-log-bin.000002
    Temporary relay log file is /usr/local/mysql/data/relay-log-bin.000002
    Testing mysql connection and privileges..mysql: [Warning] Using a password on the command line interface can be insecure.
 done.
    Testing mysqlbinlog output.. done.
    Cleaning up test file(s).. done.
Tue Oct  7 15:30:07 2025 - [info]   Executing command : apply_diff_relay_logs --command=test --slave_user='mha' --slave_host=192.168.108.133 --slave_ip=192.168.108.133 --slave_port=3306 --workdir=/tmp --target_version=5.7.17 --manager_version=0.57 --relay_log_info=/usr/local/mysql/data/relay-log.info  --relay_dir=/usr/local/mysql/data/  --slave_pass=xxx
Tue Oct  7 15:30:07 2025 - [info]   Connecting to root@192.168.108.133(192.168.108.133:22)..
  Checking slave recovery environment settings..
    Opening /usr/local/mysql/data/relay-log.info ... ok.
    Relay log found at /usr/local/mysql/data, up to relay-log-bin.000002
    Temporary relay log file is /usr/local/mysql/data/relay-log-bin.000002
    Testing mysql connection and privileges..mysql: [Warning] Using a password on the command line interface can be insecure.
 done.
    Testing mysqlbinlog output.. done.
    Cleaning up test file(s).. done.
Tue Oct  7 15:30:07 2025 - [info] Slaves settings check done.
Tue Oct  7 15:30:07 2025 - [info]
192.168.108.131(192.168.108.131:3306) (current master)
 +--192.168.108.132(192.168.108.132:3306)
 +--192.168.108.133(192.168.108.133:3306)

Tue Oct  7 15:30:07 2025 - [info] Checking replication health on 192.168.108.132..
Tue Oct  7 15:30:07 2025 - [info]  ok.
Tue Oct  7 15:30:07 2025 - [info] Checking replication health on 192.168.108.133..
Tue Oct  7 15:30:07 2025 - [info]  ok.
Tue Oct  7 15:30:07 2025 - [info] Checking master_ip_failover_script status:
Tue Oct  7 15:30:07 2025 - [info]   /usr/local/bin/master_ip_failover --command=status --ssh_user=root --orig_master_host=192.168.108.131 --orig_master_ip=192.168.108.131 --orig_master_port=3306


IN SCRIPT TEST====/sbin/ifconfig ens33:1 down==/sbin/ifconfig ens33:1 192.168.108.200===

Checking the Status of the script.. OK
Tue Oct  7 15:30:07 2025 - [info]  OK.
Tue Oct  7 15:30:07 2025 - [warning] shutdown_script is not defined.
Tue Oct  7 15:30:07 2025 - [info] Got exit code 0 (Not master dead).

MySQL Replicaxtion Health is OK.

第一次配置需要去 master 上手动开启虚拟 IP

bash 复制代码
#注意:第一次配置需要去master上手动开启虚拟IP
[root@mysql-master ~]# /sbin/ifconfig ens33:1 192.168.108.200/24

启动 MHA

bash 复制代码
[root@mha ~]# nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &
[1] 48240

--remove_dead_master_conf 该参数代表当发生主从切换后,老的主库的 ip 将会从配置文件中移除。

--manager_log 日志存放位置。

--ignore_last_failover 在缺省情况下,如果 MHA 检测到连续发生宕机,且两次宕机间隔不足 8 小时的话,则不会进行 Failover,之所以这样限制是为了避免 ping-pong 效应。该参数代表忽略上次 MHA 触发切换产生的文件,默认情况下,MHA 发生切换后会在日志目录,也就是上面设置的日志 app1.failover.complete 文件,下次再次切换的时候如果发现该目录下存在该文件将不允许触发切换,除非在第一次切换后删除该文件,为了方便,这里设置为 --ignore_last_failover。

查看 MHA 状态,可以看到当前的 master 是 MySQL-master 节点。

bash 复制代码
[root@mha ~]# masterha_check_status --conf=/etc/masterha/app1.cnf
app1 (pid:48240) is running(0:PING_OK), master:192.168.108.131

查看 MHA 日志,也可以看到当前的 master 是 192.168.108.131,如下所示。

bash 复制代码
[root@mha ~]# cat /var/log/masterha/app1/manager.log
......
Tue Oct  7 15:32:17 2025 - [info] Slaves settings check done.
Tue Oct  7 15:32:17 2025 - [info]
192.168.108.131(192.168.108.131:3306) (current master)
 +--192.168.108.132(192.168.108.132:3306)
 +--192.168.108.133(192.168.108.133:3306)

Tue Oct  7 15:32:17 2025 - [info] Checking master_ip_failover_script status:
Tue Oct  7 15:32:17 2025 - [info]   /usr/local/bin/master_ip_failover --command=status --ssh_user=root --orig_master_host=192.168.108.131 --orig_master_ip=192.168.108.131 --orig_master_port=3306


IN SCRIPT TEST====/sbin/ifconfig ens33:1 down==/sbin/ifconfig ens33:1 192.168.108.200===

Checking the Status of the script.. OK
Tue Oct  7 15:32:17 2025 - [info]  OK.
Tue Oct  7 15:32:17 2025 - [warning] shutdown_script is not defined.
Tue Oct  7 15:32:17 2025 - [info] Set master ping interval 1 seconds.
Tue Oct  7 15:32:17 2025 - [info] Set secondary check script: /usr/local/bin/masterha_secondary_check -s 192.168.108.132 -s 192.168.108.133
Tue Oct  7 15:32:17 2025 - [info] Starting ping health check on 192.168.108.131(192.168.108.131:3306)..
Tue Oct  7 15:32:17 2025 - [info] Ping(SELECT) succeeded, waiting until MySQL doesn't respond..
[root@mha ~]#

查看 MySQL-master 的 VIP 地址 192.168.108.200 是否存在?这个 VIP 地址不会因为 manager 节点停止 MHA 服务而消失。

bash 复制代码
[root@mysql-master ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.108.131  netmask 255.255.255.0  broadcast 192.168.108.255
        inet6 fe80::deb2:46ba:c54a:56ed  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:43:0b:39  txqueuelen 1000  (Ethernet)
        RX packets 42430  bytes 22790429 (21.7 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 29947  bytes 9476691 (9.0 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.108.200  netmask 255.255.255.0  broadcast 192.168.108.255
        ether 00:0c:29:43:0b:39  txqueuelen 1000  (Ethernet)

验证

bash 复制代码
#mha节点A窗口操作
[root@mha ~]# tailf /var/log/masterha/app1/manager.log     //启用监控观察日志记录

#mysql-master节点操作
[root@mysql-master ~]# pkill -9 mysql         //查看master变化,看上面命令的日志

#回到mha节点A窗口观察日志
[root@mha ~]# tailf /var/log/masterha/app1/manager.log

IN SCRIPT TEST====/sbin/ifconfig ens33:1 down==/sbin/ifconfig ens33:1 192.168.108.200===

Checking the Status of the script.. OK
Tue Oct  7 15:32:17 2025 - [info]  OK.
Tue Oct  7 15:32:17 2025 - [warning] shutdown_script is not defined.
Tue Oct  7 15:32:17 2025 - [info] Set master ping interval 1 seconds.
Tue Oct  7 15:32:17 2025 - [info] Set secondary check script: /usr/local/bin/masterha_secondary_check -s 192.168.108.132 -s 192.168.108.133
Tue Oct  7 15:32:17 2025 - [info] Starting ping health check on 192.168.108.131(192.168.108.131:3306)..
Tue Oct  7 15:32:17 2025 - [info] Ping(SELECT) succeeded, waiting until MySQL doesn't respond..
Tue Oct  7 15:39:47 2025 - [warning] Got error on MySQL select ping: 2006 (MySQL server has gone away)
Tue Oct  7 15:39:47 2025 - [info] Executing secondary network check script: /usr/local/bin/masterha_secondary_check -s 192.168.108.132 -s 192.168.108.133  --user=root  --master_host=192.168.108.131  --master_ip=192.168.108.131  --master_port=3306 --master_user=mha --master_password=manager --ping_type=SELECT
Tue Oct  7 15:39:47 2025 - [info] Executing SSH check script: save_binary_logs --command=test --start_pos=4 --binlog_dir=/usr/local/mysql/data --output_file=/tmp/save_binary_logs_test --manager_version=0.57 --binlog_prefix=master-bin
Tue Oct  7 15:39:47 2025 - [info] HealthCheck: SSH to 192.168.108.131 is reachable.
Master is reachable from 192.168.108.132!
Tue Oct  7 15:39:47 2025 - [warning] Master is reachable from at least one of other monitoring servers. Failover should not happen.
Tue Oct  7 15:39:48 2025 - [info] Ping(SELECT) succeeded, waiting until MySQL doesn't respond..

mha 节点观察日志如下

pkill -9 MySQL,mysqld 短暂暂停又会启动

从其他节点依然能够访问 master,不会主从切换

相关推荐
2601_9620746829 分钟前
大数据-263 实时数仓 - Canal 工作原理 工作流程 MySQL Binglog基本介绍
大数据·数据库·mysql
南城以南溫暖如初1472 小时前
AI 智能商城 APP 定制开发的核心需求
java·人工智能·spring boot·mysql·mybatis·需求分析
2601_962071573 小时前
基于DataX迁移MySQL到OceanBase集群
数据库·mysql·oceanbase
2601_962180334 小时前
FlinkCDC 实现 MySQL 数据变更实时同步
数据库·mysql
2601_962189604 小时前
深入浅出MySQL:概述与体系结构解析
数据库·mysql
软件聚导航15 小时前
「聚小软 AI 助手」技术升级:从数据库检索到 RAG 知识库问答
前端·数据库·mysql·微信小程序·小程序·ai编程·rag
2601_9609067216 小时前
1X发布自己的世界模型1XWM
mysql·mongodb·rabbitmq·memcached
夜雪一千17 小时前
MySQL 各种数据同步方案全梳理:从简单复制到异构同步实战
数据库·mysql