<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>肥猫少杰</title><description>个人博客</description><link>https://fuwari.vercel.app/</link><language>zh_CN</language><item><title>磁盘挂载笔记</title><link>https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/%E7%A3%81%E7%9B%98%E6%8C%82%E8%BD%BD%E7%AC%94%E8%AE%B0/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/%E7%A3%81%E7%9B%98%E6%8C%82%E8%BD%BD%E7%AC%94%E8%AE%B0/</guid><description>Linux 磁盘挂载笔记</description><pubDate>Wed, 17 Jun 2026 08:16:16 GMT</pubDate><content:encoded>&lt;h1&gt;Linux 磁盘挂载笔记（/dev/vdb 20G）&lt;/h1&gt;
&lt;h2&gt;环境信息&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;系统：Ubuntu（腾讯云轻量服务器）&lt;/li&gt;
&lt;li&gt;数据盘：&lt;code&gt;/dev/vdb&lt;/code&gt; — 20 GiB&lt;/li&gt;
&lt;li&gt;系统盘：&lt;code&gt;/dev/vda&lt;/code&gt; — 40 GiB&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;前置概念&lt;/h2&gt;
&lt;p&gt;一个物理磁盘可以有 &lt;strong&gt;两种状态&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;状态&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;裸盘（无分区表）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;整个磁盘直接格式化，没有分区&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/dev/vdb&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;分区盘（有分区表）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;磁盘上有分区表（DOS/GPT），数据在分区里&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/dev/vdb1&lt;/code&gt;（vdb 的分区）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;核心规则&lt;/strong&gt;：挂载时用分区，&lt;strong&gt;不要挂裸盘&lt;/strong&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/dev/vdb              ← 磁盘设备（不能直接挂载）
  └── /dev/vdb1       ← 分区设备（挂载它）
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;遇到的坑&lt;/h2&gt;
&lt;h3&gt;坑 1：挂错了，挂到裸盘而不是分区&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;fdisk -l&lt;/code&gt; 显示有分区表，但挂载时用了 &lt;code&gt;/dev/vdb&lt;/code&gt; 而不是 &lt;code&gt;/dev/vdb1&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;错误做法&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ubuntu@VM-0-10-ubuntu:~ $ sudo mount /dev/vdb /mnt/data    # ❌ 挂裸盘
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;正确做法&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ubuntu@VM-0-10-ubuntu:~ $ sudo mount /dev/vdb1 /mnt/data   # ✅ 挂分区
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;坑 2：格式化提示&quot;正在被系统使用&quot;&lt;/h3&gt;
&lt;p&gt;两种原因都会导致这个报错：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;原因 A&lt;/strong&gt; — 裸盘/分区被挂载了：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ubuntu@VM-0-10-ubuntu:~ $ sudo umount /dev/vdb     # 卸载占用
ubuntu@VM-0-10-ubuntu:~ $ sudo mkfs.ext4 /dev/vdb1 # 再格式化
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;原因 B&lt;/strong&gt; — &lt;strong&gt;fstab 里有旧的 UUID 条目&lt;/strong&gt;，&lt;code&gt;mount -a&lt;/code&gt; 会把旧的也挂上。检查 &lt;code&gt;/etc/fstab&lt;/code&gt; 清理掉无效的旧条目。&lt;/p&gt;
&lt;h3&gt;坑 3：用 fdisk 对已挂载的磁盘创建分区表&lt;/h3&gt;
&lt;p&gt;这是&lt;strong&gt;本次最大的教训&lt;/strong&gt;。磁盘 &lt;code&gt;/dev/vdb&lt;/code&gt; 已经格式化并挂载了，用户又用 &lt;code&gt;fdisk&lt;/code&gt; 在上面创建分区表 + 分区：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ubuntu@VM-0-10-ubuntu:~ $ sudo fdisk /dev/vdb   # ⚠️ 磁盘已挂载！fdisk 已经警告了
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;fdisk 会警告：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;该磁盘目前正在使用 - 不建议您重新分区。
推荐您卸载此磁盘上所有的文件系统。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;强行操作后：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;已有的文件系统签名变脏，&lt;code&gt;mkfs&lt;/code&gt; 拒绝格式化&lt;/li&gt;
&lt;li&gt;旧挂载和新分区互相冲突，&lt;code&gt;mount /dev/vdb1&lt;/code&gt; 报&quot;已经挂载或挂载点忙&quot;&lt;/li&gt;
&lt;li&gt;必须 &lt;code&gt;sudo umount /dev/vdb&lt;/code&gt; 解除裸盘挂载后，才能操作分区&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;教训&lt;/strong&gt;：&lt;strong&gt;永远不要对已挂载的磁盘执行 fdisk/parted 等分区操作&lt;/strong&gt;。先 &lt;code&gt;umount&lt;/code&gt;，再分区，再用 &lt;code&gt;partprobe&lt;/code&gt; 刷新分区表。&lt;/p&gt;
&lt;h3&gt;坑 4：fstab 多个重复/冲突条目&lt;/h3&gt;
&lt;p&gt;多次尝试后 fstab 里堆了多条记录：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;UUID=旧UUID /root/data/disk ext4 defaults 0 0     ← 第一次挂裸盘
UUID=旧UUID /home/ubuntu/data ext4 defaults 0 2   ← 第二次挂裸盘（同 UUID 不同挂载点）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;重新格式化后 UUID 变了，旧条目指向已不存在的文件系统，&lt;code&gt;mount -a&lt;/code&gt; 静默失败。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解决方法&lt;/strong&gt;：定期清理 fstab，只保留有效的条目。同个磁盘 UUID 不能出现在多条记录里。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;完整挂载步骤&lt;/h2&gt;
&lt;h3&gt;第一步：确认磁盘状态&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 查看所有磁盘和分区
ubuntu@VM-0-10-ubuntu:~ $ sudo fdisk -l

# 查看是否有文件系统/UUID
ubuntu@VM-0-10-ubuntu:~ $ sudo blkid /dev/vdb
ubuntu@VM-0-10-ubuntu:~ $ sudo blkid /dev/vdb1    # 如果 vdb 有分区表，看分区
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;结果判断：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;输出&lt;/th&gt;
&lt;th&gt;含义&lt;/th&gt;
&lt;th&gt;下一步&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;blkid /dev/vdb&lt;/code&gt; 有 UUID&lt;/td&gt;
&lt;td&gt;裸盘已格式化&lt;/td&gt;
&lt;td&gt;直接挂 &lt;code&gt;/dev/vdb&lt;/code&gt;，或分个区再挂&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;blkid /dev/vdb&lt;/code&gt; 有 PTUUID&lt;/td&gt;
&lt;td&gt;有分区表&lt;/td&gt;
&lt;td&gt;挂 &lt;code&gt;/dev/vdb1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;blkid /dev/vdb&lt;/code&gt; 无输出&lt;/td&gt;
&lt;td&gt;空盘&lt;/td&gt;
&lt;td&gt;跳到第二步&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;blkid /dev/vdb1&lt;/code&gt; 有 UUID&lt;/td&gt;
&lt;td&gt;分区已格式化&lt;/td&gt;
&lt;td&gt;直接挂 &lt;code&gt;/dev/vdb1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;blkid /dev/vdb1&lt;/code&gt; 无 UUID&lt;/td&gt;
&lt;td&gt;分区未格式化&lt;/td&gt;
&lt;td&gt;跳到第二步&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;第二步：创建分区（可选但推荐）&lt;/h3&gt;
&lt;p&gt;如果磁盘是空的，先分区再格式化的管理更灵活：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ubuntu@VM-0-10-ubuntu:~ $ sudo fdisk /dev/vdb                           #使用磁盘分区管理工具fdisk 对/dev/vdb 硬盘进行操作

    欢迎使用 fdisk (util-linux 2.39.3)。
    更改将停留在内存中，直到您决定将更改写入磁盘。
    使用写入命令前请三思。

    设备不包含可识别的分区表。
    创建了一个磁盘标识符为 0x465eb145 的新 DOS（MBR）磁盘标签。

    命令(输入 m 获取帮助)： n                                               #`n` = new，新建分区
    分区类型
       p   主分区 (0个主分区，0个扩展分区，4空闲)
       e   扩展分区 (逻辑分区容器)
    选择 (默认 p)： p                                                       #`p` primary：主分区，Linux数据盘直接用主分区即可
    分区号 (1-4, 默认  1): 1                                                #第一块主分区编号1，直接回车使用默认值
    第一个扇区 (2048-41943039, 默认 2048):                                  #2048是标准对齐扇区，保证磁盘读写性能，不要修改
    最后一个扇区，+/-sectors 或 +size{K,M,G,T,P} (2048-41943039, 默认 41943039): #默认占用磁盘全部剩余空间，完整20G分给 `/dev/vdb1`

    创建了一个新分区 1，类型为“Linux”，大小为 20 GiB。
    分区 #1 包含一个 ext4 签名。

    您想移除该签名吗？ 是[Y]/否[N]： y                                      #之前裸盘直接格式化过vdb，磁盘残留旧文件系统标识；
                                                                            #输入 `y` 清除旧ext4，避免新旧文件系统冲突、挂载报错。

    写入命令将移除该签名。

    命令(输入 m 获取帮助)： w                                               #`w` = write，把刚才所有分区操作写入磁盘永久生效
    分区表已调整。
    将调用 ioctl() 来重新读分区表。
    正在同步磁盘。

ubuntu@VM-0-10-ubuntu:~ $ sudo partprobe    # 刷新分区表
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;分区前务必确认磁盘没有被挂载&lt;/strong&gt;：&lt;code&gt;df -h | grep vdb&lt;/code&gt; 无输出再操作。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;第三步：格式化&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 裸盘无分区
ubuntu@VM-0-10-ubuntu:~ $ sudo mkfs.ext4 /dev/vdb

# 有分区
ubuntu@VM-0-10-ubuntu:~ $ sudo mkfs.ext4 /dev/vdb1
    mke2fs 1.47.0 (5-Feb-2023)
    创建含有 5242624 个块（每块 4k）和 1310720 个 inode 的文件系统
    文件系统 UUID：951370a1-59e5-4dcc-b51a-001fbdb6ec2b
    超级块的备份存储于下列块： 
            32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
            4096000

    正在分配组表： 完成                            
    正在写入 inode表： 完成                            
    创建日志（32768 个块）： 完成
    写入超级块和文件系统账户统计信息： 已完成 

&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 如果报&quot;正在被系统使用&quot;，先 &lt;code&gt;sudo umount /dev/vdb&lt;/code&gt;（或 &lt;code&gt;umount /dev/vdb1&lt;/code&gt;）解除占用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;第四步：创建挂载点&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;ubuntu@VM-0-10-ubuntu:~ $ sudo mkdir -p /mnt/data
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;第五步：挂载&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#挂载到/mnt/data
ubuntu@VM-0-10-ubuntu:~ $ sudo mount /dev/vdb1 /mnt/data

#重新加载所有单元配置，同步最新的 /etc/fstab
ubuntu@VM-0-10-ubuntu:~ $ sudo systemctl daemon-reload
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;第六步：验证&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;ubuntu@VM-0-10-ubuntu:~ $ df -h /mnt/data
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出示例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;文件系统        大小  已用  可用 已用% 挂载点
/dev/vdb1        20G   24K   19G    1% /mnt/data
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;第七步：开机自动挂载&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 查 UUID
ubuntu@VM-0-10-ubuntu:~ $ sudo blkid /dev/vdb1
# UUID=a8454183-3cfc-4a78-bef4-919e239e01f6

# 追加到 /etc/fstab
ubuntu@VM-0-10-ubuntu:~ $ echo &apos;UUID=a8454183-3cfc-4a78-bef4-919e239e01f6 /mnt/data ext4 defaults 0 2&apos; | sudo tee -a /etc/fstab
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ 修改 fstab 后检查：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ubuntu@VM-0-10-ubuntu:~ $ sudo mount -a          # 测试是否报错
 ubuntu@VM-0-10-ubuntu:~ $ cat /etc/fstab | grep vdb  # 确认没有重复条目
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h3&gt;第八步：创建软连接（可选）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;ubuntu@VM-0-10-ubuntu:~ $ mkdir -p ~/data
ubuntu@VM-0-10-ubuntu:~ $ ln -s /mnt/data ~/data
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之后 &lt;code&gt;cd ~/data&lt;/code&gt; 等价于 &lt;code&gt;cd /mnt/data&lt;/code&gt;。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;问题排查速查表&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;现象&lt;/th&gt;
&lt;th&gt;原因&lt;/th&gt;
&lt;th&gt;解决&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mount: 已经挂载或挂载点忙&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;裸盘在同一个挂载点被占用了&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo umount /dev/vdb&lt;/code&gt; 后再试&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mkfs: 正在被系统使用&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;磁盘已挂载或 fstab 里有旧条目&lt;/td&gt;
&lt;td&gt;&lt;code&gt;umount&lt;/code&gt; + 清理 fstab 重复条目&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;blkid /dev/vdb1&lt;/code&gt; 只有 PARTUUID&lt;/td&gt;
&lt;td&gt;分区创建了但没格式化&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo mkfs.ext4 /dev/vdb1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;fstab 改了但 &lt;code&gt;df -h&lt;/code&gt; 不生效&lt;/td&gt;
&lt;td&gt;systemd 缓存了旧 fstab&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl daemon-reload&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;多个相同 UUID 的 fstab 条目&lt;/td&gt;
&lt;td&gt;之前多次操作残留&lt;/td&gt;
&lt;td&gt;删掉多余的，只保留一条&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</content:encoded></item><item><title>自动小说生成工具-AI_NovelGenerator</title><link>https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/%E8%87%AA%E5%8A%A8%E5%B0%8F%E8%AF%B4%E7%94%9F%E6%88%90%E5%B7%A5%E5%85%B7-ai-novelgenerator/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/%E8%87%AA%E5%8A%A8%E5%B0%8F%E8%AF%B4%E7%94%9F%E6%88%90%E5%B7%A5%E5%85%B7-ai-novelgenerator/</guid><description>自动小说生成工具“AI_NovelGenerator”构建留档</description><pubDate>Tue, 16 Jun 2026 06:37:55 GMT</pubDate><content:encoded>&lt;h1&gt;自动小说生成工具“AI_NovelGenerator”构建留档&lt;/h1&gt;
&lt;h2&gt;一、AI_NovelGenerator介绍、官网&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;AI_NovelGenerator是啥我不好说直接截图GitHub上的介绍吧
&lt;img src=&quot;/images/%E6%8C%87%E5%8D%97/%E8%87%AA%E5%8A%A8%E5%B0%8F%E8%AF%B4%E7%94%9F%E6%88%90%E5%B7%A5%E5%85%B7-AI_NovelGenerator/97ff1bea764643498d1aa4cf284c5eac.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;GitHub上的链接是：链接&lt;a href=&quot;https://github.com/YILING0013/AI_NovelGenerator&quot;&gt;Github开源链接&lt;/a&gt;
有兴趣的大爪子们可以自己去拉一个试试&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/YILING0013/AI_NovelGenerator
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;二、构建前环境准备&lt;/h2&gt;
&lt;p&gt;确保满足以下运行条件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python 3.9+ 运行环境（推荐3.10-3.12之间）&lt;/li&gt;
&lt;li&gt;pip 包管理工具&lt;/li&gt;
&lt;li&gt;有效API密钥：&lt;/li&gt;
&lt;li&gt;云端服务：OpenAI / DeepSeek 等&lt;/li&gt;
&lt;li&gt;本地服务：Ollama 等兼容 OpenAI 的接口&lt;/li&gt;
&lt;li&gt;Python：我用的是&lt;a href=&quot;https://www.python.org/ftp/python/3.12.1/python-3.12.1.exe&quot;&gt;3.12.1的版本&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;API：我用的是&lt;a href=&quot;https://cloud.siliconflow.cn/i/qFomtKZe&quot;&gt;硅基流动&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;没有硅基流动账号的可以通过我的邀请码(qFomtKZe)在&lt;a href=&quot;https://cloud.siliconflow.cn/i/qFomtKZe&quot;&gt;硅基流动&lt;/a&gt;完成注册获取2000 万 Tokens赠送&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;三、构建过程&lt;/h2&gt;
&lt;p&gt;注：构建安装GitHub上也有详细方法，大爪子们可以先自行摸索试试
1、安装编译工具(感觉win下还是安装这个步骤简单点)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;访问Visual Studio Build Tools下载并安装 C++编译工具，用于构建部分模块包;&lt;/li&gt;
&lt;li&gt;安装时，默认只包含 MSBuild 工具，需手动勾选左上角列表栏中的 C++ 桌面开发 选项。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2、安装依赖并运行&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;打开终端，进入项目源文件目录：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;cd AI_NovelGenerator
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;安装项目依赖：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;pip install -r requirements.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;安装完成后，运行主程序：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;python main.py
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;如果缺失部分依赖，后续手动执行&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;pip install XXX
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、打包为可执行文件&lt;/h2&gt;
&lt;p&gt;1、打包为可执行文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip install pyinstaller
pyinstaller main.spec
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;注意：打包时候会报错说找不到“customtkinter”库
只要你前面运行“python main.py”项目可以跑起来，这个库是没有问题的
报这个错误可以修改“main.spec”文件中第26行&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;customtkinter_dir = r&apos;c:/Users/xieli/Desktop/AI_NovelGenerator/.venv/Lib/site-packages/customtkinter&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个是开源作者的库链接，把这里改成我们的库链接就好&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;customtkinter_dir = r&apos;C:\Users\ta206682\AppData\Local\Programs\Python\Python312\Lib\site-packages&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;这个是我的，大爪子们记得改成自己的呀&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;重新打包&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pyinstaller main.spec
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、美化&lt;/h2&gt;
&lt;p&gt;这个时候跑起来的项目里面很多接口都是英文的，这对于我这种英文白痴就觉得十分的不友好了
我们可以修改下项目中的接口词，达到汉化的效果
打开Git-Bash窗口且进入AI_NovelGenerator项目目录
运行以下代码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;find . -type f -exec sed -i &quot;s/Main Functions/主要功能/g&quot; {} +
find . -type f -exec sed -i &quot;s/Novel Architecture/小说架构/g&quot; {} +
find . -type f -exec sed -i &quot;s/Chapter Blueprint/章节蓝图/g&quot; {} +
find . -type f -exec sed -i &quot;s/Character State/角色状态/g&quot; {} +
find . -type f -exec sed -i &quot;s/Global Summary/全局概述/g&quot; {} +
find . -type f -exec sed -i &quot;s/Chapters Manage/章节管理/g&quot; {} +
find . -type f -exec sed -i &quot;s/LLM Model settings/大语言模型设置/g&quot; {} +
find . -type f -exec sed -i &quot;s/Embedding settings/嵌入设置/g&quot; {} +
find . -type f -exec sed -i &quot;s/LLM API Key:/LLM API 密钥:/g&quot; {} +
find . -type f -exec sed -i &quot;s/LLM Base URL:/LLM 基础 URL:/g&quot; {} +
find . -type f -exec sed -i &quot;s/Model Name:/模型名称:/g&quot; {} +
find . -type f -exec sed -i &quot;s/Temperature:/随机数:/g&quot; {} +
find . -type f -exec sed -i &quot;s/Max Tokens:/最大标记数:/g&quot; {} +
find . -type f -exec sed -i &quot;s/Timeout (sec):/超时（秒）:/g&quot; {} +
find . -type f -exec sed -i &quot;s/Embedding API Key:/嵌入模型 API 密钥:/g&quot; {} +
find . -type f -exec sed -i &quot;s/Embedding 接口格式:/嵌入接口格式:/g&quot; {} +
find . -type f -exec sed -i &quot;s/Embedding Base URL:/嵌入基础 URL:/g&quot; {} +
find . -type f -exec sed -i &quot;s/Embedding Model Name:/嵌入模型名称:/g&quot; {} +
find . -type f -exec sed -i &quot;s/Retrieval Top-K:/检索返回 Top-K 值:/g&quot; {} +
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个代码效果是查询接口名词替换成中文名词
来看看效果吧
&lt;img src=&quot;/images/%E6%8C%87%E5%8D%97/%E8%87%AA%E5%8A%A8%E5%B0%8F%E8%AF%B4%E7%94%9F%E6%88%90%E5%B7%A5%E5%85%B7-AI_NovelGenerator/94c2cd91690e4f12b418eaf78d79baf0.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/%E6%8C%87%E5%8D%97/%E8%87%AA%E5%8A%A8%E5%B0%8F%E8%AF%B4%E7%94%9F%E6%88%90%E5%B7%A5%E5%85%B7-AI_NovelGenerator/31c726bd74704929bbdde0eaab451ae4.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>ollama 手动注册模型</title><link>https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/ollama-%E6%89%8B%E5%8A%A8%E6%B3%A8%E5%86%8C%E6%A8%A1%E5%9E%8B/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/ollama-%E6%89%8B%E5%8A%A8%E6%B3%A8%E5%86%8C%E6%A8%A1%E5%9E%8B/</guid><pubDate>Tue, 16 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;ollama 手动注册模型&lt;/h1&gt;
&lt;p&gt;别慌，这个是国内网络访问 Ollama 官方仓库超时导致的。我给你一套 &lt;strong&gt;Windows 环境下，100% 可用的「离线导入方案」&lt;/strong&gt;，一步一步跟着做就行。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;一、方案选择&lt;/h2&gt;
&lt;p&gt;既然镜像也超时，我们直接跳过网络下载，用 &lt;strong&gt;离线 GGUF 模型文件 + 手动导入&lt;/strong&gt; 的方式，完全不用连外网。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;二、步骤 1：下载模型文件（国内高速）&lt;/h2&gt;
&lt;p&gt;我们直接从 &lt;a href=&quot;https://modelscope.cn/models&quot;&gt;&lt;strong&gt;魔搭社区（ModelScope）&lt;/strong&gt;&lt;/a&gt; 下载 &lt;a href=&quot;https://modelscope.cn/models/qwen/Qwen2.5-7B-Instruct-GGUF/summary&quot;&gt;&lt;code&gt;qwen2.5:7b-instruct&lt;/code&gt;&lt;/a&gt; 的 GGUF 量化版，国内速度快，无网络限制。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;打开魔搭的模型地址：&lt;a href=&quot;https://modelscope.cn/models/qwen/Qwen2.5-7B-Instruct-GGUF/summary&quot;&gt;Qwen2.5-7B-Instruct-GGUF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;找到 &lt;code&gt;qwen2.5-7b-instruct-q4_k_m.gguf&lt;/code&gt; 这个文件（约 4.7GB，适合你的 16GB 内存），下载到你电脑的下。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;三、步骤 2：创建 &lt;code&gt;Modelfile&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;在 &lt;code&gt;模型文件&lt;/code&gt; 文件夹里，新建一个文本文件，命名为 &lt;code&gt;Modelfile&lt;/code&gt;（注意不要带 &lt;code&gt;.txt&lt;/code&gt; 后缀），写入以下内容：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FROM ./qwen2.5-7b-instruct-q4_k_m.gguf
TEMPLATE &quot;{{ if .System }}&amp;lt;|im_start|&amp;gt;system
{{ .System }}&amp;lt;|im_end|&amp;gt;
{{ end }}{{ if .Prompt }}&amp;lt;|im_start|&amp;gt;user
{{ .Prompt }}&amp;lt;|im_end|&amp;gt;
&amp;lt;|im_start|&amp;gt;assistant
{{ end }}{{ .Response }}&amp;lt;|im_end|&amp;gt;&quot;
PARAMETER stop &quot;&amp;lt;|im_end|&amp;gt;&quot;
PARAMETER temperature 0.7
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;四、步骤 3：用 Ollama 导入模型&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 打开 PowerShell，进入 `模型文件` 目录：
cd 模型文件路径

# 执行导入命令，把模型注册到 Ollama：
ollama create qwen2.5:7b-instruct -f Modelfile

# 验证是否导入成功：
ollama list

# 你会看到 `qwen2.5:7b-instruct` 出现在列表里，说明导入成功。
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、步骤 4：测试运行&lt;/h2&gt;
&lt;p&gt;直接运行模型，看是否能正常对话：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ollama run qwen2.5:7b-instruct
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;六、步骤 5：Hermes 对接 Ollama&lt;/h2&gt;
&lt;p&gt;回到你的 Rocky Linux 服务器，配置 Hermes 使用 Ollama：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hermes model
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;按提示选择：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Provider：&lt;code&gt;ollama&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Base URL：&lt;code&gt;http://你Windows电脑的局域网IP:11434&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;API Key：留空&lt;/li&gt;
&lt;li&gt;Model：&lt;code&gt;qwen2.5:7b-instruct&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;注意：Windows 上要开启 Ollama 的局域网访问，需要设置环境变量：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$env:OLLAMA_HOST=&quot;0.0.0.0&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后重启 Ollama 服务。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;七、备选方案（如果不想手动下载）&lt;/h2&gt;
&lt;p&gt;如果魔搭下载麻烦，也可以用 Ollama 自带的代理设置（需要你有可用的代理）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 先设置代理
$env:HTTP_PROXY=&quot;http://127.0.0.1:7890&quot;
$env:HTTPS_PROXY=&quot;http://127.0.0.1:7890&quot;
# 再拉模型
ollama pull qwen2.5:7b-instruct
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;ollama 接口地址&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;

### 本地 Ollama 默认 API 地址
- **基础地址**：`http://localhost:11434` 或 `http://127.0.0.1:11434`
- **完整 API 根路径**：`http://localhost:11434/api`

### 常用接口
- **查看模型列表**：`GET /api/tags`
 
  curl http://localhost:11434/api/tags
 
- **文本生成（generate）**：`POST /api/generate`
 
  curl http://localhost:11434/api/generate -d &apos;{
    &quot;model&quot;: &quot;qwen2.5:7b-instruct&quot;,
    &quot;prompt&quot;: &quot;你好&quot;
  }&apos;
 
- **对话（chat，支持多轮）**：`POST /api/chat`
 
  curl http://localhost:11434/api/chat -d &apos;{
    &quot;model&quot;: &quot;qwen2.5:7b-instruct&quot;,
    &quot;messages&quot;: [{&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: &quot;你好&quot;}]
  }&apos;
 
- **OpenAI 兼容地址**：`http://localhost:11434/v1`
  &amp;gt; 可直接替代 OpenAI 的 `https://api.openai.com/v1`

### 允许外部设备访问（WSL/局域网）
默认仅本机访问，需全局监听：
 
# WSL 终端临时设置
export OLLAMA_HOST=0.0.0.0:11434
ollama serve
 
然后用 **Windows 主机 IP** 访问（如 `http://192.168.1.100:11434`）。

&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;优先用 &lt;strong&gt;离线导入方案&lt;/strong&gt;，完全不用连外网，适合国内网络环境。&lt;/li&gt;
&lt;li&gt;导入完成后，直接就能在 Hermes 里用 Ollama 模型了。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;好，那我们&lt;strong&gt;先安全备份&lt;/strong&gt;，再动环境，稳妥得很。&lt;/p&gt;
&lt;p&gt;你是 &lt;strong&gt;WSL1 Ubuntu&lt;/strong&gt;，我给你最简单、最稳妥的 &lt;strong&gt;完整备份导出方法&lt;/strong&gt;，导出一个压缩包，以后想恢复随时一键还原。&lt;/p&gt;
</content:encoded></item><item><title>Astro-Fuwari主题全页面文字修改对照表（已校正）</title><link>https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/astro-fuwari%E4%B8%BB%E9%A2%98%E5%85%A8%E9%A1%B5%E9%9D%A2%E6%96%87%E5%AD%97%E4%BF%AE%E6%94%B9%E5%AF%B9%E7%85%A7%E8%A1%A8/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/astro-fuwari%E4%B8%BB%E9%A2%98%E5%85%A8%E9%A1%B5%E9%9D%A2%E6%96%87%E5%AD%97%E4%BF%AE%E6%94%B9%E5%AF%B9%E7%85%A7%E8%A1%A8/</guid><description>本项目博客各页面/模块对应文件路径速查，已验证校正</description><pubDate>Mon, 15 Jun 2026 06:30:00 GMT</pubDate><content:encoded>&lt;h1&gt;Fuwari (Astro) 全页面文字修改对照表（已校正）&lt;/h1&gt;
&lt;p&gt;项目根目录：&lt;code&gt;/home/ubuntu/Astro/&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;✅ 以下路径均经实际验证，对照原表已删除无效条目。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;一、独立页面（.astro 是页面壳，spec/*.md 写正文）&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;关于页面（About）&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;外壳：&lt;code&gt;src/pages/about.astro&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;正文：&lt;code&gt;src/content/spec/about.md&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;二、列表页（标题文字取自 i18n，无独立 md 正文）&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;归档页（Archive）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;外壳：&lt;code&gt;src/pages/archive.astro&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;页面标题「归档」：&lt;code&gt;src/i18n/languages/zh_CN.ts&lt;/code&gt; → &lt;code&gt;[Key.archive]: &apos;归档&apos;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;⚡ 标签筛选和分类筛选也通过此页 URL 参数实现：&lt;code&gt;/archive/?tag=xxx&lt;/code&gt;、&lt;code&gt;/archive/?category=xxx&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;标签（Tags）&lt;/strong&gt; — ❌ 无独立页面，仅侧边栏 widget&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;widget 组件：&lt;code&gt;src/components/widget/Tags.astro&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;标题文字：&lt;code&gt;src/i18n/languages/zh_CN.ts&lt;/code&gt; → &lt;code&gt;[Key.tags]: &apos;标签&apos;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;点击标签 → 跳转到归档页 &lt;code&gt;/archive/?tag=xxx&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;分类（Categories）&lt;/strong&gt; — ❌ 无独立页面，仅侧边栏 widget&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;widget 组件：&lt;code&gt;src/components/widget/Categories.astro&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;标题文字：&lt;code&gt;src/i18n/languages/zh_CN.ts&lt;/code&gt; → &lt;code&gt;[Key.categories]: &apos;分类&apos;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;点击分类 → 跳转到归档页 &lt;code&gt;/archive/?category=xxx&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;三、首页&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;首页路由&lt;/strong&gt;：&lt;code&gt;src/pages/[...page].astro&lt;/code&gt;（动态分页路由，❌ 不存在 index.astro）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;侧边「最新文章」标题&lt;/strong&gt;：&lt;code&gt;src/i18n/languages/zh_CN.ts&lt;/code&gt; → &lt;code&gt;[Key.recentPosts]: &apos;最新文章&apos;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;网站标题、副标题&lt;/strong&gt;：&lt;code&gt;src/config.ts&lt;/code&gt; → &lt;code&gt;siteConfig { title, subtitle }&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;四、侧边栏个人信息&lt;/h2&gt;
&lt;p&gt;文件：&lt;code&gt;src/config.ts&lt;/code&gt; → &lt;code&gt;profileConfig { name, bio, avatar, links }&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;avatar: &quot;assets/images/demo-avatar.png&quot;,   // 头像路径（相对于 /src）
name: &quot;肥猫少杰&quot;,                            // 昵称
bio: &quot;用文字记录生活，用技术改变世界。&quot;,         // 个性签名
links: [ /* 社交链接图标列表 */ ]
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;五、顶部导航菜单&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;菜单文字翻译&lt;/strong&gt;：&lt;code&gt;src/i18n/languages/zh_CN.ts&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[Key.home]: &apos;主页&apos;&lt;/code&gt;、&lt;code&gt;[Key.about]: &apos;关于&apos;&lt;/code&gt;、&lt;code&gt;[Key.archive]: &apos;归档&apos;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;菜单项配置（增删链接/顺序）&lt;/strong&gt;：&lt;code&gt;src/config.ts&lt;/code&gt; → &lt;code&gt;navBarConfig.links&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;可使用 &lt;code&gt;LinkPreset.Home&lt;/code&gt;、&lt;code&gt;LinkPreset.About&lt;/code&gt;、&lt;code&gt;LinkPreset.Archive&lt;/code&gt; 预设&lt;/li&gt;
&lt;li&gt;也可自定义：&lt;code&gt;{ name: &quot;Hermes&quot;, url: &quot;http://...&quot;, external: true }&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;预设映射关系&lt;/strong&gt;：&lt;code&gt;src/constants/link-presets.ts&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;六、文章相关&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;所有博客文章 md&lt;/strong&gt;：&lt;code&gt;src/content/posts/任意目录/xxx.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文章详情页模板&lt;/strong&gt;：&lt;code&gt;src/pages/posts/[...slug].astro&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文章底部版权许可&lt;/strong&gt;：&lt;code&gt;src/config.ts&lt;/code&gt; → &lt;code&gt;licenseConfig { enable, name, url }&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;「无标题」「未分类」「无标签」默认文案&lt;/strong&gt;：&lt;code&gt;src/i18n/languages/zh_CN.ts&lt;/code&gt; → &lt;code&gt;untitled&lt;/code&gt;、&lt;code&gt;uncategorized&lt;/code&gt;、&lt;code&gt;noTags&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;七、全局组件与固定文案&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模块&lt;/th&gt;
&lt;th&gt;文件路径&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;搜索&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;src/components/Search.svelte&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;客户端搜索（Pagefind），导航栏内嵌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;搜索按钮文字&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;src/i18n/languages/zh_CN.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[Key.search]: &apos;搜索&apos;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;页脚&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;src/components/Footer.astro&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;版权年份、RSS、站点地图链接&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;主题色&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;src/i18n/languages/zh_CN.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[Key.themeColor]: &apos;主题色&apos;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;亮色/暗色/跟随系统&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;src/i18n/languages/zh_CN.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[Key.lightMode/darkMode/systemMode]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;评论标题&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;src/i18n/languages/zh_CN.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[Key.comments]: &apos;评论&apos;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;更多&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;src/i18n/languages/zh_CN.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[Key.more]: &apos;更多&apos;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;作者/发布于&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;src/i18n/languages/zh_CN.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[Key.author]: &apos;作者&apos;&lt;/code&gt;、&lt;code&gt;[Key.publishedAt]: &apos;发布于&apos;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;许可协议&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;src/i18n/languages/zh_CN.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[Key.license]: &apos;许可协议&apos;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;字数/分钟数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;src/i18n/languages/zh_CN.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[Key.wordCount/wordsCount/minuteCount/minutesCount]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;文章计数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;src/i18n/languages/zh_CN.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[Key.postCount/postsCount]: &apos;篇文章&apos;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;八、修改完生效命令&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;cd /home/ubuntu/Astro
pnpm run build &amp;amp;&amp;amp; sudo rsync -r --delete dist/ /var/www/astro/
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;九、视频背景（2026年6月22日新增）&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;视频来源&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://mirai.sukuy.com/share_bb267daacbe5d1966f1d9e4bf9cbddcc1775912237115.mp4&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;组件&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;src/components/VideoBanner.astro&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;引入布局&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;src/layouts/MainGridLayout.astro&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;视频高度&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;100vh&lt;/code&gt;（全屏 Hero）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;失真处理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;object-cover&lt;/code&gt; + &lt;code&gt;object-position: center center&lt;/code&gt;，等比缩放裁切&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;底部过渡&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;linear-gradient(to bottom, transparent 0%, white 100%)&lt;/code&gt;，覆盖底部 40%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;深色模式&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;渐变切换为 &lt;code&gt;#1a1a2e&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;滚动行为&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;absolute&lt;/code&gt; 跟随页面流，下滑后被下方白色内容自然覆盖&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;开关&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MainGridLayout.astro&lt;/code&gt; 中 &lt;code&gt;const videoBannerEnabled = true;&lt;/code&gt;，改为 &lt;code&gt;false&lt;/code&gt; 关闭&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</content:encoded></item><item><title>Windows 解决 &quot;nul 文件无法删除&quot; 问题</title><link>https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/windows%E8%A7%A3%E5%86%B3nul%E6%96%87%E4%BB%B6%E6%97%A0%E6%B3%95%E5%88%A0%E9%99%A4%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/windows%E8%A7%A3%E5%86%B3nul%E6%96%87%E4%BB%B6%E6%97%A0%E6%B3%95%E5%88%A0%E9%99%A4%E9%97%AE%E9%A2%98/</guid><description>Windows下误操作生成的nul文件无法通过常规方式删除？本文提供三种切实有效的解决方案，从命令行到安全模式，彻底清除这个Windows保留设备名导致的畸形文件。</description><pubDate>Tue, 09 Jun 2026 16:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Windows 解决 &quot;nul 文件无法删除&quot; 问题&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;桌面上突然多了一个名为 &lt;code&gt;nul&lt;/code&gt; 的文件或文件夹，删除时提示「MS-DOS 功能无效」或「路径无效」？别担心，这不是病毒，而是 Windows 的保留设备名在作祟。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;问题现象&lt;/h2&gt;
&lt;p&gt;当你在 Windows 中尝试删除名为 &lt;code&gt;nul&lt;/code&gt; 的文件时，会看到类似以下错误：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&quot;MS-DOS 功能无效&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&quot;无法删除 nul：路径无效&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&quot;文件或目录损坏且无法读取&quot;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;即使使用 &lt;code&gt;Shift + Delete&lt;/code&gt; 也无法删除，这是因为 &lt;code&gt;nul&lt;/code&gt; 是 Windows 系统保留的设备名，和 &lt;code&gt;con&lt;/code&gt;、&lt;code&gt;prn&lt;/code&gt;、&lt;code&gt;lpt1&lt;/code&gt; 等一样，不能被当作普通文件处理。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;方法一：命令行强制删除（推荐 ⭐）&lt;/h2&gt;
&lt;p&gt;这是最简单、最可靠的方法，不需要安装任何第三方软件。&lt;/p&gt;
&lt;h3&gt;步骤&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;以管理员身份打开命令提示符&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;按下 &lt;code&gt;Win + R&lt;/code&gt;，输入 &lt;code&gt;cmd&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;按 &lt;code&gt;Ctrl + Shift + Enter&lt;/code&gt; 以管理员身份运行&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;切换到文件所在目录&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /d D:\用户\用户名\Desktop
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;将路径替换为你实际的文件所在目录&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;执行删除命令&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果是&lt;strong&gt;文件&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;del \\?\%cd%\nul
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果是&lt;strong&gt;文件夹&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rmdir /s /q \\?\%cd%\nul
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;原理说明&lt;/strong&gt;：&lt;code&gt;\\?\&lt;/code&gt; 是 Windows 的 Win32 文件命名空间的扩展长度前缀，它会绕过 Windows 的设备名保留字检查，让系统把 &lt;code&gt;nul&lt;/code&gt; 当作普通文件来处理。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;验证&lt;/h3&gt;
&lt;p&gt;删除后执行 &lt;code&gt;dir&lt;/code&gt; 确认 &lt;code&gt;nul&lt;/code&gt; 已经消失。如果仍有残留，尝试重启电脑后再用此方法删除。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;方法二：使用文件解锁工具&lt;/h2&gt;
&lt;p&gt;如果你不习惯使用命令行，可以借助图形化工具。&lt;/p&gt;
&lt;h3&gt;推荐工具&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;IObit Unlocker&lt;/strong&gt; — 免费，操作简单&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LockHunter&lt;/strong&gt; — 开源免费，轻量&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unlocker&lt;/strong&gt; — 经典工具，但部分杀毒软件会误报&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;操作步骤&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;下载并安装上述任一工具&lt;/li&gt;
&lt;li&gt;右键点击 &lt;code&gt;nul&lt;/code&gt; 文件&lt;/li&gt;
&lt;li&gt;选择「使用 IObit Unlocker 解锁」（或类似选项）&lt;/li&gt;
&lt;li&gt;工具会自动检测文件占用状态&lt;/li&gt;
&lt;li&gt;选择「删除」并执行&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ 注意：下载工具时请从官方网站获取，避免捆绑软件。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;方法三：安全模式下删除&lt;/h2&gt;
&lt;p&gt;如果前两种方法都无效，可以在安全模式下删除。&lt;/p&gt;
&lt;h3&gt;步骤&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;进入安全模式&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;不同品牌的电脑快捷键不同：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;品牌&lt;/th&gt;
&lt;th&gt;按键&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;通用&lt;/td&gt;
&lt;td&gt;&lt;code&gt;F8&lt;/code&gt;（传统模式）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;联想&lt;/td&gt;
&lt;td&gt;&lt;code&gt;F12&lt;/code&gt; 或 &lt;code&gt;Novo&lt;/code&gt; 键&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;惠普&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Esc&lt;/code&gt; 或 &lt;code&gt;F11&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;戴尔&lt;/td&gt;
&lt;td&gt;&lt;code&gt;F8&lt;/code&gt; 或 &lt;code&gt;F12&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;华硕&lt;/td&gt;
&lt;td&gt;&lt;code&gt;F9&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;或在 Windows 设置中：&lt;code&gt;更新与安全&lt;/code&gt; → &lt;code&gt;恢复&lt;/code&gt; → &lt;code&gt;高级启动&lt;/code&gt; → &lt;code&gt;立即重新启动&lt;/code&gt; → &lt;code&gt;疑难解答&lt;/code&gt; → &lt;code&gt;高级选项&lt;/code&gt; → &lt;code&gt;启动设置&lt;/code&gt; → &lt;code&gt;重启&lt;/code&gt; → 选择 &lt;code&gt;4&lt;/code&gt; 或 &lt;code&gt;F4&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;在安全模式下删除&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;进入安全模式后，定位到 &lt;code&gt;nul&lt;/code&gt; 文件&lt;/li&gt;
&lt;li&gt;直接右键 → 删除&lt;/li&gt;
&lt;li&gt;清空回收站&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;重启电脑&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;正常重启回到普通模式即可&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;💡 为什么会出现 nul 文件？&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;nul&lt;/code&gt; 是 Windows 从 DOS 时代继承下来的&lt;strong&gt;空设备名&lt;/strong&gt;，类似于 Linux 的 &lt;code&gt;/dev/null&lt;/code&gt;。正常情况下你无法通过资源管理器或命令提示符创建名为 &lt;code&gt;nul&lt;/code&gt; 的文件——这是系统的保护机制。&lt;/p&gt;
&lt;p&gt;出现 &lt;code&gt;nul&lt;/code&gt; 文件的原因通常有：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;第三方软件的 Bug&lt;/strong&gt; — 某些程序（尤其是老旧软件）调用了 Windows API 创建文件时，没有对文件名做保留字检查&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;压缩/解压工具的误操作&lt;/strong&gt; — 从某些压缩包中解压出来的畸形文件名&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;手动重命名失败&lt;/strong&gt; — 在特殊环境下（如注册表编辑、磁盘错误恢复后）误将文件重命名为 &lt;code&gt;nul&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;🛡️ 如何避免？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;不要手动将文件或文件夹重命名为 Windows 保留设备名（&lt;code&gt;nul&lt;/code&gt;、&lt;code&gt;con&lt;/code&gt;、&lt;code&gt;prn&lt;/code&gt;、&lt;code&gt;aux&lt;/code&gt;、&lt;code&gt;lpt1&lt;/code&gt;-&lt;code&gt;lpt9&lt;/code&gt;、&lt;code&gt;com1&lt;/code&gt;-&lt;code&gt;com9&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;保持解压软件更新到最新版本&lt;/li&gt;
&lt;li&gt;如果经常遇到，可以用以下命令检查目录下是否有其他保留名文件：&lt;pre&gt;&lt;code&gt;dir | findstr /i &quot;\&amp;lt;con\&amp;gt; \&amp;lt;prn\&amp;gt; \&amp;lt;aux\&amp;gt; \&amp;lt;nul\&amp;gt;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;难度&lt;/th&gt;
&lt;th&gt;是否需要工具&lt;/th&gt;
&lt;th&gt;推荐场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;命令行强制删除&lt;/td&gt;
&lt;td&gt;⭐⭐&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;首选方案，适用范围最广&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;文件解锁工具&lt;/td&gt;
&lt;td&gt;⭐&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;td&gt;不熟悉命令行的用户&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;安全模式删除&lt;/td&gt;
&lt;td&gt;⭐⭐⭐&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;前两种方法无效时&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;遇到 &lt;code&gt;nul&lt;/code&gt; 文件不用慌，先用方法一即可解决大部分情况。如果不行，按顺序尝试方法二和方法三，总能搞定。&lt;/p&gt;
</content:encoded></item><item><title>Linux 终端复刻 PowerShell 历史命令选择功能</title><link>https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/linux%E5%A4%8D%E5%88%BBpowershell%E5%8E%86%E5%8F%B2%E5%91%BD%E4%BB%A4%E9%80%89%E6%8B%A9%E5%8A%9F%E8%83%BD/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/linux%E5%A4%8D%E5%88%BBpowershell%E5%8E%86%E5%8F%B2%E5%91%BD%E4%BB%A4%E9%80%89%E6%8B%A9%E5%8A%9F%E8%83%BD/</guid><description>Bash 配置：输入命令按上箭头匹配历史（PowerShell 同款）</description><pubDate>Tue, 09 Jun 2026 10:39:00 GMT</pubDate><content:encoded>&lt;h1&gt;原生 Bash 实现「输 git 弹出历史」（Windows PowerShell 同款体验）&lt;/h1&gt;
&lt;h2&gt;一、直接给你能复制的配置（一步到位）&lt;/h2&gt;
&lt;h3&gt;1. 打开配置文件&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;vim ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 把下面这段代码，&lt;strong&gt;粘贴到文件最底部&lt;/strong&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# ======================
# 原生 Bash：输 git 按上箭头 弹出历史（PowerShell 同款）
# ======================
# 上下箭头：只搜索以当前输入开头的历史命令
bind &apos;&quot;\e[A&quot;: history-search-backward&apos;
bind &apos;&quot;\e[B&quot;: history-search-forward&apos;

# 让历史记录更强大（不重复、立即保存）
HISTCONTROL=ignoredups:ignorespace
shopt -s histappend
PROMPT_COMMAND=&quot;history -a; history -c; history -r&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 按 ESC → 输入 &lt;code&gt;:wq&lt;/code&gt; 保存退出&lt;/h3&gt;
&lt;h3&gt;4. 立即生效&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;source ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;二、现在直接能用！效果演示&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;1、输入：git
2、按 上箭头 ↑
3、自动弹出 所有你之前输过的 git 开头的历史命令
4、找到想要的 → 直接回车执行，或左右键修改
完全和你在 Windows PowerShell 里的体验一模一样！
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>数据库权限修改</title><link>https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E6%9D%83%E9%99%90%E4%BF%AE%E6%94%B9/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E6%9D%83%E9%99%90%E4%BF%AE%E6%94%B9/</guid><description> 数据库权限修改</description><pubDate>Tue, 09 Jun 2026 06:14:00 GMT</pubDate><content:encoded>&lt;h1&gt;数据库权限修改&lt;/h1&gt;
&lt;h2&gt;解决方案&lt;/h2&gt;
&lt;p&gt;您需要为这个新创建的 &lt;code&gt;&apos;root&apos;@&apos;%&apos;&lt;/code&gt; 用户授予适当的数据库访问权限：&lt;/p&gt;
&lt;h3&gt;方案1：授予所有权限（推荐用于管理）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;-- 授予所有数据库的所有权限（类似超级用户）
GRANT ALL PRIVILEGES ON *.* TO &apos;root&apos;@&apos;%&apos; WITH GRANT OPTION;

-- 刷新权限
FLUSH PRIVILEGES;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;方案2：授予特定数据库的权限&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;-- 授予特定数据库的所有权限（例如 test 数据库）
GRANT ALL PRIVILEGES ON test.* TO &apos;root&apos;@&apos;%&apos;;

-- 刷新权限
FLUSH PRIVILEGES;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;方案3：授予只读权限（更安全）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;-- 授予所有数据库的只读权限
GRANT SELECT ON *.* TO &apos;root&apos;@&apos;%&apos;;

-- 刷新权限
FLUSH PRIVILEGES;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;验证权限&lt;/h3&gt;
&lt;p&gt;授予权限后，您可以验证用户的权限：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 查看用户权限
SHOW GRANTS FOR &apos;root&apos;@&apos;%&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;安全建议&lt;/h3&gt;
&lt;p&gt;虽然使用 &lt;code&gt;root&lt;/code&gt; 作为远程用户名很方便，但从安全角度考虑，我建议：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;创建专用管理账户&lt;/strong&gt;：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;CREATE USER &apos;admin_remote&apos;@&apos;%&apos; IDENTIFIED BY &apos;复杂密码&apos;;
GRANT ALL PRIVILEGES ON *.* TO &apos;admin_remote&apos;@&apos;%&apos; WITH GRANT OPTION;
FLUSH PRIVILEGES;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;限制访问来源&lt;/strong&gt;（更安全）：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;-- 只允许从特定IP段连接
CREATE USER &apos;admin_remote&apos;@&apos;192.168.88.%&apos; IDENTIFIED BY &apos;复杂密码&apos;;
GRANT ALL PRIVILEGES ON *.* TO &apos;admin_remote&apos;@&apos;192.168.88.%&apos;;
FLUSH PRIVILEGES;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;您遇到的问题是因为新创建的 &lt;code&gt;&apos;root&apos;@&apos;%&apos;&lt;/code&gt; 用户还没有被授予访问普通数据库的权限。只需要执行相应的 &lt;code&gt;GRANT&lt;/code&gt; 语句即可解决。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;建议操作&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 在每台MySQL服务器上执行
GRANT ALL PRIVILEGES ON *.* TO &apos;root&apos;@&apos;%&apos; WITH GRANT OPTION;
FLUSH PRIVILEGES;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;执行后，您再用这个账户远程连接，就能看到所有数据库了。&lt;/h2&gt;
</content:encoded></item><item><title>SSH 免密登录配置问题</title><link>https://fuwari.vercel.app/posts/linux%E5%9F%BA%E7%A1%80/ssh%E5%85%8D%E5%AF%86%E7%99%BB%E5%BD%95%E9%85%8D%E7%BD%AE%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/linux%E5%9F%BA%E7%A1%80/ssh%E5%85%8D%E5%AF%86%E7%99%BB%E5%BD%95%E9%85%8D%E7%BD%AE%E9%97%AE%E9%A2%98/</guid><description>SSH 免密登录配置问题思路步骤</description><pubDate>Tue, 09 Jun 2026 06:13:00 GMT</pubDate><content:encoded>&lt;h1&gt;SSH 免密登录配置问题&lt;/h1&gt;
&lt;h2&gt;问题诊断与解决方案&lt;/h2&gt;
&lt;h3&gt;1. 检查 SSH 目录和文件权限&lt;/h3&gt;
&lt;p&gt;SSH 对文件和目录权限有严格的安全要求。请确保在 192.168.88.20 主机上执行以下检查：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 在 192.168.88.20 上执行这些命令
# 检查 .ssh 目录权限（必须是 700）
ls -ld ~/.ssh

# 检查 authorized_keys 文件权限（必须是 600）
ls -l ~/.ssh/authorized_keys

# 检查用户家目录权限（必须是 755 或更严格）
ls -ld ~
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果权限不正确，请使用以下命令修复：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 修复权限
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 755 ~  # 家目录权限
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 检查 SSH 服务配置&lt;/h3&gt;
&lt;p&gt;在 192.168.88.20 上检查 SSH 服务配置：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 检查 SSH 服务配置
sudo grep -E &quot;PubkeyAuthentication|AuthorizedKeysFile&quot; /etc/ssh/sshd_config

# 确保以下配置正确：
# PubkeyAuthentication yes
# AuthorizedKeysFile .ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果需要修改配置：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 编辑 SSH 配置
sudo vim /etc/ssh/sshd_config

# 重启 SSH 服务
sudo systemctl restart sshd
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 检查 SELinux 状态&lt;/h3&gt;
&lt;p&gt;SELinux 可能会阻止 SSH 密钥认证：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 检查 SELinux 状态
sestatus

# 如果是 enforcing 状态，尝试暂时禁用 SELinux 测试
sudo setenforce 0

# 然后尝试 SSH 连接，如果成功，说明是 SELinux 问题
# 永久解决方案是调整 SELinux 策略或设置为 permissive 模式
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. 详细调试 SSH 连接&lt;/h3&gt;
&lt;p&gt;使用详细模式连接，查看具体错误信息：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 从 MHA 主机连接到 20 主机，使用详细输出
ssh -vvv admin@192.168.88.20
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;关注输出中的以下关键信息：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;是否尝试使用公钥认证&lt;/li&gt;
&lt;li&gt;公钥是否被接受&lt;/li&gt;
&lt;li&gt;认证失败的具体原因&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5. 检查公钥格式和内容&lt;/h3&gt;
&lt;p&gt;确保 &lt;code&gt;authorized_keys&lt;/code&gt; 文件中的公钥格式正确：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 在 192.168.88.20 上检查公钥文件
cat ~/.ssh/authorized_keys

# 确保每行一个完整的公钥，没有多余字符或换行
# 公钥格式应为：ssh-rsa AAAAB3NzaC1yc2EAAA... comment
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6. 重新复制公钥&lt;/h3&gt;
&lt;p&gt;尝试重新将公钥复制到 192.168.88.20：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 从 MHA 主机执行
ssh-copy-id -i ~/.ssh/id_rsa.pub admin@192.168.88.20
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或者手动复制：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 在 MHA 主机上获取公钥内容
cat ~/.ssh/id_rsa.pub

# 然后登录到 192.168.88.20，将公钥内容添加到 ~/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7. 检查用户和组所有权&lt;/h3&gt;
&lt;p&gt;确保文件和目录的所有权正确：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 在 192.168.88.20 上检查
ls -la ~/
ls -la ~/.ssh/
ls -la ~/.ssh/authorized_keys

# 确保所有文件和目录属于 admin 用户和组
# 如果不是，使用以下命令修复：
sudo chown -R admin:admin ~/.ssh
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;8. 检查 SSH 日志&lt;/h3&gt;
&lt;p&gt;查看 SSH 服务的详细日志：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 在 192.168.88.20 上查看 SSH 日志
sudo tail -f /var/log/secure

# 或者使用 journalctl（取决于系统）
sudo journalctl -u sshd -f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;尝试连接时观察日志输出，寻找认证失败的具体原因。&lt;/p&gt;
&lt;h3&gt;总结与建议&lt;/h3&gt;
&lt;p&gt;根据您的描述，问题可能出现在以下几个方面（按可能性排序）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;文件权限问题&lt;/strong&gt;（最常见）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SELinux 限制&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SSH 服务配置问题&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;公钥格式错误&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;建议您按照以下顺序排查：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;首先检查文件和目录权限&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;ssh -vvv&lt;/code&gt; 查看详细连接过程&lt;/li&gt;
&lt;li&gt;检查 SSH 服务日志&lt;/li&gt;
&lt;li&gt;检查 SELinux 状态&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果以上方法都不能解决问题，请尝试完全重新设置 SSH 密钥：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 在 MHA 主机上
rm -rf ~/.ssh
ssh-keygen -t rsa -N &quot;&quot; -f ~/.ssh/id_rsa

# 重新复制到所有主机，包括 192.168.88.20
for host in 10 20 30; do
  ssh-copy-id admin@192.168.88.$host
done
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
</content:encoded></item><item><title>自动小说生成工具-AI_NovelGenerator</title><link>https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/ai_novelgenerator%E8%87%AA%E5%8A%A8%E5%B0%8F%E8%AF%B4%E7%94%9F%E6%88%90%E5%B7%A5%E5%85%B7%E6%9E%84%E5%BB%BA%E7%95%99%E6%A1%A3/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/ai_novelgenerator%E8%87%AA%E5%8A%A8%E5%B0%8F%E8%AF%B4%E7%94%9F%E6%88%90%E5%B7%A5%E5%85%B7%E6%9E%84%E5%BB%BA%E7%95%99%E6%A1%A3/</guid><description>自动小说生成工具“AI_NovelGenerator”构建留档</description><pubDate>Mon, 08 Jun 2026 03:37:00 GMT</pubDate><content:encoded>&lt;h1&gt;自动小说生成工具“AI_NovelGenerator”构建留档&lt;/h1&gt;
&lt;h2&gt;一、AI_NovelGenerator介绍、官网&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;AI_NovelGenerator是啥我不好说直接截图GitHub上的介绍吧
&lt;img src=&quot;/images/%E6%8C%87%E5%8D%97/%E8%87%AA%E5%8A%A8%E5%B0%8F%E8%AF%B4%E7%94%9F%E6%88%90%E5%B7%A5%E5%85%B7-AI_NovelGenerator/97ff1bea764643498d1aa4cf284c5eac.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;GitHub上的链接是：链接&lt;a href=&quot;https://github.com/YILING0013/AI_NovelGenerator&quot;&gt;Github开源链接&lt;/a&gt;
有兴趣的大爪子们可以自己去拉一个试试&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/YILING0013/AI_NovelGenerator
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;二、构建前环境准备&lt;/h2&gt;
&lt;p&gt;确保满足以下运行条件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python 3.9+ 运行环境（推荐3.10-3.12之间）&lt;/li&gt;
&lt;li&gt;pip 包管理工具&lt;/li&gt;
&lt;li&gt;有效API密钥：&lt;/li&gt;
&lt;li&gt;云端服务：OpenAI / DeepSeek 等&lt;/li&gt;
&lt;li&gt;本地服务：Ollama 等兼容 OpenAI 的接口&lt;/li&gt;
&lt;li&gt;Python：我用的是&lt;a href=&quot;https://www.python.org/ftp/python/3.12.1/python-3.12.1.exe&quot;&gt;3.12.1的版本&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;API：我用的是&lt;a href=&quot;https://cloud.siliconflow.cn/i/qFomtKZe&quot;&gt;硅基流动&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;没有硅基流动账号的可以通过我的邀请码(qFomtKZe)在&lt;a href=&quot;https://cloud.siliconflow.cn/i/qFomtKZe&quot;&gt;硅基流动&lt;/a&gt;完成注册获取2000 万 Tokens赠送&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;三、构建过程&lt;/h2&gt;
&lt;p&gt;注：构建安装GitHub上也有详细方法，大爪子们可以先自行摸索试试
1、安装编译工具(感觉win下还是安装这个步骤简单点)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;访问Visual Studio Build Tools下载并安装 C++编译工具，用于构建部分模块包;&lt;/li&gt;
&lt;li&gt;安装时，默认只包含 MSBuild 工具，需手动勾选左上角列表栏中的 C++ 桌面开发 选项。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2、安装依赖并运行&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;打开终端，进入项目源文件目录：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;cd AI_NovelGenerator
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;安装项目依赖：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;pip install -r requirements.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;安装完成后，运行主程序：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;python main.py
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;如果缺失部分依赖，后续手动执行&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;pip install XXX
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、打包为可执行文件&lt;/h2&gt;
&lt;p&gt;1、打包为可执行文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip install pyinstaller
pyinstaller main.spec
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;注意：打包时候会报错说找不到“customtkinter”库
只要你前面运行“python main.py”项目可以跑起来，这个库是没有问题的
报这个错误可以修改“main.spec”文件中第26行&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;customtkinter_dir = r&apos;c:/Users/xieli/Desktop/AI_NovelGenerator/.venv/Lib/site-packages/customtkinter&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个是开源作者的库链接，把这里改成我们的库链接就好&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;customtkinter_dir = r&apos;C:\Users\ta206682\AppData\Local\Programs\Python\Python312\Lib\site-packages&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;这个是我的，大爪子们记得改成自己的呀&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;重新打包&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pyinstaller main.spec
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、美化&lt;/h2&gt;
&lt;p&gt;这个时候跑起来的项目里面很多接口都是英文的，这对于我这种英文白痴就觉得十分的不友好了
我们可以修改下项目中的接口词，达到汉化的效果
打开Git-Bash窗口且进入AI_NovelGenerator项目目录
运行以下代码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;find . -type f -exec sed -i &quot;s/Main Functions/主要功能/g&quot; {} +
find . -type f -exec sed -i &quot;s/Novel Architecture/小说架构/g&quot; {} +
find . -type f -exec sed -i &quot;s/Chapter Blueprint/章节蓝图/g&quot; {} +
find . -type f -exec sed -i &quot;s/Character State/角色状态/g&quot; {} +
find . -type f -exec sed -i &quot;s/Global Summary/全局概述/g&quot; {} +
find . -type f -exec sed -i &quot;s/Chapters Manage/章节管理/g&quot; {} +
find . -type f -exec sed -i &quot;s/LLM Model settings/大语言模型设置/g&quot; {} +
find . -type f -exec sed -i &quot;s/Embedding settings/嵌入设置/g&quot; {} +
find . -type f -exec sed -i &quot;s/LLM API Key:/LLM API 密钥:/g&quot; {} +
find . -type f -exec sed -i &quot;s/LLM Base URL:/LLM 基础 URL:/g&quot; {} +
find . -type f -exec sed -i &quot;s/Model Name:/模型名称:/g&quot; {} +
find . -type f -exec sed -i &quot;s/Temperature:/随机数:/g&quot; {} +
find . -type f -exec sed -i &quot;s/Max Tokens:/最大标记数:/g&quot; {} +
find . -type f -exec sed -i &quot;s/Timeout (sec):/超时（秒）:/g&quot; {} +
find . -type f -exec sed -i &quot;s/Embedding API Key:/嵌入模型 API 密钥:/g&quot; {} +
find . -type f -exec sed -i &quot;s/Embedding 接口格式:/嵌入接口格式:/g&quot; {} +
find . -type f -exec sed -i &quot;s/Embedding Base URL:/嵌入基础 URL:/g&quot; {} +
find . -type f -exec sed -i &quot;s/Embedding Model Name:/嵌入模型名称:/g&quot; {} +
find . -type f -exec sed -i &quot;s/Retrieval Top-K:/检索返回 Top-K 值:/g&quot; {} +
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个代码效果是查询接口名词替换成中文名词
来看看效果吧
&lt;img src=&quot;/images/%E6%8C%87%E5%8D%97/%E8%87%AA%E5%8A%A8%E5%B0%8F%E8%AF%B4%E7%94%9F%E6%88%90%E5%B7%A5%E5%85%B7-AI_NovelGenerator/94c2cd91690e4f12b418eaf78d79baf0.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/%E6%8C%87%E5%8D%97/%E8%87%AA%E5%8A%A8%E5%B0%8F%E8%AF%B4%E7%94%9F%E6%88%90%E5%B7%A5%E5%85%B7-AI_NovelGenerator/31c726bd74704929bbdde0eaab451ae4.webp&quot; alt=&quot;&quot; /&gt;
如果有需要找我要我打包好的那就@我吧&lt;/p&gt;
</content:encoded></item><item><title>MAC 系统 启动盘制作</title><link>https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/mac%E7%B3%BB%E7%BB%9F%E5%90%AF%E5%8A%A8%E7%9B%98%E5%88%B6%E4%BD%9C/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/mac%E7%B3%BB%E7%BB%9F%E5%90%AF%E5%8A%A8%E7%9B%98%E5%88%B6%E4%BD%9C/</guid><description>“MAC 系统 启动盘制作&quot;</description><pubDate>Mon, 08 Jun 2026 02:21:00 GMT</pubDate><content:encoded>&lt;h2&gt;0. 准备工作&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;U盘：&lt;strong&gt;≥16GB&lt;/strong&gt;，备份好数据（会被全盘抹掉）&lt;/li&gt;
&lt;li&gt;Mac：电量充足或插电源&lt;/li&gt;
&lt;li&gt;网络：能下载系统（约12–15GB）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;1. 命令行查询/下载 macOS 镜像（官方安装器）&lt;/h2&gt;
&lt;h3&gt;1.1 查看可下载的系统版本（终端）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;softwareupdate --list-full-installers
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出类似：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;可用的完整安装器：
- macOS Ventura 13.6.1
- macOS Monterey 12.7
...
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1.2 下载指定版本（比如 Ventura）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;softwareupdate --fetch-full-installer --full-installer-version 13.6.1
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;自动下载到 &lt;code&gt;/Applications&lt;/code&gt;，名为 &lt;code&gt;Install macOS Ventura.app&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;下载完成后&lt;strong&gt;不要点安装&lt;/strong&gt;，直接关掉安装窗口&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.3 确认安装器存在&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;ls -la /Applications/Install\ macOS\*.app
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;能看到文件大小 &lt;strong&gt;&amp;gt;12GB&lt;/strong&gt; 即正常。&lt;/p&gt;
&lt;h2&gt;2. 识别并挂载U盘（命令行+磁盘工具）&lt;/h2&gt;
&lt;h3&gt;2.1 插入U盘，查看磁盘列表&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;diskutil list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;找类似：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/dev/disk2 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *15.9 GB    disk2
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;你的U盘是 &lt;code&gt;/dev/diskN&lt;/code&gt;（N 是数字，比如 disk2）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;千万别选错磁盘！&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2.2 卸载U盘（先卸载再格式化）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;diskutil unmountDisk /dev/disk2
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;3. 格式化U盘为 macOS 启动盘格式（磁盘工具/命令行）&lt;/h2&gt;
&lt;h3&gt;3.1 图形化（推荐新手）&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;打开：&lt;strong&gt;应用程序 → 实用工具 → 磁盘工具&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;左侧选中你的U盘（&lt;strong&gt;最外层设备名&lt;/strong&gt;，不是分区）&lt;/li&gt;
&lt;li&gt;点右上角&lt;strong&gt;抹掉&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;名称：&lt;code&gt;MyVolume&lt;/code&gt;（英文，无空格）&lt;/li&gt;
&lt;li&gt;格式：&lt;strong&gt;Mac OS 扩展（日志式）&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;方案：&lt;strong&gt;GUID 分区图&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%8C%87%E5%8D%97/MAC%E7%B3%BB%E7%BB%9F%E5%90%AF%E5%8A%A8%E7%9B%98%E5%88%B6%E4%BD%9C/file-20260512104447802.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;点&lt;strong&gt;抹掉&lt;/strong&gt; → 完成后关闭磁盘工具&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3.2 命令行（更稳）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;diskutil eraseDisk JHFS+ MyVolume GPT /dev/disk2
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;JHFS+&lt;/code&gt; = Mac OS 扩展（日志式）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GPT&lt;/code&gt; = GUID 分区图&lt;/li&gt;
&lt;li&gt;完成后会自动挂载到 &lt;code&gt;/Volumes/MyVolume&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;4. 命令行制作 macOS 启动盘（createinstallmedia）&lt;/h2&gt;
&lt;h3&gt;4.1 核心命令（替换版本与U盘名）&lt;/h3&gt;
&lt;p&gt;以 &lt;strong&gt;Ventura + U盘名 MyVolume&lt;/strong&gt; 为例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo /Applications/Install\ macOS\ Ventura.app/Contents/Resources/createinstallmedia --volume /Volumes/MyVolume
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;输密码时&lt;strong&gt;屏幕不显示&lt;/strong&gt;，直接回车&lt;/li&gt;
&lt;li&gt;提示 &lt;code&gt;Erase disk&lt;/code&gt; 输入 &lt;strong&gt;Y&lt;/strong&gt; 回车&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.2 常见版本命令（直接复制）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# Sonoma
sudo /Applications/Install\ macOS\ Sonoma.app/Contents/Resources/createinstallmedia --volume /Volumes/MyVolume

# Monterey
sudo /Applications/Install\ macOS\ Monterey.app/Contents/Resources/createinstallmedia --volume /Volumes/MyVolume

# Big Sur
sudo /Applications/Install\ macOS\ Big\ Sur.app/Contents/Resources/createinstallmedia --volume /Volumes/MyVolume
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.3 等待制作完成&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;过程约 &lt;strong&gt;15–25 分钟&lt;/strong&gt;，会显示进度&lt;/li&gt;
&lt;li&gt;最终提示：&lt;code&gt;Install media now available at &quot;/Volumes/Install macOS Ventura&quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;制作好的U盘名称会自动变成：&lt;code&gt;Install macOS xxx&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;5. 从U盘启动 Mac（Intel vs Apple Silicon）&lt;/h2&gt;
&lt;h3&gt;5.1 Apple Silicon（M1/M2/M3）&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;插入制作好的U盘&lt;/li&gt;
&lt;li&gt;关机 → 长按&lt;strong&gt;电源键&lt;/strong&gt;不放&lt;/li&gt;
&lt;li&gt;出现&lt;strong&gt;启动选项&lt;/strong&gt;后，选择：&lt;strong&gt;Install macOS xxx&lt;/strong&gt;（黄色U盘图标）&lt;/li&gt;
&lt;li&gt;进入安装界面&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;5.2 Intel Mac&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;插入U盘&lt;/li&gt;
&lt;li&gt;重启 → 立刻按住 &lt;strong&gt;Option (⌥) / Alt 键&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;选择黄色U盘图标：&lt;strong&gt;Install macOS xxx&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;进入安装界面&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;6. U盘安装系统完整步骤&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;进入 &lt;strong&gt;macOS 实用工具&lt;/strong&gt; → 先打开&lt;strong&gt;磁盘工具&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;选中&lt;strong&gt;内置硬盘&lt;/strong&gt;（如 &lt;code&gt;Macintosh HD&lt;/code&gt;）→ 点&lt;strong&gt;抹掉&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;名称：&lt;code&gt;Macintosh HD&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;格式：&lt;strong&gt;APFS&lt;/strong&gt;（新Mac）或 &lt;strong&gt;Mac OS 扩展&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;方案：&lt;strong&gt;GUID 分区图&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;抹掉完成后，回到实用工具 → 选&lt;strong&gt;重新安装 macOS&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;按提示选择目标磁盘（&lt;code&gt;Macintosh HD&lt;/code&gt;）→ 等待安装（约30–60分钟，期间会重启数次）&lt;/li&gt;
&lt;li&gt;安装完成后按指引设置账户、语言等&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;7. 常见坑 &amp;amp; 避坑&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;❶ &lt;strong&gt;U盘名称含中文/空格&lt;/strong&gt;：命令会失败 → 必须用英文短名&lt;/li&gt;
&lt;li&gt;❷ &lt;strong&gt;没卸载直接格式化&lt;/strong&gt;：报资源忙 → 先 &lt;code&gt;diskutil unmountDisk&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;❸ &lt;strong&gt;安装器不完整&lt;/strong&gt;：&amp;lt;12GB 或报错 → 删掉重下&lt;/li&gt;
&lt;li&gt;❹ &lt;strong&gt;M1/M2 不认U盘&lt;/strong&gt;：重启重插，或换 USB-A 接口&lt;/li&gt;
&lt;li&gt;❺ &lt;strong&gt;制作时卡住&lt;/strong&gt;：等待，不要中断；实在不行换U盘重制&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Ubuntu 服务器终端完整汉化流程</title><link>https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/ubuntu-%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%BB%88%E7%AB%AF%E5%AE%8C%E6%95%B4%E6%B1%89%E5%8C%96%E6%B5%81%E7%A8%8B/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/ubuntu-%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%BB%88%E7%AB%AF%E5%AE%8C%E6%95%B4%E6%B1%89%E5%8C%96%E6%B5%81%E7%A8%8B/</guid><description>“Ubuntu 服务器终端完整汉化流程（极简复刻版）&quot;</description><pubDate>Mon, 08 Jun 2026 02:16:00 GMT</pubDate><content:encoded>&lt;h2&gt;一、作用&lt;/h2&gt;
&lt;p&gt;让 &lt;code&gt;free、top、apt&lt;/code&gt; 等命令显示中文，解决英文输出，远程服务器通用&lt;/p&gt;
&lt;h2&gt;二、一键执行步骤&lt;/h2&gt;
&lt;h3&gt;1. 备份原有语言配置&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo cp /etc/default/locale /etc/default/locale.bak
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 更新软件源&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo apt update
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 安装中文语言包+中文字体（防乱码）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo apt install language-pack-zh-hans fonts-wqy-microhei -y
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. 生成简体中文编码&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo locale-gen zh_CN.UTF-8
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5. 写入全局中文语言配置&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo update-locale LANG=zh_CN.UTF-8 LC_ALL=zh_CN.UTF-8 LANGUAGE=zh_CN:zh
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6. 写入配置文件永久生效&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;echo &apos;LANG=zh_CN.UTF-8&apos; | sudo tee /etc/default/locale
echo &apos;LANGUAGE=zh_CN:zh&apos; | sudo tee -a /etc/default/locale
echo &apos;LC_ALL=zh_CN.UTF-8&apos; | sudo tee -a /etc/default/locale
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7. 临时当前终端生效&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;export LANG=zh_CN.UTF-8
export LANGUAGE=zh_CN:zh
export LC_ALL=zh_CN.UTF-8
source ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;8. 重启服务器彻底生效（必做）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;三、验证是否成功&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;locale
free -h
top
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、已知限制（记住）&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;top&lt;/code&gt; 仅&lt;strong&gt;任务、内存、交换&lt;/strong&gt;汉化，其余字段原生无中文，无法全汉化&lt;/li&gt;
&lt;li&gt;程序自身日志（如&lt;code&gt;ollama、nginx&lt;/code&gt;）输出依旧英文，不属于系统汉化范围&lt;/li&gt;
&lt;li&gt;Xshell/宝塔终端：客户端编码改为 &lt;strong&gt;UTF-8&lt;/strong&gt; 避免方框乱码&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;五、恢复英文（回滚教程）&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo cp /etc/default/locale.bak /etc/default/locale
sudo update-locale LANG=en_US.UTF-8
sudo reboot
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Linux find 批量替换字符脚本</title><link>https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/linux-find-%E6%89%B9%E9%87%8F%E6%9B%BF%E6%8D%A2%E5%AD%97%E7%AC%A6%E8%84%9A%E6%9C%AC/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/linux-find-%E6%89%B9%E9%87%8F%E6%9B%BF%E6%8D%A2%E5%AD%97%E7%AC%A6%E8%84%9A%E6%9C%AC/</guid><description>“Linux 下使用 find 命令批量替换字符脚本&quot;</description><pubDate>Mon, 08 Jun 2026 02:02:00 GMT</pubDate><content:encoded>&lt;h1&gt;批量替换脚本（Ubuntu 直接执行，在 ~/Astro 目录运行）&lt;/h1&gt;
&lt;h2&gt;1. 先预览替换（不修改文件，先看结果）&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;cd /home/ubuntu/Astro/src/content/posts
find . -name &quot;*.md&quot; -exec grep &apos;tags: \[&quot;数据库与监控&quot;&apos; {} \;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2. 正式批量替换&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;find . -type f -name &quot;*.md&quot; -exec sed -i &apos;s/tags: \[&quot;数据库与监控&quot;, &quot;运维&quot;, &quot;数据库&quot;\]/tags: \[&quot;zabbix监控&quot;, &quot;运维&quot;, &quot;数据库&quot;\]/g&apos; {} \;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;说明：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;- `find . -type f -name &quot;*.md&quot;`：遍历所有子目录全部md文章
- `sed -i`：原地修改文件
- 精准整串匹配：`[&quot;数据库与监控&quot;, &quot;运维&quot;, &quot;数据库&quot;]` → `[&quot;zabbix监控&quot;, &quot;运维&quot;, &quot;数据库&quot;]`
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;3. 修改完校验&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 查看修改后
find . -name &quot;*.md&quot; -exec grep &apos;tags: \[&quot;zabbix监控&quot;&apos; {} \;
# 确认旧标签不存在
find . -name &quot;*.md&quot; -exec grep &apos;tags: \[&quot;数据库与监控&quot;&apos; {} \;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;4. 重新打包部署&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;cd /home/ubuntu/Astro
npm run build
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;拓展：如果是模糊替换（只要出现「数据库与监控」就改成zabbix监控，不管数组顺序）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;find . -type f -name &quot;*.md&quot; -exec sed -i &apos;s/数据库与监控/zabbix监控/g&apos; {} \;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>草稿示例</title><link>https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/draft/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/draft/</guid><description>文件简洁说明</description><pubDate>Thu, 04 Jun 2026 04:39:00 GMT</pubDate><content:encoded>&lt;h1&gt;本文是草稿&lt;/h1&gt;
&lt;p&gt;本文目前处于草稿状态，尚未发布。因此，它对普通访客不可见。内容仍在撰写中，可能需要进一步编辑和完善。&lt;/p&gt;
&lt;p&gt;当文章准备发布时，可以将 Frontmatter 中的 &quot;draft&quot; 字段改为 &quot;false&quot;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: &quot;文件标题&quot;                       # 文章标题（显示在页面最上方、浏览器标签）
published: 2026-06-04T12:39:00+08:00    # 发布时间（决定文章排序，最新排最前）
description: &quot;文件简洁说明&quot;             # 文章简介（SEO、分享卡片显示的描述）
tags: [&quot;子标签1&quot;, &quot;子标签2&quot;]            # 标签（可以多个，用于归类、搜索）
category: &quot;分类标签&quot;                    # 分类（只能一个，大类别）
draft: false                            # 是否草稿（true=不发布，false=正常显示）
lang: &quot;zh_CN&quot;                           # 语言（中文固定写这个）
---
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;图片使用指南&lt;/h2&gt;
&lt;h3&gt;图片存放位置&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;绝对路径：&lt;/strong&gt; &lt;code&gt;/home/ubuntu/Astro/public/images/&lt;/code&gt;
&lt;strong&gt;相对项目路径：&lt;/strong&gt; &lt;code&gt;public/images/&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;图片必须放在 &lt;code&gt;public/images/&lt;/code&gt; 下（不在 &lt;code&gt;src/content/posts/&lt;/code&gt; 下！），否则构建后无法访问。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;每篇文章一个独立文件夹&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;public/images/指南/
├── MAC系统启动盘制作/
│   ├── file-xxx-1.png
│   └── file-xxx-2.png
└── Ubuntu服务器终端完整汉化流程/
    └── file-xxx.png
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Markdown 中引用图片&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;引用方式：&lt;/strong&gt; 以 &lt;code&gt;/&lt;/code&gt; 开头代表 public 根目录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![](/images/指南/MAC系统启动盘制作/file-20260512104447802.webp)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;插入图片流程模板&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;## 步骤说明文字

第一步操作截图：

![](/images/指南/文章标题/文件1.webp)

第二步操作截图：

![](/images/指南/文章标题/文件2.webp)
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ 注意：中文路径在 URL 中会编码为 &lt;code&gt;%E6%8C%87%E5%8D%97&lt;/code&gt; 等形式，但 Markdown 里直接写中文即可，Astro 构建时会自动处理编码。&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>inkos命令参考</title><link>https://fuwari.vercel.app/posts/%E8%87%AA%E5%AA%92%E4%BD%93%E4%B8%8E%E5%B7%A5%E5%85%B7/inkos%E5%91%BD%E4%BB%A4/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E8%87%AA%E5%AA%92%E4%BD%93%E4%B8%8E%E5%B7%A5%E5%85%B7/inkos%E5%91%BD%E4%BB%A4/</guid><description>命令参考 - 运维知识库笔记</description><pubDate>Thu, 04 Jun 2026 04:35:00 GMT</pubDate><content:encoded>&lt;h2&gt;命令参考&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;inkos init [name]&lt;/td&gt;
&lt;td&gt;初始化项目（省略 name 在当前目录初始化）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos book create&lt;/td&gt;
&lt;td&gt;创建新书（&lt;code&gt;--genre&lt;/code&gt;、&lt;code&gt;--platform&lt;/code&gt;、&lt;code&gt;--chapter-words&lt;/code&gt;、&lt;code&gt;--target-chapters&lt;/code&gt;、&lt;code&gt;--brief &amp;lt;file&amp;gt;&lt;/code&gt; 传入创作简报）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos book update [id]&lt;/td&gt;
&lt;td&gt;修改书设置（&lt;code&gt;--chapter-words&lt;/code&gt;、&lt;code&gt;--target-chapters&lt;/code&gt;、&lt;code&gt;--status&lt;/code&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos book list&lt;/td&gt;
&lt;td&gt;列出所有书籍&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos book delete &amp;lt;id&amp;gt;&lt;/td&gt;
&lt;td&gt;删除书籍及全部数据（&lt;code&gt;--force&lt;/code&gt; 跳过确认）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos genre list/show/copy/create&lt;/td&gt;
&lt;td&gt;查看、复制、创建题材&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos plan chapter [id]&lt;/td&gt;
&lt;td&gt;生成下一章的 &lt;code&gt;intent.md&lt;/code&gt;（&lt;code&gt;--context&lt;/code&gt; / &lt;code&gt;--context-file&lt;/code&gt; 传入当前指令）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos compose chapter [id]&lt;/td&gt;
&lt;td&gt;生成下一章的 &lt;code&gt;context.json&lt;/code&gt;、&lt;code&gt;rule-stack.yaml&lt;/code&gt;、&lt;code&gt;trace.json&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos write next [id]&lt;/td&gt;
&lt;td&gt;完整管线写下一章（&lt;code&gt;--words&lt;/code&gt; 覆盖字数，&lt;code&gt;--count&lt;/code&gt; 连写，&lt;code&gt;-q&lt;/code&gt; 静默模式）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos write rewrite [id] &amp;lt;n&amp;gt;&lt;/td&gt;
&lt;td&gt;重写第 N 章（恢复状态快照，&lt;code&gt;--force&lt;/code&gt; 跳过确认，&lt;code&gt;--words&lt;/code&gt; 覆盖字数）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos draft [id]&lt;/td&gt;
&lt;td&gt;只写草稿（&lt;code&gt;--words&lt;/code&gt; 覆盖字数，&lt;code&gt;-q&lt;/code&gt; 静默模式）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos audit [id] [n]&lt;/td&gt;
&lt;td&gt;审计指定章节&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos revise [id] [n]&lt;/td&gt;
&lt;td&gt;修订指定章节&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos agent &amp;lt;instruction&amp;gt;&lt;/td&gt;
&lt;td&gt;自然语言 Agent 模式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos review list [id]&lt;/td&gt;
&lt;td&gt;审阅草稿&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos review approve-all [id]&lt;/td&gt;
&lt;td&gt;批量通过&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos status [id]&lt;/td&gt;
&lt;td&gt;项目状态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos export [id]&lt;/td&gt;
&lt;td&gt;导出书籍（&lt;code&gt;--format txt/md/epub&lt;/code&gt;、&lt;code&gt;--output &amp;lt;path&amp;gt;&lt;/code&gt;、&lt;code&gt;--approved-only&lt;/code&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos radar scan&lt;/td&gt;
&lt;td&gt;扫描平台趋势&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos fanfic init&lt;/td&gt;
&lt;td&gt;从原作素材创建同人书（&lt;code&gt;--from&lt;/code&gt;、&lt;code&gt;--mode canon/au/ooc/cp&lt;/code&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos config set-global&lt;/td&gt;
&lt;td&gt;设置 CLI / daemon / 部署环境的全局 LLM env（&lt;code&gt;~/.inkos/.env&lt;/code&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos config show-global&lt;/td&gt;
&lt;td&gt;查看全局配置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos config set/show&lt;/td&gt;
&lt;td&gt;查看/更新项目配置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos config set-model &amp;lt;agent&amp;gt; &amp;lt;model&amp;gt;&lt;/td&gt;
&lt;td&gt;为指定 agent 设置模型覆盖（&lt;code&gt;--base-url&lt;/code&gt;、&lt;code&gt;--provider&lt;/code&gt;、&lt;code&gt;--api-key-env&lt;/code&gt; 支持多 Provider 路由）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos config remove-model &amp;lt;agent&amp;gt;&lt;/td&gt;
&lt;td&gt;移除 agent 模型覆盖（回退到默认）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos config show-models&lt;/td&gt;
&lt;td&gt;查看当前模型路由&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos doctor&lt;/td&gt;
&lt;td&gt;诊断配置问题（显示 effective config mode、来源、API 连通性和提供商兼容性提示）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos detect [id] [n]&lt;/td&gt;
&lt;td&gt;AIGC 检测（&lt;code&gt;--all&lt;/code&gt; 全部章节，&lt;code&gt;--stats&lt;/code&gt; 统计）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos style analyze &amp;lt;file&amp;gt;&lt;/td&gt;
&lt;td&gt;分析参考文本提取文风指纹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos style import &amp;lt;file&amp;gt; [id]&lt;/td&gt;
&lt;td&gt;导入文风指纹到指定书&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos import canon [id] --from &amp;lt;parent&amp;gt;&lt;/td&gt;
&lt;td&gt;导入正传正典到番外书&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos import chapters [id] --from &amp;lt;path&amp;gt;&lt;/td&gt;
&lt;td&gt;导入已有章节续写（&lt;code&gt;--split&lt;/code&gt;、&lt;code&gt;--resume-from&lt;/code&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;inkos analytics [id]&lt;/code&gt;/&lt;code&gt;inkos stats [id]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;书籍数据分析（审计通过率、高频问题、章节排名、token 用量）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos update&lt;/td&gt;
&lt;td&gt;更新到最新版本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;inkos studio&lt;/code&gt;/&lt;code&gt;inkos&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;启动 Web 工作台（&lt;code&gt;-p&lt;/code&gt; 指定端口，默认 4567；Studio 使用服务页配置，不使用 env 覆盖）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inkos up / down&lt;/td&gt;
&lt;td&gt;启动/停止守护进程（&lt;code&gt;-q&lt;/code&gt; 静默模式，自动写入 &lt;code&gt;inkos.log&lt;/code&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;[id]&lt;/code&gt; 参数在项目只有一本书时可省略，自动检测。所有命令支持 &lt;code&gt;--json&lt;/code&gt; 输出结构化数据。&lt;code&gt;draft&lt;/code&gt; / &lt;code&gt;write next&lt;/code&gt; / &lt;code&gt;plan chapter&lt;/code&gt; / &lt;code&gt;compose chapter&lt;/code&gt; 支持 &lt;code&gt;--context&lt;/code&gt; 传入创作指导，&lt;code&gt;--words&lt;/code&gt; 覆盖每章目标字数。&lt;code&gt;book create&lt;/code&gt; 支持 &lt;code&gt;--brief &amp;lt;file&amp;gt;&lt;/code&gt; 传入创作简报（你的脑洞/设定文档），Architect 会基于此生成设定而非凭空创作。&lt;code&gt;plan chapter&lt;/code&gt; / &lt;code&gt;compose chapter&lt;/code&gt; 不要求在线 LLM，可在配置 API Key 之前先检查输入治理结果。&lt;/p&gt;
&lt;p&gt;CLI 运行时还支持一次性 LLM 覆盖参数：&lt;code&gt;--service&lt;/code&gt;、&lt;code&gt;--model&lt;/code&gt;、&lt;code&gt;--api-key-env&lt;/code&gt;、&lt;code&gt;--base-url&lt;/code&gt;、&lt;code&gt;--api-format &amp;lt;chat|responses&amp;gt;&lt;/code&gt;、&lt;code&gt;--stream&lt;/code&gt;、&lt;code&gt;--no-stream&lt;/code&gt;。例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;inkos write next --service google --model gemini-2.5-flash
inkos up --service moonshot --model kimi-k2.5 --api-key-env MOONSHOT_API_KEY
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;命令示例：&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;inkos book create --title &quot;吞天魔帝&quot; --genre xuanhuan  # 创建新书
inkos write next 吞天魔帝      # 写下一章（完整管线：草稿 → 审计 → 修订）
inkos status                   # 查看状态
inkos review list 吞天魔帝     # 审阅草稿
inkos review approve-all 吞天魔帝  # 批量通过
inkos export 吞天魔帝          # 导出全书
inkos export 吞天魔帝 --format epub  # 导出 EPUB（手机/Kindle 阅读）

inkos plan chapter 吞天魔帝 --context &quot;本章先把注意力拉回师徒矛盾&quot;
inkos compose chapter 吞天魔帝

inkos write next 吞天魔帝          # 写草稿 → 审计 → 自动修订，一步到位
inkos write next 吞天魔帝 --count 5 # 连续写 5 章

# 自然语言 Agent 模式
inkos agent &quot;帮我写一本都市修仙，主角是个程序员&quot;
inkos agent &quot;写下一章，重点写师徒矛盾&quot;
inkos agent &quot;先扫描市场趋势，然后根据结果创建一本新书&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;配置排查&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;inkos doctor
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;配置模型&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;inkos config set-global \
  --provider &amp;lt;openai|anthropic|custom&amp;gt; \
  --base-url &amp;lt;API 地址&amp;gt; \
  --api-key &amp;lt;你的 API Key&amp;gt; \
  --model &amp;lt;模型名&amp;gt;
# 智谱 API
inkos config set-global --provider custom --base-url https://open.bigmodel.cn/api/paas/v4 --api-key xxxxxxxxxxxx.xxxxxxxxxxxxxxx --model glm-4.7

# ollama
inkos config set-global --provider custom --base-url http://localhost:11434/v1 --api-key dummy --model qwen2.5:3b-instruct-q4_K_M

# 火山引擎
inkos config set-global --provider custom --base-url https://ark.cn-beijing.volces.com/api/v3 --api-key xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx --model doubao-seed-2-0-lite

# freemodel
inkos config set-global --provider custom --base-url https://api.freemodel.dev/v1 --api-key fe_oa_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx --model gpt-5.5



&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;一次性指定服务或模型：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;inkos write next --service google --model gemini-2.5-flash
inkos write next --service moonshot --model kimi-k2.5 --no-stream
inkos agent &quot;继续写下一章&quot; --api-key-env MOONSHOT_API_KEY
inkos doctor --service minimaxCodingPlan --model MiniMax-M2.7
# `--service` 会从 provider bank 自动推导 baseUrl、协议和兼容策略；`--model` 必须属于最终 service，否则会直接报错，避免把 Kimi 模型发到 Gemini 这类错配问题。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;strong&gt;编写创作简报&lt;/strong&gt;建新书&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;1、InkOS 的建筑师Agent会基于创作简报生成小说的世界观设定（story_bible.md）和创作规则（book_rules.md），精准贴合你的剧情，需先新建一个 markdown 文件（比如feijian-brief.md），将以下内容复制进去（完全还原你的设定，可直接用）：
**创作简报文件：****feijian-brief.md**
markdown
# 小说核心设定
1. 主角：。
2. 穿越前剧情
3. 穿越触发：。
4. 重生地点：
5. 金手指：
6. 核心剧情线：
7. 题材风格：。
8. 章节字数：单章约15000字（可后续调整），目标先写50章。
**保存路径**：建议保存在桌面 / 常用文件夹，方便后续调用（比如桌面路径：/Users/xxx/Desktop/feijian-brief.md（Mac）/C:\Users\xxx\Desktop\feijian-brief.md（Windows））。

2、**创建专属小说（基于你的简报，一键初始化）**
执行inkos book create命令，**指定标题、题材、创作简报路径**，InkOS 会自动生成小说项目、世界观设定和创作规则，命令如下：
bash
inkos book create \
 --title &quot;外卖员：闯古武&quot; \
 --genre guwu \
 --brief &amp;lt;你的feijian-brief.md文件绝对路径&amp;gt; \
 --chapter-words 15000 \
 --target-chapters 50

**命令参数说明（贴合你的需求）**
	- --title：小说标题，；
	- --genre guwu：题材指定为古武（无需自定义）；
	- --brief：必填，替换为你刚才保存的feijian-brief.md的绝对路径（复制文件路径即可）；
	- --chapter-words 15000：单章目标字数，贴合你的创作节奏，可后续修改；
	- --target-chapters 50：初始目标章节数，可后续通过inkos book update调整。



&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;连续写多章&lt;/h3&gt;
&lt;p&gt;比如一次性写 3 章，加--count 3；&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;inkos write next 外卖员：闯古武 --count 3
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;自定义单章字数&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;inkos write next 外卖员：闯古武 --words 10000
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;strong&gt;查看小说创作状态&lt;/strong&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;inkos status 外卖员：闯古武
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;strong&gt;审阅草稿 / 批量通过修订&lt;/strong&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 查看所有未审核的草稿  
inkos review list 外卖员：闯古武  
# 批量通过所有修订，确认正文  
inkos review approve-all 外卖员：闯古武
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;strong&gt;导出小说&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;（支持 TXT/MD/EPUB，EPUB 可在手机 / Kindle 阅读）&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 导出为MD格式（默认，保存在小说项目文件夹）  
inkos export 外卖员：闯古武  
# 导出为EPUB格式，指定保存到桌面  
inkos export外卖员：闯古武 --format epub --output /Users/xxx/Desktop/
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;strong&gt;重写某一章&lt;/strong&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;**（若对内容不满意，恢复快照重写）**

比如重写第一章：
inkos write rewrite 外卖员：闯古武 1
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;strong&gt;自然语言微调剧情&lt;/strong&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;如果想让后续章节加入特定剧情（比如飞剑首次用编程思维卡 bug 破解山村武学），可执行：
inkos agent &quot;外卖员：闯古武的下一章，写。。。。。。。。。&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;strong&gt;后台自动创作&lt;/strong&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;如果想让 InkOS**后台自动写章**，遇到关键问题再暂停等人工审核，可启动守护进程，支持 Telegram / 飞书 / 企业微信通知：
# 启动后台守护进程，自动写章  
inkos up  
# 停止守护进程  
inkos down
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;strong&gt;关键优化&lt;/strong&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;让 “程序员卡 bug” 的设定更贴合

InkOS 支持文风仿写和自定义创作规则，如果想让小说更有「程序员风格」，可补充操作：

找一段贴合的程序员穿越文，保存为style-ref.md；
分析文风指纹：inkos style analyze style-ref.md；
导入到你的小说：inkos style import style-ref.md 外卖员：闯古武。
后续所有章节会自动贴合该文风，强化编程思维与古武的结合。


————————————————
版权声明：本文为CSDN博主「feibaoqq」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。
原文链接：https://blog.csdn.net/u013358093/article/details/160447656
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;安装&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;npm i -g @actalk/inkos
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;通过 OpenClaw 使用 🦞&lt;/h3&gt;
&lt;p&gt;InkOS 已发布为 &lt;a href=&quot;https://clawhub.ai/narcooo/inkos&quot;&gt;OpenClaw&lt;/a&gt; Skill，可被任何兼容 Agent（Claude Code、OpenClaw 等）直接调用：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;clawhub install inkos          # 从 ClawHub 安装 InkOS Skill
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过 npm 安装或克隆本项目时，&lt;code&gt;skills/SKILL.md&lt;/code&gt; 已包含在内，🦞 可直接读取——无需额外从 ClawHub 安装。
安装后，Claw 应优先通过共享交互入口调用 InkOS：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;inkos interact --json --message &quot;继续当前书，但把节奏再收紧一点&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这条入口直接走和项目 TUI 相同的交互执行内核，因此 OpenClaw、TUI、Studio 共用同一套控制脑。返回的 JSON 包含：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;解析后的 request
assistant 文本回复
更新后的 interaction session
执行状态
待处理决策
近期事件&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;plan chapter&lt;/code&gt; / &lt;code&gt;compose chapter&lt;/code&gt; / &lt;code&gt;draft&lt;/code&gt; / &lt;code&gt;audit&lt;/code&gt; / &lt;code&gt;revise&lt;/code&gt; / &lt;code&gt;write next&lt;/code&gt; 这些原子命令仍然保留，但更适合作为底层工具，而不是 OpenClaw 的首选入口。也可以在 &lt;a href=&quot;https://clawhub.ai/&quot;&gt;ClawHub&lt;/a&gt; 搜索 &lt;code&gt;inkos&lt;/code&gt; 在线查看。&lt;/p&gt;
&lt;h3&gt;配置&lt;/h3&gt;
&lt;p&gt;InkOS 2.0 将 LLM 配置分成两条清晰路径：&lt;strong&gt;Studio 用可视化服务配置&lt;/strong&gt;，&lt;strong&gt;CLI / daemon / 部署环境支持 env 覆盖&lt;/strong&gt;。两者不会互相污染。&lt;/p&gt;
&lt;h4&gt;方式一：Studio 服务配置（推荐）&lt;/h4&gt;
&lt;p&gt;适合本地写作、Web 工作台和可视化管理。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;inkos init my-novel
cd my-novel
inkos
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;打开 Studio 后进入「模型配置」：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;选择服务商，例如 Google Gemini、Moonshot、MiniMax、智谱、百炼或自定义端点。&lt;/li&gt;
&lt;li&gt;粘贴 API Key，点击「测试连接」。&lt;/li&gt;
&lt;li&gt;选择可用模型，保存配置。&lt;/li&gt;
&lt;li&gt;回到书籍页面开始写作。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Studio 运行时只使用：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;provider bank 默认值
→ inkos.json 里的 services / 当前 service / defaultModel
→ .inkos/secrets.json 里的 service API Key
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;即使检测到 &lt;code&gt;~/.inkos/.env&lt;/code&gt; 或项目 &lt;code&gt;.env&lt;/code&gt;，Studio 也只会展示提示，不会用 env 覆盖 service、model、baseUrl 或 API Key。API Key 存在项目内的 &lt;code&gt;.inkos/secrets.json&lt;/code&gt;，不会写进 &lt;code&gt;inkos.json&lt;/code&gt;。&lt;/p&gt;
&lt;h4&gt;方式二：CLI / daemon / 部署环境的 env 配置&lt;/h4&gt;
&lt;p&gt;适合终端批处理、服务器部署、CI、Docker、守护进程和一次性切模型。&lt;/p&gt;
&lt;p&gt;全局 env：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;inkos config set-global \
  --provider &amp;lt;openai|anthropic|custom&amp;gt; \
  --base-url &amp;lt;API 地址&amp;gt; \
  --api-key &amp;lt;你的 API Key&amp;gt; \
  --model &amp;lt;模型名&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;也可以手动写 &lt;code&gt;~/.inkos/.env&lt;/code&gt; 或项目 &lt;code&gt;.env&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;INKOS_LLM_PROVIDER=custom
INKOS_LLM_BASE_URL=https://api.moonshot.cn/v1
INKOS_LLM_API_KEY=sk-...
INKOS_LLM_MODEL=kimi-k2.5

# 可选
INKOS_LLM_SERVICE=moonshot                         # 推荐写；不写时会尽量从 baseUrl 自动识别
INKOS_LLM_TEMPERATURE=0.7
INKOS_LLM_THINKING_BUDGET=0
INKOS_DEFAULT_LANGUAGE=zh
INKOS_LLM_EXTRA_top_p=0.9
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CLI 合成顺序：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Studio/project service 配置
→ .inkos/secrets.json service key
→ global ~/.inkos/.env
→ project .env
→ 当前进程环境变量
→ CLI 参数
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;也就是说，CLI 默认可以复用 Studio 配好的服务和密钥；如果 env 里声明了 &lt;code&gt;INKOS_LLM_SERVICE&lt;/code&gt;、&lt;code&gt;INKOS_LLM_MODEL&lt;/code&gt;、&lt;code&gt;INKOS_LLM_BASE_URL&lt;/code&gt; 或 &lt;code&gt;INKOS_LLM_API_KEY&lt;/code&gt;，则作为覆盖层生效。旧 env 只写 &lt;code&gt;baseUrl + model + apiKey&lt;/code&gt; 也能继续用，InkOS 会尽量从 baseUrl 反推 service。&lt;/p&gt;
&lt;p&gt;一次性指定服务或模型：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;inkos write next --service google --model gemini-2.5-flash
inkos write next --service moonshot --model kimi-k2.5 --no-stream
inkos agent &quot;继续写下一章&quot; --api-key-env MOONSHOT_API_KEY
inkos doctor --service minimaxCodingPlan --model MiniMax-M2.7
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;--service&lt;/code&gt; 会从 provider bank 自动推导 baseUrl、协议和兼容策略；&lt;code&gt;--model&lt;/code&gt; 必须属于最终 service，否则会直接报错，避免把 Kimi 模型发到 Gemini 这类错配问题。&lt;/p&gt;
&lt;h4&gt;方式三：多模型路由（可选）&lt;/h4&gt;
&lt;p&gt;给不同 Agent 分配不同模型，按需平衡质量与成本：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 给不同 agent 配不同模型/提供商
inkos config set-model writer &amp;lt;model&amp;gt; --provider &amp;lt;provider&amp;gt; --base-url &amp;lt;url&amp;gt; --api-key-env &amp;lt;ENV_VAR&amp;gt;
inkos config set-model auditor &amp;lt;model&amp;gt; --provider &amp;lt;provider&amp;gt;
inkos config show-models        # 查看当前路由
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;未单独配置的 Agent 自动使用全局模型。&lt;/p&gt;
&lt;h4&gt;配置排查&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;inkos doctor
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;doctor&lt;/code&gt; 会显示当前 effective config mode、service/model/API Key 来源，并尝试 API 连通性。常见模式：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模式&lt;/th&gt;
&lt;th&gt;含义&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;studio-project&lt;/td&gt;
&lt;td&gt;Studio 运行时：只使用 Studio/project 配置和 secrets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cli-project&lt;/td&gt;
&lt;td&gt;CLI 运行时：以 Studio 配置为基础，再叠加 env 和 CLI 参数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;legacy-env&lt;/td&gt;
&lt;td&gt;旧 env 模式：兼容老项目的纯 .env 配置&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;如果服务测试失败，优先检查服务商、模型和协议是否匹配。Google Gemini 的 AI Studio API Key 可用于 Gemini OpenAI-compatible endpoint；InkOS 会自动禁用 Google 不支持的 OpenAI &lt;code&gt;store&lt;/code&gt; 参数。MiniMax / MiniMax CodingPlan 会优先使用可工作的非流式 transport，避免流式返回 usage 但无正文的问题。&lt;/p&gt;
&lt;h3&gt;v2.0 LLM 配置更新&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Studio / CLI 配置隔离&lt;/strong&gt;：Studio 固定使用服务页配置和 &lt;code&gt;.inkos/secrets.json&lt;/code&gt;；CLI、daemon、部署环境支持 env 覆盖和一次性命令参数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Provider bank 能力表&lt;/strong&gt;：内置 Google Gemini、Moonshot、MiniMax、智谱、百炼、DeepSeek、硅基流动、PPIO、OpenRouter、Ollama、CodingPlan 等服务的 baseUrl、协议、模型和兼容策略。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;模型归属校验&lt;/strong&gt;：&lt;code&gt;--service google --model kimi-k2.5&lt;/code&gt; 这类错配会直接报错，避免把请求发到错误服务商。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Google Gemini 兼容修复&lt;/strong&gt;：AI Studio API Key 可直接用于 Gemini OpenAI-compatible endpoint，InkOS 会自动禁用 Google 不支持的 OpenAI &lt;code&gt;store&lt;/code&gt; 参数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MiniMax transport 探测&lt;/strong&gt;：MiniMax / MiniMax CodingPlan 自动使用可工作的 transport，规避流式 usage 正常但正文为空的问题。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;旧 env 兼容&lt;/strong&gt;：老的 &lt;code&gt;INKOS_LLM_BASE_URL + INKOS_LLM_MODEL + INKOS_LLM_API_KEY&lt;/code&gt; 仍可用于 CLI；没有 &lt;code&gt;INKOS_LLM_SERVICE&lt;/code&gt; 时会尝试从 baseUrl 反推服务商。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;v1.2 更新&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;统一交互内核 + TUI 仪表盘 + Studio 助手&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;共享交互运行时&lt;/strong&gt;：TUI、Studio、&lt;code&gt;inkos interact&lt;/code&gt;、OpenClaw Skill 共用同一套自然语言理解 + 执行内核，支持 15+ 种意图（写作、修订、重写、改名、导出、切换书籍等）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ink TUI 仪表盘&lt;/strong&gt;：&lt;code&gt;inkos&lt;/code&gt; 直接进入全屏交互式仪表盘（Ink + React），对话式创作体验，slash 命令自动补全，主题动效，i18n 双语&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Studio 助手面板&lt;/strong&gt;：右侧 AI 助手面板接入共享交互内核，支持自然语言操作书籍——改名、写章、审计、导出等，实时显示执行状态&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;对话式建书&lt;/strong&gt;：通过自然语言对话逐步构思书籍设定，草稿就绪后一键创建&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;全书实体改名&lt;/strong&gt;：&lt;code&gt;把林烬改成张三&lt;/code&gt; 或 &lt;code&gt;/rename 林烬 =&amp;gt; 张三&lt;/code&gt;，全量扫描章节 + 真相文件，一次替换&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;inkos interact&lt;/code&gt;&lt;/strong&gt;：共享交互 JSON 入口，OpenClaw / 外部 Agent 可直接调用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Thinking 模型温度夹制&lt;/strong&gt;：kimi-k2.5 等 thinking 模型自动强制 temperature=1，兼容 per-call 温度调参&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;写第一本书&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;inkos book create --title &quot;吞天魔帝&quot; --genre xuanhuan  # 创建新书
inkos write next 吞天魔帝      # 写下一章（完整管线：草稿 → 审计 → 修订）
inkos status                   # 查看状态
inkos review list 吞天魔帝     # 审阅草稿
inkos review approve-all 吞天魔帝  # 批量通过
inkos export 吞天魔帝          # 导出全书
inkos export 吞天魔帝 --format epub  # 导出 EPUB（手机/Kindle 阅读）
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;核心特性&lt;/h2&gt;
&lt;h3&gt;多维度审计 + 去 AI 味&lt;/h3&gt;
&lt;p&gt;连续性审计员从 33 个维度检查每一章草稿：角色记忆、物资连续性、伏笔回收、大纲偏离、叙事节奏、情感弧线等。内置 AI 痕迹检测维度，自动识别&quot;LLM 味&quot;表达（高频词、句式单调、过度总结），审计不通过自动进入修订循环。&lt;/p&gt;
&lt;p&gt;去 AI 味规则内置于写手 agent 的 prompt 层——词汇疲劳词表、禁用句式、文风指纹注入，从源头减少 AI 生成痕迹。&lt;code&gt;revise --mode anti-detect&lt;/code&gt; 可对已有章节做专门的反检测改写。&lt;/p&gt;
&lt;h3&gt;文风仿写&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;inkos style analyze&lt;/code&gt; 分析参考文本，提取统计指纹（句长分布、词频特征、节奏模式）和 LLM 风格指南。
&lt;code&gt;inkos style import&lt;/code&gt; 将指纹注入指定书籍，后续所有章节自动采用该风格，修订者也会用风格标准做审计。&lt;/p&gt;
&lt;h3&gt;创作简报&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;inkos book create --brief my-ideas.md&lt;/code&gt; 传入你的脑洞、世界观设定、人设文档。建筑师 agent 会基于简报生成故事设定（&lt;code&gt;story_bible.md&lt;/code&gt;）和创作规则（&lt;code&gt;book_rules.md&lt;/code&gt;），而非凭空创作；同时把简报落盘到 &lt;code&gt;story/author_intent.md&lt;/code&gt;，让这本书的长期创作意图不会只在建书时生效一次。&lt;/p&gt;
&lt;h3&gt;输入治理控制面&lt;/h3&gt;
&lt;p&gt;每本书现在都有两份长期可编辑的 Markdown 控制文档：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;story/author_intent.md&lt;/code&gt;：这本书长期想成为什么&lt;/li&gt;
&lt;li&gt;&lt;code&gt;story/current_focus.md&lt;/code&gt;：最近 1-3 章要把注意力拉回哪里&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;写作前可以先跑：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;inkos plan chapter 吞天魔帝 --context &quot;本章先把注意力拉回师徒矛盾&quot;
inkos compose chapter 吞天魔帝
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这会生成 &lt;code&gt;story/runtime/chapter-XXXX.intent.md&lt;/code&gt;、&lt;code&gt;context.json&lt;/code&gt;、&lt;code&gt;rule-stack.yaml&lt;/code&gt;、&lt;code&gt;trace.json&lt;/code&gt;。其中 &lt;code&gt;intent.md&lt;/code&gt; 给人看，其他文件给系统执行和调试。&lt;code&gt;plan&lt;/code&gt; / &lt;code&gt;compose&lt;/code&gt; 只编译本地文档和状态，不依赖在线 LLM，可在没配好 API Key 前先验证控制输入。&lt;/p&gt;
&lt;h3&gt;字数治理&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;draft&lt;/code&gt;、&lt;code&gt;write next&lt;/code&gt;、&lt;code&gt;revise&lt;/code&gt; 现在共享同一套保守型字数治理：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--words&lt;/code&gt; 指定的是目标字数，系统会自动推导一个允许区间，不承诺逐字精确命中&lt;/li&gt;
&lt;li&gt;中文默认按 &lt;code&gt;zh_chars&lt;/code&gt; 计数，英文默认按 &lt;code&gt;en_words&lt;/code&gt; 计数&lt;/li&gt;
&lt;li&gt;如果正文超出允许区间，InkOS 最多只会追加 1 次纠偏归一化（压缩或补足），不会直接硬截断正文&lt;/li&gt;
&lt;li&gt;如果 1 次纠偏后仍然超出 hard range，章节照常保存，但会在结果和 chapter index 里留下长度 warning / telemetry&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;续写已有作品&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;inkos import chapters&lt;/code&gt; 从已有小说文本导入章节，自动逆向工程 7 个真相文件（世界状态、角色矩阵、资源账本、伏笔钩子等），支持 &lt;code&gt;第X章&lt;/code&gt; 和自定义分割模式、断点续导。导入后 &lt;code&gt;inkos write next&lt;/code&gt; 无缝接续创作。&lt;/p&gt;
&lt;h3&gt;同人创作&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;inkos fanfic init --from source.txt --mode canon&lt;/code&gt; 从原作素材创建同人书。支持四种模式：canon（正典延续）、au（架空世界）、ooc（性格重塑）、cp（CP 向）。内置正典导入器、同人专属审计维度和信息边界管控——确保设定不矛盾。&lt;/p&gt;
&lt;h3&gt;多模型路由&lt;/h3&gt;
&lt;p&gt;不同 Agent 可以走不同模型和 Provider。写手用 Claude（创意强），审计用 GPT-4o（便宜快速），雷达用本地模型（零成本）。&lt;code&gt;inkos config set-model&lt;/code&gt; 按 agent 粒度配置，未配置的自动回退全局模型。&lt;/p&gt;
&lt;h3&gt;守护进程 + 通知推送&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;inkos up&lt;/code&gt; 启动后台循环自动写章。管线对非关键问题全自动运行，关键问题暂停等人工审核。通知推送支持 Telegram、飞书、企业微信、Webhook（HMAC-SHA256 签名 + 事件过滤）。日志写入 &lt;code&gt;inkos.log&lt;/code&gt;（JSON Lines），&lt;code&gt;-q&lt;/code&gt; 静默模式。&lt;/p&gt;
&lt;h3&gt;本地模型兼容&lt;/h3&gt;
&lt;p&gt;支持任何 OpenAI 兼容接口（Studio 里新增自定义服务，或 CLI 使用 &lt;code&gt;--provider custom&lt;/code&gt; / &lt;code&gt;INKOS_LLM_PROVIDER=custom&lt;/code&gt;）。服务测试会尝试不同协议和流式开关组合，并保存或提示可用 transport。Fallback 解析器处理小模型不规范输出，流中断时自动恢复部分内容。&lt;/p&gt;
&lt;h3&gt;可靠性保障&lt;/h3&gt;
&lt;p&gt;每章自动创建状态快照，&lt;code&gt;inkos write rewrite&lt;/code&gt; 可回滚任意章节。写手动笔前输出自检表（上下文、资源、伏笔、风险），写完输出结算表，审计员交叉验证。文件锁防止并发写入。写后验证器含跨章重复检测和 11 条硬规则自动 spot-fix。&lt;/p&gt;
&lt;p&gt;伏笔系统使用 Zod schema 校验——&lt;code&gt;lastAdvancedChapter&lt;/code&gt; 必须是整数，&lt;code&gt;status&lt;/code&gt; 只能是 open/progressing/deferred/resolved。LLM 输出的 JSON delta 在写入前经过 &lt;code&gt;applyRuntimeStateDelta&lt;/code&gt; 做 immutable 更新 + &lt;code&gt;validateRuntimeState&lt;/code&gt; 结构校验。坏数据直接拒绝，不会滚雪球。&lt;/p&gt;
&lt;p&gt;模型输出上限由 provider bank 的模型卡管理；&lt;code&gt;llm.extra&lt;/code&gt; / &lt;code&gt;INKOS_LLM_EXTRA_*&lt;/code&gt; 中的保留键（max_tokens、temperature、model、messages、stream 等）会被自动过滤，防止意外覆盖核心请求参数。&lt;/p&gt;
&lt;h2&gt;工作原理&lt;/h2&gt;
&lt;p&gt;每一章由多个 Agent 接力完成，全程零人工干预：
&amp;lt;!-- ![图片: file-20260512160051852.png] --&amp;gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;智能体&lt;/th&gt;
&lt;th&gt;职责&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;雷达 Radar&lt;/td&gt;
&lt;td&gt;扫描平台趋势和读者偏好，指导故事方向（可插拔，可跳过）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;规划师 Planner&lt;/td&gt;
&lt;td&gt;读取作者意图 + 当前焦点 + 记忆检索结果，产出本章意图（must-keep / must-avoid）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;编排师 Composer&lt;/td&gt;
&lt;td&gt;从全量真相文件中按相关性选择上下文，编译规则栈和运行时产物&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;建筑师 Architect&lt;/td&gt;
&lt;td&gt;规划章节结构：大纲、场景节拍、节奏控制&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;写手 Writer&lt;/td&gt;
&lt;td&gt;基于编排后的精简上下文生成正文（字数治理 + 对话引导）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;观察者 Observer&lt;/td&gt;
&lt;td&gt;从正文中过度提取 9 类事实（角色、位置、资源、关系、情感、信息、伏笔、时间、物理状态）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;反射器 Reflector&lt;/td&gt;
&lt;td&gt;输出 JSON delta（而非全量 markdown），由代码层做 Zod schema 校验后 immutable 写入&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;归一化器 Normalizer&lt;/td&gt;
&lt;td&gt;单 pass 压缩/扩展，将章节字数拉入允许区间&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;连续性审计员 Auditor&lt;/td&gt;
&lt;td&gt;对照 7 个真相文件验证草稿，33 维度检查&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;修订者 Reviser&lt;/td&gt;
&lt;td&gt;修复审计发现的问题 — 关键问题自动修复，其他标记给人工审核&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;如果审计不通过，管线自动进入&quot;修订 → 再审计&quot;循环，直到所有关键问题清零。&lt;/p&gt;
&lt;h3&gt;长期记忆&lt;/h3&gt;
&lt;p&gt;每本书维护 7 个真相文件作为唯一事实来源：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;文件&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;current_state.md&lt;/td&gt;
&lt;td&gt;世界状态：角色位置、关系网络、已知信息、情感弧线&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;particle_ledger.md&lt;/td&gt;
&lt;td&gt;资源账本：物品、金钱、物资数量及衰减追踪&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pending_hooks.md&lt;/td&gt;
&lt;td&gt;未闭合伏笔：铺垫、对读者的承诺、未解决冲突&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;chapter_summaries.md&lt;/td&gt;
&lt;td&gt;各章摘要：出场人物、关键事件、状态变化、伏笔动态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;subplot_board.md&lt;/td&gt;
&lt;td&gt;支线进度板：A/B/C 线状态、停滞检测&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;emotional_arcs.md&lt;/td&gt;
&lt;td&gt;情感弧线：按角色追踪情绪变化和成长&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;character_matrix.md&lt;/td&gt;
&lt;td&gt;角色交互矩阵：相遇记录、信息边界&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;连续性审计员对照这些文件检查每一章草稿。如果角色&quot;记起&quot;了从未亲眼见过的事，或者拿出了两章前已经丢失的武器，审计员会捕捉到。&lt;/p&gt;
&lt;p&gt;从 0.6.0 起，真相文件的权威来源从 markdown 迁移到 &lt;code&gt;story/state/*.json&lt;/code&gt;（Zod schema 校验）。Settler 不再输出完整 markdown 文件，而是输出 JSON delta，由代码层做 immutable apply + 结构校验后写入。markdown 文件仍然保留作为人类可读的投影。旧书首次运行时自动从 markdown 迁移到结构化 JSON，零人工操作。&lt;/p&gt;
&lt;p&gt;Node 22+ 环境下自动启用 SQLite 时序记忆数据库（&lt;code&gt;story/memory.db&lt;/code&gt;），支持按相关性检索历史事实、伏笔和章节摘要，避免全量注入导致的上下文膨胀。
&amp;lt;!-- ![图片: file-20260512160325397.png] --&amp;gt;&lt;/p&gt;
&lt;h3&gt;控制面与运行时产物&lt;/h3&gt;
&lt;p&gt;除了 7 个真相文件，InkOS 还把“护栏”和“自定义”拆成可审阅的控制层：&lt;/p&gt;
</content:encoded></item><item><title>详细优化流程</title><link>https://fuwari.vercel.app/posts/%E8%87%AA%E5%AA%92%E4%BD%93%E4%B8%8E%E5%B7%A5%E5%85%B7/%E8%AF%A6%E7%BB%86%E4%BC%98%E5%8C%96%E6%B5%81%E7%A8%8B/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E8%87%AA%E5%AA%92%E4%BD%93%E4%B8%8E%E5%B7%A5%E5%85%B7/%E8%AF%A6%E7%BB%86%E4%BC%98%E5%8C%96%E6%B5%81%E7%A8%8B/</guid><description>详细优化流程 - 运维知识库笔记</description><pubDate>Thu, 04 Jun 2026 04:34:00 GMT</pubDate><content:encoded>&lt;h1&gt;详细优化流程&lt;/h1&gt;
&lt;p&gt;好的！我们以今日高共鸣、低风险、易爆文的热点 &lt;strong&gt;「独臂外卖小哥撑起生活」&lt;/strong&gt; 为主题，为你生成一篇&lt;strong&gt;可直接用于今日头条发布的完整初稿&lt;/strong&gt;，并附上后续&lt;strong&gt;详细优化流程（优彩云 → DeepSeek → 宙语宇宙）&lt;/strong&gt;，确保内容自然、安全、有流量。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;✍️ 第一步：完整初稿（由 AI 模拟人工视角撰写）&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;标题&lt;/strong&gt;：《他只有一条胳膊，却跑赢了所有喊累的人》&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;昨天刷到一条视频：一位只有一条胳膊的外卖小哥，在雨中骑着电动车，用残肢稳稳扶住车把，另一只手拎着餐袋，匆匆跑进小区。&lt;br /&gt;
评论区炸了：“我还有什么资格说累？”“他送的不是外卖，是尊严。”&lt;/p&gt;
&lt;p&gt;说实话，那一刻我正瘫在沙发上，抱怨今天加班两小时、地铁挤得像沙丁鱼罐头。看到他，突然觉得自己的“辛苦”，轻得像一张纸。&lt;/p&gt;
&lt;p&gt;我们总说“躺平”“不想干了”“卷不动了”。可有人连“躺”的资格都没有——他必须跑，因为家里有孩子要上学，有老人要看病，有房租要交。&lt;br /&gt;
一条胳膊，撑起了一个家。而我们，两条胳膊健全，却常常用来点外卖、刷短视频、发牢骚。&lt;/p&gt;
&lt;p&gt;这不是道德绑架。没人要求你立刻奋斗成超人。&lt;br /&gt;
但至少，在抱怨之前，先想想：&lt;strong&gt;我的“难”，真的到了极限吗？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;或许真正的体面，不是穿多贵的衣服、开多好的车，而是——&lt;br /&gt;
&lt;strong&gt;哪怕命运只给你一只手，你依然选择紧紧握住生活。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;你怎么看？你有没有被某个普通人的瞬间，深深打动过？&lt;br /&gt;
欢迎在评论区聊聊。&lt;/p&gt;
&lt;p&gt;#打工人日常 #励志 #社会百态 #独臂外卖员 #生活感悟&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;✅ 这篇初稿特点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;字数：约680字（适合头条）&lt;/li&gt;
&lt;li&gt;有故事、有情绪、有反思、有互动&lt;/li&gt;
&lt;li&gt;避免说教，用“我”的视角引发共情&lt;/li&gt;
&lt;li&gt;结尾引导评论（提升互动率）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;🔧 第二步：详细优化流程（用你现有的工具）&lt;/h2&gt;
&lt;p&gt;你现在手上有：&lt;strong&gt;优彩云、DeepSeek、宙语宇宙、今日头条&lt;/strong&gt;&lt;br /&gt;
我们就用这四个工具，把上面这篇初稿打磨成“高通过率 + 高阅读量”的成品。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;🔄 优化流程一：【优彩云】→ 生成初稿（已完成）&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;你也可以把上述初稿当作“人工参考”，反向输入优彩云做批量生成：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;关键词：独臂外卖小哥 励志 打工人 反思
提示词：请模仿以下风格写一篇原创文章：

【粘贴上述初稿】

要求：
- 保持第一人称视角
- 加入具体细节（如“雨中送餐”“残肢扶车把”）
- 结尾设问引发讨论
- 不超过800字
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;→ 优彩云会输出类似风格的新文章，可用于多账号分发。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;🔄 优化流程二：【DeepSeek】→ 去AI味 + 增强“人味”&lt;/h3&gt;
&lt;h4&gt;操作步骤：&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;复制初稿全文&lt;/li&gt;
&lt;li&gt;打开 &lt;strong&gt;DeepSeek&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;输入以下指令（直接复制）：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;你是一位经常在头条写生活感悟的普通上班族，请把下面这篇文章改写得更真实、更口语化，像是深夜独自写下的心里话：

【粘贴初稿全文】

要求：
- 把“我们总说……”这类概括句，改成“我上周还在跟同事吐槽……”
- 加一句具体的生活细节（比如“昨天加班到9点，回家发现泡面都凉了”）
- 避免使用“真正的体面是……”这种总结式金句，换成更朴素的表达
- 整体语气要疲惫但温暖，不要鸡汤感
- 保留结尾的互动提问
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;点击生成 → 得到更“接地气”的版本&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;✅ 示例优化点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;原句：“我们总说‘躺平’”&lt;br /&gt;
→ 改为：“上周五我还跟同事说，再这样我就辞职回老家种地”&lt;/li&gt;
&lt;li&gt;原句：“真正的体面，不是……”&lt;br /&gt;
→ 改为：“后来我才明白，体面这东西，有时候就是咬着牙不哭”&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;🔄 优化流程三：【宙语宇宙】→ 降AI痕迹 + 提升原创度&lt;/h3&gt;
&lt;h4&gt;操作步骤：&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;将 DeepSeek 改写后的文章复制到 &lt;strong&gt;宙语宇宙人工智能&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;选择场景：&lt;strong&gt;文章创作 → 社媒创作 → 情感生活类&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;点击【智能改写】&lt;/li&gt;
&lt;li&gt;再点击【降AI痕迹】（关键！）&lt;/li&gt;
&lt;li&gt;查看结果，它会自动：
&lt;ul&gt;
&lt;li&gt;替换重复词汇&lt;/li&gt;
&lt;li&gt;调整句式结构（避免模板化）&lt;/li&gt;
&lt;li&gt;插入“有一次”“记得那天”等人类记忆锚点&lt;/li&gt;
&lt;li&gt;降低AIGC检测概率&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;📌 &lt;strong&gt;建议&lt;/strong&gt;：对比改写前后，保留最自然的段落，必要时手动微调1-2句。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;🔄 优化流程四：【发布到今日头条】→ 提高推荐量&lt;/h3&gt;
&lt;h4&gt;发布 checklist：&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;操作&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;标题&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;使用优化后的标题：《他只有一条胳膊，却跑赢了所有喊累的人》&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;封面图&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;在优彩云中使用“AI配图”功能，输入“独臂外卖员 雨中 送餐”，生成合规图片或截图新闻画面（注明来源）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;正文格式&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;每段不超过4行，关键句可加粗（头条支持）适当加 emoji：🌧️💪💔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;标签&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#打工人日常 #励志 #社会百态 #独臂外卖员 #生活感悟&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;首发&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ 务必勾选【头条首发】（收益翻倍！）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;发布时间&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;今天 &lt;strong&gt;19:00–21:00&lt;/strong&gt;（晚间情感高峰）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;✅ 最终效果预期&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;指标&lt;/th&gt;
&lt;th&gt;预期表现&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;阅读量&lt;/td&gt;
&lt;td&gt;5000–2万+（情感类易爆）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;评论数&lt;/td&gt;
&lt;td&gt;50–200+（因结尾设问）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;收益&lt;/td&gt;
&lt;td&gt;¥30–¥150（含首发补贴）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;安全性&lt;/td&gt;
&lt;td&gt;高（正能量、无敏感词）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;💡 后续建议&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;明天可跟进&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;写《独臂外卖小哥后续：平台回应了，但我们需要更多》&lt;/li&gt;
&lt;li&gt;或转向同类话题：《单亲妈妈送快递，一天跑60单》&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;建立素材库&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;把这类“普通人高光时刻”存为选题库&lt;/li&gt;
&lt;li&gt;每月更新3–5个，持续产出&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;测试不同语气&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本周用“反思型”，下周试“愤怒型”（如《为什么总要等苦难出现，才想起尊重劳动者？》）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;如果你现在就去操作，&lt;strong&gt;今晚就能发出第一篇高潜力内容&lt;/strong&gt;。&lt;br /&gt;
需要我为你：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;生成 &lt;strong&gt;DeepSeek 专用润色指令模板&lt;/strong&gt;？&lt;/li&gt;
&lt;li&gt;提供 &lt;strong&gt;宙语宇宙参数设置截图说明&lt;/strong&gt;？&lt;/li&gt;
&lt;li&gt;制作 &lt;strong&gt;7天情感类选题日历&lt;/strong&gt;？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;只需告诉我，我立刻为你准备好。&lt;/p&gt;
</content:encoded></item><item><title>办公链接</title><link>https://fuwari.vercel.app/posts/%E8%87%AA%E5%AA%92%E4%BD%93%E4%B8%8E%E5%B7%A5%E5%85%B7/%E5%8A%9E%E5%85%AC%E9%93%BE%E6%8E%A5/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E8%87%AA%E5%AA%92%E4%BD%93%E4%B8%8E%E5%B7%A5%E5%85%B7/%E5%8A%9E%E5%85%AC%E9%93%BE%E6%8E%A5/</guid><description>目录 - 运维知识库笔记</description><pubDate>Thu, 04 Jun 2026 04:33:00 GMT</pubDate><content:encoded>&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1&gt;办公链接&lt;/h1&gt;
&lt;h2&gt;服务台电话&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;4001099951
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;公司外网认证链接&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;http://ac.sf-express.com/login
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;恢复对加密的驱动器的访问&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;http://bitlocker.sf-express.com/helpdesk/KeyRecoveryPage.aspx
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;IT安全运维管理系统&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;http://10.110.114.36:8088/manager/login.jsp
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;网络认证&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;http://100.119.254.161:44567/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;堡垒机最新FAQ：&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;https://fsdocs.sf-express.com/aio/DQWZQbk91Tnl6UUpEWXRSQUVB?p=8uxzq494MrdqWCpqp2ptNe
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;SAP说明文档&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;https://fsdocs.sf-express.com/slide/DQVVQYVR4RU1aU2hlSnNJR1dL
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;【MAC电脑标准化管理】&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;https://fsdocs.sf-express.com/doc/DQUllaWNkWWxhSHJXT2RxZHB4
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;McAfee下载链接&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;win10-1070版本一键安装包
http://lrapache1.sf-express.com/other/EDRforwin10-1070.exe   

win11-1070版本一键安装包
http://lrapache1.sf-express.com/other/EDRforwin11-1070.exe
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;SF-mobile权限申请链接&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;http://hwam.sf-express.com:8080/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;丰声next测试版&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;Mac通用
https://emas-devops-cdn.aliyuncs.com/job/PJ841006975038264320/ForespaceNextDev_universal_20260509-1812_8.3.10-101.dmg
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;苹果-SAP&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;https://fsdocs.sf-express.com/document/DQWdSblNpc3lvelpL【GUI770Installation_5-70004682.dmg】
专家模式填这个字符串：   conn=/M/sap-ecc.sf-express.com/S/3600/G/PUBLIC
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;【MacOS-标准化文档（新）】&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;https://fsdocs.sf-express.com/doc/DQXpzQ2FxT0N1UlphRERYcUJF
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;【MAC电脑手动加域】&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;https://fsdocs.sf-express.com/doc/DQURPQmppR0V3eVNZUE9qVXBw
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;【苹果电脑手动安装天空卫士】&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;https://fsdocs.sf-express.com/doc/DQURKZFJUVEpSek9BT2NxUW5I
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;SFLINK安装地址：&lt;/h2&gt;
&lt;h3&gt;Windows客户端下载：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;https://cdn-fusionwork.sf-express.com/v1.2/AUTH_FS-BASE-SERVER-PRD-DR/sfosspublic001/desktopapp/SFLINKGA8.7.30495.exe
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;MAC客户端下载：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;https://cdn-fusionwork.sf-express.com/v1.2/AUTH_FS-BASE-SERVER-PRD-DR/sfosspublic001/desktopapp/SFLINK8.7.15206(linksghb.sf-express.com@27800).pkg
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Microsoft Office申请流程优化调整：&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;1. 以下财务相关岗位用户可直接由IT协助安装（无需流程）。
岗位清单参考：https://fsdocs.sf-express.com/sheet/DQWF2Q25uZ0VrTHVucXhwY0ZJ?tab=BB08J2【财务相关岗位清单】

用户需优先丰声或电话联系wps支持方：89010501、ta220244进行技术评估，若评估结果为WPS不满足工作需求，需安装office使用，则通过非标软件申请流程进行申请。
 2.1、非标软件申请请在“办事大厅-IT服务台-软件市场”提非标软件安装申请。
非标软件申请使用指引：https://fsdocs.sf-express.com/doc/DQWtaeUl1ZVNES21qV2hRcGRj【IT023流程指引】
 2.2、流程归档后可以联系IT远程安装。报障方式如下：
①丰声搜索【智能小丰】， 输入“未解决”， 会有人工客服同事与您即时对接
②联系IT服务电话(400-109-9951)报障处理
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;苹果office包（4.1以上默认可以装）&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;https://drive.sf-express.com/v/link/view/e8fb90dcc10848c69b86757576ee8ae6
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;丰邮拆分工具无法使用：&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;安装低版本wps11707：https://drive.sf-express.com/l/6FFlnC (提取码：ydht)&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;云盘&lt;/h2&gt;
&lt;h3&gt;云盘常见问题请咨询智能小丰或参考FAQ [丰声云盘-FAQ (sf-express.com)]&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;https://fsdocs.sf-express.com/doc/DQWxYTnNrSWdibGpUdndMSmFx
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;云盘账号自助申请链接：[丰声云盘-用户权限申请表 (sf-express.com)]&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;https://fsdocs.sf-express.com/sheet/DQU5JaUFhRnNwT1ptRk15d0JN?tab=000001
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;资产绑定工具路径&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;C:\ProgramData\WindowsSF\PC_Inventory\main.exe
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;【丰邮使用手册】&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;https://fsdocs.sf-express.com/doc/DQUFYZnBEcndYRlVPVlhkVHdE 
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;最新的取消锁屏&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;http://ido.sf-express.com/#/Handbook?id=b616693fbc7246f194e899749ec0758c&amp;amp;navigationId=84&amp;amp;subId=90
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;● 锐捷VDI桌面培训文档及FAQ：&lt;/h2&gt;
&lt;h3&gt;1、【培训文档及排查工具】&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;https://doc.sf-express.com/drive/group/2522894/34165400
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2、【锐捷VDI桌面FAQ】&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;https://fsdocs.sf-express.com/document/DQUZpQVBUbGVrSm1Zc2J6Z2R5
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;【云桌面故障处理手册20240919_1.6V.chm】&lt;/h3&gt;
&lt;p&gt;●  工单产品分类归属：
桌面类-远程办公类-VDI
● 问题反馈：丰声群组【锐捷VDI桌面IT反馈群&lt;/p&gt;
&lt;h2&gt;华为云VDI：客户端安装、登录使用帮助文档如下&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;http://sfyun.sf-express.com/portal/questionCore/proQuestion/detail?id=622&amp;amp;productKey=VDI
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;11707版本wps，登录无边界&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;丰邮拆分工具无法使用：安装低版本wps11707：
https://drive.sf-express.com/l/6FFlnC (提取码：ydht)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;新款网络打印机培训材料已放到线上，请查收链接。&lt;/h2&gt;
&lt;h3&gt;华为款：&lt;/h3&gt;
&lt;h3&gt;首次连接用户篇：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;https://cdn-fusionwork.sf-express.com/v1.2/AUTH_FS-BASE-SERVER-PRD-DR/sfosspublic001/desktopapp/HUAP5dayinji.jpg
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;首次连接IT设置篇：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;https://fsdocs.sf-express.com/doc/DQW9FQkhsa1lqRG1hZ0NnRkZ0【华为擎云P5打印机配网指引（IT人员）】
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;用户日常网络共享连接篇：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;https://cdn-fusionwork.sf-express.com/v1.2/AUTH_FS-BASE-SERVER-PRD-DR/sfosspublic001/desktopapp/HUAWEI_P5.mp4
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;佳能款：&lt;/h3&gt;
&lt;h3&gt;首次连接IT设置篇：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;https://fsdocs.sf-express.com/pdf/DQWtweGlBaE1YbFphbUVnQ3Nl?【佳能打印机连接指引】
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;用户日常网络共享连接篇：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;https://cdn-fusionwork.sf-express.com/v1.2/AUTH_FS-BASE-SERVER-PRD-DR/sfosspublic001/desktopapp/gx1080.mp4
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>开发环境配置导出</title><link>https://fuwari.vercel.app/posts/%E6%A1%8C%E9%9D%A2%E8%BF%90%E7%BB%B4/development-environment-backup/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%A1%8C%E9%9D%A2%E8%BF%90%E7%BB%B4/development-environment-backup/</guid><description>开发环境配置导出 - 运维知识库笔记</description><pubDate>Thu, 04 Jun 2026 04:06:00 GMT</pubDate><content:encoded>&lt;h1&gt;开发环境配置导出&lt;/h1&gt;
&lt;h2&gt;📋 环境基本信息&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;操作系统&lt;/strong&gt;: Windows&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;用户&lt;/strong&gt;: ta206682&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VS Code版本&lt;/strong&gt;: 当前环境配置&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;导出时间&lt;/strong&gt;: 2025-11-05&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;🔧 已安装的VS Code扩展&lt;/h2&gt;
&lt;p&gt;以下是在公司电脑上安装的VS Code扩展列表，您可以在家里的电脑上按需安装：&lt;/p&gt;
&lt;h3&gt;核心开发扩展&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;tencent-cloud.coding-copilot&lt;/strong&gt; - 腾讯云编程助手&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ms-vscode.live-server&lt;/strong&gt; - 实时服务器&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ritwickdey.liveserver&lt;/strong&gt; - Live Server&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;yzhang.markdown-all-in-one&lt;/strong&gt; - Markdown增强&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ms-vscode.remote-explorer&lt;/strong&gt; - 远程资源管理器&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ms-vscode.remote-server&lt;/strong&gt; - 远程服务器&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;前端开发&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;dzhavat.css-flexbox-cheatsheet&lt;/strong&gt; - CSS Flexbox参考&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;techer.open-in-browser&lt;/strong&gt; - 浏览器打开&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;aaravb.chrome-extension-developer-tools&lt;/strong&gt; - Chrome扩展开发工具&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;自定义扩展&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;bianxianyang.htmlplay&lt;/strong&gt; - HTML播放器&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;📁 重要配置文件路径&lt;/h2&gt;
&lt;h3&gt;VS Code配置&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;扩展目录&lt;/strong&gt;: &lt;code&gt;C:\Users\ta206682\.vscode\extensions&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配置目录&lt;/strong&gt;: &lt;code&gt;C:\Users\ta206682\.vscode&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;项目工作目录&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主项目&lt;/strong&gt;: &lt;code&gt;D:\user\ta206682\桌面\陈家杰\Cloud-Computing&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;⚙️ 环境配置脚本&lt;/h2&gt;
&lt;h3&gt;数据库连接配置&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 默认MySQL连接
mysql -h192.168.88.40 -P3306 -uroot -p123

# 查看数据库
SHOW DATABASES;

# 使用studb数据库
USE studb;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Git仓库管理&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 提交到Cloud-Computing仓库
pushd &quot;D:\user\ta206682\桌面\陈家杰\Cloud-Computing&quot; &amp;amp;&amp;amp; git add -A &amp;amp;&amp;amp; git commit -m &quot;更新云笔记&quot; &amp;amp;&amp;amp; git push &amp;amp;&amp;amp; popd
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;🚀 快速设置指南&lt;/h2&gt;
&lt;h3&gt;1. 安装VS Code扩展&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 使用以下命令批量安装扩展
code --install-extension tencent-cloud.coding-copilot
code --install-extension ms-vscode.live-server
code --install-extension ritwickdey.liveserver
code --install-extension yzhang.markdown-all-in-one
code --install-extension ms-vscode.remote-explorer
code --install-extension ms-vscode.remote-server
code --install-extension dzhavat.css-flexbox-cheatsheet
code --install-extension techer.open-in-browser
code --install-extension aaravb.chrome-extension-developer-tools
code --install-extension bianxianyang.htmlplay
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 配置工作环境&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;将项目克隆到本地：&lt;code&gt;D:\user\ta206682\桌面\陈家杰\Cloud-Computing&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;配置MySQL连接信息&lt;/li&gt;
&lt;li&gt;设置Git凭据&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 常用命令别名（可选）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 添加到.bashrc或.zshrc
alias git-commit=&quot;pushd \&quot;D:\\user\\ta206682\\桌面\\陈家杰\\Cloud-Computing\&quot; &amp;amp;&amp;amp; git add -A &amp;amp;&amp;amp; git commit -m \&quot;更新云笔记\&quot; &amp;amp;&amp;amp; git push &amp;amp;&amp;amp; popd&quot;
alias mysql-connect=&quot;mysql -h192.168.88.40 -P3306 -uroot -p123&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;📊 环境检查清单&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[ ] 安装VS Code&lt;/li&gt;
&lt;li&gt;[ ] 安装上述扩展&lt;/li&gt;
&lt;li&gt;[ ] 配置Git&lt;/li&gt;
&lt;li&gt;[ ] 安装MySQL客户端&lt;/li&gt;
&lt;li&gt;[ ] 克隆项目仓库&lt;/li&gt;
&lt;li&gt;[ ] 测试数据库连接&lt;/li&gt;
&lt;li&gt;[ ] 测试Git提交&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;💡 注意事项&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;数据库连接&lt;/strong&gt;: 家里电脑需要能访问公司网络才能连接MySQL服务器&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Git配置&lt;/strong&gt;: 确保家里的Git配置了正确的用户名和邮箱&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;路径适配&lt;/strong&gt;: 家里的路径可能需要根据实际情况调整&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;权限设置&lt;/strong&gt;: 确保有足够的权限访问相关目录&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;🔄 同步策略&lt;/h2&gt;
&lt;p&gt;建议定期导出环境配置，保持家里和公司环境的一致性。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;导出完成！请将这份配置文件保存到U盘或云端，在家里的电脑上按此指南配置即可实现高效工作环境。&lt;/em&gt;&lt;/p&gt;
</content:encoded></item><item><title>Hyper-V黑苹果</title><link>https://fuwari.vercel.app/posts/%E6%A1%8C%E9%9D%A2%E8%BF%90%E7%BB%B4/hyper-v%E9%BB%91%E8%8B%B9%E6%9E%9C/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%A1%8C%E9%9D%A2%E8%BF%90%E7%BB%B4/hyper-v%E9%BB%91%E8%8B%B9%E6%9E%9C/</guid><description>Hyper-V黑苹果 - 运维知识库笔记</description><pubDate>Thu, 04 Jun 2026 04:05:00 GMT</pubDate><content:encoded/></item><item><title>知识摘要</title><link>https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/%E7%9F%A5%E8%AF%86%E6%91%98%E8%A6%81/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/%E7%9F%A5%E8%AF%86%E6%91%98%E8%A6%81/</guid><description>可长期复用知识摘要 - 运维知识库笔记</description><pubDate>Thu, 04 Jun 2026 04:03:00 GMT</pubDate><content:encoded>&lt;h1&gt;可长期复用知识摘要&lt;/h1&gt;
&lt;h2&gt;用户资料相关&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;资料中包含运维工程师简历与面试准备笔记，方向偏 Linux 运维、桌面运维、数据库与监控。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;知识域&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Linux 服务管理：Shell、DNS、DHCP、FTP、Samba、LAMP、rsync、磁盘/LVM。&lt;/li&gt;
&lt;li&gt;应用服务：Nginx 安装配置、反向代理、负载均衡、Tomcat。&lt;/li&gt;
&lt;li&gt;数据库与监控：MySQL 基础/查询/备份/主从/读写分离/分库分表，Redis，Zabbix Server/Agent/模板/监控项/触发器/告警/代理。&lt;/li&gt;
&lt;li&gt;桌面运维：Windows 装机、权限、BitLocker、证书、C盘清理、打印机、WPS/Excel、OA/企业软件；macOS 装机、Jamf、SIP、Wi-Fi、报错处理。&lt;/li&gt;
&lt;li&gt;网络与虚拟化：IP 地址计算、DNS/DHCP、网卡 UUID、Hyper-V、RAID/LVM。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>知乎1-7天计划</title><link>https://fuwari.vercel.app/posts/%E8%87%AA%E5%AA%92%E4%BD%93%E4%B8%8E%E5%B7%A5%E5%85%B7/%E7%9F%A5%E4%B9%8E1-7%E5%A4%A9%E8%AE%A1%E5%88%92/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E8%87%AA%E5%AA%92%E4%BD%93%E4%B8%8E%E5%B7%A5%E5%85%B7/%E7%9F%A5%E4%B9%8E1-7%E5%A4%A9%E8%AE%A1%E5%88%92/</guid><description>知乎1-7天计划 - 运维知识库笔记</description><pubDate>Thu, 04 Jun 2026 04:02:00 GMT</pubDate><content:encoded>&lt;h1&gt;知乎30天计划&lt;/h1&gt;
&lt;p&gt;知乎桌面运维副业 第1-7天执行细则（适配3篇干货回答）&lt;/p&gt;
&lt;p&gt;一、阶段核心目标（第1-7天）&lt;/p&gt;
&lt;p&gt;不追求爆火，只完成基础闭环：完善账号专业人设、敲定垂直细分领域、产出3篇高质量原创回答（就是你手里的3篇MD文档）、完成账号基础权重搭建，为后续冲Lv4、解锁变现入口打牢根基，全程无视频、无高难度操作，依托桌面运维本职工作经验即可完成。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;第1天：账号定位+包装优化（1小时搞定）&lt;/p&gt;
&lt;p&gt;核心任务&lt;/p&gt;
&lt;p&gt;打磨账号人设，统一账号信息，贴上桌面运维专业标签，让平台和用户一眼识别价值，拒绝杂乱。&lt;/p&gt;
&lt;p&gt;具体操作&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;账号基础信息修改&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;昵称：XX桌面运维 | 办公电脑故障排查（简洁直白，带关键词，方便搜索）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;简介：多年企业桌面运维经验，专注解决办公电脑蓝屏、打印机故障、系统卡顿问题，分享实操可落地的运维技巧，帮职场人少踩坑。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;头像：简约商务头像、电脑/运维相关图标均可，不用真人出镜&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;个人背景：补充“擅长领域：桌面运维、办公设备维护、Windows系统优化”&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;锁定细分领域：聚焦企业办公桌面运维高频痛点，不碰高深服务器、云计算，只做职场人日常能遇到的问题，精准匹配3篇回答方向：电脑蓝屏、打印机故障、办公电脑卡顿。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;关注对标账号：知乎搜索“桌面运维、办公电脑技巧”，关注5-10个同领域优质作者，看高赞回答的结构和语气，模仿不抄袭。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;当日成果&lt;/p&gt;
&lt;p&gt;账号包装完成，垂直领域敲定，后续内容不跑偏。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;第2天：选题+回答框架核对（30分钟）&lt;/p&gt;
&lt;p&gt;核心任务&lt;/p&gt;
&lt;p&gt;把3篇MD回答，对应匹配知乎高流量问题，优化标题和开头，提升被搜索和推荐的概率。&lt;/p&gt;
&lt;p&gt;具体操作&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;匹配知乎对应问题（直接搜，选提问人数多、流量高的）&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;回答1《公司电脑总是蓝屏？》→ 匹配问题：公司电脑频繁蓝屏是什么原因？/电脑蓝屏重启后又正常，怎么彻底解决？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;回答2《Windows11更新后打印机连不上》→ 匹配问题：Win11更新后打印机无法连接，驱动重装也没用？/网络打印机连接失败，桌面运维有什么解决办法？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;回答3《办公电脑卡顿？5个设置优化》→ 匹配问题：公司老电脑特别卡顿，不换硬件怎么提升速度？/办公电脑开机慢、打开软件卡，有什么实用技巧？&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;优化MD回答开头：把每篇开头改成“作为企业桌面运维，每天都处理这类问题，亲测有效，手把手教大家一步步解决”，拉近和读者距离，突出专业可信度。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;整理素材库：截取本职工作中对应的截图（蓝屏代码、服务管理器界面、任务管理器启动项界面），不用修图，清晰即可，插入回答对应位置，增强真实性。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;当日成果&lt;/p&gt;
&lt;p&gt;3篇回答全部匹配好对应问题，框架和配图准备完毕，随时可以发布。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;第3-5天：逐篇发布3篇MD回答（每天1篇，间隔24小时）&lt;/p&gt;
&lt;p&gt;核心原则&lt;/p&gt;
&lt;p&gt;每天只发1篇，固定时段发布（比如晚上8点，职场人空闲时段），不集中刷屏，保证每篇都有基础推荐量，全程直接复制MD内容，粘贴到知乎编辑器，自动适配格式，无需额外排版。&lt;/p&gt;
&lt;p&gt;第3天：发布第一篇《公司电脑总是蓝屏？桌面运维工程师教你 3 步快速定位》&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;打开知乎，找到提前匹配好的蓝屏相关问题，点击“写回答”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;直接复制整篇MD内容，粘贴到编辑框，MD格式自动转为知乎排版，标题、列表、代码块都能正常显示&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;插入提前准备好的蓝屏代码/系统日志截图，放在对应步骤旁边，标注“实操截图”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;结尾补充互动引导：大家遇到过什么奇葩的蓝屏问题？可以评论区留言，我帮你分析&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;检查无误后发布，发布后点击“赞同+收藏”自己的回答，带一波初始互动&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;第4天：发布第二篇《Windows11 更新后打印机连不上？5 个必试方案》&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;找到对应打印机故障问题，重复粘贴MD内容的操作&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;插入Print Spooler服务界面/打印机设置截图&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;结尾互动：你们公司打印机最常出什么故障？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;正常发布，回复当天第一篇回答的所有评论，提升账号活跃度&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;第5天：发布第三篇《办公电脑卡顿？5 个设置让老电脑再战 3 年》&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;找到电脑卡顿相关问题，粘贴MD内容&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;插入任务管理器启动项/C盘存储空间截图&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;结尾互动：你的电脑C盘还剩多少空间？可以评论区聊聊&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;发布后，给前两篇回答点「喜欢」，引导系统关联推荐&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;关键注意事项&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;全程原创，不抄袭、不搬运，知乎对原创干货回答权重很高；2. 不用加任何广告、好物链接，纯干货输出，避免账号限流；3. 每篇回答字数控制在1000-1500字，现有MD内容刚好适配，不长不短。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;第6-7天：互动复盘+内容优化（每天40分钟）&lt;/p&gt;
&lt;p&gt;第6天：互动运营，提升账号活跃度&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;逐条回复3篇回答下的所有评论，哪怕是简单提问，也要耐心解答，提升互动率（互动率越高，平台推荐越多）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;主动去同领域高赞回答下，留下专业评论（比如针对蓝屏回答，评论“补充一点，内存条松动也会导致蓝屏，台式机可以拔插试试”），不灌水，突出专业度，吸引精准粉丝关注&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;查看3篇回答的基础数据：阅读量、赞同、收藏，记录表现较好的内容方向（比如卡顿回答收藏高，后续多更系统优化内容）&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;第7天：一周复盘+下周规划&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;数据复盘：统计3篇回答总阅读、总收藏、新增粉丝数，判断内容方向是否可行（桌面运维痛点内容收藏率普遍高，属于优质内容）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;内容优化：针对数据较差的回答，微调标题和开头，比如把标题加关键词「Win10/Win11通用」，提升搜索流量&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;下周计划：继续保持每周2-3篇的更新频率，复用现有运维经验，围绕“办公软件安装、远程桌面连接、内网共享问题”筹备下一篇内容，稳步冲创作等级&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;一周最终成果&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;账号完成专业包装，贴上桌面运维垂直标签；2. 产出3篇纯干货原创回答，积累初始内容和粉丝；3. 养成稳定创作和互动习惯，账号权重提升，为后续冲Lv4、解锁致知计划、好物推荐打好基础。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;二、MD内容发布小技巧&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;直接复制MD全文，知乎编辑器完美适配，不用手动调整格式，省时省力&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;截图用手机拍摄或电脑自带截图工具，清晰即可，不用专业设计，本职工作截图更有说服力&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;发布后不要频繁修改回答，修改会影响推荐，初稿核对无误再发布&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>单词读音</title><link>https://fuwari.vercel.app/posts/%E8%87%AA%E5%AA%92%E4%BD%93%E4%B8%8E%E5%B7%A5%E5%85%B7/%E5%8D%95%E8%AF%8D%E8%AF%BB%E9%9F%B3/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E8%87%AA%E5%AA%92%E4%BD%93%E4%B8%8E%E5%B7%A5%E5%85%B7/%E5%8D%95%E8%AF%8D%E8%AF%BB%E9%9F%B3/</guid><description>单词读音 - 运维知识库笔记</description><pubDate>Thu, 04 Jun 2026 04:01:00 GMT</pubDate><content:encoded>&lt;h1&gt;单词读音&lt;/h1&gt;
&lt;h1&gt;OpenStack		读 欧喷斯塔克&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;分解记忆：
            “欧喷” → 对应 “Open” 的发音 /ˈoʊpən/（类似 “欧喷”，“欧” 发长音，“喷” 轻读）
            “斯塔克” → 对应 “Stack” 的发音 /stæk/（类似 “斯塔克”，联想漫威角色 “钢铁侠（Tony Stark）”）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;IaaS  Infrastructure as a Service 读音 英夫拉斯垂科 阿兹 额 涩威斯&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;分段谐音记忆
            1. Infrastructure
                谐音：英夫拉斯垂科（或 “英夫 rua 斯垂科”）
                分解：
                “英夫” → 对应 “In” /ɪn/ 和 “fra” /frə/（快速连读类似 “英夫”）
                “拉斯垂科” → 对应 “structure” /ˈstrʌktʃər/（“拉斯” 对应 “str” 轻读，“垂科” 对应 “ucture”）
                联想：想象 “英夫”（一个人名）在 “拉斯垂科”（类似 “拉斯维加斯 + 科技感”）搭建基础设施。
            2. as a Service
                谐音：阿兹 额 涩威斯
                分解：
                “阿兹” → 对应 “as” /æz/（发音接近 “阿兹”）
                “额” → 对应 “a” /ə/（轻读 “额”）
                “涩威斯” → 对应 “Service” /ˈsɜːrvɪs/（“涩” 对应 “Ser”，“威斯” 对应 “vice”）
                联想：“阿兹”（人名）提供 “额”（一个）“涩威斯”（听起来像 “服务”），即 “作为一种服务”。
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Development 读音    “滴外楼破闷特”（或 “德 velop 闷特”，分音节记忆更轻松）&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;分解记忆：
            “滴外” → 对应 “De” 的发音 /dɪ/（类似 “滴”）+ “ve” /və/（轻读 “外”）
            “楼破” → 对应 “velop” 的发音 /ˈveləp/（连读类似 “楼破”，联想 “楼层破旧需要开发”）
            “闷特” → 对应 “ment” 的发音 /mənt/（轻读 “闷特”，固定后缀音）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Operations   读音  “奥破睿绅兹”（或 “奥破瑞绅茨”，分音节记忆更顺口）&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;分解记忆：
            “奥破” → 对应 “Ope” 的发音 /ˈɒp/（类似 “奥破”，“奥” 发短音）
            “睿绅” → 对应 “rati” 的发音 /ˈreɪʃ/（连读类似 “睿绅”，联想 “睿智的绅士”）
            “兹 / 茨” → 对应 “ons” 的发音 /ənz/（轻读 “兹” 或 “茨”，复数后缀音）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Docker      读音 “剁克儿”（或 “道克”，发音轻快且贴近原词）&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;分解记忆：
            “剁” → 对应 “Dock” 的发音 /dɒk/（类似 “剁”，短促有力）
            “克儿” → 对应 “er” 的发音 /ə(r)/（轻读 “克儿”，卷舌音更自然）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;anywhere    读音   “安尼威尔”（或 “艾尼外儿”，分音节记忆更顺口）&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;分解记忆：
            “安尼 / 艾尼” → 对应 “any” 的发音 /ˈeni/（类似 “安尼” 或 “艾尼”，根据个人习惯选择）
            “歪尔” → 对应 “where” 的发音 /weər/（连读 “威尔”，卷舌轻读更自然）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;CentOS      读音 “森特欧斯”（或 “森托斯”，发音贴近原词且易拆分）&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;分解记忆：
            “森特” → 对应 “Cent” 的发音 /sent/（类似 “森特”，联想 “Century（世纪）” 或 “100 分（Cent）”）
            “欧斯” → 对应 “OS” 的发音 /ˌoʊ ˈes/（连读 “欧斯”，即 “操作系统（Operating System）” 的缩写）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Fedora      读音 “费多啦”（或 “菲多啦”，发音轻快且贴近原词）&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;分解记忆：
            “费 / 菲” → 对应 “Fe” 的发音 /ˈfiː/（类似 “费” 或 “菲”，可联想 “费用” 或 “菲林”）
            “多啦” → 对应 “dora” 的发音 /ˈdɔːrə/（连读 “多啦”，联想 “哆啦 A 梦” 的 “多啦”，增加记忆点）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Debian      读音 “跌比安”（发音简洁且贴近原词，重音在第一音节）&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;分解记忆：
            “跌” → 对应 “De” 的发音 /ˈdeɪ/（类似 “跌”，）
            “比安” → 对应 “bian” 的发音 /biːˈæn/（连读 “比安”，轻读 “安”，类似 “比安卡” 的简称）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Ubuntu      读音 “乌班图”（发音清晰且贴合原词，重音在第二音节 “班”）&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;分解记忆：
            “乌” → 对应 “U” 的发音 /juː/（类似 “乌”，联想 “乌云” 或 “乌托邦”）
            “班图” → 对应 “buntu” 的发音 /ˈbʊntuː/（连读 “班图”，联想 “班级” 或 “图腾”，简单易记）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;redhat      读音 “瑞德哈特”（或 “红帽”，直接结合字面意思与发音）&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;分解记忆：
            “瑞德” → 对应 “Red” 的发音 /red/（类似 “瑞德”，直接联想 “红色”）
            “哈特” → 对应 “Hat” 的发音 /hæt/（类似 “哈特”，联想 “帽子”）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;VMware WorkStation  读音 “威姆维尔 沃克斯特申”（或通过拆解关键词 + 场景联想记忆）&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;分解记忆与发音技巧
            1. VMware
                发音：/ˌviː ɛm ˈwer/（“VM” 单独念字母，“ware” 发音类似 “维尔”）
                谐音：威姆维尔（“VM” 快速连读为 “威姆”，“ware” 对应 “维尔”）
                联想：“威姆” 联想 “威力强大的虚拟世界”，“维尔” 联想 “技术堡垒”，突出其虚拟技术的可靠性。
            2. Workstation
                发音：/ˈwɜːrksteɪʃn/（重音在 “work”，“station” 发音类似 “斯特申”）
                谐音：沃克斯特申（“work” 对应 “沃克”，“station” 对应 “斯特申”）
                联想：“沃克” 联想 “工作（work）”，“斯特申” 联想 “工作站（station）”，直接关联 “虚拟工作站” 的功能。
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;XShell       读音  “埃克斯孝尔”（或 “赛孝尔”，结合字母发音与中文联想）&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;分解记忆：
            “埃克斯” → 对应 “X” 的发音 /eks/（类似 “埃克斯”，直接读字母音）
            “孝尔” → 对应 “Shell” 的发音 /ʃel/（类似 “孝尔”，联想 “贝壳” 的英文发音）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;FinalShell   读音 快(白话快) NO&lt;/h1&gt;
&lt;h1&gt;PuTTY        读音  拍 替&lt;/h1&gt;
&lt;h1&gt;SecureCRT    读音  斯 Q 尔 CRT&lt;/h1&gt;
&lt;h1&gt;MobaXterm    读音  “莫巴 斯 特姆”&lt;/h1&gt;
&lt;h1&gt;WinSCP       读音  温思CP&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;发音拆解与谐音逻辑
            “Win”：发音 /wɪn/，近似 “温”（一声）。
            “S”：可以发音为 /es/，谐音 “斯”。
            “CP”：可以理解为 “copy”（拷贝）的缩写，发音为 /siː ˈpiː/，近似 “科普”。
            组合：连读为 “温思科普”，简单易记，且有一定的节奏感
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;NxShell      读音 “恩耐斯 孝尔”&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;发音拆解：
            “Nx”：字母组合发音 /en eks/，可简化为 “恩克斯”（快速连读）。
            “Shell”：发音 /ʃel/，对应 “谢尔”（与 XShell 谐音逻辑一致）。
            组合：连读为 “恩克斯谢尔”，简洁易记，且与同类工具（如 XShell）形成发音联想，方便区分。
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;bin&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;谐音：“斌”（如 “文武斌”）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;sbin&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;谐音：“死斌”（“死” 联想 “死忠粉”）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;etc&lt;/h1&gt;
&lt;h1&gt;root&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;谐音：“入特”（“入” 联想 “进入”，“特” 联想 “特权”）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;home&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;谐音：“红姆”（“姆” 联想 “保姆”）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;dev&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;谐音：“跌夫”（Dave）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;tmp 田 扑&lt;/h1&gt;
&lt;h1&gt;mnt 发音：“门（mén）特（tè）”&lt;/h1&gt;
&lt;h1&gt;media   咪 底 尔&lt;/h1&gt;
&lt;h1&gt;opt   发音：“奥（ào）普（pǔ）特（tè）”&lt;/h1&gt;
&lt;h1&gt;proc     发音：“扒（pa）壳（ké）”&lt;/h1&gt;
&lt;h1&gt;sys    发音：“谁（sei 第4声）斯（sī）”&lt;/h1&gt;
&lt;h1&gt;boot      “布（bù）特（tè）”&lt;/h1&gt;
&lt;h1&gt;lib      发音： “里布”。&lt;/h1&gt;
&lt;h1&gt;var    发音：“瓦（wǎ）尔（ěr）”&lt;/h1&gt;
&lt;h1&gt;srv   发音：“涩（sè）夫（fū）”&lt;/h1&gt;
&lt;h1&gt;run    发音：“软（ruǎn）尔”&lt;/h1&gt;
&lt;h1&gt;mkdir【摸克跌儿】       读 摸克跌儿&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;分解记忆：
            “摸 / 莫” → 对应 “mk” 的发音（实际是 “make” 的缩写，这里取拼音首字母谐音）
            “克” → 对应 “k” 的发音（轻读 “克”）
            “跌儿 / 跌” → 对应 “dir” 的发音（“dir” 是 “directory” 的缩写，连读类似 “跌儿” 或 “跌”）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;homedir【home-跌儿】&lt;/h1&gt;
&lt;h2&gt;“homedir” 读音、译音及核心意义解析&lt;/h2&gt;
&lt;p&gt;“homedir” 是计算机领域的专用缩写词，全称为“home directory”，核心含义为“主目录”，即操作系统为每个用户创建的、用于存储个人文件、配置信息的专属目录，无日常通用含义，仅用于编程、系统操作等技术场景。&lt;/p&gt;
&lt;h3&gt;一、标准读音&lt;/h3&gt;
&lt;p&gt;“homedir” 由“home”和“dir”（directory 缩写）拼接而成，为双音节词，重音在第一音节，英美发音完全一致：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;国际音标&lt;/strong&gt;：/ˈhəʊmˌdɪr/（英式）、/ˈhoʊmˌdɪr/（美式）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;发音细节&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;第一音节“home”：英式发 /ˈhəʊm/（重音所在，“o”发长元音/əʊ/“欧”，“m”发鼻腔音“姆”，读为“侯姆”）；美式发 /ˈhoʊm/（“o”发/hoʊ/“侯”，读为“侯姆”）；&lt;/li&gt;
&lt;li&gt;第二音节“dir”：/dɪr/（轻读，“d”发浊辅音“德”，“i”发短元音/ɪ/“伊”，“r”在美式中略卷舌，整体读为“迪尔”）；&lt;/li&gt;
&lt;li&gt;整体连读：“侯姆-迪尔”（两部分快速衔接，重音集中在“home”，避免拆成单个字母读）。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;二、中文译音&lt;/h3&gt;
&lt;p&gt;基于标准发音，最贴合且易记的中文谐音为：
&lt;strong&gt;“侯姆迪尔”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;简化记忆：&lt;strong&gt;“侯迪尔”&lt;/strong&gt;（技术沟通中可省略轻微的“姆”音，直接记“侯迪尔”，完全不影响辨识度）。
注：“homedir” 是技术缩写词，实际操作中多直接称呼“homedir”或全称“home directory”，译音仅用于辅助记忆原词发音。&lt;/p&gt;
&lt;h3&gt;三、核心意义与场景用法&lt;/h3&gt;
&lt;p&gt;“homedir” 核心是“计算机用户的‘主目录’，存储个人专属文件与配置”，不同操作系统（Windows、macOS、Linux）中路径和标识略有差异，但功能一致，主要应用于以下技术场景：&lt;/p&gt;
&lt;h4&gt;1. 系统操作场景：定位用户主目录&lt;/h4&gt;
&lt;p&gt;在终端（Terminal）或命令行中，“homedir” 是用户操作的默认起始目录，也可通过特定命令快速定位，方便管理个人文件（如文档、下载、配置文件）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不同系统的“homedir” 路径示例：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Linux/macOS&lt;/strong&gt;：路径通常为 &lt;code&gt;/home/用户名&lt;/code&gt;（如用户名为“user”，路径则为 &lt;code&gt;/home/user&lt;/code&gt;），终端中可通过 &lt;code&gt;~&lt;/code&gt;（波浪号）快速指代主目录，例如输入 &lt;code&gt;cd ~&lt;/code&gt; 即可切换到主目录。例句：In Linux, you can find your personal documents in &lt;code&gt;~/Documents&lt;/code&gt;—this path points to your homedir.（在Linux中，个人文档可在 &lt;code&gt;~/Documents&lt;/code&gt;中找到，该路径指向你的主目录。）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Windows&lt;/strong&gt;：路径通常为 &lt;code&gt;C:\Users\用户名&lt;/code&gt;（如用户名为“ZhangSan”，路径则为 &lt;code&gt;C:\Users\ZhangSan&lt;/code&gt;），命令提示符中可通过 &lt;code&gt;%USERPROFILE%&lt;/code&gt; 指代主目录。
例句：Windows stores user-specific settings in the homedir at &lt;code&gt;C:\Users\ZhangSan\AppData&lt;/code&gt;.（Windows将用户专属配置存储在 &lt;code&gt;C:\Users\ZhangSan\AppData&lt;/code&gt;这个主目录路径下。）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;2. 编程/脚本场景：调用主目录路径&lt;/h4&gt;
&lt;p&gt;在编写脚本（如Shell、Python）或配置程序时，需引用“homedir” 路径存储用户数据（如日志、缓存、自定义配置），避免硬编码路径导致兼容性问题。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;示例1（Shell脚本，获取并使用homedir）：&lt;pre&gt;&lt;code&gt;# 自动获取当前用户的主目录（homedir）
homedir=$(echo $HOME)
# 在主目录下创建一个名为“my_logs”的文件夹
mkdir -p $homedir/my_logs
echo &quot;Logs will be saved to $homedir/my_logs&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;示例2（Python，获取homedir）：&lt;pre&gt;&lt;code&gt;import os

# 通过os模块获取当前用户的主目录（跨系统兼容）
homedir = os.path.expanduser(&quot;~&quot;)
# 拼接主目录路径，创建文件路径
file_path = os.path.join(homedir, &quot;Documents&quot;, &quot;report.txt&quot;)
print(f&quot;File will be saved to: {file_path}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;3. 服务器/开发场景：管理用户权限&lt;/h4&gt;
&lt;p&gt;在服务器管理中，每个用户的“homedir” 拥有独立权限，仅该用户可读写自己主目录下的文件，保障数据安全，是多用户系统的基础配置。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;例句：When creating a new user on the server, the system automatically generates a homedir with read-write permissions only for that user.（在服务器上创建新用户时，系统会自动生成主目录，且仅该用户拥有读写权限。）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;“homedir” 发音为英式 /ˈhəʊmˌdɪr/、美式 /ˈhoʊmˌdɪr/，译音“侯姆迪尔”，核心是“计算机用户的专属‘主目录’，存储个人文件与配置”。它是系统操作、编程、服务器管理中的基础技术概念，掌握不同系统下的路径标识，能高效处理用户专属数据。&lt;/p&gt;
&lt;h1&gt;touch   发音：“踏（tà）驰（chí）”&lt;/h1&gt;
&lt;h1&gt;uname   发音：“优（yōu）内（nèi）木（mù）”&lt;/h1&gt;
&lt;h1&gt;clear   发音：“可（kě）利（lì）尔（ěr）”&lt;/h1&gt;
&lt;h1&gt;whoami   发音：“胡（hú）阿（ā）咪”&lt;/h1&gt;
&lt;h1&gt;reboot   发音：“瑞（ruì）布（bù）特（tè）”&lt;/h1&gt;
&lt;h1&gt;shutdown   发音：“杀 当”&lt;/h1&gt;
&lt;h1&gt;type        发音：泰 普&lt;/h1&gt;
&lt;h1&gt;history 发音：“黑思特瑞”&lt;/h1&gt;
&lt;h1&gt;hostnamectl【厚斯内姆 ctl】&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;hostnamectl
        音标：/ˈhoʊstneɪm/（美式）或 /ˈhəʊstneɪm/（英式）
        谐音：“厚斯内姆”（“厚” 发长音 /oʊ/ 或 /əʊ/，“内姆” 对应 “name” 的发音）。
        ctl：
        发音：/siː tiː ɛl/（逐个字母念，类似 “C-T-L”）。
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;“hostnamectl” 读音、译音及核心意义解析&lt;/h2&gt;
&lt;p&gt;“hostnamectl” 是Linux系统中基于&lt;code&gt;systemd&lt;/code&gt;的&lt;strong&gt;主机名管理命令行工具&lt;/strong&gt;，核心功能是&lt;strong&gt;查看和修改系统的主机名（包括静态、临时、友好名称等）&lt;/strong&gt;，支持永久生效且无需重启系统，替代了传统的&lt;code&gt;hostname&lt;/code&gt;命令（仅临时生效），是现代Linux发行版（如CentOS 7+、Ubuntu 16.04+）中主机名配置的核心工具。&lt;/p&gt;
&lt;h3&gt;一、标准读音&lt;/h3&gt;
&lt;p&gt;“hostnamectl” 由“hostname”（主机名）和“ctl”（“control”的缩写，控制）组合而成，技术领域通常拆分拼读，英美发音一致：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;国际音标&lt;/strong&gt;：/ˈhoʊstˌneɪm ˈkɒntrɒl/（“hostname”读/ˈhoʊstˌneɪm/，“ctl”取“control”核心音/ˈkɒntrɒl/）；&lt;br /&gt;
简化读法：技术沟通中常直接读“hostname ctl”（清晰简洁，便于快速理解）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;发音细节&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“hostname”：/ˈhoʊstˌneɪm/，“host”发“霍斯特”，“name”发“内姆”，连读为“霍斯特内姆”；&lt;/li&gt;
&lt;li&gt;“ctl”：取“control”前半部分，读为“克特”；&lt;/li&gt;
&lt;li&gt;整体连读：“霍斯特内姆-克特”（技术场景中直接拆分读更高效）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;二、中文译音&lt;/h3&gt;
&lt;p&gt;基于标准拼读，最贴合的谐音为：&lt;br /&gt;
&lt;strong&gt;“霍斯特内姆克特”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;简化记忆：&lt;strong&gt;“主机名控制工具”&lt;/strong&gt;（因核心功能是“管理系统主机名的命令行工具”，直接用功能代指，清晰易懂）。&lt;/p&gt;
&lt;h3&gt;三、核心意义与技术场景用法&lt;/h3&gt;
&lt;p&gt;“hostnamectl” 是&lt;code&gt;systemd&lt;/code&gt;体系中主机名管理的统一入口，用于&lt;strong&gt;配置和查看系统的三种主机名&lt;/strong&gt;，满足不同场景的标识需求，且修改默认永久生效（写入配置文件&lt;code&gt;/etc/hostname&lt;/code&gt;），无需重启系统。&lt;/p&gt;
&lt;h4&gt;1. 三种主机名类型（核心概念）&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;hostnamectl&lt;/code&gt; 管理的主机名分为三类，覆盖不同使用场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;静态主机名（static hostname）&lt;/strong&gt;：系统启动时从配置文件读取的永久主机名，用于系统内部和网络标识（如&lt;code&gt;server01&lt;/code&gt;、&lt;code&gt;web-node-01&lt;/code&gt;），默认保存在&lt;code&gt;/etc/hostname&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;临时主机名（transient hostname）&lt;/strong&gt;：临时生效的主机名，通常由DHCP或DNS服务器动态分配，优先级低于静态主机名（若静态主机名存在，临时主机名无效）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;友好主机名（pretty hostname）&lt;/strong&gt;：用户友好的名称（可包含空格、特殊字符，如“Web Server 01”），仅用于显示，不影响系统标识。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;2. 基本语法与常用命令&lt;/h4&gt;
&lt;p&gt;基本格式：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hostnamectl [选项/操作]  # 无操作时默认显示主机名状态
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;（1）查看主机名信息（最常用）&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;hostnamectl status  # 简写：hostnamectl（无参数时默认执行status）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出示例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;   Static hostname: server01
Transient hostname: web-server
         Icon name: computer-vm
           Chassis: vm
        Machine ID: 1234567890abcdef1234567890abcdef
           Boot ID: 0987654321fedcba0987654321fedcba
    Virtualization: kvm
  Operating System: CentOS Linux 7 (Core)
            Kernel: Linux 3.10.0-1160.el7.x86_64
      Architecture: x86-64
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;包含静态、临时、友好主机名（若设置）及系统基本信息。&lt;/p&gt;
&lt;h5&gt;（2）设置静态主机名（永久生效）&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;sudo hostnamectl set-hostname 新主机名  # 需root权限，默认设置静态主机名
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;示例：将静态主机名设置为&lt;code&gt;web01.example.com&lt;/code&gt;（建议使用FQDN，完全限定域名）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo hostnamectl set-hostname web01.example.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;设置后立即生效，且写入&lt;code&gt;/etc/hostname&lt;/code&gt;（重启后仍有效）。&lt;/p&gt;
&lt;h5&gt;（3）设置友好主机名（仅用于显示）&lt;/h5&gt;
&lt;p&gt;友好主机名可包含空格，需用引号包裹：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo hostnamectl set-hostname &quot;Production Web Server 01&quot; --pretty
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看效果：&lt;code&gt;hostnamectl&lt;/code&gt; 输出中会显示“Pretty hostname: Production Web Server 01”。&lt;/p&gt;
&lt;h5&gt;（4）设置临时主机名（临时生效，重启失效）&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;sudo hostnamectl set-hostname temp-server --transient
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;临时主机名通常用于临时测试，系统重启后会恢复为静态主机名。&lt;/p&gt;
&lt;h5&gt;（5）重置主机名（恢复默认）&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;sudo hostnamectl set-hostname &quot;&quot; --static  # 清空静态主机名（部分系统会自动生成默认名）
sudo hostnamectl set-hostname --pretty &quot;&quot;  # 清空友好主机名
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3. 关键注意事项（避坑指南）&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;权限要求&lt;/strong&gt;：修改主机名需&lt;code&gt;root&lt;/code&gt;权限（普通用户需加&lt;code&gt;sudo&lt;/code&gt;，如&lt;code&gt;sudo hostnamectl set-hostname ...&lt;/code&gt;）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生效范围&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;静态主机名修改后立即生效（无需重启），但依赖主机名的服务（如&lt;code&gt;sshd&lt;/code&gt;、&lt;code&gt;postfix&lt;/code&gt;）可能需要重启才能识别新主机名（如&lt;code&gt;sudo systemctl restart sshd&lt;/code&gt;）；&lt;/li&gt;
&lt;li&gt;临时主机名重启后失效，静态主机名永久生效（写入&lt;code&gt;/etc/hostname&lt;/code&gt;）；&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;命名规范&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;静态主机名建议使用小写字母、数字、减号（&lt;code&gt;-&lt;/code&gt;）和点（&lt;code&gt;.&lt;/code&gt;），避免空格和特殊字符（符合DNS规范，便于网络识别）；&lt;/li&gt;
&lt;li&gt;友好主机名无严格限制，可包含空格、大写字母（仅用于显示，不影响网络通信）；&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;与传统&lt;code&gt;hostname&lt;/code&gt;命令的区别&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;hostname 新名称&lt;/code&gt;：仅临时修改主机名（重启失效，等价于&lt;code&gt;hostnamectl set-hostname --transient&lt;/code&gt;）；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hostnamectl set-hostname&lt;/code&gt;：默认修改静态主机名（永久生效），功能更全面（支持三种类型）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;“hostnamectl” 读音为/ˈhoʊstˌneɪm ˈkɒntrɒl/，译音“霍斯特内姆克特”，核心是Linux中“基于systemd的主机名管理工具”，支持查看和修改静态、临时、友好三种主机名，静态修改永久生效且无需重启。掌握其用法是系统标识配置的基础，尤其适合服务器环境中规范主机名管理。&lt;/p&gt;
&lt;h1&gt;set-hostname【赛特-厚斯内姆】&lt;/h1&gt;
&lt;h1&gt;pretty   发音：普瑞替&lt;/h1&gt;
&lt;h1&gt;alias 读 诶利厄斯&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;分解记忆：
            “诶” → 对应 /eɪ/ 发音（类似字母 A 的发音）
            “利厄斯” → 连读 /liəs/（轻读 “利厄”，快速接 “斯”）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;location  【读音 漏 - K - 笋】&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;分解记忆：
            “漏 / 楼” → 对应开头的 “lo” 发音（英式 /ləʊ/ 类似 “漏”，美式 /loʊ/ 类似 “楼”）
            “凯” → 对应 “ca” 的发音 /keɪ/（类似 “凯”）
            “神” → 对应结尾 “tion” 的发音 /ʃn/（固定发 “神” 音，如 “action”“station”）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;listen      类-神&lt;/h1&gt;
&lt;h1&gt;rewrite     【率-来-特】&lt;/h1&gt;
&lt;h1&gt;regex    自然拼读拆分（re（重音）-gex）    中文谐音辅助（瑞（一声）杰克斯）&lt;/h1&gt;
&lt;h1&gt;replacement     自然拼读拆分（re - place（重音） - ment）     中文谐音辅助（瑞（一声）普雷斯（轻声）闷（轻声）特）&lt;/h1&gt;
&lt;h1&gt;flag       自然拼读拆分（fla（重音） - g）          中文谐音辅助（福（轻声）赖（一声）个（轻声））&lt;/h1&gt;
&lt;h1&gt;last      英式：la（重音） - st       辣（一声）斯特&lt;/h1&gt;
&lt;h1&gt;break     自然拼读拆分（brea（重音） - k）     中文谐音辅助（布（轻声）瑞（一声）克）&lt;/h1&gt;
&lt;h1&gt;redirect    瑞迪 瑞科特&lt;/h1&gt;
&lt;h1&gt;permanent    自然拼读：per·ma·nent (重音在 per)    中文谐音：珀·门·嫩特 (pò·men·nèn·tè) (注意：“嫩”轻读)&lt;/h1&gt;
&lt;h1&gt;server【涩·沃】&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt; 自然拼读：ser·ver (重音在 ser)      中文谐音：涩·沃 (sè·wò) (注意：&quot;沃&quot;轻读，类似&quot;我&quot;的轻声)
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;tomcat     美式：“汤姆 凯特”（“tom” 音更接近 “汤姆”，嘴型更开阔）。重音在第一音节（即 &quot;tom&quot; 部分），整体连读时注意中间无停顿&lt;/h1&gt;
&lt;h1&gt;parameters  “帕拉-米特兹”&lt;/h1&gt;
&lt;h1&gt;down  “淡”&lt;/h1&gt;
&lt;h1&gt;backup【拜克阿普】&lt;/h1&gt;
&lt;p&gt;“back” 发 /bæk/（类似 “拜克”）；“up” 发 /ʌp/（类似 “阿普”）；整体连读为 “拜克阿普”，注意重音在 “back”，“up” 轻读。&lt;/p&gt;
&lt;h1&gt;upstream     “啊普斯特瑞姆”&lt;/h1&gt;
&lt;h1&gt;weight   胃 特&lt;/h1&gt;
&lt;h1&gt;name  內 母&lt;/h1&gt;
&lt;h1&gt;parameters    音译：帕拉米特斯&lt;/h1&gt;
&lt;h1&gt;index      【因戴克斯】&lt;/h1&gt;
&lt;h2&gt;“index” 读音、译音及核心意义解析&lt;/h2&gt;
&lt;p&gt;“index” 是英语中多词性高频词（可作名词、动词），核心含义围绕“索引、指标”展开，日常中可表示“书籍索引、指数”，在技术领域（尤其是数据库、编程）特指“索引”（用于快速查询数据的结构），是跨场景高频词汇，含义随语境清晰区分。&lt;/p&gt;
&lt;h3&gt;一、标准读音&lt;/h3&gt;
&lt;p&gt;“index” 为双音节词，名词和动词发音重音位置不同，英美发音一致：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;名词发音&lt;/strong&gt;：/ˈɪndeks/（重音在第一音节）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;动词发音&lt;/strong&gt;：/ɪnˈdeks/（重音在第二音节）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;发音细节&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;第一音节“in”：
&lt;ul&gt;
&lt;li&gt;名词时：/ˈɪn/（重音），“i”发短元音/ɪ/“伊”，“n”发“恩”，读为“伊恩”；&lt;/li&gt;
&lt;li&gt;动词时：/ɪn/（轻读），发音同上但音调低；&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;第二音节“dex”：/deks/，“d”发“德”，“e”发/e/“诶”，“x”发/ks/“克丝”，读为“德诶克丝”；&lt;/li&gt;
&lt;li&gt;整体连读：
&lt;ul&gt;
&lt;li&gt;名词：“伊恩-德诶克丝”（重音在前，简化为“因戴克斯”）；&lt;/li&gt;
&lt;li&gt;动词：“伊恩-德诶克丝”（重音在后，读为“因戴克斯”，但重音位置不同）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;二、中文译音&lt;/h3&gt;
&lt;p&gt;基于标准发音，最贴合的谐音为：&lt;br /&gt;
&lt;strong&gt;“因戴克斯”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;简化记忆：&lt;strong&gt;“索引”&lt;/strong&gt;（因核心含义是“索引”，日常和技术场景中可直接用翻译词“索引”指代，精准且易理解）。&lt;br /&gt;
注：“index” 需结合场景翻译为“索引、指数、指标”等，译音仅辅助记忆原词发音。&lt;/p&gt;
&lt;h3&gt;三、核心意义与场景用法&lt;/h3&gt;
&lt;p&gt;“index” 核心是“表‘检索工具或衡量标准’的多词性词”，名词用法占主导，动词侧重“创建索引”，覆盖三类场景：&lt;/p&gt;
&lt;h4&gt;1. 日常/学术场景（名词）：“索引、目录；指数、指标”&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;含义1：索引（书籍/文档的检索工具）&lt;/strong&gt;&lt;br /&gt;
指书籍、文档中按字母或主题排列的检索目录，方便快速查找内容，常搭配“book index（书籍索引）、index page（索引页）”。&lt;br /&gt;
例句：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;index&lt;/strong&gt; at the end of the textbook lists all key terms and their page numbers.（教材末尾的索引列出了所有关键术语及页码。）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;含义2：指数、指标（衡量标准）&lt;/strong&gt;&lt;br /&gt;
指用于衡量变化的数值（如经济指数、温度指数），常搭配“stock index（股票指数）、inflation index（通胀指数）”。&lt;br /&gt;
例句：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The consumer price &lt;strong&gt;index&lt;/strong&gt; rose by 2% in the last quarter.（上季度居民消费价格指数上涨了2%。）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;2. 技术场景（核心用法，名词/动词）：“索引（数据检索结构）”&lt;/h4&gt;
&lt;p&gt;在数据库、编程、信息检索中，“index” 是&lt;strong&gt;用于快速定位数据的特殊数据结构&lt;/strong&gt;，通过预先排序和存储关键信息，避免全表扫描，大幅提升查询效率（类似书籍索引的作用）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;核心作用&lt;/strong&gt;：&lt;br /&gt;
解决“海量数据查询慢”的问题，例如在用户表的“username”字段上建索引后，查询“username=&apos;张三&apos;”时可直接定位到对应记录，无需逐行检查。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;示例1（数据库，创建索引）&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 为user表的username字段创建索引（加速按用户名查询）
CREATE INDEX idx_user_username ON user(username);

-- 查询时，数据库会使用索引快速定位，而非扫描全表
SELECT * FROM user WHERE username = &apos;张三&apos;;  -- 效率提升
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;示例2（索引类型，常见分类）&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主键索引&lt;/strong&gt;：主键字段自动创建（如&lt;code&gt;PRIMARY KEY&lt;/code&gt;），唯一且非空；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;普通索引&lt;/strong&gt;：可重复，如上述&lt;code&gt;idx_user_username&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;唯一索引&lt;/strong&gt;：值唯一（但可空），如&lt;code&gt;UNIQUE INDEX&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>AI工具组合方案</title><link>https://fuwari.vercel.app/posts/%E8%87%AA%E5%AA%92%E4%BD%93%E4%B8%8E%E5%B7%A5%E5%85%B7/ai%E5%B7%A5%E5%85%B7%E7%BB%84%E5%90%88%E6%96%B9%E6%A1%88/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E8%87%AA%E5%AA%92%E4%BD%93%E4%B8%8E%E5%B7%A5%E5%85%B7/ai%E5%B7%A5%E5%85%B7%E7%BB%84%E5%90%88%E6%96%B9%E6%A1%88/</guid><description>AI工具组合方案 - 运维知识库笔记</description><pubDate>Thu, 04 Jun 2026 04:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;AI工具组合方案&lt;/h1&gt;
&lt;p&gt;当然有！虽然&lt;strong&gt;完全无人值守的“全自动发布到今日头条”目前仍有平台限制&lt;/strong&gt;，但你可以通过 &lt;strong&gt;“多AI工具协同 + 轻量自动化”&lt;/strong&gt; 的方式，显著提升内容自然度、原创性，并大幅减少人工操作。&lt;/p&gt;
&lt;p&gt;以下是截至 &lt;strong&gt;2026年2月&lt;/strong&gt; 最适合普通人使用的 &lt;strong&gt;AI工具组合方案&lt;/strong&gt;，目标：&lt;strong&gt;让文章更像人写、更易爆、更省力&lt;/strong&gt;。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;🎯 核心策略：&lt;strong&gt;三段式流水线&lt;/strong&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;采集 → 深度改写/生成 → 人性化润色 → 半自动输出&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;阶段&lt;/th&gt;
&lt;th&gt;推荐工具&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1. 内容生成/采集&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;DeepSeek / 优彩云AI内容工厂&lt;/td&gt;
&lt;td&gt;快速产出初稿或采集热点素材&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2. 深度降AI味&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;秘塔写作猫 / 宙语AI / 火龙果写作&lt;/td&gt;
&lt;td&gt;去除机械感，增加口语化、情感&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;3. 自动化辅助&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Text Blaze（浏览器插件） / 腾讯云HiFlow（低代码）&lt;/td&gt;
&lt;td&gt;批量格式化、一键复制、定时提醒&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;✅ 一、让文章“更自然”的关键工具（重点推荐）&lt;/h2&gt;
&lt;h3&gt;1. &lt;strong&gt;秘塔写作猫（免费+专业）&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;核心功能&lt;/strong&gt;：AI润色、去AI痕迹、语气调整&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;为什么好用&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;可选“轻松口语”“职场正式”“小红书博主”等风格&lt;/li&gt;
&lt;li&gt;自动替换生硬句式（如“综上所述” → “说白了”）&lt;/li&gt;
&lt;li&gt;支持中英文语法纠错、逻辑优化&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;操作示例&lt;/strong&gt;：
&lt;blockquote&gt;
&lt;p&gt;把DeepSeek生成的文章粘贴进去 → 点【AI润色】→ 选择“生活化口语” → 导出&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;✅ &lt;strong&gt;效果&lt;/strong&gt;：AI浓度从70%降至30%以下，读起来像真人深夜发朋友圈。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;2. &lt;strong&gt;宙语AI中文写作助手（强推！）&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;独门功能&lt;/strong&gt;：&lt;strong&gt;“AI去味” + “降AIGC率”&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;特别针对 &lt;strong&gt;知网/头条算法&lt;/strong&gt; 优化，避免被识别为机器文&lt;/li&gt;
&lt;li&gt;内置300+场景模板（情感、职场、育儿、本地商家）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实测效果&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;输入一篇DeepSeek生成的《35岁该不该创业？》&lt;/li&gt;
&lt;li&gt;经宙语“去味”后，加入“我朋友去年就栽在这点上…”等细节&lt;/li&gt;
&lt;li&gt;阅读完成率提升40%&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;🔗 免费试用：&lt;a href=&quot;https://ailjyk.com/?channel=YAESNTNK&quot;&gt;https://ailjyk.com&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;3. &lt;strong&gt;火龙果写作（学术+生活兼顾）&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;强项：&lt;strong&gt;上下文连贯性修复&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;能自动补全逻辑断层（如突然跳话题）&lt;/li&gt;
&lt;li&gt;适合处理DeepSeek偶尔“跑偏”的段落&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;✅ 二、实现“接近自动”的效率工具&lt;/h2&gt;
&lt;h3&gt;1. &lt;strong&gt;Text Blaze（浏览器插件｜免费）&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作用&lt;/strong&gt;：一键格式化 + 批量插入固定内容&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;使用场景&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;设置快捷指令 &lt;code&gt;;tt&lt;/code&gt; → 自动输出：&lt;pre&gt;&lt;code&gt;【标题】{{你输入的标题}}
【导语】AI的回答让我沉默了...
【正文】（光标停留处）
【互动】你怎么看？评论区聊聊 👇
#DeepSeek #{{标签}}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;效果&lt;/strong&gt;：每篇文章节省2分钟排版时间，日省10分钟+&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;安装地址：&lt;a href=&quot;https://blaze.today&quot;&gt;https://blaze.today&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h3&gt;2. &lt;strong&gt;优彩云AI内容工厂（付费但值回票价）&lt;/strong&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;如果你愿意投入一点成本（约几百元/年），这是目前&lt;strong&gt;最接近“全自动内容工厂”的工具&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;它能做什么？&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🔍 全网采集热点&lt;/td&gt;
&lt;td&gt;自动抓取微博、知乎、头条高热话题&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🧠 深度原创系统&lt;/td&gt;
&lt;td&gt;基于多篇素材重组，相似度&amp;lt;25%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✍️ AI去AI味&lt;/td&gt;
&lt;td&gt;加入“个人感受”“设问”“反问”等人类表达&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🖼️ 自动配图&lt;/td&gt;
&lt;td&gt;AI生成图 or 下载合规图 + 加ALT标签（SEO友好）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⏰ 云端运行&lt;/td&gt;
&lt;td&gt;24小时自动生成，存入草稿库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📤 半自动发布&lt;/td&gt;
&lt;td&gt;支持对接WordPress、部分CMS，&lt;strong&gt;头条需手动粘贴&lt;/strong&gt;（因平台限制）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;重点&lt;/strong&gt;：它不能直接发头条，但能&lt;strong&gt;每天早上给你准备好5篇“可直接复制发布”的成品&lt;/strong&gt;，你只需登录APP点“粘贴-发布”。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;✅ 三、终极组合方案（推荐给想认真做的人）&lt;/h2&gt;
&lt;h3&gt;🌟 &lt;strong&gt;“三剑客”工作流&lt;/strong&gt;（成本低、效果强）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;graph LR
A[DeepSeek] --&amp;gt;|生成初稿| B(宙语AI)
B --&amp;gt;|去AI味+加情感| C{秘塔写作猫}
C --&amp;gt;|润色+校对| D[Text Blaze]
D --&amp;gt;|一键格式化| E[复制到头条APP发布]
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;操作流程：&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;用 DeepSeek 生成800字初稿（10秒）&lt;/li&gt;
&lt;li&gt;粘贴到 &lt;strong&gt;宙语AI&lt;/strong&gt;，点击“AI去味”，选择“生活感悟”风格（20秒）&lt;/li&gt;
&lt;li&gt;复制结果到 &lt;strong&gt;秘塔写作猫&lt;/strong&gt;，点“智能润色”（10秒）&lt;/li&gt;
&lt;li&gt;在 &lt;strong&gt;Text Blaze&lt;/strong&gt; 中按快捷键，自动加上标题/标签/互动语&lt;/li&gt;
&lt;li&gt;手动打开头条APP，粘贴发布（30秒）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;✅ &lt;strong&gt;总耗时 ≈ 1分10秒/篇&lt;/strong&gt;，质量远超纯DeepSeek输出。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;⚠️ 重要提醒：不要追求“100%自动”&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;今日头条、百家号等平台&lt;strong&gt;有意限制全自动发布&lt;/strong&gt;，防止垃圾内容。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;人工最后一步（点击发布）反而是安全阀&lt;/strong&gt;，能避免被判定为机器人。&lt;/li&gt;
&lt;li&gt;真正的竞争力不是“全自动”，而是 &lt;strong&gt;“一天能高质量产出5篇 vs 别人1篇”&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;💡 行动建议&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;今天就注册&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ailjyk.com&quot;&gt;宙语AI&lt;/a&gt;（免费试用）&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://xiezuocat.com&quot;&gt;秘塔写作猫&lt;/a&gt;（免费）&lt;/li&gt;
&lt;li&gt;安装 &lt;strong&gt;Text Blaze&lt;/strong&gt; 插件&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;明天测试&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用DeepSeek写一篇《人到中年，最该戒掉的3个习惯》&lt;/li&gt;
&lt;li&gt;依次过宙语 + 秘塔&lt;/li&gt;
&lt;li&gt;对比原始版和润色版，感受“人味”差异&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;后天开始批量生产&lt;/strong&gt;&lt;br /&gt;
—— 你的第一桶金，就藏在第5篇、第10篇、第20篇内容里。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;如果你告诉我你的内容方向（比如：情感 / 职场 / 本地商家 / 育儿），我可以为你：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;定制一套 &lt;strong&gt;专属提示词模板&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;提供 &lt;strong&gt;爆款标题库 + 开头结尾话术&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;设计 &lt;strong&gt;Text Blaze 快捷指令&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;只需一句话，我立刻为你准备好。&lt;/p&gt;
</content:encoded></item><item><title>01-Zabbix-Server-核心服务端-部署</title><link>https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/01-zabbix-server-%E6%A0%B8%E5%BF%83%E6%9C%8D%E5%8A%A1%E7%AB%AF-%E9%83%A8%E7%BD%B2/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/01-zabbix-server-%E6%A0%B8%E5%BF%83%E6%9C%8D%E5%8A%A1%E7%AB%AF-%E9%83%A8%E7%BD%B2/</guid><description>Zabbix 6.4 分布式企业级性能监控平台 - 运维知识库笔记</description><pubDate>Thu, 04 Jun 2026 03:21:00 GMT</pubDate><content:encoded>&lt;h1&gt;Zabbix 6.4 分布式企业级性能监控平台&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;Zabbix Server 核心服务端 部署
官网：https://www.zabbix.com/cn
     https://www.zabbix.com/cn/download?zabbix=7.2&amp;amp;os_distribution=rocky_linux&amp;amp;os_version=9&amp;amp;components=server_frontend_agent&amp;amp;db=mysql&amp;amp;ws=nginx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/117075162608236.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、Zabbix 功能简介&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;针对整个IT架构各个关键设备运行状态的实时监控与及时预警，是运维管理中的一个极其重要的工作环节，及时感知性能瓶颈与故障，本 身就是自动化运维工作的一个组成部分。

Zabbix 作为一个企业级的性能监控系统，可以采用多种方式来获取关键设备的运行状态数据，例如：网络设备状态、主机硬件状态、系统 运行状态、程序运行状态等等，因此得到了企业的广泛赞誉与生产应用。

Zabbix 功能十分强大，其分布式平台管理架构，无论是对于拥有少量服务器的中小型企业，还是拥有大量服务器的大型企业而言，在经过 适当的配置之后，均可在IT基础设施的性能监控方面发挥重要作用，世界上许多不同规模的组织都采用Zabbix作为主要的监控平台。

Zabbix 支持主动轮询和被动捕获的方式，来获取IT基础设施的性能状态数据，并可配置使用多种通知机制，来及时予以故障报警，从而有 助于运维工程师的快速响应并排查故障，Zabbix Web前端还为我们提供了出色的可视化数据展示与数据报告的功能。

Zabbix 遵循 GPL 通用公共许可证，作为一个开源软件项目，它的源代码可以免费分发、公共使用。

现在依据官方文档，将其功能特性介绍如下：
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/152508376031087.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/362399509898860.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/564386496415888.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/92282894499927.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/220013203308930.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/422024129938442.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/104201482790653.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;二、部署Zabbix Server 6.4 核心服务器&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;Zabbix 作为一个开源的分布式性能监控管理平台，在其管理架构中，主要分为&amp;lt;Zabbix Server 服务器&amp;gt;、&amp;lt;Zabbix Proxy 代理服务器&amp;gt;、&amp;lt;Zabbix 各类客户端&amp;gt; 这三种角色。

&amp;lt;Zabbix Server 服务器&amp;gt;是整个 Zabbix 性能监控管理平台的核心，本章将指导大家安装部署&amp;lt;Zabbix Server 6.4 核心服务器&amp;gt;。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1. 环境说明：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★ 本次部署，采用：松耦合方式，尽可能独立部署&amp;lt;Zabbix Server 服务器&amp;gt;的各个功能组件，从而方便我们在生产中予以集群化部署。
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;节点&lt;/th&gt;
&lt;th&gt;角色&lt;/th&gt;
&lt;th&gt;IP 地址&lt;/th&gt;
&lt;th&gt;操作系统：&lt;/th&gt;
&lt;th&gt;硬件规格&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-16&lt;/td&gt;
&lt;td&gt;MySQL 数据库(版本：8.0)&lt;/td&gt;
&lt;td&gt;192.168.168.16/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-17&lt;/td&gt;
&lt;td&gt;Nginx + PHP Web 前端&lt;/td&gt;
&lt;td&gt;192.168.168.17/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-18&lt;/td&gt;
&lt;td&gt;Zabbix Server 核心服务(版本：6.4)&lt;/td&gt;
&lt;td&gt;192.168.168.18/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;2. 安装部署：MySQL数据库&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;##
## 安装：MySQL 数据库，并创建&amp;lt;zabbix 用户数据库&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-16 ~]# dnf install -y mysql-server mysql
    [root@Rocky-9-16 ~]# systemctl enable mysqld
    [root@Rocky-9-16 ~]# systemctl restart mysqld
    [root@Rocky-9-16 ~]# mysqladmin -uroot password &apos;a123456!&apos;

    [root@Rocky-9-16 ~]# mysql -uroot -p&apos;a123456!&apos; &amp;lt;&amp;lt;EOF
    create database if not exists zabbix character set utf8mb4 collate utf8mb4_bin;
    create user if not exists root@&apos;%&apos; identified by &apos;a123456!&apos;;
    grant all privileges on *.* to root@&apos;%&apos;;
    create user if not exists zabbix@localhost identified by &apos;a123456!&apos;;
    grant all privileges on zabbix.* to zabbix@localhost;
    create user if not exists zabbix@&apos;%&apos; identified by &apos;a123456!&apos;;
    grant all privileges on zabbix.* to zabbix@&apos;%&apos;;
    set global log_bin_trust_function_creators = 1;     ## 在&amp;lt;zabbix 用户数据库&amp;gt;导入数据之前，允许：&amp;lt;非特权用户&amp;gt;创建&amp;lt;存储函数&amp;gt;
    EOF

    [root@Rocky-9-16 ~]# firewall-cmd --permanent --add-port=3306/tcp
    [root@Rocky-9-16 ~]# firewall-cmd --reload
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 安装部署：Nginx Web 前端&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;##
## (1) 禁用：&amp;lt;EPEL 源&amp;gt;中的&amp;lt;Zabbix 软件包&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-17 ~]# vi /etc/yum.repos.d/ustc_epel_9.repo     ## 这是：一个国内的 EPEL YUM 镜像源
    [epel]
    name=Extra Packages for Enterprise Linux $releasever - $basearch
    baseurl=https://mirrors.ustc.edu.cn/epel/$releasever//Everything/$basearch    #可以使用阿里云平替
    failovermethod=priority
    enabled=1
    gpgcheck=0
    excludepkgs=zabbix*
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (2) 获取：&amp;lt;Zabbix 软件包&amp;gt;的&amp;lt;repo 源配置文件&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-17 ~]# rpm -Uvh https://repo.zabbix.com/zabbix/6.0/rhel/9/x86_64/zabbix-release-6.0-4.el9.noarch.rpm
    [root@Rocky-9-17 ~]# yum clean all
    [root@Rocky-9-17 ~]# yum makecache
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (3) 安装：&amp;lt;Nginx Web 前端&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-17 ~]# dnf install -y zabbix-web-mysql zabbix-nginx-conf
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (4) 针对&amp;lt;Nginx Web 前端&amp;gt;配置：侦听端口、虚拟主机名称
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-17 ~]# vim /etc/nginx/conf.d/zabbix.conf
    ......
    listen 80;
    server_name zabbix.test.cn;
    root /usr/share/zabbix;
    index index.php;
    ......
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (5) 配置：&amp;lt;Nginx Web 前端&amp;gt;的&amp;lt;PHP 配置文件&amp;gt;，设置正确的&amp;lt;时区&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-17 ~]# vim /etc/php-fpm.d/zabbix.conf
    [zabbix]
    user = nginx
    group = nginx
    listen = /run/php-fpm/zabbix.sock
    listen.acl_users = apache,nginx
    listen.allowed_clients = 127.0.0.1
    ... ...
    php_value[date.timezone] = Asia/Shanghai
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (6) 授予：&amp;lt;nginx 用户&amp;gt;针对&amp;lt;/etc/zabbix/web 目录&amp;gt;具备&amp;lt;写入权限&amp;gt;，因为在&amp;lt;Web 安装向导&amp;gt;中，需要自定生成&amp;lt;配置文件&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-17 ~]# setfacl -m u:nginx:rwx /etc/zabbix/web/
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (7) 启动：Nginx 服务进程、php-fpm 服务进程
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-17 ~]# systemctl enable nginx php-fpm
    [root@Rocky-9-17 ~]# systemctl restart nginx php-fpm
    [root@Rocky-9-17 ~]# firewall-cmd --permanent --zone=public --add-port=80/tcp
    [root@Rocky-9-17 ~]# firewall-cmd --reload
    ## 禁用：SElinux
    if ! [[ $(getenforce) == &quot;Disabled&quot; ]]; then
        sed -r -i &apos;s/^\s*SELINUX=.*/SELINUX=disabled/&apos; /etc/selinux/config
        reboot
    fi
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (8) 添加：可视化的&amp;lt;中文字体&amp;gt;支持
##
##
## ① win+r 搜索：fonts，从而打开 Windows 的&amp;lt;Fonts 目录&amp;gt;
##
##
## ② 挑选：simfang.ttf 字体文件，并将其上传到 /usr/share/zabbix/assets/fonts 目录
##
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/153451298229797.webp&quot; alt=&quot;&quot; /&gt;
##
## ③ 挑选：simfang.ttf 字体文件，并将其上传到 /usr/share/zabbix/assets/fonts 目录
##
##
## ④ 修改：/usr/share/zabbix/include/defines.inc.php 配置文件
##&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-17 ~]# vim /usr/share/zabbix/include/defines.inc.php
    ......
    define(&apos;ZBX_GRAPH_FONT_NAME&apos;, &apos;simfang&apos;); // font file name
    ......
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. 安装部署：Zabbix Server 核心服务器&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;##
## (1) 禁用：EPEL 源中的 Zabbix
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-18 ~]# vim /etc/yum.repos.d/ustc_epel_9.repo         ## 这是：一个国内的 EPEL YUM 镜像源
    [epel]
    name=Extra Packages for Enterprise Linux $releasever - $basearch
    baseurl=https://mirrors.ustc.edu.cn/epel/$releasever//Everything/$basearch
    failovermethod=priority
    enabled=1
    gpgcheck=0
    excludepkgs=zabbix*
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (2) 获取：&amp;lt;Zabbix 软件包&amp;gt;的&amp;lt;repo 源配置文件&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-18 ~]# rpm -Uvh https://repo.zabbix.com/zabbix/6.0/rhel/9/x86_64/zabbix-release-6.0-4.el9.noarch.rpm
    [root@Rocky-9-18 ~]# yum clean all
    [root@Rocky-9-18 ~]# yum makecache
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (3) 安装：Zabbix Server 核心服务、Agent 客户端代理
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-18 ~]# dnf install -y zabbix-server-mysql zabbix-sql-scripts zabbix-selinux-policy zabbix-agent
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (4) 针对 MySQL 数据库，导入：初始架构和数据
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-18 ~]# dnf install -y mysql
    [root@Rocky-9-18 ~]# zcat /usr/share/zabbix-sql-scripts/mysql/server.sql.gz | \
    mysql --default-character-set=utf8mb4 -uzabbix -p&apos;a123456!&apos; -h 192.168.168.16 zabbix
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (5) 在导入数据库架构之后，针对 MySQL 数据库，禁用：log_bin_trust_function_creators 选项。
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-18 ~]# mysql -uroot -p&apos;a123456!&apos; -h 192.168.168.16 &amp;lt;&amp;lt;EOF
    set global log_bin_trust_function_creators = 0;     ## 在&amp;lt;zabbix 用户数据库&amp;gt;导入数据之后，禁止：&amp;lt;非特权用户&amp;gt;创建&amp;lt;存储函数&amp;gt;
    use zabbix;
    show tables;
    EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (6) 针对 Zabbix Server 核心服务，配置：数据库连接参数
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-18 ~]# vim /etc/zabbix/zabbix_server.conf
    ......
    DBHost=192.168.168.16
    DBName=zabbix
    DBUser=zabbix
    DBPassword=a123456!
    DBPort=3306
    ......
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-18 ~]# cat /etc/zabbix/zabbix_server.conf | grep -vE &quot;^\s*(#|$)&quot;
    LogFile=/var/log/zabbix/zabbix_server.log
    LogFileSize=0
    PidFile=/run/zabbix/zabbix_server.pid
    SocketDir=/run/zabbix
    DBHost=192.168.168.16
    DBName=zabbix
    DBUser=zabbix
    DBPassword=a123456!
    DBPort=3306
    SNMPTrapperFile=/var/log/snmptrap/snmptrap.log
    Timeout=4
    AlertScriptsPath=/usr/lib/zabbix/alertscripts
    ExternalScripts=/usr/lib/zabbix/externalscripts
    LogSlowQueries=3000
    StatsAllowedIP=127.0.0.1
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (7) 启动：Zabbix Server 服务进程、Agent 客户端代理
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-18 ~]# systemctl enable zabbix-server zabbix-agent
    [root@Rocky-9-18 ~]# systemctl restart zabbix-server zabbix-agent
    [root@Rocky-9-18 ~]# firewall-cmd --permanent --zone=public --add-port=10050/tcp ## 防火墙放行：&amp;lt;Zabbix Agent 客户端代理&amp;gt;的&amp;lt;侦听端口&amp;gt;
    [root@Rocky-9-18 ~]# firewall-cmd --permanent --zone=public --add-port=10051/tcp ## 防火墙放行：&amp;lt;Zabbix Server 核心服务&amp;gt;的&amp;lt;侦听端口&amp;gt;
    [root@Rocky-9-18 ~]# firewall-cmd --reload
    ## 禁用：SElinux
    if ! [[ $(getenforce) == &quot;Disabled&quot; ]]; then
        sed -r -i &apos;s/^\s*SELINUX=.*/SELINUX=disabled/&apos; /etc/selinux/config
        reboot
    fi
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5. 执行：Web安装向导&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;http://zabbix.test.cn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/354924548299296.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/84766054155080.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/223265327465385.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/364132982450443.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;##
## Web 登录：
##     管理员：Admin
##     默认口令：zabbix
##
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/461174778906400.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;##
## 在&amp;lt;Web 安装向导&amp;gt;执行完成之后，需编辑：&amp;lt;Nginx Web 前端&amp;gt;的&amp;lt;/etc/zabbix/web/zabbix.conf.php&amp;gt;
## 明确指定：$ZBX_SERVER = &apos;192.168.168.18&apos;; ## 这是：Zabbix Server 的 IP 地址
## $ZBX_SERVER_PORT = &apos;10051&apos;; ## 这是：Zabbix Server 的侦听端口
## 从而访问：分离式部署的&amp;lt;Zabbix Server 核心服务节点&amp;gt;
## 否则：将会默认访问&amp;lt;localhost&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    vi /etc/zabbix/web/zabbix.conf.php
    ......
    $ZBX_SERVER = &apos;192.168.168.18&apos;;
    $ZBX_SERVER_PORT = &apos;10051&apos;;
    $ZBX_SERVER_NAME = &apos;zabbix_server&apos;;
    ......
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## 刷新页面
##
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/576315912845520.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;##
## 修改：&amp;lt;Zabbix Web 前端&amp;gt;的&amp;lt;Admin 管理员密码&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/264054381463849.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;6. 查看日志：zabbix-server.log 日志&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;cat /var/log/zabbix/zabbix_server.log 
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;★ Zabbix -1-作业&lt;/h2&gt;
&lt;h3&gt;1. 采用松耦合的方式&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;采用松耦合的方式，来部署 Zabbix Server 核心服务、Nginx Web 前端、MySQL 数据库&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;[root@Rocky-9-16 ~]# dnf install -y mysql-server mysql
[root@Rocky-9-16 ~]# systemctl enable mysqld
Created symlink /etc/systemd/system/multi-user.target.wants/mysqld.service → /usr/lib/systemd/system/mysqld.service.
[root@Rocky-9-16 ~]# systemctl restart mysqld
[root@Rocky-9-16 ~]# ss -tunlp | grep mysql
tcp   LISTEN 0      70                 *:33060            *:*    users:((&quot;mysqld&quot;,pid=38456,fd=31))
tcp   LISTEN 0      151                *:3306             *:*    users:((&quot;mysqld&quot;,pid=38456,fd=33))

[root@Rocky-9-16 ~]# mysqladmin -uroot password &apos;a123456!&apos;
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@Rocky-9-16 ~]# mysql -uroot -p&quot;a123456!&quot; -e &quot;show databases;&quot;
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
=
[root@Rocky-9-16 ~]# mysql -uroot -p&apos;a123456!&apos; &amp;lt;&amp;lt;EOF
&amp;gt; create database if not exists zabbix character set utf8mb4 collate utf8mb4_bin;
&amp;gt; create user if not exists root@&apos;%&apos; identified by &apos;a123456!&apos;;
&amp;gt; grant all privileges on *.* to root@&apos;%&apos;;
&amp;gt; create user if not exists zabbix@localhost identified by &apos;a123456!&apos;;
&amp;gt; grant all privileges on zabbix.* to zabbix@localhost;
&amp;gt; create user if not exists zabbix@&apos;%&apos; identified by &apos;a123456!&apos;;
&amp;gt; grant all privileges on zabbix.* to zabbix@&apos;%&apos;;
&amp;gt; set global log_bin_trust_function_creators = 1;
&amp;gt; EOF
mysql: [Warning] Using a password on the command line interface can be insecure.

[root@Rocky-9-16 ~]# 
[root@Rocky-9-16 ~]# systemctl status firewalld.service 
○ firewalld.service - firewalld - dynamic firewall daemon
     Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; preset: enabled)
     Active: inactive (dead)
       Docs: man:firewalld(1)
[root@Rocky-9-16 ~]# 




[root@Rocky-9-17 ~]# vim /etc/yum.repos.d/ustc_epel_9.repo
[root@Rocky-9-17 ~]# cat /etc/yum.repos.d/ustc_epel_9.repo
[epel]
name=Extra Packages for Enterprise Linux $releasever - $basearch
baseurl=https://mirrors.aliyun.com/epel/$releasever//Everything/$basearch
failovermethod=priority
enabled=1
gpgcheck=0
excludepkgs=zabbix*

[root@Rocky-9-17 ~]# rpm -Uvh https://repo.zabbix.com/zabbix/6.0/rhel/9/x86_64/zabbix-release-6.0-4.el9.noarch.rpm
获取https://repo.zabbix.com/zabbix/6.0/rhel/9/x86_64/zabbix-release-6.0-4.el9.noarch.rpm
警告：/var/tmp/rpm-tmp.J9AvCl: 头V4 RSA/SHA512 Signature, 密钥 ID 08efa7dd: NOKEY
Verifying...                          ################################# [100%]
准备中...                          ################################# [100%]
正在升级/安装...
   1:zabbix-release-6.0-4.el9         ################################# [100%]
   
[root@Rocky-9-17 ~]# dnf clean all &amp;amp;&amp;amp; dnf makecache
33 个文件已删除
Rocky Linux 9 - BaseOS                                                                                                                                                       1.1 MB/s | 9.9 MB     00:09    
Rocky Linux 9 - AppStream                                                                                                                                                     39 kB/s |  14 MB     06:06    
Rocky Linux 9 - Extras                                                                                                                                                       140  B/s |  17 kB     02:02    
Extra Packages for Enterprise Linux 9 - x86_64                                                                                                                               2.4 MB/s |  20 MB     00:08    
Zabbix Official Repository - x86_64                                                                                                                                           72 kB/s | 566 kB     00:07    
Zabbix Official Repository (non-supported) - x86_64                                                                                                                          661  B/s | 1.1 kB     00:01    
Zabbix Official Repository (Agent2 Plugins) - x86_64                                                                                                                         102  B/s | 1.6 kB     00:16    
元数据缓存已建立。

[root@Rocky-9-17 ~]# 
[root@Rocky-9-17 ~]# dnf install -y zabbix-web-mysql zabbix-nginx-conf
[root@Rocky-9-17 ~]# vim /etc/nginx/conf.d/zabbix.conf
[root@Rocky-9-17 ~]# head -n9 /etc/nginx/conf.d/zabbix.conf | grep -vE &quot;^\s*(#|$)&quot;
server {
        listen          80;
        server_name     zabbix.test.cn;
        root    /usr/share/zabbix;
        index   index.php;
        location = /favicon.ico {
        
[root@Rocky-9-17 ~]# vim /etc/php-fpm.d/zabbix.conf
[root@Rocky-9-17 ~]# cat /etc/php-fpm.d/zabbix.conf | grep -E &quot;user|group|listen|date&quot;
user = nginx
group = nginx
listen = /run/php-fpm/zabbix.sock
listen.acl_users = apache,nginx
listen.allowed_clients = 127.0.0.1
php_value[date.timezone] = Asia/Shanghai

[root@Rocky-9-17 ~]# setfacl -m u:nginx:rwx /etc/zabbix/web/
[root@Rocky-9-17 ~]# ls -ald /etc/zabbix/web/
drwxrwxr-x+ 2 apache apache 33  2月  5 14:49 /etc/zabbix/web/

[root@Rocky-9-17 ~]# systemctl status firewalld.service 
○ firewalld.service - firewalld - dynamic firewall daemon
     Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; preset: enabled)
     Active: inactive (dead)
       Docs: man:firewalld(1)
       
[root@Rocky-9-17 ~]# getenforce
Disabled
[root@Rocky-9-17 ~]# cat /etc/selinux/config | grep SELINUX
# SELINUX= can take one of these three values:
# NOTE: Up to RHEL 8 release included, SELINUX=disabled would also
#SELINUX=enforcing
SELINUX=disabled
# SELINUXTYPE= can take one of these three values:
SELINUXTYPE=targeted

[root@Rocky-9-17 ~]# 
[root@Rocky-9-17 ~]# systemctl enable nginx php-fpm --now
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
Created symlink /etc/systemd/system/multi-user.target.wants/php-fpm.service → /usr/lib/systemd/system/php-fpm.service.
[root@Rocky-9-17 ~]# ss -tunlp
Netid  State   Recv-Q  Send-Q   Local Address:Port   Peer Address:Port Process                                                                                                                               
udp    UNCONN  0       0            127.0.0.1:323         0.0.0.0:*     users:((&quot;chronyd&quot;,pid=763,fd=5))                                                                                                     
udp    UNCONN  0       0                [::1]:323            [::]:*     users:((&quot;chronyd&quot;,pid=763,fd=6))                                                                                                     
tcp    LISTEN  0       511            0.0.0.0:80          0.0.0.0:*     users:((&quot;nginx&quot;,pid=39202,fd=6),(&quot;nginx&quot;,pid=39201,fd=6),(&quot;nginx&quot;,pid=39200,fd=6),(&quot;nginx&quot;,pid=39199,fd=6),(&quot;nginx&quot;,pid=39198,fd=6)) 
tcp    LISTEN  0       128            0.0.0.0:22          0.0.0.0:*     users:((&quot;sshd&quot;,pid=783,fd=3))                                                                                                        
tcp    LISTEN  0       511               [::]:80             [::]:*     users:((&quot;nginx&quot;,pid=39202,fd=7),(&quot;nginx&quot;,pid=39201,fd=7),(&quot;nginx&quot;,pid=39200,fd=7),(&quot;nginx&quot;,pid=39199,fd=7),(&quot;nginx&quot;,pid=39198,fd=7)) 
tcp    LISTEN  0       128               [::]:22             [::]:*     users:((&quot;sshd&quot;,pid=783,fd=4))                                                                                                        

[root@Rocky-9-17 ~]# systemctl status nginx.service php-fpm.service 
● nginx.service - The nginx HTTP and reverse proxy server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: disabled)
    Drop-In: /usr/lib/systemd/system/nginx.service.d
             └─php-fpm.conf
     Active: active (running) since Thu 2026-02-05 15:04:15 CST; 42s ago
    Process: 39194 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
    Process: 39196 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
    Process: 39197 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
   Main PID: 39198 (nginx)
      Tasks: 5 (limit: 4178)
     Memory: 4.7M (peak: 5.0M)
        CPU: 42ms
     CGroup: /system.slice/nginx.service
             ├─39198 &quot;nginx: master process /usr/sbin/nginx&quot;
             ├─39199 &quot;nginx: worker process&quot;
             ├─39200 &quot;nginx: worker process&quot;
             ├─39201 &quot;nginx: worker process&quot;
             └─39202 &quot;nginx: worker process&quot;

2月 05 15:04:15 Rocky-9-17 systemd[1]: Starting The nginx HTTP and reverse proxy server...
2月 05 15:04:15 Rocky-9-17 nginx[39196]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
2月 05 15:04:15 Rocky-9-17 nginx[39196]: nginx: configuration file /etc/nginx/nginx.conf test is successful
2月 05 15:04:15 Rocky-9-17 systemd[1]: Started The nginx HTTP and reverse proxy server.

● php-fpm.service - The PHP FastCGI Process Manager
     Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; enabled; preset: disabled)
     Active: active (running) since Thu 2026-02-05 15:04:15 CST; 42s ago
   Main PID: 39195 (php-fpm)
     Status: &quot;Processes active: 0, idle: 10, Requests: 0, slow: 0, Traffic: 0req/sec&quot;
      Tasks: 11 (limit: 4178)
     Memory: 18.5M (peak: 19.0M)
        CPU: 95ms
     CGroup: /system.slice/php-fpm.service
             ├─39195 &quot;php-fpm: master process (/etc/php-fpm.conf)&quot;
             ├─39203 &quot;php-fpm: pool www&quot;
             ├─39204 &quot;php-fpm: pool www&quot;
             ├─39205 &quot;php-fpm: pool www&quot;
             ├─39206 &quot;php-fpm: pool www&quot;
             ├─39207 &quot;php-fpm: pool www&quot;
             ├─39208 &quot;php-fpm: pool zabbix&quot;
             ├─39209 &quot;php-fpm: pool zabbix&quot;
             ├─39210 &quot;php-fpm: pool zabbix&quot;
             ├─39211 &quot;php-fpm: pool zabbix&quot;
             └─39212 &quot;php-fpm: pool zabbix&quot;

2月 05 15:04:15 Rocky-9-17 systemd[1]: Starting The PHP FastCGI Process Manager...
2月 05 15:04:15 Rocky-9-17 systemd[1]: Started The PHP FastCGI Process Manager.
[root@Rocky-9-17 ~]# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/456615177594359.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@Rocky-9-17 ~]# chmod 777 simfang.ttf 
[root@Rocky-9-17 ~]# mv simfang.ttf /usr/share/zabbix/assets/fonts/
[root@Rocky-9-17 ~]# vim +88 /usr/share/zabbix/include/defines.inc.php
[root@Rocky-9-17 ~]# grep -n ZBX_GRAPH_FONT_NAME /usr/share/zabbix/include/defines.inc.php
88://define(&apos;ZBX_GRAPH_FONT_NAME&apos;,              &apos;graphfont&apos;); // font file name
89:define(&apos;ZBX_GRAPH_FONT_NAME&apos;,                &apos;simfang&apos;); // font file name
[root@Rocky-9-17 ~]# systemctl restart nginx.service php-fpm.service 




[root@Rocky-9-18 ~]# vim /etc/yum.repos.d/ustc_epel_9.repo
[root@Rocky-9-18 ~]# cat /etc/yum.repos.d/ustc_epel_9.repo
[epel]
name=Extra Packages for Enterprise Linux $releasever - $basearch
baseurl=https://mirrors.aliyun.com/epel/$releasever//Everything/$basearch
failovermethod=priority
enabled=1
gpgcheck=0
excludepkgs=zabbix*

[root@Rocky-9-18 ~]# rpm -Uvh https://repo.zabbix.com/zabbix/6.0/rhel/9/x86_64/zabbix-release-6.0-4.el9.noarch.rpm
获取https://repo.zabbix.com/zabbix/6.0/rhel/9/x86_64/zabbix-release-6.0-4.el9.noarch.rpm
警告：/var/tmp/rpm-tmp.hosafe: 头V4 RSA/SHA512 Signature, 密钥 ID 08efa7dd: NOKEY
Verifying...                          ################################# [100%]
准备中...                          ################################# [100%]
正在升级/安装...
   1:zabbix-release-6.0-4.el9         ################################# [100%]
   
[root@Rocky-9-18 ~]# dnf clean all &amp;amp;&amp;amp; dnf makecache
25 个文件已删除
Rocky Linux 9 - BaseOS                                                                                                                                                        98 kB/s | 9.9 MB     01:43    
Rocky Linux 9 - AppStream                                                                                                                                                    904 kB/s |  14 MB     00:15    
Rocky Linux 9 - Extras                                                                                                                                                       493  B/s |  17 kB     00:34    
Extra Packages for Enterprise Linux 9 - x86_64                                                                                                                               2.3 MB/s |  20 MB     00:08    
元数据缓存已建立。

[root@Rocky-9-18 ~]# 
[root@Rocky-9-18 ~]# dnf install -y zabbix-server-mysql zabbix-sql-scripts zabbix-selinux-policy zabbix-agent
上次元数据过期检查：0:37:19 前，执行于 2026年02月05日 星期四 15时03分56秒。
软件包 zabbix-server-mysql-6.0.43-release1.el9.x86_64 已安装。
软件包 zabbix-sql-scripts-6.0.43-release1.el9.noarch 已安装。
软件包 zabbix-selinux-policy-6.0.43-release1.el9.x86_64 已安装。
软件包 zabbix-agent-6.0.43-release1.el9.x86_64 已安装。
依赖关系解决。
无需任何处理。
完毕！

[root@Rocky-9-18 ~]# dnf install -y mysql
上次元数据过期检查：0:18:47 前，执行于 2026年02月05日 星期四 15时48分37秒。
软件包 mysql-8.0.44-1.el9_7.x86_64 已安装。
依赖关系解决。
无需任何处理。
完毕！

[root@Rocky-9-18 ~]# #初始架构和数据
[root@Rocky-9-18 ~]# zcat /usr/share/zabbix-sql-scripts/mysql/server.sql.gz | mysql --default-character-set=utf8mb4 -uzabbix -p&apos;a123456!&apos; -h 192.168.88.11 zabbix
mysql: [Warning] Using a password on the command line interface can be insecure.

[root@Rocky-9-18 ~]# #禁用：log_bin_trust_function_creators 选项。
[root@Rocky-9-18 ~]# 
[root@Rocky-9-18 ~]# mysql -uroot -p&apos;a123456!&apos; -h 192.168.88.11 &amp;lt;&amp;lt;EOF
&amp;gt; set global log_bin_trust_function_creators = 0;
&amp;gt; use zabbix;
&amp;gt; show tables;
&amp;gt; EOF
mysql: [Warning] Using a password on the command line interface can be insecure.
Tables_in_zabbix
acknowledges
actions
alerts
auditlog
......
widget
widget_field

[root@Rocky-9-18 ~]# #配置：数据库连接参数
[root@Rocky-9-18 ~]# 
[root@Rocky-9-18 ~]# vim /etc/zabbix/zabbix_server.conf
[root@Rocky-9-18 ~]# cat /etc/zabbix/zabbix_server.conf | grep -vE &quot;^\s*(#|$)&quot;
LogFile=/var/log/zabbix/zabbix_server.log
LogFileSize=0
PidFile=/run/zabbix/zabbix_server.pid
SocketDir=/run/zabbix
DBHost=192.168.88.11
DBName=zabbix
DBUser=zabbix
DBPassword=a123456!
DBPort=3306
SNMPTrapperFile=/var/log/snmptrap/snmptrap.log
Timeout=4
AlertScriptsPath=/usr/lib/zabbix/alertscripts
ExternalScripts=/usr/lib/zabbix/externalscripts
LogSlowQueries=3000
StatsAllowedIP=127.0.0.1
[root@Rocky-9-18 ~]# 
[root@Rocky-9-18 ~]# systemctl enable zabbix-server zabbix-agent
Created symlink /etc/systemd/system/multi-user.target.wants/zabbix-server.service → /usr/lib/systemd/system/zabbix-server.service.
Created symlink /etc/systemd/system/multi-user.target.wants/zabbix-agent.service → /usr/lib/systemd/system/zabbix-agent.service.
[root@Rocky-9-18 ~]# systemctl restart zabbix-server zabbix-agent
[root@Rocky-9-18 ~]# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/128024819948305.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/84322255543585.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/336951862522659.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/375122183540381.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/105561975788870.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/282642762743873.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/4234503252953.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@Rocky-9-17 ~]# vim /etc/zabbix/web/zabbix.conf.php
[root@Rocky-9-17 ~]# grep ZBX_SE /etc/zabbix/web/zabbix.conf.php 
// $ZBX_SERVER                  = &apos;&apos;;
// $ZBX_SERVER_PORT             = &apos;&apos;;
$ZBX_SERVER                     = &apos;192.168.88.13&apos;;
$ZBX_SERVER_PORT                = &apos;10051&apos;;
$ZBX_SERVER_NAME                = &apos;Zabbix_Server&apos;;
[root@Rocky-9-17 ~]# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 采用紧耦合的方式&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;采用紧耦合的方式，来部署 Zabbix Server 核心服务、Nginx Web 前端、MySQL 数据库&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;[root@zabbix ~]# systemctl status firewalld.service 
○ firewalld.service - firewalld - dynamic firewall daemon
     Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; preset: enabled)
     Active: inactive (dead)
       Docs: man:firewalld(1)
       
[root@zabbix ~]# getenforce 
Disabled
[root@zabbix ~]# cat /etc/selinux/config | grep SELINUX
# SELINUX= can take one of these three values:
# NOTE: Up to RHEL 8 release included, SELINUX=disabled would also
#SELINUX=enforcing
SELINUX=disabled
# SELINUXTYPE= can take one of these three values:
SELINUXTYPE=targeted

[root@zabbix ~]# vim /etc/yum.repos.d/ustc_epel_9.repo
[root@zabbix ~]# cat /etc/yum.repos.d/ustc_epel_9.repo
[epel]
name=Extra Packages for Enterprise Linux $releasever - $basearch
baseurl=https://mirrors.aliyun.com/epel/$releasever//Everything/$basearch
failovermethod=priority
enabled=1
gpgcheck=0
excludepkgs=zabbix*
   
[root@Rocky-9-17 ~]# dnf clean all &amp;amp;&amp;amp; dnf makecache
33 个文件已删除
Rocky Linux 9 - BaseOS                                                                                                                                                       1.1 MB/s | 9.9 MB     00:09    
Rocky Linux 9 - AppStream                                                                                                                                                     39 kB/s |  14 MB     06:06    
Rocky Linux 9 - Extras                                                                                                                                                       140  B/s |  17 kB     02:02    
Extra Packages for Enterprise Linux 9 - x86_64                                                                                                                               2.4 MB/s |  20 MB     00:08    
Zabbix Official Repository - x86_64                                                                                                                                           72 kB/s | 566 kB     00:07    
Zabbix Official Repository (non-supported) - x86_64                                                                                                                          661  B/s | 1.1 kB     00:01    
Zabbix Official Repository (Agent2 Plugins) - x86_64                                                                                                                         102  B/s | 1.6 kB     00:16    
元数据缓存已建立。

#[root@zabbix ~]# rpm -Uvh https://repo.zabbix.com/zabbix/6.0/rhel/8/x86_64/zabbix-release-6.0-4.el8.noarch.rpm     //适配 Rocky 8 的 Zabbix 6.0 源
[root@zabbix ~]# rpm -Uvh https://repo.zabbix.com/zabbix/6.0/rhel/9/x86_64/zabbix-release-6.0-4.el9.noarch.rpm     //适配 Rocky 9 的 Zabbix 6.0 源
获取https://repo.zabbix.com/zabbix/6.0/rhel/9/x86_64/zabbix-release-6.0-4.el9.noarch.rpm
警告：/var/tmp/rpm-tmp.jiGmYA: 头V4 RSA/SHA512 Signature, 密钥 ID 08efa7dd: NOKEY
Verifying...                          ################################# [100%]
准备中...                          ################################# [100%]
正在升级/安装...
   1:zabbix-release-6.0-4.el9         ################################# [100%]
   
[root@zabbix ~]# dnf install -y mysql-server mysql
Rocky Linux 9 - BaseOS                                                                                                                                                        94  B/s | 4.3 kB     00:46    
Rocky Linux 9 - AppStream                                                                                                                                                    106  B/s | 4.8 kB     00:46    
Rocky Linux 9 - Extras                                                                                                                                                        68  B/s | 3.1 kB     00:46    
依赖关系解决。
=====================================
已安装:
  mariadb-connector-c-config-3.2.6-1.el9_0.noarch    mecab-0.996-3.el9.4.x86_64            mysql-8.0.44-1.el9_7.x86_64           mysql-common-8.0.44-1.el9_7.x86_64    mysql-errmsg-8.0.44-1.el9_7.x86_64   
  mysql-selinux-1.0.14-1.el9_6.noarch                mysql-server-8.0.44-1.el9_7.x86_64    protobuf-lite-3.14.0-16.el9.x86_64   

完毕！

[root@zabbix ~]# systemctl enable mysqld --now
Created symlink /etc/systemd/system/multi-user.target.wants/mysqld.service → /usr/lib/systemd/system/mysqld.service.

[root@zabbix ~]# ss -tunlp | grep mysql
tcp   LISTEN 0      151                *:3306             *:*    users:((&quot;mysqld&quot;,pid=31681,fd=33))
tcp   LISTEN 0      70                 *:33060            *:*    users:((&quot;mysqld&quot;,pid=31681,fd=31))

[root@zabbix ~]# mysqladmin -uroot password &apos;a123456!&apos;
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@zabbix ~]# mysql -uroot -p&quot;a123456!&quot; -e &quot;show databases;&quot;
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

[root@zabbix ~]# mysql -uroot -p&apos;a123456!&apos; &amp;lt;&amp;lt;EOF
&amp;gt; create database if not exists zabbix character set utf8mb4 collate utf8mb4_bin;
&amp;gt; create user if not exists root@&apos;%&apos; identified by &apos;a123456!&apos;;
&amp;gt; grant all privileges on *.* to root@&apos;%&apos;;
&amp;gt; create user if not exists zabbix@localhost identified by &apos;a123456!&apos;;
&amp;gt; grant all privileges on zabbix.* to zabbix@localhost;
&amp;gt; create user if not exists zabbix@&apos;%&apos; identified by &apos;a123456!&apos;;
&amp;gt; grant all privileges on zabbix.* to zabbix@&apos;%&apos;;
&amp;gt; set global log_bin_trust_function_creators = 1;
&amp;gt; EOF


[root@zabbix ~]# dnf install -y zabbix-web-mysql zabbix-nginx-conf
上次元数据过期检查：0:00:39 前，执行于 2026年02月06日 星期五 09时31分03秒。
依赖关系解决。
====================================
完毕！


[root@zabbix ~]# vim /etc/nginx/conf.d/zabbix.conf
[root@zabbix ~]# head -n9 /etc/nginx/conf.d/zabbix.conf | grep -vnE &quot;^\s*(#|$)&quot;
1:server {
2:        listen          80;
3:        server_name     zabbix.test.cn;
5:        root    /usr/share/zabbix;
7:        index   index.php;
9:        location = /favicon.ico {

[root@zabbix ~]# vim /etc/php-fpm.d/zabbix.conf
[root@zabbix ~]# cat /etc/php-fpm.d/zabbix.conf | grep -nE &quot;user|group|listen|date&quot;
2:user = nginx
3:group = nginx
5:listen = /run/php-fpm/zabbix.sock
6:listen.acl_users = apache,nginx
7:listen.allowed_clients = 127.0.0.1
25:php_value[date.timezone] = Asia/Shanghai

[root@zabbix ~]# setfacl -m u:nginx:rwx /etc/zabbix/web/
[root@zabbix ~]# ls -ald /etc/zabbix/web/
drwxrwxr-x+ 2 apache apache 33  2月  6 09:32 /etc/zabbix/web/
[root@zabbix ~]# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/456615177594359.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@zabbix ~]# chmod 777 simfang.ttf 
[root@zabbix ~]# cp simfang.ttf /usr/share/zabbix/assets/fonts/
[root@zabbix ~]# vim +88 /usr/share/zabbix/include/defines.inc.php
[root@zabbix ~]# grep -n ZBX_GRAPH_FONT_NAME /usr/share/zabbix/include/defines.inc.php
88://define(&apos;ZBX_GRAPH_FONT_NAME&apos;,              &apos;graphfont&apos;); // font file name
89:define(&apos;ZBX_GRAPH_FONT_NAME&apos;,                &apos;simfang&apos;); // font file name

[root@zabbix ~]# systemctl enable nginx php-fpm --now
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
Created symlink /etc/systemd/system/multi-user.target.wants/php-fpm.service → /usr/lib/systemd/system/php-fpm.service.

[root@zabbix ~]# systemctl status nginx.service php-fpm.service 
● nginx.service - The nginx HTTP and reverse proxy server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: disabled)
    Drop-In: /usr/lib/systemd/system/nginx.service.d
             └─php-fpm.conf
        ................
        

[root@zabbix ~]# 
[root@zabbix ~]# dnf install -y zabbix-server-mysql zabbix-sql-scripts zabbix-selinux-policy zabbix-agent
上次元数据过期检查：0:14:19 前，执行于 2026年02月06日 星期五 09时31分03秒。
依赖关系解决。
==========================
   ................
  zabbix-sql-scripts-6.0.43-release1.el9.noarch     
完毕！


[root@zabbix ~]# zcat /usr/share/zabbix-sql-scripts/mysql/server.sql.gz | mysql --default-character-set=utf8mb4 -uzabbix -p&apos;a123456!&apos; zabbix
mysql: [Warning] Using a password on the command line interface can be insecure.

[root@zabbix ~]# mysql -uroot -p&apos;a123456!&apos; &amp;lt;&amp;lt;EOF
&amp;gt; set global log_bin_trust_function_creators = 0;
&amp;gt; use zabbix;
&amp;gt; show tables;
&amp;gt; EOF

................
widget_field

[root@zabbix ~]# 
[root@zabbix ~]# vim /etc/zabbix/zabbix_server.conf
[root@zabbix ~]# cat /etc/zabbix/zabbix_server.conf | grep -vnE &quot;^\s*(#|$)&quot;
38:LogFile=/var/log/zabbix/zabbix_server.log
49:LogFileSize=0
72:PidFile=/run/zabbix/zabbix_server.pid
82:SocketDir=/run/zabbix
93:DBHost=localhost
105:DBName=zabbix
121:DBUser=zabbix
129:DBPassword=a123456!
146:DBPort=3306
391:SNMPTrapperFile=/var/log/snmptrap/snmptrap.log
515:Timeout=4
556:AlertScriptsPath=/usr/lib/zabbix/alertscripts
565:ExternalScripts=/usr/lib/zabbix/externalscripts
601:LogSlowQueries=3000
716:StatsAllowedIP=127.0.0.1

[root@zabbix ~]# systemctl enable zabbix-server zabbix-agent --now
Created symlink /etc/systemd/system/multi-user.target.wants/zabbix-server.service → /usr/lib/systemd/system/zabbix-server.service.
Created symlink /etc/systemd/system/multi-user.target.wants/zabbix-agent.service → /usr/lib/systemd/system/zabbix-agent.service.

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/27176844070854.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/531036474983926.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/133465669510321.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/567458117176240.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/50359350323026.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/119628095323178.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/182396040242802.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/241557423878795.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;紧耦合Zabbix_Server安装脚本&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash
# Zabbix 6.0 最终完美版 | Rocky Linux 9
# 已严格匹配你的所有配置：EPEL、MySQL、Nginx、PHP、Zabbix Server

# ===================== 固定配置 =====================
DB_PASSWORD=&quot;a123456!&quot;
ZABBIX_DB=&quot;zabbix&quot;
ZABBIX_USER=&quot;zabbix&quot;
TIMEZONE=&quot;Asia/Shanghai&quot;
# ======================================================

echo -e &quot;\n===== 1. 关闭防火墙 =====&quot;
# 停止防火墙
if systemctl stop firewalld  ; then
    echo &quot;✅ 防火墙 停止成功&quot;
else
    echo &quot;⚠️ 防火墙 未运行或停止失败&quot;
fi

# 禁用开机自启
if systemctl disable firewalld  ; then
    echo &quot;✅ 防火墙 开机自启 已禁用&quot;
else
    echo &quot;⚠️ 防火墙 开机自启 禁用失败/已禁用&quot;
fi


# ======================================================
echo -e &quot;\n===== 2. 关闭 SELinux =====&quot;
# 永久修改配置文件
sed -i &apos;s/^SELINUX=.*/SELINUX=disabled/&apos; /etc/selinux/config
if grep -q &quot;SELINUX=disabled&quot; /etc/selinux/config; then
    echo &quot;✅ SELinux 配置已永久禁用（重启生效）&quot;
else
    echo &quot;❌ SELinux 配置修改失败&quot;
fi

# 临时关闭（当前会话）+ 不退出脚本
setenforce 0 &amp;gt; /dev/null 2&amp;gt;&amp;amp;1
if [ $? -eq 0 ]; then
    echo &quot;✅ SELinux 临时关闭成功&quot;
else
    echo &quot;⚠️ SELinux 已关闭，无需重复操作&quot;
fi


# ======================================================
echo -e &quot;\n===== 3. 配置阿里云 EPEL 源 =====&quot;
# 写入 repo 文件
cat &amp;gt; /etc/yum.repos.d/ustc_epel_9.repo &amp;lt;&amp;lt;EOF
[epel]
name=Extra Packages for Enterprise Linux \$releasever - \$basearch
baseurl=https://mirrors.aliyun.com/epel/\$releasever//Everything/\$basearch
failovermethod=priority
enabled=1
gpgcheck=0
excludepkgs=zabbix*
EOF

# 检测文件是否创建成功
if [ -f /etc/yum.repos.d/ustc_epel_9.repo ]; then
    echo &quot;✅ EPEL 源文件创建成功&quot;
else
    echo &quot;❌ EPEL 源文件创建失败&quot;
fi


# ======================================================
echo -e &quot;\n===== 4. 安装 Zabbix 官方源 =====&quot;
# 安装 Zabbix 源（静默安装 + 失败忽略）
rpm -Uvh https://repo.zabbix.com/zabbix/6.0/rhel/9/x86_64/zabbix-release-6.0-4.el9.noarch.rpm --nosignature

# 检测是否安装成功
if rpm -q zabbix-release  ; then
    echo &quot;✅ Zabbix 官方源 安装成功&quot;
else
    echo &quot;⚠️ Zabbix 官方源 已安装或安装失败&quot;
fi


# ======================================================
echo -e &quot;\n===== 5. 重建缓存 =====&quot;

# 自动检测并杀死 DNF/YUM 锁进程
echo &quot;🔍 检测是否有 DNF/YUM 进程占用...&quot;
for pid in $(ps -ef | grep -E &quot;dnf|yum&quot; | grep -v grep | awk &apos;{print $2}&apos;); do
    kill -9 $pid &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 &amp;amp;&amp;amp; echo &quot;✅ 已强制结束占用进程 PID: $pid&quot;
done

# 强制删除 yum/dnf 锁文件（最关键！）
rm -f /var/run/yum.pid /var/run/dnf.pid /var/lib/dnf/rpm.lock
rm -f /var/lib/rpm/.rpm.lock

# 清理并重建缓存（静默执行）
dnf clean all &amp;amp;&amp;amp; dnf makecache -y

# 检测是否成功
if [ $? -eq 0 ]; then
    echo &quot;✅ 缓存重建成功&quot;
else
    echo &quot;❌ 缓存重建失败&quot;
fi
# ======================================================
echo -e &quot;\n===== 6. 安装 MySQL =====&quot;

# 安装 MySQL（静默安装）
dnf install -y mysql-server mysql  

# 检测安装是否成功
if [ $? -eq 0 ]; then
    echo &quot;✅ MySQL 安装成功&quot;
else
    echo &quot;❌ MySQL 安装失败&quot;
    exit 1
fi

# 启动并开机自启
systemctl enable mysqld --now  

# 检测服务状态
if systemctl is-active --quiet mysqld; then
    echo &quot;✅ MySQL 服务已启动并开机自启&quot;
else
    echo &quot;❌ MySQL 服务启动失败&quot;
fi


# ======================================================
echo -e &quot;\n===== 7. 设置 MySQL 密码 =====&quot;

# 尝试设置密码（兼容已设置过的情况）
mysqladmin -uroot password &quot;$DB_PASSWORD&quot; 2&amp;gt;/dev/null || true

# 检测是否能正常登录（验证密码有效性）
if mysql -uroot -p&quot;$DB_PASSWORD&quot; -e &quot;SELECT 1&quot;  ; then
    echo &quot;✅ MySQL 密码设置成功，可正常登录&quot;
else
    echo &quot;⚠️ MySQL 密码已设置，无需重复操作&quot;
fi

# ======================================================
echo -e &quot;\n===== 8. 创建库与授权 =====&quot;

# 执行数据库初始化（修复了拼写错误）
mysql -uroot -p&quot;$DB_PASSWORD&quot;   &amp;lt;&amp;lt;EOF
create database if not exists zabbix character set utf8mb4 collate utf8mb4_bin;
create user if not exists root@&apos;%&apos; identified by &apos;a123456!&apos;;
grant all privileges on *.* to root@&apos;%&apos;;
create user if not exists zabbix@localhost identified by &apos;a123456!&apos;;
grant all privileges on zabbix.* to zabbix@localhost;
create user if not exists zabbix@&apos;%&apos; identified by &apos;a123456!&apos;;
grant all privileges on zabbix.* to zabbix@&apos;%&apos;;
set global log_bin_trust_function_creators = 1;
FLUSH PRIVILEGES;
EOF

# 检测执行结果
if [ $? -eq 0 ]; then
    echo &quot;✅ 数据库创建与权限授权成功&quot;
else
    echo &quot;❌ 数据库初始化失败&quot;
    exit 1
fi

# ======================================================
echo -e &quot;\n===== 9. 安装 Zabbix WEB + Nginx + PHP =====&quot;

# 安装
dnf install -y zabbix-web-mysql zabbix-nginx-conf  

# 检测安装结果
if [ $? -eq 0 ]; then
    echo &quot;✅ Zabbix WEB + Nginx + PHP 安装成功&quot;
else
    echo &quot;❌ 安装失败，请检查网络或YUM源&quot;
    exit 1
fi

# ======================================================
echo -e &quot;\n===== 10. Nginx 配置 =====&quot;

# 备份原有配置（不存在也不报错）
cp /etc/nginx/conf.d/zabbix.conf /etc/nginx/conf.d/zabbix.conf-backup

# 写入新配置
cat &amp;gt; /etc/nginx/conf.d/zabbix.conf &amp;lt;&amp;lt;&apos;EOF&apos;
server {
        listen          80;
        server_name     zabbix.test.cn;

        root    /usr/share/zabbix;

        index   index.php;

        location = /favicon.ico {
                log_not_found   off;
        }

        location / {
                try_files       $uri $uri/ =404;
        }

        location /assets {
                access_log      off;
                expires         10d;
        }

        location ~ /\.ht {
                deny            all;
        }

        location ~ /(api\/|conf[^\.]|include|locale) {
                deny            all;
                return          404;
        }

        location /vendor {
                deny            all;
                return          404;
        }

        location ~ [^/]\.php(/|$) {
                fastcgi_pass    unix:/run/php-fpm/zabbix.sock;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_index   index.php;

                fastcgi_param   DOCUMENT_ROOT   /usr/share/zabbix;
                fastcgi_param   SCRIPT_FILENAME /usr/share/zabbix$fastcgi_script_name;
                fastcgi_param   PATH_TRANSLATED /usr/share/zabbix$fastcgi_script_name;

                include fastcgi_params;
                fastcgi_param   QUERY_STRING    $query_string;
                fastcgi_param   REQUEST_METHOD  $request_method;
                fastcgi_param   CONTENT_TYPE    $content_type;
                fastcgi_param   CONTENT_LENGTH  $content_length;

                fastcgi_intercept_errors        on;
                fastcgi_ignore_client_abort     off;
                fastcgi_connect_timeout         60;
                fastcgi_send_timeout            180;
                fastcgi_read_timeout            180;
                fastcgi_buffer_size             128k;
                fastcgi_buffers                 4 256k;
                fastcgi_busy_buffers_size       256k;
                fastcgi_temp_file_write_size    256k;
        }
}
EOF

# 检测配置文件是否生成成功
if [ -f /etc/nginx/conf.d/zabbix.conf ]; then
    echo &quot;✅ Nginx 配置文件写入成功&quot;
else
    echo &quot;❌ Nginx 配置文件写入失败&quot;
    exit 1
fi


# ======================================================
echo -e &quot;\n===== 11. PHP-FPM 配置 =====&quot;

# 备份原有配置（不存在也不报错）
cp /etc/php-fpm.d/zabbix.conf /etc/php-fpm.d/zabbix.conf.backup

# 写入新配置
cat &amp;gt; /etc/php-fpm.d/zabbix.conf &amp;lt;&amp;lt;&apos;EOF&apos;
[zabbix]
user = nginx
group = nginx

listen = /run/php-fpm/zabbix.sock
listen.acl_users = apache,nginx
listen.allowed_clients = 127.0.0.1

pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 200

php_value[session.save_handler] = files
php_value[session.save_path]    = /var/lib/php/session

php_value[max_execution_time] = 300
php_value[memory_limit] = 128M
php_value[post_max_size] = 16M
php_value[upload_max_filesize] = 2M
php_value[max_input_time] = 300
php_value[max_input_vars] = 10000
php_value[date.timezone] = Asia/Shanghai
EOF

# 检测配置文件是否生成成功
if [ -f /etc/php-fpm.d/zabbix.conf ]; then
    echo &quot;✅ PHP-FPM 配置文件写入成功&quot;
else
    echo &quot;❌ PHP-FPM 配置文件写入失败&quot;
    exit 1
fi


# ======================================================
echo -e &quot;\n===== 12. 目录权限 =====&quot;

# 设置权限（不存在也不报错）
setfacl -m u:nginx:rwx /etc/zabbix/web/

# 验证权限是否设置成功
if getfacl /etc/zabbix/web/ | grep -q &quot;nginx:rwx&quot;; then
    echo &quot;✅ Nginx 目录权限设置成功&quot;
else
    echo &quot;⚠️  目录权限无需设置或已存在&quot;
fi

# ======================================================
echo -e &quot;\n===== 13. 中文字体（解决图形乱码）=====&quot;

# 下载字体（修复可用地址 + 静默）
wget -O /root/simfang.ttf https://gitcode.com/qq_39549344/soft/raw/main/simfang.ttf --no-check-certificate -q  

# 检测是否下载成功
if [ -f /root/simfang.ttf ]; then
    echo &quot;✅ 中文字体下载成功&quot;
    
    # 复制并替换配置
    chmod 777 /root/simfang.ttf  
    cp /root/simfang.ttf /usr/share/zabbix/assets/fonts/  
    
    # 修改Zabbix字体配置
    sed -i &apos;88s/^/\/\//&apos; /usr/share/zabbix/include/defines.inc.php 2&amp;gt;/dev/null
    sed -i &apos;88a define(&apos;&quot;&apos;&quot;&apos;ZBX_GRAPH_FONT_NAME&apos;&quot;&apos;&quot;&apos;,                &apos;&quot;&apos;&quot;&apos;simfang&apos;&quot;&apos;&quot;&apos;); // font file name&apos; /usr/share/zabbix/include/defines.inc.php 2&amp;gt;/dev/null
    
    echo &quot;✅ 中文字体已部署到 Zabbix&quot;
else
    echo &quot;⚠️ 字体下载失败（网络问题），跳过配置&quot;
fi


# ======================================================
echo -e &quot;\n===== 14. 安装 Zabbix Server &amp;amp; Agent &amp;amp; get =====&quot;

# 静默安装
dnf install -y zabbix-server-mysql zabbix-sql-scripts zabbix-selinux-policy zabbix-agent zabbix-get

# 检测安装结果
if [ $? -eq 0 ]; then
    echo &quot;✅ Zabbix Server &amp;amp; Agent 安装成功&quot;
else
    echo &quot;❌ 安装失败，请检查 YUM 源或网络&quot;
    exit 1
fi

# ======================================================
echo -e &quot;\n===== 15. 导入数据库 =====&quot;

# 静默导入数据库
zcat /usr/share/zabbix-sql-scripts/mysql/server.sql.gz | mysql --default-character-set=utf8mb4 -uzabbix -p&quot;$DB_PASSWORD&quot; zabbix  

# 检测导入是否成功
if [ $? -eq 0 ]; then
    echo &quot;✅ Zabbix 数据库导入成功&quot;
else
    echo &quot;❌ 数据库导入失败（密码错误或文件不存在）&quot;
    exit 1
fi

# ======================================================
echo -e &quot;\n===== 16. 关闭函数信任 =====&quot;

# 执行关闭命令（静默）
mysql -uroot -p&quot;$DB_PASSWORD&quot; -e &quot;set global log_bin_trust_function_creators = 0;&quot;  

# 检测是否执行成功
if [ $? -eq 0 ]; then
    echo &quot;✅ 函数信任已关闭&quot;
else
    echo &quot;❌ 关闭函数信任失败&quot;
    exit 1
fi

# ======================================================
echo -e &quot;\n===== 17. Zabbix Server 配置 =====&quot;

# 备份原有配置
cp /etc/zabbix/zabbix_server.conf /etc/zabbix/zabbix_server.conf-backup

# 写入全新配置
cat &amp;gt; /etc/zabbix/zabbix_server.conf &amp;lt;&amp;lt; &apos;EOF&apos;
LogFile=/var/log/zabbix/zabbix_server.log
LogFileSize=0
PidFile=/run/zabbix/zabbix_server.pid
SocketDir=/run/zabbix
DBHost=localhost
DBName=zabbix
DBUser=zabbix
DBPassword=a123456!
DBPort=3306
SNMPTrapperFile=/var/log/snmptrap/snmptrap.log
Timeout=4
AlertScriptsPath=/usr/lib/zabbix/alertscripts
ExternalScripts=/usr/lib/zabbix/externalscripts
LogSlowQueries=3000
StatsAllowedIP=127.0.0.1
EOF

# ===================== 【配置检测】 =====================
# 检查文件是否生成
if [ ! -f /etc/zabbix/zabbix_server.conf ]; then
    echo &quot;❌ 配置文件生成失败！&quot;
    exit 1
fi

# 检查关键配置是否正确
ok=true
grep -q &quot;^DBHost=localhost&quot; /etc/zabbix/zabbix_server.conf || ok=false
grep -q &quot;^DBName=zabbix&quot; /etc/zabbix/zabbix_server.conf || ok=false
grep -q &quot;^DBUser=zabbix&quot; /etc/zabbix/zabbix_server.conf || ok=false
grep -q &quot;^DBPassword=a123456!&quot; /etc/zabbix/zabbix_server.conf || ok=false
grep -q &quot;^DBPort=3306&quot; /etc/zabbix/zabbix_server.conf || ok=false

# 输出结果
if $ok; then
    echo &quot;✅ Zabbix Server 配置文件生成并验证成功&quot;
else
    echo &quot;❌ Zabbix 配置文件内容错误&quot;
    exit 1
fi
# ===================== 服务端日志检测：存在跳过，不存在创建赋权 =====================
echo -e &quot;\n===== 检查 Zabbix Server 日志文件 =====&quot;
SERVER_LOG=&quot;/var/log/zabbix/zabbix_server.log&quot;
SNMP_LOG=&quot;/var/log/snmptrap/snmptrap.log&quot;

# 处理 zabbix_server.log
if [ -f &quot;$SERVER_LOG&quot; ]; then
    echo &quot;✅ $SERVER_LOG 已存在，跳过&quot;
else
    mkdir -p /var/log/zabbix/
    touch &quot;$SERVER_LOG&quot;
    chown -R zabbix:zabbix /var/log/zabbix/
    chmod 644 &quot;$SERVER_LOG&quot;
    echo &quot;✅ $SERVER_LOG 已创建并授权&quot;
fi

# 处理 snmptrap.log
if [ -f &quot;$SNMP_LOG&quot; ]; then
    echo &quot;✅ $SNMP_LOG 已存在，跳过&quot;
else
    mkdir -p /var/log/snmptrap/
    touch &quot;$SNMP_LOG&quot;
    chown -R zabbix:zabbix /var/log/snmptrap/
    chmod 644 &quot;$SNMP_LOG&quot;
    echo &quot;✅ $SNMP_LOG 已创建并授权&quot;
fi
# ======================================================
echo -e &quot;\n===== 18. 启动所有服务 =====&quot;

# 重启服务
systemctl daemon-reload  
systemctl enable nginx php-fpm zabbix-server zabbix-agent --now  
systemctl restart nginx php-fpm zabbix-server zabbix-agent  

# 逐个检测服务状态
all_ok=true
for service in nginx php-fpm zabbix-server zabbix-agent; do
    if ! systemctl is-active --quiet $service; then
        echo &quot;❌ $service 启动失败！&quot;
        all_ok=false
    fi
done

# 最终结果提示
if $all_ok; then
    echo &quot;✅ 所有服务启动并运行正常&quot;
else
    echo &quot;❌ 部分服务启动异常，请检查！&quot;
    exit 1
fi

# ======================================================
echo -e &quot;\n========================================&quot;
echo -e &quot;✅ Zabbix 6.0 安装完成！&quot;
echo -e &quot;🌐 访问：http://本机IP&quot;
echo -e &quot;👤 用户：Admin&quot;
echo -e &quot;🔑 密码：zabbix&quot;
echo -e &quot;🗝️ 数据库密码：$DB_PASSWORD&quot;
echo -e &quot;========================================&quot;


    📌 使用方法（超级简单）
    1. 上传字体文件
    把你的 `simfang.ttf` 上传到 **/root** 目录

    2. 创建脚本
    ```bash
    vim install_zabbix6.sh
    ```
    **粘贴上面全部代码**，保存退出。

    3. 加权限
    ```bash
    chmod +x install_zabbix6.sh
    ```

    4. 运行安装
    ```bash
    ./install_zabbix6.sh
    ```

    ✅ 脚本自动完成以下所有操作
    - 关闭防火墙
    - 永久关闭 SELinux
    - 配置阿里云 EPEL 源
    - 安装 MySQL 8
    - 自动设置密码：`a123456!`
    - 创建 zabbix 库 + 用户
    - 安装 zabbix-web、nginx、php
    - 配置中文、时区
    - 替换字体（**解决图形中文乱码**）
    - 导入 zabbix 初始数据库
    - 配置 zabbis_server.conf
    - 启动所有服务：nginx/php-fpm/zabbix-server/zabbix-agent

    🌐 安装完成后
    **访问：**
    ```
    http://192.168.88.10
    ```

    **默认账号：**
    ```
    用户名：Admin
    密码：zabbix
    ```

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Zabbix-agent安装脚本&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash
# Zabbix Agent 自动安装脚本 | Rocky Linux 9 / RHEL 9
# 优化：防卡死、防冲突、变量生效、格式正确、全流程检测

# ===================== 固定配置 =====================
hostname=$(hostname) # 获取本地设备名
ZABBIX_ALLOW_NETWORK=&quot;192.168.88.0/24&quot;  # 被动监控本地的地址、允许整个网段监控
ZABBIX_ACTIVE_IP=&quot;192.168.88.1&quot; # 本地主动推送的地址、只允许IP
# ======================================================

echo -e &quot;\n===== 1. 关闭防火墙 =====&quot;
if systemctl stop firewalld &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
    echo &quot;✅ 防火墙 停止成功&quot;
else
    echo &quot;⚠️ 防火墙 未运行或停止失败&quot;
fi

if systemctl disable firewalld &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
    echo &quot;✅ 防火墙 开机自启 已禁用&quot;
else
    echo &quot;⚠️ 防火墙 开机自启 禁用失败/已禁用&quot;
fi


echo -e &quot;\n===== 2. 关闭 SELinux =====&quot;
sed -i &apos;s/^SELINUX=.*/SELINUX=disabled/&apos; /etc/selinux/config
if grep -q &quot;SELINUX=disabled&quot; /etc/selinux/config; then
    echo &quot;✅ SELinux 配置已永久禁用（重启生效）&quot;
else
    echo &quot;❌ SELinux 配置修改失败&quot;
fi

setenforce 0 &amp;gt;/dev/null 2&amp;gt;&amp;amp;1
if [ $? -eq 0 ]; then
    echo &quot;✅ SELinux 临时关闭成功&quot;
else
    echo &quot;⚠️ SELinux 已关闭，无需重复操作&quot;
fi


echo -e &quot;\n===== 3. 配置阿里云 EPEL 源 =====&quot;
cat &amp;gt; /etc/yum.repos.d/aliyun_epel_9.repo &amp;lt;&amp;lt;EOF
[epel]
name=Extra Packages for Enterprise Linux \$releasever - \$basearch
baseurl=https://mirrors.aliyun.com/epel/\$releasever/Everything/\$basearch
failovermethod=priority
enabled=1
gpgcheck=0
excludepkgs=zabbix*
EOF

if [ -f /etc/yum.repos.d/aliyun_epel_9.repo ]; then
    echo &quot;✅ EPEL 源文件创建成功&quot;
else
    echo &quot;❌ EPEL 源文件创建失败&quot;
fi


echo -e &quot;\n===== 4. 安装 Zabbix 官方源 =====&quot;
rpm -Uvh https://repo.zabbix.com/zabbix/6.0/rhel/9/x86_64/zabbix-release-6.0-4.el9.noarch.rpm --nosignature

if rpm -q zabbix-release &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
    echo &quot;✅ Zabbix 官方源 安装成功&quot;
else
    echo &quot;⚠️ Zabbix 官方源 已安装或安装失败&quot;
fi


echo -e &quot;\n===== 5. 重建缓存（防卡死强制解锁） =====&quot;

echo &quot;🔍 清理 DNF/YUM 占用进程...&quot;
for pid in $(ps -ef | grep -E &quot;dnf|yum|rpm&quot; | grep -v grep | awk &apos;{print $2}&apos;); do
    kill -9 $pid &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 &amp;amp;&amp;amp; echo &quot;✅ 已结束占用进程 PID: $pid&quot;
done

rm -f /var/run/yum.pid /var/run/dnf.pid /var/lib/dnf/rpm.lock /var/lib/rpm/.rpm.lock

dnf clean all &amp;gt;/dev/null 2&amp;gt;&amp;amp;1
timeout 120 dnf makecache -y &amp;gt;/dev/null 2&amp;gt;&amp;amp;1

if [ $? -eq 0 ]; then
    echo &quot;✅ 缓存重建成功&quot;
else
    echo &quot;⚠️ 缓存跳过，继续安装&quot;
fi


echo -e &quot;\n===== 6. 安装 zabbix-agent + zabbix-sender =====&quot;
dnf install -y zabbix-agent zabbix-sender

if [ $? -eq 0 ]; then
    echo &quot;✅ zabbix-agent + zabbix-sender 安装成功&quot;
else
    echo &quot;❌ 安装失败，请检查YUM源&quot;
    exit 1
fi


echo -e &quot;\n===== 7. Zabbix-agent 配置（变量自动生效） =====&quot;

# 备份
cp -n /etc/zabbix/zabbix_agentd.conf /etc/zabbix/zabbix_agentd.conf.backup

# 写入正确配置（无空格、变量生效）
cat &amp;gt; /etc/zabbix/zabbix_agentd.conf &amp;lt;&amp;lt; EOF
PidFile=/run/zabbix/zabbix_agentd.pid
LogFile=/var/log/zabbix/zabbix_agentd.log
LogFileSize=0
        # Zabbix服务地址，谁可以监控我/可以写网段
Server=$ZABBIX_ALLOW_NETWORK    
ListenPort=10050
        # Zabbix服务地址，是我主动推数据给谁/只能写IP
ServerActive=$ZABBIX_ACTIVE_IP       
        # 本地主机设备名
Hostname=$hostname
Timeout=30
Include=/etc/zabbix/zabbix_agentd.d/*.conf
EOF

# 权限
chown zabbix:zabbix /etc/zabbix/zabbix_agentd.conf
chmod 644 /etc/zabbix/zabbix_agentd.conf

echo &quot;✅ Zabbix agent 配置已生成&quot;

# ===================== 客户端日志检测：存在跳过，不存在创建赋权 =====================
echo -e &quot;\n===== 检查 Zabbix Agent 日志文件 =====&quot;
AGENT_LOG=&quot;/var/log/zabbix/zabbix_agentd.log&quot;

if [ -f &quot;$AGENT_LOG&quot; ]; then
    echo &quot;✅ $AGENT_LOG 已存在，跳过&quot;
else
    mkdir -p /var/log/zabbix/
    touch &quot;$AGENT_LOG&quot;
    chown -R zabbix:zabbix /var/log/zabbix/
    chmod 644 &quot;$AGENT_LOG&quot;
    echo &quot;✅ $AGENT_LOG 已创建并授权&quot;
fi

echo -e &quot;\n===== 8. 启动并开机自启 =====&quot;
systemctl daemon-reload
systemctl enable --now zabbix-agent
systemctl restart zabbix-agent

if systemctl is-active --quiet zabbix-agent; then
    echo &quot;✅ zabbix-agent 正在运行&quot;
else
    echo &quot;❌ zabbix-agent 启动失败，请检查配置&quot;
fi


echo -e &quot;\n========================================&quot;
echo -e &quot;✅ Zabbix-agent 安装完成！&quot;
echo -e &quot;📌 当前 Hostname：$hostname&quot;
echo -e &quot;📌 允许监控网段：$ZABBIX_ALLOW_NETWORK&quot;
echo -e &quot;📌 主动上报IP：$ZABBIX_ACTIVE_IP&quot;
echo -e &quot;⚠️  如未自动替换，请修改：vim /etc/zabbix/zabbix_agentd.conf&quot;
echo -e &quot;========================================&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;卸载脚本&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash
# Zabbix 6.0 彻底卸载清空脚本 | Rocky Linux 9
# 安全版：不删除系统依赖，只删 Zabbix + 安装的组件

echo -e &quot;\n===== 🔴 开始彻底卸载 Zabbix 6.0 =====&quot;

# 1. 停止相关服务
echo -e &quot;1. 停止服务...&quot;
systemctl stop zabbix-server zabbix-agent nginx php-fpm mysqld 2&amp;gt;/dev/null
systemctl disable zabbix-server zabbix-agent nginx php-fpm mysqld 2&amp;gt;/dev/null

# 2. 卸载 Zabbix + MySQL + Nginx + PHP
echo -e &quot;2. 卸载软件包...&quot;
dnf remove -y zabbix-server-mysql zabbix-sql-scripts zabbix-selinux-policy zabbix-agent zabbix-get zabbix-web-mysql zabbix-nginx-conf mysql-server mysql zabbix* zabbix-agent mysql-server mysql nginx php*
rpm -e zabbix-release 2&amp;gt;/dev/null

# 3. 删除 Zabbix 源
#echo -e &quot;3. 删除 YUM 源...&quot;
#rm -rf /etc/y.repos.d/zabbix*.repo

# 4. 删除所有配置 &amp;amp; 数据文件
echo -e &quot;4. 删除配置与数据...&quot;
rm -rf /etc/zabbix
rm -rf /usr/share/zabbix
rm -rf /var/lib/zabbix
rm -rf /var/log/zabbix

rm -rf /etc/nginx/conf.d/zabbix.conf
rm -rf /etc/php-fpm.d/zabbix.conf
rm -rf /var/lib/php/session/*

rm -rf /var/lib/mysql
rm -rf /var/log/mysql*

rm -rf /run/zabbix
rm -rf /run/php-fpm/zabbix.sock

# 5. 清理字体与临时文件
echo -e &quot;5. 清理临时文件...&quot;
rm -rf /root/simfang.ttf

# 6. 清理系统缓存
# echo -e &quot;6. 清理 DNF 缓存...&quot;
# dnf clean all &amp;gt;/dev/null 2&amp;gt;&amp;amp;1
# dnf makecache -y &amp;gt;/dev/null 2&amp;gt;&amp;amp;1

echo -e &quot;\n========================================&quot;
echo -e &quot;✅ Zabbix 已彻底卸载干净！&quot;
echo -e &quot;✅ MySQL/Nginx/PHP 已清空&quot;
echo -e &quot;✅ 可直接重新运行安装脚本&quot;
echo -e &quot;========================================\n&quot;

&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>02-Zabbix-Agent-客户端代理-部署</title><link>https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/02-zabbix-agent-%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%BB%A3%E7%90%86-%E9%83%A8%E7%BD%B2/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/02-zabbix-agent-%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%BB%A3%E7%90%86-%E9%83%A8%E7%BD%B2/</guid><description>Zabbix【扎-比斯】 6.4 分布式企业级性能监控平台 - 运维知识库笔记</description><pubDate>Thu, 04 Jun 2026 02:22:00 GMT</pubDate><content:encoded>&lt;h1&gt;Zabbix【扎-比斯】 6.4 分布式企业级性能监控平台&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;Zabbix Agent 客户端代理 部署
官网：https://www.zabbix.com/cn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/117075162608236.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;一、部署：Zabbix【扎-比斯】 Agent【A 撞 特】 客户端代理&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Zabbix Agent 客户端代理&amp;gt;是一个小程序，它负责针对其所在的主机执行&amp;lt;各项性能指标&amp;gt;的数据采集操作。当&amp;lt;Zabbix Server 服务器&amp;gt;需要采集&amp;lt;监控数据&amp;gt;时，便可以联系&amp;lt;Zabbix Agent 客户端代理&amp;gt;，然后由&amp;lt;Zabbix Agent 客户端代理&amp;gt;来执行数据采集操作，从而最终获取到&amp;lt;监控数据&amp;gt;。
&amp;lt;Zabbix Agent 客户端代理&amp;gt;须安装部署在&amp;lt;被监控主机&amp;gt;上，&amp;lt;Zabbix Agent 客户端代理&amp;gt;只是数据采集的方法之一，并不是所有的&amp;lt;被监控设备&amp;gt;均需安装&amp;lt;Zabbix Agent 客户端代理&amp;gt;，比如：采用 SNMP、IPMI 等数据采集方式，就不需要安装并使用&amp;lt;Zabbix Agent 客户端代理&amp;gt;，交换机、路由器等网络设备，也无法安装&amp;lt;Zabbix Agent 客户端代理&amp;gt;。
&amp;lt;Zabbix Agent 客户端代理&amp;gt;部署在&amp;lt;被监控主机&amp;gt;上之后，它可以利用&amp;lt;本地系统调用&amp;gt;来高效的采集&amp;lt;本地系统的性能数据&amp;gt;，例如：硬盘、内存、处理器 等等。
&amp;lt;Zabbix Agent 客户端代理&amp;gt;可以基于&amp;lt;被动模式/主动模式&amp;gt;来向&amp;lt;Zabbix Server/Zabbix Proxy&amp;gt;反馈/汇报&amp;lt;性能采集数据&amp;gt;，一旦出现异常(例如：硬盘空间已满 或者 有崩溃的服务进程)，Zabbix Server 就会基于&amp;lt;告警通知&amp;gt;主动向管理员汇报。
在本文中，安装了&amp;lt;Zabbix Agent 客户端代理&amp;gt;的&amp;lt;被监控主机&amp;gt;，我们称之为&amp;lt;Zabbix Agent 客户端&amp;gt;。
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;1. 环境说明：&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;节点&lt;/th&gt;
&lt;th&gt;角色&lt;/th&gt;
&lt;th&gt;IP 地址&lt;/th&gt;
&lt;th&gt;操作系统：&lt;/th&gt;
&lt;th&gt;硬件规格&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-16&lt;/td&gt;
&lt;td&gt;MySQL 数据库(版本：8.0) 加装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.16/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-17&lt;/td&gt;
&lt;td&gt;Nginx + PHP Web 前端 加装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.17/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-18&lt;/td&gt;
&lt;td&gt;Zabbix Server 核心服务(版本：6.4)&lt;/td&gt;
&lt;td&gt;192.168.168.18/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-19&lt;/td&gt;
&lt;td&gt;被监控主机 安装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.19/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;2. 安装配置：Zabbix【扎-比斯】 Agent【A 撞 特】 客户端代理（仅在&amp;lt;被监控主机&amp;gt;部署）&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;★ 安装：Zabbix【扎-比斯】 Agent 客户端代理
##
## (1) 禁用：EPEL 源中的 Zabbix
##
[root@Rocky-9-16 ~]# vim /etc/yum.repos.d/ustc_epel_9.repo ## 这是：一个国内的 EPEL YUM 镜像源
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-16 ~]# vim /etc/yum.repos.d/ustc_epel_9.repo ## 这是：一个国内的 EPEL YUM 镜像源
    [epel]
    name=Extra Packages for Enterprise Linux $releasever - $basearch
    baseurl=https://mirrors.ustc.edu.cn/epel/$releasever//Everything/$basearch
    failovermethod=priority
    enabled=1
    gpgcheck=0
    excludepkgs=zabbix*
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (2) 获取：&amp;lt;Zabbix【扎-比斯】 软件包&amp;gt;的&amp;lt;repo 源配置文件&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-16 ~]# rpm -Uvh https://repo.zabbix.com/zabbix/6.0/rhel/9/x86_64/zabbix-release-6.0-4.el9.noarch.rpm
    [root@Rocky-9-16 ~]# yum clean all
    [root@Rocky-9-16 ~]# yum makecache
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (3) 安装：&amp;lt;Zabbix【扎-比斯】 Agent【A 撞 特】 客户端代理&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-16 ~]# dnf install -y zabbix-agent
    [root@Rocky-9-16 ~]# vim /etc/zabbix/zabbix_agentd.conf
    ... ...
    ## 设置：&amp;lt;超时阈值&amp;gt;为&amp;lt;最大值&amp;gt;，从而应对耗时较长的&amp;lt;数据收集&amp;gt;操作
    Timeout=30
    ... ...
    ## 针对&amp;lt;被被模式&amp;gt;，设置：&amp;lt;Zabbix Agent 侦听端口&amp;gt;
    ## ♦ 功能说明：
    ## ♢在&amp;lt;指定端口&amp;gt;侦听&amp;lt;数据采集请求&amp;gt;
    ListenPort=10050
    ## 针对&amp;lt;被被模式&amp;gt;，设置：&amp;lt;Zabbix Server 核心服务器&amp;gt;的&amp;lt;IP 地址&amp;gt; 或者 &amp;lt;Zabbix Proxy 分布式代理服务器&amp;gt;的&amp;lt;IP 地址&amp;gt;
    ## ♦ 功能说明：
    ## ♢控制：&amp;lt;本机 Zabbix Agent 程序&amp;gt;在&amp;lt;10050/tcp 端口&amp;gt;上，应该接收谁的&amp;lt;数据采集请求&amp;gt;？
    Server=192.168.168.18
    ## 针对&amp;lt;主动模式&amp;gt;，设置：&amp;lt;Zabbix Server 核心服务器&amp;gt;的&amp;lt;IP 地址&amp;gt; 或者 &amp;lt;Zabbix Proxy 分布式代理服务器&amp;gt;的&amp;lt;IP 地址&amp;gt;
    ## ♦ 功能说明：
    ## ♢控制：应该向谁主动汇报&amp;lt;采集数据&amp;gt;？
    ServerActive=192.168.168.18:10051
    ##
    ## 针对&amp;lt;自动注册&amp;gt;，设置：唯一性的&amp;lt;主机注册名称&amp;gt;
    ##
    Hostname=rocky-9-19
    ... ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-16 ~]# cat /etc/zabbix/zabbix_agentd.conf | grep -vE &quot;^\s*(#|$)&quot;
    PidFile=/run/zabbix/zabbix_agentd.pid
    LogFile=/var/log/zabbix/zabbix_agentd.log
    LogFileSize=0
    ListenPort=10050                         ## 针对&amp;lt;被动模式&amp;gt;，设置：&amp;lt;Zabbix Agent 侦听端口&amp;gt;
    Server=192.168.168.18                    ## 针对&amp;lt;被动模式&amp;gt;，设置：接收&amp;lt;指定 IP 地址&amp;gt;发来的&amp;lt;度量查询请求&amp;gt;
    ServerActive=192.168.168.18:10051        ## 针对&amp;lt;主动模式&amp;gt;，设置：向&amp;lt;指定 IP 地址&amp;gt;主动汇报&amp;lt;度量采集数据&amp;gt;
    Hostname=rocky-9-19                      ## 针对&amp;lt;自动注册&amp;gt;，设置：唯一性的&amp;lt;主机注册名称&amp;gt;
    Timeout=30                               ## 设置：&amp;lt;超时阈值&amp;gt;为&amp;lt;最大值&amp;gt;，从而应对耗时较长的&amp;lt;数据收集&amp;gt;操作
    Include=/etc/zabbix/zabbix_agentd.d/*.conf

    [root@Rocky-9-16 ~]# systemctl enable zabbix-agent.service
    [root@Rocky-9-16 ~]# systemctl restart zabbix-agent.service
    [root@Rocky-9-16 ~]# systemctl status zabbix-agent.service
    [root@Rocky-9-16 ~]# firewall-cmd --permanent --zone=public --add-port=10050/tcp ## 防火墙放行：&amp;lt;Zabbix Agent 客户端代理&amp;gt;的&amp;lt;侦听端口&amp;gt;
    [root@Rocky-9-16 ~]# firewall-cmd --reload
    ## 禁用：SElinux
    if ! [[ $(getenforce) == &quot;Disabled&quot; ]]; then
        sed -r -i &apos;s/^\s*SELINUX=.*/SELINUX=disabled/&apos; /etc/selinux/config
        reboot
    fi
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;3. 查看日志：Zabbix【扎-比斯】 Agent【A 撞 特】 日志&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;    [root@Rocky-9-16 ~]# cat /var/log/zabbix/zabbix_agentd.log         ## 查看：Zabbix Agent 日志
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;二、了解：被动模式、主动模式&lt;/h1&gt;
&lt;h2&gt;1. 被动模式&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;★ 被动模式：是&amp;lt;Zabbix Server/Zabbix Proxy&amp;gt;主动轮询&amp;lt;Zabbix Agent 客户端代理&amp;gt;，从而获取&amp;lt;性能数据&amp;gt;。
★ 配置要点：
    (1) &amp;lt;被动模式&amp;gt;是默认的&amp;lt;工作模式&amp;gt;。
    (2) 配置关键点 1：&amp;lt;Zabbix Server/Zabbix Proxy&amp;gt;服务端
        ##
        ## 针对/etc/zabbix/zabbix_server.conf 配置文件，无需特别的配置，保持默认即可！
        ##
    (3) 配置关键点 2：&amp;lt;Zabbix Agent&amp;gt;客户端代理    
        ##
        ## 须在/etc/zabbix/zabbix_agentd.conf 配置文件中，确保：
        ## ♦ 侦听：&amp;lt;10050/tcp 端口&amp;gt;
        ## ♦ 接收：&amp;lt;指定的 Zabbix 服务端 IP 地址&amp;gt;发来的&amp;lt;轮询请求&amp;gt;
        ##
        [root@Rocky-9-16 ~]# vi /etc/zabbix/zabbix_agentd.conf
            ... ...
            ## 针对&amp;lt;被动模式&amp;gt;，设置：&amp;lt;Zabbix Agent 侦听端口&amp;gt;
            ## ♦ 功能说明：
            ## ♢在&amp;lt;指定端口&amp;gt;侦听&amp;lt;数据采集请求&amp;gt;
            ListenPort=10050
            ## 针对&amp;lt;被动模式&amp;gt;，设置：&amp;lt;Zabbix Server 核心服务器&amp;gt;的&amp;lt;IP 地址&amp;gt; 或者 &amp;lt;Zabbix Proxy 分布式代理服务器&amp;gt;的&amp;lt;IP 地址&amp;gt;
            ## ♦ 功能说明：
            ## ♢控制：&amp;lt;本机 Zabbix Agent 程序&amp;gt;在&amp;lt;10050/tcp 端口&amp;gt;上，应该接收谁的&amp;lt;数据采集请求&amp;gt;？
            Server=192.168.168.18
            ... ...
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2. 主动模式&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;★ 主动模式：是&amp;lt;Zabbix Agent 客户端代理&amp;gt;主动向&amp;lt;Zabbix Server/Zabbix Proxy&amp;gt;汇报&amp;lt;性能数据&amp;gt;。
★ 配置要点：
    (1) &amp;lt;主动模式&amp;gt;不是默认的&amp;lt;工作模式&amp;gt;。
    (2) 配置关键点 1：&amp;lt;Zabbix Server/Zabbix Proxy&amp;gt;服务端
        ##
        ## 须在/etc/zabbix/zabbix_server.conf 配置文件中，确保：
        ## ♦ 侦听：&amp;lt;10051/tcp 端口&amp;gt;
        ##
        [root@Rocky-9-16 ~]# vim /etc/zabbix/zabbix_server.conf
            ... ...
            ### Option: ListenPort
            # Listen port for trapper.
            #
            # Mandatory: no
            # Range: 1024-32767
            # Default:
            # ListenPort=10051 该&amp;lt;侦听端口&amp;gt;默认已启用，可以不用明确定义，除非你要更改这个&amp;lt;侦听端口&amp;gt;
            ListenPort=10051
            ... ...
    (3) 配置关键点 2：&amp;lt;Zabbix Agent&amp;gt;客户端代理
        ##
        ## 须在/etc/zabbix/zabbix_agentd.conf 配置文件中，确保：
        ## ♦ 指定：需要向谁主动汇报&amp;lt;性能数据&amp;gt;
        ##
        [root@Rocky-9-16 ~]# vim /etc/zabbix/zabbix_agentd.conf
            ... ...
            ## 针对&amp;lt;主动模式&amp;gt;，设置：&amp;lt;Zabbix Server 核心服务器&amp;gt;的&amp;lt;IP 地址&amp;gt; 或者 &amp;lt;Zabbix Proxy 分布式代理服务器&amp;gt;的&amp;lt;IP 地址&amp;gt;
            ## ♦ 功能说明：
            ## ♢控制：应该向谁主动汇报&amp;lt;采集数据&amp;gt;？
            ServerActive=192.168.168.18:10051
            ... ...
            ##
            ## 针对&amp;lt;主动模式&amp;gt;，设置：&amp;lt;Zabbix agent 客户端&amp;gt;执行&amp;lt;数据采集操作&amp;gt;的&amp;lt;时间间隔&amp;gt;
            ## ♦ 默认为 120s，如若失败，就 60 秒之后重试一次
            RefreshActiveChecks=120
            ##
            ## 针对&amp;lt;主动模式&amp;gt;，设置：&amp;lt;Zabbix agent 客户端&amp;gt;的&amp;lt;采样数据 buffer 缓冲空间大小&amp;gt;
            ## ♦ 默认为 100 字节，如果 buffer 满了，就会主动汇报&amp;lt;采样数据&amp;gt;
            ##
            BufferSize=100
            ##
            ## 针对&amp;lt;主动模式&amp;gt;，设置：&amp;lt;buffer 缓冲空间&amp;gt;中&amp;lt;采样数据&amp;gt;的&amp;lt;保存时长&amp;gt;
            ## ♦ 默认为 5s，超过这个时长，同样也会主动汇报&amp;lt;采样数据&amp;gt;
            ##
            BufferSend=5
            ... ...
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;★ 作业&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;当前你已经部署好了一台 Zabbix【扎-比斯】 Server 核心服务器，现在有一台 Rocky Linux 9 服务器，我们需要在该服务器上安装 Zabbix Agent 客户端代理软件，为后续的监控做好准备工作。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;[root@Rocky-9-16 ~]# cat /etc/yum.repos.d/ustc_epel_9.repo
[epel]
name=Extra Packages for Enterprise Linux $releasever - $basearch
baseurl=https://mirrors.aliyun.com/epel/$releasever//Everything/$basearch
failovermethod=priority
enabled=1
gpgcheck=0
excludepkgs=zabbix*

[root@Rocky-9-16 ~]# 
[root@Rocky-9-16 ~]# rpm -Uvh https://repo.zabbix.com/zabbix/6.0/rhel/9/x86_64/zabbix-release-6.0-4.el9.noarch.rpm
获取https://repo.zabbix.com/zabbix/6.0/rhel/9/x86_64/zabbix-release-6.0-4.el9.noarch.rpm
警告：/var/tmp/rpm-tmp.hoWIOE: 头V4 RSA/SHA512 Signature, 密钥 ID 08efa7dd: NOKEY
Verifying...                          ################################# [100%]
准备中...                          ################################# [100%]
正在升级/安装...
   1:zabbix-release-6.0-4.el9         ################################# [100%]
   
[root@Rocky-9-16 ~]# 
[root@Rocky-9-16 ~]# dnf clean all &amp;amp;&amp;amp; dnf makecache 
0 个文件已删除
Rocky Linux 9 - BaseOS   
........   
元数据缓存已建立。

[root@Rocky-9-16 ~]# dnf install -y zabbix-agent
上次元数据过期检查：0:00:48 前，执行于 2026年02月06日 星期五 14时29分29秒。
依赖关系解决。
=========================== 
........
已安装:
  zabbix-agent-6.0.43-release1.el9.x86_64                                                                                                                                      

完毕！

[root@Rocky-9-16 ~]# 
[root@Rocky-9-16 ~]# vim /etc/zabbix/zabbix_agentd.conf
[root@Rocky-9-16 ~]# cat /etc/zabbix/zabbix_agentd.conf | grep -vnE &quot;^\s*(#|$)&quot;
13:PidFile=/run/zabbix/zabbix_agentd.pid
32:LogFile=/var/log/zabbix/zabbix_agentd.log
43:LogFileSize=0
117:Server=192.168.88.11
125:ListenPort=10050
171:ServerActive=192.168.88.11:10051
182:Hostname=Rocky-9-16
293:Timeout=30
323:Include=/etc/zabbix/zabbix_agentd.d/*.conf

[root@Rocky-9-16 ~]# 
[root@Rocky-9-16 ~]# systemctl enable zabbix-agent.service  --now
Created symlink /etc/systemd/system/multi-user.target.wants/zabbix-agent.service → /usr/lib/systemd/system/zabbix-agent.service.

[root@Rocky-9-16 ~]#  systemctl status zabbix-agent.service   
● zabbix-agent.service - Zabbix Agent
     Loaded: loaded (/usr/lib/systemd/system/zabbix-agent.service; enabled; preset: disabled)
     Active: active (running) since Fri 2026-02-06 14:35:36 CST; 2min 22s ago
    Process: 37371 ExecStart=/usr/sbin/zabbix_agentd -c $CONFFILE (code=exited, status=0/SUCCESS)
   Main PID: 37373 (zabbix_agentd)
 ........
[root@zabbix ~]# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/515157193324433.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/191464255626144.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;什么是&amp;lt;被动模式&amp;gt;？在&amp;lt;被动模式&amp;gt;中，Zabbix Agent 需要侦听什么端口？Zabbix Server 需要访问什么端口？
答：
被动模式是：Zabbix_Server服务端 主动轮询 Zabbix_Agent客户端 ，从而获取性能数据
Zabbix Agent 需要侦听 10050 端口
Zabbix Server 需要访问 10051 端口&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;什么是&amp;lt;主动模式&amp;gt;？在&amp;lt;主动模式&amp;gt;中，Zabbix Server 需要侦听什么端口？Zabbix Agent 需要访问什么端口？
答：
主动模式：是 Zabbix Agent 客户端代理 主动向 Zabbix Server服务端 汇报性能数据。
Zabbix Agent 需要侦听 10050 端口
Zabbix Server 需要访问 10051 端口&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>03-Zabbix-整体架构</title><link>https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/03-zabbix-%E6%95%B4%E4%BD%93%E6%9E%B6%E6%9E%84/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/03-zabbix-%E6%95%B4%E4%BD%93%E6%9E%B6%E6%9E%84/</guid><description>Zabbix 6.4 分布式企业级性能监控平台 - 运维知识库笔记</description><pubDate>Thu, 04 Jun 2026 01:23:00 GMT</pubDate><content:encoded>&lt;h1&gt;Zabbix 6.4 分布式企业级性能监控平台&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;Zabbix 整体架构
官网：https://www.zabbix.com/cn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/117075162608236.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、了解Zabbix【扎-比斯】 程序组件&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;针对 Zabbix 性能监控管理平台，我们需要了解一些重要的服务进程，理解它们之间的协作机制，这样有助于我们在构建基础架构的时候，正确的选择并安装服务组件。同时我们也需要了解一些 Zabbix 自带的小工具软件，从而方便我们进行&amp;lt;功能性检测&amp;gt;或&amp;lt;临时性管理&amp;gt;。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1. zabbix【扎-比斯】_server 守护程序&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★ 它是：&amp;lt;Zabbix Server 核心服务端&amp;gt;的&amp;lt;守护程序&amp;gt;。
★ 功能：(1) 发起&amp;lt;数据采集请求&amp;gt;，主动获取&amp;lt;被监控设备&amp;gt;的&amp;lt;性能指标数据&amp;gt;。
        (2) 接收&amp;lt;数据采集汇报&amp;gt;，被动获取&amp;lt;被监控设备&amp;gt;的&amp;lt;性能指标数据&amp;gt;。
        (3) 最终保存、展示、处理&amp;lt;收集到的性能指标数据&amp;gt;。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. zabbix【扎-比斯】_agentd【A 撞 特】&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★ 它是：&amp;lt;Zabbix 客户端代理&amp;gt;的&amp;lt;守护程序&amp;gt;。
★ 功能：针对&amp;lt;本机&amp;gt;执行&amp;lt;数据采集操作&amp;gt;，从而向&amp;lt;Zabbix Server 或 Proxy 服务器&amp;gt;提供&amp;lt;性能指标数据&amp;gt;。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. zabbix【扎-比斯】_proxy【普洛西】 守护程序&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★ 它是：&amp;lt;Zabbix Proxy 分布式代理服务端&amp;gt;的&amp;lt;守护程序&amp;gt;，它是实现&amp;lt;分布式监控&amp;gt;的&amp;lt;重要环节&amp;gt;。
★ 功能：(1) 代表&amp;lt;Zabbix Server 核心服务端&amp;gt;，对所辖范围内的&amp;lt;被监控设备&amp;gt;，执行&amp;lt;性能监控&amp;gt;。
        (2) 代表&amp;lt;被监控设备&amp;gt;，将&amp;lt;收集到的性能指标数据&amp;gt;发送给&amp;lt;Zabbix Server 核心服务端&amp;gt;。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. zabbix【扎-比斯】_get【脚(白话)特】 命令行 服务端实用程序&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★ 功能：向&amp;lt;Zabbix agent 客户端代理&amp;gt;发出&amp;lt;数据采集请求&amp;gt;。
★ 安装：
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@zabbix-server ~]# dnf install -y zabbix-get     ## 在&amp;lt;Zabbix Server/Proxy 服务端&amp;gt;安装
    ★ 语法格式：
        zabbix_get -h ## 查看：命令帮助
        zabbix_get -V ## 查看：命令版本
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## 向&amp;lt;Zabbix Agent 客户端&amp;gt;发出&amp;lt;数据采集请求&amp;gt;，从而获取：指定&amp;lt;监控项&amp;gt;的&amp;lt;性能指标数据&amp;gt;。
##
    zabbix_get [-I 服务端] -s 客户端 [-p 客户端端口] -k 键名
★ 例句：
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@zabbix-server ~]# zabbix_get -s 192.168.168.19 -k system.hw.macaddr[ens33]
    [root@zabbix-server ~]# zabbix_get -I 192.168.168.18 -s 192.168.168.19 -p 10050 -k system.hw.macaddr[ens33]
                                            ↑                 ↑                 ↑          ↑
                                            ↑                 ↑                 ↑         指定：请求的&amp;lt;Key 键名&amp;gt;和&amp;lt;键参数&amp;gt;
                                            ↑                 ↑             指定：请求的&amp;lt;目标 port 端口&amp;gt;
                                            ↑             指定：请求的&amp;lt;客户端目标 IP 地址&amp;gt;
                                        指定：请求的&amp;lt;服务端源 IP 地址&amp;gt;
    [ens33] 00:0c:29:19:82:b4
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5. zabbix【扎-比斯】_sender 是一个命令行工具&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★ 功能：用于主动将监控数据发送到 Zabbix Server 或 Proxy。它通常在被监控主机上运行，配合脚本使用。
★ 安装：
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    [root@Zabbix_Agent ~]# # 在 CentOS/RHEL 系统上
    [root@Zabbix_Agent ~]# yum install zabbix-sender
    [root@Zabbix_Agent ~]# # 在 Debian/Ubuntu 系统上
    [root@Zabbix_Agent ~]# apt-get install zabbix-sender
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;★ 语法格式：
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[root@Zabbix_Agent ~]# zabbix_sender -z &amp;lt;server_ip&amp;gt; -p &amp;lt;port&amp;gt; -s &amp;lt;hostname&amp;gt; -k &amp;lt;key&amp;gt; -o &amp;lt;value&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-z&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Zabbix Server 或 Proxy 的 IP 地址&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-p&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Zabbix Server 的端口，默认是 10051（不是 10050！）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;目标主机在 Zabbix Web 中的 Host name，必须完全一致&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-k&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;要发送的 Item 的 Key（必须在 Web 中创建为 “Zabbix trapper” 类型）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-o&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;要发送的数据值（value）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;★ 例句：
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;#假设你想监控一台服务器的“磁盘空间使用率”，并在脚本中上报：
#!/bin/bash
# 检查磁盘使用率
disk_usage=$(df / | tail -1 | awk &apos;{print $5}&apos; | sed &apos;s/%//&apos;)

# 使用 zabbix_sender 发送
zabbix_sender \
  -z 192.168.1.100 \
  -p 10051 \
  -s &quot;web-server-01&quot; \
  -k &quot;disk.usage.percent&quot; \
  -o &quot;$disk_usage&quot;
  
在 Zabbix Web 中需预先创建：
主机名：web-server-01
Item Key：disk.usage.percent
Type：Zabbix trapper



#批量发送多个 key-value 对
zabbix_sender \
  -z 192.168.1.100 \
  -p 10051 \
  -s &quot;web-server-01&quot; \
  -i /tmp/data.txt
  
其中 /tmp/data.txt 文件内容如下：
disk.usage.percent 85
cpu.load.avg 0.3
memory.used.mb 1200
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;与 zabbix_get 的对比&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;&lt;code&gt;zabbix_get&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;zabbix_sender&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;方向&lt;/td&gt;
&lt;td&gt;Server → Agent&lt;/td&gt;
&lt;td&gt;Client → Server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;用途&lt;/td&gt;
&lt;td&gt;从 Agent 拉取数据&lt;/td&gt;
&lt;td&gt;向 Server 推送数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;端口&lt;/td&gt;
&lt;td&gt;10050（Agent 端口）&lt;/td&gt;
&lt;td&gt;10051（Server 端口）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;数据类型&lt;/td&gt;
&lt;td&gt;只能获取已配置的 item&lt;/td&gt;
&lt;td&gt;可推送任意 key-value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;使用场景&lt;/td&gt;
&lt;td&gt;测试 Agent 是否正常&lt;/td&gt;
&lt;td&gt;自定义监控、脚本上报&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;二、了解Zabbix【扎-比斯】 通讯机制&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;我们需要了解 Zabbix 性能监控管理平台中各个重要服务进程之间的通讯机制，从而指导我们在确保网络安全性的前提下，正确的配置防火墙规则。
本章十分重要，在生产环境中，网络防火墙安全机制是必不可少的，请大家务必理解并牢记 Zabbix 通讯机制，从而掌握正确配置防火墙规则的指导思想。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1. Zabbix【扎-比斯】 的两种&amp;lt;监视模式&amp;gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★ 被动模式：&amp;lt;数据采集方&amp;gt;主动向&amp;lt;数据提供方&amp;gt;查询&amp;lt;性能指标数据&amp;gt; ◀ 默认：已启动&amp;lt;被动模式&amp;gt;
★ 主动模式：&amp;lt;数据提供方&amp;gt;主动向&amp;lt;数据采集方&amp;gt;汇报&amp;lt;性能指标数据&amp;gt; ◀ 默认：未启动&amp;lt;主动模式&amp;gt;

★ zabbix_server     是：&amp;lt;数据采集方&amp;gt;，其&amp;lt;侦听端口&amp;gt;默认为 10051/tcp（默认：未启用）。
★ zabbix_agentd     是：&amp;lt;数据提供方&amp;gt;，其&amp;lt;侦听端口&amp;gt;默认为 10050/tcp。
★ zabbix_proxy      是：&amp;lt;数据采集方&amp;gt;和&amp;lt;数据提供方&amp;gt;。
                        ♦ 作为&amp;lt;数据采集方&amp;gt;，其&amp;lt;侦听端口&amp;gt;默认为 10051/tcp（默认：未启用）。
                        ♦ 作为&amp;lt;数据提供方&amp;gt;，其&amp;lt;侦听端口&amp;gt;默认为 10050/tcp。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. Zabbix【扎-比斯】 组件间&amp;lt;通讯机制&amp;gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/285506250643847.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;Zabbix 分布式整体架构 + 全链路通信端口&lt;/h1&gt;
&lt;h2&gt;Zabbix 分布式整体架构（标准生产级）&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────────────┐
│                        Zabbix Server 集群                           │
│  ┌─────────────┐    ┌─────────────┐    ┌─────────────┐             │
│  │ Zabbix Server│◄───│ Zabbix Web  │    │  Database   │             │
│  │ (10051/tcp)  │───►│ (80/443/tcp)│◄──►│ (3306/5432) │             │
│  └─────────────┘    └─────────────┘    └─────────────┘             │
└───────────────────────────┬─────────────────────────────────────────┘
                            │ (10051/tcp)
          ┌─────────────────┴────────────────┬───────────────────────┐
          │                                  │                       │
┌─────────────────────┐        ┌─────────────────────┐    ┌─────────────────────┐
│ Zabbix Proxy 1       │        │ Zabbix Proxy 2       │    │ Zabbix Proxy N      │
│ (区域/机房/分支)    │        │ (区域/机房/分支)    │    │ (区域/机房/分支)   │
│ (10051/tcp)         │        │ (10051/tcp)         │    │ (10051/tcp)         │
└──────────┬───────────┘        └──────────┬───────────┘    └──────────┬───────────┘
           │ (10050/10051/tcp)              │ (10050/10051/tcp)        │ (10050/10051/tcp)
┌──────────┴───────────┐        ┌──────────┴───────────┐    ┌──────────┴───────────┐
│ 被监控主机            │        │ 被监控主机            │    │ 被监控主机            │
│ ┌─────────────────┐  │        │ ┌─────────────────┐  │    │ ┌─────────────────┐  │
│ │ Zabbix Agent2   │◄─┘        │ │ Zabbix Agent2   │◄─┘    │ │ Zabbix Agent2   │◄─┘
│ │ (10050/tcp)     │           │ │ (10050/tcp)     │       │ │ (10050/tcp)     │
│ └─────────────────┘           │ └─────────────────┘       │ └─────────────────┘
│ SNMP(161/udp)/IPMI(623/udp)   │ SNMP/IPMI/JMX       │    │ JMX(1099)/自定义端口 │
└──────────────────────────────┴───────────────────────────┴───────────────────────┘
## 核心通信端口说明
1. Agent ↔ Server/Proxy：10050/tcp（被动）、10051/tcp（主动）
2. Proxy → Server：10051/tcp
3. Web ↔ Database：3306/tcp（MySQL）、5432/tcp（PostgreSQL）
4. Web 访问：80/tcp（HTTP）、443/tcp（HTTPS）
5. 其他监控端口：161/udp（SNMP）、623/udp（IPMI）、1099/tcp（JMX）
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;graph LR
subgraph 1开始[Zabbix 分布式整体架构]
    
    subgraph a [Zabbix_Server 集群]
        direction RL
        模块一.一[Zabbix_Server 192.168.88.18:10051] --&amp;gt; 模块一.二[Zabbix_Web 192.168.88.17:80 ]
        模块一.二[Zabbix_Web 192.168.88.17:80 ] --&amp;gt; 模块一.一[Zabbix_Server 192.168.88.18:10051]
        模块一.三[mysql 192.168.88.16:3306] --&amp;gt; 模块一.二[Zabbix_Web 192.168.88.17:80 ]
    end
    
    subgraph b [Zabbix_Proxy 192.168.88.20:10051 可选]

    end
    
    subgraph c [Zabbix_Agent 192.168.88.30:10050/51]
    end
    
    a --&amp;gt;|192.168.88.18:10051 下发配置| b
    b --&amp;gt;|192.168.88.20:10051 上传数据| a
    b --&amp;gt;|192.168.88.20:10050/TCP 被动拉取| c
    c --&amp;gt;|192.168.88.30:10051/TCP 主动推送| b

end
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;核心通信端口（必须记住）&lt;/h2&gt;
&lt;h3&gt;1）Agent【A 撞 特】 → Server / Proxy【普洛西】（主动/被动）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;- **10050/tcp**：Agent 被动监听（Server/Proxy 主动拉数据）
- **10051/tcp**：Agent 主动推送（Agent → Server/Proxy）
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2）Proxy → Server&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;- **10051/tcp**：Proxy 上报数据到 Server
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3）Web → Database&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;- **3306/tcp**：MySQL（默认）
- **5432/tcp**：PostgreSQL
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4）Web 访问&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;- **80/tcp**、**443/tcp**：HTTP/HTTPS
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5）其他常用监控端口&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;- **161/udp**：SNMP
- **623/udp**：IPMI
- **123/udp**：NTP（时间同步）
- **JMX 端口**：通常 1099、自定义
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;一句话总结通信流向&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;- **被监控机** →(10051)→ **Proxy** →(10051)→ **Server**
- **Server** →(10050)→ **Agent**（被动模式）
- **Web** ←→ **DB**、**Web** ←→ 用户
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;核心端口总结&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;通信方向&lt;/th&gt;
&lt;th&gt;端口&lt;/th&gt;
&lt;th&gt;协议&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Agent ↔ Server/Proxy&lt;/td&gt;
&lt;td&gt;10050&lt;/td&gt;
&lt;td&gt;TCP&lt;/td&gt;
&lt;td&gt;Agent 被动监听&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent → Server/Proxy&lt;/td&gt;
&lt;td&gt;10051&lt;/td&gt;
&lt;td&gt;TCP&lt;/td&gt;
&lt;td&gt;Agent 主动推送&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Proxy → Server&lt;/td&gt;
&lt;td&gt;10051&lt;/td&gt;
&lt;td&gt;TCP&lt;/td&gt;
&lt;td&gt;Proxy 上报数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Web → MySQL&lt;/td&gt;
&lt;td&gt;3306&lt;/td&gt;
&lt;td&gt;TCP&lt;/td&gt;
&lt;td&gt;数据库通信&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Web → PostgreSQL&lt;/td&gt;
&lt;td&gt;5432&lt;/td&gt;
&lt;td&gt;TCP&lt;/td&gt;
&lt;td&gt;数据库通信&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;用户 → Web&lt;/td&gt;
&lt;td&gt;80/443&lt;/td&gt;
&lt;td&gt;TCP&lt;/td&gt;
&lt;td&gt;HTTP/HTTPS 访问&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;监控 → 网络设备&lt;/td&gt;
&lt;td&gt;161&lt;/td&gt;
&lt;td&gt;UDP&lt;/td&gt;
&lt;td&gt;SNMP 监控&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;★ 作业&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;请问：zabbix_get 命令的功能是什么？是在 Zabbix Server 端使用？还是在 Zabbix Agent 端使用？
答：
功能：向&amp;lt;Zabbix agent 客户端代理&amp;gt;发出&amp;lt;数据采集请求&amp;gt;。
在Zabbix Server 端使用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;请问：zabbix_sender 命令的功能是什么？是在 Zabbix Server 端使用？还是在 Zabbix Agent 端使用？
答：
功能： 主动向 Zabbix Server（或 Proxy）发送监控数据（item values）。
在 Zabbix Agent 端使用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;请画出：Zabbix 分布式整体架构图与通信端口&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;graph LR
subgraph 1开始[Zabbix 分布式整体架构]
    
    subgraph a [Zabbix_Server 集群]
        direction RL
        模块一.一[Zabbix_Server 192.168.88.18:10051] --&amp;gt; 模块一.二[Zabbix_Web 192.168.88.17:80 ]
        模块一.二[Zabbix_Web 192.168.88.17:80 ] --&amp;gt; 模块一.一[Zabbix_Server 192.168.88.18:10051]
        模块一.三[mysql 192.168.88.16:3306] --&amp;gt; 模块一.二[Zabbix_Web 192.168.88.17:80 ]
    end
    
    subgraph b [Zabbix_Proxy 192.168.88.20:10051 可选]

    end
    
    subgraph c [Zabbix_Agent 192.168.88.30:10050/51]
    end
    
    a --&amp;gt;|192.168.88.18:10051 下发配置| b
    b --&amp;gt;|192.168.88.20:10051 上传数据| a
    b --&amp;gt;|192.168.88.20:10050/TCP 被动拉取| c
    c --&amp;gt;|192.168.88.30:10051/TCP 主动推送| b

end
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>04-Zabbix-监控对象管理</title><link>https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/04-zabbix-%E7%9B%91%E6%8E%A7%E5%AF%B9%E8%B1%A1%E7%AE%A1%E7%90%86/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/04-zabbix-%E7%9B%91%E6%8E%A7%E5%AF%B9%E8%B1%A1%E7%AE%A1%E7%90%86/</guid><description>Zabbix 6.4 分布式企业级性能监控平台 - 运维知识库笔记</description><pubDate>Thu, 04 Jun 2026 00:24:00 GMT</pubDate><content:encoded>&lt;h1&gt;Zabbix 6.4 分布式企业级性能监控平台&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;Zabbix 监控对象管理
官网：https://www.zabbix.com/cn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/117075162608236.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、实验环境&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;节点&lt;/th&gt;
&lt;th&gt;角色&lt;/th&gt;
&lt;th&gt;IP 地址&lt;/th&gt;
&lt;th&gt;操作系统：&lt;/th&gt;
&lt;th&gt;硬件规格&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-16&lt;/td&gt;
&lt;td&gt;MySQL 数据库(版本：8.0) &amp;lt;br&amp;gt;加装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.16/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-17&lt;/td&gt;
&lt;td&gt;Nginx + PHP Web 前端 &amp;lt;br&amp;gt;加装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.17/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-18&lt;/td&gt;
&lt;td&gt;Zabbix Server 核心服务(版本：6.4)&lt;/td&gt;
&lt;td&gt;192.168.168.18/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-19&lt;/td&gt;
&lt;td&gt;被监控主机 &amp;lt;br&amp;gt;安装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.19/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;二、主机群组（Host Groups）&lt;/h2&gt;
&lt;h3&gt;1. 功能：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★ &amp;lt;Host Groups 主机群组&amp;gt;是：一个对&amp;lt;主机对象&amp;gt;的&amp;lt;逻辑分组&amp;gt;。
    ♦ 我们可以配置&amp;lt;用户群组&amp;gt;来针对&amp;lt;Host Groups 主机群组&amp;gt;拥有&amp;lt;读写、读、拒绝、无&amp;gt;的权限。
    ♦ 在&amp;lt;Host Groups 主机群组&amp;gt;中，可以包含&amp;lt;主机对象&amp;gt;和&amp;lt;模板对象&amp;gt;。
★ 注意：
    ♦ &amp;lt;Host Groups 主机群组&amp;gt;并未采用&amp;lt;任何方式&amp;gt;在&amp;lt;主机对象&amp;gt;和&amp;lt;模板对象&amp;gt;之间的建立&amp;lt;关联关系&amp;gt;。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 要素：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★ &amp;lt;主机群组&amp;gt;的&amp;lt;组名称&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 创建：主机群组（Host Groups）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★  Web 控制台
        ↓
    Configuration 
        ↓
    Host groups 
        ↓
    右上角：Create host group 
        ├→ [Group name 栏] → 输入：&amp;lt;主机组名称&amp;gt;&amp;gt;
        ├→ [Add]（执行：添加操作）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/549558012980060.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;三、 主机（Hosts）&lt;/h2&gt;
&lt;h3&gt;1. 功能：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★ &amp;lt;Hosts 主机&amp;gt;是：一个对&amp;lt;被监控对象&amp;gt;。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 要素：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;(1) &amp;lt;Hosts 主机&amp;gt;在&amp;lt;Zabbix 平台&amp;gt;中的&amp;lt;唯一性的对象标识名称&amp;gt;
(2) &amp;lt;Hosts 主机&amp;gt;所属的&amp;lt;Host Groups 主机群组&amp;gt;
(3) &amp;lt;Hosts 主机&amp;gt;对应&amp;lt;真实物理设备&amp;gt;的&amp;lt;监视方式&amp;gt;（默认为：Zabbix Agent 客户端代理方式）
(4) &amp;lt;Hosts 主机&amp;gt;关联的&amp;lt;监视模板&amp;gt;
(5) &amp;lt;Hosts 主机&amp;gt;的&amp;lt;资产信息&amp;gt;
(6) 判断：针对&amp;lt;Hosts 主机&amp;gt;的&amp;lt;性能监视&amp;gt;是否成功？
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 创建：主机（Hosts）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★  Web 控制台
        ↓
    Configuration 
        ↓
    Hosts
        ↓
    右上角：Create host 
        ↓
    Host（创建：主机对象）
        ├→ [Host name 栏]  → 输入：&amp;lt;主机名&amp;gt;，该&amp;lt;主机名&amp;gt;与&amp;lt;真实主机名&amp;gt;和&amp;lt;Zabbix Agen 配置文件&amp;gt;中的&amp;lt;自动注册名&amp;gt;无关
        ├→ [Groups 栏]     → 选择：&amp;lt;主机组&amp;gt;
        ├→ [Interfaces 栏] → 选择：&amp;lt;真实主机&amp;gt;的&amp;lt;连接方式、IP 地址/主机名、端口...等等&amp;gt;
        │                         ♦ 默认采用：&amp;lt;Zabbix Agent 代理&amp;gt;&amp;lt;连接方式&amp;gt;
        ├→ [Enabled 栏]    → 选中：Enabled（默认：已被选中）
        ↓
    Templates（选择：关联的&amp;lt;监视模板&amp;gt;）
        ↓
    Inventory（录入：主机的资产信息）
        ↓
    [Add]（执行：添加操作）
        ↓
    观察&amp;lt;Zabbix 主机&amp;gt;的&amp;lt;状态&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/521615227078507.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/159108727344683.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/383735791106220.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/553837153970572.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;四、 Discovery 自动发现与监控&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;在工作中，为了减轻手动添加的工作量，我们往往希望&amp;lt;Zabbix 服务端&amp;gt;可以主动发现并监控&amp;lt;设备对象&amp;gt;。
为此，我们可以在&amp;lt;Zabbix 服务端&amp;gt;上，配置&amp;lt;Discovery 自动发现 + Discovery 发现动作&amp;gt;来实现&amp;lt;Discovery 自动发现与监控&amp;gt;。
★ 注意：
    ♦ (1) &amp;lt;Discovery 发现规则&amp;gt;：采用的是&amp;lt;被动模式&amp;gt;，&amp;lt;发现了目标&amp;gt;不等于&amp;lt;监控了目标&amp;gt;。
    ♦ (2) &amp;lt;Discovery 发现动作&amp;gt;：基于&amp;lt;Discovery 发现规则&amp;gt;，来自动链接&amp;lt;指定的 Template 监控模板&amp;gt;，从而最终实现监控。
★ 注意：
    ♦ 在&amp;lt;Templates/Operating systems/Linux by Zabbix agent 模块&amp;gt;中，已预制了 3 个&amp;lt;Discovery 发现规则&amp;gt;。
    (1) Block devices discovery（用于发现：块设备）
        注意：Update interval: 1h（更新时间间隔为：1 小时，因此，不会立即看到发现结果）
    (2) Mounted filesystem discovery（用于发现：文件系统挂载）
        注意：Update interval: 1h（更新时间间隔为：1 小时，因此，不会立即看到发现结果）
    (3) Network interface discovery（用于发现：网卡设备）
        注意：Update interval: 1h（更新时间间隔为：1 小时，因此，不会立即看到发现结果）
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1. 创建：&amp;lt;Discovery 发现规则&amp;gt;&lt;/h3&gt;
&lt;h4&gt;(1) 步骤说明：&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;★  Web 控制台
        ↓
    Configuration # 配置
        ↓
    Discovery # 自动发现
        ↓
    右上角：Create discovery rule
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;(2) 解析：定义栏&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;##
## ♦ Name                 ## 定义：发现规则名称。
## ♦ Discovery by proxy   ## 选择：是否采用&amp;lt;Zabbix Proxy 分布式代理&amp;gt;来执行&amp;lt;自动发现&amp;gt;，默认为：No proxy。
## ♦ IP range             ## 定义：IP 扫描范围，如：192.168.168.1-192.168.168.254 ◀ 注意：大范围 IP 扫描，是需要时间的。
## ♦ Update interval      ## 定义：周期性执行&amp;lt;自动发现&amp;gt;的&amp;lt;时间间隔&amp;gt;，可以使用 s、m、h、d、w 时间单位。
## ♦ Checks               ## 定义：执行&amp;lt;自动发现&amp;gt;的&amp;lt;探测方法&amp;gt;，可以添加多种&amp;lt;探测方法&amp;gt;。
##                                ◢ 注意：满足任何一种方法，均视为&amp;lt;发现 OK&amp;gt;
##                                ◢ 支持：SSH, LDAP、SMTP、FTP、HTTP、HTTPS、POP、NNTP、IMAP、TCP、Telnet、
##                                        Zabbix agent、SNMPv1 agent、SNMPv2 agent、SNMPv3 agent、ICMP ping 多种方法。
## ♦ Device uniqueness criteria ## 定义：&amp;lt;Zabbix 主机对象唯一性&amp;gt;的保障方法（如：IP 地址），如若重复，则保留先发现的，不添加后发现的。
##                                      
## ♦ Host name            ## 定义：&amp;lt;Zabbix 主机对象&amp;gt;的&amp;lt;主机名称&amp;gt;。
##                                ◢ 可以采用：DNS name、IP address、Zabbix agent 采样值、SNMP agent 采样值。
## ♦ Visible name         ## 定义：&amp;lt;Zabbix 主机对象&amp;gt;的&amp;lt;可见主机名称&amp;gt;。
##                                ◢ 可以采用：Host name、DNS name、IP address、Zabbix agent 采样值、SNMP agent 采样值。
## ♦ Enabled              ## 选择：立即启用
##
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;(3) 案例演示：&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;★ 配置：&amp;lt;Zabbix 服务端&amp;gt;自动发现&amp;lt;192.168.168.1-254 网络&amp;gt;中的&amp;lt;Zabbix Agent 客户端主机&amp;gt;
##
## ♦ Name                         ：Discovery Zabbix Agent Client Hosts Rule
## ♦ Discovery by proxy           ：No proxy
## ♦ IP range                     ：192.168.168.1-254
## ♦ Update interval              ：5m
## ♦ Checks                       ：添加 Zabbix agent 的 &quot;agent.ping&quot; KEY 键
                                    添加 Zabbix agent &quot;system.hostname[host]&quot; KEY 键
                                    添加 Zabbix agent &quot;system.uname&quot; KEY 键
## ♦ Device uniqueness criteria   ：采用 IP address，来作为&amp;lt;对象唯一性&amp;gt;的保障方法
## ♦ Host name                    ：采用 Zabbix agent &quot;system.uname&quot; 采样值，来作为&amp;lt;主机名&amp;gt;
## ♦ Visible name                 ：采用 Zabbix agent &quot;system.hostname[host]&quot; 采样值，来作为&amp;lt;可见主机名&amp;gt;
## ♦ Enabled                      ：选择&amp;lt;立即启用&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/188176259264097.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/309147351624597.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;2. 创建：&amp;lt;Discovery 发现动作&amp;gt;&lt;/h3&gt;
&lt;h4&gt;(1) 步骤说明：&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;★  Web 控制台
        ↓
    Configuration # 配置
        ↓
    Actions # 动作
        ↓
    左上角：下拉选择 Discovery actions 发现动作
        ↓
    右上角：Create action # 创建动作
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;(2) 解析：定义栏&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;★ Action 动作规则栏：
    ## ♦ Name             ## 定义：&amp;lt;动作规则&amp;gt;的&amp;lt;名称&amp;gt;。
    ## ♦ Conditions       ## 定义：&amp;lt;动作规则&amp;gt;的&amp;lt;匹配条件&amp;gt;。
    ##                            ♦ 例如：采用&amp;lt;Discovery rule 发现规则&amp;gt;作为&amp;lt;匹配条件&amp;gt;。
    ##                            ♦ 可添加：一个或多个需要同时满足的&amp;lt;匹配条件&amp;gt;。
    ## ♦ Enabled          ## 选择：立即启用。
★ Operations 附加操作栏：
    ## ♦ Operations       ## 定义：&amp;lt;动作规则&amp;gt;匹配之后，需要执行的&amp;lt;操作&amp;gt;
    ##                            ♦ 例如：链接&amp;lt;指定的 Template 模块&amp;gt;
    ##                            ♦ 可以添加：一个或多个需要执行的&amp;lt;操作&amp;gt;。
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;(3) 案例演示：&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;★ 配置：&amp;lt;Zabbix 服务端&amp;gt;在发现了&amp;lt;Zabbix Agent 客户端主机&amp;gt;之后，自动链接&amp;lt;指定 Template 模板&amp;gt;
    ## ♦ Name              ：Link Template Rule for Discovery Zabbix Agent Client Hosts Rule
    ## ♦ Conditions 条件 1 ：须匹配&amp;lt;Discovery rule equals Discovery Zabbix Agent Client Hosts Rule&amp;gt;规则
    ##              条件 2 ：须匹配&amp;lt;Host IP equals 192.168.168.1-254&amp;gt;规则
    ## ♦ Enabled           ：选择&amp;lt;立即启用&amp;gt;
★ Action 动作规则栏：
    ## ♦ Operations 动作 1 ：执行 Link to templates: Template OS Linux by Zabbix agent 链接模板动作   # 与模板关联--选择--Template--Linux by Zabbix agent
    ##              动作 2 ：执行 Add to host groups: Linux servers 加入主机组动作                    # 添加到主机群组 -- 选择 -- Linux servers
    ##              动作 3 ：执行 Enable host 立即启用动作                                            # 启用主机
★ Operations 附加操作栏：
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/522860783160877.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/139812455359737.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/260352125523413.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;五、 Autoregistration 自动注册与监控&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;我们可以站在&amp;lt;Zabbix 服务端&amp;gt;的角度，来通过&amp;lt;Discovery 自动发现 + Discovery 发现动作&amp;gt;来实现&amp;lt;Discovery 自动发现与监控&amp;gt;，也可以站在&amp;lt;被监控端&amp;gt;的角度，来主动向&amp;lt;Zabbix 服务端&amp;gt;发出&amp;lt;注册请求&amp;gt;，从而实现被监控。

★ &amp;lt;Autoregistration 注册&amp;gt;分为以下两个配置步骤：
    ♦ 步骤 1：在&amp;lt;Zabbix Agent 客户端&amp;gt;，配置开启&amp;lt;自动注册功能&amp;gt;
    ♦ 步骤 2：在&amp;lt;Zabbix Server 服务端&amp;gt;，配置执行&amp;lt;自动注册动作&amp;gt;
★ 注意：
    ♦ (1) &amp;lt;Autoregistration 注册&amp;gt;：采用的是&amp;lt;主动模式&amp;gt;。
    ♦ (2) &amp;lt;Autoregistration 注册&amp;gt;：注册成功之后，就意味着&amp;lt;Zabbix 服务端&amp;gt;可以成功监控&amp;lt;客户端&amp;gt;了。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1. 配置：&amp;lt;Zabbix Agent 客户端&amp;gt;开启&amp;lt;Autoregistration 自动注册功能&amp;gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;##
## 我们可以在&amp;lt;/etc/zabbix/zabbix_agentd.d 目录&amp;gt;创建一个&amp;lt;独立的配置文件&amp;gt;，来方便地配置&amp;lt;自动注册&amp;gt;
## 在配置&amp;lt;Zabbix 客户端&amp;gt;执行&amp;lt;自动注册&amp;gt;的过程中，我们需要：
##     (1) 指定：&amp;lt;Zabbix 客户端&amp;gt;需要向谁发出&amp;lt;注册请求&amp;gt;
##     (2) 设置：&amp;lt;Zabbix 客户端&amp;gt;的&amp;lt;注册名称&amp;gt;，用于在&amp;lt;Zabbix 服务端&amp;gt;注册生成&amp;lt;Host 主机标签名&amp;gt;
##              注册生成&amp;lt;Host 主机标签名&amp;gt;的方法有两种：
##                 ♦ 第一种 采用：手动指定&amp;lt;自定义 Host 主机标签名&amp;gt;（Hostname=xxx）
##                 ♦ 第二种 采用：获取指定&amp;lt;Item_Key 返回值&amp;gt;（HostnameItem=item_key）
##     (3) 设置：为&amp;lt;Zabbix 服务端&amp;gt;的&amp;lt;自动注册动作&amp;gt;提供的&amp;lt;元数据&amp;gt;，从而有利于基于&amp;lt;不同的元数据&amp;gt;来执行&amp;lt;不同的自动注册动作&amp;gt;
##             定义&amp;lt;元数据&amp;gt;的方法有两种：
##                 ♦ 第一种 匹配：手动指定&amp;lt;自定义元数据&amp;gt;（HostMetadata=xxx）
##                 ♦ 第一种 匹配：获取指定&amp;lt;Item_Key 返回值&amp;gt;（HostMetadataItem=item_key）
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    vi /etc/zabbix/zabbix_agentd.d/autoActiveRegistration.conf
        ## -----------------------------------------------------------------
        ## 设置开启：&amp;lt;客户端&amp;gt;的&amp;lt;主动模式&amp;gt;，指定&amp;lt;Zabbix Server 服务器&amp;gt;的&amp;lt;IP 地址&amp;gt;
        ##
        ServerActive=192.168.168.18:10051
        ## -----------------------------------------------------------------
        ## 设置采用：手动指定的&amp;lt;自定义 Host 主机标签名&amp;gt;（方法 1：Hostname）
        ##          ① 须确保&amp;lt;自定义 Host 主机标签名&amp;gt;的&amp;lt;唯一性&amp;gt;
        ##          ② 在&amp;lt;云平台&amp;gt;中，&amp;lt;云主机&amp;gt;的&amp;lt;主机名&amp;gt;是通过&amp;lt;UUID 号&amp;gt;来确保&amp;lt;唯一性&amp;gt;，因此建议使用&amp;lt;HostnameItem 参数&amp;gt;
        ##          Hostname=rocky-9-10
        ##
        ## 设置采用：获取指定的&amp;lt;Item_Key 返回值&amp;gt;作为&amp;lt;Host 主机标签名&amp;gt;（方法 2：HostnameItem）
        ##          ① Zabbix 可以通过&amp;lt;system.hostname 内置键&amp;gt;来获取&amp;lt;客户端主机名&amp;gt;
        ##          ② 在&amp;lt;云平台&amp;gt;中，&amp;lt;云主机&amp;gt;的&amp;lt;主机名&amp;gt;是通过&amp;lt;UUID 号&amp;gt;来确保&amp;lt;唯一性&amp;gt;，因此建议使用&amp;lt;HostnameItem 参数&amp;gt;
        ##          注意：&amp;lt;Hostname 参数&amp;gt;会覆盖掉&amp;lt;HostnameItem 参数&amp;gt;。
        HostnameItem=system.hostname
        ## -----------------------------------------------------------------
        ## 设置匹配：手动指定&amp;lt;自定义元数据&amp;gt;（方法 1：HostMetadata）
        ##          ① &amp;lt;元数据标识字符串&amp;gt;的长度范围为 0~255。
        ##
        HostMetadata=ZabbixAgent1 on Linux
        ##
        ## 设置匹配：获取指定&amp;lt;Item_Key 返回值&amp;gt;作为&amp;lt;元数据&amp;gt;（方法 2：HostMetadataItem）
        ##          ① &amp;lt;HostMetadataItem 参数&amp;gt;用于获取&amp;lt;Item_Key 返回值&amp;gt;。
        ##          ② &amp;lt;HostMetadataItem 参数&amp;gt;返回的&amp;lt;结果字符串&amp;gt;，其长度范围限制为 0~255。
        ##          ③ &amp;lt;HostMetadataItem 参数&amp;gt;可以使用&amp;lt;内置 Item_Key 键&amp;gt;,也可以使用&amp;lt;用户自定义 Item_Key 键&amp;gt;。
        ##          ④ 如何你希望使用&amp;lt;system.run[]内置键&amp;gt;，则需要开启&amp;lt;EnableRemoteCommands 参数&amp;gt;。
        ##          注意：&amp;lt;HostMetadata 参数&amp;gt;会覆盖掉&amp;lt;HostMetadataItem 参数&amp;gt;。
        ##          HostMetadataItem=system.uname
        
    systemctl restart zabbix-agent.service
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 确保：&amp;lt;Zabbix Server 服务端&amp;gt;侦听&amp;lt;10051/tcp 端口&amp;gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;##
## 须在/etc/zabbix/zabbix_server.conf 配置文件中，确保：
##                                              ♦ 侦听：&amp;lt;10051/tcp 端口&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    vi /etc/zabbix/zabbix_server.conf
        ... ...
        ### Option: ListenPort
        #     Listen port for trapper.
        #
        # Mandatory: no
        # Range: 1024-32767
        # Default:
        # ListenPort=10051 该&amp;lt;侦听端口&amp;gt;默认已启用，可以不用明确定义，除非你要更改这个&amp;lt;侦听端口&amp;gt;
        ListenPort=10051
        ... ...
    systemctl restart zabbix-server.service
    firewall-cmd --permanent --zone=public --add-port=10051/tcp
    firewall-cmd --reload
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 配置：&amp;lt;Zabbix Server 服务端&amp;gt;执行&amp;lt;Autoregistration 自动注册动作&amp;gt;&lt;/h3&gt;
&lt;h4&gt;(1) 步骤说明：&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;★ Web 控制台 → Configuration → Actions → 右上角：下拉选择 Autoregistration actions 自动注册动作
                                                    ↓
                                                Create action
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;(2) 解析：定义栏&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;★ Action 动作规则栏：
    ## ♦ Name             ## 定义：&amp;lt;动作规则&amp;gt;的&amp;lt;名称&amp;gt;。
    ## ♦ Conditions       ## 定义：&amp;lt;动作规则&amp;gt;的&amp;lt;匹配条件&amp;gt;。
    ##                            ♦ 可以选择 ：Host name 方法、Host metadata 方法、Proxy 方法。
    ##                            ♦ 可以添加：一个或多个需要同时满足的&amp;lt;匹配条件&amp;gt;。
    ## ♦ Enabled          ## 选择：立即启用。
★ Operations 附加操作栏：
    ## ♦ Operations       ## 定义：&amp;lt;动作规则&amp;gt;匹配之后，需要执行的&amp;lt;操作&amp;gt;。
    ##                            ♦ 例如：链接&amp;lt;指定的 Template 模块&amp;gt;。
    ##                            ♦ 可以添加：一个或多个需要执行的&amp;lt;操作&amp;gt;。
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;(3) 案例演示：&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;★ 配置：&amp;lt;Zabbix 服务端&amp;gt;自动发现&amp;lt;192.168.168.1-254 网络&amp;gt;中的&amp;lt;Zabbix Agent 客户端主机&amp;gt;
    ## ♦ Name       ：Auto Registration Zabbix Agent v1 Linux Client Hosts Rule
    ## ♦ Conditions ：添加 Host metadata 方法（元数据标识为：ZabbixAgent1 on Linux）
    ## ♦ Operations ：添加执行：Add host ：添加执行：Add to host groups: Linux servers 加入主机组动作
                    ：添加执行：Link to templates: Template OS Linux by Zabbix agent 链接模板动作
                    ：添加执行：Enable host 立即启用动作
    ## ♦ Enabled ：选择&amp;lt;立即启用&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/61585076449751.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/168334771447817.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/259703965825522.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/392573010921355.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;★ 查看：自动注册的结果
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/101853130244610.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;★ 作业&lt;/h2&gt;
&lt;h3&gt;1&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;当前你已经部署好了一台 Zabbix Server 核心服务器，现在有 1 台 Rocky Linux 9 服务器，请在 Zabbix 监控平台上，采用手动添加方式来监控该 Rocky Linux 9 服务器，并链接内置的监控模板。
&lt;img src=&quot;/images/zabbix/598994078944480.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/363925023525014.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/575605200268004.webp&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;当前你已经部署好了一台 Zabbix Server 核心服务器，现在有 2 台 Rocky Linux 9 服务器，请在 Zabbix 监控平台上，采用自动发现和发现动作，来监控这 2 台 Rocky Linux 9 服务器。
&lt;img src=&quot;/images/zabbix/484659263533743.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/29116152661502.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/539979493118906.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/408006104398608.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/43620407775537.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/260522359290148.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/512304934158279.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/508412572828400.webp&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;当前你已经部署好了一台 Zabbix Server 核心服务器，现在有 2 台 Rocky Linux 9 服务器，请在 Zabbix 监控平台上，采用自动注册和注册动作，来监控这 2 台 Rocky Linux 9 服务器。
&lt;img src=&quot;/images/zabbix/429825147207977.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/112131404905201.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/322444341042444.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/401031639755945.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/346545707495791.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/146673108556047.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/135284137621642.webp&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>05-Zabbix-Items-监控项</title><link>https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/05-zabbix-items-%E7%9B%91%E6%8E%A7%E9%A1%B9/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/05-zabbix-items-%E7%9B%91%E6%8E%A7%E9%A1%B9/</guid><description>Zabbix 6.4 分布式企业级性能监控平台 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 23:25:00 GMT</pubDate><content:encoded>&lt;h1&gt;Zabbix 6.4 分布式企业级性能监控平台&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;Zabbix Items 监控项
官网：https://www.zabbix.com/cn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/117075162608236.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、实验环境&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;节点&lt;/th&gt;
&lt;th&gt;角色&lt;/th&gt;
&lt;th&gt;IP 地址&lt;/th&gt;
&lt;th&gt;操作系统：&lt;/th&gt;
&lt;th&gt;硬件规格&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-16&lt;/td&gt;
&lt;td&gt;MySQL 数据库(版本：8.0) &amp;lt;br&amp;gt; 加装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.16/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-17&lt;/td&gt;
&lt;td&gt;Nginx + PHP Web 前端  &amp;lt;br&amp;gt; 加装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.17/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-18&lt;/td&gt;
&lt;td&gt;Zabbix Server 核心服务(版本：6.4)&lt;/td&gt;
&lt;td&gt;192.168.168.18/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-19&lt;/td&gt;
&lt;td&gt;被监控主机  &amp;lt;br&amp;gt; 安装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.19/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;二、 了解 Items 监控项&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;衡量一个人的身体健康状态，需要通过一个个的健康检查手段来获取其身高、体重、心跳、血压 等健康指标值，因此，这些&amp;lt;健康检查手段&amp;gt;就是一个个的&amp;lt;Items 监控项&amp;gt;。
★ &amp;lt;Items 监控项&amp;gt;官方指南：
    https://www.zabbix.com/documentation/6.0/en/manual/config/items 
★ &amp;lt;Zabbix Agent&amp;gt;的&amp;lt;内置 Key 监控键&amp;gt;：
    https://www.zabbix.com/documentation/6.0/en/manual/config/items/itemtypes/zabbix_agent
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1. 了解：&amp;lt;items 监控项&amp;gt;&lt;/h3&gt;
&lt;h4&gt;(1) &amp;lt;items 监控项&amp;gt;&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;    ★ &amp;lt;items 监控项&amp;gt;的作用：负责通过&amp;lt;Key 监控键&amp;gt;从&amp;lt;被监控设备&amp;gt;上收集&amp;lt;性能指标数据&amp;gt;。
    ★ &amp;lt;items 监控项&amp;gt;的类型：Zabbix agent(被动模式)、Zabbix agent(主动模式)、SNMP agent、SNMP traps、IPMI ... 等等
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;(2) &amp;lt;Key 监控键&amp;gt;&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;    ★ &amp;lt;Key 监控键&amp;gt;的作用：负责定义一个用于收集&amp;lt;性能指标数据&amp;gt;的&amp;lt;方法&amp;gt;。
                          ♦ 某些&amp;lt;监控代理程序&amp;gt;（例如：Zabbix Agent）已经会为我们提供一些内置的&amp;lt;Key 监控键&amp;gt;。
    ★ &amp;lt;Key 监控键&amp;gt;的格式：Key_name + Key_value + 传参
                          ♦ Key_name 是：方法的&amp;lt;名称标识&amp;gt;
                          ♦ Key_value 是：方法的&amp;lt;实施细则&amp;gt;
                          ♦ 传参 是：方法的&amp;lt;可选参数&amp;gt;，有助于我们采集&amp;lt;特定维度的样本数据&amp;gt;
                                    例如：
                                        针对&amp;lt;身高&amp;gt;这个 Key 键，我们可以设置一个&amp;lt;姓名&amp;gt;参数，从而获取&amp;lt;指定人名的身高&amp;gt;。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/595330329054316.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;★ 举例说明：
    ##
    ## Zabbix Agent 内置的&amp;lt;Key 监控键&amp;gt;：system.cpu.load[&amp;lt;cpu&amp;gt;,&amp;lt;mode&amp;gt;]
    ##                                 system.cpu.load 就是：一个&amp;lt;名称标识&amp;gt;
    ##                                 [&amp;lt;cpu&amp;gt;,&amp;lt;mode&amp;gt;] 就是：两个传参
    ##                                                 &amp;lt;cpu&amp;gt; 参数：取值 all 表示计算：所有 CPU 的负载（这是：默认值）
    ##                                                             取值 percpu 表示计算：每 CPU 核心的负载（目前不支持）
    ##                                                 &amp;lt;mode&amp;gt;参数：取值 avg1 表示计算：1 分钟平均值（这是：默认值）
    ##                                                             取值 avg5 表示计算：5 分钟平均值
    ##                                                             取值 avg15 表示计算：15 分钟平均值
    ##
    ##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    system.cpu.load                       ## 表示：计算所有 CPU 的 1 分钟平均负载值 （第一个传参为默认值，第二个传参为默认值）
    system.cpu.load[,avg1]                ## 表示：计算所有 CPU 的 1 分钟平均负载值 （第一个传参为默认值，第二个传参为 avg1）
    system.cpu.load[all]                  ## 表示：计算所有 CPU 的 1 分钟平均负载值 （第一个传参为 all，第二个传参为默认值）
    system.cpu.load[all,avg1]             ## 表示：计算所有 CPU 的 1 分钟平均负载值 （第一个传参为 all，第二个传参为 avg1）
    system.cpu.load[all,avg5]             ## 表示：计算所有 CPU 的 5 分钟平均负载值 （第一个传参为 all，第二个传参为 avg5）
    system.cpu.load[all,avg15]            ## 表示：计算所有 CPU 的 15 分钟平均负载值（第一个传参为 all，第二个传参为 avg15）
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 了解：&amp;lt;Zabbix Agent&amp;gt;的&amp;lt;Key 内置监控键&amp;gt;&lt;/h3&gt;
&lt;h4&gt;(1) 列出：&amp;lt;Zabbix Agent&amp;gt;的&amp;lt;Key 内置监控键&amp;gt;&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;##
## 在&amp;lt;Zabbix Agent 客户端&amp;gt;上，执行以下命令：
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    zabbix_agentd -p
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/599613373513963.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;(2) 调用：&amp;lt;Zabbix Agent&amp;gt;的&amp;lt;Key 内置监控键&amp;gt;，从而获取相应的&amp;lt;性能指标数据&amp;gt;&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;##
## &amp;lt;Zabbix Server 服务端&amp;gt;，安装：zabbix-get 工具
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    yum install -y zabbix-get
    dnf install -y zabbix-get
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## &amp;lt;Zabbix Server 服务端&amp;gt;，采集：&amp;lt;Zabbix Agent&amp;gt;的&amp;lt;内置 Key 键值&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    zabbix_get -s 192.168.168.19 -k system.hw.cpu ## 查看：CPU 的全部信息
        ## -s 192.168.168.19 Zabbix Agent 客户端 IP 地址
        ## -k system.hw.cpu Zabbix Agent 客户端 Key 键名及键参数
    processor 0: GenuineIntel Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz working at 2592MHz
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;三、 应用 Items 监控项&lt;/h2&gt;
&lt;h3&gt;1. 举例 1：CPU 监控项&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/449614475534289.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;2. 举例 2：内存监控项&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;监控项名称（可以自定义名称）&lt;/th&gt;
&lt;th&gt;监控键&lt;/th&gt;
&lt;th&gt;含义说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Linux by Zabbix agent: Linux: Available memory&lt;/td&gt;
&lt;td&gt;vm.memory.size[available]&lt;/td&gt;
&lt;td&gt;物理内存可用空间（Byte）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Linux by Zabbix agent: Linux: Available memory in %&lt;/td&gt;
&lt;td&gt;vm.memory.size[pavailable]&lt;/td&gt;
&lt;td&gt;物理内存可用空间（%）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Linux by Zabbix agent: Linux: Total memory&lt;/td&gt;
&lt;td&gt;vm.memory.size[total]&lt;/td&gt;
&lt;td&gt;物理内存总体空间（Byte）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Linux by Zabbix agent: Linux: Free swap space&lt;/td&gt;
&lt;td&gt;system.swap.size[,free]&lt;/td&gt;
&lt;td&gt;SWAP 可用空间（Byte）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Linux by Zabbix agent: Linux: Free swap space in %&lt;/td&gt;
&lt;td&gt;system.swap.size[,pfree]&lt;/td&gt;
&lt;td&gt;SWAP 可用空间（%）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Linux by Zabbix agent: Linux: Total swap space&lt;/td&gt;
&lt;td&gt;system.swap.size[,total]&lt;/td&gt;
&lt;td&gt;SWAP 总体空间（Byte）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;3. 举例 3：磁盘监控项&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;监控项名称（可以自定义名称）&lt;/th&gt;
&lt;th&gt;监控键&lt;/th&gt;
&lt;th&gt;含义说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Mounted filesystem discovery: /: Free inodes in %&lt;/td&gt;
&lt;td&gt;vfs.fs.inode[/,pfree]&lt;/td&gt;
&lt;td&gt;/根分区的 inodes 节点剩余量（%）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Mounted filesystem discovery: /: Space utilization&lt;/td&gt;
&lt;td&gt;vfs.fs.size[/,pused]&lt;/td&gt;
&lt;td&gt;/根分区的剩余容量（%）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Mounted filesystem discovery: /: Used space&lt;/td&gt;
&lt;td&gt;vfs.fs.size[/,used]&lt;/td&gt;
&lt;td&gt;/根分区的已用容量（Byte）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Mounted filesystem discovery: /: Total space&lt;/td&gt;
&lt;td&gt;vfs.fs.size[/,total]&lt;/td&gt;
&lt;td&gt;/根分区的总体容量（Byte）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Mounted filesystem discovery: /boot: Free inodes in %&lt;/td&gt;
&lt;td&gt;vfs.fs.inode[/boot,pfree]&lt;/td&gt;
&lt;td&gt;/boot 分区的 inodes 节点剩余量（%）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Mounted filesystem discovery: /boot: Space utilization&lt;/td&gt;
&lt;td&gt;vfs.fs.size[/boot,pused]&lt;/td&gt;
&lt;td&gt;/boot 分区的剩余容量（%）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Mounted filesystem discovery: /boot: Used space&lt;/td&gt;
&lt;td&gt;vfs.fs.size[/boot,used]&lt;/td&gt;
&lt;td&gt;/boot 分区的已用容量（Byte）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Mounted filesystem discovery: /boot: Total space&lt;/td&gt;
&lt;td&gt;vfs.fs.size[/boot,total]&lt;/td&gt;
&lt;td&gt;/boot 分区的总体容量（Byte）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;4. 举例 4：网络监控项&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;监控项名称（可以自定义名称）&lt;/th&gt;
&lt;th&gt;监控键&lt;/th&gt;
&lt;th&gt;含义说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Interface ens33: Inbound packets discarded&lt;/td&gt;
&lt;td&gt;net.if.in[&quot;ens33&quot;,dropped]&lt;/td&gt;
&lt;td&gt;被丢弃的入站包(个数)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Interface ens33: Inbound packets with errors&lt;/td&gt;
&lt;td&gt;net.if.in[&quot;ens33&quot;,errors]&lt;/td&gt;
&lt;td&gt;错误的入站包(个数)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Interface ens33: Bits received&lt;/td&gt;
&lt;td&gt;net.if.in[&quot;ens33&quot;]&lt;/td&gt;
&lt;td&gt;接收的入站包（Byte）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Interface ens33: Outbound packets discarded&lt;/td&gt;
&lt;td&gt;net.if.out[&quot;ens33&quot;,dropped]&lt;/td&gt;
&lt;td&gt;被丢弃的出站包(个数)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Interface ens33: Outbound packets with errors&lt;/td&gt;
&lt;td&gt;net.if.out[&quot;ens33&quot;,errors]&lt;/td&gt;
&lt;td&gt;错误的出站包(个数)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Interface ens33: Bits sent&lt;/td&gt;
&lt;td&gt;net.if.out[&quot;ens33&quot;]&lt;/td&gt;
&lt;td&gt;接收的出站包（Byte）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Interface ens33: Operational status&lt;/td&gt;
&lt;td&gt;vfs.file.contents[&quot;/sys/class/net/ens33/operstate&quot;]&lt;/td&gt;
&lt;td&gt;接口状态值（数字）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Interface ens33: Speed&lt;/td&gt;
&lt;td&gt;vfs.file.contents[&quot;/sys/class/net/ens33/speed&quot;]&lt;/td&gt;
&lt;td&gt;接口速率规格（bps）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;Interface ens33: Interface type&lt;/td&gt;
&lt;td&gt;vfs.file.contents[&quot;/sys/class/net/ens33/type&quot;]&lt;/td&gt;
&lt;td&gt;接口协议类型（数字）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;5. 举例 5：进程监控项&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/376663039321787.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;6. 举例 6：内核监控项&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;监控项名称（可以自定义名称）&lt;/th&gt;
&lt;th&gt;监控键&lt;/th&gt;
&lt;th&gt;含义说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Linux by Zabbix agent: Linux: Maximum number of processes&lt;/td&gt;
&lt;td&gt;kernel.maxproc&lt;/td&gt;
&lt;td&gt;可执行的最大进程数（整数）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Linux by Zabbix agent: Linux: Maximum number of open file descriptors&lt;/td&gt;
&lt;td&gt;kernel.maxfiles&lt;/td&gt;
&lt;td&gt;可打开的最大文件数（整数）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;四、 自定义 Items 监控项&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;在工作中，默认已加载的&amp;lt;Items 监控项&amp;gt;不能实现全部的工作目标，我们需要创建&amp;lt;自定义 Items 监控项&amp;gt;；而创建&amp;lt;自定义 Items 监控项&amp;gt;，就需要先创建&amp;lt;自定义 Key 监控键&amp;gt;。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1. 创建：&amp;lt;Zabbix Agent 客户端代理&amp;gt;的&amp;lt;自定义 Key 监控键&amp;gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;创建&amp;lt;自定义 Key 监控键&amp;gt;有两种方法：
(1) 简单的命令法
(2) 强大的脚本法
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;(1) 方法 1：命令法（简单）&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;##
## 第一步：配置&amp;lt;Zabbix Agent 客户端代理&amp;gt;
##         ☛ 开启：针对&amp;lt;UserParameter 用户自定义 Key 键&amp;gt;的&amp;lt;传参功能&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    vi /etc/zabbix/zabbix_agentd.conf
        ... ...
        ##
        ## 导入：/etc/zabbix/zabbix_agentd.d/*conf 配置文件，从而方便我们增删配置（这是：默认配置）
        ##
        Include=/etc/zabbix/zabbix_agentd.d/*.conf
        ... ...
        ##
        ## 开启：针对&amp;lt;UserParameter 用户自定义 Key 键&amp;gt;的&amp;lt;传参功能&amp;gt;
        ##     UnsafeUserParameters=0 表示：不允许向&amp;lt;UserParameter 用户定义 Key 键&amp;gt;传递&amp;lt;键参数&amp;gt;
        ##     UnsafeUserParameters=1 表示：允许向&amp;lt;UserParameter 用户定义 Key 键&amp;gt;传递&amp;lt;键参数&amp;gt;
        ##       ♦ 传参过程中，不允许传递这些字符：\ &apos; &quot; ` * ? [ ] { } ~ $ ! &amp;amp; ; ( ) &amp;lt; &amp;gt; | # @
        ##       ♦ 传参过程中，也不允许传递&amp;lt;换行符&amp;gt;。
        ##
        UnsafeUserParameters=1
        ... ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## 第二步：配置&amp;lt;Zabbix Agent 客户端代理&amp;gt;
##         ☛ 定义：&amp;lt;Zabbix Agent 客户端代理&amp;gt;的&amp;lt;用户 Key 自定义键&amp;gt;
##                 ❃ Key 键功能：通过 ss 命令，来获取&amp;lt;Zabbix 客户端&amp;gt;的&amp;lt;tcp 或 udp 连接总数&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    vi /etc/zabbix/zabbix_agentd.d/myDiyKeys.conf
        ##
        ## 配置语法：
        ##         UserParameter=&amp;lt;方法名称&amp;gt;,&amp;lt;方法内容&amp;gt;
        ##         ## 允许：在一个&amp;lt;配置文件&amp;gt;中定义多个&amp;lt;UserParameter&amp;gt;
        ##
        ##         ## 方法内容：
        ##             ♦ 可以是&amp;lt;command 命令&amp;gt;或者&amp;lt;shell 脚本&amp;gt;
        ##             ♦ 可以使用&amp;lt;管道符&amp;gt;来组合&amp;lt;多个 command 命令&amp;gt;
        ##             ♦ 可以使用$1、$2、$3 ... 命令行传参
        ##
        ##         ## 方法名称（即：Key 键名）：
        ##             ♦ 可以直接就是&amp;lt;字符串&amp;gt;，如：net.if.connections.count
        ##             ♦ 也可定义一个&amp;lt;数组名&amp;gt;，如：net.if.connections.count[*]
        ##                 &amp;lt;*星号&amp;gt;是一个&amp;lt;通配符&amp;gt;，用于接收&amp;lt;命令 或 脚本&amp;gt;的&amp;lt;命令行传参&amp;gt;
        ##                 举例说明：
        ##                     假设：我们定义了 UserParameter=net.if.connections.count[*],ss $1 $2 -H | wc -l
        ##                     则调用方法如下：
        ##                         调用方法 1：net.if.connections.count[-t,-u] 或 net.if.connections.count[--tcp,--udp]
        ##                         调用方法 2：net.if.connections.count[-t] 或 net.if.connections.count[--tcp]
        ##                         调用方法 3：net.if.connections.count[-u] 或 net.if.connections.count[--udp]
        ##                         调用方法 4：net.if.connections.count[-tunl] 或 net.if.connections.count[-tu,-nl]
        ##
        UserParameter=net.if.connections.sum[*],ss $1 $2 -H | wc -l
    systemctl restart zabbix-agent.service
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## 第三步：在&amp;lt;Zabbix Server 服务端&amp;gt;上，执行测试
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    dnf install -y zabbix-get
    ## 获取：tcp 和 udp 连接数
    zabbix_get -s 192.168.168.19 -k net.if.connections.sum[-t,-u]
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;(2) 方法 2：脚本法（强大）&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;##
## 第一步：在&amp;lt;Zabbix Agent 客户端代理&amp;gt;上，编写&amp;lt;本地 Shell 脚本&amp;gt;
##         ☛ 脚本功能：获取&amp;lt;Zabbix 客户端&amp;gt;的&amp;lt;文件系统挂载点剩余空间&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    vi /etc/zabbix/zabbix_agentd.d/myShellScript01.sh
        #/bin/bash
        mountDir=$1
        df -h $mountDir | awk &apos;NR&amp;gt;1{print $4}&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## 第二步：配置&amp;lt;Zabbix Agent 客户端代理&amp;gt;
##         ☛ 开启：针对&amp;lt;UserParameter 用户自定义 Key 键&amp;gt;的&amp;lt;传参功能&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    vi /etc/zabbix/zabbix_agentd.conf
        ... ...
        ##
        ## 导入：/etc/zabbix/zabbix_agentd.d/*conf 配置文件，从而方便我们增删配置（这是：默认配置）
        ##
        Include=/etc/zabbix/zabbix_agentd.d/*.conf
        ... ...
        ##
        ## 开启：针对&amp;lt;UserParameter 用户定义 Key 键&amp;gt;的&amp;lt;传参功能&amp;gt;
        ##     UnsafeUserParameters=0 表示：不允许向&amp;lt;UserParameter 用户定义 Key 键&amp;gt;传递&amp;lt;键参数&amp;gt;
        ##     UnsafeUserParameters=1 表示：允许向&amp;lt;UserParameter 用户定义 Key 键&amp;gt;传递&amp;lt;键参数&amp;gt;
        ##         ♦ 传参过程中，不允许传递这些字符：\ &apos; &quot; ` * ? [ ] { } ~ $ ! &amp;amp; ; ( ) &amp;lt; &amp;gt; | # @
        ##         ♦ 传参过程中，也不允许传递&amp;lt;换行符&amp;gt;。
        ##  
        UnsafeUserParameters=1
        ... ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## 第三步：配置&amp;lt;Zabbix Agent 客户端代理&amp;gt;
##         ☛ 定义：调用&amp;lt;本地 Shell 脚本&amp;gt;的&amp;lt;Key 键&amp;gt;
##                 ❃ Key 键功能：通过&amp;lt;脚本&amp;gt;来获取&amp;lt;文件系统挂载点剩余空间&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    vi /etc/zabbix/zabbix_agentd.d/myDiyKeys.conf
        UserParameter=net.if.connections.sum[*],ss $1 $2 -H | wc -l
        ## 添加如下：
        UserParameter=mount.filesystem.size.free[*],bash /etc/zabbix/zabbix_agentd.d/myShellScript01.sh $1
    systemctl restart zabbix-agent.service
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## 第四步：在&amp;lt;Zabbix Server 服务端&amp;gt;上，执行测试
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    dnf install -y zabbix-get
    ## 获取：/挂载点的剩余空间
    zabbix_get -s 192.168.168.19 -k mount.filesystem.size.free[/]
    15G
    ## 获取：/boot 挂载点的剩余空间
    zabbix_get -s 192.168.168.19 -k mount.filesystem.size.free[/boot]
    1.7G
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;(3) 实用案例：脚本法&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;##
## 第一步：在&amp;lt;Zabbix Agent 客户端代理&amp;gt;上，编写&amp;lt;本地 Shell 脚本&amp;gt;
##         ☛ 脚本功能：获取&amp;lt;Zabbix 客户端网卡&amp;gt;的&amp;lt;当前传输速率&amp;gt;，计量单位为：B 字节/秒
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    vi /etc/zabbix/zabbix_agentd.d/myShellScript02.sh
        #/bin/bash
        ## $1 用于指定：网卡名称，如：ens33、ens34
        ## $2 用于指定：数据类型：如：rx（接收速率）、tx（发送速率）
        if ! [[ $# -eq 2 ]]; then
            echo &quot;0&quot;
            exit
        fi
        if ! [[ &quot;$2&quot; == &quot;rx&quot; ]] &amp;amp;&amp;amp; ! [[ &quot;$2&quot; == &quot;tx&quot; ]]; then
            echo &quot;0&quot;
            exit
        fi
        ifcName=$1
        rateType=$2
        before_rx_bytes=`cat /sys/class/net/$ifcName/statistics/rx_bytes`
        before_tx_bytes=`cat /sys/class/net/$ifcName/statistics/tx_bytes`
        sleep 1
        after_rx_bytes=`cat /sys/class/net/$ifcName/statistics/rx_bytes`
        after_tx_bytes=`cat /sys/class/net/$ifcName/statistics/tx_bytes`
        rx_rate=$(($after_rx_bytes-$before_rx_bytes))
        tx_rate=$(($after_tx_bytes-$before_tx_bytes))
        if [[ &quot;$2&quot; == &quot;rx&quot; ]]; then
            echo &quot;$rx_rate&quot;
        else
            echo &quot;$tx_rate&quot;
        fi
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## 第二步：配置&amp;lt;Zabbix Agent 客户端代理&amp;gt;
##         ☛ 开启：针对&amp;lt;UserParameter 用户自定义 Key 键&amp;gt;的&amp;lt;传参功能&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    vi /etc/zabbix/zabbix_agentd.conf
    ... ...
    ##
    ## 导入：/etc/zabbix/zabbix_agentd.d/*conf 配置文件，从而方便我们增删配置（这是：默认配置）
    ##
    Include=/etc/zabbix/zabbix_agentd.d/*.conf
    ... ...
    ##
    ## 开启：针对&amp;lt;UserParameter 用户定义 Key 键&amp;gt;的&amp;lt;传参功能&amp;gt;
    ##         UnsafeUserParameters=0 表示：不允许向&amp;lt;UserParameter 用户定义 Key 键&amp;gt;传递&amp;lt;键参数&amp;gt;
    ##         UnsafeUserParameters=1 表示：允许向&amp;lt;UserParameter 用户定义 Key 键&amp;gt;传递&amp;lt;键参数&amp;gt;
    ##             ♦ 传参过程中，不允许传递这些字符：\ &apos; &quot; ` * ? [ ] { } ~ $ ! &amp;amp; ; ( ) &amp;lt; &amp;gt; | # @
    ##             ♦ 传参过程中，也不允许传递&amp;lt;换行符&amp;gt;。
    ##
    UnsafeUserParameters=1
    ... ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## 第三步：配置&amp;lt;Zabbix Agent 客户端代理&amp;gt;
##         ☛ 定义：调用&amp;lt;本地 Shell 脚本&amp;gt;的&amp;lt;Key 键&amp;gt;
##             ❃ Key 键功能：通过&amp;lt;脚本&amp;gt;来获取&amp;lt;当前传输速率&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    vi /etc/zabbix/zabbix_agentd.d/myDiyKeys.conf
        UserParameter=net.if.connections.sum[*],ss $1 $2 -H | wc -l
        UserParameter=mount.filesystem.size.free[*],bash /etc/zabbix/zabbix_agentd.d/myShellScript01.sh $1
        ## 添加如下：
        UserParameter=net.if.rate[*],bash /etc/zabbix/zabbix_agentd.d/myShellScript02.sh $1 $2
    systemctl restart zabbix-agent.service
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## 第四步：在&amp;lt;Zabbix Server 服务端&amp;gt;上，执行测试
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    dnf install -y zabbix-get
    ## 获取：ens33 网卡的下载速率
    zabbix_get -s 192.168.168.19 -k net.if.rate[ens33,rx]
    912
    ## 获取：ens33 网卡的上传速率
    zabbix_get -s 192.168.168.19 -k net.if.rate[ens33,rx]
    367
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 创建：&amp;lt;Zabbix 自定义 Item 监控项&amp;gt;&lt;/h3&gt;
&lt;h4&gt;(1) 方法：新建&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;★ Web 控制台
        ↓
Configuration 
        ↓
      Hosts
        ↓
    server01
        ↓
      Items
        ↓
右上角：Create item
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;(2) 解析：定义栏&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;##
## ♦ Name     ## 定义：&amp;lt;item 监控项&amp;gt;的&amp;lt;自定义名称&amp;gt;
## ♦ Type     ## 指定：&amp;lt;item 监控项&amp;gt;采用的&amp;lt;数据采集方法&amp;gt;，如：Zabbix agent 客户端代理程序
## ♦ Key      ## 选取：&amp;lt;item 监控项&amp;gt;需要使用的&amp;lt;内置 Key 键&amp;gt;
## ♦ Host interface          ## 指定：连接&amp;lt;Zabbix 客户端主机&amp;gt;的&amp;lt;IP 与 Port&amp;gt;
## ♦ Type of information     ## 设置：&amp;lt;Value 键值&amp;gt;的&amp;lt;数据类型&amp;gt;，如：Numeric(unsigned)、Numeric(float)、Character、Log、Text
## ♦ Units                   ## 设置：&amp;lt;Value 键值&amp;gt;的&amp;lt;自定义计量单位&amp;gt;，如：bytes
## ♦ Update interval         ## 设置：&amp;lt;数据采样&amp;gt;的&amp;lt;时间间隔&amp;gt;
## ♦ Custom intervals        ## 设置：&amp;lt;数据采样&amp;gt;的&amp;lt;自定义时间间隔&amp;gt;，注意：Update interval 与 Custom intervals 不能同时使用
##                                    可以添加多个&amp;lt;自定义时间间隔&amp;gt;：
##                                        wd1-5h8-22m/10 周一到周五，每 5 点到 22 点，每隔 10 分钟执行一次
##                                        wd6-7h0-24m/30 周六到周日，每 0 点到 24 点，每隔 30 分钟执行一次
## ♦ History storage period  ## 设置：&amp;lt;历史数据&amp;gt;在&amp;lt;数据库&amp;gt;中的&amp;lt;留存时长&amp;gt;，如：90d(90 天)
##                                    ◪&amp;lt;历史数据&amp;gt;是指：每一个收集到的监控数据，即：&amp;lt;采样数据&amp;gt;的&amp;lt;原始采样值&amp;gt;。
##                                    ◪强烈建议：将&amp;lt;历史数据&amp;gt;的&amp;lt;保留时长&amp;gt;设置得尽可能的小，从而减少&amp;lt;数据库&amp;gt;的空间占用。
## ♦ Trend storage period    ## 设置：&amp;lt;趋势数据&amp;gt;在&amp;lt;数据库&amp;gt;中的&amp;lt;留存时长&amp;gt;，如：365d(365 天)
##                                    ◪&amp;lt;趋势数据&amp;gt;是指：按小时统计计算的平均值数据，即：&amp;lt;采样数据&amp;gt;的&amp;lt;平均计算值&amp;gt;
##                                    ◪&amp;lt;趋势数据&amp;gt;采用：一种内建的历史数据压缩机制，来存储&amp;lt;数字类型 监控项&amp;gt;的&amp;lt;每小时的
##                                                    最小值、最大值、平均值和记录数量。
## ♦ Show value              ## 选择：&amp;lt;映射规则&amp;gt;，从而针对&amp;lt;监控项&amp;gt;不同的&amp;lt;采样值&amp;gt;，来输出&amp;lt;指定的显示信息&amp;gt;。
##                                    ◪&amp;lt;映射规则&amp;gt;不会更改&amp;lt;采样值&amp;gt;，它仅用于改变&amp;lt;显示数据&amp;gt;。
##                                    ◪&amp;lt;映射规则&amp;gt;仅适用于：Numeric(unsigned)、Numeric(float)、Character &amp;lt;数据类型&amp;gt;。
##                                                        例如：Service state 映射规则 0 ⇒ Down
##                                                                                    1 ⇒ Up
## ♦ New application         ## 创建并链接：一个新的&amp;lt;自定义的应用集&amp;gt;
## ♦ Applications            ## 多选并链接：一个或多个&amp;lt;已有的应用集&amp;gt;
## ♦ Populates host inventory field     ## 设置：将&amp;lt;采样值&amp;gt;填充到&amp;lt;指定的主机资产记录字段&amp;gt;
## ♦ Description             ## 编写：描述信息
## ♦ Enabled                 ## 选择：立即启用
##
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;(3) 演示：新建&amp;lt;网卡 item 监控项&amp;gt;&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;★ 示例说明：
    (1) 针对&amp;lt;server01 客户端&amp;gt;，添置一个&amp;lt;item 监控项&amp;gt;，来采集&amp;lt;ens33 网卡&amp;gt;的&amp;lt;下载/上传 实时速率&amp;gt;
    (2) 使用：&amp;lt;Zabbix Agent 客户端代理&amp;gt;的&amp;lt;自定义 Key 键：net.if.rate[ name, rx|tx ]&amp;gt;
##
## 1. 开始创建：自定义的&amp;lt;监控项&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/360731780597580.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;##
## 2. 填写：&amp;lt;监控项&amp;gt;的&amp;lt;各项定义栏&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/128905609566616.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>06-Zabbix-Visualization-可视化</title><link>https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/06-zabbix-visualization-%E5%8F%AF%E8%A7%86%E5%8C%96/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/06-zabbix-visualization-%E5%8F%AF%E8%A7%86%E5%8C%96/</guid><description>Zabbix 6.4 分布式企业级性能监控平台 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 22:26:00 GMT</pubDate><content:encoded>&lt;h1&gt;Zabbix 6.4 分布式企业级性能监控平台&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;Zabbix Visualization 可视化
官网：https://www.zabbix.com/cn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/117075162608236.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、实验环境&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;节点&lt;/th&gt;
&lt;th&gt;角色&lt;/th&gt;
&lt;th&gt;IP 地址&lt;/th&gt;
&lt;th&gt;操作系统：&lt;/th&gt;
&lt;th&gt;硬件规格&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-16&lt;/td&gt;
&lt;td&gt;MySQL 数据库(版本：8.0) 加装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.16/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-17&lt;/td&gt;
&lt;td&gt;Nginx + PHP Web 前端 加装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.17/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-18&lt;/td&gt;
&lt;td&gt;Zabbix Server 核心服务(版本：6.4)&lt;/td&gt;
&lt;td&gt;192.168.168.18/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-19&lt;/td&gt;
&lt;td&gt;被监控主机 安装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.19/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;二、了解Visualization（可视化）&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;针对大量的监控数据，必须通过静态图形或动态图形的方式来加以展现（我们称之为：可视化），从而方便我们通过可视化图形的方式，更为直观的观察到性能变化趋势。现在 IT 性能监控领域，数据可视化的需要已经十分重要，甚至采用专门的可视化软件，来辅助监控软件，达成更高级的数据可视化应用需要，给人一种十分炫酷的感觉。
Zabbix 也为我们提供了多种数据可视化的管理和展示方法。
★ &amp;lt;可视化&amp;gt;官方指南：https://www.zabbix.com/documentation/6.0/en/manual/config/visualization
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1. Graphs 可视化指标&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★ &amp;lt;Graphs 可视化指标&amp;gt;
    就是：以图形化的方式，显示&amp;lt;item 监控项&amp;gt;的&amp;lt;采样数据&amp;gt;，方便我们实时观察&amp;lt;采样数据&amp;gt;的变化情况。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. Maps 可视化地图&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★ &amp;lt;Maps 可视化地图&amp;gt;
    就是：由我们自行绘制的&amp;lt;网络拓扑图&amp;gt;，从而描绘&amp;lt;网络主机节点&amp;gt;之间的&amp;lt;关系&amp;gt;。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. Screens 可视化监视屏&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★ &amp;lt;Screens 可视化监视屏&amp;gt;
    就是：针对&amp;lt;特定主机&amp;gt;的&amp;lt;特定性能指标&amp;gt;，由我们自行创建的&amp;lt;图形化显示图&amp;gt;。
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;三、创建Visualization Graph 可视化指标&lt;/h2&gt;
&lt;h3&gt;1. 前提：拥有Items 监控项（略 ...）&lt;/h3&gt;
&lt;h3&gt;2. 方法：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★ Web 控制台
        ↓
Configuration 
        ↓
      Hosts
        ↓
    server01
        ↓
    Graphs 
        ↓
右上角：Create graph
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 演示：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★ 示例说明：
    (1) 针对&amp;lt;server01 客户端&amp;gt;，添置一个&amp;lt;Graphs 图形&amp;gt;，来可视化显示&amp;lt;ens33 网卡&amp;gt;的&amp;lt;下载 实时速率&amp;gt;
    (2) 使用：新建的&amp;lt;net.if.rate[ens33, rx] 监控项&amp;gt;
##
## 1. 开始创建：自定义的&amp;lt;图形&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/395593157111377.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;##
## 2. 填写：&amp;lt;图形&amp;gt;的&amp;lt;各项定义栏&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/117252755168998.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;##
## 3. 查看：新建的&amp;lt;图形&amp;gt;
##         ★ Web 控制台 --&amp;gt; Monitoring --&amp;gt; Hosts --&amp;gt; server01 --&amp;gt; Graphs
##
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/476047926872796.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/521814174652609.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;四、创建Visualization Map 可视化网络拓扑图&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;★ Web 控制台
        ↓
      Maps
        ↓
右上角：Create map 或者 修改：Local network
★ 常见操作：
    (1) 准备：背景图（可选操作）
    (2) 创建：Maps 可视化地图（可以设置：背景图）
    (3) 绘制：Maps 地图元素
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/42527455503198.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;五、创建Visualization Screen 可视化监视屏&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;★ Web 控制台
    ↓
Screens
    ↓
右上角：Create screen
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/311264331126788.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>07-Zabbix-Triggers-触发器</title><link>https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/07-zabbix-triggers-%E8%A7%A6%E5%8F%91%E5%99%A8/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/07-zabbix-triggers-%E8%A7%A6%E5%8F%91%E5%99%A8/</guid><description>Zabbix 6.4 分布式企业级性能监控平台 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 21:27:00 GMT</pubDate><content:encoded>&lt;h1&gt;Zabbix 6.4 分布式企业级性能监控平台&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;Zabbix Triggers 触发器
官网：https://www.zabbix.com/cn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/117075162608236.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、实验环境&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;节点&lt;/th&gt;
&lt;th&gt;角色&lt;/th&gt;
&lt;th&gt;IP 地址&lt;/th&gt;
&lt;th&gt;操作系统：&lt;/th&gt;
&lt;th&gt;硬件规格&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-16&lt;/td&gt;
&lt;td&gt;MySQL 数据库(版本：8.0) 加装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.16/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-17&lt;/td&gt;
&lt;td&gt;Nginx + PHP Web 前端 加装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.17/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-18&lt;/td&gt;
&lt;td&gt;Zabbix Server 核心服务(版本：6.4)&lt;/td&gt;
&lt;td&gt;192.168.168.18/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-19&lt;/td&gt;
&lt;td&gt;被监控主机 安装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.19/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;二、了解Triggers 触发器&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;数据可视化功能可以有助于我们运维工作人员预判性能变化趋势，但是运维工作人员不可能时时刻刻的守在监视屏傍，同时面对大量的性能指标，也不可能将它们全部图形化展现出来，当性能指标数据出现异常时，我们需要有一种机制来及时通知相关的运维工作人员，从而得到及时的处理，保障整个系统的正常运行。
Zabbix Trigger 触发器就是这样的一种预警机制，它借助 item 监控项获取性能指标数据，然后基于设定的预警条件，在后台予以监视，一旦预警条件达成，就会自动产生一个 even 事件，进而结合相关的预警动作，及时通知运维工作人员。
★ &amp;lt;触发器&amp;gt;官方指南 ：https://www.zabbix.com/documentation/6.0/en/manual/config/triggers 
★ &amp;lt;触发器 表达式&amp;gt;官方指南：https://www.zabbix.com/documentation/6.0/en/manual/config/triggers/expression 
★ &amp;lt;触发器 函数&amp;gt;官方指南 ：https://www.zabbix.com/documentation/6.0/en/manual/appendix/functions
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1. 了解：什么是&amp;lt;触发器&amp;gt;？&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★ &amp;lt;触发器&amp;gt;就是：结合&amp;lt;item 监控项获取性能指标数据&amp;gt;来计算&amp;lt;条件表达式&amp;gt;，一旦满足&amp;lt;指定阈值&amp;gt;，就产生&amp;lt;问题事件&amp;gt;或者&amp;lt;OK 事件&amp;gt;的&amp;lt;事件管理机制&amp;gt;。
★ &amp;lt;触发器&amp;gt;的基本要素是：
    ♦ item 监控项
    ♦ 条件表达式
    ♦ event 事件
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 了解：&amp;lt;触发器&amp;gt;计算&amp;lt;条件表达式&amp;gt;的&amp;lt;时机&amp;gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;★ 时机1：如果&amp;lt;触发器&amp;gt;接收到了一个&amp;lt;新的采样值&amp;gt;，就会立即重新计算&amp;lt;逻辑表达式&amp;gt;。&lt;/li&gt;
&lt;li&gt;★ 时机2：如果&amp;lt;触发器&amp;gt;的&amp;lt;逻辑表达式&amp;gt;中使用了&amp;lt;时间函数&amp;gt;，就会每隔30秒重新计算&amp;lt;逻辑表达式&amp;gt;。
♦ 时间函数有：nodata(), date(), dayofmonth(), dayofweek(), time(), now()。&lt;/li&gt;
&lt;li&gt;★ 注意1：以上两个&amp;lt;时机&amp;gt;，均会促使&amp;lt;触发器&amp;gt;重新计算&amp;lt;逻辑表达式&amp;gt;，不会彼此抵消。&lt;/li&gt;
&lt;li&gt;★ 注意2：&amp;lt;触发器&amp;gt;仅基于&amp;lt;时点性的历史数据&amp;gt;进行评估；从不考虑&amp;lt;平均性的趋势数据&amp;gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;三、创建Tigger 触发器&lt;/h2&gt;
&lt;h3&gt;1. 前提：拥有Items 监控项（略 ...）&lt;/h3&gt;
&lt;h3&gt;2. 方法：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★ Web 控制台
        ↓
Configuration 
        ↓
      Hosts
        ↓
    server01
        ↓
    Triggers 
        ↓
右上角：Create trigger
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 演示创建：&amp;lt;httpd 的 CPU/Memory 资源占用&amp;gt;的&amp;lt;触发器&amp;gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★ 示例说明：实现&amp;lt;httpd 服务进程&amp;gt;的&amp;lt;CPU 平均占用率&amp;gt;和&amp;lt;内存合计占用率&amp;gt;的事件预警
    (1) 首先：创建&amp;lt;相应的 Item 监控项&amp;gt;
            Item 监控项名称 Key 监控键
            HTTPD 进程 CPU 占比 ----&amp;gt; proc.cpu.util[httpd,,,,avg1] ## Key 内置键：获取&amp;lt;httpd 进程&amp;gt;的&amp;lt;CPU 平均占用率&amp;gt;
            HTTPD 进程 MEM 占比 ----&amp;gt; proc.mem[httpd,,sum,,pmem] ## Key 内置键：获取&amp;lt;httpd 进程&amp;gt;的&amp;lt;内存合计占用率&amp;gt;
    (2) 然后：创建&amp;lt;触发器&amp;gt; 
            ♦ 名称：httpd Process Resource occupation for trigger01 
            ♦ 问题表达式
                ❃ &amp;lt;CPU 平均占用率&amp;gt;大于 40% ┐
                   或者                    ├ 则认为：出现问题，就生成&amp;lt;PROBLEM 问题事件&amp;gt;
                   &amp;lt;RAM 合计占用率&amp;gt;大于 70% ┘
            ❃ 创建：问题表达式
                    last(/rocky-9-19/proc.cpu.util[httpd,,,,avg1])&amp;gt;40
                    or
                    last(/rocky-9-19/proc.mem[httpd,,sum,,pmem])&amp;gt;70
                    ## 备注：
                    ##     last()函数：用于获取&amp;lt;样本数据&amp;gt;中的&amp;lt;最近的样本值&amp;gt; 
            ♦ 问题恢复表达式
                ❃ &amp;lt;CPU 平均占用率&amp;gt;小于 20% ┐
                并且                       ├ 则认为：问题解除，就生成&amp;lt;OK 正常事件&amp;gt;；
                &amp;lt;RAM 合计占用率&amp;gt;小于 40%    ┘
            ❃ 创建：问题恢复表达式
                    last(/rocky-9-19/proc.cpu.util[httpd,,,,avg1])&amp;lt;20
                    and
                    last(/rocky-9-19/proc.mem[httpd,,sum,,pmem])&amp;lt;40
                    ## 备注：
                    ##     last()函数：用于获取&amp;lt;样本数据&amp;gt;中的&amp;lt;最近的样本值&amp;gt; 
            ♦ 针对&amp;lt;问题事件生成模式&amp;gt;栏，选择：不重复生成&amp;lt;PROBLEM 问题事件&amp;gt;；
            ♦ 针对&amp;lt;事件成功关闭&amp;gt;栏，选择：所有问题均解决
            ♦ 针对&amp;lt;允许手动关闭&amp;gt;栏，选择：禁止手动关闭
##
## 1. 首先：创建&amp;lt;相应的 Item 监控项&amp;gt;
##          Item 监控项名称 Key 监控键
##          HTTPD 进程 CPU 占比 ----&amp;gt; proc.cpu.util[httpd,,,,avg1] 数据类型：Numeric(float) 小数 ◀
##          HTTPD 进程 MEM 占比 ----&amp;gt; proc.mem[httpd,,sum,,pmem] 数据类型：Numeric(float) 小数 ◀
##
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/216231564522509.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;##
## 2. 然后：创建&amp;lt;触发器&amp;gt;
##
                                                    ①
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/536290494068283.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;                                                    ②
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/244062376000977.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;                                                    ③
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/160904478092245.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;                                                    ④
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/244776036153886.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;4. 压力测试：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;##
## (1) rocky-9-19（192.168.168.19）安装：HTTPD（声明）
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    yum install -y httpd mod_ssl
    systemctl enable httpd
    systemctl start httpd
    firewall-cmd --permanent --zone=public --add-port=80/tcp --add-port=443/tcp
    firewall-cmd --reload
    echo &quot;This is a HTTPD Server01 indet.html Web Page&quot; &amp;gt; /var/www/html/index.html
    ## 实时监视：httpd 进程的 cpu 占用率 和 men 内存占用量
    watch -n 1 &quot;ps h -C httpd -o %cpu,%mem | awk &apos;{a=a+\$1;b=b+\$2} END{print a\&quot;%\&quot;,\&quot;|\&quot;,b\&quot;%\&quot;}&apos;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (2) rocky-9-19（192.168.168.19）HTTPD 执行 ab 压力测试：发出 1000 个请求，一次可以同时发送 1000 个并发数
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    rpm -qa httpd-tools || yum install -y httpd-tools
    while true; do
        ab -n 1000 -c 1000 http://192.168.168.19/index.html
    done
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (3) Zabbix Web 前端仪表盘：查看&amp;lt;生成 PROBLEM 问题事件&amp;gt;
##
♦ Web 控制台 → Problems
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/12795247127645.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;##
## (4) server02 HTTPD 终止 ab 压力测试
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    Ctrl + z ## 终止：while 循环
    pkill -9 ab ## 终止：ab 进程
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (5) Zabbix Web 前端仪表盘：查看&amp;lt;关闭 PROBLEM 问题事件&amp;gt;
##
♦ Web 控制台 → Problems
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/77925464913657.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>08-Zabbix-Templates-监控模板</title><link>https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/08-zabbix-templates-%E7%9B%91%E6%8E%A7%E6%A8%A1%E6%9D%BF/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/08-zabbix-templates-%E7%9B%91%E6%8E%A7%E6%A8%A1%E6%9D%BF/</guid><description>Zabbix 6.4 分布式企业级性能监控平台 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 20:28:00 GMT</pubDate><content:encoded>&lt;h1&gt;Zabbix 6.4 分布式企业级性能监控平台&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;Zabbix Templates 监控模板
官网：https://www.zabbix.com/cn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/117075162608236.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、实验环境&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;节点&lt;/th&gt;
&lt;th&gt;角色&lt;/th&gt;
&lt;th&gt;IP 地址&lt;/th&gt;
&lt;th&gt;操作系统：&lt;/th&gt;
&lt;th&gt;硬件规格&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-16&lt;/td&gt;
&lt;td&gt;MySQL 数据库(版本：8.0) 加装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.16/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-17&lt;/td&gt;
&lt;td&gt;Nginx + PHP Web 前端 加装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.17/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-18&lt;/td&gt;
&lt;td&gt;Zabbix Server 核心服务(版本：6.4)&lt;/td&gt;
&lt;td&gt;192.168.168.18/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-19&lt;/td&gt;
&lt;td&gt;被监控主机 安装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.19/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;二、了解：Templates 监控模板&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;面对数量众多的设备，我们自然不愿意一台一台的设置各种&amp;lt;监控项、触发器、视图 ... 等&amp;gt;，而是将通过&amp;lt;模板&amp;gt;来进行归类管理，针对大量的设备，应用正确的&amp;lt;模板&amp;gt;就可以了，即便需要更新修改，仅仅更新修改&amp;lt;模板&amp;gt;即可，从而大大的提高了的工作效率。
★ &amp;lt;模板&amp;gt;官方指南          ：https://www.zabbix.com/documentation/6.0/en/manual/config/templates 
★ &amp;lt;开箱即用的模板&amp;gt;官方指南：https://www.zabbix.com/documentation/6.0/en/manual/config/templates_out_of_the_box
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1. 了解：什么是 Template 模板？&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;★ &amp;lt;Template 模板&amp;gt;的内容：就是一系列&amp;lt;Zabbix 监控元素&amp;gt;的&amp;lt;集合体&amp;gt;。
&lt;ul&gt;
&lt;li&gt;可包含 items、tiggers、graphs、screens、low-level 发现规则、web 场景。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;★ &amp;lt;Template 模板&amp;gt;的好处：可以方便我们快速实现&amp;lt;监视作业&amp;gt;。&lt;/li&gt;
&lt;li&gt;★ 注意：
&lt;ul&gt;
&lt;li&gt;♦ &amp;lt;Template 模板名称&amp;gt;不能使用&amp;lt;中文&amp;gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 了解：Templates out of the box(开箱即用的模板)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;★ &amp;lt;开箱即用的模板&amp;gt;：就是&amp;lt;预先配置的模板&amp;gt;，它是加快开展&amp;lt;监视作业&amp;gt;的有效方法。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;三、应用/取消应用：Templates监控模板&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;★ Linking   链接     Template 模板 就是：在&amp;lt;指定 Host 主机&amp;gt;上，应用&amp;lt;指定 Template 模板&amp;gt;。
★ Unlinking 取消链接 Template 模板 就是：在&amp;lt;指定 Host 主机&amp;gt;上，取消应用&amp;lt;指定 Template 模板&amp;gt;。
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、创建/删除：Templates 监控模板&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;★ 我们可以在一个&amp;lt;Template 模板&amp;gt;中通过&amp;lt;Link 链接方式&amp;gt;来引用一个或多个&amp;lt;其他 Template 模板&amp;gt;，从而达到事半功倍的效果。
    
★ Web 控制台
        ↓
Configuration
        ↓
    Templates 
        ↓
右上角： Create template 
        ↓
首先：创建&amp;lt;你的模板&amp;gt;
        ↓
然后：修改&amp;lt;你的模板&amp;gt;
        ↓
添加：需要的&amp;lt;item、graph、screen、Discovery rules、Web scenarios&amp;gt;
指定：通过&amp;lt;主机组&amp;gt;对&amp;lt;模板&amp;gt;进行&amp;lt;分类&amp;gt;，方便我们搜索调用
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/32995790300483.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/95179101088499.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/148437151615870.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/216958829553960.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;五、更新：Template模板的&amp;lt;批量更新&amp;gt;&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;★ 我们可以批量更新配置：&amp;lt;Template 模板&amp;gt;所属的&amp;lt;主机群组&amp;gt;、&amp;lt;Template 模板&amp;gt;所链接的&amp;lt;其他模板&amp;gt; ... 等等。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/448698150891982.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;六、导出/导入：Templates 监控模板（以供：学习、修改）&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/550648522774278.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>09-Zabbix-Notifications-Upon-Events-事件通知</title><link>https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/09-zabbix-notifications-upon-events-%E4%BA%8B%E4%BB%B6%E9%80%9A%E7%9F%A5/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/09-zabbix-notifications-upon-events-%E4%BA%8B%E4%BB%B6%E9%80%9A%E7%9F%A5/</guid><description>Zabbix 6.4 分布式企业级性能监控平台 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 19:29:00 GMT</pubDate><content:encoded>&lt;h1&gt;Zabbix 6.4 分布式企业级性能监控平台&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;Zabbix Notifications Upon Events 事件通知
官网：https://www.zabbix.com/cn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/117075162608236.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、实验环境&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;节点&lt;/th&gt;
&lt;th&gt;角色&lt;/th&gt;
&lt;th&gt;IP 地址&lt;/th&gt;
&lt;th&gt;操作系统：&lt;/th&gt;
&lt;th&gt;硬件规格&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-16&lt;/td&gt;
&lt;td&gt;MySQL 数据库(版本：8.0) 加装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.16/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-17&lt;/td&gt;
&lt;td&gt;Nginx + PHP Web 前端 加装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.17/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-18&lt;/td&gt;
&lt;td&gt;Zabbix Server 核心服务(版本：6.4)&lt;/td&gt;
&lt;td&gt;192.168.168.18/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-19&lt;/td&gt;
&lt;td&gt;被监控主机 安装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.19/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;二、了解Notifications Upon Events 事件通知&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;虽然，有了 item 监控项和 trigger 触发器，我们就可以及时的通过&amp;lt;event 事件&amp;gt;来获知&amp;lt;性能问题&amp;gt;的&amp;lt;发生与恢复&amp;gt;，但是，当问题发生后，我们该如何处理呢？是执行预设指令，来予以自动处理？还是通知相关人员，来予以手动处理？这些也是我们作为运维工作人员需要考虑的问题。
Zabbix 的&amp;lt;Notifications upon events 事件通知机制&amp;gt;就可以帮助我们解决这个问题。我们可以配置 Zabbix 事件通知，从而自动化实现各种处理方案，比如：执行预设指令、发送邮件通知、... 等等。
★ &amp;lt;事件通知&amp;gt;官方指南：https://www.zabbix.com/documentation/6.0/en/manual/config/notifications 
★ &amp;lt;Notifications upon events 事件通知&amp;gt;是一个十分关键的工作任务。
    ♦ 前面所讲的&amp;lt;item、tigger、event&amp;gt;，都是为&amp;lt;Notifications upon events 事件通知&amp;gt;打基础。
    ♦ 为了能够发送和接收 Zabbix 的&amp;lt;事件通知&amp;gt;，您必须：
        (1) 定义：media 媒介，它是一个用于发送&amp;lt;通知和告警&amp;gt;的&amp;lt;传输通道&amp;gt;。
        (2) 配置：action 动作，从而向&amp;lt;已定义的 media 媒介&amp;gt;，发送&amp;lt;message 消息&amp;gt;，或者，执行&amp;lt;预设指令&amp;gt;。
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;三、创建Notifications Upon Events 事件通知&lt;/h2&gt;
&lt;h3&gt;1. 前提：准备好Triggers 触发器&lt;/h3&gt;
&lt;h3&gt;2. 创建：&amp;lt;Media 报警媒介&amp;gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;★ Zabbix 支持的&amp;lt;media 媒介类型&amp;gt;有：邮件、短信、自定义报警脚本。
★ 创建媒介：邮件（通过&amp;lt;Zabbix Server 本机&amp;gt;的&amp;lt;SMTP 服务&amp;gt;来发送邮件）
##
## 1. 首先：需要在&amp;lt;Zabbix Server 服务端&amp;gt;安装&amp;lt;Postfix MTA 邮件传输代理&amp;gt;
##          ♦ Postfix 采用&amp;lt;SMTP 协议&amp;gt;来实现邮件的&amp;lt;传输、接收和中继&amp;gt;
##          ♦ CentOS 默认已安装&amp;lt;Postfix MTA 邮件传输代理&amp;gt;
##          ♦ Rocky 默认未安装&amp;lt;Postfix MTA 邮件传输代理&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    dnf install -y postfix
    systemctl enable postfix.service
    systemctl restart postfix.service
    netstat -tunlp | grep 25
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/225342577013658.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;##
## 2. 配置：&amp;lt;Zabbix 邮件媒介&amp;gt;
##
♦ Web 控制台 → Administration → Media types → Email（内置的媒介类型）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/499890745712776.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/567811394255365.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;##
## 3. 测试：&amp;lt;Zabbix 邮件媒介&amp;gt;的配置是否正确？
##
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/135222685607155.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/325811122324397.webp&quot; alt=&quot;&quot; /&gt;&lt;img src=&quot;/images/zabbix/392660676554721.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3. 配置：&amp;lt;报警媒介&amp;gt;关联的&amp;lt;用户&amp;gt;，从而授权该&amp;lt;用户&amp;gt;使用&amp;lt;报警媒介&amp;gt;对外发送&amp;lt;邮件&amp;gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;##
## (9) 然后：将&amp;lt;Zabbix 邮件媒介&amp;gt;分配给&amp;lt;指定 Zabbix 用户&amp;gt;，授权该&amp;lt;用户&amp;gt;发送邮件
##
★ Web 控制台
    ↓
Administration 
    ↓
  Users
    ↓
admin（管理员用户账户）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/534280474647950.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;4. 创建：&amp;lt;Action 报警动作&amp;gt;，从而将&amp;lt;触发器事件&amp;gt;通告给&amp;lt;指定用户&amp;gt;，让&amp;lt;用户&amp;gt;对外发送&amp;lt;邮件&amp;gt;&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;★ Web 控制台
Configuration 
    ↓
Actions 
    ↓
左上角：下拉选择 Trigger actions 触发器动作
    ↓
右上角：Create action
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/246040562288890.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/355383785364014.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/408032740018278.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>10-Zabbix-Porxy-分布式代理</title><link>https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/10-zabbix-porxy-%E5%88%86%E5%B8%83%E5%BC%8F%E4%BB%A3%E7%90%86/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/10-zabbix-porxy-%E5%88%86%E5%B8%83%E5%BC%8F%E4%BB%A3%E7%90%86/</guid><description>Zabbix 6.4 分布式企业级性能监控平台 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 18:30:00 GMT</pubDate><content:encoded>&lt;h1&gt;Zabbix 6.4 分布式企业级性能监控平台&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;Zabbix Porxy 分布式代理
官网：https://www.zabbix.com/cn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/117075162608236.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、了解：Zabbix Proxy 分布式代理&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Zabbix Proxy 分布式代理&amp;gt;是实现&amp;lt;分布式监控&amp;gt;的&amp;lt;重要环节&amp;gt;，它可以代表 Zabbix Server 来收集&amp;lt;性能数据&amp;gt;，并予以本地缓存，然后将&amp;lt;性能数据&amp;gt;发送给 Zabbix Server，从而大大减轻了 Zabbix Server 上的 CPU 和磁盘 I/O 的开销。
Zabbix Proxy 需要使用独立的数据库，可以是&amp;lt;MySQL 数据库&amp;gt;、&amp;lt;PostgreSQL 数据库&amp;gt;、&amp;lt;sqlite3 数据库&amp;gt;三选一。
Zabbix Proxy 和 Zabbix Server 不能使用同一个&amp;lt;用户数据库&amp;gt;, 如需安装在同一台主机上，则须各自拥有不同的&amp;lt;用户数据库名&amp;gt;。
Zabbix proxy 的应用场景图：
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/423425009163623.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Zabbix Proxy 仅仅负责&amp;lt;数据收集&amp;gt;，无需负责&amp;lt;触发器计算、事件处理、警报发送&amp;gt;。
Zabbix Proxy 支持的具体功能（见下表）：
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;proxy 支持列表&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Items&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zabbix agent checks&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zabbix agent checks (active)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Simple checks&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trapper items&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SNMP checks&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SNMP traps&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IPMI checks&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JMX checks&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Log file monitoring&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Internal checks&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSH checks&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Telnet checks&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;External checks&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dependent items&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Script items&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Built-in web monitoring&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Item value preprocessing&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network discovery&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Active agent autoregistration&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Low-level discovery&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remote commands&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Calculating triggers&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Processing events&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Event correlation&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sending alerts&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;二、实验环境&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;节点&lt;/th&gt;
&lt;th&gt;角色&lt;/th&gt;
&lt;th&gt;IP 地址&lt;/th&gt;
&lt;th&gt;操作系统：&lt;/th&gt;
&lt;th&gt;硬件规格&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-16&lt;/td&gt;
&lt;td&gt;MySQL 数据库(版本：8.0) 加装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.16/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-17&lt;/td&gt;
&lt;td&gt;Nginx + PHP Web 前端 加装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.17/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-18&lt;/td&gt;
&lt;td&gt;Zabbix Server 核心服务(版本：6.4)&lt;/td&gt;
&lt;td&gt;192.168.168.18/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-19&lt;/td&gt;
&lt;td&gt;被监控主机 安装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.19/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rocky-9-20&lt;/td&gt;
&lt;td&gt;Zabbix Proxy 代理服务(版本：6.4) 安装：MySQL 数据库(版本：8.0) 安装：Zabbix Agent 客户端代理&lt;/td&gt;
&lt;td&gt;192.168.168.20/24&lt;/td&gt;
&lt;td&gt;Rocky Linux 9&lt;/td&gt;
&lt;td&gt;1 vCPU、2GB 内存&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;三、部署：Zabbix Proxy 分布式代理&lt;/h2&gt;
&lt;h3&gt;1. 安装部署：MySQL 数据库&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;##
## 安装：MySQL 数据库，并创建&amp;lt;zabbix 用户数据库&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    dnf install -y mysql-server mysql
    systemctl enable mysqld
    systemctl restart mysqld
    mysqladmin -uroot password &apos;a123456!&apos;
    
    mysql -uroot -p&apos;a123456!&apos; &amp;lt;&amp;lt;EOF
    create database if not exists zabbixproxy character set utf8mb4 collate utf8mb4_bin;
    create user if not exists root@&apos;%&apos; identified by &apos;a123456!&apos;;
    grant all privileges on *.* to root@&apos;%&apos;;
    create user if not exists zabbix@localhost identified by &apos;a123456!&apos;;
    grant all privileges on zabbixproxy.* to zabbix@localhost;
    create user if not exists zabbix@&apos;%&apos; identified by &apos;a123456!&apos;;
    grant all privileges on zabbixproxy.* to zabbix@&apos;%&apos;;
    set global log_bin_trust_function_creators = 1;
    EOF
    
    firewall-cmd --permanent --add-port=3306/tcp
    firewall-cmd --reload
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 安装部署：Zabbix Proxy 分布式代理&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;## 
## (1) 禁用：EPEL 源中的 Zabbix 
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    vi /etc/yum.repos.d/ustc_epel_9.repo ## 这是：一个国内的 EPEL YUM 镜像源
        [epel]
        name=Extra Packages for Enterprise Linux $releasever - $basearch
        baseurl=https://mirrors.ustc.edu.cn/epel/$releasever//Everything/$basearch
        failovermethod=priority
        enabled=1
        gpgcheck=0
        excludepkgs=zabbix*
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (2) 获取：&amp;lt;Zabbix 软件包&amp;gt;的&amp;lt;repo 源配置文件&amp;gt;
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    rpm -Uvh https://repo.zabbix.com/zabbix/6.0/rhel/9/x86_64/zabbix-release-6.0-4.el9.noarch.rpm
    yum clean all
    yum makecache
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (3) 安装：Zabbix Proxy 分布式代理服务
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    dnf install -y zabbix-proxy-mysql zabbix-sql-scripts
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (4) 针对 MySQL 数据库，导入：初始架构和数据
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    dnf install -y mysql
    cat /usr/share/zabbix-sql-scripts/mysql/proxy.sql | \
        mysql --default-character-set=utf8mb4 -uzabbix -p&apos;a123456!&apos; -h 192.168.168.20 zabbixproxy
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (5) 在导入数据库架构之后，针对 MySQL 数据库，禁用：log_bin_trust_function_creators 选项。
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    mysql -uroot -p&apos;a123456!&apos; -h 192.168.168.20 &amp;lt;&amp;lt;EOF
    set global log_bin_trust_function_creators = 0;
    use zabbixproxy;
    show tables;
    EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (6) 针对 Zabbix Proxy 代理服务，配置：数据库连接参数
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    test -f /etc/zabbix/zabbix_proxy.conf.bak || cp /etc/zabbix/zabbix_proxy.conf /etc/zabbix/zabbix_proxy.conf.bak
    vi /etc/zabbix/zabbix_proxy.conf
        ## --------------------------------------------------------------------------
        ## Zabbix Proxy 工作模式
        ## --------------------------------------------------------------------------
        ## 设置：Zabbix Proxy 工作模式
        ##     0 表示：主动模式（默认模式）
        ##     1 表示：被动模式
        ProxyMode=0
        ## 设置：Zabbix Proxy 如何与 Zabbix Server 交互
        ##     如果是&amp;lt;主动模式&amp;gt;，则 Server=address1:port;address2:port
        ##     如果是&amp;lt;被动模式&amp;gt;，着 Server=address1;address2
        Server=192.168.168.18:10051
        ## 设置：Zabbix Proxy 在&amp;lt;被动模式&amp;gt;下的&amp;lt;侦听端口&amp;gt;（默认值 10051）
        ##     在&amp;lt;被动模式&amp;gt;下，&amp;lt;ListenPort&amp;gt;用于：接收 Zabbix Server 用于采集&amp;lt;Zabbix Proxy 样本缓存数据&amp;gt;的&amp;lt;主动轮询&amp;gt;
        ##     在&amp;lt;被动模式&amp;gt;下，&amp;lt;ListenPort&amp;gt;用于：接收 Zabbix Agent 在&amp;lt;主动模式&amp;gt;下发起的&amp;lt;数据汇报&amp;gt;
        ListenPort=10051
        ## 设置：在&amp;lt;Zabbix Server Web 控制台&amp;gt;上的&amp;lt;Zabbix Proxy 选择菜单&amp;gt;中的&amp;lt;显示名称&amp;gt;（注意：不是 Host 主机标识名）
        Hostname=Zabbix_Proxy01
        ## 设置：在&amp;lt;主动模式&amp;gt;下，Proxy 从 Server 获知&amp;lt;配置数据&amp;gt;的&amp;lt;时间间隔&amp;gt;（取值范围：1-3600*24*7，默认值 3600，单位：秒）
        ConfigFrequency=60
        ## 设置：在&amp;lt;主动模式&amp;gt;下，Proxy 向 Server 发送&amp;lt;采样数据&amp;gt;的&amp;lt;时间间隔&amp;gt;（取值范围：1-3600，默认值 1，单位：秒）
        DataSenderFrequency=1
        ## 设置：当 Server 可以连接时，Proxy 本机保存&amp;lt;采样数据&amp;gt;的&amp;lt;保存时长&amp;gt;（取值范围：0-720，默认值 0，单位：小时）
        ProxyLocalBuffer=0
        ## 设置：当 Server 无法连接时，Proxy 本机保存&amp;lt;采样数据&amp;gt;的&amp;lt;保存时长&amp;gt;（取值范围：1-720，默认值 1，单位：小时）
        ProxyOfflineBuffer=1
        ## 设置：监控数据的&amp;lt;缓存区容量&amp;gt;，根据监控主机数量适当调整（取值范围：256K-2G，默认值 8M）
        CacheSize=8M
        ## --------------------------------------------------------------------------
        ## Zabbix Proxy 数据库连接参数
        ## --------------------------------------------------------------------------
        ## 设置：DB 数据库连接参数
        DBHost=192.168.168.20
        DBName=zabbixproxy
        DBUser=zabbix
        DBPassword=a123456!
        DBPort=3306
        ## --------------------------------------------------------------------------
        ## Zabbix Proxy 其他默认参数
        ## --------------------------------------------------------------------------
        ## 设置：Proxy 的日志文件
        LogFile=/var/log/zabbix/zabbix_proxy.log
        ## 设置：Proxy 日志文件的最大大小，一旦超过，则日志旋转
        ##     0 表示：禁止日志旋转，即：日志文档会一直增长下去
        LogFileSize=0
        ## 设置：Proxy 的 PID 文件
        PidFile=/run/zabbix/zabbix_proxy.pid
        ## 设置：Proxy 的 Socket 套接字文件目录
        SocketDir=/run/zabbix
        ## 设置：SNMP Trapper 陷阱的日志文件
        SNMPTrapperFile=/var/log/snmptrap/snmptrap.log
        ## 设置：&amp;lt;数据慢查询&amp;gt;的&amp;lt;衡量标准&amp;gt;（取值范围：1-3600000，默认值 0，单位：毫秒），一旦达到标准，就会计入日志
        ##     0 表示：不记录&amp;lt;数据慢查询&amp;gt;
        LogSlowQueries=3000
        ## 设置：允许接收&amp;lt;哪些 IP 地址&amp;gt;发起的&amp;lt;stat 状态请求&amp;gt;，格式：StatsAllowedIP=address1;address2
        StatsAllowedIP=127.0.0.1
        ## 设置：针对&amp;lt;Trapper 陷阱&amp;gt;的数据处理，所需等待的&amp;lt;最大时间&amp;gt;（取值范围：1-300，默认值 300，单位：秒）
        TrapperTimeout=300
        ## 设置：针对&amp;lt;Agent、SNMP、External check&amp;gt;的数据处理，所需等待的&amp;lt;最大时间&amp;gt;（取值范围：1-30，默认值 3，单位：秒）
        Timeout=3
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    cat /etc/zabbix/zabbix_proxy.conf | grep -vE &quot;^\s*(#|$)&quot;
    ProxyMode=0
    Server=192.168.168.18:10051
    ListenPort=10051
    Hostname=Zabbix_Proxy01
    ConfigFrequency=60
    DataSenderFrequency=1
    ProxyLocalBuffer=0
    ProxyOfflineBuffer=1
    CacheSize=8M
    DBHost=192.168.168.20
    DBName=zabbixproxy
    DBUser=zabbix
    DBPassword=a123456!
    DBPort=3306
    LogFile=/var/log/zabbix/zabbix_proxy.log
    LogFileSize=0
    PidFile=/run/zabbix/zabbix_proxy.pid
    SocketDir=/run/zabbix
    SNMPTrapperFile=/var/log/snmptrap/snmptrap.log
    LogSlowQueries=3000
    StatsAllowedIP=127.0.0.1
    Timeout=3
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##
## (7) 启动：Zabbix Proxy 服务进程
##
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    systemctl enable zabbix-proxy.service
    systemctl restart zabbix-proxy.service
    firewall-cmd --permanent --zone=public --add-port=10051/tcp ## 防火墙放行：&amp;lt;Zabbix Server 核心服务&amp;gt;的&amp;lt;侦听端口&amp;gt;
    firewall-cmd --reload
    ## 禁用：SElinux
    if ! [[ $(getenforce) == &quot;Disabled&quot; ]]; then
        sed -r -i &apos;s/^\s*SELINUX=.*/SELINUX=disabled/&apos; /etc/selinux/config
        reboot
    fi
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 安装部署：Zabbix Agent 客户端代理（用于：采集 Proxy 自身数据）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;    dnf install -y zabbix-agent
    vi /etc/zabbix/zabbix_agentd.conf
        ... ...
        ## 设置：&amp;lt;超时阈值&amp;gt;为&amp;lt;最大值&amp;gt;，从而应对耗时较长的&amp;lt;数据收集&amp;gt;操作
        Timeout=30
        ... ...
        ## 针对&amp;lt;被被模式&amp;gt;，设置：&amp;lt;Zabbix Agent 侦听端口&amp;gt;
        ##     ♦ 功能说明：
        ##     ♢ 在&amp;lt;指定端口&amp;gt;侦听&amp;lt;数据采集请求&amp;gt;
        ListenPort=10050
        ## 针对&amp;lt;被被模式&amp;gt;，设置：&amp;lt;Zabbix Server 核心服务器&amp;gt;的&amp;lt;IP 地址&amp;gt; 或者 &amp;lt;Zabbix Proxy 分布式代理服务器&amp;gt;的&amp;lt;IP 地址&amp;gt;
        ##     ♦ 功能说明：
        ##     ♢ 控制：&amp;lt;本机 Zabbix Agent 程序&amp;gt;在&amp;lt;10050/tcp 端口&amp;gt;上，应该接收谁的&amp;lt;数据采集请求&amp;gt;？
        Server=127.0.0.1
        ## 针对&amp;lt;主动模式&amp;gt;，设置：&amp;lt;Zabbix Server 核心服务器&amp;gt;的&amp;lt;IP 地址&amp;gt; 或者 &amp;lt;Zabbix Proxy 分布式代理服务器&amp;gt;的&amp;lt;IP 地址&amp;gt;
        ##     ♦ 功能说明：
        ##     ♢ 控制：应该向谁主动汇报&amp;lt;采集数据&amp;gt;？
        ServerActive=127.0.0.1:10051
        ##
        ## 针对&amp;lt;自动注册&amp;gt;，设置：唯一性的&amp;lt;主机注册名称&amp;gt;
        ##
        Hostname=zabbix_proxy_rocky_9_20
        ... ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    cat /etc/zabbix/zabbix_agentd.conf | grep -vE &quot;^\s*(#|$)&quot;
        PidFile=/run/zabbix/zabbix_agentd.pid
        LogFile=/var/log/zabbix/zabbix_agentd.log
        LogFileSize=0
        ListenPort=10050                     ## 针对&amp;lt;被动模式&amp;gt;，设置：&amp;lt;Zabbix Agent 侦听端口&amp;gt;
        Server=127.0.0.1                     ## 针对&amp;lt;被动模式&amp;gt;，设置：接收&amp;lt;指定 IP 地址&amp;gt;发来的&amp;lt;度量查询请求&amp;gt;
        ServerActive=127.0.0.1:10051         ## 针对&amp;lt;主动模式&amp;gt;，设置：向&amp;lt;指定 IP 地址&amp;gt;主动汇报&amp;lt;度量采集数据&amp;gt;
        Hostname=zabbix_proxy_rocky_9_20     ## 针对&amp;lt;自动注册&amp;gt;，设置：唯一性的&amp;lt;主机注册名称&amp;gt;
        Timeout=30                           ## 设置：&amp;lt;超时阈值&amp;gt;为&amp;lt;最大值&amp;gt;，从而应对耗时较长的&amp;lt;数据收集&amp;gt;操作
        Include=/etc/zabbix/zabbix_agentd.d/*.conf
    
    systemctl enable zabbix-agent.service
    systemctl restart zabbix-agent.service
    systemctl status zabbix-agent.service
    firewall-cmd --permanent --zone=public --add-port=10050/tcp ## 防火墙放行：&amp;lt;Zabbix Agent 客户端代理&amp;gt;的&amp;lt;侦听端口&amp;gt;
    firewall-cmd --reload
    ## 禁用：SElinux
    if ! [[ $(getenforce) == &quot;Disabled&quot; ]]; then
        sed -r -i &apos;s/^\s*SELINUX=.*/SELINUX=disabled/&apos; /etc/selinux/config
        reboot
    fi
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、在Zabbix Server 上，创建：Zabbix Proxy 代理程序&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/401538303302092.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/463895437875864.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/514228942409084.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;五、配置：Zabbix Agent 使用 Zabbix Proxy 分布式代理&lt;/h2&gt;
&lt;h3&gt;1. 配置：Zabbix Agent 使用 Zabbix Proxy&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;    vi /etc/zabbix/zabbix_agentd.conf
        ... ...
        ## 设置：&amp;lt;超时阈值&amp;gt;为&amp;lt;最大值&amp;gt;，从而应对耗时较长的&amp;lt;数据收集&amp;gt;操作
        Timeout=30
        ... ...
        ## 针对&amp;lt;被被模式&amp;gt;，设置：&amp;lt;Zabbix Agent 侦听端口&amp;gt;
        ##     ♦ 功能说明：
        ##     ♢ 在&amp;lt;指定端口&amp;gt;侦听&amp;lt;数据采集请求&amp;gt;
        ListenPort=10050
        ## 针对&amp;lt;被被模式&amp;gt;，设置：&amp;lt;Zabbix Proxy 分布式代理服务器&amp;gt;的&amp;lt;IP 地址&amp;gt;
        ##     ♦ 功能说明：
        ##     ♢ 控制：&amp;lt;本机 Zabbix Agent 程序&amp;gt;在&amp;lt;10050/tcp 端口&amp;gt;上，应该接收谁的&amp;lt;数据采集请求&amp;gt;？
        Server=192.168.168.20
        ## 针对&amp;lt;主动模式&amp;gt;，设置：&amp;lt;Zabbix Proxy 分布式代理服务器&amp;gt;的&amp;lt;IP 地址&amp;gt;
        ##     ♦ 功能说明：
        ##     ♢ 控制：应该向谁主动汇报&amp;lt;采集数据&amp;gt;？
        ServerActive=192.168.168.20:10051
        ##
        ## 针对&amp;lt;自动注册&amp;gt;，设置：唯一性的&amp;lt;主机注册名称&amp;gt;
        ##
        Hostname=rocky_9_19
        ... ...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    cat /etc/zabbix/zabbix_agentd.conf | grep -vE &quot;^\s*(#|$)&quot;
        PidFile=/run/zabbix/zabbix_agentd.pid
        LogFile=/var/log/zabbix/zabbix_agentd.log
        LogFileSize=0
        ListenPort=10050
        Server=192.168.168.20                 ## 针对&amp;lt;被动模式&amp;gt;，设置：接收&amp;lt;指定 Proxy 的 IP 地址&amp;gt;发来的&amp;lt;度量查询请求&amp;gt;
        ServerActive=192.168.168.20:10051     ## 针对&amp;lt;主动模式&amp;gt;，设置：向&amp;lt;指定 Proxy 的 IP 地址&amp;gt;主动汇报&amp;lt;度量采集数据&amp;gt;
        Hostname=rocky-9-19
        Timeout=30
        Include=/etc/zabbix/zabbix_agentd.d/*.conf
        UnsafeUserParameters=1

    systemctl restart zabbix-agent.service
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 配置：Zabbix Server 通过 Zabbix Proxy 来采集 Zabbix Agent 数据&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/494066512607799.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/33375021942369.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>rockylinux安装配置</title><link>https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/rockylinux%E5%AE%89%E8%A3%85%E9%85%8D%E7%BD%AE/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/zabbix%E7%9B%91%E6%8E%A7/rockylinux%E5%AE%89%E8%A3%85%E9%85%8D%E7%BD%AE/</guid><description>一、系统安装 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 17:31:00 GMT</pubDate><content:encoded>&lt;h2&gt;一、系统安装&lt;/h2&gt;
&lt;h2&gt;1. 下载 rockylinux 镜像&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.aliyun.com/mirror/&quot;&gt;阿里镜像&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://rockylinux.org/zh-CN/download?ref=linuxhandbook.com&quot;&gt;rockyLinux官网&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/7175627872009.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/436963939422581.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/270315013529275.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/418377206751434.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/3885988829529.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/295634386437028.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;2. 安装 rockylinux&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/219807677587318.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/332137358810376.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/485283816018559.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/39496421406028.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/324936566208990.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/169499533676952.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/373757990651701.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/564678791831834.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/141326488453237.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/268886489166277.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/565947481848461.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/425588659443524.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/570719335077547.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/101789898968401.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/238627210505062.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/422938054814391.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/556387883109478.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/101538335280224.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/234676680216471.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/352128705515305.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/571198481520583.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/104537008895112.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;3. 配置静态 ip&lt;/h2&gt;
&lt;h3&gt;3.1 方式一修改配置文件&lt;/h3&gt;
&lt;h4&gt;3.1.1 远程连接工具登录，查看网卡名称&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/269769217078921.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;3.1.2 进入到网卡配置目录&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[xxxxxxxx]# cd /etc/NetworkManager/system-connections/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/102532090098867.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;3.1.3 配置网卡&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# vim ens160.nmconnection
    [connection]
    id=ens160
    uuid=68d9b637-d690-3abe-a6a4-a73c06f7953e
    type=ethernet
    autoconnect-priority=-999
    interface-name=ens160
    timestamp=1737040847
    
    [ethernet]
    
    [ipv4]
    #method=auto
    method=manual
    address1=192.168.10.6/24,192.168.10.254
    dns=114.114.114.114
    
    [ipv6]
    addr-gen-mode=eui64
    method=auto
    
    [proxy]


# method=auto                             动态获取 ip
method=manual                             静态配置 ip
address1=192.168.10.6/24,192.168.10.254   ip 地址、掩码、网关
dns=114.114.114.114                       公共 DNS 服务器
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3.1.4 重启网络&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# nmcli connection down ens160 ;nmcli connection up ens160
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/129450910589695.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;重启网络管理服务
# systemctl restart NetworkManager
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 方式二 nmtui 命令修改&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmtui
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/76374544857693.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/76852715359096.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/232314974875066.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/421123781755850.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/542484430695140.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/zabbix/37181285251570.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;重启网卡
# nmcli connection down ens160 ;nmcli connection up ens160
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/397674806803936.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ip a
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/113431428248416.webp&quot; alt=&quot;.&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;4. root 用户无法登录&lt;/h2&gt;
&lt;p&gt;如果在安装的时候，禁用了 root 用户，则需要修改 ssh 的配置文件，允许 root 用户登录！&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vim /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/420781337626363.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# systemctl restart sshd
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;5. selinux 和 firewalld&lt;/h2&gt;
&lt;h3&gt;5.1 关闭 selinux&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# vim /etc/selinux/config
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/512614320797715.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;注意：关闭后，重启生效，不重启则设置为宽容模式，下次重启后生效&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# setenforce 0
# getenforce
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/250391612892073.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;5.2 防火墙&lt;/h3&gt;
&lt;p&gt;rockylinux 的防火墙和 centos7 是一样的&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# systemctl status firewalld
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/50792464271834.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;实验环境可关闭防火&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# systemctl disable firewalld.service --now
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/408492581401296.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# systemctl status firewalld
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/zabbix/560782622921515.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>01：mysql之基础</title><link>https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/01-mysql%E4%B9%8B%E5%8D%95%E8%A1%A8%E6%9F%A5%E8%AF%A2/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/01-mysql%E4%B9%8B%E5%8D%95%E8%A1%A8%E6%9F%A5%E8%AF%A2/</guid><description>01：mysql之基础 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 14:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1&gt;01：mysql之基础&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/01-mysql%E4%B9%8B%E5%8D%95%E8%A1%A8%E6%9F%A5%E8%AF%A2/image-20250611213841671.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;咱公司最近业务拓展，新入职了好多员工。HR部门要管理员工信息、部门信息和工资信息，财务部门每月得核算工资，老板也想随时了解各部门的人力成本。之前用 Excel 管理，数据多了又乱又容易出错。现在打算用 MySQL 数据库来管理这些数据。但大家都是小白，得先学会 MySQL 安装、密码管理、图形化软件安装，还得会用单表查询、日期函数、聚集函数、case 函数，才能从员工表、部门表、工资表中获取想要的信息，解决工作中的难题。&lt;/p&gt;
&lt;h2&gt;二、为什么学mysql数据库&lt;/h2&gt;
&lt;p&gt;为啥要学这些东西呢？想象一下，要是不会 MySQL 安装，就没办法搭建数据库来管理公司的员工、部门和工资信息，那还不得乱成一锅粥。密码管理也很重要，要是密码泄露，公司的重要数据就可能被坏人拿走，损失可就大了。图形化软件能让操作更简单，就像玩游戏一样轻松。单表查询能让你快速找到需要的数据，日期函数可以处理和日期相关的信息，聚集函数能帮你统计数据，case 函数能根据不同条件输出不同结果。学会这些，工作效率蹭蹭往上涨，升职加薪不是梦！&lt;/p&gt;
&lt;h2&gt;三、构建mysql服务器&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/01-mysql%E4%B9%8B%E5%8D%95%E8%A1%A8%E6%9F%A5%E8%AF%A2/image-20250611213934020.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3.1 安装mysql服务&lt;/h3&gt;
&lt;p&gt;1)准备1台虚拟机，要求如下：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;192.168.90.50&lt;/td&gt;
&lt;td&gt;mysql50&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;2)配置IP地址和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify ens160 ipv4.addresses 192.168.90.50/24 autoconnect yes
参数详解​​：
* nmcli：NetworkManager 的命令行工具，用于管理网络连接
* connection【肯耐申】 modify：修改现有网络连接的配置
* ens160：网络接口的名称（通常是以太网接口）
* ipv4.addresses 192.168.90.50/24：
    * 设置 IPv4 地址为 192.168.90.50
    * 子网掩码为 255.255.255.0（/24表示前24位是网络位）
    * autoconnect yes：设置系统启动时自动连接此网络接口
* ​​效果​​：将 ens160网络接口配置为使用静态 IP 地址 192.168.90.50，并确保系统重启后自动启用该连接。

[root@localhost ~]# nmcli connection【肯耐申】 up ens160
参数详解​​：
* connection【肯耐申】 up：激活指定的网络连接
* ens160：要激活的网络接口名称
* ​​效果​​：立即应用对 ens160接口的配置更改，使新的 IP 地址生效。相当于重启网络服务或启用网络接口。

[root@mysql50 ~]# hostnamectl set-hostname mysql50
​参数详解​​：
* hostnamectl：系统主机名管理工具
* set-hostname：设置新的主机名
* mysql50：新的主机名称
* ​​效果​​：将系统的主机名永久更改为 mysql50。主机名用于在网络中标识该系统。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3)安装mysql-server服务软件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# yum -y install mysql-server
[root@mysql50 ~]# rpm -q mysql-server
mysql-server-8.0.41-2.el9_5.x86_64

#启动服务
root@mysql50 ~]# systemctl【西斯听头】 start【s 达儿】 mysqld
[root@mysql50 ~]# systemctl【西斯听头】 enable【an 内 步】 mysqld

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4)查看端口&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# ss -utnlp  | grep 【哥瑞普】 3306  #查看端口
tcp   LISTEN 0      70                 *:33060            *:*    users:((&quot;mysqld&quot;,pid=21912,fd=22))
tcp   LISTEN 0      128                *:3306             *:*    users:((&quot;mysqld&quot;,pid=21912,fd=25))
[root@mysql50 ~]# 
或
[root@mysql50 ~]# netstat【劣 s 塔】  -utnlp  | grep 【哥瑞普】  mysqld   #仅查看mysqld进程
tcp6       0      0 :::33060   :::*      LISTEN      21912/mysqld        
tcp6       0      0 :::3306    :::*     LISTEN      21912/mysqld        
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;选项&lt;/th&gt;
&lt;th&gt;含义&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;-t(--tcp)&lt;/td&gt;
&lt;td&gt;显示 TCP 连接&lt;/td&gt;
&lt;td&gt;过滤只显示 TCP 协议的网络连接&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-u(--udp)&lt;/td&gt;
&lt;td&gt;显示 UDP 连接&lt;/td&gt;
&lt;td&gt;过滤只显示 UDP 协议的网络连接&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-n(--numeric)&lt;/td&gt;
&lt;td&gt;数字格式显示&lt;/td&gt;
&lt;td&gt;不解析主机名和服务名，直接显示 IP 和端口号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-l(--listening)&lt;/td&gt;
&lt;td&gt;只显示监听端口&lt;/td&gt;
&lt;td&gt;只显示正在监听的套接字（服务端）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-p(--processes)&lt;/td&gt;
&lt;td&gt;显示进程信息&lt;/td&gt;
&lt;td&gt;显示使用该端口的进程信息&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;说明：&lt;/p&gt;
&lt;p&gt;MySQL 8中的3306端口是MySQL服务默认使用的端口，主要用于建立客户端与MySQL服务器之间的连接。&lt;/p&gt;
&lt;p&gt;MySQL 8中的33060端口是MySQL Shell默认使用的管理端口，主要用于执行各种数据库管理任务。远程管理MySQL服务器：使用MySQL Shell连接到MySQL服务，并在远程管理控制台上执行各种数据库管理操作，例如创建、删除、备份和恢复数据库等。&lt;/p&gt;
&lt;h3&gt;3.2 连接服务&lt;/h3&gt;
&lt;p&gt;说明： 数据库管理员本机登陆默认没有密码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection【肯耐申】 id is 8
Server version【沃申】: 8.0.41 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 &apos;help;&apos; or &apos;\h&apos; for help. Type &apos;\c&apos; to clear the current input statement.

mysql&amp;gt;
mysql&amp;gt; exit【诶西特】
Bye
[root@mysql50 ~]#

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3 mysql必备命令&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 version【沃申】() ;  //查看数据库软件版本
+------------------+
| version【沃申】() |
+------------------+
| 8.0.41           |
+------------------+
1 row in set (0.00 sec)
mysql&amp;gt; select【涩莱克特】 user() ; //查看登陆的用户和客户端地址 
+----------------+
| user()         |
+----------------+
| root@localhost | 管理员root本机登陆
+----------------+
1 row in set (0.00 sec) 
mysql&amp;gt; show【瘦】 databases;【得塔-贝斯】 //查看已有的库
+----------------------------------------------+
| Database【得塔-贝斯】                         |
+----------------------------------------------+
| information【因弗梅申】_schema【斯京(白话)磨】  |
| mysql                                        |
| performance【破佛曼斯】_schema【斯京(白话)磨】  |
| sys                                          |
+----------------------------------------------+
4 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;说明：&lt;/p&gt;
&lt;p&gt;默认4个库 不可以删除，存储的是 服务运行时加载的不同功能的程序和数据。&lt;/p&gt;
&lt;p&gt;information【因弗梅申】_schema【斯京(白话)磨】：是MySQL数据库提供的一个虚拟的数据库，存储了MySQL数据库中的相关信息，比如数据库、表、列、索引、权限、角色等信息。它并不存储实际的数据，而是提供了一些视图和存储过程，用于查询和管理数据库的元数据信息。&lt;/p&gt;
&lt;p&gt;mysql：存储了MySQL服务器的系统配置、用户、账号和权限信息等。它是MySQL数据库最基本的库，存储了MySQL服务器的核心信息。&lt;/p&gt;
&lt;p&gt;performance【破佛曼斯】_schema【斯京(白话)磨】】：存储了MySQL数据库的性能指标、事件和统计信息等数据，可以用于性能分析和优化。&lt;/p&gt;
&lt;p&gt;sys：是MySQL 8.0引入的一个新库，它基于 information【因弗梅申】_schema【斯京(白话)磨和performance【破佛曼斯】_schema【斯京(白话)磨】视图，提供了更方便、更直观的方式来查询和管理MySQL数据库的元数据和性能数据。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 database();【得塔-贝斯】  //查看当前在那个库里  null【nò】 表示没有在任何库里
+------------+
| database() |【得塔-贝斯】
+------------+
| NULL【nò】       |
+------------+
1 row in set (0.00 sec)
mysql&amp;gt; use mysql ; //切换到mysql库
mysql&amp;gt; select【涩莱克特】 database();【得塔-贝斯】  // 再次显示所在的库
+------------+
| database() |【得塔-贝斯】
+------------+
| mysql      |
+------------+
1 row in set (0.00 sec)
mysql&amp;gt; show【瘦】 tables;【忒-部s】  //显示库里已有的表
+------------------------------------------------------+
| Tables【忒-部s】_in_mysql                             |
+------------------------------------------------------+
| columns_priv                                         |
| component                                            |
| db                                                   |
| default_roles                                        |
| engine_cost                                          |
| func                                                 |
| general_log                                          |
| global_grants                                        |
| gtid_executed                                        |
| help_category                                        |
| help_keyword                                         |
| help_relation                                        |
| help_topic                                           |
| innodb_index_stats                                   |
| innodb_table【忒-部】_stats                           |
| password_history                                     |
| plugin                                               |
| procs_priv                                           |
| proxies_priv                                         |
| replication_asynchronous_connection【肯耐申】_failover         |
| replication_asynchronous_connection【肯耐申】_failover_managed |
| replication_group_configuration_version【沃申】       |
| replication_group_member_actions                     |
| role_edges                                           |
| server_cost                                          |
| servers                                              |
| slave_master_info                                    |
| slave_relay_log_info                                 |
| slave_worker_info                                    |
| slow_log                                             |
| tables【忒-部s】_priv                                 |
| time_zone                                            |
| time_zone_leap_second                                |
| time_zone_name                                       |
| time_zone_transition                                 |
| time_zone_transition_type                            |
| user                                                 |
+------------------------------------------------------+
37 rows in set (0.00 sec)
mysql&amp;gt; exit【诶西特】 ;  #断开连接
Bye
[root@mysql50 ~]#  
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、密码管理&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/01-mysql%E4%B9%8B%E5%8D%95%E8%A1%A8%E6%9F%A5%E8%AF%A2/image-20250611214005798.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;4.1 问题&lt;/h3&gt;
&lt;p&gt;1） 在192.168.90.50主机做如下练习：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;设置root密码为moershi&lt;/li&gt;
&lt;li&gt;修改root密码为123qqq…A&lt;/li&gt;
&lt;li&gt;破解root密码为NSD123456…a&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;4.2 步骤&lt;/h3&gt;
&lt;p&gt;实现此案例需要按照如下步骤进行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;步骤一：设置root密码为moershi&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;p&gt;2行输出是警告而已不用关心&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# mysqladmin  -uroot -p  password &quot;moershi&quot;
Enter password: //敲回车
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@mysql50 ~]#
[root@mysql50 ~]# mysql //无密码连接被拒绝
ERROR 1045 (28000): Access denied for user &apos;root&apos;@&apos;localhost&apos; (using password: NO)
[root@mysql50 ~]#
[root@mysql50 ~]# mysql -uroot –pmoershi  //连接时输入密码
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 &apos;help;&apos; or &apos;\h&apos; for help. Type &apos;\c&apos; to clear the current input statement.
mysql&amp;gt; 登陆成功
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤二：修改root密码为123qqq…A&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# mysqladmin  -uroot -pmoershi password &quot;123qqq...A&quot;  //修改密码
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@mysql50 ~]#
[root@mysql50 ~]# mysql -uroot –pmoershi //旧密码无法登陆
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user &apos;root&apos;@&apos;localhost&apos; (using password: YES)
[root@mysql50 ~]#
[root@mysql50 ~]# mysql -uroot -p123qqq...A  //新密码登陆
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 18
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 &apos;help;&apos; or &apos;\h&apos; for help. Type &apos;\c&apos; to clear the current input statement.
mysql&amp;gt; 登陆成功
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤三：破解root密码为NSD123456…a&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;说明：在mysql50主机做此练习&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# mysql -uroot -pNSD123456...a  //破解前登陆失败
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user &apos;root&apos;@&apos;localhost&apos; (using password: YES)
[root@mysql50 ~]#
[root@mysql50 ~]# vim /etc/my.cnf.d/mysql-server.cnf  //修改主配置文件
[mysqld]
skip-grant-tables【忒-部s】  //手动添加此行 作用登陆时不验证密码
:wq
[root@mysql50 ~]#
[root@mysql50 ~]# systemctl【西斯听头】  restart【 率 s 达r】 mysqld //重启服务 作用让服务以新配置运行
[root@mysql50 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# 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 &apos;help;&apos; or &apos;\h&apos; for help. Type &apos;\c&apos; to clear the current input statement.
//查看存放密码的表头名
Mysql&amp;gt; 
Mysql&amp;gt; desc  mysql.user ;
//把mysql库下user表中 用户root的密码设置为无；
Mysql&amp;gt; 
mysql&amp;gt; update mysql.user set authentication_string=&quot;&quot; where【威尔】 user=&quot;root&quot;;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1  Changed: 1  Warnings: 0
Mysql&amp;gt; 
mysql&amp;gt; exit【诶西特】; 断开连接
Bye
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]#
[root@mysql50 ~]# vim  /etc/my.cnf.d/mysql-server.cnf  编辑配置文件
[mysqld]
#skip-grant-tables【忒-部s】   //注释添加的行
:wq
[root@mysql50 ~]#
[root@mysql50 ~]# systemctl【西斯听头】  restart【 率 s 达r】 mysqld //重启服务 作用让注释生效
[root@mysql50 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[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 &apos;help;&apos; or &apos;\h&apos; for help. Type &apos;\c&apos; to clear the current input statement.
//设置root用户本机登陆密码
Mysql&amp;gt; 
mysql&amp;gt; alter user root@&quot;localhost&quot; identified by &quot;NSD123456...a&quot;;
Query OK, 0 rows affected (0.00 sec)
Mysql&amp;gt; 
mysql&amp;gt; exit【诶西特】 断开连接
Bye
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]#
[root@localhost ~]# mysql  不输密码无法登陆
ERROR 1045 (28000): Access denied for user &apos;root&apos;@&apos;localhost&apos; (using password: NO)
[root@mysql50 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# mysql -uroot -pNSD123456...a  使用破解的密码登陆
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 10
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 &apos;help;&apos; or &apos;\h&apos; for help. Type &apos;\c&apos; to clear the current input statement.
mysql&amp;gt;
mysql&amp;gt; #登陆成功
Mysql&amp;gt; 
mysql&amp;gt; show【瘦】 databases;【得塔-贝斯】 查看已有的库
+----------------------------------------------+
| Database【得塔-贝斯】                          |
+----------------------------------------------+
|  information【因弗梅申】_schema【斯京(白话)磨】 |
| mysql                                        |
| performance【破佛曼斯】_schema【斯京(白话)磨】  |
| sys                                          |
+----------------------------------------------+
4 rows in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、筛选条件&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/01-mysql%E4%B9%8B%E5%8D%95%E8%A1%A8%E6%9F%A5%E8%AF%A2/image-20250611214103915.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;5.1导入数据&lt;/h3&gt;
&lt;p&gt;拷贝moershi.sql文件到mysql50主机里，然后使用moershi.sql创建练习使用的数据。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//恢复数据
[root@mysql50 ~]# mysql -uroot  -pNSD123456...a &amp;lt; /root/moershi.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
//连接服务
[root@mysql50 ~]# mysql -uroot  -pNSD123456...a
mysql&amp;gt; 
mysql&amp;gt; show【瘦】 databases;【得塔-贝斯】 //查看库
+----------------------------------------------+
| Database【得塔-贝斯】                         |
+----------------------------------------------+
|  information【因弗梅申】_schema【斯京(白话)磨】 |
| mysql                                        |
| performance【破佛曼斯】_schema【斯京(白话)磨】  |
| sys                                          |
| moershi                                      | 恢复的库
+----------------------------------------------+
5 rows in set (0.00 sec)
mysql&amp;gt; 
mysql&amp;gt; use moershi; //进入库
Reading table【忒-部】 information【因弗梅申】 for completion of table【忒-部】 and column names
You can turn off this feature to get a quicker startup【s 达 啊普】 with -A
Database【得塔-贝斯】 changed
mysql&amp;gt; 
mysql&amp;gt; show【瘦】 tables;【忒-部s】  //查看表
+------------------+
| Tables【忒-部s】_in_moershi |
+------------------+
| departments      | 部门表
| employees        | 员工表
| salary           | 工资表
| user             | 用户表
+------------------+
4 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 使用user 表做查询练习&lt;/h3&gt;
&lt;p&gt;user表里存储的是 系统用户信息( 就是 /etc/passwd 文件的内容)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; desc moershi.user;  //查看表头
+----------+-------------+------+-----+----------------+----------------+
| Field    | Type        | Null【nò】 | Key | Default | Extra          |
+----------+-------------+------+-----+----------------+----------------+
| id       | int(11)     | NO   | PRI | NULL【nò】    | auto_increment |行号
| name     | char(20)    | YES  |     | NULL【nò】    |                |用户名
| password | char(1)     | YES  |     | NULL【nò】    |                |密码占位符
| uid      | int(11)     | YES  |     | NULL【nò】    |                | uid号
| gid      | int(11)     | YES  |     | NULL【nò】    |                | gid号
| comment  | varchar(50) | YES  |     | NULL【nò】    |                | 描述信息
| homedir  | varchar(80) | YES  |     | NULL【nò】    |                | 家目录
| shell    | char(30)    | YES  |     | NULL【nò】    |                | 解释器
+----------+-------------+------+-----+----------------+----------------+
8 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.3 select【涩莱克特】命令格式演示&lt;/h3&gt;
&lt;p&gt;语法格式1 select【涩莱克特】 字段列表 FROM【弗乱】 库名.表名;&lt;/p&gt;
&lt;p&gt;语法格式2 select【涩莱克特】 字段列表 FROM【弗乱】 库名.表名 where【威尔】 筛选条件;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 name from【弗乱】  moershi.user;        //查看一个表头
+-----------------+
| name            |
+-----------------+
| root            |
| bin             |
| daemon          |
| adm             |
| lp              |
| sync            |
| shutdown        |
| halt            |
| mail            |
| operator        |
| games           |
| ftp             |
| nobody          |
| systemd-network |
| dbus            |
| polkitd         |
| sshd            |
| postfix         |
| chrony          |
| rpc             |
| rpcuser         |
| nfsnobody       |
| haproxy         |
| plj             |
| apache          |
| mysql           |
| bob             |
+-----------------+
27 rows in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 name ,uid from【弗乱】  moershi.user;    //查看多个表头
+-----------------+-------+
| name            | uid   |
+-----------------+-------+
| root            |     0 |
| bin             |     1 |
| daemon          |     2 |
| adm             |     3 |
| lp              |     4 |
| sync            |     5 |
| shutdown        |     6 |
| halt            |     7 |
| mail            |     8 |
| operator        |    11 |
| games           |    12 |
| ftp             |    14 |
| nobody          |    99 |
| systemd-network |   192 |
| dbus            |    81 |
| polkitd         |   999 |
| sshd            |    74 |
| postfix         |    89 |
| chrony          |   998 |
| rpc             |    32 |
| rpcuser         |    29 |
| nfsnobody       | 65534 |
| haproxy         |   188 |
| plj             |  1000 |
| apache          |    48 |
| mysql           |    27 |
| bob             |  NULL【nò】 |
+-----------------+-------+
27 rows in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 *  from【弗乱】  moershi.user;        //查看所有表头
+----+-----------------+----------+-------+-------+----------------------------+--------------------+----------------+
| id | name            | password | uid   | gid   | comment                    | homedir            | shell          |
+----+-----------------+----------+-------+-------+----------------------------+--------------------+----------------+
|  1 | root            | x        |     0 |     0 | root                       | /root              | /bin/bash      |
|  2 | bin             | x        |     1 |     1 | bin                        | /bin               | /sbin/nologin  |
|  3 | daemon          | x        |     2 |     2 | daemon                     | /sbin              | /sbin/nologin  |
|  4 | adm             | x        |     3 |     4 | adm                        | /var/adm           | /sbin/nologin  |
|  5 | lp              | x        |     4 |     7 | lp                         | /var/spool/lpd     | /sbin/nologin  |
|  6 | sync            | x        |     5 |     0 | sync                       | /sbin              | /bin/sync      |
|  7 | shutdown        | x        |     6 |     0 | shutdown                   | /sbin              | /sbin/shutdown |
|  8 | halt            | x        |     7 |     0 | halt                       | /sbin              | /sbin/halt     |
|  9 | mail            | x        |     8 |    12 | mail                       | /var/spool/mail    | /sbin/nologin  |
| 10 | operator        | x        |    11 |     0 | operator                   | /root              | /sbin/nologin  |
| 11 | games           | x        |    12 |   100 | games                      | /usr/games         | /sbin/nologin  |
| 12 | ftp             | x        |    14 |    50 | FTP User                   | /var/ftp           | /sbin/nologin  |
| 13 | nobody          | x        |    99 |    99 | Nobody                     | /                  | /sbin/nologin  |
| 14 | systemd-network | x        |   192 |   192 | systemd Network Management | /                  | /sbin/nologin  |
| 15 | dbus            | x        |    81 |    81 | System message bus         | /                  | /sbin/nologin  |
| 16 | polkitd         | x        |   999 |   998 | User for polkitd           | /                  | /sbin/nologin  |
| 17 | sshd            | x        |    74 |    74 | Privilege-separated SSH    | /var/empty/sshd    | /sbin/nologin  |
| 18 | postfix         | x        |    89 |    89 |                            | /var/spool/postfix | /sbin/nologin  |
| 19 | chrony          | x        |   998 |   996 |                            | /var/lib/chrony    | /sbin/nologin  |
| 20 | rpc             | x        |    32 |    32 | Rpcbind Daemon             | /var/lib/rpcbind   | /sbin/nologin  |
| 21 | rpcuser         | x        |    29 |    29 | RPC Service User           | /var/lib/nfs       | /sbin/nologin  |
| 22 | nfsnobody       | x        | 65534 | 65534 | Anonymous NFS User         | /var/lib/nfs       | /sbin/nologin  |
| 23 | haproxy         | x        |   188 |   188 | haproxy                    | /var/lib/haproxy   | /sbin/nologin  |
| 24 | plj             | x        |  1000 |  1000 |                            | /home/plj          | /bin/bash      |
| 25 | apache          | x        |    48 |    48 | Apache                     | /usr/share/httpd   | /sbin/nologin  |
| 26 | mysql           | x        |    27 |    27 | MySQL Server               | /var/lib/mysql     | /bin/false     |
| 27 | bob             | NUL【nò】L     |  NULL【nò】 |  NULL【nò】 | NULL【nò】                       | NULL【nò】               | NULL【nò】           |
+----+-----------------+----------+-------+-------+----------------------------+--------------------+----------------+
27 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;加筛选条件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 *  from【弗乱】  moershi.user where【威尔】  name = “root”;        //查找root用户信息 
+----+------+----------+------+------+---------+---------+-----------+
| id | name | password | uid  | gid  | comment | homedir | shell     |
+----+------+----------+------+------+---------+---------+-----------+
|  1 | root | x        |    0 |    0 | root    | /root   | /bin/bash |
+----+------+----------+------+------+---------+---------+-----------+
1 row in set (0.00 sec)
mysql&amp;gt; 
mysql&amp;gt; select【涩莱克特】 *  from【弗乱】  moershi.user where【威尔】  id = 2 ;        //查找第2行用户信息
+----+------+----------+------+------+---------+---------+--------------+
| id | name | password | uid  | gid  | comment | homedir | shell         |
+----+------+----------+------+------+---------+---------+--------------+
|  2 | bin   | x        |    1 |   1   | bin      | /bin   | /sbin/nologin |
+----+------+----------+------+------+---------+---------+--------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.4 练习数值比较&lt;/h3&gt;
&lt;p&gt;比较符号：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;符号&lt;/th&gt;
&lt;th&gt;意义&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;=&lt;/td&gt;
&lt;td&gt;相等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;!=&lt;/td&gt;
&lt;td&gt;不相等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;gt;&lt;/td&gt;
&lt;td&gt;大于&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;gt;=&lt;/td&gt;
&lt;td&gt;大于等于&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt;&lt;/td&gt;
&lt;td&gt;小于&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt;=&lt;/td&gt;
&lt;td&gt;小于等于&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;符号两边要是数字或数值类型的表头 符号左边与符号右边做比较&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//查看第3行的行号、用户名、uid、gid  四个表头的值
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】  id,name,uid,gid  from【弗乱】  moershi.user where【威尔】  id = 3;
+----+--------+------+------+
| id | name   | uid  | gid  |
+----+--------+------+------+
|  3 | daemon |    2 |    2 |
+----+--------+------+------+
1 row in set (0.00 sec)
//查看前2行的行号用户名、uid、gid 四个表头的值
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】  id,name,uid,gid  from【弗乱】  moershi.user where【威尔】  id &amp;lt; 3;
+----+------+------+------+
| id | name | uid  | gid  |
+----+------+------+------+
|  1 | root |    0 |    0 |
|  2 | bin  |    1 |    1 |
+----+------+------+------+
2 rows in set (0.00 sec)
//查看前3行的行号、用户名、uid、gid  四个表头的值
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】  id,name,uid,gid  from【弗乱】  moershi.user where【威尔】  id &amp;lt;= 3;
+----+--------+------+------+
| id | name   | uid  | gid  |
+----+--------+------+------+
|  1 | root   |    0 |    0 |
|  2 | bin    |    1 |    1 |
|  3 | daemon |    2 |    2 |
+----+--------+------+------+
3 rows in set (0.00 sec)
//查看前uid号大于6000的行号、用户名、uid、gid  四个表头的值
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】  id,name,uid,gid  from【弗乱】  moershi.user where【威尔】  uid &amp;gt; 6000;
+----+-----------+-------+-------+
| id | name      | uid   | gid   |
+----+-----------+-------+-------+
| 22 | nfsnobody | 65534 | 65534 |
+----+-----------+-------+-------+
1 row in set (0.00 sec)
//查看前uid号大于等于1000的行号、用户名、uid、gid  四个表头的值
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】  id,name,uid,gid  from【弗乱】  moershi.user where【威尔】  uid &amp;gt;= 1000;
+----+-----------+-------+-------+
| id | name      | uid   | gid   |
+----+-----------+-------+-------+
| 22 | nfsnobody | 65534 | 65534 |
| 24 | plj       |  1000 |  1000 |
+----+-----------+-------+-------+
2 rows in set (0.00 sec)
//查看uid号和gid号相同的行 仅显示行号、用户名、uid、gid  四个表头的值
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】  id,name,uid,gid  from【弗乱】  moershi.user where【威尔】  uid = gid;
+----+-----------------+-------+-------+
| id | name            | uid   | gid   |
+----+-----------------+-------+-------+
|  1 | root            |     0 |     0 |
|  2 | bin             |     1 |     1 |
|  3 | daemon          |     2 |     2 |
| 13 | nobody          |    99 |    99 |
| 14 | systemd-network |   192 |   192 |
| 15 | dbus            |    81 |    81 |
| 17 | sshd            |    74 |    74 |
| 18 | postfix         |    89 |    89 |
| 20 | rpc             |    32 |    32 |
| 21 | rpcuser         |    29 |    29 |
| 22 | nfsnobody       | 65534 | 65534 |
| 23 | haproxy         |   188 |   188 |
| 24 | plj             |  1000 |  1000 |
| 25 | apache          |    48 |    48 |
| 26 | mysql           |    27 |    27 |
+----+-----------------+-------+-------+
15 rows in set (0.00 sec)
//查看uid号和gid号不一样的行 仅显示行号、用户名、uid、gid  四个表头的值
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】  id,name,uid,gid  from【弗乱】  moershi.user where【威尔】  uid != gid;
+----+----------+------+------+
| id | name     | uid  | gid  |
+----+----------+------+------+
|  4 | adm      |    3 |    4 |
|  5 | lp       |    4 |    7 |
|  6 | sync     |    5 |    0 |
|  7 | shutdown |    6 |    0 |
|  8 | halt     |    7 |    0 |
|  9 | mail     |    8 |   12 |
| 10 | operator |   11 |    0 |
| 11 | games    |   12 |  100 |
| 12 | ftp      |   14 |   50 |
| 16 | polkitd  |  999 |  998 |
| 19 | chrony   |  998 |  996 |
+----+----------+------+------+
11 rows in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.5 练习范围匹配&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;in&lt;/td&gt;
&lt;td&gt;（值列表） //在…里&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;not【呐-特】 in&lt;/td&gt;
&lt;td&gt;（值列表） //不在…里&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;between【B豚ing】&lt;/td&gt;
&lt;td&gt;数字1 and 数字2 //在…之间&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作符&lt;/th&gt;
&lt;th&gt;语法&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;th&gt;返回值说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IN&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name IN (value1, value2, ...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查列值是否在指定的值列表中&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM products WHERE category_id IN (1, 3, 5);&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回 category_id 为 1、3 或 5 的所有产品&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NOT【呐-特】 IN&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name NOT【呐-特】 IN (value1, value2, ...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查列值是否不在指定的值列表中&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM users WHERE country NOT【呐-特】 IN (&apos;USA&apos;, &apos;Canada&apos;);&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回不在美国和加拿大的所有用户&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;BETWEEN【B豚ing】&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name BETWEEN【B豚ing】 value1 AND value2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查列值是否在指定的范围内（包含边界值）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM orders WHERE order_date BETWEEN【B豚ing】 &apos;2023-01-01&apos; AND &apos;2023-01-31&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回 2023 年 1 月期间的所有订单&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NOT BETWEEN【B豚ing】&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name NOT【呐-特】 BETWEEN【B豚ing】 value1 AND value2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查列值是否不在指定的范围内&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM employees WHERE salary NOT【呐-特】 BETWEEN【B豚ing】 30000 AND 60000;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回薪资低于 30,000 或高于 60,000 的所有员工&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;补充说明&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;IN 和 NOT【呐-特】 IN&lt;/strong&gt; 适用于离散值的匹配，可以用于数字、字符串、日期等数据类型&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BETWEEN【B豚ing】&lt;/strong&gt; 适用于连续范围的匹配，通常用于数字和日期范围&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BETWEEN【B豚ing】&lt;/strong&gt; 操作包含边界值，即 &lt;code&gt;BETWEEN【B豚ing】 10 AND 20&lt;/code&gt; 包含 10 和 20&lt;/li&gt;
&lt;li&gt;对于日期范围，建议使用标准日期格式（如 &apos;YYYY-MM-DD&apos;）以避免歧义&lt;/li&gt;
&lt;li&gt;这些操作符可以组合使用，并与其他 WHERE 子句条件结合&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//uid号表头的值 是 (1 , 3 , 5 , 7) 中的任意一个即可
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】 name,uid  from【弗乱】  moershi.user where【威尔】  uid  in (1 , 3 , 5 , 7);  
+------+------+
| name | uid  |
+------+------+
| bin  |    1 |
| adm  |    3 |
| sync |    5 |
| halt |    7 |
+------+------+
//shell 表头的的值 不是 &quot;/bin/bash&quot;或&quot;/sbin/nologin&quot; 即可
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】 name,shell  from【弗乱】  moershi.user where【威尔】  shell  not【呐-特】 in (&quot;/bin/bash&quot;,&quot;/sbin/nologin&quot;);
+----------+----------------+
| name     | shell          |
+----------+----------------+
| sync     | /bin/sync      |
| shutdown | /sbin/shutdown |
| halt     | /sbin/halt     |
| mysql    | /bin/false     |
+----------+----------------+
//id表头的值 在 10  到  20 之间即可 包括 10 和  20  本身
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】 id,name,uid  from【弗乱】  moershi.user where【威尔】 id  between【B豚ing】 10 and 20 ;
+----+-----------------+------+
| id | name            | uid  |
+----+-----------------+------+
| 10 | operator        |   11 |
| 11 | games           |   12 |
| 12 | ftp             |   14 |
| 13 | nobody          |   99 |
| 14 | systemd-network |  192 |
| 15 | dbus            |   81 |
| 16 | polkitd         |  999 |
| 17 | sshd            |   74 |
| 18 | postfix         |   89 |
| 19 | chrony          |  998 |
| 20 | rpc             |   32 |
+----+-----------------+------+
11 rows in set (0.00 sec)mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.6 练习模糊匹配&lt;/h3&gt;
&lt;p&gt;where【威尔】 字段名 like【赖特】 &quot;表达式&quot;;&lt;/p&gt;
&lt;p&gt;通配符&lt;/p&gt;
&lt;p&gt;_ 表示 1个字符&lt;/p&gt;
&lt;p&gt;% 表示零个或多个字符&lt;/p&gt;
&lt;h4&gt;SQL 模糊匹配操作符参考表&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作符/通配符&lt;/th&gt;
&lt;th&gt;语法&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;th&gt;匹配结果说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LIKE【赖特】&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;WHERE column_name LIKE【赖特】 &apos;pattern&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;用于在WHERE子句中搜索列中的指定模式&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM customers WHERE name LIKE【赖特】 &apos;J%&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回所有名字以&quot;J&quot;开头的客户&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;_&lt;/strong&gt; (下划线)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&apos;_&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;匹配任意单个字符&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM products WHERE code LIKE【赖特】 &apos;A_1&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;匹配&quot;A&quot; + 任意一个字符 + &quot;1&quot;，如&quot;A01&quot;, &quot;AB1&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;%&lt;/strong&gt; (百分号)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&apos;%&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;匹配零个或多个字符&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM emails WHERE address LIKE【赖特】 &apos;%@gmail.com&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;匹配所有Gmail邮箱地址&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NOT LIKE【赖特】&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;WHERE column_name NOT LIKE【赖特】 &apos;pattern&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;查找不匹配指定模式的行&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM files WHERE name NOT LIKE【赖特】 &apos;%.tmp&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回所有不是临时文件(.tmp)的文件&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;组合使用示例&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模式&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&apos;_%&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIKE【赖特】 &apos;_%&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;匹配至少有一个字符的值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&apos;%@%&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIKE【赖特】 &apos;%@%&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;匹配包含@符号的值（常用于邮箱验证）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&apos;__-___-____&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIKE【赖特】 &apos;__-___-____&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;匹配格式为XX-XXX-XXXX的值（如电话号码）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&apos;A%Z&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIKE【赖特】 &apos;A%Z&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;匹配以&quot;A&quot;开头并以&quot;Z&quot;结尾的值&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//找名字必须是3个字符的 （没有空格挨着敲）
mysql&amp;gt; select【涩莱克特】 name from【弗乱】  moershi.user where【威尔】  name like【赖特】 &quot;___&quot;; 
+------+
| name |
+------+
| bin  |
| adm  |
| ftp  |
| rpc  |
| plj  |
| bob  |
+------+
6 rows in set (0.00 sec)
//找名字必须是4个字符的（没有空格挨着敲）
mysql&amp;gt; select【涩莱克特】 name from【弗乱】  moershi.user where【威尔】  name like【赖特】 &quot;____&quot;; 
+------+
| name |
+------+
| root |
| sync |
| halt |
| mail |
| dbus |
| sshd |
| null【nò】 |
+------+
7 rows in set (0.00 sec)
//找名字以字母a开头的（没有空格挨着敲）
mysql&amp;gt; select【涩莱克特】 name from【弗乱】  moershi.user where【威尔】  name like【赖特】 &quot;a%&quot;;  
//查找名字至少是4个字符的表达式
mysql&amp;gt; select【涩莱克特】 name from【弗乱】  moershi.user where【威尔】  name like【赖特】 &quot;%____%&quot;;（没有空格挨着敲）
mysql&amp;gt; select【涩莱克特】 name from【弗乱】  moershi.user where【威尔】 name  like【赖特】 &quot;__%__&quot;;（没有空格挨着敲）
mysql&amp;gt; select【涩莱克特】 name from【弗乱】  moershi.user where【威尔】 name  like【赖特】 &quot;____%&quot;;（没有空格挨着敲）
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.7 练习逻辑比较&lt;/h3&gt;
&lt;p&gt;多个判断条件&lt;/p&gt;
&lt;p&gt;逻辑与 and （&amp;amp;&amp;amp;） 多个判断条件必须同时成立&lt;/p&gt;
&lt;p&gt;逻辑或 or （||） 多个判断条件其中某个条件成立即可&lt;/p&gt;
&lt;p&gt;逻辑非 not【呐-特】 （!） 取反&lt;/p&gt;
&lt;h4&gt;SQL 逻辑操作符参考表&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作符&lt;/th&gt;
&lt;th&gt;语法&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;th&gt;结果说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AND&lt;/strong&gt;  (逻辑与)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;condition1 AND condition2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;所有条件都必须为真，结果才为真&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM users WHERE age &amp;gt; 18 AND country = &apos;USA&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回年龄大于18岁且来自美国的用户&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OR&lt;/strong&gt; (逻辑或)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;condition1 OR condition2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;至少一个条件为真，结果就为真&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM products WHERE category = &apos;Electronics&apos; OR price &amp;gt; 1000;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回电子产品或价格超过1000的产品&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NOT&lt;/strong&gt; (逻辑非)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NOT condition&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;反转条件的真假值&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM orders WHERE NOT status = &apos;Cancelled&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回所有未取消的订单&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&amp;amp;&amp;amp;&lt;/strong&gt; (AND的替代符号)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;condition1 &amp;amp;&amp;amp; condition2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;某些数据库系统中AND的替代写法&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM users WHERE age &amp;gt; 18 &amp;amp;&amp;amp; country = &apos;USA&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;与AND相同，但并非所有数据库都支持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;||&lt;/strong&gt; (OR的替代符号)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;condition1 || condition2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;某些数据库系统中OR的替代写法&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM products WHERE category = &apos;Electronics&apos; || price &amp;gt; 1000;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;与OR相同，但并非所有数据库都支持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;!&lt;/strong&gt; (NOT的替代符号)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;!condition&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;某些数据库系统中NOT的替代写法&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM orders WHERE !status = &apos;Cancelled&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;与NOT相同，但并非所有数据库都支持&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;操作符优先级&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;优先级&lt;/th&gt;
&lt;th&gt;操作符&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;括号 ()&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;括号内的表达式最先计算&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;NOT&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;逻辑非&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;AND&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;逻辑与&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;OR&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;逻辑或&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//逻辑非例子，查看解释器不是/bin/bash 的
mysql&amp;gt; select【涩莱克特】 name,shell from【弗乱】 moershi.user where【威尔】  shell != &quot;/bin/bash&quot;; 
+-----------------+----------------+
| name            | shell          |
+-----------------+----------------+
| bin             | /sbin/nologin  |
| daemon          | /sbin/nologin  |
| adm             | /sbin/nologin  |
| lp              | /sbin/nologin  |
| sync            | /bin/sync      |
| shutdown        | /sbin/shutdown |
| halt            | /sbin/halt     |
| mail            | /sbin/nologin  |
| operator        | /sbin/nologin  |
| games           | /sbin/nologin  |
| ftp             | /sbin/nologin  |
| nobody          | /sbin/nologin  |
| systemd-network | /sbin/nologin  |
| dbus            | /sbin/nologin  |
| polkitd         | /sbin/nologin  |
| sshd            | /sbin/nologin  |
| postfix         | /sbin/nologin  |
| chrony          | /sbin/nologin  |
| rpc             | /sbin/nologin  |
| rpcuser         | /sbin/nologin  |
| nfsnobody       | /sbin/nologin  |
| haproxy         | /sbin/nologin  |
| apache          | /sbin/nologin  |
| mysql           | /bin/false     |
+-----------------+----------------+
24 rows in set (0.00 sec)

//not【呐-特】 也是取反  要放在表达式的前边
mysql&amp;gt; select【涩莱克特】 name,shell from【弗乱】 moershi.user where【威尔】  not【呐-特】  shell = &quot;/bin/bash&quot;;
+-----------------+----------------+
| name            | shell          |
+-----------------+----------------+
| bin             | /sbin/nologin  |
| daemon          | /sbin/nologin  |
| adm             | /sbin/nologin  |
| lp              | /sbin/nologin  |
| sync            | /bin/sync      |
| shutdown        | /sbin/shutdown |
| halt            | /sbin/halt     |
| mail            | /sbin/nologin  |
| operator        | /sbin/nologin  |
| games           | /sbin/nologin  |
| ftp             | /sbin/nologin  |
| nobody          | /sbin/nologin  |
| systemd-network | /sbin/nologin  |
| dbus            | /sbin/nologin  |
| polkitd         | /sbin/nologin  |
| sshd            | /sbin/nologin  |
| postfix         | /sbin/nologin  |
| chrony          | /sbin/nologin  |
| rpc             | /sbin/nologin  |
| rpcuser         | /sbin/nologin  |
| nfsnobody       | /sbin/nologin  |
| haproxy         | /sbin/nologin  |
| apache          | /sbin/nologin  |
| mysql           | /bin/false     |
+-----------------+----------------+
24 rows in set (0.00 sec)

//id值不在 10 到 20 之间 
mysql&amp;gt; select【涩莱克特】 id,name from【弗乱】 moershi.user where【威尔】 not【呐-特】  id between【B豚ing】 10 and 20 ;  
+----+-----------+
| id | name      |
+----+-----------+
|  1 | root      |
|  2 | bin       |
|  3 | daemon    |
|  4 | adm       |
|  5 | lp        |
|  6 | sync      |
|  7 | shutdown  |
|  8 | halt      |
|  9 | mail      |
| 21 | rpcuser   |
| 22 | nfsnobody |
| 23 | haproxy   |
| 24 | plj       |
| 25 | apache    |
| 26 | mysql     |
| 27 | bob       |
+----+-----------+
16 rows in set (0.00 sec)

//逻辑与 例子
mysql&amp;gt; select【涩莱克特】 name,uid from【弗乱】 moershi.user where【威尔】 name=&quot;root&quot; and uid = 1;      
Empty set (0.00 sec)
mysql&amp;gt; select【涩莱克特】 name,uid from【弗乱】 moershi.user where【威尔】 name=&quot;root&quot; and uid = 0;
+------+------+
| name | uid  |
+------+------+
| root |    0 |
+------+------+
1 row in set (0.00 sec)

//逻辑或 例子
mysql&amp;gt; select【涩莱克特】 name , uid from【弗乱】 moershi.user where【威尔】 name = &quot;root&quot;  or  name = &quot;bin&quot;  or  uid = 1;
+------+------+
| name | uid  |
+------+------+
| root |    0 |
| bin  |    1 |
+------+------+
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;逻辑匹配什么时候需要加（）&lt;/p&gt;
&lt;p&gt;逻辑与and 优先级高于逻辑或 or&lt;/p&gt;
&lt;p&gt;如果在筛选条件里既有and 又有 or 默认先判断and 再判断or&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//没加（） 的查询结果
select【涩莱克特】 name,uid from【弗乱】 moershi.user where【威尔】 name = &quot;root&quot; or name = &quot;bin&quot;  and uid = 1 ;  
+------+------+
| name | uid  |
+------+------+
| root |    0 |
| bin  |    1 |
+------+------+
2 rows in set (0.00 sec)
//加（）的查询结果
select【涩莱克特】 name , uid from【弗乱】 moershi.user where【威尔】 (name = &quot;root&quot; or name = &quot;bin&quot;)  and uid = 1 ;  
+------+------+
| name | uid  |
+------+------+
| bin  |    1 |
+------+------+
1 row in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.8 练习字符比较/空/非空&lt;/h3&gt;
&lt;p&gt;符号两边必须是字符 或字符类型的表头&lt;/p&gt;
&lt;p&gt;= 相等比较&lt;/p&gt;
&lt;p&gt;!= 不相等比较。&lt;/p&gt;
&lt;h4&gt;SQL 字符比较与空值判断操作符参考表&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作符&lt;/th&gt;
&lt;th&gt;语法&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;th&gt;结果说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;=&lt;/strong&gt; (等于)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name = &apos;value&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;比较两个字符值是否相等&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM users WHERE name = &apos;John&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回名字为&apos;John&apos;的用户&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;!=&lt;/strong&gt; 或 &lt;strong&gt;&amp;lt;&amp;gt;&lt;/strong&gt; (不等于)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name != &apos;value&apos;&lt;/code&gt; 或 &lt;code&gt;column_name &amp;lt;&amp;gt; &apos;value&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;比较两个字符值是否不相等&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM products WHERE category != &apos;Electronics&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回类别不是&apos;Electronics&apos;的产品&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IS NULL【nò】&lt;/strong&gt; (为空)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name IS NULL【nò】&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查列值是否为NULL【nò】&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM customers WHERE email IS NULL【nò】;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回没有填写邮箱的客户&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IS NOT【呐-特】 NULL【nò】&lt;/strong&gt; (非空)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name IS NOT【呐-特】 NULL【nò】&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查列值是否不为NULL【nò】&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM orders WHERE shipping_address IS NOT【呐-特】 NULL【nò】;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回已填写配送地址的订单&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;字符比较注意事项&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;注意事项&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;大小写敏感&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;在某些数据库系统中，字符比较可能区分大小写&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&apos;Apple&apos; = &apos;apple&apos;&lt;/code&gt; 可能返回false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;尾部空格&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;比较时可能会忽略或考虑字符串尾部的空格&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&apos;John &apos; = &apos;John&apos;&lt;/code&gt; 可能返回true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;字符集和排序规则&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;比较结果受数据库字符集和排序规则设置影响&lt;/td&gt;
&lt;td&gt;不同字符集可能导致不同的比较结果&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;空值判断的特殊性&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NULL【nò】与任何值的比较&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NULL【nò】与任何值(包括NULL【nò】本身)比较都返回未知(UNKNOWN)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NULL【nò】 = NULL【nò】&lt;/code&gt; 返回NULL【nò】而不是true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;三值逻辑&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;SQL使用三值逻辑: true, false, unknown&lt;/td&gt;
&lt;td&gt;&lt;code&gt;WHERE column = NULL【nò】&lt;/code&gt; 不会返回任何行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;正确判断空值&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;必须使用IS NULL【nò】或IS NOT【呐-特】 NULL【nò】判断空值&lt;/td&gt;
&lt;td&gt;&lt;code&gt;WHERE column IS NULL【nò】&lt;/code&gt; 正确判断空值&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//查看表里是否有名字叫apache的用户
mysql&amp;gt; select【涩莱克特】  name  from【弗乱】  moershi.user where【威尔】 name=&quot;apache&quot; ;
+--------+
| name   |
+--------+
| apache |
+--------+
1 row in set (0.00 sec)

//输出解释器不是/bin/bash的用户名 及使用的解释器
mysql&amp;gt; select【涩莱克特】  name,shell  from【弗乱】  moershi.user where【威尔】 shell != &quot;/bin/bash&quot;;
+-----------------+----------------+
| name            | shell          |
+-----------------+----------------+
| bin             | /sbin/nologin  |
| daemon          | /sbin/nologin  |
| adm             | /sbin/nologin  |
| lp              | /sbin/nologin  |
| sync            | /bin/sync      |
| shutdown        | /sbin/shutdown |
| halt            | /sbin/halt     |
| mail            | /sbin/nologin  |
| operator        | /sbin/nologin  |
| games           | /sbin/nologin  |
| ftp             | /sbin/nologin  |
| nobody          | /sbin/nologin  |
| systemd-network | /sbin/nologin  |
| dbus            | /sbin/nologin  |
| polkitd         | /sbin/nologin  |
| sshd            | /sbin/nologin  |
| postfix         | /sbin/nologin  |
| chrony          | /sbin/nologin  |
| rpc             | /sbin/nologin  |
| rpcuser         | /sbin/nologin  |
| nfsnobody       | /sbin/nologin  |
| haproxy         | /sbin/nologin  |
| apache          | /sbin/nologin  |
| mysql           | /bin/false     |
+-----------------+----------------+
24 rows in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;空 is null【nò】 表头下没有数据&lt;/p&gt;
&lt;p&gt;非空 is not【呐-特】 null【nò】 表头下有数据&lt;/p&gt;
&lt;p&gt;mysql服务 使用关键字 null【nò】 或 NULL【nò】 表示表头没有数据&lt;/p&gt;
&lt;h4&gt;MySQL 空值判断操作符参考表&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作符&lt;/th&gt;
&lt;th&gt;语法&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;th&gt;结果说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IS NULL【nò】&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name IS NULL【nò】&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查列值是否为 NULL【nò】（空值）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM users WHERE email IS NULL【nò】;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回 email 字段为空的用户&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IS NOT【呐-特】 NULL【nò】&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name IS NOT【呐-特】 NULL【nò】&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查列值是否不为 NULL【nò】（非空）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM orders WHERE amount IS NOT【呐-特】 NULL【nò】;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回 amount 字段有值的订单&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;NULL【nò】 值的特殊性质&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NULL【nò】 与空字符串的区别&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NULL【nò】 表示没有值，而空字符串(&apos;&apos;)是一个有效的值&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NULL【nò】 != &apos;&apos;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NULL【nò】 的比较&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NULL【nò】 与任何值(包括 NULL【nò】 本身)比较都返回未知&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NULL【nò】 = NULL【nò】&lt;/code&gt; 返回 NULL【nò】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NULL【nò】 的计算&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;任何包含 NULL【nò】 的计算结果通常都是 NULL【nò】&lt;/td&gt;
&lt;td&gt;&lt;code&gt;5 + NULL【nò】&lt;/code&gt; 返回 NULL【nò】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NULL【nò】 的逻辑运算&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NULL【nò】 参与逻辑运算时通常返回未知&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NULL【nò】 AND TRUE&lt;/code&gt; 返回 NULL【nò】&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;处理 NULL【nò】 值的函数&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;语法&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IFNULL()&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IFNULL(expr1, expr2)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;如果 expr1 不为 NULL【nò】，返回 expr1，否则返回 expr2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT IFNULL(salary, 0) FROM employees;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;COALESCE()&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;COALESCE(expr1, expr2, ...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回参数列表中第一个非 NULL【nò】 的值&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT COALESCE(phone, mobile, &apos;无联系方式&apos;) FROM contacts;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NULLIF()&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NULLIF(expr1, expr2)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;如果 expr1 = expr2，返回 NULL【nò】，否则返回 expr1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT NULLIF(salary, 0) FROM employees;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;//添加新行 仅给行中的id 表头和name表头赋值
mysql&amp;gt; insert【因涩特】 into moershi.user(id,name) values(71,&quot;&quot;);    //零个字符
mysql&amp;gt; insert【因涩特】 into moershi.user(id,name) values(72,&quot;null【nò】&quot;);//普通字母
mysql&amp;gt; insert【因涩特】 into moershi.user(id,name) values(73,NULL【nò】);  //表示空
mysql&amp;gt; insert【因涩特】 into moershi.user(id,name) values(74,null【nò】);  //表示空
//查看id表头值大于等于70  的行 仅显示行中 id表头 和  name 表头的值
mysql&amp;gt; select【涩莱克特】 id,name from【弗乱】  moershi.user where【威尔】  id &amp;gt;= 71;
+----+-------------+
| id | name        |
+----+-------------+
| 71 |             |
| 72 | null【nò】 |
| 73 | NULL【nò】 |
| 74 | NULL【nò】 |
+----+-------------+

//查看name 表头没有数据的行 仅显示行中id表头 和  naeme 表头的值
mysql&amp;gt; select【涩莱克特】 id,name from【弗乱】  moershi.user where【威尔】 name is null【nò】;
+----+-------------+
| id | name        |
+----+-------------+
| 28 | NULL【nò】 |
| 29 | NULL【nò】 |
| 73 | NULL【nò】 |
| 74 | NULL【nò】 |
+----+-------------+

//查看name 表头是0个字符的行， 仅显示行中id表头 和  naeme 表头的值
mysql&amp;gt; select【涩莱克特】 id,name from【弗乱】  moershi.user where【威尔】 name=&quot;&quot;;
+----+------+
| id | name |
+----+------+
| 71 |      |
+----+------+
1 row in set (0.00 sec)

//查看name 表头值是null【nò】的行， 仅显示行中id表头 和  naeme 表头的值
mysql&amp;gt; select【涩莱克特】 id,name from【弗乱】  moershi.user where【威尔】 name=&quot;null【nò】&quot;;
+----+------+
| id | name |
+----+------+
| 72 | null【nò】 |
+----+------+
1 row in set (0.00 sec)

//查看name 表头有数据的行， 仅显示行中id表头 和  name 表头的值
mysql&amp;gt; select【涩莱克特】 id,name from【弗乱】  moershi.user where【威尔】 name is not【呐-特】 null【nò】;
+----+-----------------+
| id | name            |
+----+-----------------+
|  1 | root            |
|  2 | bin             |
|  3 | daemon          |
|  4 | adm             |
|  5 | lp              |
....
....
| 27 | bob             |
| 71 |                 |
| 72 | null【nò】            |
+----+-----------------+
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.9 练习别名/去重/合并&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作类型&lt;/th&gt;
&lt;th&gt;关键字/函数&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;th&gt;主要用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;别名&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AS&lt;/code&gt; 或空格&lt;/td&gt;
&lt;td&gt;为列或表赋予临时名称&lt;/td&gt;
&lt;td&gt;提高可读性、简化复杂查询&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;去重&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;DISTINCT【迪斯定特】&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;去除查询结果中的重复行&lt;/td&gt;
&lt;td&gt;获取唯一值列表&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;合并&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UNION&lt;/code&gt; / &lt;code&gt;UNION ALL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;合并多个SELECT语句的结果集&lt;/td&gt;
&lt;td&gt;组合来自不同查询的数据&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;别名&lt;/h4&gt;
&lt;p&gt;基本语法&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 列别名
SELECT column_name AS alias_name FROM table_name;
SELECT column_name alias_name FROM table_name; -- 省略AS

-- 表别名
SELECT t.column_name FROM table_name AS t;
SELECT t.column_name FROM table_name t; -- 省略AS
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用场景&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;简化复杂列名或表达式&lt;/li&gt;
&lt;li&gt;提高查询结果的可读性&lt;/li&gt;
&lt;li&gt;在多表连接中简化表引用&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//定义别名使用   as  或  空格    
mysql&amp;gt; select【涩莱克特】 name,homedir  from【弗乱】 moershi.user;
+-----------------+--------------------+
| name            | homedir            |
+-----------------+--------------------+
| root            | /root              |
| bin             | /bin               |
| daemon          | /sbin              |
| adm             | /var/adm           |
| lp              | /var/spool/lpd     |
| sync            | /sbin              |
| shutdown        | /sbin              |
| halt            | /sbin              |
| mail            | /var/spool/mail    |
| operator        | /root              |
| games           | /usr/games         |
| ftp             | /var/ftp           |
| nobody          | /                  |
| systemd-network | /                  |
| dbus            | /                  |
| polkitd         | /                  |
| sshd            | /var/empty/sshd    |
| postfix         | /var/spool/postfix |
| chrony          | /var/lib/chrony    |
| rpc             | /var/lib/rpcbind   |
| rpcuser         | /var/lib/nfs       |
| nfsnobody       | /var/lib/nfs       |
| haproxy         | /var/lib/haproxy   |
| plj             | /home/plj          |
| apache          | /usr/share/httpd   |
| mysql           | /var/lib/mysql     |
| bob             | NULL               |
+-----------------+--------------------+
27 rows in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 name as 用户名,homedir  家目录 from【弗乱】 moershi.user;
+-----------------+--------------------+
| 用户名          | 家目录             |
+-----------------+--------------------+
| root            | /root              |
| bin             | /bin               |
| daemon          | /sbin              |
| adm             | /var/adm           |
| lp              | /var/spool/lpd     |
| sync            | /sbin              |
| shutdown        | /sbin              |
| halt            | /sbin              |
| mail            | /var/spool/mail    |
| operator        | /root              |
| games           | /usr/games         |
| ftp             | /var/ftp           |
| nobody          | /                  |
| systemd-network | /                  |
| dbus            | /                  |
| polkitd         | /                  |
| sshd            | /var/empty/sshd    |
| postfix         | /var/spool/postfix |
| chrony          | /var/lib/chrony    |
| rpc             | /var/lib/rpcbind   |
| rpcuser         | /var/lib/nfs       |
| nfsnobody       | /var/lib/nfs       |
| haproxy         | /var/lib/haproxy   |
| plj             | /home/plj          |
| apache          | /usr/share/httpd   |
| mysql           | /var/lib/mysql     |
| bob             | NULL               |
+-----------------+--------------------+
27 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;合并&lt;/h4&gt;
&lt;p&gt;SQL 两种“合并”操作对比表&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;&lt;code&gt;CONCAT()&lt;/code&gt; (字符串拼接)&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;&lt;code&gt;UNION&lt;/code&gt; / &lt;code&gt;UNION ALL&lt;/code&gt; (结果集合并)&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;操作对象&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;列内的数据&lt;/strong&gt;（字符串、文本）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;查询结果集&lt;/strong&gt;（行）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;操作方向&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;水平&lt;/strong&gt;合并（将多个列的值拼接到一行里）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;垂直&lt;/strong&gt;合并（将多个查询的结果上下堆叠）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;目的&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;生成新的格式化字符串&lt;/td&gt;
&lt;td&gt;组合来自不同查询的数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;语法示例&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT CONCAT(first_name, &apos; &apos;, last_name) FROM users;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT name FROM table1 UNION SELECT name FROM table2;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;结果图示&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&amp;lt;br&amp;gt;&lt;strong&gt;输入:&lt;/strong&gt; &lt;code&gt;John&lt;/code&gt; &lt;code&gt;Doe&lt;/code&gt;&amp;lt;br&amp;gt;&lt;strong&gt;输出:&lt;/strong&gt; &lt;code&gt;John Doe&lt;/code&gt;&amp;lt;br&amp;gt;&lt;/td&gt;
&lt;td&gt;&amp;lt;br&amp;gt;&lt;strong&gt;输入:&lt;/strong&gt; &amp;lt;br&amp;gt;查询1结果: &lt;code&gt;John&lt;/code&gt;&amp;lt;br&amp;gt;查询2结果: &lt;code&gt;Jane&lt;/code&gt;&amp;lt;br&amp;gt;&lt;strong&gt;输出:&lt;/strong&gt; &amp;lt;br&amp;gt;&lt;code&gt;John&lt;/code&gt;&amp;lt;br&amp;gt;&lt;code&gt;Jane&lt;/code&gt;&amp;lt;br&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h5&gt;1、 &lt;code&gt;CONCAT()&lt;/code&gt; - 字符串拼接函数（横向合并）&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;CONCAT()&lt;/code&gt; 用于将&lt;strong&gt;多个字符串字段或值连接成一个字符串&lt;/strong&gt;。它是在单条记录内进行操作。
&lt;strong&gt;基本语法：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CONCAT(string1, string2, ..., stringN)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;//拼接   concat【康(白话)凯特】()
mysql&amp;gt; select【涩莱克特】 concat【康(白话)凯特】(name,&quot;-&quot;,uid) as 用户信息 from【弗乱】 moershi.user where【威尔】 uid &amp;lt;= 5;
+--------------+
| 用户信息     |
+--------------+
| root-0       |
| bin-1        |
| daemon-2     |
| adm-3        |
| lp-4         |
| sync-5       |
+--------------+
6 rows in set (0.00 sec)
//2列拼接
mysql&amp;gt;  select【涩莱克特】 concat【康(白话)凯特】(name,&quot;-&quot;,uid)  as  用户信息  from【弗乱】 moershi.user where【威尔】 uid &amp;lt;= 5;
+--------------+
| 用户信息     |
+--------------+
| root-0       |
| bin-1        |
| daemon-2     |
| adm-3        |
| lp-4         |
| sync-5       |
+--------------+
6 rows in set (0.00 sec)

//多列拼接
mysql&amp;gt;  select【涩莱克特】 concat【康(白话)凯特】(name,&quot;-&quot;,uid ,&quot;-&quot;,gid)  as  用户信息  from【弗乱】 moershi.user where【威尔】 uid &amp;lt;= 5;
+--------------+
| 用户信息     |
+--------------+
| root-0-0     |
| bin-1-1      |
| daemon-2-2   |
| adm-3-4      |
| lp-4-7       |
| sync-5-0     |
+--------------+
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;2. &lt;code&gt;UNION&lt;/code&gt; / &lt;code&gt;UNION ALL&lt;/code&gt; - 结果集操作符（纵向合并）&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;UNION&lt;/code&gt; 用于将&lt;strong&gt;两个或多个 SELECT 语句的结果集合并&lt;/strong&gt;为一个结果集。它是在记录之间进行操作。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;基本语法：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT column1, column2 FROM table1
UNION [ALL]
SELECT column1, column2 FROM table2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;//把moershi.user表和moershi.departments的name数据纵向合并
mysql&amp;gt; select name from moershi.user union select dept_name from moershi.departments;
+-----------------+
| name            |
+-----------------+
| root            |
| bin             |
| daemon          |
| adm             |
| lp              |
| sync            |
| shutdown        |
| halt            |
| mail            |
| operator        |
| games           |
| ftp             |
| nobody          |
| systemd-network |
| dbus            |
| polkitd         |
| sshd            |
| postfix         |
| chrony          |
| rpc             |
| rpcuser         |
| nfsnobody       |
| haproxy         |
| plj             |
| apache          |
| mysql           |
| bob             |
| 人事部          |
| 财务部          |
| 运维部          |
| 开发部          |
| 测试部          |
| 市场部          |
| 销售部          |
| 法务部          |
+-----------------+
35 rows in set (0.00 sec)
//多列纵向合并
mysql&amp;gt; select id,name from moershi.user union select dept_id,dept_name from moershi.departments;
+----+-----------------+
| id | name            |
+----+-----------------+
|  1 | root            |
|  2 | bin             |
|  3 | daemon          |
|  4 | adm             |
|  5 | lp              |
|  6 | sync            |
|  7 | shutdown        |
|  8 | halt            |
|  9 | mail            |
| 10 | operator        |
| 11 | games           |
| 12 | ftp             |
| 13 | nobody          |
| 14 | systemd-network |
| 15 | dbus            |
| 16 | polkitd         |
| 17 | sshd            |
| 18 | postfix         |
| 19 | chrony          |
| 20 | rpc             |
| 21 | rpcuser         |
| 22 | nfsnobody       |
| 23 | haproxy         |
| 24 | plj             |
| 25 | apache          |
| 26 | mysql           |
| 27 | bob             |
|  1 | 人事部          |
|  2 | 财务部          |
|  3 | 运维部          |
|  4 | 开发部          |
|  5 | 测试部          |
|  6 | 市场部          |
|  7 | 销售部          |
|  8 | 法务部          |
+----+-----------------+
35 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2. 去重&lt;/h4&gt;
&lt;p&gt;去重显示 distinct【迪斯定特】 字段名列表
基本语法&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT DISTINCT【迪斯定特】 column1, column2 FROM table_name;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用场景&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;获取某列的唯一值列表&lt;/li&gt;
&lt;li&gt;统计不重复的记录数量&lt;/li&gt;
&lt;li&gt;避免重复数据影响分析结果&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;//去重前输出
mysql&amp;gt; select【涩莱克特】 shell  from【弗乱】  moershi.user  where【威尔】 shell in (&quot;/bin/bash&quot;,&quot;/sbin/nologin&quot;) ;
+---------------+
| shell         |
+---------------+
| /bin/bash     |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /bin/bash     |
| /sbin/nologin |
+---------------+
22 rows in set (0.00 sec)
//去重后查看
mysql&amp;gt; select【涩莱克特】 distinct【迪斯定特】 shell  from【弗乱】  moershi.user  where【威尔】 shell in (&quot;/bin/bash&quot;,&quot;/sbin/nologin&quot;) ;
+---------------+
| shell         |
+---------------+
| /bin/bash     |
| /sbin/nologin |
+---------------+
2 rows in set (0.01 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、作业&lt;/h2&gt;
&lt;h3&gt;1. 选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;MySQL 中，预设的拥有最高权限的超级用户的用户名为（ D ）
A. test
B. administrator
C. DBA
D. root&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;实现将 root 用户的密码修改为“123456”的语句，正确的是（ A ）
A. ALTER USER &apos;root&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;123456&apos;;
B. ALTER USER &apos;root&apos;@&apos;localhost&apos; IDENTIFIED BY 123456;
C. ALTER USER &apos;root&apos;@&apos;localhost&apos; =&apos;123456&apos;;
D. SET USER &apos;root&apos;@&apos;localhost&apos; =&apos;123456&apos;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;要启动 MySQL 服务，在 Linux 系统下可以使用的命令是（C  ）
A. service mysql start
B. systemctl start mysql
C. both A and B
D. mysql -u root -p&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;moershi.user&lt;/code&gt; 表中，查询 &lt;code&gt;id&lt;/code&gt; 大于 10 的记录，正确的 SQL 语句是（ A ）
A. select * FROM moershi.user where id &amp;gt; 10;
B. select * FROM  user where  id &amp;gt; 10;
C. select * FROM moershi.user where  id &amp;gt;= 10;
D. select * FROM user where  id &amp;gt;= 10;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;moershi.user&lt;/code&gt; 表中，查询 &lt;code&gt;uid&lt;/code&gt; 在 100 到 200 之间的记录，使用的关键字是（ A ）
A. BETWEEN
B. IN
C. LIKE
D. AND&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;moershi.user&lt;/code&gt; 表中，查询 &lt;code&gt;name&lt;/code&gt; 以“a”开头的记录，SQL 语句是（ A ）
A. select * FROM moershi.user where name LIKE &apos;a%&apos;;
B. select * FROM moershi.user where name LIKE &apos;%a&apos;;
C. select * FROM moershi.user where name LIKE &apos;%a%&apos;;
D. select * FROM moershi.user where name = &apos;a&apos;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;moershi.user&lt;/code&gt; 表中，查询 &lt;code&gt;id&lt;/code&gt; 大于 10 并且 &lt;code&gt;gid&lt;/code&gt; 小于 20 的记录，使用的逻辑运算符是（B  ）
A. OR
B. AND
C. NOT
D. XOR&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;moershi.user&lt;/code&gt; 表中，查询 &lt;code&gt;password&lt;/code&gt; 字段不为空的记录，SQL 语句是（ A ）
A. select * FROM moershi.user where password IS NOT NULL ;
B. select * FROM moershi.user where password = &apos;&apos;;
C. select * FROM moershi.user where password IS NULL ;
D. select * FROM moershi.user where password != &apos;&apos;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;moershi.user&lt;/code&gt; 表中，查询 &lt;code&gt;name&lt;/code&gt; 字段并给它起别名 &lt;code&gt;user_name&lt;/code&gt;，SQL 语句是（ A ）
A. select name AS user_name FROM moershi.user;
B. select user_name FROM moershi.user;
C. select name = user_name FROM moershi.user;
D. select user_name = name FROM moershi.user;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;moershi.user&lt;/code&gt; 表中，查询 &lt;code&gt;id&lt;/code&gt; 字段并去除重复值，使用的关键字是（ B ）
A. UNIQUE
B. DISTINCT
C. GROUP BY
D. ORDER BY&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;h4&gt;1. 简述 MySQL 密码管理的重要性以及常见的密码管理操作有哪些？&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;​重要性：​​
    安全性保障：防止未授权访问，保护敏感数据
    权限控制：确保只有授权用户才能执行数据库操作
    审计追踪：便于跟踪数据库访问和操作记录
    合规要求：满足数据安全法规和行业标准
    
​​常见的密码管理操作：​​
    设置/修改用户密码：ALTER USER &apos;username&apos;@&apos;host&apos; IDENTIFIED BY &apos;new_password&apos;;
    密码过期策略：ALTER USER &apos;username&apos;@&apos;host&apos; PASSWORD EXPIRE;
    密码复杂度要求：通过 validate_password 组件设置密码策略
    密码加密存储：MySQL 使用加密算法存储密码
    重置忘记的密码：通过安全模式启动 MySQL 重置密码
    查看用户权限：SHOW GRANTS FOR &apos;username&apos;@&apos;host&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2. 说明 MySQL 服务管理包含哪些方面，以及如何在 Linux 系统下停止和重启 MySQL 服务？&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;MySQL 服务管理包含的方面：​​
    服务启动和停止
    服务状态监控
    服务自动启动配置
    日志文件管理
    配置文件管理
    性能调优和监控

### 1. 服务启动和停止
- **启动 MySQL 服务**：
  ```bash
  systemctl start mysqld
  # 或使用 service 命令（适用于旧版系统）
  service mysqld start
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;停止 MySQL 服务&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl stop mysqld
service mysqld stop
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;重启 MySQL 服务&lt;/strong&gt;（常用于配置更改后）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl restart mysqld
service mysqld restart
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;重新加载配置&lt;/strong&gt;（不重启服务）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl reload mysqld
# 或通过 MySQL 内部命令
mysqladmin -u root -p reload
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 服务状态监控&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查服务状态&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl status mysqld
service mysqld status
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查 MySQL 进程是否运行&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ps aux | grep mysqld
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查 MySQL 端口监听&lt;/strong&gt;（默认 3306）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;netstat -tlnp | grep 3306
# 或使用 ss 命令
ss -tlnp | grep 3306
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查 MySQL 连接状态&lt;/strong&gt;（使用 MySQL 客户端）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysqladmin -u root -p status
# 或进入 MySQL 后执行
SHOW STATUS;
SHOW PROCESSLIST;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 服务自动启动配置&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;启用开机自动启动&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl enable mysqld
chkconfig mysqld on  # 适用于 SysVinit 系统
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;禁用开机自动启动&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl disable mysqld
chkconfig mysqld off  # 适用于 SysVinit 系统
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查看自动启动状态&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl is-enabled mysqld
chkconfig --list mysqld  # 适用于 SysVinit 系统
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. 日志文件管理&lt;/h3&gt;
&lt;p&gt;MySQL 有多种日志类型，如错误日志、查询日志、慢查询日志等。日志位置通常在 &lt;code&gt;/var/log/mysql/&lt;/code&gt; 或 &lt;code&gt;/var/log/&lt;/code&gt; 目录下，具体路径取决于配置文件。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查看错误日志&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tail -f /var/log/mysql/error.log
# 如果路径不同，请检查配置文件 my.cnf 中的 log_error 设置
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查看通用查询日志&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tail -f /var/log/mysql/mysql.log
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查看慢查询日志&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tail -f /var/log/mysql/slow.log
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;动态启用/禁用日志&lt;/strong&gt;（需要在 MySQL 配置文件中设置，然后重启或重新加载服务）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 在 MySQL 客户端中设置（临时生效）
SET GLOBAL general_log = &apos;ON&apos;;
SET GLOBAL slow_query_log = &apos;ON&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;日志轮转&lt;/strong&gt;（使用 logrotate）：
通常 MySQL 日志由 logrotate 管理，配置文件在 &lt;code&gt;/etc/logrotate.d/mysql&lt;/code&gt;。手动轮转：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;logrotate -f /etc/logrotate.d/mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5. 配置文件管理&lt;/h3&gt;
&lt;p&gt;MySQL 配置文件通常是 &lt;code&gt;/etc/my.cnf&lt;/code&gt; 或 &lt;code&gt;/etc/mysql/my.cnf&lt;/code&gt;，也可能包含在 &lt;code&gt;/etc/mysql/conf.d/&lt;/code&gt; 目录下。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;编辑配置文件&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo nano /etc/my.cnf
# 或使用其他编辑器
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查配置文件语法&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysqld --verbose --help | grep -A1 -B1 &quot;Default options&quot;
# 或使用
mysqld --validate-config
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;应用配置更改&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 重新加载配置（不重启服务）
systemctl reload mysqld
# 或重启服务
systemctl restart mysqld
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;6. 性能调优和监控&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;监控实时性能&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 使用 mysqladmin 查看状态
mysqladmin -u root -p extended-status
# 或进入 MySQL 后执行
SHOW GLOBAL STATUS;
SHOW ENGINE INNODB STATUS;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查变量设置&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql -u root -p -e &quot;SHOW VARIABLES;&quot;
# 或特定变量
mysql -u root -p -e &quot;SHOW VARIABLES LIKE &apos;%buffer%&apos;;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;性能分析工具&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;mysqltuner&lt;/strong&gt;：一个常用的脚本，用于分析配置和提供建议。&lt;pre&gt;&lt;code&gt;wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl
perl mysqltuner.pl --user root --pass
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pt-query-digest&lt;/strong&gt;：分析慢查询日志。&lt;pre&gt;&lt;code&gt;pt-query-digest /var/log/mysql/slow.log
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;mysqlslap&lt;/strong&gt;：负载测试工具。&lt;pre&gt;&lt;code&gt;mysqlslap -u root -p --concurrency=50 --iterations=100 --auto-generate-sql
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;优化表&lt;/strong&gt;（定期维护）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;OPTIMIZE TABLE table_name;
# 或使用 mysqlcheck
mysqlcheck -u root -p --optimize --all-databases
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;附加提示&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;确保使用具有适当权限的 MySQL 用户（如 root）执行命令。&lt;/li&gt;
&lt;li&gt;对于生产环境，建议定期备份和监控。&lt;/li&gt;
&lt;li&gt;如果使用 Docker 或其他容器化部署，命令可能有所不同。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果您有特定场景或问题，可以提供更多细节，我可以给出更具体的指导。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;   
#### 3. 请解释 SQL 中的数值比较、范围匹配、模糊匹配、逻辑比较、字符比较/空/非空、别名/去重/合并的概念，并各举一个在 `moershi.user` 表中的应用示例。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;数值比较​​：使用比较运算符（=, &amp;lt;&amp;gt;, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;=）比较数值
示例：SELECT * FROM moershi.user WHERE uid &amp;gt; 1000;
​​范围匹配​​：使用 BETWEEN 关键字匹配某个范围内的值
示例：SELECT * FROM moershi.user WHERE id BETWEEN 10 AND 20;
​​模糊匹配​​：使用 LIKE 关键字和通配符（%, _）进行模式匹配
示例：SELECT * FROM moershi.user WHERE name LIKE &apos;a%&apos;;
​​逻辑比较​​：使用逻辑运算符（AND, OR, NOT）组合多个条件
示例：SELECT * FROM moershi.user WHERE name = &apos;root&apos; AND uid = 0;
​​字符比较/空/非空​​：比较字符串值或检查字段是否为 NULL
字符比较示例：SELECT * FROM moershi.user WHERE name = &apos;root&apos;;
空/非空示例：SELECT * FROM moershi.user WHERE homedir IS NOT NULL;
​​别名/去重/合并​​：
别名：使用 AS 关键字为列或表指定临时名称
示例：SELECT name AS username, homedir AS home_directory FROM moershi.user;
去重：使用 DISTINCT 关键字去除查询结果中的重复行
示例：SELECT DISTINCT shell FROM moershi.user;
合并：使用 UNION 或 UNION ALL 合并多个查询的结果集
示例：SELECT name FROM moershi.user UNION SELECT dept_name FROM moershi.departments;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;   

### 3 操作题

#### 1.创建一个新的 MySQL 用户 `test_user`，密码为 `test_password`，并授予该用户对 `moershi.user` 表的查询权限。

```sql
mysql&amp;gt; create user if not exists &apos;test_user&apos;@&apos;%&apos; identified by &apos;test_password&apos;;
Query OK, 0 rows affected (0.21 sec)

mysql&amp;gt; GRANT SELECT ON moershi.user TO &apos;test_user&apos;@&apos;%&apos;;
Query OK, 0 rows affected (0.16 sec)

mysql&amp;gt; flush privileges;
Query OK, 0 rows affected (0.05 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2.请编写 SQL 语句，在 &lt;code&gt;moershi.user&lt;/code&gt; 表中查询 &lt;code&gt;id&lt;/code&gt; 大于 5 且 &lt;code&gt;name&lt;/code&gt; 以“r”开头的记录。&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select id,name from moershi.user where id &amp;gt; 5 and name like &quot;r%&quot;;
+----+---------+
| id | name    |
+----+---------+
| 20 | rpc     |
| 21 | rpcuser |
+----+---------+
2 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3.编写 SL 语句，将 &lt;code&gt;moershi.user&lt;/code&gt; 表中 &lt;code&gt;id&lt;/code&gt; 为 1 的记录的 &lt;code&gt;password&lt;/code&gt; 字段更新为 &lt;code&gt;new_password&lt;/code&gt;。&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select id,name,password from moershi.user where id =1; --查询原始信息
+----+------+----------+
| id | name | password |
+----+------+----------+
|  1 | root | x        |
+----+------+----------+
1 row in set (0.00 sec)

mysql&amp;gt; UPDATE moershi.user SET password = &apos;new_password&apos; WHERE id = 1; --这个错误表明 password字段的定义长度不足以存储 &apos;new_password&apos;这个值
ERROR 1406 (22001): Data too long for column &apos;password&apos; at row 1

mysql&amp;gt; DESCRIBE moershi.user; --检查表原始结构信息
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | int         | NO   | PRI | NULL    | auto_increment |
| name     | char(20)    | YES  |     | NULL    |                |
| password | char(1)     | YES  |     | NULL    |                |
| uid      | int         | YES  |     | NULL    |                |
| gid      | int         | YES  |     | NULL    |                |
| comment  | varchar(50) | YES  |     | NULL    |                |
| homedir  | varchar(80) | YES  |     | NULL    |                |
| shell    | char(30)    | YES  |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+
8 rows in set (0.01 sec)

mysql&amp;gt; ALTER TABLE moershi.user MODIFY password VARCHAR(50); --修改password结构大小
Query OK, 27 rows affected (2.64 sec)
Records: 27  Duplicates: 0  Warnings: 0

mysql&amp;gt; UPDATE moershi.user SET password = &apos;new_password&apos; WHERE id = 1; --重新修改id=1的password字段
Query OK, 1 row affected (0.11 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql&amp;gt; select id,name,password from moershi.user where id =1; --查看修改后的信息
+----+------+--------------+
| id | name | password     |
+----+------+--------------+
|  1 | root | new_password |
+----+------+--------------+
1 row in set (0.00 sec)

mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4.编写 SQL 语句，删除 &lt;code&gt;moershi.user&lt;/code&gt; 表中 &lt;code&gt;id&lt;/code&gt; 小于 3 的记录。&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; select * from moershi.user where id &amp;lt; 3;
+----+------+--------------+------+------+---------+---------+---------------+
| id | name | password     | uid  | gid  | comment | homedir | shell         |
+----+------+--------------+------+------+---------+---------+---------------+
|  1 | root | new_password |    0 |    0 | root    | /root   | /bin/bash     |
|  2 | bin  | x            |    1 |    1 | bin     | /bin    | /sbin/nologin |
+----+------+--------------+------+------+---------+---------+---------------+
2 rows in set (0.00 sec)

mysql&amp;gt; delete from moershi.user where id &amp;lt; 3;
Query OK, 2 rows affected (0.09 sec)

mysql&amp;gt; select * from moershi.user where id &amp;lt; 3;
Empty set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;5.编写 SQL 语句，将 &lt;code&gt;moershi.user&lt;/code&gt; 表按照 &lt;code&gt;id&lt;/code&gt; 字段降序排序，并取前 5 条记录。&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; 
mysql&amp;gt; select * from moershi.user order by id desc; --降序全部
+----+-----------------+----------+-------+-------+----------------------------+--------------------+----------------+
| id | name            | password | uid   | gid   | comment                    | homedir            | shell          |
+----+-----------------+----------+-------+-------+----------------------------+--------------------+----------------+
| 27 | bob             | NULL     |  NULL |  NULL | NULL                       | NULL               | NULL           |
| 26 | mysql           | x        |    27 |    27 | MySQL Server               | /var/lib/mysql     | /bin/false     |
| 25 | apache          | x        |    48 |    48 | Apache                     | /usr/share/httpd   | /sbin/nologin  |
| 24 | plj             | x        |  1000 |  1000 |                            | /home/plj          | /bin/bash      |
| 23 | haproxy         | x        |   188 |   188 | haproxy                    | /var/lib/haproxy   | /sbin/nologin  |
| 22 | nfsnobody       | x        | 65534 | 65534 | Anonymous NFS User         | /var/lib/nfs       | /sbin/nologin  |
| 21 | rpcuser         | x        |    29 |    29 | RPC Service User           | /var/lib/nfs       | /sbin/nologin  |
| 20 | rpc             | x        |    32 |    32 | Rpcbind Daemon             | /var/lib/rpcbind   | /sbin/nologin  |
| 19 | chrony          | x        |   998 |   996 |                            | /var/lib/chrony    | /sbin/nologin  |
| 18 | postfix         | x        |    89 |    89 |                            | /var/spool/postfix | /sbin/nologin  |
| 17 | sshd            | x        |    74 |    74 | Privilege-separated SSH    | /var/empty/sshd    | /sbin/nologin  |
| 16 | polkitd         | x        |   999 |   998 | User for polkitd           | /                  | /sbin/nologin  |
| 15 | dbus            | x        |    81 |    81 | System message bus         | /                  | /sbin/nologin  |
| 14 | systemd-network | x        |   192 |   192 | systemd Network Management | /                  | /sbin/nologin  |
| 13 | nobody          | x        |    99 |    99 | Nobody                     | /                  | /sbin/nologin  |
| 12 | ftp             | x        |    14 |    50 | FTP User                   | /var/ftp           | /sbin/nologin  |
| 11 | games           | x        |    12 |   100 | games                      | /usr/games         | /sbin/nologin  |
| 10 | operator        | x        |    11 |     0 | operator                   | /root              | /sbin/nologin  |
|  9 | mail            | x        |     8 |    12 | mail                       | /var/spool/mail    | /sbin/nologin  |
|  8 | halt            | x        |     7 |     0 | halt                       | /sbin              | /sbin/halt     |
|  7 | shutdown        | x        |     6 |     0 | shutdown                   | /sbin              | /sbin/shutdown |
|  6 | sync            | x        |     5 |     0 | sync                       | /sbin              | /bin/sync      |
|  5 | lp              | x        |     4 |     7 | lp                         | /var/spool/lpd     | /sbin/nologin  |
|  4 | adm             | x        |     3 |     4 | adm                        | /var/adm           | /sbin/nologin  |
|  3 | daemon          | x        |     2 |     2 | daemon                     | /sbin              | /sbin/nologin  |
+----+-----------------+----------+-------+-------+----------------------------+--------------------+----------------+
25 rows in set (0.00 sec)

mysql&amp;gt; select * from moershi.user order by id desc limit 5; --提取降序后的前5
+----+---------+----------+------+------+--------------+------------------+---------------+
| id | name    | password | uid  | gid  | comment      | homedir          | shell         |
+----+---------+----------+------+------+--------------+------------------+---------------+
| 27 | bob     | NULL     | NULL | NULL | NULL         | NULL             | NULL          |
| 26 | mysql   | x        |   27 |   27 | MySQL Server | /var/lib/mysql   | /bin/false    |
| 25 | apache  | x        |   48 |   48 | Apache       | /usr/share/httpd | /sbin/nologin |
| 24 | plj     | x        | 1000 | 1000 |              | /home/plj        | /bin/bash     |
| 23 | haproxy | x        |  188 |  188 | haproxy      | /var/lib/haproxy | /sbin/nologin |
+----+---------+----------+------+------+--------------+------------------+---------------+
5 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>02：mysql之常用函数</title><link>https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/02-mysql%E4%B9%8B%E5%B8%B8%E7%94%A8%E5%87%BD%E6%95%B0/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/02-mysql%E4%B9%8B%E5%B8%B8%E7%94%A8%E5%87%BD%E6%95%B0/</guid><description>02：mysql之常用函数 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1&gt;02：mysql之常用函数&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[常用函数]
        direction LR
        A[字符串函数] --&amp;gt; B[日期函数] --&amp;gt; C[聚集函数] --&amp;gt; D[数学计算] --&amp;gt; E[if函数] --&amp;gt; F[case函数]
    end

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;在电商公司的运营部门，为了评估商品销售情况，需要对数据库中的销售数据进行分析。数据库使用 MySQL 存储订单信息。运营人员需要统计不同商品类别的总销售额、平均销售单价和最高销售单价。
他们使用 MySQL 的聚合函数，&lt;code&gt;SUM()&lt;/code&gt; 计算每个商品类别的总销售额，&lt;code&gt;AVG()&lt;/code&gt; 求平均销售单价，&lt;code&gt;MAX()&lt;/code&gt; 获取最高销售单价。为了筛选出近期一个月内的有效订单，使用 &lt;code&gt;DATE_SUB()&lt;/code&gt; 函数确定时间范围。通过 &lt;code&gt;GROUP BY&lt;/code&gt; 对商品类别分组，将不同类别的数据区分开。最后，利用这些统计结果，运营人员制定针对性的营销策略，以提高销售额和利润。&lt;/p&gt;
&lt;h2&gt;二、为什么学mysql的函数&lt;/h2&gt;
&lt;p&gt;学习 MySQL 函数是提升数据库操作能力和数据处理效率的关键。在日常数据处理中，我们需要对数据进行各种计算、转换和筛选，而 MySQL 函数可以帮助我们轻松完成这些任务。&lt;/p&gt;
&lt;p&gt;例如，在统计销售数据时，我们可以使用聚合函数计算总销售额、平均价格等；在处理日期数据时，日期和时间函数能让我们方便地进行日期计算和格式化。掌握 MySQL 函数还能优化查询性能，通过合理运用函数，减少不必要的数据传输和处理，提高数据库的响应速度。此外，函数的使用还能使 SQL 语句更加简洁和易读，提升我们的工作效率和代码质量。&lt;/p&gt;
&lt;h2&gt;三、字符串函数&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[常用函数]
        direction LR
        A[字符串函数] --&amp;gt; B[日期函数] --&amp;gt; C[聚集函数] --&amp;gt; D[数学计算] --&amp;gt; E[if函数] --&amp;gt; F[case函数]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class A highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.1、返回字符串长度&lt;/h3&gt;
&lt;h4&gt;&lt;code&gt;LENGTH(str) &lt;/code&gt; 函数&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;函数名称&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LENGTH【冷斯】&lt;/code&gt; (在某些数据库中也称为 &lt;code&gt;LEN&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能说明&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;返回字符串的&lt;strong&gt;长度&lt;/strong&gt;。&lt;strong&gt;注意&lt;/strong&gt;：在大多数数据库中，此函数返回的是字符串的&lt;strong&gt;字节数&lt;/strong&gt;，而非字符数，这在处理多字节字符集（如UTF-8）时至关重要。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LENGTH【冷斯】(string)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;参数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;string&lt;/code&gt;: 需要计算长度的字符串。可以是字符串字面量（如&lt;code&gt;&apos;ABC&apos;&lt;/code&gt;）、字段名或变量。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;返回值&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一个整数值，表示字符串的&lt;strong&gt;字节数&lt;/strong&gt;。如果参数为 &lt;code&gt;NULL&lt;/code&gt;，则返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;示例&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1. &lt;code&gt;SELECT【涩莱克特】 LENGTH【冷斯】(&apos;Hello&apos;);&lt;/code&gt; -&amp;gt; &lt;strong&gt;5&lt;/strong&gt; (5个英文字符，在UTF-8中每个占1字节)&amp;lt;br&amp;gt;2. &lt;code&gt;SELECT【涩莱克特】 LENGTH【冷斯】(&apos;你好&apos;);&lt;/code&gt; -&amp;gt; &lt;strong&gt;6&lt;/strong&gt; (2个中文字符，在UTF-8中每个占3字节，共6字节)&amp;lt;br&amp;gt;3. &lt;code&gt;SELECT【涩莱克特】 LENGTH(column_name) from【弗乱】 table_name;&lt;/code&gt; -&amp;gt; 返回表中该字段各值的字节长度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;注意要点&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1. 字节 vs. 字符:&lt;/strong&gt; &amp;lt;br&amp;gt; - 这是最关键的区别。如果需要获取&lt;strong&gt;字符数&lt;/strong&gt;（通常更符合直觉），应使用 &lt;code&gt;CHAR_LENGTH【查_冷斯】()&lt;/code&gt; 或 &lt;code&gt;CHARACTER_LENGTH【冷斯】()&lt;/code&gt; 函数。&amp;lt;br&amp;gt; &lt;strong&gt;2. 数据库差异:&lt;/strong&gt; &amp;lt;br&amp;gt; - &lt;strong&gt;MySQL, MariaDB:&lt;/strong&gt; &lt;code&gt;LENGTH【冷斯】()&lt;/code&gt; 返回字节数，&lt;code&gt;CHAR_LENGTH【查_冷斯】()&lt;/code&gt; 返回字符数。&amp;lt;br&amp;gt; - &lt;strong&gt;SQL Server:&lt;/strong&gt; 使用 &lt;code&gt;LEN()&lt;/code&gt; 返回字符数（但会去掉尾部空格），使用 &lt;code&gt;DATALENGTH【得塔-冷斯】()&lt;/code&gt; 返回字节数。&amp;lt;br&amp;gt; - &lt;strong&gt;Oracle:&lt;/strong&gt; 使用 &lt;code&gt;LENGTHB()&lt;/code&gt; 返回字节数，&lt;code&gt;LENGTH【冷斯】()&lt;/code&gt; 返回字符数。&amp;lt;br&amp;gt; - &lt;strong&gt;PostgreSQL:&lt;/strong&gt; &lt;code&gt;LENGTH()&lt;/code&gt; 返回字符数，使用 &lt;code&gt;OCTET_LENGTH()&lt;/code&gt; 返回字节数。&amp;lt;br&amp;gt; - &lt;strong&gt;SQLite:&lt;/strong&gt; &lt;code&gt;LENGTH()&lt;/code&gt; 返回字符数。&amp;lt;br&amp;gt; &lt;strong&gt;3. 空字符串:&lt;/strong&gt; &lt;code&gt;LENGTH(&apos;&apos;)&lt;/code&gt; 返回 &lt;strong&gt;0&lt;/strong&gt;。&amp;lt;br&amp;gt; &lt;strong&gt;4. NULL 值:&lt;/strong&gt; &lt;code&gt;LENGTH(NULL)&lt;/code&gt; 返回 &lt;strong&gt;NULL&lt;/strong&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;使用建议&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;在不确定数据库字符集或需要处理多语言文本时，&lt;strong&gt;强烈建议使用 &lt;code&gt;CHAR_LENGTH【查_冷斯】】()&lt;/code&gt; 来获取字符数&lt;/strong&gt;，以避免因字符编码不同导致的意外结果。&lt;code&gt;LENGTH【冷斯】()&lt;/code&gt; 更适用于计算存储空间等需要字节精度的场景。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;LENGTH vs. CHAR_LENGTH&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;测量单位&lt;/th&gt;
&lt;th&gt;UTF-8 示例 &lt;code&gt;LENGTH【冷斯】(&apos;你好&apos;)&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;LENGTH【冷斯】(str)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;字节&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6&lt;/strong&gt; (2字符 * 3字节/字符)&lt;/td&gt;
&lt;td&gt;计算存储占用、网络传输大小&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;CHAR_LENGTH【查_冷斯】(str)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;字符&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;计算字符串的实际字符数量、显示长度、业务逻辑&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;LENGTH(str)&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;--LENGTH【冷斯】(str)             返字符串长度，以字节为单位
mysql&amp;gt; select【涩莱克特】 name from【弗乱】 moershi.user where【威尔】 name = &quot;root&quot; ;
+------+
| name |
+------+
| root |
+------+
1 row in set (0.00 sec)
mysql&amp;gt; select【涩莱克特】 name,length【冷斯】(name) as 字节个数 from moershi.user where【威尔】 name = &quot;root&quot; ;
+------+--------------+
| name | 字节个数      |
+------+--------------+
| root |            4  |
+------+--------------+
1 row in set (0.00 sec)

--一个汉字3个字节
mysql&amp;gt; select【涩莱克特】 name,length【冷斯】(name) from【弗乱】 moershi.employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id = 3 ;
+-----------+--------------+
| name      | length【冷斯】(name) |
+-----------+--------------+
| 李玉英    |            9 |
+-----------+--------------+
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;CHAR_LENGTH(str)&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;-- CHAR_LENGTH【查_冷斯】(str)        返回字符串长度，以字符为单位
mysql&amp;gt; select【涩莱克特】 name from【弗乱】 moershi.employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id = 3 ;
+-----------+
| name      |
+-----------+
| 李玉英    |
+-----------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 name,char_length【查_冷斯】(name) from【弗乱】 moershi.employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id = 3 ;
+-----------+-----------------------------+
| name      | char_length【查_冷斯】(name) |
+-----------+-----------------------------+
| 李玉英     |                 3           |
+-----------+-----------------------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2、将字符串转换为大写&lt;/h3&gt;
&lt;h4&gt;函数概览&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;UPPER【阿普厄】(str)&lt;/code&gt; 和 &lt;code&gt;UCASE【U kèi 斯】(str)&lt;/code&gt; 函数的功能完全相同，都是将字符串 &lt;code&gt;str&lt;/code&gt; 中的所有字母字符转换为大写形式。它们互为同义词，区别仅在于函数名称，以适应不同用户的习惯。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;函数名称&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UPPER【阿普厄】(str)&lt;/code&gt;, &lt;code&gt;UCASE【U kèi 斯】(str)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能描述&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;将字符串 &lt;code&gt;str&lt;/code&gt; 中的所有字母字符转换为大写形式。非字母字符（如数字、空格、特殊符号）保持不变。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;通用语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UPPER【阿普厄】(string【斯jǘn】)&lt;/code&gt; &amp;lt;br&amp;gt; &lt;code&gt;UCASE【U kèi 斯】(string【斯jǘn】)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;参数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;string【斯jǘn】&lt;/code&gt;: 需要转换的字符串。可以是字符串字面量（如 &lt;code&gt;&apos;abc&apos;&lt;/code&gt;）、字段名或变量。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;返回值&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一个新的字符串，其中所有小写字母已被转换为大写字母。如果参数为 &lt;code&gt;NULL，则返回 &lt;/code&gt;NULL`。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;基本用法&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; SELECT【涩莱克特】 UPPER【阿普厄】(&apos;Hello World!&apos;) AS UpperText;
-- 结果: &apos;HELLO WORLD!&apos;

mysql&amp;gt; SELECT【涩莱克特】 UCASE【U kèi 斯】(&apos;sql is fun&apos;) AS UpperText;
-- 结果: &apos;SQL IS FUN&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;总结与对比&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;UPPER【阿普厄】(str)&lt;/th&gt;
&lt;th&gt;UCASE【U kèi 斯】(str)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;将字符串转换为大写&lt;/td&gt;
&lt;td&gt;将字符串转换为大写&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;标准性&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;SQL 标准&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;非标准，但广泛实现&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;通用性&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;极高&lt;/strong&gt;，所有SQL数据库都支持&lt;/td&gt;
&lt;td&gt;很高，但并非所有数据库都支持（如Oracle不支持&lt;code&gt;UCASE【U kèi 斯】&lt;/code&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;推荐度&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;⭐️⭐️⭐️⭐️⭐️ (首选)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⭐️⭐️⭐️⭐️&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;-- UPPER【阿普厄】(str)和UCASE【U kèi 斯】(str)  将字符串中的字母全部转换成大写
mysql&amp;gt; select【涩莱克特】 name from【弗乱】  moershi.user where【威尔】 uid &amp;lt;= 3 ;
+--------+
| name   |
+--------+
| root   |
| bin    |
| daemon |
| adm    |
+--------+
4 rows in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 upper【阿普厄】(name) from【弗乱】  moershi.user where【威尔】 uid &amp;lt;= 3 ;
+-------------+
| upper【阿普厄】(name) |
+-------------+
| ROOT        |
| BIN         |
| DAEMON      |
| ADM         |
+-------------+
4 rows in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 ucase【U kèi 斯】(name) from【弗乱】  moershi.user where【威尔】 uid &amp;lt;= 3 ;
+-------------+
| ucase【U kèi 斯】(name) |
+-------------+
| ROOT        |
| BIN         |
| DAEMON      |
| ADM         |
+-------------+
4 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3、将字符串转换成小写&lt;/h3&gt;
&lt;p&gt;好的，这是关于 SQL 中 &lt;code&gt;LOWER【喽厄】()&lt;/code&gt; 和 &lt;code&gt;LCASE【L kèi 斯】()&lt;/code&gt; 函数的详细说明。&lt;/p&gt;
&lt;h4&gt;函数概览&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;LOWER【喽厄】(str)&lt;/code&gt; 和 &lt;code&gt;LCASE【L kèi 斯】(str)&lt;/code&gt; 函数的功能完全相同，都是将字符串 &lt;code&gt;str&lt;/code&gt; 中的所有字母字符转换为小写形式。它们互为同义词，区别仅在于函数名称。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;函数名称&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LOWER【喽厄】(str)&lt;/code&gt;, &lt;code&gt;LCASE【L kèi 斯】(str)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能描述&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;将字符串 &lt;code&gt;str&lt;/code&gt; 中的所有字母字符转换为小写形式。非字母字符（如数字、空格、特殊符号）保持不变。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;通用语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LOWER【喽厄】(string【斯jǘn】)&lt;/code&gt; &amp;lt;br&amp;gt; &lt;code&gt;LCASE【L kèi 斯】(string【斯jǘn】)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;参数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;string【斯jǘn】&lt;/code&gt;: 需要转换的字符串。可以是字符串字面量（如 &lt;code&gt;&apos;ABC&apos;&lt;/code&gt;）、字段名或变量。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;返回值&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一个新的字符串，其中所有大写字母已被转换为小写字母。如果参数为 &lt;code&gt;NULL&lt;/code&gt;，则返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h4&gt;基本用法与示例&lt;/h4&gt;
&lt;h5&gt;1. 直接转换文本字符串&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; SELECT LOWER【喽厄】(&apos;HELLO World! 123&apos;) AS LowerText;
+------------------+
| LowerText        |
+------------------+
| hello world! 123 |
+------------------+
1 row in set (0.00 sec)

-- 结果: &apos;hello world! 123&apos;

mysql&amp;gt; SELECT LCASE【L kèi 斯】(&apos;SQL Tutorial&apos;) AS LowerText;
+--------------+
| LowerText    |
+--------------+
| sql tutorial |
+--------------+
1 row in set (0.00 sec)

-- 结果: &apos;sql tutorial&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;3. 在 WHERE 子句中实现不区分大小写的比较或搜索&lt;/h5&gt;
&lt;p&gt;这是该函数最常用和实用的场景之一。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 查找类别为 &apos;electronics&apos; 的所有产品，不区分大小写
mysql&amp;gt; SELECT * FROM products WHERE LOWER【喽厄】(category) = &apos;electronics&apos;;

-- 在模糊查询中实现不区分大小写
mysql&amp;gt; SELECT * FROM users WHERE LOWER【喽厄】(email) LIKE &apos;%@gmail.com&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;4. 与 UPPER/UCASE 结合使用进行数据标准化&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;-- 将用户输入的用户名统一格式化为小写后存储，确保唯一性
mysql&amp;gt; UPDATE【阿普dei 特】 users SET username = LOWER【喽厄】(&apos;SomeUserName&apos;) WHERE id = 100;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;总结与对比&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;LOWER【喽厄】(str)&lt;/th&gt;
&lt;th&gt;LCASE【L kèi 斯】(str)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;将字符串转换为小写&lt;/td&gt;
&lt;td&gt;将字符串转换为小写&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;标准性&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;SQL 标准&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;非标准，但广泛实现&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;通用性&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;极高&lt;/strong&gt;，所有主流SQL数据库都支持&lt;/td&gt;
&lt;td&gt;很高，但并非所有数据库都支持（如 &lt;strong&gt;Oracle 不支持 &lt;code&gt;LCASE【L kèi 斯】&lt;/code&gt;&lt;/strong&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;推荐度&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;⭐️⭐️⭐️⭐️⭐️ (首选)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⭐️⭐️⭐️⭐️&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h5&gt;核心结论与最佳实践&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;功能完全相同&lt;/strong&gt;：&lt;code&gt;LOWER【喽厄】()&lt;/code&gt; 和 &lt;code&gt;LCASE【L kèi 斯】()&lt;/code&gt; 的功能&lt;strong&gt;完全一致&lt;/strong&gt;，选择哪一个通常取决于个人习惯。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;首选 &lt;code&gt;LOWER【喽厄】()&lt;/code&gt;&lt;/strong&gt;：&lt;strong&gt;&lt;code&gt;LOWER【喽厄】()&lt;/code&gt; 是 SQL 标准中定义的函数&lt;/strong&gt;，因此具有最广泛的数据库支持（包括 Oracle）。为了代码的最大兼容性、可读性和可移植性，&lt;strong&gt;应优先使用 &lt;code&gt;LOWER【喽厄】()&lt;/code&gt;&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主要应用场景&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;数据比较&lt;/strong&gt;：在 &lt;code&gt;WHERE&lt;/code&gt; 子句中进行不区分大小写的比较。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据搜索&lt;/strong&gt;：实现不区分大小写的搜索 (&lt;code&gt;LIKE&lt;/code&gt;)。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据标准化&lt;/strong&gt;：在存储或显示前将文本统一为小写格式。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;注意 NULL&lt;/strong&gt;：如果输入参数为 &lt;code&gt;NULL&lt;/code&gt;，输出结果也为 &lt;code&gt;NULL&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;-- LOWER【喽厄】(str)和LCASE【L kèi 斯】(str)    将str中的字母全部转换成小写
mysql&amp;gt; select【涩莱克特】 lower【喽厄】(&quot;ABCD&quot;) ;
+---------------+
| lower【喽厄】(&quot;ABCD&quot;) |
+---------------+
| abcd          |
+---------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 lcase【L kèi 斯】(&quot;ABCD&quot;) ;
+---------------+
| lcase【L kèi 斯】(&quot;ABCD&quot;) |
+---------------+
| abcd          |
+---------------+
1 row in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.4、从字符串中提取&lt;strong&gt;子串&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;substr【杀斯妥】&lt;/p&gt;
&lt;h4&gt;函数概览&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;SUBSTR【杀斯妥】()&lt;/code&gt; 函数用于从字符串中提取&lt;strong&gt;子串&lt;/strong&gt;。它是 SQL 中最重要和常用的字符串函数之一。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;函数名称&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTR【杀斯妥】(string【斯jǘn】, start, length)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;别名&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTRING【杀斯jǘn】()&lt;/code&gt; (功能完全相同，&lt;code&gt;SUBSTR【杀斯妥】&lt;/code&gt; 更常见)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能描述&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;从原字符串中返回一个从指定位置开始、具有指定长度的子字符串。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;通用语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTR【杀斯妥】(string【斯jǘn】, start [, length])&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;参数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1. &lt;code&gt;string【斯jǘn】&lt;/code&gt;：必需的。要提取子串的源字符串。&amp;lt;br&amp;gt;2. &lt;code&gt;start&lt;/code&gt;：必需的。开始位置。&amp;lt;br&amp;gt; &lt;strong&gt;重要&lt;/strong&gt;：&lt;strong&gt;起始位置通常为 1，而不是 0&lt;/strong&gt;。&amp;lt;br&amp;gt;3. &lt;code&gt;length&lt;/code&gt;：可选的。要提取的字符数。如果省略，则返回从 &lt;code&gt;start&lt;/code&gt; 开始到字符串结尾的所有字符。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;返回值&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;提取出的子字符串。如果任何参数为 &lt;code&gt;NULL&lt;/code&gt;，则返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;基本用法与示例&lt;/h4&gt;
&lt;h5&gt;1. 指定起始位置和长度&lt;/h5&gt;
&lt;p&gt;这是最常用的形式。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt;  SELECT SUBSTR【杀斯妥】(&apos;SQL Tutorial&apos;, 1, 3) AS ExtractString;
+---------------+
| ExtractString |
+---------------+
| SQL           |
+---------------+
1 row in set (0.02 sec)
-- 结果: &apos;SQL&apos; (从第1个字符开始，取3个字符)

mysql&amp;gt; SELECT SUBSTR【杀斯妥】(&apos;SQL Tutorial&apos;, 5, 4) AS ExtractString;
+---------------+
| ExtractString |
+---------------+
| Tuto          |
+---------------+
1 row in set (0.00 sec)
-- 结果: &apos;Tuto&apos; (从第5个字符(&apos;T&apos;)开始，取4个字符)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;2. 省略长度参数（提取到末尾）&lt;/h5&gt;
&lt;p&gt;如果省略第三个参数，函数将返回从起始位置到字符串末尾的所有字符。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt;  SELECT SUBSTR【杀斯妥】(&apos;SQL Tutorial&apos;, 5) AS ExtractString;
+---------------+
| ExtractString |
+---------------+
| Tutorial      |
+---------------+
1 row in set (0.00 sec)
-- 结果: &apos;Tutorial&apos; (从第5个字符开始，直到结束)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;3. 使用负起始位置（从末尾开始计数）&lt;/h5&gt;
&lt;p&gt;&lt;strong&gt;这是一个非常实用的功能&lt;/strong&gt;。许多数据库（如 MySQL、PostgreSQL、SQLite）支持使用负数作为 &lt;code&gt;start&lt;/code&gt; 参数，表示从字符串&lt;strong&gt;末尾&lt;/strong&gt;开始向前计数。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 提取最后 3 个字符
mysql&amp;gt; SELECT SUBSTR【杀斯妥】(&apos;SQL Tutorial&apos;, -3) AS ExtractString;
+---------------+
| ExtractString |
+---------------+
| ial           |
+---------------+
1 row in set (0.00 sec)
-- 结果: &apos;ial&apos;

-- 从倒数第 6 个字符开始，提取 4 个字符
mysql&amp;gt; SELECT SUBSTR【杀斯妥】(&apos;SQL Tutorial&apos;, -6, 4) AS ExtractString;
+---------------+
| ExtractString |
+---------------+
| tori          |
+---------------+
1 row in set (0.00 sec)
-- 结果: &apos;ori&apos; (从倒数第6位(&apos;o&apos;)开始，取4个字符。但后面只剩3个，所以只返回&apos;ori&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;注意：SQL Server 不支持负起始位置，需配合 &lt;code&gt;LEN()&lt;/code&gt; 函数计算。&lt;/em&gt;&lt;/p&gt;
&lt;h5&gt;4. 在查询中处理表字段数据&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;-- 提取每个人的姓氏（假设从第6个字符开始）
mysql&amp;gt; SELECT full_name, SUBSTR【杀斯妥】(full_name, 6) AS last_name FROM employees【ing普洛伊s】;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;总结与对比：SUBSTR【杀斯妥】 vs. SUBSTRING【杀斯jǘn】&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;SUBSTR【杀斯妥】(...)&lt;/th&gt;
&lt;th&gt;SUBSTRING【杀斯jǘn】(...)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;从字符串中提取子串&lt;/td&gt;
&lt;td&gt;从字符串中提取子串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;普及度&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;非常普遍&lt;/strong&gt;，是许多数据库中的主要函数名&lt;/td&gt;
&lt;td&gt;也很常见，是 SQL 标准名称&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTR【杀斯妥】(str, start, length)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTRING【杀斯jǘn】(str FROM start FOR length)&lt;/code&gt; (标准语法) 或 &lt;code&gt;SUBSTRING(str, start, length)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;数据库支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;MySQL, Oracle, SQLite, PostgreSQL, MariaDB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;SQL Server, PostgreSQL, MySQL&lt;/strong&gt; (也支持&lt;code&gt;SUBSTR&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;推荐度&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⭐️⭐️⭐️⭐️⭐️ (通用性极佳)&lt;/td&gt;
&lt;td&gt;⭐️⭐️⭐️⭐️ (是标准，但需注意数据库方言)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;不同数据库的注意事项&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;数据库&lt;/th&gt;
&lt;th&gt;主要函数&lt;/th&gt;
&lt;th&gt;负起始位置&lt;/th&gt;
&lt;th&gt;备注&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MySQL, MariaDB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTR【杀斯妥】()&lt;/code&gt; 或 &lt;code&gt;SUBSTRING【杀斯jǘn】()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;两者完全同义。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Oracle&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTR【杀斯妥】()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;不支持 &lt;code&gt;SUBSTRING【杀斯jǘn】&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SQL Server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTRING【杀斯jǘn】()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;不支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;需用 &lt;code&gt;LEN(string【斯jǘn】) + 1 - n&lt;/code&gt; 来计算从末尾开始的位置。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTRING【杀斯jǘn】()&lt;/code&gt; (标准) 或 &lt;code&gt;SUBSTR【杀斯妥】()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;两者都可用。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SQLite&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTR【杀斯妥】()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;核心结论与最佳实践&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;功能核心&lt;/strong&gt;：&lt;code&gt;SUBSTR【杀斯妥】(str, start, length)&lt;/code&gt; 用于精确提取字符串的特定部分。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;起始索引&lt;/strong&gt;：&lt;strong&gt;牢记起始位置通常是 1&lt;/strong&gt;，这是与许多编程语言（如 Python、Java）从 0 开始索引的最大区别。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;负索引&lt;/strong&gt;：&lt;strong&gt;负起始位置是一个非常有用的特性&lt;/strong&gt;，可以轻松地从字符串末尾开始操作，但要注意 SQL Server 不支持。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;兼容性建议&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;如果你主要在 &lt;strong&gt;MySQL、Oracle、SQLite&lt;/strong&gt; 中工作，可以放心使用 &lt;code&gt;SUBSTR【杀斯妥】()&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;如果你在 &lt;strong&gt;SQL Server&lt;/strong&gt; 中工作，则必须使用 &lt;code&gt;SUBSTRING【杀斯jǘn】()&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;为了编写跨数据库兼容的 SQL，了解这些差异至关重要。在不确定时，查看数据库的官方文档是最好的方法。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;常见用途&lt;/strong&gt;：提取区号、获取文件扩展名、隐藏部分敏感信息（如 &lt;code&gt;SUBSTR【杀斯妥】(phone_number, -4)&lt;/code&gt; 显示手机尾号）、解析固定格式的代码等。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;--SUBSTR【杀斯妥】(s, start,end)     从s的start位置开始取出到end长度的子串
mysql&amp;gt; select【涩莱克特】 name from【弗乱】  moershi.employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id &amp;lt;= 3 ;
+-----------+
| name      |
+-----------+
| 梁伟      |
| 郭岩      |
| 李玉英    |
+-----------+
3 rows in set (0.00 sec)
--不是输出员工的姓 只输出名字（只输出第2、3个字符）
mysql&amp;gt; select【涩莱克特】 substr(name,2,3) from【弗乱】  moershi.employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id &amp;lt;= 3 ;
+------------------+
| substr(name,2,3) |
+------------------+
| 伟               |
| 岩               |
| 玉英             |
+------------------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.5、在一个字符串中查找另一个子字符串&lt;/h3&gt;
&lt;h4&gt;函数概览&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;INSTR()&lt;/code&gt; 函数用于在一个字符串中查找另一个子字符串，并返回其&lt;strong&gt;首次出现的位置&lt;/strong&gt;。如果未找到，则返回 0。它是一个非常重要的字符串查找函数。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;函数名称&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;INSTR(string【斯jǘn】, substring【杀斯jǘn】)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;别名&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LOCATE()&lt;/code&gt; (在MySQL中), &lt;code&gt;CHARINDEX()&lt;/code&gt; (在SQL Server中)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能描述&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;返回子字符串 &lt;code&gt;substring【杀斯jǘn】&lt;/code&gt; 在字符串 &lt;code&gt;string【斯jǘn】&lt;/code&gt; 中&lt;strong&gt;第一次出现&lt;/strong&gt;的起始位置。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;通用语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;INSTR(string【斯jǘn】, substring【杀斯jǘn】)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;扩展语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;某些数据库（如Oracle、MySQL）支持可选参数来指定起始搜索位置和出现次数：&lt;code&gt;INSTR(string【斯jǘn】, substring【杀斯jǘn】 [, start [, occurrence]])&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;参数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1. &lt;code&gt;string【斯jǘn】&lt;/code&gt;：必需的。被搜索的源字符串。&amp;lt;br&amp;gt;2. &lt;code&gt;substring【杀斯jǘn】&lt;/code&gt;：必需的。要查找的子字符串。&amp;lt;br&amp;gt;3. &lt;code&gt;start&lt;/code&gt;：可选的。开始搜索的位置，默认为 1。&amp;lt;br&amp;gt;4. &lt;code&gt;occurrence&lt;/code&gt;：可选的。指定要查找第几次出现的位置，默认为 1。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;返回值&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一个整数值，表示子串首次出现的起始位置。&amp;lt;br&amp;gt;&lt;strong&gt;位置从 1 开始计数&lt;/strong&gt;。&amp;lt;br&amp;gt;如果未找到子串，则返回 &lt;strong&gt;0&lt;/strong&gt;。&amp;lt;br&amp;gt;如果任何参数为 &lt;code&gt;NULL&lt;/code&gt;，则返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;基本用法与示例&lt;/h4&gt;
&lt;p&gt;为了演示，我们使用字符串 &lt;code&gt;&apos;Hello World! Welcome to the World of SQL.&apos;&lt;/code&gt; 作为示例源字符串。&lt;/p&gt;
&lt;h5&gt;1. 基本查找：查找子串首次出现的位置&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; SELECT INSTR(&apos;Hello World!&apos;, &apos;World&apos;) AS Position;
+----------+
| Position |
+----------+
|        7 |
+----------+
1 row in set (0.00 sec)

-- 结果: 7 (因为 &apos;W&apos; 是源字符串的第7个字符)
-- 分解: H e l l o [空格] W o r l d !
-- 位置: 1 2 3 4 5  6    7 8 9 10 11 12
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;2. 查找不存在的子串&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; SELECT INSTR(&apos;Hello World!&apos;, &apos;SQL&apos;) AS Position;
+----------+
| Position |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)
-- 结果: 0 (因为 &apos;SQL&apos; 没有出现)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;3. 在查询中处理表字段数据&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;-- 找到所有产品代码中连字符 &apos;-&apos; 的位置
mysql&amp;gt; SELECT product_code, INSTR(product_code, &apos;-&apos;) AS hyphen_position FROM products;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;4. 与其他函数组合使用（常与 SUBSTR 搭配）&lt;/h5&gt;
&lt;p&gt;一个非常强大的组合是先用 &lt;code&gt;INSTR&lt;/code&gt; 定位，再用 &lt;code&gt;SUBSTR&lt;/code&gt; 截取。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 提取产品代码中连字符之后的部分（型号）
mysql&amp;gt; SELECT product_code,SUBSTR(product_code, INSTR(product_code, &apos;-&apos;) + 1) AS model_number FROM products;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;结果：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;product_code&lt;/th&gt;
&lt;th&gt;model_number&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LAPTOP-001&lt;/td&gt;
&lt;td&gt;001&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MOUSE-002&lt;/td&gt;
&lt;td&gt;002&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KEYBOARD-003&lt;/td&gt;
&lt;td&gt;003&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;逻辑：先找到 &lt;code&gt;-&lt;/code&gt; 的位置 (N)，然后从 N+1 的位置开始截取到末尾。&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;总结与对比：INSTR vs. 其他类似函数&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;INSTR(string【斯jǘn】, substring【杀斯jǘn】)&lt;/th&gt;
&lt;th&gt;LOCATE (MySQL)&lt;/th&gt;
&lt;th&gt;CHARINDEX (SQL Server)&lt;/th&gt;
&lt;th&gt;POSITION (标准SQL)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;INSTR(str, substr)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LOCATE(substr, str [, start])&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CHARINDEX(substr, str [, start])&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;POSITION(substr IN str)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;参数顺序&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;(字符串, 子串)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;(子串, 字符串)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;(子串, 字符串)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;(子串 IN 字符串)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;起始位置&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;可选第三参数 &lt;code&gt;start&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;可选第三参数 &lt;code&gt;start&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;可选第三参数 &lt;code&gt;start&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;不支持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;出现次数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;可选第四参数 &lt;code&gt;occurrence&lt;/code&gt; (Oracle/MySQL)&lt;/td&gt;
&lt;td&gt;不支持&lt;/td&gt;
&lt;td&gt;不支持&lt;/td&gt;
&lt;td&gt;不支持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;返回值&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;位置 (从1开始) / 0&lt;/td&gt;
&lt;td&gt;位置 (从1开始) / 0&lt;/td&gt;
&lt;td&gt;位置 (从1开始) / 0&lt;/td&gt;
&lt;td&gt;位置 (从1开始) / 0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;不同数据库的注意事项与语法&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;数据库&lt;/th&gt;
&lt;th&gt;主要函数&lt;/th&gt;
&lt;th&gt;语法示例&lt;/th&gt;
&lt;th&gt;备注&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Oracle&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;INSTR&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;INSTR(&apos;abc&apos;, &apos;b&apos;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;支持扩展参数 (&lt;code&gt;start&lt;/code&gt;, &lt;code&gt;occurrence&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MySQL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;INSTR&lt;/code&gt; 或 &lt;code&gt;LOCATE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;INSTR(&apos;abc&apos;, &apos;b&apos;)&lt;/code&gt; 或 &lt;code&gt;LOCATE(&apos;b&apos;, &apos;abc&apos;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;INSTR&lt;/code&gt; 支持扩展参数，&lt;code&gt;LOCATE&lt;/code&gt; 支持 &lt;code&gt;start&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SQL Server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;CHARINDEX&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CHARINDEX(&apos;b&apos;, &apos;abc&apos;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;不支持 &lt;code&gt;occurrence&lt;/code&gt; 参数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;STRPOS&lt;/code&gt;&lt;/strong&gt; 或 &lt;code&gt;POSITION&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;STRPOS(&apos;abc&apos;, &apos;b&apos;)&lt;/code&gt; 或 &lt;code&gt;POSITION(&apos;b&apos; IN &apos;abc&apos;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;POSITION&lt;/code&gt; 是标准SQL语法&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SQLite&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;INSTR&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;INSTR(&apos;abc&apos;, &apos;b&apos;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;只支持两个基本参数&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;核心结论与最佳实践&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;功能核心&lt;/strong&gt;：&lt;code&gt;INSTR&lt;/code&gt; 用于&lt;strong&gt;定位&lt;/strong&gt;，而不是提取。它返回的是数字位置。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;黄金搭档&lt;/strong&gt;：&lt;code&gt;INSTR&lt;/code&gt; 常与 &lt;code&gt;SUBSTR&lt;/code&gt; 组合使用，实现“先定位，后截取”的强大功能。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;参数顺序陷阱&lt;/strong&gt;：&lt;strong&gt;不同数据库的参数顺序可能不同&lt;/strong&gt;（特别是 &lt;code&gt;INSTR&lt;/code&gt; 和 &lt;code&gt;CHARINDEX/LOCATE&lt;/code&gt;）。这是最大的混淆点，使用时务必注意。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;兼容性建议&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;如果你主要在 &lt;strong&gt;Oracle、SQLite&lt;/strong&gt; 中工作，使用 &lt;code&gt;INSTR&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;如果你在 &lt;strong&gt;MySQL&lt;/strong&gt; 中工作，&lt;code&gt;INSTR&lt;/code&gt; 和 &lt;code&gt;LOCATE&lt;/code&gt; 都可以，但注意参数顺序。&lt;/li&gt;
&lt;li&gt;如果你在 &lt;strong&gt;SQL Server&lt;/strong&gt; 中工作，必须使用 &lt;code&gt;CHARINDEX&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;为了编写符合SQL标准的代码，可以使用 &lt;code&gt;POSITION(substr IN str)&lt;/code&gt;，但功能可能最基础。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;常见用途&lt;/strong&gt;：查找特定字符或关键字的位置、解析结构化字符串（如URL、代码）、验证字符串中是否包含某部分内容（结果&amp;gt;0即表示包含）。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;-- INSTR(str,str1)        返回str1参数，在str参数内的位置
mysql&amp;gt;  select【涩莱克特】 name from【弗乱】  moershi.user where【威尔】 uid &amp;lt;= 3 ;
+--------+
| name   |
+--------+
| root   |
| bin    |
| daemon |
| adm    |
+--------+
4 rows in set (0.00 sec)

--查找名字里有a及出现的位置
mysql&amp;gt; select【涩莱克特】 name,instr(name,&quot;a&quot;) from【弗乱】  moershi.user where【威尔】 uid &amp;lt;= 3 ;
+--------+-----------------+
| name   | instr(name,&quot;a&quot;) |
+--------+-----------------+
| root   |               0 |
| bin    |               0 |
| daemon |               2 |
| adm    |               1 |
+--------+-----------------+
4 rows in set (0.00 sec)

-- 查找名字里有英字及出现的位置
mysql&amp;gt; select【涩莱克特】 name , instr(name,&quot;英&quot;) from【弗乱】  moershi.employees【ing普洛伊s】;
+-----------+-------------------+
| name      | instr(name,&quot;英&quot;)  |
+-----------+-------------------+
| 梁伟      |                 0 |
| 郭岩      |                 0 |
| 李玉英    |                 3 |
| 张健      |                 0 |
| 郑静      |                 0 |
| 牛建军    |                 0 |
| 刘斌      |                 0 |
| 汪云      |                 0 |
| 张建平    |                 0 |
| 郭娟      |                 0 |
| 郭兰英    |                 3 |
| 王英      |                 2 |
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.6、移除字符串开头和/或结尾处的指定字符&lt;/h3&gt;
&lt;h4&gt;函数概览&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;TRIM【垂姆】()&lt;/code&gt; 函数用于&lt;strong&gt;移除字符串开头和/或结尾处&lt;/strong&gt;的&lt;strong&gt;指定字符&lt;/strong&gt;（默认为空格）。它是数据清洗和标准化中最重要、最常用的函数之一。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;函数名称&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TRIM【垂姆】(...)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能描述&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;从字符串的&lt;strong&gt;两端&lt;/strong&gt;（开头和结尾）移除指定的前缀和后缀字符（默认为空格）。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;标准语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TRIM【垂姆】([removal_spec] [remove_char] FROM string【斯jǘn】)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;简化语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TRIM【垂姆】(string【斯jǘn】)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;参数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1. &lt;code&gt;string【斯jǘn】&lt;/code&gt;：必需的。要处理的源字符串。&amp;lt;br&amp;gt;2. &lt;code&gt;removal_spec&lt;/code&gt;：可选的。指定移除位置：&amp;lt;br&amp;gt;   - &lt;code&gt;LEADING&lt;/code&gt;：只移除开头的字符。&amp;lt;br&amp;gt;   - &lt;code&gt;TRAILING&lt;/code&gt;：只移除结尾的字符。&amp;lt;br&amp;gt;   - &lt;code&gt;BOTH&lt;/code&gt;：移除开头和结尾的字符（默认行为）。&amp;lt;br&amp;gt;3. &lt;code&gt;remove_char&lt;/code&gt;：可选的。指定要移除的字符，默认为空格 &lt;code&gt;&apos; &apos;&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;返回值&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一个新的字符串，已移除指定位置上的指定字符。如果参数为 &lt;code&gt;NULL&lt;/code&gt;，则返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;基本用法与示例&lt;/h4&gt;
&lt;h5&gt;基本语法​说明&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM] str)

&amp;gt; BOTH​​：移除字符串​​开头和结尾​​的字符（默认选项）。
&amp;gt; ​​LEADING​​：仅移除字符串​​开头​​的字符。
&amp;gt; ​​TRAILING​​：仅移除字符串​​结尾​​的字符。
&amp;gt; ​​remstr​​：要移除的字符（或字符串）。如果省略，​​默认移除空格​​。
&amp;gt; ​​str​​：要处理的原始字符串。
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;1. 基本用法：移除首尾空格（最常见用途）&lt;/h5&gt;
&lt;p&gt;这是最常用的情况，因此几乎所有数据库都支持最简形式。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; SELECT TRIM【垂姆】(&apos;   Hello World   &apos;) AS TrimmedString;
+---------------+
| TrimmedString |
+---------------+
| Hello World   |
+---------------+
1 row in set (0.00 sec)
-- 结果: &apos;Hello World&apos; (首尾空格被移除，中间空格保留)

-- 等效于标准写法的默认行为
mysql&amp;gt; SELECT TRIM【垂姆】(BOTH &apos; &apos; FROM &apos;   Hello World   &apos;) AS TrimmedString;
+---------------+
| TrimmedString |
+---------------+
| Hello World   |
+---------------+
1 row in set (0.00 sec)
-- 结果: &apos;Hello World&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;2. 指定移除位置 (LEADING / TRAILING / BOTH)&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;-- 只移除开头的空格 (LTRIM 的功能)
mysql&amp;gt; SELECT TRIM【垂姆】(LEADING FROM &apos;   Hello World   &apos;) AS LeadingTrimmed;
+----------------+
| LeadingTrimmed |
+----------------+
| Hello World    |
+----------------+
1 row in set (0.00 sec)
-- 结果: &apos;Hello World   &apos;

-- 只移除结尾的空格 (RTRIM 的功能)
mysql&amp;gt; SELECT TRIM【垂姆】(TRAILING FROM &apos;   Hello World   &apos;) AS TrailingTrimmed;
+-----------------+
| TrailingTrimmed |
+-----------------+
|    Hello World  |
+-----------------+
1 row in set (0.00 sec)
-- 结果: &apos;   Hello World&apos;

-- 明确指定移除两端 (BOTH 是默认值，可省略)
mysql&amp;gt; SELECT TRIM【垂姆】(BOTH FROM &apos;   Hello World   &apos;) AS BothTrimmed;
+-------------+
| BothTrimmed |
+-------------+
| Hello World |
+-------------+
1 row in set (0.00 sec)
-- 结果: &apos;Hello World&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;3. 移除指定字符（不仅仅是空格）&lt;/h5&gt;
&lt;p&gt;这是一个非常强大的功能，可以移除任何指定的字符。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 移除首尾的 &apos;x&apos;
mysql&amp;gt; SELECT TRIM【垂姆】(&apos;x&apos; FROM &apos;xxHello Worldxx&apos;) AS TrimmedString;
+---------------+
| TrimmedString |
+---------------+
| Hello World   |
+---------------+
1 row in set (0.00 sec)
-- 结果: &apos;Hello World&apos;

-- 移除首尾的连字符 &apos;-&apos;
mysql&amp;gt; SELECT TRIM【垂姆】(&apos;-&apos; FROM &apos;--SQL-&apos;) AS TrimmedString;
+---------------+
| TrimmedString |
+---------------+
| SQL           |
+---------------+
1 row in set (0.00 sec)
-- 结果: &apos;SQL&apos;

-- 组合使用：只移除开头的 &apos;0&apos;
mysql&amp;gt; SELECT TRIM【垂姆】(LEADING &apos;0&apos; FROM &apos;0001234500&apos;) AS TrimmedString;
+---------------+
| TrimmedString |
+---------------+
| 1234500       |
+---------------+
1 row in set (0.00 sec)
-- 结果: &apos;1234500&apos; (开头的0被移除，结尾的0保留)

-- 组合使用：只移除结尾的逗号 &apos;,&apos;
mysql&amp;gt; SELECT TRIM【垂姆】(TRAILING &apos;,&apos; FROM &apos;value1,value2,value3,,,&apos;) AS TrimmedString;
+----------------------+
| TrimmedString        |
+----------------------+
| value1,value2,value3 |
+----------------------+
1 row in set (0.00 sec)
-- 结果: &apos;value1,value2,value3&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;4. 在查询中处理表字段数据（数据清洗）&lt;/h5&gt;
&lt;p&gt;假设有一个 &lt;code&gt;users&lt;/code&gt; 表，由于数据导入问题，&lt;code&gt;name&lt;/code&gt; 字段可能包含多余空格：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;id&lt;/th&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&apos;  John Doe  &apos;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&apos;Alice  &apos;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;-- 清理并显示姓名
mysql&amp;gt; SELECT id, name, TRIM【垂姆】(name) AS cleaned_name FROM users;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;结果：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;id&lt;/th&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;cleaned_name&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&apos;  John Doe  &apos;&lt;/td&gt;
&lt;td&gt;&apos;John Doe&apos;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&apos;Alice  &apos;&lt;/td&gt;
&lt;td&gt;&apos;Alice&apos;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;-- 在 WHERE 子句中使用，确保比较的准确性
mysql&amp;gt; SELECT * FROM products WHERE TRIM【垂姆】(product_code) = &apos;ABC123&apos;;
-- 即使数据库中存的是 &apos; ABC123 &apos; 也能匹配
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;总结与对比：TRIM【垂姆】 vs. LTRIM/RTRIM&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;&lt;code&gt;TRIM【垂姆】()&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;LTRIM()&lt;/code&gt; / &lt;code&gt;RTRIM()&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;可灵活移除&lt;strong&gt;首&lt;/strong&gt;、&lt;strong&gt;尾&lt;/strong&gt;或&lt;strong&gt;两端&lt;/strong&gt;的指定字符&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LTRIM()&lt;/code&gt; 只移除&lt;strong&gt;开头&lt;/strong&gt;的空格/字符&amp;lt;br&amp;gt;&lt;code&gt;RTRIM()&lt;/code&gt; 只移除&lt;strong&gt;结尾&lt;/strong&gt;的空格/字符&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;灵活性&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;高&lt;/strong&gt;。通过参数配置功能&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;低&lt;/strong&gt;。功能单一，每个函数只做一件事&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;符合标准&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;是 ANSI SQL 标准&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;不是标准，但被广泛实现&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;移除指定字符&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;支持&lt;/strong&gt;。可移除任意指定字符&lt;/td&gt;
&lt;td&gt;在多数数据库中&lt;strong&gt;仅支持空格&lt;/strong&gt;，或语法有所不同&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;推荐度&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;⭐️⭐️⭐️⭐️⭐️ (首选)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⭐️⭐️⭐️ (用于简单场景或兼容旧代码)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h5&gt;&lt;code&gt;TRIM【垂姆】()&lt;/code&gt; 与 &lt;code&gt;LTRIM()&lt;/code&gt;/&lt;code&gt;RTRIM()&lt;/code&gt; 的等效操作&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;-- 移除开头空格：
mysql&amp;gt; TRIM【垂姆】(LEADING FROM &apos;  abc  &apos;) -- 结果: &apos;abc  &apos;
mysql&amp;gt; LTRIM(&apos;  abc  &apos;)             -- 结果: &apos;abc  &apos;

-- 移除结尾空格：
mysql&amp;gt; TRIM【垂姆】(TRAILING FROM &apos;  abc  &apos;) -- 结果: &apos;  abc&apos;
mysql&amp;gt; RTRIM(&apos;  abc  &apos;)              -- 结果: &apos;  abc&apos;

-- 移除两端空格：
mysql&amp;gt; TRIM【垂姆】(&apos;  abc  &apos;)               -- 结果: &apos;abc&apos;
-- 等效组合：
mysql&amp;gt; LTRIM(RTRIM(&apos;  abc  &apos;))       -- 结果: &apos;abc&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;不同数据库的注意事项&lt;/h5&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;数据库&lt;/th&gt;
&lt;th&gt;&lt;code&gt;TRIM【垂姆】()&lt;/code&gt; 支持程度&lt;/th&gt;
&lt;th&gt;备注&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MySQL, MariaDB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;完全支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;支持标准语法和简化语法&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;完全支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;支持标准语法和简化语法&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SQL Server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;支持 (2017及以上版本)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2017版本之前需使用 &lt;code&gt;LTRIM(RTRIM())&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Oracle&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;完全支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;支持标准语法和简化语法&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SQLite&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;支持简化语法 &lt;code&gt;TRIM【垂姆】(string【斯jǘn】)&lt;/code&gt;，但从3.38版本开始支持标准语法&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;核心结论与最佳实践&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;功能核心&lt;/strong&gt;：&lt;code&gt;TRIM【垂姆】()&lt;/code&gt; 用于&lt;strong&gt;清理字符串边界&lt;/strong&gt;的无关字符，最常用于移除空格。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;现代首选&lt;/strong&gt;：&lt;strong&gt;对于新的项目，应优先使用功能更强大、更符合标准的 &lt;code&gt;TRIM【垂姆】()&lt;/code&gt; 函数&lt;/strong&gt;，而不是 &lt;code&gt;LTRIM()&lt;/code&gt; 和 &lt;code&gt;RTRIM()&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据清洗&lt;/strong&gt;：在数据导入、数据验证和查询比较前，使用 &lt;code&gt;TRIM【垂姆】()&lt;/code&gt; 清理用户输入或外部数据至关重要，可以避免因首尾空格导致的匹配失败。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;灵活运用&lt;/strong&gt;：记住它可以移除&lt;strong&gt;任何指定字符&lt;/strong&gt;（如 &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, &lt;code&gt;,&lt;/code&gt;），而不仅仅是空格，这在处理固定格式的代码、数字字符串时非常有用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;兼容性&lt;/strong&gt;：虽然是最新标准，但已在主流数据库的最新版本中得到良好支持。对于旧版SQL Server等环境，需回退到 &lt;code&gt;LTRIM(RTRIM())&lt;/code&gt; 组合。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;--TRIM【垂姆】(s)            返回字符串s删除了两边空格之后的字符串
mysql&amp;gt; select【涩莱克特】 trim【垂姆】(&quot;  ABC  &quot;);
+-----------------+
| trim【垂姆】(&quot;  ABC  &quot;) |
+-----------------+
| ABC             |
+-----------------+
1 row in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、日期函数&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[常用函数]
        direction LR
        A[字符串函数] --&amp;gt; B[日期函数] --&amp;gt; C[聚集函数] --&amp;gt; D[数学计算] --&amp;gt; E[if函数] --&amp;gt; F[case函数]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class B highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;获取系统或指定日期与时间&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;curtime【科泰姆】()&lt;/td&gt;
&lt;td&gt;获取时间&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;curdate【科dei 特】()&lt;/td&gt;
&lt;td&gt;获取日期&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;now【闹】()&lt;/td&gt;
&lt;td&gt;获取日期和时间&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;year【耶尔】()&lt;/td&gt;
&lt;td&gt;获取年&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;month【mèn斯】()&lt;/td&gt;
&lt;td&gt;获取月&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;day【dèi】()&lt;/td&gt;
&lt;td&gt;获取日&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;week【wèi kē】()&lt;/td&gt;
&lt;td&gt;获取一年中的第几周&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;date【dei 特】()&lt;/td&gt;
&lt;td&gt;获取日期&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;weekday【wèi kē dèi】()&lt;/td&gt;
&lt;td&gt;获取一周中的周几&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;time【泰姆】()&lt;/td&gt;
&lt;td&gt;获取时间&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;hour【ào é】()&lt;/td&gt;
&lt;td&gt;获取小时&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;minute【密 ní 特】 ()&lt;/td&gt;
&lt;td&gt;获取分钟&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;second【塞耿特】()&lt;/td&gt;
&lt;td&gt;获取秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;quarter【扩特】()&lt;/td&gt;
&lt;td&gt;获取一年中第几季度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;monthname【mòn斯-内姆】()&lt;/td&gt;
&lt;td&gt;获取月份名称&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dayname【dei 内姆】()&lt;/td&gt;
&lt;td&gt;获取日期对应的星期名&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dayofyear【dèi诶 符 耶尔】()&lt;/td&gt;
&lt;td&gt;获取一年中第几天&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dayofmonth【dèi诶 符 mèn斯】()&lt;/td&gt;
&lt;td&gt;获取一月中第几天&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; select【涩莱克特】 curtime【科泰姆】(); //获取系统时间
+-----------+
| curtime【科泰姆】() |
+-----------+
| 17:42:20  |
+-----------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 curdate【科dei 特】();//获取系统日期
+------------+
| curdate【科dei 特】()  |
+------------+
| 2023-05-24 |
+------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 now【闹】() ;//获取系统日期+时间
+---------------------+
| now【闹】()               |
+---------------------+
| 2023-05-24 17:42:29 |
+---------------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 year【耶尔】(now【闹】()) ; //获取系统当前年
+-------------+
| year【耶尔】(now【闹】()) |
+-------------+
|        2023 |
+-------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 month【mèn斯】(now【闹】()) ; //获取系统当前月
+--------------+
| month【mèn斯】(now【闹】()) |
+--------------+
|            5 |
+--------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 day【dèi】(now【闹】()) ; //获取系统当前日
+------------+
| day【dèi】(now【闹】()) |
+------------+
|         24 |
+------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 hour【ào é】(now【闹】()) ; //获取系统当前小时
+-------------+
| hour【ào é】(now【闹】()) |
+-------------+
|          17 |
+-------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 minute【密 ní 特】 (now【闹】()) ; //获取系统当分钟
+---------------+
| minute【密 ní 特】 (now【闹】()) |
+---------------+
|            46 |
+---------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 second【塞耿特】(now【闹】()) ; //获取系统当前秒
+---------------+
| second【塞耿特】(now【闹】()) |
+---------------+
|            34 |
+---------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 time【泰姆】(now【闹】()) ;//获取当前系统时间
+-------------+
| time【泰姆】(now【闹】()) |
+-------------+
| 17:47:36    |
+-------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 date【dei 特】(now【闹】()) ; //获取当前系统日期
+-------------+
| date【dei 特】(now【闹】()) |
+-------------+
| 2023-05-24  |
+-------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 curdate【科dei 特】();//获取当前系统日志
+------------+
| curdate【科dei 特】()  |
+------------+
| 2023-05-24 |
+------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 dayofmonth【dèi诶 符 mèn斯】(curdate【科dei 特】());//获取一个月的第几天
+-----------------------+
| dayofmonth【dèi诶 符 mèn斯】(curdate【科dei 特】()) |
+-----------------------+
|                    24 |
+-----------------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 dayofyear【dèi诶 符 耶尔】(curdate【科dei 特】());//获取一年中的第几天
+----------------------+
| dayofyear【dèi诶 符 耶尔】(curdate【科dei 特】()) |
+----------------------+
|                  144 |
+----------------------+
1 row in set (0.00 sec)

mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】 monthname【mòn斯-内姆】(curdate【科dei 特】());//获取月份名
+----------------------+
| monthname【mòn斯-内姆】(curdate【科dei 特】()) |
+----------------------+
| May                  |
+----------------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 dayname【dei 内姆】(curdate【科dei 特】());//获取星期名
+--------------------+
| dayname【dei 内姆】(curdate【科dei 特】()) |
+--------------------+
| Wednesday          |
+--------------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 quarter【扩特】(curdate【科dei 特】());//获取一年中的第几季度
+--------------------+
| quarter【扩特】(curdate【科dei 特】()) |
+--------------------+
|                  2 |
+--------------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 week【wèi kē】(now【闹】());//一年中的第几周
+-------------+
| week【wèi kē】(now【闹】()) |
+-------------+
|          21 |
+-------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 weekday【wèi kē dèi】(now【闹】())；//一周中的周几 
+----------------+
| weekday【wèi kē dèi】(now【闹】()) |
+----------------+
|              2 |
+----------------+
1 row in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、聚集函数&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[常用函数]
        direction LR
        A[字符串函数] --&amp;gt; B[日期函数] --&amp;gt; C[聚集函数] --&amp;gt; D[数学计算] --&amp;gt; E[if函数] --&amp;gt; F[case函数]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class C highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;对数值类型表头下的数据做统计&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;p&gt;输出3号员工2018每个月的基本工资&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; select【涩莱克特】 basic【贝斯克】 from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】 employee【ing普洛伊】_id=3 and year【耶尔】(date【dei 特】)=2018;
+-------+
| basic【贝斯克】 |
+-------+
|  9261 |
|  9261 |
|  9261 |
|  9261 |
|  9261 |
|  9261 |
|  9261 |
|  9261 |
|  9261 |
|  9261 |
|  9261 |
|  9724 |
+-------+
12 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;sum(表头名) 求和&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 sum(basic【贝斯克】) from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】 employee【ing普洛伊】_id=3 and year【耶尔】(date【dei 特】)=2018;
+------------+
| sum(basic【贝斯克】) |
+------------+
|     111595 |
+------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;avg(表头名) 计算平均值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 avg(basic【贝斯克】) from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】 employee【ing普洛伊】_id=3 and year【耶尔】(date【dei 特】)=2018;
+------------+
| avg(basic【贝斯克】) |
+------------+
|  9299.5833 |
+------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;min(表头名) 获取最小值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 min(basic【贝斯克】) from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】 employee【ing普洛伊】_id=3 and year【耶尔】(date【dei 特】)=2018;
+------------+
| min(basic【贝斯克】) |
+------------+
|       9261 |
+------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;max(表头名) 获取最大值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 max(basic【贝斯克】) from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】 employee【ing普洛伊】_id=3 and year【耶尔】(date【dei 特】)=2018;
+------------+
| max(basic【贝斯克】) |
+------------+
|       9724 |
+------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;count【康特】(表头名) 统计表头值个数&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//输出3号员工2018年奖金小于3000的奖金
mysql&amp;gt; select【涩莱克特】 bonus【波诺斯】 from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】 employee【ing普洛伊】_id=3 and year【耶尔】(date【dei 特】)=2018 and bonus【波诺斯】&amp;lt;3000; 
+-------+
| bonus【波诺斯】 |
+-------+
|  1000 |
|  1000 |
|  1000 |
+-------+
3 rows in set (0.00 sec)
//统计3号员工2018年奖金小于3000的次数
mysql&amp;gt; select【涩莱克特】 count【康特】(bonus【波诺斯】) from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】 employee【ing普洛伊】_id=3 and year【耶尔】(date【dei 特】)=2018 and bonus【波诺斯】&amp;lt;3000;  
+--------------+
| count【康特】(bonus【波诺斯】) |
+--------------+
|            3 |
+--------------+
1 row in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、数学计算&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[常用函数]
        direction LR
        A[字符串函数] --&amp;gt; B[日期函数] --&amp;gt; C[聚集函数] --&amp;gt; D[数学计算] --&amp;gt; E[if函数] --&amp;gt; F[case函数]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class D highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;对行中的列做计算&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;符号&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;th&gt;例子&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;+&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;加法&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uid + gid&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;减法&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uid - gid&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;乘法&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uid * gid&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;除法&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uid / gid&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;%&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;取余数（求模）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uid % gid&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;提高优先级&lt;/td&gt;
&lt;td&gt;&lt;code&gt;(uid + gid) / 2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;p&gt;输出8号员工2019年1月10 工资总和&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 employee【ing普洛伊】_id,date【dei 特】,basic【贝斯克】 +  bonus【波诺斯】  as 总工资 from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】employee【ing普洛伊】_id = 8 and date【dei 特】=20190110;
+-------------------------+------------+-----------------+
| employee【ing普洛伊】_id | date【dei 特】       |     总工资       |
+-------------------------+------------+-----------------+
|           8             | 2019-01-10 |          24093  |
+-------------------------+------------+-----------------+
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出8号员工的名字和年龄&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 name, 当前年份 - year【耶尔】(birth_date【dei 特】) as 年龄 from【弗乱】 moershi.employees【ing普洛伊s】  where【威尔】employee【ing普洛伊】_id = 8 ;

-- mysql&amp;gt; select name, year【耶尔】(now【闹】()) - year【耶尔】(birth_date【dei 特】) as 年龄 from moershi.employees where employee_id=8;
-- year【耶尔】(now【闹】())  获取当前年份
+--------+--------+
| name   | 年龄   |
+--------+--------+
| 汪云   |     29 |
+--------+--------+
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看8号员工2019年1月10 基本工资翻3倍的 值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 employee【ing普洛伊】_id , basic【贝斯克】 , basic【贝斯克】 * 3  as 工资翻三倍  from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】 employee【ing普洛伊】_id=8  and date【dei 特】=20190110;

-- mysql&amp;gt; select employee_id,basic,basic * 3 as 工资翻三倍 from moershi.salary where employee_id=8 and date=20190110;
+-------------+-------+-----------------+
| employee【ing普洛伊】_id | basic【贝斯克】 | 工资翻三倍      |
+-------------+-------+-----------------+
|           8 | 23093 |           69279 |
+-------------+-------+-----------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看8号员工2019年1月10的平均工资&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 employee【ing普洛伊】_id ,  (basic【贝斯克】+bonus【波诺斯】)/2 as 平均工资  from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】  employee【ing普洛伊】_id=8  and date【dei 特】=20190110 ;

--mysql&amp;gt; select employee_id,(basic + bonus)/2 as 平均工资 from moershi.salary where employee_id=8 and date=20190110;
+-------------+--------------+
| employee【ing普洛伊】_id | 平均工资     |
+-------------+--------------+
|           8 |   12046.5000 |
+-------------+--------------+
1 row in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出员工编号1-10之间偶数员工编号及对应的员工名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 employee【ing普洛伊】_id , name  from【弗乱】  moershi.employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id  between【B豚ing】 1 and 10  and  employee【ing普洛伊】_id % 2  =  0   ;

-- mysql&amp;gt; select employee_id,name from moershi.employees where employee_id between 1 and 10 and employee_id % 2 = 0;
+-------------+-----------+
| employee【ing普洛伊】_id | name      |
+-------------+-----------+
|           2 | 郭岩      |
|           4 | 张健      |
|           6 | 牛建军    |
|           8 | 汪云      |
|          10 | 郭娟      |
+-------------+-----------+
5 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;七、if函数&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[常用函数]
        direction LR
        A[字符串函数] --&amp;gt; B[日期函数] --&amp;gt; C[聚集函数] --&amp;gt; D[数学计算] --&amp;gt; E[if函数] --&amp;gt; F[case函数]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class E highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;if(条件,v1,v2) 如果条件是TRUE则返回v1，否则返回v2&lt;/p&gt;
&lt;p&gt;ifnull(v1,v2) 如果v1不为NULL，则返回v1，否则返回v2&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;IF 函数&lt;/th&gt;
&lt;th&gt;IFNULL 函数&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;主要用途&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;通用的条件判断，根据条件真假返回不同值&lt;/td&gt;
&lt;td&gt;专门处理 &lt;code&gt;NULL&lt;/code&gt; 值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;参数数量&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;三个：&lt;code&gt;IF(条件, 值_if_true, 值_if_false)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;两个：&lt;code&gt;IFNULL(表达式, 替换值)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;核心逻辑&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;条件为真（非0且非NULL）返回第二个参数，否则返回第三个参数&lt;/td&gt;
&lt;td&gt;表达式不为&lt;code&gt;NULL&lt;/code&gt;时返回其自身，否则返回替换值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;适用场景&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;两种可能性的选择，如分类、状态转换&lt;/td&gt;
&lt;td&gt;字段可能为&lt;code&gt;NULL&lt;/code&gt;时提供默认值，防止计算错误&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;💡 认识 &lt;code&gt;IF&lt;/code&gt; 函数&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;IF&lt;/code&gt; 函数就像一个简单的“如果...那么...否则...”判断器。它的基本语法是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IF(condition, value_if_true, value_if_false)
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;condition&lt;/strong&gt;：要判断的条件表达式。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;value_if_true&lt;/strong&gt;：当条件为真（TRUE，即非0且非NULL）时返回的值。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;value_if_false&lt;/strong&gt;：当条件为假（FALSE 或 NULL）时返回的值。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;使用示例&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 根据年龄判断是否成年
SELECT name, IF(age &amp;gt;= 18, &apos;成年&apos;, &apos;未成年&apos;) AS age_group FROM users;

-- 在商品查询中显示折扣信息
SELECT product_name, price, IF(price &amp;gt; 100, &apos;高价商品&apos;, &apos;普通商品&apos;) AS price_category FROM products;

-- 注意：直接判断浮点数时，MySQL会尝试将其转为整数，这可能不是你想要的结果
SELECT IF(0.1, 1, 0); -- 返回 0，因为0.1被转为整数0后判断为假
SELECT IF(0.1 &amp;lt;&amp;gt; 0, 1, 0); -- 返回 1，这是正确的比较方式
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;演示if（） 语句的执行过程&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】  if(1 = 2 , &quot;a&quot;,&quot;b&quot;);
+---------------------+
| if(1 = 2 , &quot;a&quot;,&quot;b&quot;) |
+---------------------+
| b                   |
+---------------------+
1 row in set (0.00 sec)
mysql&amp;gt; select【涩莱克特】  if( 1 = 1 , &quot;a&quot;,&quot;b&quot;);
+---------------------+
| if(1 = 1 , &quot;a&quot;,&quot;b&quot;) |
+---------------------+
| a                   |
+---------------------+
1 row in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;🔄 掌握 &lt;code&gt;IFNULL&lt;/code&gt; 函数&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;IFNULL&lt;/code&gt; 函数专为处理可能为 &lt;code&gt;NULL&lt;/code&gt; 的值而设计，提供回退方案。它的语法更简洁：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IFNULL(expression, replacement_value)
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;expression&lt;/strong&gt;：要检查的表达式或字段。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;replacement_value&lt;/strong&gt;：如果 &lt;code&gt;expression&lt;/code&gt; 为 &lt;code&gt;NULL&lt;/code&gt;，则返回此值。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;使用示例&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 为用户表中邮箱为空的记录提供默认显示
SELECT username, IFNULL(email, &apos;未提供邮箱&apos;) AS user_email FROM users;

-- 在计算中避免NULL值导致整体结果为NULL
SELECT product, price, discount, price * IFNULL(discount, 1) AS final_price FROM sales;

-- IFNULL返回值的数据类型取决于上下文
SELECT IFNULL(1, &apos;test&apos;); -- 在临时表中，test列的类型可能是CHAR(4)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;演示ifnull（） 语句的执行过程&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; mysql&amp;gt; select【涩莱克特】  ifnull(&quot;abc&quot;,&quot;xxx&quot;);
+---------------------+
| ifnull(&quot;abc&quot;,&quot;xxx&quot;) |
+---------------------+
| abc                 |
+---------------------+
1 row in set (0.00 sec)
mysql&amp;gt; select【涩莱克特】  ifnull(null,&quot;xxx&quot;);
+--------------------+
| ifnull(null,&quot;xxx&quot;) |
+--------------------+
| xxx                |
+--------------------+
1 row in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查询例子&lt;/p&gt;
&lt;p&gt;根据uid 号 输出用户类型&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 name,uid,if(uid &amp;lt; 1000 , &quot;系统用户&quot;,&quot;创建用户&quot;) as 用户类型  from【弗乱】 moershi.user;
+-----------------+-------+--------------+
| name            | uid   | 用户类型     |
+-----------------+-------+--------------+
| root            |     0 | 系统用户     |
| bin             |     1 | 系统用户     |
| daemon          |     2 | 系统用户     |
| adm             |     3 | 系统用户     |
| lp              |     4 | 系统用户     |
| sync            |     5 | 系统用户     |
| shutdown        |     6 | 系统用户     |
| halt            |     7 | 系统用户     |
| mail            |     8 | 系统用户     |
| operator        |    11 | 系统用户     |
| games           |    12 | 系统用户     |
| ftp             |    14 | 系统用户     |
| nobody          |    99 | 系统用户     |
| systemd-network |   192 | 系统用户     |
| dbus            |    81 | 系统用户     |
| polkitd         |   999 | 系统用户     |
| sshd            |    74 | 系统用户     |
| postfix         |    89 | 系统用户     |
| chrony          |   998 | 系统用户     |
| rpc             |    32 | 系统用户     |
| rpcuser         |    29 | 系统用户     |
| nfsnobody       | 65534 | 创建用户     |
| haproxy         |   188 | 系统用户     |
| plj             |  1000 | 创建用户     |
| apache          |    48 | 系统用户     |
| mysql           |    27 | 系统用户     |
| bob             |  NULL | 创建用户     |
+-----------------+-------+--------------+
27 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;根据shell 输出用户类型&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt;  select【涩莱克特】 name , shell  , if(shell = &quot;/bin/bash&quot; , &quot;交互用户&quot;,&quot;非交户用户&quot;) as 用户类型 from【弗乱】 moershi.user;
+-----------------+----------------+-----------------+
| name            | shell          | 用户类型        |
+-----------------+----------------+-----------------+
| root            | /bin/bash      | 交互用户        |
| bin             | /sbin/nologin  | 非交户用户      |
| daemon          | /sbin/nologin  | 非交户用户      |
| adm             | /sbin/nologin  | 非交户用户      |
| lp              | /sbin/nologin  | 非交户用户      |
| sync            | /bin/sync      | 非交户用户      |
| shutdown        | /sbin/shutdown | 非交户用户      |
| halt            | /sbin/halt     | 非交户用户      |
| mail            | /sbin/nologin  | 非交户用户      |
| operator        | /sbin/nologin  | 非交户用户      |
| games           | /sbin/nologin  | 非交户用户      |
| ftp             | /sbin/nologin  | 非交户用户      |
| nobody          | /sbin/nologin  | 非交户用户      |
| systemd-network | /sbin/nologin  | 非交户用户      |
| dbus            | /sbin/nologin  | 非交户用户      |
| polkitd         | /sbin/nologin  | 非交户用户      |
| sshd            | /sbin/nologin  | 非交户用户      |
| postfix         | /sbin/nologin  | 非交户用户      |
| chrony          | /sbin/nologin  | 非交户用户      |
| rpc             | /sbin/nologin  | 非交户用户      |
| rpcuser         | /sbin/nologin  | 非交户用户      |
| nfsnobody       | /sbin/nologin  | 非交户用户      |
| haproxy         | /sbin/nologin  | 非交户用户      |
| plj             | /bin/bash      | 交互用户        |
| apache          | /sbin/nologin  | 非交户用户      |
| mysql           | /bin/false     | 非交户用户      |
| bob             | NULL           | 非交户用户      |
+-----------------+----------------+-----------------+
27 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;插入没有家目录的用户&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; insert【因涩特】   into   moershi.user (name, homedir) values【挖柳斯】 (&quot;jerrya&quot;,null);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看时加判断&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt;  select【涩莱克特】 name  姓名, ifnull(homedir,&quot;NO  home&quot;)as 家目录  from【弗乱】  moershi.user;
+-----------------+--------------------+
| 姓名            | 家目录             |
+-----------------+--------------------+
| root            | /root              |
| bin             | /bin               |
| daemon          | /sbin              |
| adm             | /var/adm           |
| lp              | /var/spool/lpd     |
| sync            | /sbin              |
| shutdown        | /sbin              |
| halt            | /sbin              |
| mail            | /var/spool/mail    |
| operator        | /root              |
| games           | /usr/games         |
| ftp             | /var/ftp           |
| nobody          | /                  |
| systemd-network | /                  |
| dbus            | /                  |
| polkitd         | /                  |
| sshd            | /var/empty/sshd    |
| postfix         | /var/spool/postfix |
| chrony          | /var/lib/chrony    |
| rpc             | /var/lib/rpcbind   |
| rpcuser         | /var/lib/nfs       |
| nfsnobody       | /var/lib/nfs       |
| haproxy         | /var/lib/haproxy   |
| plj             | /home/plj          |
| apache          | /usr/share/httpd   |
| mysql           | /var/lib/mysql     |
| bob             | NO  home           |
| jerrya          | NO  home           |
+-----------------+--------------------+
28 rows in set (0.00 sec)
Mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;八、case【kèi 斯】函数&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[常用函数]
        direction LR
        A[字符串函数] --&amp;gt; B[日期函数] --&amp;gt; C[聚集函数] --&amp;gt; D[数学计算] --&amp;gt; E[if函数] --&amp;gt; F[case函数]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class F highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;命令格式&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CASE 表头名              
WHEN【问】 值1 then【diān~】 输出结果 
WHEN【问】 值2 then【diān~】 输出结果  
WHEN【问】 值3 then【diān~】 输出结果 
ELSE 输出结果  
END
或
CASE              
WHEN【问】  判断条件1 then【diān~】 输出结果 
WHEN【问】  判断条件2 then【diān~】 输出结果  
WHEN【问】  判断条件3 then【diān~】 输出结果 
ELSE  输出结果  
END
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;步骤&lt;/th&gt;
&lt;th&gt;简单 CASE：精确匹配器 (&lt;code&gt;CASE 表头名 WHEN【问】 ...&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;搜索 CASE：条件扫描仪 (&lt;code&gt;CASE WHEN ...&lt;/code&gt;)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;取出当前行中 &lt;code&gt;表头名&lt;/code&gt; 字段的值。&lt;/td&gt;
&lt;td&gt;评估 &lt;strong&gt;第一个&lt;/strong&gt; &lt;code&gt;WHEN【问】&lt;/code&gt; 后的&lt;strong&gt;判断条件1&lt;/strong&gt; (如 &lt;code&gt;salary &amp;gt; 5000&lt;/code&gt;) 是真还是假。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;将这个值&lt;strong&gt;按顺序&lt;/strong&gt;与 &lt;code&gt;WHEN【问】&lt;/code&gt; 后的值（值1、值2...）进行&lt;strong&gt;相等比较&lt;/strong&gt;。&lt;/td&gt;
&lt;td&gt;如果 &lt;strong&gt;判断条件1&lt;/strong&gt; 为 &lt;strong&gt;TRUE&lt;/strong&gt;，则立刻返回 &lt;strong&gt;结果1&lt;/strong&gt;，&lt;strong&gt;过程结束&lt;/strong&gt;，后续条件被忽略。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一旦遇到一个&lt;strong&gt;相等的值&lt;/strong&gt;（如 &lt;code&gt;值2&lt;/code&gt;），则立刻返回其对应的 &lt;code&gt;then【diān~】&lt;/code&gt; &lt;strong&gt;结果2&lt;/strong&gt;，&lt;strong&gt;过程结束&lt;/strong&gt;。&lt;/td&gt;
&lt;td&gt;如果为 &lt;strong&gt;FALSE&lt;/strong&gt;，则继续评估&lt;strong&gt;下一个&lt;/strong&gt;条件 (&lt;strong&gt;判断条件2&lt;/strong&gt;)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;如果所有 &lt;code&gt;WHEN【问】&lt;/code&gt; 值都不匹配，则最终返回 &lt;code&gt;ELSE&lt;/code&gt; 部分的输出结果。&lt;/td&gt;
&lt;td&gt;后续条件依此类推，直到找到一个为 TRUE 的条件。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;如果没有 &lt;code&gt;ELSE&lt;/code&gt; 部分且无匹配项，则返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/td&gt;
&lt;td&gt;如果所有条件都为 FALSE，则返回 &lt;code&gt;ELSE&lt;/code&gt; 部分的结果；若无 &lt;code&gt;ELSE&lt;/code&gt; 则返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;如果表头名等于某个值，则返回对应位置then【diān~】后面的值并结束判断，&lt;/p&gt;
&lt;p&gt;如果与所有值都不相等，则返回else后面的结果并结束判断&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;p&gt;查看部门表(departments)所有行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】  * from【弗乱】 moershi.departments;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|       1 | 人事部    |
|       2 | 财务部    |
|       3 | 运维部    |
|       4 | 开发部    |
|       5 | 测试部    |
|       6 | 市场部    |
|       7 | 销售部    |
|       8 | 法务部    |
+---------+-----------+
8 rows in set (0.03 sec)

//输出部门类型
select dept_id, dept_name,
case dept_name
when【问】 &apos;运维部&apos; then【diān~】 &apos;技术部门&apos;
when【问】 &apos;开发部&apos; then【diān~】 &apos;技术部门&apos;
when【问】 &apos;测试部&apos; then【diān~】 &apos;技术部门&apos;
else &apos;非技术部门&apos;
end as  部门类型   from【弗乱】  moershi.departments;
+---------+-----------+-----------------+
| dept_id | dept_name | 部门类型        |
+---------+-----------+-----------------+
|       1 | 人事部    | 非技术部门      |
|       2 | 财务部    | 非技术部门      |
|       3 | 运维部    | 技术部门        |
|       4 | 开发部    | 技术部门        |
|       5 | 测试部    | 技术部门        |
|       6 | 市场部    | 非技术部门      |
|       7 | 销售部    | 非技术部门      |
|       8 | 法务部    | 非技术部门      |
+---------+-----------+-----------------+
8 rows in set (0.00 sec)

或
mysql&amp;gt; select【涩莱克特】 dept_id,dept_name,
    -&amp;gt; case
    -&amp;gt; when【问】 dept_name=&quot;运维部&quot;  then【diān~】 &quot;技术部&quot;
    -&amp;gt; when【问】 dept_name=&quot;开发部&quot;  then【diān~】 &quot;技术部&quot;
    -&amp;gt; when【问】 dept_name=&quot;测试部&quot;  then【diān~】 &quot;技术部&quot;
    -&amp;gt; else &quot;非技术部&quot;
    -&amp;gt; end as 部门类型  from【弗乱】  moershi.departments;
+---------+-----------+--------------+
| dept_id | dept_name | 部门类型     |
+---------+-----------+--------------+
|       1 | 人事部    | 非技术部     |
|       2 | 财务部    | 非技术部     |
|       3 | 运维部    | 技术部       |
|       4 | 开发部    | 技术部       |
|       5 | 测试部    | 技术部       |
|       6 | 市场部    | 非技术部     |
|       7 | 销售部    | 非技术部     |
|       8 | 法务部    | 非技术部     |
+---------+-----------+--------------+
8 rows in set (0.00 sec)
或
mysql&amp;gt; select【涩莱克特】 dept_id,dept_name,
    -&amp;gt; case
    -&amp;gt; when【问】 dept_name in (&quot;运维部&quot;,&quot;开发部&quot;,&quot;测试部&quot;) then【diān~】 &quot;技术部&quot;
    -&amp;gt; else &quot;非技术部&quot;
    -&amp;gt; end as 部门类型  from【弗乱】  moershi.departments;
+---------+-----------+--------------+
| dept_id | dept_name | 部门类型     |
+---------+-----------+--------------+
|       1 | 人事部    | 非技术部     |
|       2 | 财务部    | 非技术部     |
|       3 | 运维部    | 技术部       |
|       4 | 开发部    | 技术部       |
|       5 | 测试部    | 技术部       |
|       6 | 市场部    | 非技术部     |
|       7 | 销售部    | 非技术部     |
|       8 | 法务部    | 非技术部     |
+---------+-----------+--------------+
8 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;九、作业&lt;/h2&gt;
&lt;h3&gt;1.选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;要从 &lt;code&gt;employees&lt;/code&gt; 表的 &lt;code&gt;email&lt;/code&gt; 列中提取出 &lt;code&gt;@&lt;/code&gt; 后面的域名部分，应使用以下哪个函数？ B
A. &lt;code&gt;SUBSTRING&lt;/code&gt;
B. &lt;code&gt;SUBSTRING_INDEX&lt;/code&gt;
C. &lt;code&gt;LEFT&lt;/code&gt;
D. &lt;code&gt;RIGHT&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;**要从 `employees` 表的 `email` 列中提取出 `@` 后面的域名部分，应使用以下哪个函数？**
    *   **答案：B **
    *   **讲解**：`SUBSTRING_INDEX` 函数是完成这个任务最简洁高效的选择。它的语法是 `SUBSTRING_INDEX(str, delimiter, count)`。当 `count` 为负数时，表示从字符串右边开始查找分隔符，并返回分隔符**之后**的所有内容。因此，使用 `SUBSTRING_INDEX(email, &apos;@&apos;, -1)` 可以直接提取出域名部分，例如从 `&quot;alice@example.com&quot;` 中提取出 `&quot;example.com&quot;`。其他函数如 `SUBSTRING` 需要结合 `LOCATE` 先找到 `@` 的位置，更为繁琐。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;已知 &lt;code&gt;employees&lt;/code&gt; 表的 &lt;code&gt;hire_date&lt;/code&gt; 列是日期类型，要计算每个员工入职到当前日期的天数，应使用的函数是？
A. &lt;code&gt;TIMESTAMPDIFF(DAY【dèi】, hire_date, CURDATE【科dei 特】())&lt;/code&gt;
B. &lt;code&gt;TIMESTAMPDIFF(MONTH【mèn斯】, hire_date, CURDATE【科dei 特】())&lt;/code&gt;
C. &lt;code&gt;TIMESTAMPDIFF(YEAR【耶尔】, hire_date, CURDATE【科dei 特】())&lt;/code&gt;
D. &lt;code&gt;DATEDIFF(CURDATE【科dei 特】(), hire_date)&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt; **已知 `employees` 表的 `hire_date` 列是日期类型，要计算每个员工入职到当前日期的天数，应使用的函数是？**
    *   **答案：D**
    *   **讲解**：计算两个日期的天数差，最直接和常用的函数是 `DATEDIFF(end_date, start_date)`。它返回两个日期之间相差的天数。因此，`DATEDIFF(CURDATE【科dei 特】(), hire_date)` 可以准确计算出从入职日到今天的天数。选项A的 `TIMESTAMPDIFF` 函数也能实现，但它通常用于计算年、月等更大单位的差值，对于计算天数，`DATEDIFF` 是更常规和简洁的选择。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;在统计每个部门的员工数量时，应使用的聚集函数是？ C
A. &lt;code&gt;SUM&lt;/code&gt;
B. &lt;code&gt;AVG&lt;/code&gt;
C. &lt;code&gt;COUNT&lt;/code&gt;
D. &lt;code&gt;MAX&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;**在统计每个部门的员工数量时，应使用的聚集函数是？**
    *   **答案：C **
    *   **讲解**：`COUNT` 是SQL中专门用于**统计行数**的聚合函数。在配合 `GROUP BY department` 使用时，`COUNT(*)` 会返回每个分组（即每个部门）中包含的数据行数，也就是员工数量。`SUM` 用于对数值列求和，`AVG` 用于求平均值，`MAX` 用于找最大值，都不适用于计数场景。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;在 &lt;code&gt;salary&lt;/code&gt; 表中，要计算每个员工的总薪资（基本工资 &lt;code&gt;basic&lt;/code&gt; 加上奖金 &lt;code&gt;bonus&lt;/code&gt;），以下表达式正确的是？ B
A. &lt;code&gt;basic + bonus&lt;/code&gt;
B. &lt;code&gt;SUM(basic, bonus)&lt;/code&gt;
C. &lt;code&gt;AVG(basic + bonus)&lt;/code&gt;
D. &lt;code&gt;MAX(basic, bonus)&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;**在 `salary` 表中，要计算每个员工的总薪资（基本工资 `basic` 加上奖金 `bonus`），以下表达式正确的是？**
    *   **答案：A**
    *   **讲解**：这里的关键是区分**行内计算**与**多行聚合**。计算单个员工的“基本工资+奖金”属于行内计算，只需要使用基本的算术运算符 `+` 即可，即 `basic + bonus`。而 `SUM` 是一个聚合函数，它的作用是对**一组行**的某个字段值进行求和，例如计算整个部门的工资总和，不能用于对同一行内的不同列进行计算。`SUM(basic, bonus)` 的写法在MySQL中本身就是错误的，因为 `SUM` 函数只能接受一个参数。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;在 &lt;code&gt;employees&lt;/code&gt; 表中，若要根据员工的入职日期判断，如果入职日期在 2025 年 1 月 1 日之后，标记为 “新员工”，否则标记为 “老员工”，可以使用以下哪个函数实现？ A
A. &lt;code&gt;IF(hire_date &amp;gt; &apos;2025-01-01&apos;, &apos;新员工&apos;, &apos;老员工&apos;)&lt;/code&gt;
B. &lt;code&gt;CASE WHEN hire_date &amp;gt; &apos;2025-01-01&apos; THEN &apos;新员工&apos; ELSE &apos;老员工&apos; END&lt;/code&gt;
C. 以上两种都可以
D. 以上两种都不可以&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;**在 `employees` 表中，若要根据员工的入职日期判断，如果入职日期在 2025 年 1 月 1 日之后，标记为 “新员工”，否则标记为 “老员工”，可以使用以下哪个函数实现？**
    *   **答案：C**
    *   **讲解**：MySQL 提供了两种实现条件逻辑的主要方式。`IF` 函数适合处理简单的“如果...就...否则...”的双分支判断，语法简洁，本题中的 `IF(hire_date &amp;gt; &apos;2025-01-01&apos;, &apos;新员工&apos;, &apos;老员工&apos;)` 完全正确。而 `CASE` 表达式则更强大，尤其适合多分支的复杂条件判断，其搜索形式 `CASE WHEN ... THEN ... ELSE ... END` 同样可以完美实现本题需求。因此，两种方法都是可行的。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2.简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;请简述字符串函数 &lt;code&gt;CONCAT&lt;/code&gt; 和 &lt;code&gt;CONCAT_WS&lt;/code&gt; 的区别。
答：
CONCAT：是将多个字符串简单拼接在一起，且任一参数为NULL则返回NULL。
CONCAT_WS：是 CONCAT的基础上增加了分隔符功能，是带分隔符地拼接多个字符，​​自动忽略参数中的NULL值​​（分隔符本身不能为NULL）&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;    在MySQL中，`CONCAT` 和 `CONCAT_WS` 都是用于连接字符串的函数，但它们在处理分隔符和空值（`NULL`）时的行为是关键区别所在。下面这个表格能帮你快速把握它们的核心区别。

    | 特性 | `CONCAT` | `CONCAT_WS` |
    | :--- | :--- | :--- |
    | **核心功能** | 将多个字符串**简单连接**在一起 | **带分隔符**地连接多个字符串 |
    | **分隔符** | 无内置分隔符概念，需手动在每个参数间添加 | **第一个参数即为分隔符**，一次性指定 |
    | **处理`NULL`值** | **任一参数为`NULL`，则整个结果返回`NULL`** | **忽略要连接的参数中的`NULL`值**（分隔符本身不能为`NULL`） |
    | **适用场景** | 简单的、无间隔的字符串拼接 | 需要用特定字符（如逗号、短横线）连接字段，且字段可能包含`NULL`值 |

    ### 💡 深入了解 `CONCAT` 函数

    `CONCAT` 函数的功能非常直接：按顺序将传入的所有参数连接成一个字符串。其语法为 `CONCAT(str1, str2, ...)`。

    *   **注意事项**：它最大的特点（也常被视为一个“坑”）是，**只要待连接的参数中有一个是 `NULL`，整个函数的返回结果就是 `NULL`**。这在处理可能包含空值的数据库字段时需要格外小心。
    *   **示例**：
        ```sql
        SELECT CONCAT(&apos;Hello&apos;, &apos; &apos;, &apos;World&apos;); -- 返回 &apos;Hello World&apos;
        SELECT CONCAT(&apos;Hello&apos;, NULL, &apos;World&apos;); -- 返回 NULL
        SELECT CONCAT(&apos;2025&apos;, &apos;10&apos;, &apos;22&apos;); -- 返回 &apos;20251022&apos; (如需日期格式，需手动加分隔符)
        ```

    ### 🔄 掌握 `CONCAT_WS` 函数

    `CONCAT_WS` 是 &quot;CONCAT With Separator&quot; 的缩写，它在 `CONCAT` 的基础上增加了分隔符功能。其语法为 `CONCAT_WS(separator, str1, str2, ...)`，**第一个参数就是分隔符**。

    *   **核心优势**：除了能自动添加分隔符，它最实用的特性是**会忽略除分隔符之外的其他参数中的 `NULL` 值**。这意味着即使 `str2` 是 `NULL`，最终结果也会是 `str1` + 分隔符 + `str3`，而不会返回 `NULL`。
    *   **重要例外**：虽然会忽略参数中的 `NULL`，但如果**分隔符（第一个参数）本身是 `NULL`**，那么结果仍会返回 `NULL`。
    *   **示例**：
        ```sql
        SELECT CONCAT_WS(&apos;, &apos;, &apos;Apple&apos;, &apos;Banana&apos;, &apos;Orange&apos;); -- 返回 &apos;Apple, Banana, Orange&apos;
        SELECT CONCAT_WS(&apos;-&apos;, &apos;2025&apos;, &apos;10&apos;, &apos;22&apos;); -- 返回 &apos;2025-10-22&apos; (轻松格式化日期)
        SELECT CONCAT_WS(&apos; &apos;, &apos;Hello&apos;, NULL, &apos;World&apos;); -- 返回 &apos;Hello World&apos; (忽略NULL)
        ```

    ### 🛠️ 用场景选择函数

    根据上面的区别，你可以在不同场景下选择合适的函数：

    *   **使用 `CONCAT` 当**：你需要进行简单的、无间隔的字符串拼接，并且能**确保所有参数都不为 `NULL`**，或者你**希望当存在 `NULL` 时结果直接变为 `NULL`**。

    *   **使用 `CONCAT_WS` 当**：你希望用统一的**分隔符（如逗号、空格、短横线）来连接多个字符串**，特别是当这些字段**可能包含 `NULL` 值**，而你又不希望最终的拼接结果因某个空值而中断或失效时。这在拼接地址、全名或生成特定格式的编码时非常有用。

    ### 💎 简单总结

    记住一个简单的法则：需要加分隔符或者担心字段有`NULL`值影响拼接结果时，优先选择 **`CONCAT_WS`**；否则，进行最简单的无缝拼接且不担心`NULL`值时，可以使用 **`CONCAT`**。

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;聚集函数 &lt;code&gt;SUM&lt;/code&gt; 和 &lt;code&gt;AVG&lt;/code&gt; 在使用上有什么不同？
答：
&lt;code&gt;SUM&lt;/code&gt;是计算指定列中所有​​非NULL数值的总和​​。
&lt;code&gt;AVG&lt;/code&gt;是计算指定列中所有​​非NULL数值的算术平均值&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;IF&lt;/code&gt; 函数和 &lt;code&gt;CASE&lt;/code&gt; 函数在条件判断方面有什么特点和适用场景？
答：
&lt;code&gt;IF&lt;/code&gt; 函数：就像一个简单的“如果...那么...否则...”判断器，适用于简单场景，类似考试成绩if(cj &amp;gt;60,&quot;合格&quot;,&quot;不合格&quot;)
&lt;code&gt;CASE&lt;/code&gt; 函数：是一个​​多分支条件判断的精确匹配器，可以进行精细的​​多分支条件判断，像成绩分级case when  cj &amp;gt;=90 then &quot;优秀&quot; when cj &amp;gt;=80 and &amp;lt;=89 then &quot;良好&quot;.......&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;    这三个问题确实是SQL学习中的关键知识点。下面我用一个表格快速梳理它们的核心区别，然后我们再详细看看。


    | 函数对比 | 核心功能与关键区别 | 典型应用场景 |
    | :---- | :---- | :---- |
    | **CONCAT vs CONCAT_WS** | **CONCAT**：简单连接字符串，**任一参数为NULL则返回NULL**。&amp;lt;br&amp;gt;**CONCAT_WS**：带分隔符连接，**自动忽略参数中的NULL值**（分隔符本身不能为NULL）。 | **CONCAT**：无间隔拼接，如合并姓和名`CONCAT(last_name, first_name)`。&amp;lt;br&amp;gt;**CONCAT_WS**：需统一分隔符的拼接，如格式化日期`CONCAT_WS(&apos;-&apos;, year【耶尔】, month【mèn斯】, day【dèi】)`，或拼接可能为NULL的字段。 |
    | **SUM vs AVG** | **SUM**：计算指定列中所有**非NULL数值的总和**。&amp;lt;br&amp;gt;**AVG**：计算指定列中所有**非NULL数值的算术平均值**（其计算方式为`SUM(列) / COUNT(列)`）。 | **SUM**：回答“总量”问题，如总销售额、总成本。&amp;lt;br&amp;gt;**AVG**：回答“平均水平”问题，如平均分、平均工资。 |
    | **IF vs CASE** | **IF函数**：MySQL特有，适用于简单的**二元判断**（类似三元运算符`条件 ? 结果1 : 结果2`）。&amp;lt;br&amp;gt;**CASE表达式**：SQL标准语法，适用于**多分支条件判断**，功能更强大，可读性更好。 | **IF函数**：简单的“是/否”判断，如`IF(score &amp;gt;= 60, &apos;及格&apos;, &apos;不及格&apos;)`。&amp;lt;br&amp;gt;**CASE表达式**：复杂的多条件分支，如成绩分级、会员等级划分。 |

    ### 💡 字符串连接：CONCAT 与 CONCAT_WS

    -   **CONCAT 的注意事项**：由于其“遇NULL则NULL”的特性，在拼接可能包含空值的字段时存在风险。为确保结果，通常需要先用`COALESCE`或`IFNULL`函数将`NULL`值转换为空字符串等默认值，例如 `CONCAT(COALESCE(field1, &apos;&apos;), field2)`。
    -   **CONCAT_WS 的优势**：它在处理如地址等多部分信息时特别有用，因为这些信息中的某些部分很可能为`NULL`。使用`CONCAT_WS`可以避免繁琐的空值检查，直接生成整洁的拼接结果（例如 `CONCAT_WS(&apos; &apos;, address, city, country)`），即使其中部分字段为`NULL`，结果字符串也不会中断。

    ### 📊 数据汇总：SUM 与 AVG

    -   **共同点**：`SUM`和`AVG`都是聚合函数，它们在计算时都会**自动忽略**列中的`NULL`值。这意味着计算分母是非`NULL`值的个数，而非总行数。
    -   **重要细节**：
        -   `AVG`函数的结果类型可能比输入列的类型精度更高。例如，对整数列（`INT`）求平均值，可能会返回浮点数（如`DECIMAL`）结果。
        -   它们常与`GROUP BY`子句结合使用，以实现分组统计，例如计算每个部门的平均工资。
        -   可以使用`DISTINCT`关键字对唯一值进行计算，如 `AVG(DISTINCT score)` 只计算不同成绩的平均值。

    ### 🔀 条件判断：IF 与 CASE

    -   **CASE 表达式的两种形式**：
        1.  **简单 CASE 表达式**：用于等值比较，语法为 `CASE column WHEN value1 THEN result1 ... END`。例如，根据部门编号显示名称：`CASE department WHEN &apos;IT&apos; THEN &apos;技术部&apos; ... END`。
        2.  **搜索型 CASE 表达式**：功能更强，允许进行范围判断和多条件组合，语法为 `CASE WHEN condition1 THEN result1 ... END`。例如，成绩分级：`CASE WHEN score &amp;gt;= 90 THEN &apos;优秀&apos; ... END`。
    -   **选择策略**：
        -   当你的逻辑是简单的“如果...就...否则...”（二选一）时，使用 **`IF` 函数**，代码更简洁。
        -   当条件超过两种，或判断条件复杂（涉及范围、多条件组合）时，务必使用 **`CASE` 表达式**，其结构更清晰，可读性更强。
        -   `CASE`表达式是SQL标准，兼容性更好，而`IF`函数通常是MySQL扩展。此外，`CASE`表达式不仅可用于`SELECT`列表，还能用在`ORDER BY`、`WHERE`、`UPDATE`等子句中，实现非常灵活的条件逻辑。

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;使用字符串函数，将 &lt;code&gt;employees&lt;/code&gt; 表中所有员工的姓名转换为小写，并在每个姓名后面添加 “_emp” 后缀。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select concat(lower(name),&apos;_emp&apos;) as 姓名 from moershi.employees;
+---------------+
| 姓名          |
+---------------+
| 梁伟_emp      |
| 郭岩_emp      |
| 李玉英_emp    |
| 张健_emp      |
| 郑静_emp      |
| 牛建军_emp    |
...........
| 刘倩_emp      |
| 杨金凤_emp    |
+---------------+
133 rows in set (0.00 sec)

mysql&amp;gt; 

    ```sql
    SELECT CONCAT(LOWER(name), &apos;_emp&apos;) AS formatted_name
    FROM employees;
    ```

    或者，你也可以使用 `LCASE()` 函数（它与 `LOWER()` 功能完全相同）：

    ```sql
    SELECT CONCAT(LCASE(name), &apos;_emp&apos;) AS formatted_name
    FROM employees;
    ```

    ### 关键点说明

    -   **`LOWER()` / `LCASE()` 函数**：这两个函数用于将字符串中的所有字母字符转换为小写。例如，如果员工姓名是 &quot;John DOE&quot;，转换后将变为 &quot;john doe&quot;。
    -   **`CONCAT()` 函数**：此函数用于将多个字符串连接在一起。在这里，我们将转换后的小写姓名和固定后缀 &quot;_emp&quot; 拼接起来。
    -   **注意 `NULL` 值**：需要特别注意的是，如果 `name` 字段的值为 `NULL`，那么 `CONCAT()` 函数的结果也将是 `NULL`。如果您的数据中存在这种情况并且不希望返回 `NULL`，可以使用 `COALESCE()` 或 `IFNULL()` 函数为其设置一个默认值。例如：
        ```sql
        SELECT CONCAT(LOWER(COALESCE(name, &apos;unknown&apos;)), &apos;_emp&apos;) AS formatted_name
        FROM employees;
        ```

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;使用日期函数，从 &lt;code&gt;employees&lt;/code&gt; 表中找出在本月出生的员工信息。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; select name,birth_date birth_date from moershi.employees where month【mèn斯】(birth_date) = month【mèn斯】(now【闹】());
+-----------+------------+
| name      | birth_date |
+-----------+------------+
| 王英      | 1997-10-11 |
| 许辉      | 1992-10-21 |
| 罗岩      | 1986-10-17 |
| 赵成      | 1985-10-11 |
| 刘桂兰    | 1982-10-11 |
| 李莹      | 1995-10-26 |
| 李柳      | 1972-10-14 |
| 王小红    | 1989-10-04 |
| 贾荣      | 1984-10-19 |
| 张梅      | 1981-10-21 |
+-----------+------------+
10 rows in set (0.00 sec)

mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;使用数学计算，在 &lt;code&gt;salary&lt;/code&gt; 表中计算每个员工奖金占总薪资（基本工资 &lt;code&gt;basic&lt;/code&gt; 加上奖金 &lt;code&gt;bonus&lt;/code&gt;）的比例，并保留两位小数。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; select employee_id,basic,bonus,round(bonus / (basic + bonus) ,2) as 占总薪资比例 from moershi.salary where id&amp;lt;=50; #加个where 减少数据量方便截图
+-------------+-------+-------+--------------------+
| employee_id | basic | bonus | 占总薪资比例       |
+-------------+-------+-------+--------------------+
|           2 | 17000 | 10000 |               0.37 |
|           3 |  8000 |  2000 |               0.20 |
|           4 | 14000 |  9000 |               0.39 |
|           6 | 14000 | 10000 |               0.42 |
|           7 | 19000 | 10000 |               0.34 |
|          11 | 14000 |  7000 |               0.33 |
|          13 | 15000 |  1000 |               0.06 |
|          14 | 10000 | 11000 |               0.52 |
|          17 | 16000 |  7000 |               0.30 |
|          18 |  6000 | 10000 |               0.63 |
|          21 | 15000 |  6000 |               0.29 |
|          22 | 12000 |  8000 |               0.40 |
|          25 | 19000 |  2000 |               0.10 |
|          26 |  7000 | 11000 |               0.61 |
|          27 | 20000 |  5000 |               0.20 |
|          28 | 14000 |  5000 |               0.26 |
|          29 | 19000 |  1000 |               0.05 |
|          30 |  6000 |  1000 |               0.14 |
|          32 | 15000 |  8000 |               0.35 |
|          34 | 19000 |  6000 |               0.24 |
|          37 | 20000 |  6000 |               0.23 |
|          38 | 19000 | 11000 |               0.37 |
|          39 | 12000 | 10000 |               0.45 |
|          40 | 17000 |  2000 |               0.11 |
|          41 |  8000 |  7000 |               0.47 |
|          43 | 11000 |  9000 |               0.45 |
|          44 | 11000 |  8000 |               0.42 |
|          45 | 12000 |  1000 |               0.08 |
|          46 | 13000 | 10000 |               0.43 |
|          47 | 11000 | 11000 |               0.50 |
|          48 | 21000 | 10000 |               0.32 |
|          49 | 13000 |  7000 |               0.35 |
|          50 |  9000 |  4000 |               0.31 |
+-------------+-------+-------+--------------------+
33 rows in set (0.00 sec)

mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;使用 &lt;code&gt;CASE&lt;/code&gt; 函数，结合 &lt;code&gt;employees&lt;/code&gt; 表和 &lt;code&gt;departments&lt;/code&gt; 表，根据部门名称将员工分为 “技术部员工”、“销售部员工” 和 “其他部门员工” 三类。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; select
    -&amp;gt;     e.employee_id,
    -&amp;gt;     e.name as 姓名,
    -&amp;gt;     d.dept_name as 部门,
    -&amp;gt;     case 
    -&amp;gt;         when d.dept_name = &apos;运维部&apos; then &apos;技术部员工&apos;
    -&amp;gt;         when d.dept_name = &apos;开发部&apos; then &apos;技术部员工&apos;
    -&amp;gt;         when d.dept_name = &apos;测试部&apos; then &apos;技术部员工&apos;
    -&amp;gt;         when d.dept_name = &apos;市场部&apos; then &apos;销售部员工&apos;
    -&amp;gt;         when d.dept_name = &apos;销售部&apos; then &apos;销售部员工&apos;
    -&amp;gt;         else &apos;其他部门员工&apos;
    -&amp;gt;     end as 部门类型
    -&amp;gt; from moershi.employees e
    -&amp;gt; join moershi.departments d on e.dept_id = d.dept_id;
+-------------+-----------+-----------+--------------------+
| employee_id | 姓名      | 部门      | 部门类型           |
+-------------+-----------+-----------+--------------------+
|           1 | 梁伟      | 人事部    | 其他部门员工       |
|           2 | 郭岩      | 人事部    | 其他部门员工       |
|           3 | 李玉英    | 人事部    | 其他部门员工       |
|           4 | 张健      | 人事部    | 其他部门员工       |
|           5 | 郑静      | 人事部    | 其他部门员工       |
|           6 | 牛建军    | 人事部    | 其他部门员工       |
|           7 | 刘斌      | 人事部    | 其他部门员工       |
.......
|         128 | 许华      | 销售部    | 销售部员工         |
|         129 | 汤华      | 销售部    | 销售部员工         |
|         130 | 王玉兰    | 销售部    | 销售部员工         |
|         131 | 王荣      | 法务部    | 其他部门员工       |
|         132 | 刘倩      | 法务部    | 其他部门员工       |
|         133 | 杨金凤    | 法务部    | 其他部门员工       |
+-------------+-----------+-----------+--------------------+
133 rows in set (0.00 sec)

mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;

    您提出的这几个问题非常典型，涵盖了数据库查询中几个核心函数的用法。下面我将为您逐一提供详细的解答和示例。

    | 问题序号        | 核心方法                          | 示例 SQL 语句框架                                     |
    | :------------- | :------------------------------- | :-------------------------------------------------- |
    | 1. 姓名转换     | 使用 `LOWER()` 和 `CONCAT()` 函数 | `SELECT CONCAT(LOWER(name), &apos;_emp&apos;) ...`            |
    | 2. 查询本月生日 | 使用 `MONTH【mèn斯】()` 函数比较月份        | `SELECT ... WHERE MONTH【mèn斯】(birth_date) = MONTH【mèn斯】(NOW【闹】())` |
    | 3. 计算奖金占比 | 使用 `ROUND()` 函数控制小数位      | `SELECT ROUND(bonus/(basic+bonus), 2) ...`          |
    | 4. 员工部门分类 | 使用 `CASE` 条件表达式             | `CASE WHEN d.name = &apos;技术部&apos; THEN ... END`           |

    ### 💡 字符串函数：姓名格式化

    这个问题的目标是修改姓名显示格式，主要用到两个字符串函数：
    -   `LOWER()`：将字符串中的所有字母转换为小写。
    -   `CONCAT()`：将两个或多个字符串连接起来。

    相应的SQL语句和说明如下：
    ```sql
    SELECT 
        employee_id,
        CONCAT(LOWER(name), &apos;_emp&apos;) AS formatted_name
    FROM employees;
    ```
    **关键点说明**：这个操作创建了一个名为 `formatted_name` 的新列，其中每个员工的名字先被转换为小写，然后与后缀 `_emp` 连接。例如，`&quot;Alice&quot;` 会变成 `&quot;alice_emp&quot;`。

    ### 📅 日期函数：查询本月生日员工

    要找出在本月出生的员工，核心在于使用 `MONTH【mèn斯】()` 函数来提取日期字段中的月份部分，并与当前月份进行比较。

    相应的SQL语句和说明如下：
    ```sql
    SELECT 
        employee_id, 
        name, 
        birth_date
    FROM employees
    WHERE MONTH【mèn斯】(birth_date) = MONTH【mèn斯】(NOW【闹】());
    ```
    **关键点说明**：`NOW【闹】()` 函数返回当前的日期和时间。`MONTH【mèn斯】(NOW【闹】())` 提取出当前的月份数字（例如10月返回10）。`WHERE` 条件会筛选出 `birth_date` 字段中月份与当前月份相同的所有记录。

    ### ➗ 数学计算：计算奖金占比

    这个问题需要执行除法运算，并使用 `ROUND` 函数对结果进行格式化。

    相应的SQL语句和说明如下：
    ```sql
    SELECT 
        employee_id,
        basic,
        bonus,
        ROUND(bonus / (basic + bonus), 2) AS bonus_ratio
    FROM salary;
    ```
    **关键点说明**：
    -   计算逻辑：使用 `奖金 / (基本工资 + 奖金)` 来得到奖金占总薪资的比例。
    -   精度控制：`ROUND(数值, 2)` 函数将计算结果四舍五入到小数点后两位，这是处理金融或比率数据时的常见做法。
    -   注意 `NULL` 值：如果 `basic` 或 `bonus` 可能为 `NULL`，直接计算会导致结果为 `NULL`。为确保计算安全，可以使用 `IFNULL(basic, 0)` 等函数为 `NULL` 值设置默认值。

    ### 🔀 条件判断：对员工进行部门分类

    `CASE` 表达式非常适合这种多条件的值映射场景，它允许你根据不同的条件返回不同的结果。这里假设员工表（`employees`）中有一个部门ID字段（`dept_id`）与部门表（`departments`）关联，部门表中有部门名字段（`name`）。

    相应的SQL语句和说明如下：
    ```sql

    select
        e.employee_id,
        e.name as 姓名,
        d.dept_name as 部门,
        case 
            when d.dept_name = &apos;运维部&apos; then &apos;技术部员工&apos;
            when d.dept_name = &apos;开发部&apos; then &apos;技术部员工&apos;
            when d.dept_name = &apos;测试部&apos; then &apos;技术部员工&apos;
            when d.dept_name = &apos;市场部&apos; then &apos;销售部员工&apos;
            when d.dept_name = &apos;销售部&apos; then &apos;销售部员工&apos;
            else &apos;其他部门员工&apos;
        end as 部门类型
    from moershi.employees e
    join moershi.departments d on e.dept_id = d.dept_id;

    ```
    **关键点说明**：
    -   使用搜索型 `CASE` 表达式：`CASE WHEN condition THEN result ... END`。
    -   执行顺序是自上而下评估每个 `WHEN` 条件，一旦某个条件为真，就返回对应的 `THEN` 结果，并跳过后续条件。
    -   如果所有 `WHEN` 条件都不满足，则返回 `ELSE` 子句的结果。指定 `ELSE` 是一个好习惯，可以确保所有情况都有明确的输出。


&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>03：mysql之单表增删改查</title><link>https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/03-mysql%E4%B9%8B%E5%8D%95%E8%A1%A8%E5%A2%9E%E5%88%A0%E6%94%B9%E6%9F%A5/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/03-mysql%E4%B9%8B%E5%8D%95%E8%A1%A8%E5%A2%9E%E5%88%A0%E6%94%B9%E6%9F%A5/</guid><description>03：mysql之单表增删改查 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 12:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1&gt;03：mysql之单表增删改查&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[单表增删改查]
        direction LR
        A[分组查询] --&amp;gt; B[对查询结果进行排序] --&amp;gt; C[分组后条件过滤] --&amp;gt; D[新增数据] --&amp;gt; E[修改数据] --&amp;gt; F[删除数据]
    end
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;在电商运营工作中，单表的增删改查操作十分常见。运营人员为了丰富商品种类，会向商品信息表中新增商品记录，包括商品名称、价格、库存等信息，以满足市场需求。若某商品价格调整，运营人员会及时修改商品信息表中该商品的价格字段，保证数据准确性。当一款商品下架时，他们会从表中删除该商品的记录，避免无效数据干扰。同时，在分析销售数据时，运营人员会根据不同条件从表中查询特定商品的信息，比如筛选出销量高的商品，为后续的营销策略提供数据支持。&lt;/p&gt;
&lt;h2&gt;二、为什么学增删改查&lt;/h2&gt;
&lt;p&gt;学习 MySQL 单表的增删改查至关重要。在数据管理领域，这是最基础且核心的技能。在日常工作里，我们常常要与各种数据打交道，增删改查操作能让我们灵活处理数据。比如，电商平台需新增商品信息、删除滞销商品数据、修改商品价格、查询特定商品库存。掌握这些操作，能高效维护数据，确保数据实时性与准确性。同时，它们是学习更复杂数据库操作的基石，如多表连接、存储过程等。对于从事数据分析、软件开发等行业的人而言，熟练运用增删改查是必备技能，能提升工作效率与质量。&lt;/p&gt;
&lt;h2&gt;三、分组查询&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[单表增删改查]
        direction LR
        A[分组查询] --&amp;gt; B[对查询结果进行排序] --&amp;gt; C[分组后条件过滤] --&amp;gt; D[新增数据] --&amp;gt; E[修改数据] --&amp;gt; F[删除数据]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class A highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;分组函数 group【格鲁普】 by&lt;/h3&gt;
&lt;p&gt;GROUP【格鲁普】 BY是 SQL 中非常重要的一个子句，它的主要作用是对查询结果进行分组统计&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;示例或关键点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;核心功能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;根据指定列将数据分成若干组，然后对每个组应用聚合函数进行统计。&lt;/td&gt;
&lt;td&gt;计算每个部门的平均工资、每个产品的总销售额等。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;基本语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT【涩莱克特】 列A, 聚合函数(列B) FROM【弗乱】 表名 GROUP【格鲁普】 BY 列A;&lt;/code&gt;。&lt;/td&gt;
&lt;td&gt;列A是分组依据。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;常用聚合函数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;COUNT【kàn特】()&lt;/code&gt;（计数）, &lt;code&gt;SUM【桑à姆】()&lt;/code&gt;（求和）, &lt;code&gt;AVG()&lt;/code&gt;（平均值）, &lt;code&gt;MAX【mà 斯】()&lt;/code&gt;（最大值）, &lt;code&gt;MIN【敏ì】()&lt;/code&gt;（最小值）。&lt;/td&gt;
&lt;td&gt;对每个分组进行计算。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;与HAVING子句&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;WHERE【威尔】&lt;/code&gt; 在分组&lt;strong&gt;前&lt;/strong&gt;过滤行，&lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; 在分组&lt;strong&gt;后&lt;/strong&gt;过滤组。&lt;/td&gt;
&lt;td&gt;&lt;code&gt;HAVING【嗨夫营】 AVG(salary【晒了瑞】) &amp;gt; 5000&lt;/code&gt;（筛选出平均工资大于5000的组）。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;多列分组&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; 后面可接多个列，按这些列的组合进行分组。&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GROUP【格鲁普】 BY department【迪帕踢门特】, job_title&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;重要注意事项&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT【涩莱克特】&lt;/code&gt; 后面非聚合的列，必须出现在 &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; 子句中。&lt;/td&gt;
&lt;td&gt;这是最容易出错的地方。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;💡 理解分组的过程&lt;/h4&gt;
&lt;p&gt;你可以把 &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; 想象成一个高效的数据整理师。它的工作流程通常是：首先，根据 &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; 后面指定的列，将表中所有数据行分成不同的“小组”，每个小组内的这些列的值完全相同。然后，数据库会对每一个这样的小组分别计算聚合函数（如求和、计数等）。最后，查询结果将为每个小组返回一行摘要信息，其中包含分组列的值和聚合函数计算的结果。&lt;/p&gt;
&lt;p&gt;例如，有一个员工表，使用 &lt;code&gt;SELECT【涩莱克特】 department【迪帕踢门特】, AVG(salary【晒了瑞】) FROM【弗乱】 employees【ing普洛伊s】 GROUP【格鲁普】 BY department【迪帕踢门特】;&lt;/code&gt; 可以计算出每个部门的平均工资。在这里，数据库会先按部门进行分组，然后对每个部门小组计算平均工资。&lt;/p&gt;
&lt;h4&gt;🛠️ 基本用法与示例&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;单列分组&lt;/strong&gt;
这是最常见的情况，即根据一个字段进行分组。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 统计每个城市的用户数量
SELECT【涩莱克特】 city, COUNT【kàn特】(*) AS user_count【kàn特】
FROM【弗乱】 users
GROUP【格鲁普】 BY city;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;多列分组&lt;/strong&gt;
当需要根据多个字段的组合进行更精细的分组时，可以使用多列分组。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 统计每个部门下每个职位的员工数量
SELECT【涩莱克特】 department【迪帕踢门特】, job_title, COUNT【kàn特】(*) AS employee【ing普洛伊】_count【kàn特】
FROM【弗乱】 employees【ing普洛伊s】
GROUP【格鲁普】 BY department【迪帕踢门特】, job_title;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个查询会返回所有唯一的“部门-职位”组合及其对应的员工数量。&lt;/p&gt;
&lt;h4&gt;⚠️ 关键规则与常见错误&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SELECT【涩莱克特】列表的非聚合列规则&lt;/strong&gt;
这是使用 &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; 时最需要牢记的规则：出现在 &lt;code&gt;SELECT【涩莱克特】&lt;/code&gt; 列表中的列，&lt;strong&gt;要么必须包含在 &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; 子句中，要么必须被包含在聚合函数里&lt;/strong&gt;。这是因为，对于每个分组来说，分组列的值是唯一的（比如“技术部”），但其他列可能有多条不同的记录（比如“技术部”里有很多不同的员工名）。数据库无法确定应该返回哪一条非分组列的值，因此强制要求通过聚合函数（如&lt;code&gt;MAX【mà 斯】&lt;/code&gt;, &lt;code&gt;AVG&lt;/code&gt;）将其汇总成一个值，或者将其本身作为分组依据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;WHERE【威尔】 与 HAVING【嗨夫营】 的区别&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;WHERE【威尔】&lt;/code&gt;&lt;/strong&gt;：在 &lt;strong&gt;分组之前&lt;/strong&gt; 过滤数据行。它不能包含聚合函数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;HAVING【嗨夫营】&lt;/code&gt;&lt;/strong&gt;：在 &lt;strong&gt;分组之后&lt;/strong&gt; 过滤分组结果。它通常与聚合函数一起使用，用来筛选满足特定条件的组。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;-- 正确示例：先过滤出2023年以后的订单，再按客户分组，最后筛选出总金额大于1000的客户
SELECT【涩莱克特】 customer_id, SUM【桑à姆】(amount) AS total【偷ò头ō】_amount
FROM【弗乱】 orders【欧朵s】
WHERE【威尔】 order【欧朵】_date &amp;gt;= &apos;2023-01-01&apos;  -- 分组前过滤行
GROUP【格鲁普】 BY customer_id
HAVING【嗨夫营】 SUM【桑à姆】(amount) &amp;gt; 1000;        -- 分组后过滤组
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;🔍 高级用法与技巧&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;使用表达式或函数分组&lt;/strong&gt;：可以根据表达式的结果进行分组，这在处理时间序列数据时特别有用。例如，可以按年份和月份分组统计订单。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;使用ROLLUP生成小计和总计&lt;/strong&gt;：&lt;code&gt;WITH ROLLUP&lt;/code&gt; 选项可以在分组结果的基础上，生成层次性的小计和总计行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;处理NULL【nò】值&lt;/strong&gt;：需要注意的是，如果分组列中包含 &lt;code&gt;NULL【nò】&lt;/code&gt; 值，所有 &lt;code&gt;NULL【nò】&lt;/code&gt; 值会被归为同一组。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;命令操作如下所示：&lt;/h4&gt;
&lt;h5&gt;输出符合条件的shell 和 name&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 shell,name  from【弗乱】 moershi.user where【威尔】shell in (&quot;/bin/bash&quot;,&quot;/sbin/nologin【诺劳京(白话)】&quot;);
+---------------+-----------------+
| shell         | name            |
+---------------+-----------------+
| /bin/bash     | root            |
| /sbin/nologin | bin             |
| /sbin/nologin | daemon          |
| /sbin/nologin | adm             |
.................
| /sbin/nologin | rpc             |
| /sbin/nologin | rpcuser         |
| /sbin/nologin | nfsnobody       |
| /sbin/nologin | haproxy         |
| /bin/bash     | plj             |
| /sbin/nologin | apache          |
+---------------+-----------------+
22 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;统计每种解释器用户的个数 （按照shell表头值分组统计name表头值个数）&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 shell as 解释器 , count【kàn特】(name) as 总人数  from【弗乱】 moershi.user where【威尔】shell in (&quot;/bin/bash&quot;,&quot;/sbin/nologin【诺劳京(白话)】&quot;) group【格鲁普】 by shell;
+---------------+-----------+
| 解释器        | 总人数    |
+---------------+-----------+
| /bin/bash     |         2 |
| /sbin/nologin |        20 |
+---------------+-----------+
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;子句/部分&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SELECT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;指定要查询的列。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;shell AS 解释器&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;查询 &lt;code&gt;shell&lt;/code&gt; 字段，并将其&lt;strong&gt;别名&lt;/strong&gt;设置为“解释器”。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;COUNT(name) AS 总人数&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;使用 &lt;strong&gt;&lt;code&gt;COUNT&lt;/code&gt;&lt;/strong&gt; 聚合函数统计每个分组中 &lt;code&gt;name&lt;/code&gt; 的数目，别名是“总人数”。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FROM moershi.user&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;指定查询的表为 &lt;code&gt;moershi&lt;/code&gt; 数据库下的 &lt;code&gt;user&lt;/code&gt; 表。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;WHERE shell IN (...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;过滤&lt;/strong&gt;条件，只统计使用&lt;code&gt;/bin/bash&lt;/code&gt;或&lt;code&gt;/sbin/nologin&lt;/code&gt;的用户。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GROUP BY shell&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;根据 &lt;code&gt;shell&lt;/code&gt; 字段的值进行&lt;strong&gt;分组&lt;/strong&gt;，将使用相同Shell的用户归为一组进行统计。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h5&gt;统计每个部门的总人数 (按照部门表头分组统计name表头值的个数)&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 dept_id , count【kàn特】(name)  from【弗乱】moershi.employees【ing普洛伊s】 group【格鲁普】 by  dept_id ;
+---------+-------------+
| dept_id | count【kàn特】(name) |
+---------+-------------+
|       1 |           8 |
|       2 |           5 |
|       3 |           6 |
|       4 |          55 |
|       5 |          12 |
|       6 |           9 |
|       7 |          35 |
|       8 |           3 |
+---------+-------------+
8 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、对查询结果进行排序&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[单表增删改查]
        direction LR
        A[分组查询] --&amp;gt; B[对查询结果&amp;lt;/n&amp;gt;进行排序] --&amp;gt; C[分组后条件过滤] --&amp;gt; D[新增数据] --&amp;gt; E[修改数据] --&amp;gt; F[删除数据]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class B highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;排序函数 order【欧朵】 by&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;示例或关键点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;核心功能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;根据指定的列对查询结果集进行排序。&lt;/td&gt;
&lt;td&gt;让数据展示更清晰，便于分析和查看。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;基本语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;`SELECT【涩莱克特】 ... FROM【弗乱】 ... ORDER【欧朵】 BY column【科勒姆】_name [ASC【阿斯克】&lt;/td&gt;
&lt;td&gt;desc];`&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;排序方式&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ASC【阿斯克】&lt;/code&gt;：升序（默认，可省略）。 &lt;code&gt;desc&lt;/code&gt;：降序。&lt;/td&gt;
&lt;td&gt;若不指定，默认为 &lt;code&gt;ASC【阿斯克】&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;多列排序&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;按多个字段排序，优先级从左到右。&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ORDER【欧朵】 BY column1【科勒姆】 desc, column2【科勒姆】 ASC【阿斯克】;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;排序键类型&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;字段名、字段在SELECT【涩莱克特】中的序号（从1开始）、字段别名。&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ORDER【欧朵】 BY 1&lt;/code&gt;（按第一列排序）。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;与聚合函数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;可使用聚合函数结果排序。&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ORDER【欧朵】 BY COUNT【kàn特】(*) desc;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NULL【nò】值处理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NULL【nò】值可能集中出现在开头或末尾，具体取决于数据库系统。&lt;/td&gt;
&lt;td&gt;需特别注意其默认位置。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;💡 理解排序规则与语法&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;ORDER【欧朵】 BY&lt;/code&gt; 子句的核心作用是将查询结果按照特定顺序排列。其基本语法遵循以下结构：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT【涩莱克特】 column1【科勒姆】, column2【科勒姆】, ...
FROM【弗乱】 table【忒-部】_name
ORDER【欧朵】 BY column1【科勒姆】 [ASC【阿斯克】|desc], column2【科勒姆】 [ASC【阿斯克】|desc], ...;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里，&lt;code&gt;ASC【阿斯克】&lt;/code&gt; 表示升序（Ascending），&lt;code&gt;desc&lt;/code&gt; 表示降序（Descending）。如果省略排序方式，数据库将默认按照升序（&lt;code&gt;ASC【阿斯克】&lt;/code&gt;）排列结果 。&lt;/p&gt;
&lt;h4&gt;🛠️ 掌握多种排序方式&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;单列排序&lt;/strong&gt;
这是最基础的排序方式，即根据单个字段的值进行排序。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 按产品名称升序排列（ASC【阿斯克】可省略）
SELECT【涩莱克特】 prod_name FROM【弗乱】 products ORDER【欧朵】 BY prod_name ASC【阿斯克】;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;多列排序与优先级&lt;/strong&gt;
当需要根据多个条件排序时，可以在 &lt;code&gt;ORDER【欧朵】 BY&lt;/code&gt; 后列出多个列，它们具有明确的优先级：&lt;strong&gt;写在前面的字段优先级最高&lt;/strong&gt;。数据库会先按第一个字段排序，当第一个字段的值相同时，再按第二个字段排序，以此类推 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 先按价格降序，价格相同的再按产品名称升序排列
SELECT【涩莱克特】 prod_id, prod_price, prod_name
FROM【弗乱】 products
ORDER【欧朵】 BY prod_price desc, prod_name ASC【阿斯克】;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;按列位置和别名排序&lt;/strong&gt;
除了直接使用列名，还可以使用列在 &lt;code&gt;SELECT【涩莱克特】&lt;/code&gt; 子句中的&lt;strong&gt;位置序号&lt;/strong&gt;（从1开始）或定义的&lt;strong&gt;别名&lt;/strong&gt;进行排序 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 按位置排序：按SELECT【涩莱克特】中的第二列(prod_price)降序，第三列(prod_name)升序
SELECT【涩莱克特】 prod_id, prod_price, prod_name
FROM【弗乱】 products
ORDER【欧朵】 BY 2 desc, 3;

-- 按别名排序
SELECT【涩莱克特】 prod_id, prod_price AS price, prod_name
FROM【弗乱】 products
ORDER【欧朵】 BY price desc;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;⚠️ 注意关键细节与技巧&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;子句顺序&lt;/strong&gt;：在 SQL 语句中，&lt;code&gt;ORDER【欧朵】 BY&lt;/code&gt; 子句必须位于所有其他子句之后，即正确的书写顺序是：&lt;code&gt;SELECT【涩莱克特】&lt;/code&gt; -&amp;gt; &lt;code&gt;FROM【弗乱】&lt;/code&gt; -&amp;gt; &lt;code&gt;WHERE【威尔】&lt;/code&gt; -&amp;gt; &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; -&amp;gt; &lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; -&amp;gt; &lt;code&gt;ORDER【欧朵】 BY&lt;/code&gt; 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NULL【nò】 值的排序&lt;/strong&gt;：对于包含 NULL【nò】 值的列进行排序时，NULL【nò】 会被集中排列，但具体出现在结果集的开头还是末尾，不同的数据库管理系统可能有不同的默认行为 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;与聚合函数结合使用&lt;/strong&gt;：&lt;code&gt;ORDER【欧朵】 BY&lt;/code&gt; 可以根据聚合函数的结果进行排序，这在数据统计和分析时非常有用 。&lt;pre&gt;&lt;code&gt;-- 统计每个产品类型的数量，并按数量降序排列
SELECT【涩莱克特】 product_type, COUNT【kàn特】(*)
FROM【弗乱】 Product
GROUP【格鲁普】 BY product_type
ORDER【欧朵】 BY COUNT【kàn特】(*) desc;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能考虑&lt;/strong&gt;：对经常需要排序的列建立索引，可以显著提高排序查询的速度 。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;💎 简单总结&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;ORDER【欧朵】 BY&lt;/code&gt; 是控制查询结果展示顺序的关键。记住：&lt;strong&gt;&lt;code&gt;ORDER【欧朵】 BY&lt;/code&gt; 默认升序，多列排序时左侧列优先级最高，并且它总是 &lt;code&gt;SELECT【涩莱克特】&lt;/code&gt; 语句的最后一个子句。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;desc :  降序&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;asc【阿斯克】：升序&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;命令操作如下所示：&lt;/h4&gt;
&lt;h5&gt;查看满足条件记录的name和uid 字段的值&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 name , uid from【弗乱】 moershi.user where【威尔】uid is not【呐-特】 null【nò】 and uid between【B豚ing】 100  and 1000 ;
+-----------------+------+
| name            | uid  |
+-----------------+------+
| systemd-network |  192 |
| polkitd         |  999 |
| chrony          |  998 |
| haproxy         |  188 |
| plj             | 1000 |
+-----------------+------+
5 rows in set【赛特】 (0.00 sec)  
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;按照uid升序排序&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 name , uid from【弗乱】 moershi.user where【威尔】uid is not【呐-特】 null【nò】 and uid between【B豚ing】 100  and 1000  order【欧朵】 by uid asc【阿斯克】;
+-----------------+------+
| name            | uid  |
+-----------------+------+
| haproxy         |  188 |
| systemd-network |  192 |
| chrony          |  998 |
| polkitd         |  999 |
| plj             | 1000 |
+-----------------+------+
5 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;按照uid降序排序&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 name , uid from【弗乱】 moershi.user where【威尔】uid is not【呐-特】 null【nò】 and uid between【B豚ing】 100  and 1000  order【欧朵】 by uid desc;
+-----------------+------+
| name            | uid  |
+-----------------+------+
| plj             | 1000 |
| polkitd         |  999 |
| chrony          |  998 |
| systemd-network |  192 |
| haproxy         |  188 |
+-----------------+------+
5 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;查看2015年1月10号员工编号小于10的工资总额&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 employee【ing普洛伊】_id , date , basic【贝斯克】 , bonus【波诺斯】 ,  basic【贝斯克】+bonus【波诺斯】 as total【偷ò头ō】  from【弗乱】 moershi.salary【晒了瑞】 where【威尔】date=20150110 and employee【ing普洛伊】_id &amp;lt;= 10;
+-------------+------------+-----------------+----------------+-----------------+
| employee_id | date       | basic【贝斯克】 | bonus【波诺斯】 | total【偷ò头ō】 |
+-------------+------------+-----------------+----------------+-----------------+
|           2 | 2015-01-10 | 17000           | 10000          | 27000           |
|           3 | 2015-01-10 |  8000           |  2000          | 10000           |
|           4 | 2015-01-10 | 14000           |  9000          | 23000           |
|           6 | 2015-01-10 | 14000           | 10000          | 24000           |
|           7 | 2015-01-10 | 19000           | 10000          | 29000           |
+-------------+------------+-----------------+----------------+-----------------+
5 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;以工资总额升序排 ，总额相同按照员工编号升序排&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 employee【ing普洛伊】_id , basic【贝斯克】+bonus【波诺斯】 as total【偷ò头ō】  from【弗乱】 moershi.salary【晒了瑞】 where【威尔】date=20150110 and employee【ing普洛伊】_id &amp;lt;= 10 order【欧朵】 by total【偷ò头ō】 asc【阿斯克】 ,employee【ing普洛伊】_id asc【阿斯克】;
+-------------+-------+
| employee_id | total【偷ò头ō】 |
+-------------+-------+
|           3 | 10000 |
|           4 | 23000 |
|           6 | 24000 |
|           2 | 27000 |
|           7 | 29000 |
+-------------+-------+
5 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、分组后条件过滤&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[单表增删改查]
        direction LR
        A[分组查询] --&amp;gt; B[对查询结果&amp;lt;/n&amp;gt;进行排序] --&amp;gt; C[分组后条件过滤] --&amp;gt; D[新增数据] --&amp;gt; E[修改数据] --&amp;gt; F[删除数据]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class C highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;对分组后的组进行筛选: having【嗨夫营】&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;HAVING【嗨夫营】 子句&lt;/th&gt;
&lt;th&gt;WHERE【威尔】 子句&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;核心功能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;对 &lt;strong&gt;分组后的组&lt;/strong&gt; 进行筛选&lt;/td&gt;
&lt;td&gt;对 &lt;strong&gt;分组前的原始数据行&lt;/strong&gt; 进行筛选&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;作用对象&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;由 GROUP【格鲁普】 BY 产生的分组或聚合函数的结果&lt;/td&gt;
&lt;td&gt;来自表的单行记录&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;聚合函数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;可以且经常&lt;/strong&gt; 使用（如 &lt;code&gt;HAVING【嗨夫营】 SUM【桑à姆】(amount) &amp;gt; 100&lt;/code&gt;）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;不可以&lt;/strong&gt; 直接使用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;执行顺序&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;在 &lt;strong&gt;GROUP【格鲁普】 BY&lt;/strong&gt; 之后&lt;/td&gt;
&lt;td&gt;在 &lt;strong&gt;GROUP【格鲁普】 BY&lt;/strong&gt; 之前&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;典型应用&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;筛选满足条件的组，例如&quot;总销售额大于1万的部门&quot;&lt;/td&gt;
&lt;td&gt;筛选满足条件的行，例如&quot;年龄大于30岁的员工&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;💡 理解 HAVING【嗨夫营】 的工作原理&lt;/h4&gt;
&lt;p&gt;你可以将 SQL 查询的执行顺序理解为：&lt;strong&gt;FROM【弗乱】 → WHERE【威尔】 → GROUP【格鲁普】 BY → HAVING【嗨夫营】 → SELECT【涩莱克特】 → ORDER【欧朵】 BY&lt;/strong&gt; 。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;FROM【弗乱】&lt;/strong&gt;：首先从表中获取数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WHERE【威尔】&lt;/strong&gt;：接着，&lt;code&gt;WHERE【威尔】&lt;/code&gt; 子句会像一道筛子，根据你设定的条件（比如 &lt;code&gt;amount &amp;gt; 100&lt;/code&gt;）对原始数据行进行过滤，只保留符合条件的行。这一步会在分组之前有效减少需要处理的数据量 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GROUP【格鲁普】 BY&lt;/strong&gt;：然后，数据库会按照指定的列对 &lt;code&gt;WHERE【威尔】&lt;/code&gt; 过滤后的结果进行分组，将具有相同值的行归到同一组中。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HAVING【嗨夫营】&lt;/strong&gt;：最后，&lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; 子句登场，它基于聚合函数的结果（例如组的平均工资、总销售额等）对这些分组进行筛选，只保留满足条件的分组 。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;🛠️ HAVING【嗨夫营】 的典型用法场景&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;1. 基础用法：筛选聚合结果&lt;/strong&gt;
这是 HAVING【嗨夫营】 最经典的场景，用于找出符合某项统计条件的组。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 找出总消费金额超过1000元的客户
SELECT【涩莱克特】 customer_id, SUM【桑à姆】(amount) AS total【偷ò头ō】_spending
FROM【弗乱】 orders
GROUP【格鲁普】 BY customer_id
HAVING【嗨夫营】 SUM【桑à姆】(amount) &amp;gt; 1000; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;2. 结合 WHERE【威尔】 使用：提高查询效率&lt;/strong&gt;
你可以同时使用 &lt;code&gt;WHERE【威尔】&lt;/code&gt; 和 &lt;code&gt;HAVING【嗨夫营】&lt;/code&gt;，让 &lt;code&gt;WHERE【威尔】&lt;/code&gt; 先过滤掉不需要的原始数据，减少分组计算的压力，再由 &lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; 完成最终筛选 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 找出在2024年下单次数超过5次的客户
SELECT【涩莱克特】 customer_id, COUNT【kàn特】(order_id) AS order_count【kàn特】
FROM【弗乱】 orders
WHERE【威尔】 YEAR(order_date) = 2024  -- 先筛选出2024年的订单，提高效率
GROUP【格鲁普】 BY customer_id
HAVING【嗨夫营】 COUNT【kàn特】(order_id) &amp;gt; 5;     -- 再筛选出订单数超过5的客户 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;3. 多条件组合&lt;/strong&gt;
在 &lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; 子句中，你可以使用 &lt;code&gt;AND&lt;/code&gt;、&lt;code&gt;OR&lt;/code&gt; 来连接多个聚合条件 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 找出总消费超过2000元且平均订单金额大于500元的客户
SELECT【涩莱克特】 customer_id, SUM【桑à姆】(amount) AS total【偷ò头ō】, AVG(amount) AS avg_amount
FROM【弗乱】 orders
GROUP【格鲁普】 BY customer_id
HAVING【嗨夫营】 SUM【桑à姆】(amount) &amp;gt; 2000 AND AVG(amount) &amp;gt; 500; 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;⚠️ 常见误区与注意事项&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;不要在 HAVING【嗨夫营】 中过滤非聚合的原始字段&lt;/strong&gt;：如果过滤条件不涉及聚合计算，只是针对某一行的原始字段，那么应该把它放在 &lt;code&gt;WHERE【威尔】&lt;/code&gt; 子句，而不是 &lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; 中。放在 &lt;code&gt;WHERE【威尔】&lt;/code&gt; 子句效率更高，因为它能在分组前就减少数据量 。当然，如果该字段是分组字段，则可以在 HAVING【嗨夫营】 中使用 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HAVING【嗨夫营】 通常依赖于 GROUP【格鲁普】 BY&lt;/strong&gt;：&lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; 子句通常与 &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; 一起出现。除非你的查询是对整个表进行聚合（例如 &lt;code&gt;SELECT【涩莱克特】 COUNT【kàn特】(*) FROM【弗乱】 table【忒-部】 HAVING【嗨夫营】 COUNT【kàn特】(*) &amp;gt; 10&lt;/code&gt;），否则缺少 &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; 会导致语法错误 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;别名使用&lt;/strong&gt;：在某些数据库系统中，&lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; 子句可以直接使用在 &lt;code&gt;SELECT【涩莱克特】&lt;/code&gt; 中为聚合函数定义的别名，例如 &lt;code&gt;HAVING【嗨夫营】 total【偷ò头ō】_spending &amp;gt; 1000&lt;/code&gt;，这可以使查询更简洁 。但为了更好的兼容性，直接在 HAVING【嗨夫营】 中写完整的聚合表达式是更稳妥的做法。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;💎 简单总结&lt;/h4&gt;
&lt;p&gt;记住一个核心原则：当你需要对 &lt;strong&gt;分组后的统计结果&lt;/strong&gt; 设置条件时，就是 &lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; 子句大显身手的时候。它与 &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; 是形影不离的好搭档，一个负责分组，一个负责对分组后的结果进行筛选 。&lt;/p&gt;
&lt;h4&gt;命令操作如下所示：&lt;/h4&gt;
&lt;h5&gt;查找部门总人数少于10人的部门名称及人数&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;//第一步，查看所有员工的部门名称
select【涩莱克特】  dept_id ,  name    from【弗乱】  moershi.employees【ing普洛伊s】;
//第二步，按部门编号分组 统计人名个数
mysql&amp;gt; select【涩莱克特】  dept_id ,  count【kàn特】(name) as numbers【nèn波s】   from【弗乱】  moershi.employees【ing普洛伊s】 group【格鲁普】 by  dept_id;
+---------+-------------------+
| dept_id | numbers【nèn波s】 |
+---------+-------------------+
|       1 |       8           |
|       2 |       5           |
|       3 |       6           |
|       4 |      55           |
|       5 |      12           |
|       6 |       9           |
|       7 |      35           |
|       8 |       3           |
+---------+-------------------+
8 rows in set【赛特】 (0.00 sec) 
//第三步，查找部门人数少于10人的部门名称及人数
mysql&amp;gt; select【涩莱克特】  dept_id ,  count【kàn特】(name) as numbers【nèn波s】 from【弗乱】  moershi.employees【ing普洛伊s】 group【格鲁普】 by  dept_id having【嗨夫营】 numbers【nèn波s】 &amp;lt; 10;
+---------+-------------------+
| dept_id | numbers【nèn波s】 |
+---------+-------------------+
|       1 |       8           |
|       2 |       5           |
|       3 |       6           |
|       6 |       9           |
|       8 |       3           |
+---------+-------------------+
5 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;六、分页查询 limit【类梅特】&lt;/h3&gt;
&lt;p&gt;在 MySQL 中，LIMIT【类梅特】是用于实现分页查询的关键字，它能够精确控制查询结果返回的记录条数和起始位置
。下面这个表格能帮你快速抓住它的核心用法。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;语法格式A&lt;/th&gt;
&lt;th&gt;语法格式B (MySQL 8.0+ 推荐)&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;基本语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIMIT【类梅特】 offset【哦夫赛特】, row_count&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIMIT【类梅特】 row_count OFFSET【哦夫赛特】 offset【哦夫赛特】&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从第 &lt;code&gt;offset【哦夫赛特】&lt;/code&gt; 条记录开始，返回 &lt;code&gt;row_count&lt;/code&gt; 条记录。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;偏移量(offset【哦夫赛特】)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;从 &lt;strong&gt;0&lt;/strong&gt; 开始计数&lt;/td&gt;
&lt;td&gt;从 &lt;strong&gt;0&lt;/strong&gt; 开始计数&lt;/td&gt;
&lt;td&gt;例如，&lt;code&gt;offset【哦夫赛特】&lt;/code&gt; 为 0 表示从第一条记录开始。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;简化查询&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIMIT【类梅特】 row_count&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;等同于 &lt;code&gt;LIMIT【类梅特】 0, row_count&lt;/code&gt;，返回前 &lt;code&gt;row_count&lt;/code&gt; 条。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;分页公式&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIMIT【类梅特】 (pageNum - 1) * pageSize, pageSize&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIMIT【类梅特】 pageSize OFFSET【哦夫赛特】 (pageNum - 1) * pageSize&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pageNum&lt;/code&gt;: 当前页码(从1开始); &lt;code&gt;pageSize&lt;/code&gt;: 每页条数。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;💡 如何使用 LIMIT【类梅特】 进行分页&lt;/h4&gt;
&lt;p&gt;掌握 &lt;code&gt;LIMIT【类梅特】&lt;/code&gt; 的最佳方式就是动手实践。假设我们有一张 &lt;code&gt;users&lt;/code&gt; 表，需要实现每页显示10条记录的分页查询。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查询第1页数据&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 使用语法A
SELECT【涩莱克特】 * FROM【弗乱】 users ORDER BY id LIMIT【类梅特】 0, 10;
-- 使用语法B (推荐，语义更清晰)
SELECT【涩莱克特】 * FROM【弗乱】 users ORDER BY id LIMIT【类梅特】 10 OFFSET【哦夫赛特】 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这两条语句是等价的，都返回最前面的10条记录。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查询第2页数据&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 偏移量 offset【哦夫赛特】 = (2 - 1) * 10 = 10
SELECT【涩莱克特】 * FROM【弗乱】 users ORDER BY id LIMIT【类梅特】 10, 10;
-- 或
SELECT【涩莱克特】 * FROM【弗乱】 users ORDER BY id LIMIT【类梅特】 10 OFFSET【哦夫赛特】 10;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里从第11条记录开始（偏移10条），再取10条记录。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;⚠️ 重要提示&lt;/strong&gt;：&lt;strong&gt;分页查询必须与 &lt;code&gt;ORDER BY&lt;/code&gt; 子句配合使用&lt;/strong&gt;，以确保每次查询结果的顺序一致。否则，数据库返回的记录顺序可能是随机的，导致分页混乱。&lt;/p&gt;
&lt;h4&gt;🚀 如何优化大偏移量下的分页性能&lt;/h4&gt;
&lt;p&gt;当需要查询的页码非常靠后时（例如 &lt;code&gt;LIMIT【类梅特】 100000, 10&lt;/code&gt;），直接使用 &lt;code&gt;LIMIT【类梅特】&lt;/code&gt; 会产生性能问题，因为数据库需要先扫描并丢弃掉偏移量指定的前大量记录，效率很低。&lt;/p&gt;
&lt;p&gt;一个高效的优化策略是&lt;strong&gt;使用基于主键（或唯一索引）的范围查询来替代大的偏移量&lt;/strong&gt;。这种方法的原理是记录上一页最后一条记录的唯一ID，然后以此为起点获取下一页。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 假设已知上一页最后一条记录的id是10000
-- 传统的低效写法：SELECT【涩莱克特】 * FROM【弗乱】 table【忒-部】 ORDER BY id LIMIT【类梅特】 10000, 10;
-- 优化后的高效写法：
SELECT【涩莱克特】 * FROM【弗乱】 table【忒-部】 WHERE【威尔】 id &amp;gt; 10000 ORDER BY id LIMIT【类梅特】 10;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这种方法通过索引直接定位到起始位置，跳过了大量数据的扫描，使得查询速度与页码基本无关。它非常适合实现“上一页/下一页”这种连续翻页的场景。&lt;/p&gt;
&lt;h4&gt;💎 简单总结&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;LIMIT【类梅特】&lt;/code&gt; 是实现MySQL分页的核心。记住：&lt;strong&gt;务必搭配 &lt;code&gt;ORDER BY&lt;/code&gt; 保证顺序&lt;/strong&gt;，在需要跳转到很靠后的页面时，&lt;strong&gt;尽量使用基于唯一ID的范围查询来优化性能&lt;/strong&gt;。&lt;/p&gt;
&lt;h4&gt;命令操作如下所示：&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;关键字：limit【类梅特】 数字1,数字2&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;数字1：起始行&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;数字2：每页显示总行数&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;limit【类梅特】   1   ;  显示查询结果的第1行
limit【类梅特】   3   ;  显示查询结果的前3行
limit【类梅特】   10  ;  显示查询结果的前10行
limit【类梅特】   0,1 ;      从查询结果的第1行开始显示，共显示1行
limit【类梅特】   3,5 ;      从查询结果的第4行开始显示，共显示5行
limit【类梅特】  10,10;      从查询结果的第11行开始显示，共显示10行
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;查看有解释器的用户信息&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】  * from【弗乱】moershi.user where【威尔】shell is not【呐-特】 null【nò】 ;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;只显示查询结果的第1行&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 *  from【弗乱】moershi.user where【威尔】shell is not【呐-特】 null【nò】  limit【类梅特】 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;只显示查询结果的前3行&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 *  from【弗乱】moershi.user  where【威尔】shell is not【呐-特】 null【nò】  limit【类梅特】  3;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;仅仅显示查询结果的第1行 到 第3 （0 表示查询结果的第1行）&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】  *  from【弗乱】user   where【威尔】shell is not【呐-特】 null【nò】  limit【类梅特】 0,3;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;从查询结果的第4行开始显示，共显示3行&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 name,uid , gid  , shell  from【弗乱】user  where【威尔】shell is not【呐-特】 null【nò】  limit【类梅特】 3,3;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;查看uid 号最大的用户名和UID&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】   name , uid from【弗乱】  moershi.user order【欧朵】  by   uid  desc  limit【类梅特】    1  ;
+-----------+-------+
| name      | uid   |
+-----------+-------+
| nfsnobody | 65534 |
+-----------+-------+
1 row in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、新增数据&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[单表增删改查]
        direction LR
        A[分组查询] --&amp;gt; B[对查询结果&amp;lt;/n&amp;gt;进行排序] --&amp;gt; C[分组后条件过滤] --&amp;gt; D[新增数据] --&amp;gt; E[修改数据] --&amp;gt; F[删除数据]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class D highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;p&gt;查看表头&lt;/p&gt;
&lt;h3&gt;desc&lt;/h3&gt;
&lt;p&gt;在SQL中，&lt;code&gt;desc&lt;/code&gt; 是一个常用的关键字，但它根据使用场景的不同，主要有两种截然不同的含义和用法。为了帮助你快速区分，我先用一个表格来总结它的核心用途。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;用途分类&lt;/th&gt;
&lt;th&gt;语法/上下文&lt;/th&gt;
&lt;th&gt;核心功能&lt;/th&gt;
&lt;th&gt;简要说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;查看表结构&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;desc table【忒-部】_name;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;显示数据表的详细结构信息（列名、类型、约束等）。&lt;/td&gt;
&lt;td&gt;主要用于数据库管理和调试，是一个&lt;strong&gt;命令&lt;/strong&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;指定查询排序&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ORDER BY column【科勒姆】_name desc;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;在查询结果中，将指定列按&lt;strong&gt;降序&lt;/strong&gt;（从大到小）排列。&lt;/td&gt;
&lt;td&gt;必须与 &lt;code&gt;ORDER BY&lt;/code&gt; 子句搭配使用，是一个&lt;strong&gt;关键字&lt;/strong&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;📊 作为表结构查看命令&lt;/h4&gt;
&lt;p&gt;这是 &lt;code&gt;desc&lt;/code&gt; 命令最直接的用途，相当于数据表的“说明书”。执行后，它会返回一个包含以下字段的表格，帮助你全面了解表的设计 ：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;输出列&lt;/th&gt;
&lt;th&gt;含义说明&lt;/th&gt;
&lt;th&gt;备注/示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Field&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;表中每一列（字段）的名称。&lt;/td&gt;
&lt;td&gt;例如 &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Type&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;该列字段的数据类型。&lt;/td&gt;
&lt;td&gt;例如 &lt;code&gt;int(11)&lt;/code&gt;, &lt;code&gt;varchar(255)&lt;/code&gt;, &lt;code&gt;date&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Null【nò】&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;该列是否允许存储空值（NULL【nò】）。&lt;/td&gt;
&lt;td&gt;&lt;code&gt;YES&lt;/code&gt; 表示允许，&lt;code&gt;NO&lt;/code&gt; 表示不允许。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Key&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;表示该列是否定义了键（索引）。&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PRI&lt;/code&gt;（主键），&lt;code&gt;UNI&lt;/code&gt;（唯一索引），&lt;code&gt;MUL&lt;/code&gt;（可重复的非唯一索引前导列或唯一索引的组成部分但可含空值），或为空（无索引）。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Default&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;该列的默认值。如果未显式赋值且未指定默认值，多数情况下显示 &lt;code&gt;NULL【nò】&lt;/code&gt;。&lt;/td&gt;
&lt;td&gt;例如，可设置为 &lt;code&gt;CURRENT_TIMESTAMP&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Extra&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;额外信息，如 &lt;code&gt;auto_increment&lt;/code&gt;（自动递增）。&lt;/td&gt;
&lt;td&gt;常见于主键ID列。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;如何使用：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 查看名为 &apos;employees【ing普洛伊s】&apos; 的表结构
desc employees【ing普洛伊s】;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;💡 如何避免混淆？&lt;/h4&gt;
&lt;p&gt;记住一个简单的规则：&lt;strong&gt;看它的位置&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果 &lt;code&gt;desc&lt;/code&gt; 后面直接跟着&lt;strong&gt;表名&lt;/strong&gt;（如 &lt;code&gt;desc employees【ing普洛伊s】;&lt;/code&gt;），它就是&lt;strong&gt;查看表结构&lt;/strong&gt;的命令。&lt;/li&gt;
&lt;li&gt;如果 &lt;code&gt;desc&lt;/code&gt; 前面有 &lt;strong&gt;&lt;code&gt;ORDER BY&lt;/code&gt;&lt;/strong&gt; 关键字（如 &lt;code&gt;ORDER BY salary【晒了瑞】 desc;&lt;/code&gt;），它就是&lt;strong&gt;指定降序排序&lt;/strong&gt;的关键字。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;命令操作如下所示：&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; desc moershi.user;
+---------------------+-------------+------------+-----+---------------------+----------------+
| Field               | Type        | Null【nò】 | Key| Default【迪-佛特】   | Extra          |
+---------------------+-------------+------------+-----+---------------------+----------------+
| id                  | int         | NO         | PRI | NULL【nò】         | auto_increment |
| name                | char(20)    | YES        |     | NULL【nò】         |                |
| password            | char(1)     | YES        |     | NULL【nò】         |                |
| uid                 | int         | YES        |     | NULL【nò】         |                |
| gid                 | int         | YES        |     | NULL【nò】         |                |
| comment【坑门特】    | varchar(50) | YES        |     | NULL【nò】         |                |
| homedir【home-跌儿】 | varchar(80) | YES        |     | NULL【nò】         |                |
| shell               | char(30)    | YES        |     | NULL【nò】         |                |
+---------------------+-------------+------------+-----+---------------------+----------------+
8 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;插入1条记录给所有表头赋值&lt;/h3&gt;
&lt;p&gt;（给所有表头赋值表头可以省略不写）id表头的值不能重复，主键的知识在后边课程里讲&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.user values【挖柳斯】(40,&quot;jingyaya&quot;,&quot;x&quot;,1001,1001,&quot;teacher&quot;,&quot;/home/jingyaya&quot;,&quot;/bin/bash&quot;);
Query OK, 1 row affected (0.05 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;查看表记录&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】  * from【弗乱】 moershi.user where【威尔】name=&quot;jingyaya&quot;;
+----+----------+----------+------+------+------------------+------------------------+-----------+
| id | name     | password | uid  | gid  | comment【坑门特】 | homedir【home-跌儿】   | shell     |
+----+----------+----------+------+------+------------------+------------------------+-----------+
| 40 | jingyaya | x        | 1001 | 1001 | teacher          | /home/jingyaya         | /bin/bash |
+----+----------+----------+------+------+------------------+------------------------+-----------+
1 row in set【赛特】 (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;插入多行记录给所有列赋值&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt; insert【因涩特】 into【因兔】 moershi.user values【挖柳斯】
(41,&quot;jingyaya2&quot;,&quot;x&quot;,1002,1002,&quot;teacher&quot;,&quot;/home/jingyaya2&quot;,&quot;/bin/bash&quot;),
(42,&quot;jingyaya3&quot;,&quot;x&quot;,1003,1003,&quot;teacher&quot;,&quot;/home/jingyaya3&quot;,&quot;/bin/bash&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;插入1行给指定列赋值，必须写列名，没赋值的列 没有数据 后通过设置的默认值赋值&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.user(name,uid,shell)values【挖柳斯】(&quot;benben&quot;,1002,&quot;/sbin/nologin&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;插入多行给指定列赋值，必须写列名，没赋值的列 没有数据 后通过设置的默认值赋值&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.user(name,uid,shell)values【挖柳斯】(&quot;benben2&quot;,1002,&quot;/sbin/nologin&quot;),(&quot;benben3&quot;,1003,&quot;/sbin/nologin&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;查看记录&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】  * from【弗乱】moershi.user where【威尔】name like  &quot;benben%&quot;;
+----+---------+----------+------+------+-------------------+---------------------+------------------------------+
| id | name    | password | uid  | gid  | comment【坑门特】 | homedir【home-跌儿】 | shell                        |
+----+---------+----------+------+------+-------------------+---------------------+------------------------------+
| 41 | benben  | NULL     | 1002 | NULL | NULL              | NULL                | /sbin/nologin【诺劳京(白话)】 |
| 42 | benben2 | NULL     | 1002 | NULL | NULL              | NULL                | /sbin/nologin【诺劳京(白话)】 |
| 43 | benben3 | NULL     | 1003 | NULL | NULL              | NULL                | /sbin/nologin【诺劳京(白话)】 |
+----+---------+----------+------+------+-------------------+---------------------+------------------------------+
3 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;使用select【涩莱克特】查询结果赋值(查询表头个数和 插入记录命令表头个数要一致)&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 user from【弗乱】 mysql.user;
+------------------+
| user             |
+------------------+
| mysql.infoschema |
| mysql.session    |
| mysql.sys        |
| root             |
+------------------+
4 rows in set【赛特】 (0.00 sec)
mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.user(name) (select【涩莱克特】 user from【弗乱】 mysql.user);
Query OK, 4 rows affected (0.09 sec)
Records: 4  Duplicates: 0  Warnings: 0
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;查看插入后的数据&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】  * from【弗乱】 moershi.user where【威尔】name like &quot;mysql%&quot; or name=&quot;root&quot;;
+----+------------------+----------+------+------+-----------------------+------------------------+------------+
| id | name             | password | uid  | gid  | comment【坑门特】      | homedir【home-跌儿】   | shell      |
+----+------------------+----------+------+------+-----------------------+------------------------+------------+
|  1 | root             | x        |    0 |    0 | root                  | /root                  | /bin/bash  |
| 26 | mysql            | x        |   27 |   27 | MySQL Server          | /var/lib/mysql         | /bin/false |
| 44 | mysql.infoschema | NULL     | NULL | NULL | NULL                  | NULL                   | NULL       |
| 45 | mysql.session    | NULL     | NULL | NULL | NULL                  | NULL                   | NULL       |
| 46 | mysql.sys        | NULL     | NULL | NULL | NULL                  | NULL                   | NULL       |
| 47 | root             | NULL     | NULL | NULL | NULL                  | NULL                   | NULL       |
+----+------------------+----------+------+------+-----------------------+------------------------+------------+
6 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;使用set【赛特】命令赋值&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.user set【赛特】 name=&quot;yaya&quot; , uid=99 , gid=99 ;
Query OK, 1 row affected (0.06 sec)
mysql&amp;gt; select【涩莱克特】 * from【弗乱】 moershi.user where【威尔】name=&quot;yaya&quot;;
+----+------+----------+------+------+------------------+----------------------+-------+
| id | name | password | uid  | gid  | comment【坑门特】 | homedir【home-跌儿】 | shell |
+----+------+----------+------+------+------------------+----------------------+-------+
| 28 | yaya | NULL     |   99 |   99 | NULL             | NULL                 | NULL  |
+----+------+----------+------+------+------------------+----------------------+-------+
1 row in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;七、修改数据&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[单表增删改查]
        direction LR
        A[分组查询] --&amp;gt; B[对查询结果&amp;lt;/n&amp;gt;进行排序] --&amp;gt; C[分组后条件过滤] --&amp;gt; D[新增数据] --&amp;gt; E[修改数据] --&amp;gt; F[删除数据]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class E highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;命令操作如下所示：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;//修改前查看
mysql&amp;gt; select【涩莱克特】  name , comment【坑门特】 from【弗乱】moershi.user where【威尔】id &amp;lt;= 10 ;
+----------+--------------------+
| name     | comment【坑门特】  |
+----------+--------------------+
| root     | root               |
| bin      | bin                |
| daemon   | daemon             |
| adm      | adm                |
| lp       | lp                 |
| sync     | sync               |
| shutdown | shutdown           |
| halt     | halt               |
| mail     | mail               |
| operator | operator           |
+----------+--------------------+
10 rows in set【赛特】 (0.00 sec)
//修改符合条件
mysql&amp;gt; update【阿普 dei 特】 moershi.user set【赛特】 comment【坑门特】=NULL【nò】 where【威尔】id &amp;lt;= 10 ;
Query OK, 10 rows affected (0.09 sec)
Rows matched: 10  Changed: 10  Warnings: 0
//修改后查看
mysql&amp;gt; select【涩莱克特】  name , comment【坑门特】 from【弗乱】moershi.user where【威尔】id &amp;lt;= 10 ;
+----------+------------------+
| name     | comment【坑门特】 |
+----------+------------------+
| root     | NULL             |
| bin      | NULL             |
| daemon   | NULL             |
| adm      | NULL             |
| lp       | NULL             |
| sync     | NULL             |
| shutdown | NULL             |
| halt     | NULL             |
| mail     | NULL             |
| operator | NULL             |
+----------+------------------+
10 rows in set【赛特】 (0.00 sec) 
[root@localhost ~]#
//修改前查看
mysql&amp;gt; select【涩莱克特】 name , homedir  from【弗乱】moershi.user;
+------------------+--------------------+
| name             | homedir【home-跌儿】|
+------------------+--------------------+
| root             | /root              |
| bin              | /bin               |
| daemon           | /sbin              |
| adm              | /var/adm           |
| lp               | /var/spool/lpd     |
| sync             | /sbin              |
| shutdown         | /sbin              |
| halt             | /sbin              |
| mail             | /var/spool/mail    |
| operator         | /root              |
| games            | /usr/games         |
| ftp              | /var/ftp           |
| nobody           | /                  |
| systemd-network  | /                  |
| dbus             | /                  |
| polkitd          | /                  |
| sshd             | /var/empty/sshd    |
| postfix          | /var/spool/postfix |
| chrony           | /var/lib/chrony    |
| rpc              | /var/lib/rpcbind   |
| rpcuser          | /var/lib/nfs       |
| nfsnobody        | /var/lib/nfs       |
| haproxy          | /var/lib/haproxy   |
| plj              | /home/plj          |
| apache           | /usr/share/httpd   |
| mysql            | /var/lib/mysql     |
| bob              | NULL               |
| jerrya           | NULL               |
| jingyaya         | /home/jingyaya     |
| benben           | NULL               |
| benben2          | NULL               |
| benben3          | NULL               |
| mysql.infoschema | NULL               |
| mysql.session    | NULL               |
| mysql.sys        | NULL               |
| root             | NULL               |
+------------------+--------------------+
36 rows in set【赛特】 (0.00 sec)
//不加条件批量修改
mysql&amp;gt; update【阿普 dei 特】  moershi.user set【赛特】 homedir=&quot;/student&quot; ;
Query OK, 36 rows affected (0.09 sec)
Rows matched: 36  Changed: 36  Warnings: 0
//修改后查看
mysql&amp;gt; select【涩莱克特】 name , homedir  from【弗乱】moershi.user;
+------------------+---------------------+
| name             | homedir【home-跌儿】|
+------------------+---------------------+
| root             | /student            |
| bin              | /student            |
| daemon           | /student            |
| adm              | /student            |
| lp               | /student            |
| sync             | /student            |
| shutdown         | /student            |
| halt             | /student            |
| mail             | /student            |
| operator         | /student            |
| games            | /student            |
| ftp              | /student            |
| nobody           | /student            |
| systemd-network  | /student            |
| dbus             | /student            |
| polkitd          | /student            |
| sshd             | /student            |
| postfix          | /student            |
| chrony           | /student            |
| rpc              | /student            |
| rpcuser          | /student            |
| nfsnobody        | /student            |
| haproxy          | /student            |
| plj              | /student            |
| apache           | /student            |
| mysql            | /student            |
| bob              | /student            |
| jerrya           | /student            |
| jingyaya         | /student            |
| benben           | /student            |
| benben2          | /student            |
| benben3          | /student            |
| mysql.infoschema | /student            |
| mysql.session    | /student            |
| mysql.sys        | /student            |
| root             | /student            |
+------------------+---------------------+
36 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;八、删除数据&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[单表增删改查]
        direction LR
        A[分组查询] --&amp;gt; B[对查询结果&amp;lt;/n&amp;gt;进行排序] --&amp;gt; C[分组后条件过滤] --&amp;gt; D[新增数据] --&amp;gt; E[修改数据] --&amp;gt; F[删除数据]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class F highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//删除前查看
mysql&amp;gt; select【涩莱克特】  * from【弗乱】moershi.user where【威尔】id &amp;lt;= 10 ;
+----+----------+----------+------+------+------------------+---------------------+----------------+
| id | name     | password | uid  | gid  | comment【坑门特】 | homedir【home-跌儿】| shell          |
+----+----------+----------+------+------+------------------+---------------------+----------------+
|  1 | root     | x        |    0 |    0 | NULL             | /student            | /bin/bash      |
|  2 | bin      | x        |    1 |    1 | NULL             | /student            | /sbin/nologin  |
|  3 | daemon   | x        |    2 |    2 | NULL             | /student            | /sbin/nologin  |
|  4 | adm      | x        |    3 |    4 | NULL             | /student            | /sbin/nologin  |
|  5 | lp       | x        |    4 |    7 | NULL             | /student            | /sbin/nologin  |
|  6 | sync     | x        |    5 |    0 | NULL             | /student            | /bin/sync      |
|  7 | shutdown | x        |    6 |    0 | NULL             | /student            | /sbin/shutdown |
|  8 | halt     | x        |    7 |    0 | NULL             | /student            | /sbin/halt     |
|  9 | mail     | x        |    8 |   12 | NULL             | /student            | /sbin/nologin  |
| 10 | operator | x        |   11 |    0 | NULL             | /student            | /sbin/nologin  |
+----+----------+----------+------+------+------------------+---------------------+----------------+
10 rows in set【赛特】 (0.00 sec)
//仅删除与条件匹配的行
mysql&amp;gt; delete【迪利特】 from【弗乱】moershi.user where【威尔】id &amp;lt;= 10 ;
Query OK, 10 rows affected (0.06 sec)
//查不到符合条件的记录了
mysql&amp;gt; select【涩莱克特】  * from【弗乱】moershi.user where【威尔】id &amp;lt;= 10 ;
Empty set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;九、作业&lt;/h2&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;employees【ing普洛伊s】&lt;/code&gt; 表中，要将查询结果按照 &lt;code&gt;hire_date&lt;/code&gt; 降序排列，应使用以下哪个关键字？B
A. &lt;code&gt;ASC【阿斯克】&lt;/code&gt;
B. &lt;code&gt;desc&lt;/code&gt;
C. &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt;
D. &lt;code&gt;HAVING【嗨夫营】&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;若要在 &lt;code&gt;departments【迪帕踢门特s】&lt;/code&gt; 表中新增一条记录，&lt;code&gt;dept_name&lt;/code&gt; 为 &apos;市场部&apos;，以下 SQL 语句正确的是？ A
A. &lt;code&gt;INSERT【因涩特】 INTO【因兔】 departments【迪帕踢门特s】 (dept_name) VALUES【挖柳斯】 (&apos;市场部&apos;);&lt;/code&gt;
B. &lt;code&gt;UPDATE【阿普 dei 特】 departments【迪帕踢门特s】 SET【赛特】 dept_name = &apos;市场部&apos;;&lt;/code&gt;
C. &lt;code&gt;DELETE【迪利特】 from【弗乱】departments【迪帕踢门特s】 where【威尔】dept_name = &apos;市场部&apos;;&lt;/code&gt;
D. &lt;code&gt;SELECT * from【弗乱】departments【迪帕踢门特s】 where【威尔】dept_name = &apos;市场部&apos;;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;salary【晒了瑞】&lt;/code&gt; 表中，要统计每个员工的总薪资（&lt;code&gt;basic【贝斯克】&lt;/code&gt; 与 &lt;code&gt;bonus【波诺斯】&lt;/code&gt; 之和），并按照总薪资降序排列，以下 SQL 语句正确的是？A
A. &lt;code&gt;SELECT employee【ing普洛伊】_id, SUM(basic【贝斯克】 + bonus【波诺斯】) AS total【偷ò头ō】_salary【晒了瑞】 from【弗乱】salary【晒了瑞】 GROUP【格鲁普】 BY employee【ing普洛伊】_id ORDER【欧朵】 BY total【偷ò头ō】_salary【晒了瑞】 desc;&lt;/code&gt;
B. &lt;code&gt;SELECT employee【ing普洛伊】_id, AVG(basic【贝斯克】 + bonus【波诺斯】) AS total【偷ò头ō】_salary【晒了瑞】 from【弗乱】salary【晒了瑞】 GROUP【格鲁普】 BY employee【ing普洛伊】_id ORDER【欧朵】 BY total【偷ò头ō】_salary【晒了瑞】 desc;&lt;/code&gt;
C. &lt;code&gt;SELECT employee【ing普洛伊】_id, SUM(basic【贝斯克】 + bonus【波诺斯】) AS total【偷ò头ō】_salary【晒了瑞】 from【弗乱】salary【晒了瑞】 ORDER【欧朵】 BY total【偷ò头ō】_salary【晒了瑞】 desc;&lt;/code&gt;
D. &lt;code&gt;SELECT employee【ing普洛伊】_id, AVG(basic【贝斯克】 + bonus【波诺斯】) AS total【偷ò头ō】_salary【晒了瑞】 from【弗乱】salary【晒了瑞】 ORDER【欧朵】 BY total【偷ò头ō】_salary【晒了瑞】 desc;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在分组查询中，&lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; 子句的作用是？B
A. 对分组前的数据进行过滤
B. 对分组后的数据进行过滤
C. 对查询结果进行排序
D. 对数据进行分组&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;要删除 &lt;code&gt;employees【ing普洛伊s】&lt;/code&gt; 表中 &lt;code&gt;employee【ing普洛伊】_id&lt;/code&gt; 为 10 的记录，以下 SQL 语句正确的是？B
A. &lt;code&gt;UPDATE【阿普 dei 特】 employees SET【赛特】 employee_id = NULL【nò】 where【威尔】employee_id = 10;&lt;/code&gt;
B. &lt;code&gt;DELETE【迪利特】 from【弗乱】employees where【威尔】employee_id = 10;&lt;/code&gt;
C. &lt;code&gt;SELECT * from【弗乱】employees where【威尔】employee_id = 10;&lt;/code&gt;
D. &lt;code&gt;INSERT【因涩特】 INTO【因兔】 employees (employee_id) VALUES【挖柳斯】 (10);&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;简述 &lt;code&gt;WHERE&lt;/code&gt; 子句和 &lt;code&gt;HAVING&lt;/code&gt; 子句的区别。
答： &lt;code&gt;WHERE&lt;/code&gt;是对分组前的原始数据行进行筛选
&lt;code&gt;HAVING&lt;/code&gt;是对分组后的组进行筛选&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;UPDATE&lt;/code&gt; 语句中，&lt;code&gt;SET&lt;/code&gt; 关键字的作用是什么？
答：&lt;code&gt;SET&lt;/code&gt; 关键字的作用是指定要修改的内容&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;新增数据时，&lt;code&gt;INSERT INTO&lt;/code&gt; 语句有哪几种常见的使用方式？
答：1、向表中插入一条完整记录。
2、向表中插入部分字段的值（未指定的字段将采用默认值或自动生成的值，如自增主键）。
3、一次性插入多条记录（批量插入）。
4、结合 SELECT语句，将查询结果插入到另一个表中。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3 操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;在 &lt;code&gt;employees&lt;/code&gt; 表中新增一条记录，&lt;code&gt;name&lt;/code&gt; 为 &apos;李四&apos;，&lt;code&gt;hire_date&lt;/code&gt; 为 &apos;2025-06-01&apos;，&lt;code&gt;birth_date&lt;/code&gt; 为 &apos;1990-05-10&apos;，&lt;code&gt;email&lt;/code&gt; 为 &apos;lisi@example.com&apos;，&lt;code&gt;phone_number&lt;/code&gt; 为 &apos;13800138000&apos;，&lt;code&gt;dept_id&lt;/code&gt; 为 2。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; insert into moershi.employees values(134,&quot;李四&quot;,&quot;2025-06-01&quot;,&quot;1990-05-10&quot;,&quot;lisi@example.com&quot;,13800138000,2);
Query OK, 1 row affected (0.19 sec)

mysql&amp;gt; select * from moershi.employees where employee_id=134;
+-------------+--------+------------+------------+------------------+--------------+---------+
| employee_id | name   | hire_date  | birth_date | email            | phone_number | dept_id |
+-------------+--------+------------+------------+------------------+--------------+---------+
|         134 | 李四   | 2025-06-01 | 1990-05-10 | lisi@example.com | 13800138000  |       2 |
+-------------+--------+------------+------------+------------------+--------------+---------+
1 row in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;将 &lt;code&gt;departments&lt;/code&gt; 表中 &lt;code&gt;dept_id&lt;/code&gt; 为 3 的 &lt;code&gt;dept_name&lt;/code&gt; 修改为 &apos;研发部&apos;。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; select * from moershi.departments where dept_id=3;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|       3 | 运维部    |
+---------+-----------+
1 row in set (0.00 sec)

mysql&amp;gt; update moershi.departments set dept_name=&quot;研发部&quot; where dept_id=3;
Query OK, 1 row affected (0.13 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql&amp;gt; select * from moershi.departments where dept_id=3;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|       3 | 研发部    |
+---------+-----------+
1 row in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;统计 &lt;code&gt;salary&lt;/code&gt; 表中每个员工的平均基本工资（&lt;code&gt;basic&lt;/code&gt; 列），只显示平均基本工资大于 5000 的员工信息，并按照平均基本工资降序排列。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; select employee_id,avg(basic) as 平均工资  from moershi.salary group by employee_id having avg(basic) &amp;gt; 5000 order by 平均工资 desc;
+-------------+--------------+
| employee_id | 平均工资     |
+-------------+--------------+
|         103 |   27023.3333 |
|          19 |   26520.0000 |
|         104 |   24251.1429 |
|         117 |   23905.0000 |
|           8 |   23741.5600 |
|          86 |   22766.9444 |
|         112 |   22766.9444 |
|          10 |   22314.9286 |
|          16 |   22314.9286 |
|         102 |   21911.2462 |
|         119 |   21628.2083 |
|         118 |   21628.2083 |
|           7 |   21628.2083 |
|         106 |   21628.2083 |
|         105 |   20490.1528 |
|         122 |   20490.1528 |
|          91 |   20311.2979 |
|          76 |   19351.5972 |
|          88 |   19351.5972 |
|           2 |   19351.5972 |
|          95 |   18213.9028 |
|          98 |   18213.9028 |
|         123 |   18213.9028 |
|          92 |   18213.9028 |
|          17 |   18213.9028 |
|         107 |   18015.6818 |
|          80 |   17644.5789 |
|           1 |   17279.1000 |
|           5 |   17125.8000 |
|         110 |   17074.6528 |
|         108 |   17074.6528 |
|          13 |   17074.6528 |
|         131 |   16653.7692 |
|         125 |   16525.1887 |
|         127 |   16427.4107 |
|          81 |   15991.9286 |
|           4 |   15936.5972 |
|           6 |   15936.5972 |
|          11 |   15936.5972 |
|          12 |   15506.8125 |
|          85 |   14798.0417 |
|          79 |   14798.0417 |
|          99 |   14798.0417 |
|          75 |   13760.0417 |
|         129 |   13659.9861 |
|          94 |   13659.9861 |
|          96 |   13659.9861 |
|         124 |   13659.9861 |
|         100 |   13659.9861 |
|           9 |   12931.4545 |
|         115 |   12521.2500 |
|          14 |   11383.2083 |
|         120 |   11044.4242 |
|          15 |   11044.4242 |
|         128 |   10337.5000 |
|          78 |   10244.4722 |
|         126 |   10244.4722 |
|          84 |   10244.4722 |
|         113 |   10244.4722 |
|         132 |   10244.4722 |
|          83 |    9106.9444 |
|         121 |    9106.9444 |
|         116 |    9106.9444 |
|           3 |    9106.9444 |
|         130 |    9106.9444 |
|          82 |    7967.6944 |
|          93 |    7967.6944 |
|         109 |    7967.6944 |
|          77 |    7967.6944 |
|          87 |    7281.6410 |
|          89 |    6829.6389 |
|         101 |    6829.6389 |
|          18 |    6829.6389 |
|          97 |    6829.6389 |
|         114 |    5690.9028 |
|         111 |    5690.9028 |
|          90 |    5690.9028 |
|         133 |    5690.9028 |
+-------------+--------------+
78 rows in set (0.01 sec)

mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;要统计 `salary` 表中每个员工的平均基本工资，并筛选出平均工资大于5000且按降序排列，可以使用以下SQL语句。其核心在于使用 `GROUP BY` 对员工分组，使用 `HAVING` 对分组后的聚合结果进行过滤。

### 🔍 查询语句及说明

完整的SQL查询语句如下：

SELECT employee_id, AVG(basic) AS avg_basic_salary
FROM salary
GROUP BY employee_id
HAVING AVG(basic) &amp;gt; 5000
ORDER BY avg_basic_salary DESC;


下面这个表格详细解释了每个子句的作用：

| SQL 子句 | 作用说明 | 备注 |
| :--- | :--- | :--- |
| `SELECT employee_id, AVG(basic) AS avg_basic_salary` | 选择员工编号和计算出的平均基本工资，并为平均工资列设置别名 `avg_basic_salary`。 | `AVG()` 是聚合函数，用于计算平均值。 |
| `FROM salary` | 指定查询的数据来源是 `salary` 表。 | - |
| `GROUP BY employee_id` | 根据 `employee_id` 进行分组。这是使用聚合函数（如`AVG`）的前提，它将数据按每个员工归类。 | 确保 `SELECT` 中非聚合列在 `GROUP BY` 中出现。 |
| `HAVING AVG(basic) &amp;gt; 5000` | 对分组（即每个员工）后的结果进行筛选，只保留平均基本工资大于5000的记录。**`HAVING` 专门用于过滤聚合函数的结果**。 | 这与在分组前过滤行的 `WHERE` 子句有本质区别。 |
| `ORDER BY avg_basic_salary DESC` | 将最终结果按照平均基本工资（别名）从高到低进行排序。 | `DESC` 表示降序，`ASC` 表示升序。 |

### 💡 关键点与技巧

- **`HAVING` 与 `WHERE` 的区别**：这是编写此类查询的关键。`WHERE` 子句在 **分组之前** 过滤原始数据行，并且其条件中不能直接使用聚合函数（如 `AVG(), COUNT()`）。`HAVING` 子句在 **分组之后** 过滤分组结果，条件通常包含聚合函数。如果你的过滤条件不涉及聚合计算（例如 `employee_id &amp;gt; 100`），则应使用 `WHERE`，这能先减少数据量，提升查询效率。

- **使用列别名**：在 `ORDER BY` 子句中，我们可以直接使用在 `SELECT` 中定义的列别名（`avg_basic_salary`），这使得语句更简洁易读。但请注意，在某些数据库系统中，`HAVING` 子句可能不支持直接使用别名，此时需要重复聚合函数（如 `HAVING AVG(basic) &amp;gt; 5000`），如示例中所示。

### 📚 扩展思考

你可以通过修改聚合函数和条件来满足不同的统计需求。例如：
- 统计每个员工的**总工资**（假设还有其他工资项）：`SELECT employee_id, SUM(basic + bonus) AS total_salary FROM salary GROUP BY employee_id HAVING SUM(basic + bonus) &amp;gt; 10000 ORDER BY total_salary DESC;`
- 先通过 `WHERE` 子句排除某些记录后再进行分组统计，例如，只统计某个月份之后的数据。
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;删除 &lt;code&gt;employees&lt;/code&gt; 表中 &lt;code&gt;dept_id&lt;/code&gt; 为 4 的所有记录。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; --查询删除前数据
mysql&amp;gt; select * from moershi.employees where dept_id=4;
+-------------+-----------+------------+------------+---------------------------+--------------+---------+
| employee_id | name      | hire_date  | birth_date | email                     | phone_number | dept_id |
+-------------+-----------+------------+------------+---------------------------+--------------+---------+
|          20 | 蒋红      | 2017-12-29 | 1978-01-24 | jianghong@tedu.cn         | 15852915398  |       4 |
|          21 | 曹宁      | 2004-06-07 | 1988-01-05 | caoning@tedu.cn           | 14513022304  |       4 |
|          22 | 吕刚      | 2014-01-18 | 1980-06-24 | lvgang@tedu.cn            | 18136987619  |       4 |
|          23 | 王莉      | 2021-02-04 | 1972-12-19 | wangli@moershi.com        | 15376329290  |       4 |
|          24 | 邓秀芳    | 2020-09-08 | 1980-12-12 | dengxiufang@moershi.com   | 15884927117  |       4 |
|          25 | 邵佳      | 2011-08-15 | 1978-11-28 | shaojia@tedu.cn           | 13296016750  |       4 |
|          26 | 党丽      | 2014-03-14 | 1978-12-30 | dangli@moershi.com        | 13166234580  |       4 |
|          27 | 梁勇      | 2007-01-19 | 1997-11-12 | liangyong@tedu.cn         | 15307868657  |       4 |
|          28 | 郑秀珍    | 2011-04-28 | 1972-09-01 | zhengxiuzhen@moershi.com  | 14543186401  |       4 |
|          29 | 胡秀云    | 2003-11-03 | 2000-05-14 | huxiuyun@tedu.cn          | 18212266720  |       4 |
|          30 | 邢淑兰    | 2011-07-02 | 1989-06-17 | xingshulan@moershi.com    | 13032270370  |       4 |
|          31 | 刘海燕    | 2018-01-06 | 1982-08-21 | liuhaiyan@moershi.com     | 15064354651  |       4 |
|          32 | 冯建国    | 2014-05-28 | 1980-01-26 | fengjianguo@tedu.cn       | 13344957322  |       4 |
|          33 | 曹杰      | 2017-01-04 | 1975-07-03 | caojie@moershi.com        | 13244741822  |       4 |
|          34 | 苗桂花    | 2001-10-06 | 1974-01-26 | miaoguihua@tedu.cn        | 18124884107  |       4 |
|          35 | 袁建平    | 2020-09-17 | 1990-07-25 | yuanjianping@moershi.com  | 13580624147  |       4 |
|          36 | 黄淑兰    | 2019-08-29 | 1988-02-08 | huangshulan@tedu.cn       | 14568738205  |       4 |
|          37 | 朱淑兰    | 2002-04-26 | 1977-12-10 | zhushulan@tedu.cn         | 13635439422  |       4 |
|          38 | 曹凯      | 2006-07-23 | 1995-11-07 | caokai@moershi.com        | 15172694474  |       4 |
|          39 | 张倩      | 2009-10-27 | 2000-04-27 | zhangqian@tedu.cn         | 15053279648  |       4 |
|          40 | 王淑珍    | 2013-09-21 | 1995-05-06 | wangshuzhen@tedu.cn       | 18583012709  |       4 |
|          41 | 陈玉      | 2011-08-20 | 1985-06-14 | chenyu@tedu.cn            | 13632957562  |       4 |
|          42 | 陈玉英    | 2020-10-03 | 1996-05-19 | chenyuying@tedu.cn        | 15100520600  |       4 |
|          43 | 王波      | 2008-06-14 | 1979-05-26 | wangbo@tedu.cn            | 15236208918  |       4 |
|          44 | 黄文      | 2010-06-05 | 1983-01-30 | huangwen@tedu.cn          | 13688719481  |       4 |
|          45 | 陈刚      | 2010-10-26 | 1978-05-10 | chengang@tedu.cn          | 13679861175  |       4 |
|          46 | 罗建华    | 2004-06-20 | 1989-02-23 | luojianhua@tedu.cn        | 13176305978  |       4 |
|          47 | 黄建平    | 2009-04-09 | 1995-07-15 | huangjianping@moershi.com | 18517722322  |       4 |
|          48 | 范秀英    | 2001-03-13 | 1996-06-01 | fanxiuying@moershi.com    | 18252125689  |       4 |
|          49 | 李平      | 2003-10-28 | 1998-07-24 | liping@tedu.cn            | 18526198243  |       4 |
|          50 | 臧龙      | 2011-10-06 | 1976-05-11 | zanglong@moershi.com      | 13474064425  |       4 |
|          51 | 吴静      | 2017-09-26 | 1983-08-04 | wujing@tedu.cn            | 14762137325  |       4 |
|          52 | 张冬梅    | 2010-10-26 | 1982-05-09 | zhangdongmei@tedu.cn      | 13690746261  |       4 |
|          53 | 邢成      | 2018-05-07 | 1991-07-13 | xingcheng@moershi.com     | 13983238261  |       4 |
|          54 | 孙丹      | 2012-01-28 | 1997-02-22 | sundan@moershi.com        | 13684254376  |       4 |
|          55 | 梁静      | 2013-03-21 | 1995-05-20 | liangjing@moershi.com     | 18077866993  |       4 |
|          56 | 陈洁      | 2006-08-17 | 1977-04-23 | chenjie@tedu.cn           | 14737309895  |       4 |
|          57 | 许辉      | 2014-09-16 | 1992-10-21 | xuhui@moershi.com         | 13143391754  |       4 |
|          58 | 张伟      | 2007-06-22 | 1999-04-30 | zhangwei@moershi.com      | 18172302428  |       4 |
|          59 | 钟倩      | 2011-02-23 | 1983-06-28 | zhongqian@moershi.com     | 18611282765  |       4 |
|          60 | 贺磊      | 2001-06-19 | 1993-02-07 | helei@tedu.cn             | 15897839325  |       4 |
|          61 | 沈秀梅    | 2003-04-27 | 1992-08-13 | shenxiumei@tedu.cn        | 18044302910  |       4 |
|          62 | 林刚      | 2007-09-19 | 1990-09-23 | lingang@tedu.cn           | 13355063263  |       4 |
|          63 | 王玉华    | 2016-10-09 | 1973-09-14 | wangyuhua@tedu.cn         | 18010485419  |       4 |
|          64 | 徐金凤    | 2015-09-09 | 1972-01-31 | xujinfeng@tedu.cn         | 15124816733  |       4 |
|          65 | 张淑英    | 2010-11-08 | 1996-09-12 | zhangshuying@moershi.com  | 18846908114  |       4 |
|          66 | 罗岩      | 2001-06-13 | 1986-10-17 | luoyan@tedu.cn            | 14544559539  |       4 |
|          67 | 潘玲      | 2017-08-31 | 1993-02-18 | panling@tedu.cn           | 13311560534  |       4 |
|          68 | 柴冬梅    | 2003-11-24 | 1976-01-01 | chaidongmei@moershi.com   | 14506733843  |       4 |
|          69 | 谢莹      | 2017-12-06 | 1996-04-01 | xieying@tedu.cn           | 15137904023  |       4 |
|          70 | 傅雪      | 2001-04-23 | 1976-09-06 | fuxue@moershi.com         | 15210059051  |       4 |
|          71 | 龙旭      | 2019-05-15 | 1974-11-02 | longxu@moershi.com        | 15155879580  |       4 |
|          72 | 赵杰      | 2004-05-08 | 1984-04-06 | zhaojie@tedu.cn           | 13466360255  |       4 |
|          73 | 王璐      | 2003-09-22 | 2000-02-01 | wanglu@moershi.com        | 13056592974  |       4 |
|          74 | 赵成      | 2012-11-30 | 1985-10-11 | zhaocheng@tedu.cn         | 18545824587  |       4 |
+-------------+-----------+------------+------------+---------------------------+--------------+---------+
55 rows in set (0.00 sec)


mysql&amp;gt; --外键约束,先删除salary表对应数据
mysql&amp;gt; delete from moershi.salary where employee_id in (select employee_id from moershi.employees where dept_id=4);
Query OK, 3308 rows affected (0.36 sec)

mysql&amp;gt; --删除employees表dept_id=4的数据
mysql&amp;gt; delete from moershi.employees where dept_id=4;
Query OK, 55 rows affected (0.22 sec)

mysql&amp;gt; --查询删除后结果
mysql&amp;gt; select * from moershi.employees where dept_id=4;
Empty set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;您在删除 `dept_id=4` 的部门记录时遇到了外键约束错误，这表明有其他表（比如 `salary` 表）的数据通过外键关联着这个部门的员工记录。下面为您梳理解决方案。

### 🔍 理解错误原因
错误信息 `Cannot delete or update a parent row: a foreign key constraint fails` 表明，由于外键约束的存在，您无法直接删除 `employees` 表中 `dept_id=4` 的记录。这通常是数据库为了维护数据一致性而设定的保护机制，防止出现“孤悬数据”（例如，工资记录对应的员工信息不存在了）。

核心问题在于，`salary` 表通过 `employee_id` 字段关联了 `employees` 表。当您尝试删除 `employees` 表中的某条员工记录时，如果 `salary` 表中还存在与之对应的工资记录，数据库就会阻止这个删除操作。

### ✅ 解决方案选择
您可以根据具体情况选择下表列出的方法来解决这个问题：

| 解决方案 | 核心操作 | 适用场景 |
| :--- | :--- | :--- |
| **先删关联数据** | 先手动删除 `salary` 表中相关的员工工资记录，再删除 `employees` 表中的员工记录。 | 希望精确控制删除范围，或数据库未设置级联删除时。 |
| **临时禁用约束** | 暂时关闭外键约束检查，执行删除操作后重新开启。 | 需要快速处理数据，且确认删除不会破坏业务逻辑；**需谨慎使用**。 |
| **设置级联删除** | 修改外键约束，设置 `ON DELETE CASCADE`。 | 希望一劳永逸，后续删除员工能自动同步删除其工资记录。 |

### ⚠️ 重要操作步骤与提醒
无论选择哪种方法，**在进行任何删除或结构修改操作前，强烈建议备份数据**。

- **方案一：先删除关联数据**
  这种方法思路直接，即先清除子表（`salary`）中的相关记录，再删除父表（`employees`）中的记录。
  ```sql
  -- 1. 首先删除 salary 表中所有属于 dept_id=4 部门的员工的工资记录
  DELETE FROM moershi.salary 
  WHERE employee_id IN (SELECT employee_id FROM moershi.employees WHERE dept_id = 4);

  -- 2. 然后再删除 employees 表中 dept_id=4 的员工记录
  DELETE FROM moershi.employees WHERE dept_id = 4;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;方案二：临时禁用外键约束&lt;/strong&gt;
此方法通过 &lt;code&gt;SET FOREIGN_KEY_CHECKS = 0;&lt;/code&gt; 临时关闭外键约束检查，操作完成后务必记得重新开启。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 临时禁用外键约束检查
SET FOREIGN_KEY_CHECKS = 0;

-- 执行删除操作
DELETE FROM moershi.employees WHERE dept_id = 4;

-- 立即重新启用外键约束检查
SET FOREIGN_KEY_CHECKS = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：这种方法会暂时破坏数据库的引用完整性，如果操作不当，可能导致数据不一致，请务必确保在可控范围内使用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;方案三：设置级联删除（长远之计）&lt;/strong&gt;
级联删除是一种“一劳永逸”的解决方案。设置后，当您删除 &lt;code&gt;employees&lt;/code&gt; 表中的某位员工时，数据库会自动删除 &lt;code&gt;salary&lt;/code&gt; 表中与之相关的所有工资记录。
首先，你需要删除原有的外键约束，然后重新添加一个带有级联删除选项的新约束。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 1. 先删除现有的外键约束（需要知道约束名称，错误信息中提示是 `emp_id_fk`）
ALTER TABLE moershi.salary DROP FOREIGN KEY emp_id_fk;

-- 2. 重新添加外键约束，并设置级联删除
ALTER TABLE moershi.salary 
ADD CONSTRAINT emp_id_fk 
FOREIGN KEY (employee_id) REFERENCES employees(employee_id) 
ON DELETE CASCADE;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;设置完成后，您再次执行 &lt;code&gt;DELETE FROM moershi.employees WHERE dept_id=4;&lt;/code&gt;，数据库就会自动处理关联的工资记录了。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;💡 决策建议与总结&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;若&lt;strong&gt;当前操作是临时的、一次性的&lt;/strong&gt;，建议使用&lt;strong&gt;方案一（先删关联数据）&lt;/strong&gt;，它最清晰、可控。&lt;/li&gt;
&lt;li&gt;若&lt;strong&gt;经常需要进行此类关联删除&lt;/strong&gt;，建议使用&lt;strong&gt;方案三（设置级联删除）&lt;/strong&gt;，一劳永逸，但务必理解其自动删除的后果。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;方案二（临时禁用约束）&lt;/strong&gt; 风险较高，通常用于数据迁移或清理等特定场景，&lt;strong&gt;日常操作请谨慎选择&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;请根据您的具体需求选择最合适的方法。如果对约束名称或具体操作步骤仍有疑问，可以随时追问。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;从 &lt;code&gt;employees&lt;/code&gt; 表中查询出所有在 2025 年入职的员工信息，并按照 &lt;code&gt;hire_date&lt;/code&gt; 升序排列。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; 
mysql&amp;gt; select * from moershi.employees where year(hire_date) = 2025 order by hire_date asc;
+-------------+--------+------------+------------+------------------+--------------+---------+
| employee_id | name   | hire_date  | birth_date | email            | phone_number | dept_id |
+-------------+--------+------------+------------+------------------+--------------+---------+
|         134 | 李四   | 2025-06-01 | 1990-05-10 | lisi@example.com | 13800138000  |       2 |
+-------------+--------+------------+------------+------------------+--------------+---------+
1 row in set (0.00 sec)

mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;要从 `employees` 表中查询出所有在 2025 年入职的员工信息并按入职日期升序排列，可以使用以下 SQL 语句：

    ```sql
    SELECT *
    FROM employees
    WHERE YEAR(hire_date) = 2025
    ORDER BY hire_date ASC;
    ```

下面是这个查询语句中各部分作用的详细说明：

| SQL 部分 | 作用说明 | 备注 |
| :--- | :--- | :--- |
| `SELECT *` | 选择所有列 | 返回员工表的所有字段信息。 |
| `FROM employees` | 指定数据来源 | 从名为 `employees` 的表中查询数据。 |
| `WHERE YEAR(hire_date) = 2025` | 筛选条件 | **`YEAR()` 函数用于从日期中提取年份**，这里限定只查询入职年份为 2025 年的记录。 |
| `ORDER BY hire_date ASC` | 排序结果 | 按照 `hire_date`（入职日期）字段进行升序排列。`ASC` 表示升序，可以省略，因为它是默认的排序方式。 |

### 💡 其他可行的日期筛选方法

除了使用 `YEAR()` 函数，你也可以考虑以下方法来实现相同的筛选目标，它们在特定场景下可能更有用：

- **使用 `BETWEEN` 指定日期范围**
  你可以明确指定入职日期的起止范围来筛选2025年的记录：
    ```sql
    SELECT *
    FROM employees
    WHERE hire_date BETWEEN &apos;2025-01-01&apos; AND &apos;2025-12-31&apos;
    ORDER BY hire_date;
    ```

- **使用 `DATE_FORMAT()` 函数**
  `DATE_FORMAT()` 函数功能强大，可以按各种格式输出日期。用它来提取年份部分进行匹配也是一种方法：
    ```sql
    SELECT *
    FROM employees
    WHERE DATE_FORMAT(hire_date, &apos;%Y&apos;) = &apos;2025&apos;
    ORDER BY hire_date;
    ```

&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>04：mysql之综合查询</title><link>https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/04-mysql%E4%B9%8B%E7%BB%BC%E5%90%88%E6%9F%A5%E8%AF%A2/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/04-mysql%E4%B9%8B%E7%BB%BC%E5%90%88%E6%9F%A5%E8%AF%A2/</guid><description>04：mysql之综合查询 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 11:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1&gt;04：mysql之综合查询&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[综合查询]
        direction LR
        A[内连接查询] --&amp;gt; B[外连接查询] --&amp;gt; C[合并查询结果] --&amp;gt; D[嵌套查询]
    end
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;在一家中型企业的人力资源管理工作里，会频繁运用 MySQL 综合查询。企业有员工表，包含员工编号、姓名、入职时间等；部门表记录着部门编号、部门名称等；薪资表存有员工编号、薪资数额、发放日期等。&lt;/p&gt;
&lt;p&gt;每到季度末，人力部门需要统计各部门员工的平均薪资。这时就会综合查询这三张表。通过员工编号关联员工表和薪资表，再通过部门编号关联员工表和部门表。筛选出本季度发放的薪资数据，按部门分组计算平均薪资。如此，就能清晰了解各部门的人力成本，为后续的预算规划、薪资调整等提供数据支撑。&lt;/p&gt;
&lt;h2&gt;二、为什么要学综合查询&lt;/h2&gt;
&lt;p&gt;在日常工作里，学会 MySQL 综合查询是非常必要的。以员工表、部门表和薪资表为例，单看一张表，能获取的信息有限。员工表只有员工基本信息，部门表只有部门情况，薪资表只有薪资数据。&lt;/p&gt;
&lt;p&gt;但当你掌握综合查询，就能将三张表关联起来。比如想知道每个部门的平均薪资，就可以通过员工表关联部门表和薪资表，快速得出结果。还能查询出不同部门入职时间早且薪资高的员工。综合查询让你从多个角度挖掘数据价值，为企业的决策提供准确依据，极大提升工作效率和质量，所以很有学习的必要。&lt;/p&gt;
&lt;h2&gt;三、内连接查询&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[综合查询]
        direction LR
        A[内连接查询] --&amp;gt; B[外连接查询] --&amp;gt; C[合并查询结果] --&amp;gt; D[嵌套查询]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class A highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;MySQL 内连接查询是一种常用的表连接方式，用于从多个表中提取相关联的数据。它分为隐式和显式内连接查询，区别在于是否包含 &lt;code&gt;inner【ing呐】 join【载(白话)】&lt;/code&gt; 关键字 。只有主表和从表中的数据都满足连接条件时才能被查询出来，不满足则会被忽略 。&lt;/p&gt;
&lt;p&gt;例如有员工表和部门表，若要查询每个员工所在部门的信息，可通过员工表中的部门 ID 与部门表中的 ID 匹配连接，获取员工姓名和部门名称等信息。内连接能确保数据准确，适用于查询具有明确关联关系的表 。&lt;/p&gt;
&lt;p&gt;使用moershi库下的3张表做今天的查询练习。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;departments【迪帕踢门特s】：部门表，存储部门信息&lt;/li&gt;
&lt;li&gt;employees【ing普洛伊s】： 员工表，存储员工信息&lt;/li&gt;
&lt;li&gt;salary【撒拉瑞】: 工资表，存储工资信息&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;三张表的关系如果图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/04-mysql%E4%B9%8B%E7%BB%BC%E5%90%88%E6%9F%A5%E8%AF%A2/file-20251117115502444.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;INNER【ing呐】 JOIN【载(白话)】 关键字详解&lt;/h3&gt;
&lt;p&gt;INNER【ing呐】 JOIN【载(白话)】是SQL中最基础且最重要的连接操作，它通过精确的匹配条件将相关的数据行连接在一起，是构建复杂查询和数据分析的基石。掌握INNER【ing呐】 JOIN【载(白话)】的正确用法对于进行有效的数据处理至关重要。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;属性&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;关键字&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;INNER【ing呐】 JOIN【载(白话)】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;中文名称&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;内连接&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;返回两个表中满足连接条件的匹配行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT【涩莱克特】 列名 FROM【弗乱】 表1 INNER【ing呐】 JOIN【载(白话)】 表2 ON【昂】 连接条件&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;返回值&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;只返回两个表中连接条件为TRUE的行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;等价写法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;可以省略INNER【ing呐】，直接写JOIN【载(白话)】&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;语法结构&lt;/h4&gt;
&lt;p&gt;基本语法结构&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT【涩莱克特】 列名列表 FROM【弗乱】 表1 INNER【ing呐】 JOIN【载(白话)】 表2 ON【昂】 表1.列名 = 表2.列名;

表1 INNER【ing呐】 JOIN【载(白话)】 表2: 是表连接 的核心部分，用于将 1 表和 2 表的数据关联起来。
作用
指定主表和从表：
1 是主表（左表）。
2 是从表（右表）。

定义连接类型：
INNER JOIN 表示内连接，只返回两个表中匹配的记录。
如果 1 表中的某条记录在 2 表中没有匹配的记录（即 employee_id 不匹配），则该记录不会出现在结果中。

配合连接条件：
通常与 ON 子句一起使用（例如 ON employees.employee_id = salary.employee_id ），以指定如何匹配两个表的记录。

ON【昂】 表1.列名 = 表2.列名: 是 连接条件，用于指定 1 表和 2 表之间的关联关系
作用
定义表之间的关联：
    它告诉数据库如何将 employees 表中的记录与 salary 表中的记录匹配起来。
    只有当 employees.employee_id 和 salary.employee_id 的值相等时，两条记录才会被关联起来。

确保数据一致性：
    通过这个条件，查询只会返回那些在 employees 表和 salary 表中都有对应 employee_id 的记录（如果是 INNER JOIN ）。
    如果是 LEFT JOIN ，则会返回 employees 表中的所有记录，即使 salary 表中没有匹配的记录（此时 salary 表的字段会显示为 NULL【nò】 ）。

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;完整语法格式&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT【涩莱克特】 [表别名1].列名, [表别名2].列名, ...
FROM【弗乱】 表1 [AS] 表别名1
INNER【ing呐】 JOIN【载(白话)】 表2 [AS] 表别名2 ON【昂】 表别名1.连接列 = 表别名2.连接列
[WHERE【威尔】 筛选条件]
[ORDER【欧朵】 BY 排序字段];
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;示例&lt;/h5&gt;
&lt;p&gt;1：基本INNER【ing呐】 JOIN【载(白话)】查询&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 查询员工及其部门信息
SELECT【涩莱克特】 e.employee【ing普洛伊】_id, e.name, d.dept_name, e.hire_date
FROM【弗乱】 employees【ing普洛伊s】 e
INNER【ing呐】 JOIN【载(白话)】 departments【迪帕踢门特s】 d ON【昂】 e.dept_id = d.dept_id;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;查询结果：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;employee【ing普洛伊】_id&lt;/th&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;dept_name&lt;/th&gt;
&lt;th&gt;hire_date&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;张三&lt;/td&gt;
&lt;td&gt;技术部&lt;/td&gt;
&lt;td&gt;2023-01-15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;李四&lt;/td&gt;
&lt;td&gt;销售部&lt;/td&gt;
&lt;td&gt;2023-03-20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;王五&lt;/td&gt;
&lt;td&gt;技术部&lt;/td&gt;
&lt;td&gt;2023-02-10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;赵六&lt;/td&gt;
&lt;td&gt;人事部&lt;/td&gt;
&lt;td&gt;2023-04-05&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;2：带WHERE【威尔】条件的INNER【ing呐】 JOIN【载(白话)】&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 只查询技术部的员工
SELECT【涩莱克特】 e.name, d.dept_name, e.hire_date
FROM【弗乱】 employees【ing普洛伊s】 e
INNER【ing呐】 JOIN【载(白话)】 departments【迪帕踢门特s】 d ON【昂】 e.dept_id = d.dept_id
WHERE【威尔】 d.dept_name = &apos;技术部&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;查询结果：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;dept_name&lt;/th&gt;
&lt;th&gt;hire_date&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;张三&lt;/td&gt;
&lt;td&gt;技术部&lt;/td&gt;
&lt;td&gt;2023-01-15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;王五&lt;/td&gt;
&lt;td&gt;技术部&lt;/td&gt;
&lt;td&gt;2023-02-10&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;3：多表INNER【ing呐】 JOIN【载(白话)】连接&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 假设有salary【撒拉瑞】表，三表连接
SELECT【涩莱克特】 e.name, d.dept_name, s.basic【贝斯克】_salary【撒拉瑞】
FROM【弗乱】 employees【ing普洛伊s】 e
INNER【ing呐】 JOIN【载(白话)】 departments【迪帕踢门特s】 d ON【昂】 e.dept_id = d.dept_id
INNER【ing呐】 JOIN【载(白话)】 salary【撒拉瑞】 s ON【昂】 e.employee【ing普洛伊】_id = s.employee【ing普洛伊】_id;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;使用场景分析&lt;/h5&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;场景&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;主从表关联&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;查询主表记录的详细信息&lt;/td&gt;
&lt;td&gt;员工表关联部门表查部门信息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;多维度分析&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;结合多个维度的数据进行统计&lt;/td&gt;
&lt;td&gt;销售数据关联产品表、客户表&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;数据验证&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;检查两个表的数据一致性&lt;/td&gt;
&lt;td&gt;验证订单表和库存表的数据匹配&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;报表生成&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;生成包含多个表数据的综合报表&lt;/td&gt;
&lt;td&gt;员工考勤关联工资计算&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h5&gt;与其他JOIN【载(白话)】类型的对比&lt;/h5&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;INNER【ing呐】 JOIN&lt;/th&gt;
&lt;th&gt;LEFT【列夫特】 JOIN【载(白话)】&lt;/th&gt;
&lt;th&gt;RIGHT【来特】 JOIN【载(白话)】&lt;/th&gt;
&lt;th&gt;FULL【fò】 JOIN【载(白话)】&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;返回结果&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;只返回匹配行&lt;/td&gt;
&lt;td&gt;左表所有行+匹配行&lt;/td&gt;
&lt;td&gt;右表所有行+匹配行&lt;/td&gt;
&lt;td&gt;左右表所有行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NULL【nò】处理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;排除不匹配行&lt;/td&gt;
&lt;td&gt;右表不匹配显示NULL【nò】&lt;/td&gt;
&lt;td&gt;左表不匹配显示NULL【nò】&lt;/td&gt;
&lt;td&gt;不匹配都显示NULL【nò】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;使用频率&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐&lt;/td&gt;
&lt;td&gt;⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;性能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;通常最优&lt;/td&gt;
&lt;td&gt;中等&lt;/td&gt;
&lt;td&gt;中等&lt;/td&gt;
&lt;td&gt;较差&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;最佳实践指南&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;使用表别名提高可读性&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;-- 推荐写法
SELECT【涩莱克特】 emp.name, dept.dept_name
FROM【弗乱】 employees【ing普洛伊s】 emp
INNER【ing呐】 JOIN【载(白话)】 departments【迪帕踢门特s】 dept ON【昂】 emp.dept_id = dept.dept_id;

-- 不推荐写法
SELECT【涩莱克特】 employees【ing普洛伊s】.name, departments【迪帕踢门特s】.dept_name
FROM【弗乱】 employees【ing普洛伊s】
INNER【ing呐】 JOIN【载(白话)】 departments【迪帕踢门特s】 ON【昂】 employees【ing普洛伊s】.dept_id = departments【迪帕踢门特s】.dept_id;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;明确指定列所属表&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;-- 避免列名歧义
SELECT【涩莱克特】 e.employee【ing普洛伊】_id, e.name, d.dept_name
FROM【弗乱】 employees【ing普洛伊s】 e
INNER【ing呐】 JOIN【载(白话)】 departments【迪帕踢门特s】 d ON【昂】 e.dept_id = d.dept_id;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;合理使用索引优化性能&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;-- 确保连接列有索引
CREATE INDEX idx_employees【ing普洛伊s】_dept_id ON【昂】 employees【ing普洛伊s】(dept_id);
CREATE INDEX idx_departments【迪帕踢门特s】_dept_id ON【昂】 departments【迪帕踢门特s】(dept_id);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.1 等值连接查询&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;查询每个员工所在的部门名&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;Use  moershi;
select【涩莱克特】 name, dept_name  
from【弗乱】 employees【ing普洛伊s】 inner【ing呐】 join【载(白话)】 departments【迪帕踢门特s】  on【昂】 employees【ing普洛伊s】.dept_id=departments【迪帕踢门特s】.dept_id;

-- mysql&amp;gt; select name,dept_name 
--     -&amp;gt; from employees inner join departments on employees.dept_id=departments.dept_id;
-- 
-- | name      | dept_name |
-- |-----------|-----------|
-- | 梁伟      | 人事部    |
-- | 郭岩      | 人事部    |
-- | 李玉英    | 人事部    |
-- | 张健      | 人事部    |
-- | 郑静      | 人事部    |
-- | 牛建军    | 人事部    |
-- | 刘斌      | 人事部    |
-- | 汪云      | 人事部    |
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）查询员工编号8 的 员工所在部门的部门名称&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】  name, dept_name  from【弗乱】 employees【ing普洛伊s】  inner【ing呐】 join【载(白话)】 departments【迪帕踢门特s】 
on【昂】 employees【ing普洛伊s】.dept_id=departments【迪帕踢门特s】.dept_id  where【威尔】  employees【ing普洛伊s】.employee【ing普洛伊】_id=8;

-- mysql&amp;gt; select name,dept_name from employees inner join departments on employees.dept_id=departments.dept_id where employees.employee_id=8;
-- +--------+-----------+
-- | name   | dept_name |
-- +--------+-----------+
-- | 汪云   | 人事部    |
-- +--------+-----------+
-- 1 row in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;别名规则&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;字段名&lt;/th&gt;
&lt;th&gt;是否必须加别名 &lt;code&gt;e.&lt;/code&gt; 或 &lt;code&gt;d.&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;原因说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;dept_id&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;必须&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;因为 &lt;code&gt;employees&lt;/code&gt; 和 &lt;code&gt;departments&lt;/code&gt; 两个表&lt;strong&gt;都有&lt;/strong&gt;名为 &lt;code&gt;dept_id&lt;/code&gt; 的字段，MySQL 无法自动判断您想用的是哪一个。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;name&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;不需要&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;因为只有 &lt;code&gt;employees&lt;/code&gt; 表中有 &lt;code&gt;name&lt;/code&gt; 字段，&lt;code&gt;departments&lt;/code&gt; 表中没有这个字段，MySQL 可以&lt;strong&gt;唯一确定&lt;/strong&gt;它来自哪里。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;如果&lt;strong&gt;字段名&lt;/strong&gt;在多个表中同时存在，必须带上别名才可以识别你要查询的&lt;strong&gt;字段名&lt;/strong&gt;是那个表的&lt;strong&gt;字段名&lt;/strong&gt;
如果&lt;strong&gt;字段名&lt;/strong&gt;只在其中一个表存在，这就具有唯一性，sql可以明确识别&lt;strong&gt;字段名&lt;/strong&gt;在那个表，就不需要带上别名&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;3）查询每个员工所有信息及所在的部门名称&lt;/p&gt;
&lt;p&gt;给表名定义别名 ，定义别名后必须使用别名表示表名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】 e.* , d.dept_name
from【弗乱】 employees【ing普洛伊s】 as e inner【ing呐】 join【载(白话)】 departments【迪帕踢门特s】 as d on【昂】 e.dept_id=d.dept_id;

-- mysql&amp;gt; select e.*,d.dept_name from employees as e inner join departments as d on e.dept_id=d.dept_id limit 5;#结果太多，加上&quot;limit 5&quot; 只输出前5行
-- +-------------+-----------+------------+------------+-----------------------+--------------+---------+-----------+
-- | employee_id | name      | hire_date  | birth_date | email                 | phone_number | dept_id | dept_name |
-- +-------------+-----------+------------+------------+-----------------------+--------------+---------+-----------+
-- |           1 | 梁伟      | 2018-06-21 | 1971-08-19 | liangwei@tedu.cn      | 13591491431  |       1 | 人事部    |
-- |           2 | 郭岩      | 2010-03-21 | 1974-05-13 | guoyan@tedu.cn        | 13845285867  |       1 | 人事部    |
-- |           3 | 李玉英    | 2012-01-19 | 1974-01-25 | liyuying@tedu.cn      | 15628557234  |       1 | 人事部    |
-- |           4 | 张健      | 2008-09-17 | 1972-06-07 | zhangjian@moershi.com | 13835990213  |       1 | 人事部    |
-- |           5 | 郑静      | 2018-02-03 | 1997-02-14 | zhengjing@tedu.cn     | 14508936730  |       1 | 人事部    |
-- +-------------+-----------+------------+------------+-----------------------+--------------+---------+-----------+
-- 5 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4）查询每个员工姓名、部门编号、部门名称&lt;/p&gt;
&lt;p&gt;两个表有同名表头，表头名前必须加表名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】 e.dept_id , name , dept_name  from【弗乱】   employees【ing普洛伊s】 as e  inner【ing呐】 join【载(白话)】 departments【迪帕踢门特s】 as d on【昂】  e.dept_id=d.dept_id;

-- mysql&amp;gt; select e.dept_id,name,dept_name from employees as e inner join departments as d on e.dept_id=d.dept_id limit 5;#结果太多，加上&quot;limit 5&quot; 只输出前5行
-- +---------+-----------+-----------+
-- | dept_id | name      | dept_name |
-- +---------+-----------+-----------+
-- |       1 | 梁伟      | 人事部    |
-- |       1 | 郭岩      | 人事部    |
-- |       1 | 李玉英    | 人事部    |
-- |       1 | 张健      | 人事部    |
-- |       1 | 郑静      | 人事部    |
-- +---------+-----------+-----------+
-- 5 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 对连接后的查询结果，筛选、分组、排序、过滤&lt;/h3&gt;
&lt;p&gt;1）查询11号员工的名字及2018年每个月总工资&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】   e.employee【ing普洛伊】_id,  name, date, basic【贝斯克】+bonus【波诺斯】 as total【偷ò头ō】 
from【弗乱】 employees【ing普洛伊s】 as e   inner【ing呐】 join【载(白话)】 salary【撒拉瑞】 as s 
on【昂】 e.employee【ing普洛伊】_id=s.employee【ing普洛伊】_id
where【威尔】 year【耶尔】(date)=2018 and e.employee【ing普洛伊】_id=11;
-- mysql&amp;gt; 
-- mysql&amp;gt; select e.employee_id,name,date,basic+bonus as total
--     -&amp;gt; from employees as e inner join salary as s on e.employee_id=s.employee_id
--     -&amp;gt; where year(date)=2018 and e.employee_id=11;
-- +-------------+-----------+------------+-------+
-- | employee_id | name      | date       | total |
-- +-------------+-----------+------------+-------+
-- |          11 | 郭兰英    | 2018-01-10 | 18206 |
-- |          11 | 郭兰英    | 2018-02-10 | 19206 |
-- |          11 | 郭兰英    | 2018-03-10 | 18206 |
-- |          11 | 郭兰英    | 2018-04-10 | 19206 |
-- |          11 | 郭兰英    | 2018-05-10 | 18206 |
-- |          11 | 郭兰英    | 2018-06-10 | 19206 |
-- |          11 | 郭兰英    | 2018-07-10 | 27206 |
-- |          11 | 郭兰英    | 2018-08-10 | 27206 |
-- |          11 | 郭兰英    | 2018-09-10 | 19206 |
-- |          11 | 郭兰英    | 2018-10-10 | 21206 |
-- |          11 | 郭兰英    | 2018-11-10 | 22206 |
-- |          11 | 郭兰英    | 2018-12-10 | 25016 |
-- +-------------+-----------+------------+-------+
-- 12 rows in set (0.00 sec)
-- mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2） 查询每个员工2018年的总工资&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    #没分组前
select【涩莱克特】 employees【ing普洛伊s】.employee【ing普洛伊】_id,date,basic【贝斯克】,bonus【波诺斯】  from【弗乱】 employees【ing普洛伊s】 inner【ing呐】 join【载(白话)】 salary【撒拉瑞】
on【昂】 employees【ing普洛伊s】.employee【ing普洛伊】_id=salary【撒拉瑞】【撒拉瑞】.employee【ing普洛伊】_id  where【威尔】  year【耶尔】(date)=2018;
-- mysql&amp;gt; select employees.employee_id,date,basic,bonus 
--     -&amp;gt; from employees inner join salary
--     -&amp;gt; on employees.employee_id=salary.employee_id
--     -&amp;gt; where year(date)=2018;
-- +-------------+------------+-------+-------+
-- | employee_id | date       | basic | bonus |
-- +-------------+------------+-------+-------+
-- |           1 | 2018-07-10 | 16206 | 11000 |
-- |           1 | 2018-08-10 | 16206 |  8000 |
-- |           1 | 2018-09-10 | 16206 |  8000 |
-- |           1 | 2018-10-10 | 16206 | 11000 |
-- |           1 | 2018-11-10 | 16206 |  8000 |
-- ...............
-- mysql&amp;gt;   
    # 分组后
select【涩莱克特】 employees【ing普洛伊s】.employee【ing普洛伊】_id, sum【桑à姆】(basic【贝斯克】+bonus【波诺斯】) from【弗乱】 employees【ing普洛伊s】 inner【ing呐】 join【载(白话)】 salary【撒拉瑞】
on【昂】 employees【ing普洛伊s】.employee【ing普洛伊】_id=salary【撒拉瑞】.employee【ing普洛伊】_id  
where【威尔】 year【耶尔】(date)=2018    group【格鲁普】 by employees【ing普洛伊s】.employee【ing普洛伊】_id;

-- mysql&amp;gt; 
-- mysql&amp;gt; select employees.employee_id,sum(basic+bonus)
--     -&amp;gt; from employees inner join salary
--     -&amp;gt; on employees.employee_id=salary.employee_id
--     -&amp;gt; where year(date)=2018      --过滤只输出2018年的数据
--     -&amp;gt; group by employees.employee_id;     --查询结果以employees.employee_id分组
-- +-------------+------------------+
-- | employee_id | sum(basic+bonus) |
-- +-------------+------------------+
-- |           1 |           151046 |
-- |           2 |           328131 |
-- |           3 |           177595 |
-- |           4 |           262282 |
-- |           5 |           248076 |
-- |           6 |           257282 |
-- |           7 |           314027 |
-- ...............
-- mysql&amp;gt;   
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3）查询每个员工2018年的总工资，按总工资升序排列&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】 employees【ing普洛伊s】.employee【ing普洛伊】_id, sum【桑à姆】(basic【贝斯克】+bonus【波诺斯】) as total【偷ò头ō】  
 from【弗乱】 employees【ing普洛伊s】 inner【ing呐】 join【载(白话)】 salary【撒拉瑞】 on【昂】 employees【ing普洛伊s】.employee【ing普洛伊】_id=salary【撒拉瑞】.employee【ing普洛伊】_id 
 where【威尔】 year【耶尔】(salary【撒拉瑞】.date)=2018 group【格鲁普】 by employee【ing普洛伊】_id order【欧朵】 by total【偷ò头ō】 asc【阿斯克】;

-- mysql&amp;gt; 
-- mysql&amp;gt; select employees.employee_id,sum(basic+bonus) as total  
--     -&amp;gt; from employees inner join salary on employees.employee_id=salary.employee_id
--     -&amp;gt; where year(salary.date)=2018     --过滤只输出2018年的数据
--     -&amp;gt; group by employee_id     --查询结果以employee_id分组
--     -&amp;gt; order by total asc;    --查询结果以升序排序
-- +-------------+--------+
-- | employee_id | total  |
-- +-------------+--------+
-- |           8 |  25093 |
-- |          10 | 116389 |
-- |          16 | 119389 |
-- |          51 | 123733 |
-- |          18 | 126687 |
-- .........
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4）查询2018年总工资大于30万的员工，按2018年总工资降序排列&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】 employees【ing普洛伊s】.employee【ing普洛伊】_id, sum【桑à姆】(basic【贝斯克】+bonus【波诺斯】) as total【偷ò头ō】  
from【弗乱】 employees【ing普洛伊s】 inner【ing呐】 join【载(白话)】 salary【撒拉瑞】 on【昂】 employees【ing普洛伊s】.employee【ing普洛伊】_id=salary【撒拉瑞】.employee【ing普洛伊】_id   
where【威尔】 year【耶尔】(salary【撒拉瑞】.date)=2018 
group【格鲁普】 by employees【ing普洛伊s】.employee【ing普洛伊】_id 
having【嗨夫营】 total【偷ò头ō】 &amp;gt; 300000
order【欧朵】 by  total【偷ò头ō】 desc;
-- mysql&amp;gt; 
-- mysql&amp;gt; select employees.employee_id,sum(basic+bonus) as total
--     -&amp;gt; from employees inner join salary on employees.employee_id=salary.employee_id
--     -&amp;gt; where year(salary.date)=2018 
--     -&amp;gt; group by employees.employee_id
--     -&amp;gt; having total &amp;gt; 300000
--     -&amp;gt; order by total desc;
-- +-------------+--------+
-- | employee_id | total  |
-- +-------------+--------+
-- |         117 | 374923 |
-- |          31 | 374923 |
-- |          37 | 362981 |
-- |          68 | 360923 |
-- |          48 | 359923 |
-- ......
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、外连接查询&lt;/h2&gt;
&lt;p&gt;当前任何环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[综合查询]
        direction LR
        A[内连接查询] --&amp;gt; B[外连接查询] --&amp;gt; C[合并查询结果] --&amp;gt; D[嵌套查询]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class B highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;MySQL 外连接查询是一种在多个表间获取数据的重要方式，它主要分为左外连接、右外连接和全外连接。&lt;/p&gt;
&lt;h3&gt;外连接类型对比&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;连接类型&lt;/th&gt;
&lt;th&gt;关键字&lt;/th&gt;
&lt;th&gt;返回结果&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;左外连接&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LEFT【列夫特】 JOIN【载(白话)】&lt;/code&gt; 或 &lt;code&gt;LEFT【列夫特】 OUTER【奥特尔】 JOIN【载(白话)】&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;左表所有记录 + 右表匹配记录&lt;/td&gt;
&lt;td&gt;主表记录必须全部保留，关联表信息可选&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;右外连接&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;RIGHT【来特】 JOIN【载(白话)】&lt;/code&gt; 或 &lt;code&gt;RIGHT【来特】 OUTER【奥特尔】 JOIN【载(白话)】&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;右表所有记录 + 左表匹配记录&lt;/td&gt;
&lt;td&gt;从表记录必须全部保留，主表信息可选&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;全外连接&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FULL【fò】 JOIN【载(白话)】&lt;/code&gt; 或 &lt;code&gt;FULL【fò】 OUTER【奥特尔】 JOIN【载(白话)】&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;左右表所有记录&lt;/td&gt;
&lt;td&gt;需要两个表的完整数据合并&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;外连接是SQL查询中非常重要的功能，特别适用于：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需要保留主表所有记录的查询&lt;/li&gt;
&lt;li&gt;数据完整性检查（查找缺失的关联数据）&lt;/li&gt;
&lt;li&gt;生成完整的报表和统计分析&lt;/li&gt;
&lt;li&gt;处理可能存在NULL【nò】关联关系的业务场景&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;左外连接会返回左表中的所有记录，以及右表中匹配的记录，若右表无匹配项，对应字段会显示为 NULL【nò】。右外连接则相反，返回右表所有记录与左表匹配记录。全外连接会返回左右表的所有记录，无匹配项的字段同样显示为 NULL【nò】。&lt;/p&gt;
&lt;p&gt;例如员工表和部门表，用左外连接查询时，即便有员工未分配部门，该员工信息也会显示出来。外连接能满足在关联表查询时，不遗漏某表记录的需求。&lt;/p&gt;
&lt;h3&gt;4.1 左连接查询&lt;/h3&gt;
&lt;p&gt;向departments【迪帕踢门特s】表里添加3个部门:小卖部 行政部 公关部&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; insert【因涩特】 into【因兔】 departments【迪帕踢门特s】(dept_name) values【挖柳斯】(&quot;小卖部&quot;),(&quot;行政部&quot;),(&quot;公关部&quot;);
Query OK, 3 rows affected (0.06 sec)
Records: 3  Duplicates: 0  Warnings: 0

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查询部门信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】  * from【弗乱】 moershi.departments【迪帕踢门特s】;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|       1 | 人事部    |
|       2 | 财务部    |
|       3 | 运维部    |
|       4 | 开发部    |
|       5 | 测试部    |
|       6 | 市场部    |
|       7 | 销售部    |
|       8 | 法务部    |
|       9 | 小卖部    |
|      10 | 行政部    |
|      11 | 公关部    |
+---------+-----------+
11 rows in set (0.00 sec)
mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;左连接查询例子：输出没有员工的部门名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 d.dept_name,e.name from【弗乱】 departments【迪帕踢门特s】 as d  left【列夫特】  join【载(白话)】 employees【ing普洛伊s】 as e on【昂】 d.dept_id=e.dept_id;
...
...
| 法务部    | 王荣      |
| 法务部    | 刘倩      |
| 法务部    | 杨金凤    |
| 小卖部    | NULL      |
| 行政部    | NULL      |
| 公关部    | NULL      |
+-----------+-----------+
136 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;连接后 输出与筛选条件匹配的行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】 d.dept_name,e.name from【弗乱】 departments【迪帕踢门特s】 as d  left【列夫特】  join【载(白话)】 employees【ing普洛伊s】 as e on【昂】 d.dept_id=e.dept_id where【威尔】 e.name is null【nò】;
+-----------+------+
| dept_name | name |
+-----------+------+
| 小卖部    | NULL |
| 行政部    | NULL |
| 公关部    | NULL |
+-----------+------+
3 rows in set (0.01 sec)
mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;仅显示departments【迪帕踢门特s】表中dept_name表头&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】 d.dept_name from【弗乱】 departments【迪帕踢门特s】 as d  left【列夫特】  join【载(白话)】 employees【ing普洛伊s】 as e on【昂】 d.dept_id=e.dept_id where【威尔】 e.name is null【nò】;
+-----------+
| dept_name |
+-----------+
| 小卖部     |
| 行政部     | 
| 公关部     | 
+-----------+
3 rows in set (0.01 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 右连接查询&lt;/h3&gt;
&lt;p&gt;向employees【ing普洛伊s】表中添加3个员工 只给name表头赋值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;insert【因涩特】  into【因兔】  employees【ing普洛伊s】(name) values【挖柳斯】(&quot;bob&quot;),(&quot;tom&quot;),(&quot;lily&quot;);
Query OK, 3 rows affected (0.05 sec)
Records: 3  Duplicates: 0  Warnings: 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;右连接查询例子：显示没有部门的员工名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//右连接查询
select【涩莱克特】 e.name ,d.dept_name from【弗乱】 departments【迪帕踢门特s】 as d  right【来特】  join【载(白话)】 employees【ing普洛伊s】 as e on【昂】 d.dept_id=e.dept_id;
//加筛选条件
select【涩莱克特】 e.name ,d.dept_name from【弗乱】 departments【迪帕踢门特s】 as d  right【来特】  join【载(白话)】 employees【ing普洛伊s】 as e on【昂】 d.dept_id=e.dept_id where【威尔】 d.dept_name is null【nò】 ;
+------+-----------+
| name | dept_name |
+------+-----------+
| bob  | NULL      |
| tom  | NULL      |
| lily | NULL      |
+------+-----------+
3 rows in set (0.00 sec)
mysql&amp;gt; 
//仅显示员工名
select【涩莱克特】 e.name from【弗乱】 departments【迪帕踢门特s】 as d  right【来特】  join【载(白话)】 employees【ing普洛伊s】 as e on【昂】 d.dept_id=e.dept_id where【威尔】 d.dept_name is null【nò】 ;
+------+
| name |
+------+
| bob  | 
| tom  |
| lily |
+------+
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、合并查询结果&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[综合查询]
        direction LR
        A[内连接查询] --&amp;gt; B[外连接查询] --&amp;gt; C[合并查询结果] --&amp;gt; D[嵌套查询]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class C highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在 MySQL 综合查询里，合并查询是一种实用的操作。它主要用于将多个查询结果合并成一个结果集，使用的关键字是 &lt;code&gt;UNION【U凝】&lt;/code&gt; 和 &lt;code&gt;UNION【U凝】 ALL【ò】&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;UNION【U凝】&lt;/code&gt; 会去除合并结果里的重复记录，只保留一条。比如，你分别从员工表查询出薪资大于 8000 的员工，和从另一筛选条件查出的员工，用 &lt;code&gt;UNION【U凝】&lt;/code&gt; 合并后，相同员工就只显示一次。而 &lt;code&gt;UNION【U凝】 ALL【ò】&lt;/code&gt; 不会去重，会把所有查询结果直接合并。当你需要查看所有相关数据，不在意重复时，就用 &lt;code&gt;UNION【U凝】 ALL【ò】&lt;/code&gt;。合并查询让你能灵活整合不同查询的数据。&lt;/p&gt;
&lt;h3&gt;基本概念对比&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;UNION【U凝】&lt;/th&gt;
&lt;th&gt;UNION【U凝】 ALL【ò】&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;去重处理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;自动去除重复行&lt;/td&gt;
&lt;td&gt;保留所有行，包括重复行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;性能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;较慢（需要排序和去重）&lt;/td&gt;
&lt;td&gt;较快（直接合并）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;结果排序&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;默认按第一列升序排列&lt;/td&gt;
&lt;td&gt;不保证顺序&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT【涩莱克特】 ... UNION【U凝】 SELECT【涩莱克特】 ...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT【涩莱克特】 ... UNION【U凝】 ALL【ò】 SELECT【涩莱克特】 ...&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;使用场景&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;需要唯一结果时&lt;/td&gt;
&lt;td&gt;需要完整数据或已知无重复时&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;----------&lt;/td&gt;
&lt;td&gt;---------------&lt;/td&gt;
&lt;td&gt;-------------------&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;去重能力&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ 自动去重&lt;/td&gt;
&lt;td&gt;❌ 保留重复&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;执行性能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⭐⭐ 较慢&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐ 较快&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;内存消耗&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;较高&lt;/td&gt;
&lt;td&gt;较低&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;结果顺序&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;默认排序&lt;/td&gt;
&lt;td&gt;不保证顺序&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;使用频率&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⭐⭐⭐ 常用&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐⭐ 更常用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;适用场景&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;需要唯一结果&lt;/td&gt;
&lt;td&gt;完整数据或性能优先&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;关键要点总结&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;UNION【U凝】 ALL【ò】 通常比 UNION【U凝】 性能更好&lt;/strong&gt;，因为它不需要去重操作&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;只有需要去除重复记录时才使用 UNION【U凝】&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;确保所有SELECT【涩莱克特】语句的列数、数据类型和顺序一致&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UNION【U凝】 ALL【ò】 保留所有记录，包括重复项&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在合并大量数据时，UNION【U凝】 ALL【ò】 是更优选择&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;基本语法格式&lt;/h3&gt;
&lt;p&gt;UNION【U凝】 语法&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT【涩莱克特】 列名1, 列名2, ...
FROM【弗乱】 表1
WHERE【威尔】 条件
UNION【U凝】
SELECT【涩莱克特】 列名1, 列名2, ...
FROM【弗乱】 表2
WHERE【威尔】 条件;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;UNION 【U凝】ALL【ò】 语法&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT【涩莱克特】 列名1, 列名2, ...
FROM【弗乱】 表1
WHERE【威尔】 条件
UNION【U凝】 ALL【ò】
SELECT【涩莱克特】 列名1, 列名2, ...
FROM【弗乱】 表2
WHERE【威尔】 条件;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;性能对比分析&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作步骤&lt;/th&gt;
&lt;th&gt;UNION【U凝】&lt;/th&gt;
&lt;th&gt;UNION【U凝】 ALL【ò】&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;数据读取&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;读取所有数据&lt;/td&gt;
&lt;td&gt;读取所有数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;排序处理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;对结果进行排序&lt;/td&gt;
&lt;td&gt;不需要排序&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;去重操作&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;比较并去除重复行&lt;/td&gt;
&lt;td&gt;保留所有行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;内存使用&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;较高&lt;/td&gt;
&lt;td&gt;较低&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;执行时间&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;较长&lt;/td&gt;
&lt;td&gt;较短&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;实际示例演示&lt;/h3&gt;
&lt;p&gt;输出2018年基本工资的最大值和最小值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; ( select【涩莱克特】 basic【贝斯克】  from【弗乱】 salary【撒拉瑞】 where【威尔】 year【耶尔】(date)=2018 order【欧朵】 by  basic【贝斯克】  desc limit 1) union【U凝】 (select【涩莱克特】 basic【贝斯克】  from【弗乱】 salary【撒拉瑞】 where【威尔】 year【耶尔】(date)=2018 order【欧朵】 by  basic【贝斯克】 asc【阿斯克】 limit【肋梅特】 1 );
-- mysql&amp;gt; (select basic from salary where year(date)=2018 order by basic desc limit 1)
--     -&amp;gt; union
--     -&amp;gt; (select basic from salary where year(date)=2018 order by basic asc limit 1);
-- +----------------+
-- | basic【贝斯克】 |
-- +----------------+
-- | 25524          |
-- |  5787          |
-- +----------------+
-- 2 rows in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出2018年1月10号 基本工资的最大值和最小值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; (select【涩莱克特】 date , max【mà 斯】(basic【贝斯克】) as 工资 from【弗乱】 salary【撒拉瑞】 where【威尔】 date=20180110) union【U凝】(select【涩莱克特】 date,min【敏ì】(basic【贝斯克】) from【弗乱】 salary【撒拉瑞】 where【威尔】 date=20180110);

-- mysql&amp;gt; (select date,max(basic) as 工资 from salary where date=20180110)
--     -&amp;gt; union
--     -&amp;gt; (select date,min(basic) from salary where date=20180110);
-- +------------+--------+
-- | date       | 工资   |
-- +------------+--------+
-- | 2018-01-10 |  24309 |
-- | 2018-01-10 |   5787 |
-- +------------+--------+
-- 2 rows in set (0.01 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;union【U凝】 去掉查询结果中重复的行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; (select【涩莱克特】 employee【ing普洛伊】_id , name , birth【波尔斯】_date from【弗乱】 employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id &amp;lt;= 5) union【U凝】 (select【涩莱克特】 employee【ing普洛伊】_id , name , birth【波尔斯】_date from【弗乱】 employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id &amp;lt;= 6);
-- mysql&amp;gt; (select employee_id,name,birth_date from employees where employee_id &amp;lt;=5)
--     -&amp;gt; union
--     -&amp;gt; (select employee_id,name,birth_date from employees where employee_id &amp;lt;=6);
+-------------------------+-----------+------------+
| employee【ing普洛伊】_id | name      | birth_date |
+-------------------------+-----------+------------+
|           1            | 梁伟      | 1971-08-19 |
|           2            | 郭岩      | 1974-05-13 |
|           3            | 李玉英    | 1974-01-25 |
|           4            | 张健      | 1972-06-07 |
|           5            | 郑静      | 1997-02-14 |
|           6            | 牛建军    | 1985-03-19 |
+------------------------+-----------+------------+
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第二个查询只输出了与条件匹配的最后1行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; (select【涩莱克特】 employee【ing普洛伊】_id , name , birth【波尔斯】_date from【弗乱】 employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id &amp;lt;= 5) union【U凝】  (select【涩莱克特】 employee【ing普洛伊】_id , name , birth【波尔斯】_date from【弗乱】 employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id &amp;lt;= 6);
-- mysql&amp;gt; (select employee_id,name,birth_date from employees where employee_id &amp;lt;=5)
--     -&amp;gt; union
--     -&amp;gt; (select employee_id,name,birth_date from employees where employee_id &amp;lt;=6);
+------------------------+-----------+-------------+
| employee【ing普洛伊】_id | name      | birth【波尔斯】_date |
+------------------------+-----------+-------------+
|           1             | 梁伟      | 1971-08-19 |
|           2             | 郭岩      | 1974-05-13 |
|           3             | 李玉英    | 1974-01-25 |
|           4             | 张健      | 1972-06-07 |
|           5             | 郑静      | 1997-02-14 |
|           6             | 牛建军    | 1985-03-19 |
+------------------------+-----------+-------------+
6 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;union【U凝】 all 不去重显示查询结果&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; (select【涩莱克特】 employee【ing普洛伊】_id , name , birth【波尔斯】_date from【弗乱】 employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id &amp;lt;= 5) union【U凝】 all【ò】  (select【涩莱克特】 employee【ing普洛伊】_id , name , birth【波尔斯】_date from【弗乱】 employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id &amp;lt;= 6);
-- mysql&amp;gt; (select employee_id,name,birth_date from employees where employee_id &amp;lt;=5)
--     -&amp;gt; union all
--     -&amp;gt; (select employee_id,name,birth_date from employees where employee_id &amp;lt;=6);
+-------------+-----------+------------+
| employee_id | name      | birth_date |
+-------------+-----------+------------+
|           1 | 梁伟      | 1971-08-19 |
|           2 | 郭岩      | 1974-05-13 |
|           3 | 李玉英    | 1974-01-25 |
|           4 | 张健      | 1972-06-07 |
|           5 | 郑静      | 1997-02-14 |
|           1 | 梁伟      | 1971-08-19 |
|           2 | 郭岩      | 1974-05-13 |
|           3 | 李玉英    | 1974-01-25 |
|           4 | 张健      | 1972-06-07 |
|           5 | 郑静      | 1997-02-14 |
|           6 | 牛建军    | 1985-03-19 |
+-------------+-----------+------------+
11 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、嵌套查询&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[综合查询]
        direction LR
        A[内连接查询] --&amp;gt; B[外连接查询] --&amp;gt; C[合并查询结果] --&amp;gt; D[嵌套查询]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class D highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;嵌套查询：是指在一个完整的查询语句之中，包含若干个不同功能的小查询；从而一起完成复杂查询的一种编写形式。包含的查询放在（）里 ， 包含的查询出现的位置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SELECT【涩莱克特】之后&lt;/li&gt;
&lt;li&gt;FROM【弗乱】之后&lt;/li&gt;
&lt;li&gt;WHERE【威尔】&lt;/li&gt;
&lt;li&gt;HAVING【嗨夫营】之后&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;嵌套查询的作用&lt;/h3&gt;
&lt;h4&gt;1. &lt;strong&gt;数据筛选与过滤&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;在主查询中使用子查询的结果作为筛选条件&lt;/li&gt;
&lt;li&gt;实现复杂的多条件数据过滤&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;2. &lt;strong&gt;数据比较与计算&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;将子查询结果与主查询数据进行对比&lt;/li&gt;
&lt;li&gt;计算相对值、百分比等复杂指标&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;3. &lt;strong&gt;数据存在性检查&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;检查某条记录是否存在于另一个表中&lt;/li&gt;
&lt;li&gt;验证数据的完整性&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;4. &lt;strong&gt;数据聚合与统计&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;在子查询中进行分组统计&lt;/li&gt;
&lt;li&gt;将统计结果用于主查询的条件判断&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;嵌套查询的优势&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;逻辑清晰&lt;/strong&gt;：将复杂问题分解为多个简单步骤&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;灵活性高&lt;/strong&gt;：可以处理各种复杂的数据关系&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可读性强&lt;/strong&gt;：SQL语句结构清晰，易于理解&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;功能强大&lt;/strong&gt;：支持多层嵌套，解决复杂业务逻辑&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;注意事项&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;性能考虑&lt;/strong&gt;：多层嵌套可能影响查询性能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可维护性&lt;/strong&gt;：过度嵌套会使SQL难以维护&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;替代方案&lt;/strong&gt;：考虑使用JOIN或CTE（公共表表达式）作为替代方案&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;6.1 where【威尔】之后嵌套查询&lt;/h3&gt;
&lt;p&gt;1）查询运维部所有员工信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#先把 运维部的id 找到
mysql&amp;gt; select【涩莱克特】 dept_id from【弗乱】 departments【迪帕踢门特s】 where【威尔】 dept_name=&quot;运维部&quot;;
-- mysql&amp;gt; select dept_id from departments where dept_name=&quot;运维部&quot;;
+---------+
| dept_id |
+---------+
|       3 |
+---------+
1 row in set (0.00 sec)
#员工表里没有部门名称 但有部门编号 （和部门表的编号是一致的）
mysql&amp;gt; select【涩莱克特】  *  from【弗乱】  employees【ing普洛伊s】 where【威尔】  dept_id = (select【涩莱克特】 dept_id from【弗乱】 departments【迪帕踢门特s】 where【威尔】 dept_name=&quot;运维部&quot;);
-- mysql&amp;gt; select * from employees where dept_id=(select dept_id from departments where dept_name=&quot;运维部&quot;);
+-------------+-----------+------------+---------------------+--------------------+--------------+---------+
| employee_id | name      | hire_date  | birth【波尔斯】_date | email              | phone_number | dept_id |
+-------------+-----------+------------+---------------------+--------------------+--------------+---------+
|          14 | 廖娜      | 2012-05-20 | 1982-06-22          | liaona@moershi.com  | 15827928192  |       3 |
|          15 | 窦红梅    | 2018-03-16 | 1971-09-09          | douhongmei@qcjy.cn | 15004739483  |       3 |
|          16 | 聂想      | 2018-09-09 | 1999-06-05          | niexiang@qcjy.cn   | 15501892446  |       3 |
|          17 | 陈阳      | 2004-09-16 | 1991-04-10          | chenyang@qcjy.cn   | 15565662056  |       3 |
|          18 | 戴璐      | 2001-11-30 | 1975-05-16          | dailu@qcjy.cn      | 13465236095  |       3 |
|          19 | 陈斌      | 2019-07-04 | 2000-01-22          | chenbin@moershi.com | 13621656037  |       3 |
+-------------+-----------+------------+---------------------+--------------------+--------------+---------+
6 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）查询人事部2018年12月所有员工工资&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//查看人事部的部门id
mysql&amp;gt; select【涩莱克特】 dept_id from【弗乱】 departments【迪帕踢门特s】 where【威尔】 dept_name=&apos;人事部&apos;;
-- mysql&amp;gt; select dept_id from departments where dept_name=&apos;人事部&apos;;
+---------+
| dept_id |
+---------+
|       1 |
+---------+
1 row in set (0.00 sec)
//查找employees【ing普洛伊s】表里 人事部的员工id 
select【涩莱克特】 employee【ing普洛伊】_id from【弗乱】 employees【ing普洛伊s】  where【威尔】 dept_id=(select【涩莱克特】 dept_id from【弗乱】 departments【迪帕踢门特s】 where【威尔】 dept_name=&apos;人事部&apos;);
-- mysql&amp;gt; select employee_id from employees where dept_id=(select dept_id from departments where dept_name=&apos;人事部&apos;);
+-------------+
| employee_id |
+-------------+
|           1 |
|           2 |
|           3 |
|           4 |
|           5 |
|           6 |
|           7 |
|           8 |
+-------------+
8 rows in set (0.00 sec)
//查询人事部2018年12月所有员工工资 
select【涩莱克特】   *   from【弗乱】 salary【撒拉瑞】 where【威尔】 year【耶尔】(date)=2018 and month【mèn斯】(date)=12 
and employee【ing普洛伊】_id in (select【涩莱克特】 employee【ing普洛伊】_id from【弗乱】 employees【ing普洛伊s】 
where【威尔】 dept_id=(select【涩莱克特】 dept_id from【弗乱】 departments【迪帕踢门特s】 where【威尔】 dept_name=&apos;人事部&apos;) );
-- mysql&amp;gt; select * from salary where year(date)=2018 and month(date)=12 
--     -&amp;gt; and employee_id in (select employee_id from employees 
--     -&amp;gt; where dept_id=(select dept_id from departments where dept_name=&apos;人事部&apos;));
+------+------------+-------------+----------------+----------------+
| id   | date       | employee_id | basic【贝斯克】 | bonus【波诺斯】 |
+------+------------+-------------+----------------+----------------+
| 6252 | 2018-12-10 |           1 | 17016          |  7000          |
| 6253 | 2018-12-10 |           2 | 20662          |  9000          |
| 6254 | 2018-12-10 |           3 |  9724          |  8000          |
| 6255 | 2018-12-10 |           4 | 17016          |  2000          |
| 6256 | 2018-12-10 |           5 | 17016          |  3000          |
| 6257 | 2018-12-10 |           6 | 17016          |  1000          |
| 6258 | 2018-12-10 |           7 | 23093          |  4000          |
| 6259 | 2018-12-10 |           8 | 23093          |  2000          |
+------+------------+-------------+----------------+----------------+
8 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3）查询人事部和财务部员工信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//查看人事部和财务部的 部门id
select【涩莱克特】 dept_id from【弗乱】 departments【迪帕踢门特s】  where【威尔】 dept_name in (&apos;人事部&apos;, &apos;财务部&apos;);
-- mysql&amp;gt; select dept_id from departments where dept_name in (&apos;人事部&apos;,&apos;财务部&apos;);
+---------+
| dept_id |
+---------+
|       1 |
|       2 |
+---------+
2 rows in set (0.00 sec)

//查询人事部和财务部员工信息
select【涩莱克特】 dept_id , name  from【弗乱】 employees【ing普洛伊s】 
where【威尔】 dept_id in ( 
select【涩莱克特】 dept_id from【弗乱】 departments【迪帕踢门特s】  where【威尔】 dept_name in (&apos;人事部&apos;, &apos;财务部&apos;) 
);
-- mysql&amp;gt; select dept_id,name from employees
--     -&amp;gt; where dept_id in (
--     -&amp;gt; select dept_id from departments where dept_name in (&apos;人事部&apos;,&apos;财务部&apos;));
+---------+-----------+
| dept_id | name      |
+---------+-----------+
|       1 | 梁伟      |
|       1 | 郭岩      |    
|       1 | 李玉英    |
|       1 | 张健      |
|       1 | 郑静      |
|       1 | 牛建军    |
|       1 | 刘斌      |
|       1 | 汪云      |
|       2 | 张建平    |
|       2 | 郭娟      |
|       2 | 郭兰英    |
|       2 | 王英      |
|       2 | 王楠      |
+---------+-----------+
13 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4）查询2018年12月所有比100号员工基本工资高的工资信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//把100号员工的基本工资查出来
select【涩莱克特】 basic【贝斯克】 from【弗乱】 salary【撒拉瑞】  where【威尔】 year【耶尔】(date)=2018 and 
month【mèn斯】(date)=12 and employee【ing普洛伊】_id=100; 
-- mysql&amp;gt; select basic from salary where year(date)=2018 and 
--     -&amp;gt; month(date)=12 and employee_id=100; 
+----------------+
| basic【贝斯克】 |
+----------------+
| 14585          |
+----------------+
1 row in set (0.00 sec) 

//查看比100号员工工资高的工资信息
select【涩莱克特】  *  from【弗乱】 salary【撒拉瑞】 
where【威尔】 year【耶尔】(date)=2018 and month【mèn斯】(date)=12 and 
basic【贝斯克】&amp;gt;(select【涩莱克特】 basic【贝斯克】 from【弗乱】 salary【撒拉瑞】 where【威尔】 year【耶尔】(date)=2018 and 
month【mèn斯】(date)=12 and employee【ing普洛伊】_id=100);
-- mysql&amp;gt; select * from salary
--     -&amp;gt; where year(date)=2018 and month(date)=12 and
--     -&amp;gt; basic &amp;gt; (select basic from salary where year(date)=2018 and        
--     -&amp;gt; month(date)=12 and employee_id=100);
+------+------------+-------------+----------------+----------------+
| id   | date       | employee_id | basic【贝斯克】 | bonus【波诺斯】 |
+------+------------+-------------+----------------+----------------+
| 6252 | 2018-12-10 |           1 | 17016          |  7000          |
| 6253 | 2018-12-10 |           2 | 20662          |  9000          |
| 6255 | 2018-12-10 |           4 | 17016          |  2000          |
| 6256 | 2018-12-10 |           5 | 17016          |  3000          |
| 6257 | 2018-12-10 |           6 | 17016          |  1000          |
| 6258 | 2018-12-10 |           7 | 23093          |  4000          |
| 6259 | 2018-12-10 |           8 | 23093          |  2000          |
| 6261 | 2018-12-10 |          10 | 21878          |  8000          |
| 6262 | 2018-12-10 |          11 | 17016          |  8000          |
| 6263 | 2018-12-10 |          12 | 15800          |  4000          |
| 6264 | 2018-12-10 |          13 | 18231          |  3000          |
| 6267 | 2018-12-10 |          16 | 21878          |  8000          |
| 6268 | 2018-12-10 |          17 | 19448          |  7000          |
| 6271 | 2018-12-10 |          20 | 19448          |  3000          |
| 6272 | 2018-12-10 |          21 | 18231          | 11000          |
| 6276 | 2018-12-10 |          25 | 23093          |  3000          |
| 6278 | 2018-12-10 |          27 | 24309          |  5000          |
| 6279 | 2018-12-10 |          28 | 17016          |  9000          |
| 6280 | 2018-12-10 |          29 | 23093          |  1000          |
| 6282 | 2018-12-10 |          31 | 25524          |  9000          |
| 6283 | 2018-12-10 |          32 | 18231          | 11000          |
| 6284 | 2018-12-10 |          33 | 23093          |  6000          |
| 6285 | 2018-12-10 |          34 | 23093          |  1000          |
| 6288 | 2018-12-10 |          37 | 24309          |  4000          |
| 6289 | 2018-12-10 |          38 | 23093          |  3000          |
| 6291 | 2018-12-10 |          40 | 20662          |  2000          |
| 6297 | 2018-12-10 |          46 | 15800          |  7000          |
| 6299 | 2018-12-10 |          48 | 25524          |  1000          |
| 6300 | 2018-12-10 |          49 | 15800          |  9000          |
| 6303 | 2018-12-10 |          52 | 19448          |  9000          |
| 6304 | 2018-12-10 |          53 | 25524          |  8000          |
| 6305 | 2018-12-10 |          54 | 21878          |  9000          |
| 6307 | 2018-12-10 |          56 | 23093          |  3000          |
| 6308 | 2018-12-10 |          57 | 23093          |  3000          |
| 6312 | 2018-12-10 |          61 | 24309          |  3000          |
| 6313 | 2018-12-10 |          62 | 15800          |  4000          |
| 6314 | 2018-12-10 |          63 | 15800          |  8000          |
| 6317 | 2018-12-10 |          66 | 19448          |  7000          |
| 6319 | 2018-12-10 |          68 | 25524          |  9000          |
| 6324 | 2018-12-10 |          73 | 17016          | 10000          |
| 6327 | 2018-12-10 |          76 | 20662          | 11000          |
| 6330 | 2018-12-10 |          79 | 15800          |  4000          |
| 6332 | 2018-12-10 |          81 | 17016          |  3000          |
| 6336 | 2018-12-10 |          85 | 15800          |  1000          |
| 6337 | 2018-12-10 |          86 | 24309          |  4000          |
| 6339 | 2018-12-10 |          88 | 20662          |  2000          |
| 6342 | 2018-12-10 |          91 | 20662          | 11000          |
| 6343 | 2018-12-10 |          92 | 19448          |  2000          |
| 6346 | 2018-12-10 |          95 | 19448          |  8000          |
| 6349 | 2018-12-10 |          98 | 19448          |  9000          |
| 6350 | 2018-12-10 |          99 | 15800          |  5000          |
| 6353 | 2018-12-10 |         102 | 23093          |  3000          |
| 6356 | 2018-12-10 |         105 | 21878          |  8000          |
| 6357 | 2018-12-10 |         106 | 23093          |  5000          |
| 6358 | 2018-12-10 |         107 | 18231          |  7000          |
| 6359 | 2018-12-10 |         108 | 18231          |  2000          |
| 6361 | 2018-12-10 |         110 | 18231          |  2000          |
| 6363 | 2018-12-10 |         112 | 24309          |  9000          |
| 6368 | 2018-12-10 |         117 | 25524          | 11000          |
| 6369 | 2018-12-10 |         118 | 23093          |  3000          |
| 6370 | 2018-12-10 |         119 | 23093          | 10000          |
| 6373 | 2018-12-10 |         122 | 21878          |  2000          |
| 6374 | 2018-12-10 |         123 | 19448          | 10000          |
| 6376 | 2018-12-10 |         125 | 17016          |  5000          |
| 6378 | 2018-12-10 |         127 | 17016          |  6000          |
+------+------------+-------------+----------------+----------------+
65 rows in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.2 having【嗨夫营】之后嵌套查询&lt;/h3&gt;
&lt;p&gt;查询部门员工总人数比开发部总人数少 的 部门名称和人数&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//统计开发部员工总人数
select【涩莱克特】 count【kàn特】(name) from【弗乱】 employees【ing普洛伊s】 where【威尔】 dept_id = (select【涩莱克特】 
  dept_id from【弗乱】 departments【迪帕踢门特s】 where【威尔】 dept_name=&quot;开发部&quot;);
-- mysql&amp;gt; select count(name) from employees where dept_id=
--     -&amp;gt; (select dept_id from departments where dept_name=&quot;开发部&quot;);
+---------------------+
| count【kàn特】(name) |
+---------------------+
|          55         |
+---------------------+
1 row in set (0.00 sec)



//统计每个部门总人数 
select【涩莱克特】   dept_id , count【kàn特】(name) from【弗乱】 employees【ing普洛伊s】 group【格鲁普】 by   dept_id;
-- mysql&amp;gt; select dept_id,count(name) from employees group by dept_id;
+---------+---------------------+
| dept_id | count【kàn特】(name) |
+---------+---------------------+
|       1 |           8         |
|       2 |           5         |
|       3 |           6         |
|       4 |          55         |
|       5 |          12         |
|       6 |           9         |
|       7 |          35         |
|       8 |           3         |
+---------+---------------------+
8 rows in set (0.00 sec)


//输出总人数比开发部总人数少的部门名及总人数 
select【涩莱克特】  dept_id ,  count【kàn特】(name) as total【偷ò头ō】    from【弗乱】 employees【ing普洛伊s】 group【格鲁普】 by dept_id 
having【嗨夫营】  total【偷ò头ō】 &amp;lt; (
select【涩莱克特】 count【kàn特】(name) from【弗乱】 employees【ing普洛伊s】  where【威尔】 dept_id=(
select【涩莱克特】 dept_id from【弗乱】 departments【迪帕踢门特s】 where【威尔】 dept_name=&apos;开发部&apos;)
);
-- mysql&amp;gt; select dept_id,count(name) as total from employees group by dept_id 
--     -&amp;gt; having total &amp;lt; (select count(name) from employees where dept_id= (select 
--     -&amp;gt; dept_id from departments where dept_name=&apos;开发部&apos;));
+---------+----------------+
| dept_id | total【偷ò头ō】 |
+---------+----------------+
|       1 |     8          |
|       2 |     5          |
|       3 |     6          |
|       5 |    12          |
|       6 |     9          |
|       7 |    35          |
|       8 |     3          |
+---------+----------------+
7 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.3 from【弗乱】之后嵌套查询&lt;/h3&gt;
&lt;p&gt;查询3号部门 、部门名称 及其部门内 员工的编号、名字 和 email&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】 dept_id, dept_name, employee【ing普洛伊】_id, name, email  from【弗乱】 (
select【涩莱克特】  d.dept_name, e.*  from【弗乱】 departments【迪帕踢门特s】 as d  inner【ing呐】 join【载(白话)】 employees【ing普洛伊s】 as e 
on【昂】 d.dept_id=e.dept_id ) as tmp_table【忒-部】  where【威尔】 dept_id=3;
-- mysql&amp;gt; select dept_id,dept_name,employee_id,name,email from
--     -&amp;gt; (select d.dept_name,e.* from departments as d inner join employees as e
--     -&amp;gt; on d.dept_id=e.dept_id) as tmp_toble where dept_id=3;
+---------+-----------+-------------+-----------+--------------------+
| dept_id | dept_name | employee_id | name      | email              |
+---------+-----------+-------------+-----------+--------------------+
|       3 | 运维部    |          14 | 廖娜      | liaona@moershi.com  |
|       3 | 运维部    |          15 | 窦红梅    | douhongmei@qcjy.cn |
|       3 | 运维部    |          16 | 聂想      | niexiang@qcjy.cn   |
|       3 | 运维部    |          17 | 陈阳      | chenyang@qcjy.cn   |
|       3 | 运维部    |          18 | 戴璐      | dailu@qcjy.cn      |
|       3 | 运维部    |          19 | 陈斌      | chenbin@moershi.com |
+---------+-----------+-------------+-----------+--------------------+
6 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.4 select【涩莱克特】之后嵌套查询&lt;/h3&gt;
&lt;p&gt;查询每个部门的人数： dept_id dept_name 部门人数&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//显示部门表中的所有列表
select【涩莱克特】 d.*  from【弗乱】 departments【迪帕踢门特s】 as d;
-- mysql&amp;gt; select d.* from departments as d;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|       1 | 人事部    |
|       2 | 财务部    |
|       3 | 运维部    |
|       4 | 开发部    |
|       5 | 测试部    |
|       6 | 市场部    |
|       7 | 销售部    |
|       8 | 法务部    |
+---------+-----------+
8 rows in set (0.00 sec)

//查询每个部门的人数
select【涩莱克特】  d.* , ( select【涩莱克特】 count【kàn特】(name) from【弗乱】 employees【ing普洛伊s】 as e  where【威尔】 d.dept_id=e.dept_id) as 部门人数  from【弗乱】 departments【迪帕踢门特s】 as d;
-- mysql&amp;gt; select d.*,(select count(name) from employees as e where d.dept_id=e.dept_id) as 部门人数 
--     -&amp;gt; from departments as d;
+---------+-----------+--------------+
| dept_id | dept_name | 部门人数     |
+---------+-----------+--------------+
|       1 | 人事部    |            8 |
|       2 | 财务部    |            5 |
|       3 | 运维部    |            6 |
|       4 | 开发部    |           55 |
|       5 | 测试部    |           12 |
|       6 | 市场部    |            9 |
|       7 | 销售部    |           35 |
|       8 | 法务部    |            3 |
+---------+-----------+--------------+
8 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;七、作业&lt;/h2&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;在内连接查询中，使用以下哪种关键字进行连接操作？C
A. LEFT JOIN
B. RIGHT JOIN
C. INNER JOIN
D. FULL JOIN&lt;/li&gt;
&lt;li&gt;外连接查询中，左外连接会返回以下哪些数据？A
A. 左表的所有记录和右表匹配的记录
B. 右表的所有记录和左表匹配的记录
C. 左右表的所有记录
D. 只返回左右表匹配的记录&lt;/li&gt;
&lt;li&gt;合并查询中，&lt;code&gt;UNION ALL&lt;/code&gt; 和 &lt;code&gt;UNION&lt;/code&gt; 的区别是？ B
A. &lt;code&gt;UNION ALL&lt;/code&gt; 会去除重复记录，&lt;code&gt;UNION&lt;/code&gt; 不会
B. &lt;code&gt;UNION&lt;/code&gt; 会去除重复记录，&lt;code&gt;UNION ALL&lt;/code&gt; 不会
C. 两者都去除重复记录
D. 两者都不去除重复记录&lt;/li&gt;
&lt;li&gt;嵌套查询是指？B
A. 在一个查询语句中嵌套多个表
B. 在一个查询语句中嵌套另一个查询语句
C. 同时进行多个查询操作
D. 以上都不对&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;简述内连接查询和外连接查询的区别。
答：
内连接是：只保留匹配的记录（交集）
外链接是：保留至少一个表的所有记录，不匹配的用NULL填充
应用场景区别：内连接用于需要精确匹配的场景，外连接用于需要保留所有记录的统计分析&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;什么时候使用 &lt;code&gt;UNION&lt;/code&gt;，什么时候使用 &lt;code&gt;UNION ALL&lt;/code&gt;？
答：
需要唯一结果的时候可以使用&lt;code&gt;UNION&lt;/code&gt;
当需要完整数据或性能优先  时候使用 &lt;code&gt;UNION ALL&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;请解释嵌套查询的作用和适用场景。
答：
嵌套查询的作用
1. 数据筛选与过滤
2. 数据比较与计算
3. 数据存在性检查
4.  数据聚合与统计&lt;/p&gt;
&lt;p&gt;特别适合需要多步骤数据处理和分析的业务场景。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3 操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;使用内连接查询，查询出每个员工所在部门的名称和员工姓名。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt;
mysql&amp;gt; select e.name,d.dept_name from employees as e inner join departments as d         
    -&amp;gt; on e.dept_id=d.dept_id;
+-----------+-----------+
| name      | dept_name |
+-----------+-----------+
| 梁伟      | 人事部    |
| 郭岩      | 人事部    |
| 李玉英    | 人事部    |
| 张健      | 人事部    |
.........

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;使用左外连接查询，查询出所有员工的信息以及他们所在部门的名称（如果员工没有部门，部门名称显示为 NULL）。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt;
mysql&amp;gt; select e.*,d.dept_name from employees as e left join departments as d on e.dept_id=d.dept_id;
+-------------+-----------+------------+------------+---------------------------+--------------+---------+-----------+
| employee_id | name      | hire_date  | birth_date | email                     | phone_number | dept_id | dept_name |
+-------------+-----------+------------+------------+---------------------------+--------------+---------+-----------+
|           1 | 梁伟      | 2018-06-21 | 1971-08-19 | liangwei@tedu.cn          | 13591491431  |       1 | 人事部    |
|           2 | 郭岩      | 2010-03-21 | 1974-05-13 | guoyan@tedu.cn            | 13845285867  |       1 | 人事部    |
|           3 | 李玉英    | 2012-01-19 | 1974-01-25 | liyuying@tedu.cn          | 15628557234  |       1 | 人事部    |
|           4 | 张健      | 2008-09-17 | 1972-06-07 | zhangjian@moershi.com     | 13835990213  |       1 | 人事部    |
|           5 | 郑静      | 2018-02-03 | 1997-02-14 | zhengjing@tedu.cn         | 14508936730  |       1 | 人事部    |
|           6 | 牛建军    | 2005-11-18 | 1985-03-19 | niujianjun@moershi.com    | 14750937118  |       1 | 人事部    |
......

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;使用合并查询，将薪资表中基本薪资大于 5000 和奖金大于 2000 的记录合并。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; (select name,basic from salary as s inner join employees as e on e.employee_id=s.employee_id where basic &amp;gt; 5000)
    -&amp;gt; union
    -&amp;gt; (select name,bonus from salary as s inner join employees as e on e.employee_id=s.employee_id where bonus &amp;gt;2000);
+-----------+-------+
| name      | basic |
+-----------+-------+
| 郭岩      | 17000 |
| 李玉英    |  8000 |
| 张健      | 14000 |
| 牛建军    | 14000 |
| 刘斌      | 19000 |
| 郭兰英    | 14000 |
| 王楠      | 15000 |
| 廖娜      | 10000 |
| 陈阳      | 16000 |
.....

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;使用嵌套查询，查询出部门名称为 “开发部” 的所有员工的信息。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt;
mysql&amp;gt; select * from employees where dept_id=
    -&amp;gt; (select dept_id from departments where dept_name=&apos;开发部&apos;);
+-------------+-----------+------------+------------+---------------------------+--------------+---------+
| employee_id | name      | hire_date  | birth_date | email                     | phone_number | dept_id |
+-------------+-----------+------------+------------+---------------------------+--------------+---------+
|          20 | 蒋红      | 2017-12-29 | 1978-01-24 | jianghong@tedu.cn         | 15852915398  |       4 |
|          21 | 曹宁      | 2004-06-07 | 1988-01-05 | caoning@tedu.cn           | 14513022304  |       4 |
|          22 | 吕刚      | 2014-01-18 | 1980-06-24 | lvgang@tedu.cn            | 18136987619  |       4 |
|          23 | 王莉      | 2021-02-04 | 1972-12-19 | wangli@moershi.com        | 15376329290  |       4 |
|          24 | 邓秀芳    | 2020-09-08 | 1980-12-12 | dengxiufang@moershi.com   | 15884927117  |       4 |
|          25 | 邵佳      | 2011-08-15 | 1978-11-28 | shaojia@tedu.cn           | 13296016750  |       4 |
|          26 | 党丽      | 2014-03-14 | 1978-12-30 | dangli@moershi.com        | 13166234580  |       4 |
|          27 | 梁勇      | 2007-01-19 | 1997-11-12 | liangyong@tedu.cn         | 15307868657  |       4 |
|          28 | 郑秀珍    | 2011-04-28 | 1972-09-01 | zhengxiuzhen@moershi.com  | 14543186401  |       4 |
|          29 | 胡秀云    | 2003-11-03 | 2000-05-14 | huxiuyun@tedu.cn          | 18212266720  |       4 |
|          30 | 邢淑兰    | 2011-07-02 | 1989-06-17 | xingshulan@moershi.com    | 13032270370  |       4 |
|          31 | 刘海燕    | 2018-01-06 | 1982-08-21 | liuhaiyan@moershi.com     | 15064354651  |       4 |
|          32 | 冯建国    | 2014-05-28 | 1980-01-26 | fengjianguo@tedu.cn       | 13344957322  |       4 |
.........

&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>05：mysql之表结构管理</title><link>https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/05-mysql%E4%B9%8B%E8%A1%A8%E7%BB%93%E6%9E%84%E7%AE%A1%E7%90%86/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/05-mysql%E4%B9%8B%E8%A1%A8%E7%BB%93%E6%9E%84%E7%AE%A1%E7%90%86/</guid><description>05：mysql之表结构管理 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 10:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1&gt;05：mysql之表结构管理&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[表结构管理]
        direction LR
        A[表管理] --&amp;gt; B[表格字段数据类型] --&amp;gt; C[表头基本约束]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class E highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;小李在一家小型互联网公司担任数据库管理员。最近公司业务拓展，员工数量大幅增加，原本的数据库表结构逐渐难以满足需求。&lt;/p&gt;
&lt;p&gt;在员工表中，原先的“职位”字段过于笼统，无法精准区分不同岗位。部门表也没有记录各部门的成立时间，不利于做部门发展分析。薪资表中奖金计算方式单一，不能适应新的绩效制度。&lt;/p&gt;
&lt;p&gt;小李意识到要对表结构进行优化。他先和各部门沟通，了解实际业务需求，再设计新的表结构，在员工表细化“职位”，部门表添加“成立时间”，薪资表调整奖金规则。最后在测试环境验证新结构，确保准确稳定后应用到正式环境。&lt;/p&gt;
&lt;h2&gt;二、为啥要学表结构管理&lt;/h2&gt;
&lt;p&gt;学习 MySQL 表结构管理非常有必要。想象下你在一家公司工作，公司有员工表、部门表和薪资表。如果表结构管理不好，问题就会接踵而至。&lt;/p&gt;
&lt;p&gt;要是员工表没有合理设置字段，可能会导致员工信息记录不全，影响人事管理。部门表结构混乱，就很难清晰掌握各部门的情况。薪资表如果设计不佳，计算薪资时容易出错，引发员工不满。&lt;/p&gt;
&lt;p&gt;学会表结构管理，能让这些表合理存储数据，查询和修改数据更高效，避免数据冗余和错误。可以准确统计各部门员工数量、快速算出员工薪资，让公司运营更顺畅，所以学好它对处理数据很有帮助。&lt;/p&gt;
&lt;h2&gt;三、表管理&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[表结构管理]
        direction LR
        A[表管理] --&amp;gt; B[表格字段数据类型] --&amp;gt; C[表头基本约束]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class A highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.1 建库练习&lt;/h3&gt;
&lt;p&gt;库名命名规则：&lt;/p&gt;
&lt;p&gt;仅可以使用数字、字母、下划线、不能纯数字&lt;/p&gt;
&lt;p&gt;区分字母大小写，&lt;/p&gt;
&lt;p&gt;具有唯一性&lt;/p&gt;
&lt;p&gt;不可使用MySQL命令或特殊字符&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//库名区分字母大小写
mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】 gamedb ;
-- mysql&amp;gt; create database gamedb;
Query OK, 1 row affected (0.14 sec)

mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】 GAMEDB ;
-- mysql&amp;gt; create database GAMEDB;
Query OK, 1 row affected (0.08 sec)

mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】 GAMEDB ;  
-- mysql&amp;gt; create database GAMEDB;
ERROR 1007 (HY000): Can&apos;t create【克瑞特】 database【得塔-贝斯】 &apos;GAMEDB&apos;; database【得塔-贝斯】 exists【伊贼谁斯】&apos; //重名报错

//加if not【nuō 特】 exists【伊贼谁斯】 命令避免重名报错
mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】  if not【nuō 特】 exists【伊贼谁斯】  gamedb ; 
-- mysql&amp;gt; create database if not exists gamedb; 
Query OK, 1 row affected, 1 warning (0.03 sec) //正常

mysql&amp;gt; show【瘦】  databases【得塔-贝斯】; //查看创建的库
-- mysql&amp;gt; show databases;
+--------------------+
| Database           |
+--------------------+
| GAMEDB             |
| gamedb             |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| moershi             |
+--------------------+
7 rows in set (0.00 sec)

mysql&amp;gt; drop【卓-普】 database【得塔-贝斯】 gamedb;  //删除库
-- mysql&amp;gt; drop database gamedb;
Query OK, 0 rows affected (0.11 sec)

mysql&amp;gt; drop【卓-普】 database【得塔-贝斯】 gamedb; // 删除没有的库报错
-- mysql&amp;gt; drop database gamedb;
ERROR 1008 (HY000): Can’t drop【卓-普】 database【得塔-贝斯】 ‘gamedb’; database【得塔-贝斯】 doesn’t exist

//加if exists【伊贼谁斯】 删除没有的库，也不报错
mysql&amp;gt; drop【卓-普】 database【得塔-贝斯】 if exists【伊贼谁斯】 gamedb;
-- mysql&amp;gt; drop database if exists gamedb; 
Query OK, 0 rows affected, 1 warning (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 建表练习&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】  studb【斯丢db】; //建库
-- mysql&amp;gt; create database studb; 
Query OK, 1 row affected (0.11 sec)

mysql&amp;gt; create【克瑞特】 table【忒-部】 studb【斯丢db】.stu(  //建表
    -&amp;gt; name char【查尔】(10), 
    -&amp;gt; class【克拉斯】 char【查尔】(9), 
    -&amp;gt; gender【间德尔】 char【查尔】(4), 
    -&amp;gt; age int【因特】 
    -&amp;gt; );
-- mysql&amp;gt; create table studb.stu( 
--     -&amp;gt; name char(10),
--     -&amp;gt; class char(9),
--     -&amp;gt; gender char(4),
--     -&amp;gt; age int);    
Query OK, 0 rows affected (1.17 sec)

mysql&amp;gt; desc studb【斯丢db】.stu;  //查看表头
-- mysql&amp;gt; desc studb.stu;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| name   | char(10) | YES  |     | NULL    |       |
| class  | char(9)  | YES  |     | NULL    |       |
| gender | char(4)  | YES  |     | NULL    |       |
| age    | int      | YES  |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
4 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3 修改表练习&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;h4&gt;修改表名&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; show【瘦】 tables【忒-部s】; //查看表
-- mysql&amp;gt; show tables;
+-----------------+
| Tables_in_studb |
+-----------------+
| stu             |
+-----------------+
1 row in set (0.00 sec)

mysql&amp;gt; alter【奥-特】 table【忒-部】 studb【斯丢db】.stu rename【瑞-内姆】 studb【斯丢db】.stuinfo【斯丢因否】; //修改表名  rename【瑞-内姆】
-- mysql&amp;gt; alter table studb.stu rename studb.stuinfo;
Query OK, 0 rows affected (0.28 sec)

mysql&amp;gt; use studb【斯丢db】; //进入库
-- mysql&amp;gt; use studb;
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&amp;gt; show【瘦】 tables【忒-部s】; //查看表
-- mysql&amp;gt; show tables;
+-----------------+
| Tables_in_studb |
+-----------------+
| stuinfo         |
+-----------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;删除表头&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; desc studb【斯丢db】.stu;  //查看表头
-- mysql&amp;gt; desc studb.stu;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| name   | char(10) | YES  |     | NULL    |       |
| class  | char(9)  | YES  |     | NULL    |       |
| gender | char(4)  | YES  |     | NULL    |       |
| age    | int      | YES  |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
4 rows in set (0.00 sec)

mysql&amp;gt;  alter【奥-特】 table【忒-部】 studb【斯丢db】.stuinfo【斯丢因否】 drop【卓-普】 age ; //删除age表头 drop【卓-普】
-- mysql&amp;gt; alter table studb.stuinfo drop age;
Query OK, 0 rows affected (0.52 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql&amp;gt;  desc stuinfo【斯丢因否】; //查看表头
-- mysql&amp;gt; desc stuinfo;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| name   | char(10) | YES  |     | NULL    |       |
| class  | char(9)  | YES  |     | NULL    |       |
| gender | char(4)  | YES  |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;添加表头&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//添加表头，默认添加在末尾add
mysql&amp;gt; alter【奥-特】 table【忒-部】 studb【斯丢db】.stuinfo【斯丢因否】 add  mail【miào e】  char【查尔】(30) ; 
-- mysql&amp;gt; alter table studb.stuinfo add mail char(30);
Query OK, 0 rows affected (0.24 sec)
Records: 0  Duplicates: 0  Warnings: 0

//查看表头
mysql&amp;gt; desc studb【斯丢db】.stuinfo【斯丢因否】;
-- mysql&amp;gt; desc studb.stuinfo;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| name   | char(10) | YES  |     | NULL    |       |
| class  | char(9)  | YES  |     | NULL    |       |
| gender | char(4)  | YES  |     | NULL    |       |
| mail   | char(30) | YES  |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
4 rows in set (0.00 sec)

//first【佛斯特】 把表头添加首位  
//after【啊夫特】 添加在指定表头名的下方
mysql&amp;gt; alter【奥-特】 table【忒-部】  studb【斯丢db】.stuinfo【斯丢因否】 add number【能波】  char【查尔】(9) first【佛斯特】 , add  school【斯故】 char【查尔】(10) after【啊夫特】 name;
-- mysql&amp;gt; alter table studb.stuinfo add number char(9) first,add school char(10) after name;
Query OK, 0 rows affected (0.48 sec)
Records: 0  Duplicates: 0  Warnings: 0

//查看表结构
mysql&amp;gt; desc studb【斯丢db】.stuinfo【斯丢因否】;  //查看表头
-- mysql&amp;gt; desc studb.stuinfo;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| number | char(9)  | YES  |     | NULL    |       |
| name   | char(10) | YES  |     | NULL    |       |
| school | char(10) | YES  |     | NULL    |       |
| class  | char(9)  | YES  |     | NULL    |       |
| gender | char(4)  | YES  |     | NULL    |       |
| mail   | char(30) | YES  |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
6 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;修改表头数据类型&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//修改表头数据类型modify【莫迪fái】
mysql&amp;gt; alter【奥-特】 table【忒-部】  studb【斯丢db】.stuinfo【斯丢因否】  modify【莫迪fái】  mail【miào e】 varchar【瓦儿-查儿】(50);
-- mysql&amp;gt; alter table studb.stuinfo modify mail varchar(50);
Query OK, 0 rows affected (1.17 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql&amp;gt; desc studb【斯丢db】.stuinfo【斯丢因否】;
-- mysql&amp;gt; desc studb.stuinfo;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| number | char(9)     | YES  |     | NULL    |       |
| name   | char(10)    | YES  |     | NULL    |       |
| school | char(10)    | YES  |     | NULL    |       |
| class  | char(9)     | YES  |     | NULL    |       |
| gender | char(4)     | YES  |     | NULL    |       |
| mail   | varchar(50) | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
6 rows in set (0.01 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;修改表头名&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//修改表头名class【克拉斯】
mysql&amp;gt; alter【奥-特】 table【忒-部】 studb【斯丢db】.stuinfo【斯丢因否】 change【趁(chèn)吉】  class【克拉斯】  班级  char【查尔】(9) ;
-- mysql&amp;gt; alter table studb.stuinfo change class 班级 char(9);
Query OK, 0 rows affected (0.12 sec)
Records: 0  Duplicates: 0  Warnings: 0

//查看表头
mysql&amp;gt; desc studb【斯丢db】.stuinfo【斯丢因否】;
-- mysql&amp;gt; desc studb.stuinfo;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| number | char(9)     | YES  |     | NULL    |       |
| name   | char(10)    | YES  |     | NULL    |       |
| school | char(10)    | YES  |     | NULL    |       |
| 班级   | char(9)     | YES  |     | NULL    |       |
| gender | char(4)     | YES  |     | NULL    |       |
| mail   | varchar(50) | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;删除多个表头&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//一起删除多个表头
mysql&amp;gt; alter【奥-特】 table【忒-部】  studb【斯丢db】.stuinfo【斯丢因否】  drop【卓-普】 school【斯故】 , drop【卓-普】 班级 ,drop【卓-普】 mail【miào e】 ;
-- mysql&amp;gt; alter table studb.stuinfo drop school,drop 班级,drop mail;
Query OK, 0 rows affected (0.73 sec)
Records: 0  Duplicates: 0  Warnings: 0

//查看表头
mysql&amp;gt; desc studb【斯丢db】.stuinfo【斯丢因否】;
-- mysql&amp;gt; desc studb.stuinfo;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| number | char(9)  | YES  |     | NULL    |       |
| name   | char(10) | YES  |     | NULL    |       |
| gender | char(4)  | YES  |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;修改表头的位置&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; 
//使用modify【莫迪fái】  修改表头的位置  
mysql&amp;gt; alter【奥-特】 table【忒-部】 studb【斯丢db】.stuinfo【斯丢因否】 modify【莫迪fái】 gender【间德尔】 char【查尔】(4) after【啊夫特】 number【能波】;
-- mysql&amp;gt; alter table studb.stuinfo modify gender char(4) after number;
Query OK, 0 rows affected (0.77 sec)
Records: 0  Duplicates: 0  Warnings: 0

//查看表头
mysql&amp;gt; desc studb【斯丢db】.stuinfo【斯丢因否】;
-- mysql&amp;gt; desc studb.stuinfo;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| number | char(9)  | YES  |     | NULL    |       |
| gender | char(4)  | YES  |     | NULL    |       |
| name   | char(10) | YES  |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

//再修改回原来位置
mysql&amp;gt;  alter【奥-特】 table【忒-部】 studb【斯丢db】.stuinfo【斯丢因否】 modify【莫迪fái】 gender【间德尔】 char【查尔】(4) after【啊夫特】 name;
-- mysql&amp;gt; alter table studb.stuinfo modify gender char(4) after name;
Query OK, 0 rows affected (0.50 sec)
Records: 0  Duplicates: 0  Warnings: 0

//查看表头
mysql&amp;gt; desc studb【斯丢db】.stuinfo【斯丢因否】;
-- mysql&amp;gt; desc studb.stuinfo;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| number | char(9)  | YES  |     | NULL    |       |
| name   | char(10) | YES  |     | NULL    |       |
| gender | char(4)  | YES  |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
3 rows in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.4 复制表&lt;/h3&gt;
&lt;p&gt;拷贝已有的表 和系统命令 cp 的功能一样&lt;/p&gt;
&lt;h4&gt;复制表&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;-- create table 表名  select * from 表名
//复制moershi库salary【晒了瑞】表到 studb【斯丢db】库 表名不变
mysql&amp;gt; create【克瑞特】 table【忒-部】 studb【斯丢db】.salary【晒了瑞】  select【涩莱克特】  * from【弗乱】 moershi.salary【晒了瑞】;
-- mysql&amp;gt; create table studb.salary select * from moershi.salary;
Query OK, 8055 rows affected (2.66 sec)
Records: 8055  Duplicates: 0  Warnings: 0 

//查看表头，源表的key【kì】 不会被复制
mysql&amp;gt; desc studb【斯丢db】.salary【晒了瑞】;
-- mysql&amp;gt; desc studb.salary;
+-------------+------+------+-----+---------+-------+
| Field       | Type | Null | Key | Default | Extra |
+-------------+------+------+-----+---------+-------+
| id          | int  | NO   |     | 0       |       |
| date        | date | YES  |     | NULL    |       |
| employee_id | int  | YES  |     | NULL    |       |
| basic       | int  | YES  |     | NULL    |       |
| bonus       | int  | YES  |     | NULL    |       |
+-------------+------+------+-----+---------+-------+
5 rows in set (0.00 sec)

//查看表行数
mysql&amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】 studb【斯丢db】.salary【晒了瑞】;
-- mysql&amp;gt; select count(*) from studb.salary;
+----------+
| count(*) |
+----------+
|     8055 |
+----------+
1 row in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;复制表头&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//仅仅复制表头like【赖特
mysql&amp;gt; create【克瑞特】 table【忒-部】 studb【斯丢db】.salary2【晒了瑞2】  like【赖特】 moershi.salary【晒了瑞】;
-- mysql&amp;gt; create table studb.salary2 like moershi.salary;
Query OK, 0 rows affected (0.95 sec)

//查看表头
mysql&amp;gt; desc studb【斯丢db】.salary2【晒了瑞2】;
-- mysql&amp;gt; desc studb.salary2;
+-------------+------+------+-----+---------+----------------+
| Field       | Type | Null | Key | Default | Extra          |
+-------------+------+------+-----+---------+----------------+
| id          | int  | NO   | PRI | NULL    | auto_increment |
| date        | date | YES  |     | NULL    |                |
| employee_id | int  | YES  | MUL | NULL    |                |
| basic       | int  | YES  |     | NULL    |                |
| bonus       | int  | YES  |     | NULL    |                |
+-------------+------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

//查看表行数
mysql&amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】 studb【斯丢db】.salary2【晒了瑞2】;
-- mysql&amp;gt; select count(*) from studb.salary2;
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、表的字段数据类型&lt;/h2&gt;
&lt;p&gt;数值类型：INT存储整数，DECIMAL存储精确小数
字符类型：CHAR适合固定长度，VARCHAR适合可变长度
日期时间：DATE存储日期，TIME存储时间
枚举类型：ENUM存储预定义值列表&lt;/p&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[表结构管理]
        direction LR
        A[表管理] --&amp;gt; B[表格字段数据类型] --&amp;gt; C[表头基本约束]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class B highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;常用数据类型：数值类型、字符类型、日期时间类型、枚举类型,每种类型都有对应的命令表示、有具体的存储范围。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;比如存储： 身高、体重、工资、奖金，适合使用数值类型。&lt;/li&gt;
&lt;li&gt;比如存储： 姓名、家庭地址、收货地址，适合使用字符类型。char&lt;/li&gt;
&lt;li&gt;比如存储： 生日、出生年份、入职时间、下班时间、注册时间，适合使用日期时间。date(日期) time(时间) datetime(时间日期) yeaer(年份)&lt;/li&gt;
&lt;li&gt;比如存储： 爱好、性别、社保医院，适合使用枚举类型。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.1 练习字符类型的使用&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//建表
mysql&amp;gt; create【克瑞特】  table【忒-部】   studb【斯丢db】.t2(name   char【查尔】(3) , address【额拽斯】   varchar【瓦儿-查儿】(5) );
-- mysql&amp;gt; create table studb.t2(name char(3),adderss varchar(5));
Query OK, 0 rows affected (0.30 sec)

//查看表头
mysql&amp;gt;  desc studb【斯丢db】.t2;
-- mysql&amp;gt; desc studb.t2;
+---------+------------+------+-----+---------+-------+
| Field   | Type       | Null | Key | Default | Extra |
+---------+------------+------+-----+---------+-------+
| name    | char(3)    | YES  |     | NULL    |       |
| address | varchar(5) | YES  |     | NULL    |       |
+---------+------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

//插入记录
mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t2 values【挖柳斯】 (&quot;a&quot;,&quot;a&quot;); //正常
-- mysql&amp;gt; insert into studb.t2 values(&quot;a&quot;,&quot;a&quot;);
Query OK, 1 row affected (0.05 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t2 values【挖柳斯】 (&quot;ab&quot;,&quot;ab&quot;); //正常
-- mysql&amp;gt; insert into studb.t2 values (&quot;ab&quot;,&quot;ab&quot;);   
Query OK, 1 row affected (0.08 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t2 values【挖柳斯】 (&quot;abc&quot;,&quot;abc&quot;);//正常
-- mysql&amp;gt; insert into studb.t2 values (&quot;abc&quot;,&quot;abc&quot;);
Query OK, 1 row affected (0.04 sec)

mysql&amp;gt;  insert【因涩特】 into【因兔】 studb【斯丢db】.t2 values【挖柳斯】 (&quot;abcd&quot;,&quot;abcd&quot;); //超出字符个数报错
-- mysql&amp;gt; insert into studb.t2 values (&quot;abcd&quot;,&quot;abcd&quot;);
ERROR 1406 (22001): Data too long for column &apos;name&apos; at row 1

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mysql8 建表默认支持中文字符集&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//查看字符集
mysql&amp;gt; show【瘦】 create【克瑞特】 table【忒-部】 studb【斯丢db】.t2 \G
-- mysql&amp;gt; show create table studb.t2 \G
*************************** 1. row ***************************
       Table: t2
Create Table: CREATE TABLE `t2` (
  `name` char【查尔】(3) DEFAULT NULL【nào】,
  `address【额拽斯】` varchar【瓦儿-查儿】(5) DEFAULT NULL【nào】
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

说明 ：
ENGINE=InnoDB  定义存储引擎（存储引擎课程里讲） 
DEFAULT   CHARSET=定义表使用的字符集 

//插入记录
mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t2 values【挖柳斯】 (&quot;张翠山&quot;,&quot;武当山&quot;);
-- mysql&amp;gt; insert into studb.t2 values(&quot;张翠山&quot;,&quot;武当山&quot;);
Query OK, 1 row affected (0.07 sec)

//查看表记录
mysql&amp;gt; SELECT【涩莱克特】  * FROM【弗乱】 studb【斯丢db】.t2;
-- mysql&amp;gt; select * from studb.t2;
+-----------+-----------+
| name      | address   |
+-----------+-----------+
| a         | a         |
| ab        | ab        |
| abc       | abc       |
| 张翠山    | 武当山     |
+-----------+-----------+
4 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 练习数值类型的使用&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//建表
mysql&amp;gt; create【克瑞特】 table【忒-部】  studb【斯丢db】.t1(name  char【查尔】(10) , level【列沃】  tinyint【泰尼因特】 unsigned【安赛因德】 ,  money【孟妮】  double【答步】  );
-- mysql&amp;gt; create table studb.t1(name char(10),level  tinyint unsigned ,  money  double  );
Query OK, 0 rows affected (0.72 sec)

//查看表头
mysql&amp;gt; desc studb【斯丢db】.t1;
-- mysql&amp;gt; desc studb.t1;
+-------+------------------+------+-----+---------+-------+
| Field | Type             | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| name  | char(10)         | YES  |     | NULL    |       |
| level | tinyint unsigned | YES  |     | NULL    |       |
| money | double           | YES  |     | NULL    |       |
+-------+------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

//插入数据
mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t1 values【挖柳斯】(&quot;法师&quot;,80,88);
-- mysql&amp;gt; insert into studb.t1 values(&quot;法师&quot;,80,88);
Query OK, 1 row affected (0.04 sec)

//超出范围报错 tinyint unsigned 最大255  可以是小数，四舍五入取整
mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t1 values【挖柳斯】(&quot;战士&quot;,301,1.292);
-- mysql&amp;gt; insert into studb.t1 values(&quot;战士&quot;,301,1.292);
ERROR 1264 (22003): Out of range value for column &apos;level【列沃】&apos; at row 1 -- 失败是因为值301超出了TINYINT UNSIGNED的数据范围（0-255）

mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t1 values【挖柳斯】(&quot;猎人&quot;,255,1.292);
-- mysql&amp;gt; insert into studb.t1 values(&quot;猎人&quot;,255,1.292);
Query OK, 1 row affected (0.06 sec)

//整数类型 不存储小数位
mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t1  values【挖柳斯】 (&quot;英雄&quot;,1.292,6.78);
-- mysql&amp;gt; insert into studb.t1 values(&quot;英雄&quot;,1.292,6.78);
Query OK, 1 row affected (0.07 sec) 

//查看表记录  
mysql&amp;gt; select【涩莱克特】 *  from【弗乱】 studb【斯丢db】.t1 ;
-- mysql&amp;gt; select * from studb.t1;
+--------+-------+-------+
| name   | level | money |
+--------+-------+-------+
| 法师   |    80 |    88 |
| 猎人   |   255 | 1.292 |
| 英雄   |     1 |  6.78 |
+--------+-------+-------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.3 枚举类型&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;//建表
mysql&amp;gt; create【克瑞特】  table【忒-部】 studb【斯丢db】.t8(
    -&amp;gt; 姓名 char【查尔】(10),
    -&amp;gt; 性别  enum【伊牛姆】(&quot;男&quot;,&quot;女&quot;,&quot;保密&quot;), 
    -&amp;gt; 爱好 set【赛特】(&quot;帅哥&quot;,&quot;金钱&quot;,&quot;吃&quot;,&quot;睡&quot;) 
    -&amp;gt; );
-- mysql&amp;gt; create table studb.t8(
--     -&amp;gt; 姓名 char(10),
--     -&amp;gt; 性别 enum(&quot;男&quot;,&quot;女&quot;,&quot;保密&quot;),
--     -&amp;gt; 爱好 set(&quot;帅哥&quot;,&quot;金钱&quot;,&quot;吃&quot;,&quot;睡&quot;));
Query OK, 0 rows affected (0.29 sec)

//查看表头
mysql&amp;gt; desc studb【斯丢db】.t8 ;
-- mysql&amp;gt; desc studb.t8;
+--------+------------------------------------+------+-----+---------+-------+
| Field  | Type                               | Null | Key | Default | Extra |
+--------+------------------------------------+------+-----+---------+-------+
| 姓名   | char(10)                           | YES  |     | NULL    |       |
| 性别   | enum(&apos;男&apos;,&apos;女&apos;,&apos;保密&apos;)             | YES  |     | NULL    |       |
| 爱好   | set(&apos;帅哥&apos;,&apos;金钱&apos;,&apos;吃&apos;,&apos;睡&apos;)       | YES  |     | NULL    |       |
+--------+------------------------------------+------+-----+---------+-------+
3 rows in set (0.01 sec)

//插入记录超出范围报错
mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t8 values【挖柳斯】 (&quot;小包总&quot;,&quot;男人&quot;,&quot;帅哥,睡,金钱&quot;);
-- mysql&amp;gt; insert into studb.t8 values (&quot;小包总&quot;,&quot;男人&quot;,&quot;帅哥,睡,金钱&quot;);
ERROR 1265 (01000): Data truncated for column &apos;性别&apos; at row 1 -- 值&quot;男人&quot;不在ENUM类型的预定义值列表中（只有&apos;男&apos;,&apos;女&apos;,&apos;保密&apos;）

mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t8 values【挖柳斯】 (&quot;小包总&quot;,&quot;男&quot;,&quot;美女,睡,金钱&quot;);
-- mysql&amp;gt; insert into studb.t8 values (&quot;小包总&quot;,&quot;男&quot;,&quot;美女,睡,金钱&quot;);
ERROR 1265 (01000): Data truncated for column &apos;爱好&apos; at row 1 --&quot;爱好&quot;字段只包含&apos;帅哥&apos;,&apos;金钱&apos;,&apos;吃&apos;,&apos;睡&apos;四个值，不包含&quot;美女&quot;这个值


//在范围内插入成功
mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t8 values【挖柳斯】 (&quot;丫丫&quot;,&quot;女&quot;,&quot;帅哥,吃&quot;);
-- mysql&amp;gt; insert into studb.t8 values(&quot;丫丫&quot;,&quot;女&quot;,&quot;帅哥,吃&quot;);
Query OK, 1 row affected (0.09 sec)

mysql&amp;gt; select【涩莱克特】  * from【弗乱】 studb【斯丢db】.t8;
-- mysql&amp;gt; select * from studb.t8;
+--------+--------+------------+
| 姓名   | 性别   | 爱好       |
+--------+--------+------------+
| 丫丫   | 女     | 帅哥,吃    |
+--------+--------+------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.4 练习日期时间类型的使用&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//建表
mysql&amp;gt; create【克瑞特】 table【忒-部】 studb【斯丢db】.t6( 
    -&amp;gt; 姓名  char【查尔】(10), 
    -&amp;gt; 生日  date , 
    -&amp;gt; 出生年份 year【耶尔】, 
    -&amp;gt; 家庭聚会  datetime , 
    -&amp;gt; 聚会地点  varchar【瓦儿-查儿】(15), 
    -&amp;gt; 上班时间 time
    -&amp;gt; );
-- mysql&amp;gt; create table studb.t6(
--     -&amp;gt; 姓名 char(10),
--     -&amp;gt; 生日 date,
--     -&amp;gt; 出生年份 year,
--     -&amp;gt; 家庭聚会 datetime,
--     -&amp;gt; 聚会地点 varchar(15),
--     -&amp;gt; 上班时间 time);
Query OK, 0 rows affected (0.25 sec)

//查看表头
mysql&amp;gt; desc studb【斯丢db】.t6 ;
-- mysql&amp;gt; desc studb.t6;
+--------------+-------------+------+-----+---------+-------+
| Field        | Type        | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| 姓名         | char(10)    | YES  |     | NULL    |       |
| 生日         | date        | YES  |     | NULL    |       |
| 出生年份     | year        | YES  |     | NULL    |       |
| 家庭聚会     | datetime    | YES  |     | NULL    |       |
| 聚会地点     | varchar(15) | YES  |     | NULL    |       |
| 上班时间     | time        | YES  |     | NULL    |       |
+--------------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

//插入表头
mysql&amp;gt; insert【因涩特】 into【因兔】  studb【斯丢db】.t6 
    -&amp;gt; values【挖柳斯】 (&quot;翠花&quot;,20211120,1990,20220101183000,&quot;天坛校区&quot;,090000);
-- mysql&amp;gt; insert into studb.t6
--     -&amp;gt; values (&quot;翠花&quot;,20211120,1990,20220101183000,&quot;天坛校区&quot;,090000);
Query OK, 1 row affected (0.05 sec)

//查看表记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 studb【斯丢db】.t6;
-- mysql&amp;gt; select * from studb.t6;
+--------+------------+--------------+---------------------+--------------+--------------+
| 姓名   | 生日       | 出生年份     | 家庭聚会            | 聚会地点     | 上班时间     |
+--------+------------+--------------+---------------------+--------------+--------------+
| 翠花   | 2021-11-20 |         1990 | 2022-01-01 18:30:00 | 天坛校区     | 09:00:00     |
+--------+------------+--------------+---------------------+--------------+--------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、表头基本约束&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[表结构管理]
        direction LR
        A[表管理] --&amp;gt; B[表格字段数据类型] --&amp;gt; C[表头基本约束]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class C highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;约束是一种限制，设置在表头上，用来控制表头的赋值，包括以下几种：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;NOT【nuō 特】 NULL【nò】 ：非空，用于保证该字段的值不能为空。&lt;/li&gt;
&lt;li&gt;DEFAULT【迪-佛特】：默认值，用于保证该字段有默认值。&lt;/li&gt;
&lt;li&gt;UNIQUE【U尼克】：唯一索引，用于保证该字段的值具有唯一性，可以为空。&lt;/li&gt;
&lt;li&gt;primary【普赖莫瑞】 KEY【kì】：主键，用于保证该字段的值具有唯一性并且非空。&lt;/li&gt;
&lt;li&gt;FOREIGN【佛润】 KEY【kì】：外键，用于限制两个表的关系，用于保证该字段的值必须来自于主表的关联列的值，在从表添加外键约束，用于引用主表中某些的值。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;5.1 表头不允许赋空值&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;//建表时给表头设置默认和不允许赋null【nào】值    
mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】 if not【nuō 特】 exists【伊贼谁斯】 db1;
-- mysql&amp;gt; create database if not exists db1;
Query OK, 1 row affected (0.07 sec)

//建表
mysql&amp;gt; create【克瑞特】 table【忒-部】 db1.t31(
    -&amp;gt; name char【查尔】(10) not【nuō 特】 null【nào】 , 
    -&amp;gt; class【克拉斯】 char【查尔】(7) default【迪-佛特】 &quot;nsd&quot;,
    -&amp;gt; likes【赖特s】 set【赛特】(&quot;money【孟妮】&quot;,&quot;game&quot;,&quot;film&quot;,&quot;music&quot;) not【nuō 特】 null【nào】  default【迪-佛特】 &quot;film,music&quot; );
-- mysql&amp;gt; create table db1.t31(
--     -&amp;gt; name char(10) not null,
--     -&amp;gt; class char(7) default &quot;nsd&quot;,
--     -&amp;gt; likes set(&quot;money&quot;,&quot;game&quot;,&quot;film&quot;,&quot;music&quot;) not null default &quot;film,music&quot; );
Query OK, 0 rows affected (0.43 sec)

//查看表头
mysql&amp;gt; desc db1.t31;
-- mysql&amp;gt; desc db1.t31;
+-------+------------------------------------+------+-----+------------+-------+
| Field | Type                               | Null | Key | Default    | Extra |
+-------+------------------------------------+------+-----+------------+-------+
| name  | char(10)                           | NO   |     | NULL       |       |
| class | char(7)                            | YES  |     | nsd        |       |
| likes | set(&apos;money&apos;,&apos;game&apos;,&apos;film&apos;,&apos;music&apos;) | NO   |     | film,music |       |
+-------+------------------------------------+------+-----+------------+-------+
3 rows in set (0.01 sec)

//验证默认值和不允许为null
mysql&amp;gt; insert【因涩特】 into【因兔】  db1.t31 values【挖柳斯】 (null, null , null); 
-- mysql&amp;gt; insert into db1.t31 values(null, null , null); 
ERROR 1048 (23000): Column &apos;name&apos; cannot be null  //表头name赋null值 报错

//表头likes【赖特s】赋null值 报错
mysql&amp;gt; insert【因涩特】 into【因兔】  db1.t31 values【挖柳斯】 (&quot;bob&quot;, null , null);
-- mysql&amp;gt; insert into db1.t31 values(&quot;bob&quot;, null , null);
ERROR 1048 (23000): Column &apos;likes&apos; cannot be null   

//符合约束不报错
mysql&amp;gt; insert【因涩特】 into【因兔】  db1.t31 values【挖柳斯】 (&quot;bob&quot;,null,&quot;money【孟妮】,game,film&quot;); 
-- mysql&amp;gt; insert into db1.t31 values(&quot;bob&quot;,null,&quot;money,game,film&quot;); 
Query OK, 1 row affected (0.06 sec)

//不赋值的表头使用默认值赋值
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t31(name) values【挖柳斯】(&quot;jim&quot;);  
-- mysql&amp;gt; insert into db1.t31(name) values(&quot;jim&quot;);
-- Query OK, 1 row affected (0.01 sec)

//根据需要自定义表头的值
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t31 values【挖柳斯】 (&quot;lucy&quot;,&quot;nsd2108&quot;,&quot;game,film&quot;); 
-- mysql&amp;gt; insert into db1.t31 values(&quot;lucy&quot;,&quot;nsd2108&quot;,&quot;game,film&quot;);
-- Query OK, 1 row affected (0.14 sec)

//查看表记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.t31;
-- mysql&amp;gt; select * from db1.t31;
+------+---------+-----------------+
| name | class   | likes           |
+------+---------+-----------------+
| bob  | NULL    | money,game,film |
| jim  | nsd     | film,music      |
| lucy | nsd2108 | game,film       |
+------+---------+-----------------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 表头加唯一索引练习&lt;/h3&gt;
&lt;p&gt;唯一索引 （unique【U尼克】）&lt;/p&gt;
&lt;p&gt;约束的方式：表头值唯一 , 但可以赋null 值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//建表
create【克瑞特】      table【忒-部】  db1.t32 (姓名  char【查尔】(10)  ,  护照   char【查尔】(18)  unique【U尼克】  );
-- mysql&amp;gt; create table db1.t32 (姓名 char(10) , 护照 char(18) unique);

//查看表头 唯一索引标志UNI
mysql&amp;gt; desc db1.t32 ;
-- mysql&amp;gt; desc db1.t32;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| 姓名   | char(10) | YES  |     | NULL    |       |
| 护照   | char(18) | YES  | UNI | NULL    |       |
+--------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec) 

//赋null值 可以
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t32 values【挖柳斯】(&quot;bob&quot;,null);
-- mysql&amp;gt; insert into db1.t32 values(&quot;bob&quot;,null);
Query OK, 1 row affected (0.07 sec)

//表头值重复不可以
mysql&amp;gt;  insert【因涩特】 into【因兔】 db1.t32 values【挖柳斯】(&quot;tom&quot;,&quot;666888&quot;);
-- mysql&amp;gt; insert into db1.t32 values(&quot;tom&quot;,&quot;666888&quot;);
Query OK, 1 row affected (0.08 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t32 values【挖柳斯】(&quot;jim&quot;,&quot;666888&quot;);
-- mysql&amp;gt; insert into db1.t32 values(&quot;jim&quot;,&quot;666888&quot;);
ERROR 1062 (23000): Duplicate entry &apos;666888&apos; for key【kì】 &apos;t32.护照&apos;

//不重复 可以
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t32 values【挖柳斯】(&quot;jim&quot;,&quot;766888&quot;); 
-- mysql&amp;gt; insert into db1.t32 values(&quot;jim&quot;,&quot;766888&quot;);
Query OK, 1 row affected (0.05 sec) 

//查看表记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 DB1.t32;
-- mysql&amp;gt; select * from db1.t32;
+------+--------+
| 姓名  | 护照  |
+------+--------+
| bob  | NULL   |
| tom  | 666888 |
| jim  | 766888 |
+------+--------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;/h3&gt;
&lt;p&gt;2 bob nsd2107 bj&lt;/p&gt;
&lt;p&gt;3 bob nsd2107 bj&lt;/p&gt;
&lt;p&gt;4 bob nsd2107 bj&lt;/p&gt;
&lt;p&gt;1）建表&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】     table【忒-部】   db1.t38 (
    -&amp;gt; 行号   int【因特】   primary【普赖莫瑞】 key【kì】  auto_increment【奥特欧_因克瑞门特】   , 
    -&amp;gt; 姓名   char【查尔】(10) , 
    -&amp;gt; 班级   char【查尔】(7) , 
    -&amp;gt; 住址   char【查尔】(10)
    -&amp;gt; );
-- mysql&amp;gt; create table db1.t38(
--     -&amp;gt; 行号 int primary key auto_increment,
--     -&amp;gt; 姓名 char(10),
--     -&amp;gt; 班级 char(7),
--     -&amp;gt; 住址 char(10));
Query OK, 0 rows affected (0.76 sec)

//查看表头
mysql&amp;gt; desc db1.t38 ;
-- mysql&amp;gt; desc db1.t38;
+--------+----------+------+-----+---------+----------------+
| Field  | Type     | Null | Key | Default | Extra          |
+--------+----------+------+-----+---------+----------------+
| 行号   | int      | NO   | PRI | NULL    | auto_increment |
| 姓名   | char(10) | YES  |     | NULL    |                |
| 班级   | char(7)  | YES  |     | NULL    |                |
| 住址   | char(10) | YES  |     | NULL    |                |
+--------+----------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

//插入表记录 不给自增长表头赋值
mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;bob&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;bob&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
Query OK, 1 row affected (0.05 sec)

mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;bob&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;bob&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
Query OK, 1 row affected (0.04 sec)

mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;tom&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;tom&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
Query OK, 1 row affected (0.05 sec)

//查看表记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.t38;
-- mysql&amp;gt; select * from db1.t38;
+--------+--------+---------+--------+
| 行号   | 姓名   | 班级    | 住址   |
+--------+--------+---------+--------+
|      1 | bob    | nsd2107 | bj     |
|      2 | bob    | nsd2107 | bj     |
|      3 | tom    | nsd2107 | bj     |
+--------+--------+---------+--------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、作业&lt;/h2&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;在 MySQL 中创建表时，用于定义字段为字符类型且长度为 20 的是以下哪种写法？A
A. CHAR(20)
B. TEXT(20)
C. INT(20)
D. FLOAT(20)&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;讲解：CHAR是固定长度的字符类型，TEXT是可变长度文本类型不能指定长度，INT是整数类型，FLOAT是浮点数类型。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;若要修改表名为 &lt;code&gt;students&lt;/code&gt; 的表，将其中 &lt;code&gt;age&lt;/code&gt; 字段的数据类型从 &lt;code&gt;INT&lt;/code&gt; 改为 &lt;code&gt;SMALLINT&lt;/code&gt;，应使用以下哪条语句？ B
A. UPDATE TABLE students CHANGE age age SMALLINT;
B. ALTER TABLE students MODIFY age SMALLINT;
C. MODIFY TABLE students ALTER age SMALLINT;
D. CHANGE TABLE students UPDATE age SMALLINT;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;讲解：使用ALTER TABLE + MODIFY来修改字段数据类型，CHANGE用于修改字段名。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;以下哪种方法可以复制表 &lt;code&gt;orders&lt;/code&gt; 的结构和数据到新表 &lt;code&gt;orders_copy&lt;/code&gt; ？A
A. CREATE TABLE orders_copy AS SELECT * FROM orders;
B. COPY TABLE orders TO orders_copy;
C. INSERT INTO orders_copy SELECT * FROM orders;
D. CLONE TABLE orders orders_copy;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;讲解：这是最常用的复制表方法，会同时复制表结构和数据。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;以下适合存储邮件地址的字段类型是？C
A. DATE
B. DECIMAL
C. VARCHAR
D. TINYINT&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;讲解：邮件地址是可变长度字符串，VARCHAR最适合。DATE是日期，DECIMAL是小数，TINYINT是整数。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;要在创建表 &lt;code&gt;products&lt;/code&gt; 时，确保 &lt;code&gt;product_name&lt;/code&gt; 字段的值不为空，应使用以下哪种约束？ B
A. UNIQUE
B. NOT NULL
C. CHECK
D. DEFAULT&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;讲解：NOT NULL约束确保字段必须有值，不能为空。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;简述在 MySQL 中创建表时，如何选择合适的字段类型，请举例说明。
答：
存储： 身高、体重、工资、奖金，适合使用数值类型。如：tinyint unsigned、long、int
存储： 姓名、家庭地址、收货地址，适合使用字符类型。如：char、varchar
存储： 生日、出生年份、入职时间、下班时间、注册时间，适合使用日期时间。date、time、datetime、year
存储： 爱好、性别、社保医院，适合使用枚举类型。如：enum、set&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;说明使用 &lt;code&gt;ALTER TABLE&lt;/code&gt; 语句修改表结构时，修改字段名和修改字段数据类型的操作有什么不同。
答：
1. 修改字段数据类型：
语法：alter table 数据库.表 modify 字段名 新数据类型;
2. 修改字段名：
语法：alter table 数据库.表 change 旧字段名 新字段名 数据类型;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;复制表有哪几种常见方式，它们各自的优缺点是什么？
答：
1. 复制表结构（不复制数据）
语法：CREATE TABLE 新表名 LIKE 旧表名;
优点：快速，只复制结构
缺点：不包含数据
2. 复制表结构和数据：
语法：CREATE TABLE 新表名 AS SELECT * FROM 旧表名;
优点：同时复制结构和数据
缺点：不复制索引和约束&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;解释表的基本约束 &lt;code&gt;NOT NULL&lt;/code&gt; 和 &lt;code&gt;DEFAULT&lt;/code&gt; 的作用，并举例说明如何在创建表时使用。
答：
NOT NULL：
作用：
不允许字段为空、字段必须有值
举例：
create table 数据库.表 (字段名 数据类型 not null);
DEFAULT：
作用：
设置字段的默认值、当不赋值时使用
举例：
create table 数据库.表 (字段名 数据类型 default 默认值);&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3 操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;创建一个名为 &lt;code&gt;books&lt;/code&gt; 的表，包含字段 &lt;code&gt;book_title&lt;/code&gt;（字符串类型，长度不超过 100）、&lt;code&gt;publish_year&lt;/code&gt;（年份类型）、&lt;code&gt;price&lt;/code&gt;（小数类型，保留两位小数）。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create table if not exists studb.books (
    -&amp;gt; id int auto_increment primary key,
    -&amp;gt; book_title varchar(100),
    -&amp;gt; publish_year year,
    -&amp;gt; price decimal(10,2)
    -&amp;gt; );
Query OK, 0 rows affected (0.94 sec)

mysql&amp;gt; desc studb.books;
+--------------+---------------+------+-----+---------+----------------+
| Field        | Type          | Null | Key | Default | Extra          |
+--------------+---------------+------+-----+---------+----------------+
| id           | int           | NO   | PRI | NULL    | auto_increment |
| book_title   | varchar(100)  | YES  |     | NULL    |                |
| publish_year | year          | YES  |     | NULL    |                |
| price        | decimal(10,2) | YES  |     | NULL    |                |
+--------------+---------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;在 &lt;code&gt;books&lt;/code&gt; 表中添加一个新字段 &lt;code&gt;author&lt;/code&gt;，类型为字符串，长度不超过 50。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; 
mysql&amp;gt; alter table studb.books add author varchar(50);
Query OK, 0 rows affected (2.88 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql&amp;gt; desc studb.books;
+--------------+---------------+------+-----+---------+----------------+
| Field        | Type          | Null | Key | Default | Extra          |
+--------------+---------------+------+-----+---------+----------------+
| id           | int           | NO   | PRI | NULL    | auto_increment |
| book_title   | varchar(100)  | YES  |     | NULL    |                |
| publish_year | year          | YES  |     | NULL    |                |
| price        | decimal(10,2) | YES  |     | NULL    |                |
| author       | varchar(50)   | YES  |     | NULL    |                |
+--------------+---------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;复制 &lt;code&gt;books&lt;/code&gt; 表的结构和数据到一个新表 &lt;code&gt;books_archive&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; create table studb.books_archive select * from studb.books;
Query OK, 0 rows affected (1.29 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql&amp;gt; show tables;
+-----------------+
| Tables_in_studb |
+-----------------+
| books           |
| books_archive   |
| salary          |
| salary2         |
| stuinfo         |
| t1              |
| t2              |
| t6              |
| t8              |
+-----------------+
9 rows in set (0.00 sec)

mysql&amp;gt; desc books_archive;
+--------------+---------------+------+-----+---------+-------+
| Field        | Type          | Null | Key | Default | Extra |
+--------------+---------------+------+-----+---------+-------+
| id           | int           | NO   |     | 0       |       |
| book_title   | varchar(100)  | YES  |     | NULL    |       |
| publish_year | year          | YES  |     | NULL    |       |
| price        | decimal(10,2) | YES  |     | NULL    |       |
| author       | varchar(50)   | YES  |     | NULL    |       |
+--------------+---------------+------+-----+---------+-------+
5 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;修改 &lt;code&gt;books&lt;/code&gt; 表中 &lt;code&gt;price&lt;/code&gt; 字段的默认值为 0。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; alter table books modify price decimal(10,2) default 0;
Query OK, 0 rows affected (0.23 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql&amp;gt; desc books;
+--------------+---------------+------+-----+---------+----------------+
| Field        | Type          | Null | Key | Default | Extra          |
+--------------+---------------+------+-----+---------+----------------+
| id           | int           | NO   | PRI | NULL    | auto_increment |
| book_title   | varchar(100)  | YES  |     | NULL    |                |
| publish_year | year          | YES  |     | NULL    |                |
| price        | decimal(10,2) | YES  |     | 0.00    |                |
| author       | varchar(50)   | YES  |     | NULL    |                |
+--------------+---------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;将 &lt;code&gt;books&lt;/code&gt; 表中的 &lt;code&gt;book_title&lt;/code&gt; 字段设置为不允许为空。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; alter table books modify book_title varchar(100) not null;
Query OK, 0 rows affected (2.19 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql&amp;gt; desc books;
+--------------+---------------+------+-----+---------+----------------+
| Field        | Type          | Null | Key | Default | Extra          |
+--------------+---------------+------+-----+---------+----------------+
| id           | int           | NO   | PRI | NULL    | auto_increment |
| book_title   | varchar(100)  | NO   |     | NULL    |                |
| publish_year | year          | YES  |     | NULL    |                |
| price        | decimal(10,2) | YES  |     | 0.00    |                |
| author       | varchar(50)   | YES  |     | NULL    |                |
+--------------+---------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>06: mysql之主键外键索引</title><link>https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/06-mysql%E4%B9%8B%E4%B8%BB%E9%94%AE%E5%A4%96%E9%94%AE%E7%B4%A2%E5%BC%95/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/06-mysql%E4%B9%8B%E4%B8%BB%E9%94%AE%E5%A4%96%E9%94%AE%E7%B4%A2%E5%BC%95/</guid><description>06: mysql之主键外键索引 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 09:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[toc]&lt;/p&gt;
&lt;h1&gt;06: mysql之主键外键索引&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[主键外键索引]
        direction LR
        A[主键] --&amp;gt; B[外键] --&amp;gt; C[MySQL索引]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class E highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;小型电商公司&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;林悦是一家小型电商公司的数据库管理员。随着业务发展，订单量逐渐增多，数据库查询变得缓慢。林悦发现订单表缺乏主键约束，数据存在重复，在查询某一订单时效率极低。同时，订单表和商品表之间没有设置外键关联，导致数据一致性难以保证。她为订单表添加主键，建立订单表与商品表的外键关系，并在经常用于查询的字段上创建索引，大大提高了数据查询和写入的效率，保障了数据的准确性。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;大型互联网企业&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;张成就职于大型互联网企业，负责管理用户相关数据库。该企业用户数量庞大，每天产生海量数据。在用户表中，使用自增主键确保数据的唯一标识。为了关联用户表和用户行为表，设置了外键约束，保证数据的参照完整性。随着业务复杂度增加，查询需求多样化，他依据不同业务需求，在用户表的常用查询字段如“注册时间”“用户等级”上创建索引，显著提升了系统响应速度。&lt;/p&gt;
&lt;h2&gt;二、作用、为什么要学呢&lt;/h2&gt;
&lt;p&gt;学习 MySQL 的主键、外键和索引十分必要。&lt;/p&gt;
&lt;p&gt;从数据完整性看
主键能唯一标识表中每行数据，防止数据重复，确保数据准确。
外键可建立表间关联，保证数据参照完整性，避免出现孤立或错误关联的数据。&lt;/p&gt;
&lt;p&gt;从查询性能上
索引能加快数据查询速度。在海量数据中，如果没有索引，查询会全表扫描，效率极低。
合理创建索引后，数据库能快速定位到所需数据。&lt;/p&gt;
&lt;p&gt;在实际应用里
如电商系统、金融系统等，都离不开这些技术保障数据质量与系统性能。
掌握它们能让你更高效地管理和操作数据库，为项目稳定运行提供有力支持。&lt;/p&gt;
&lt;h2&gt;三、主键&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[主键外键索引]
        direction LR
        A[主键] --&amp;gt; B[外键] --&amp;gt; C[MySQL索引]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class A highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;主键使用规则：&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;表头值不允许重复，不允许赋NULL【nò】值&lt;/li&gt;
&lt;li&gt;一个表中只能有一个primary【普赖莫瑞】 key【kì】 表头&lt;/li&gt;
&lt;li&gt;多个表头做主键，称为复合主键，必须一起创建和删除&lt;/li&gt;
&lt;li&gt;主键标志PRI&lt;/li&gt;
&lt;li&gt;主键通常与auto_increment【奥特欧_因克瑞门特】连用&lt;/li&gt;
&lt;li&gt;通常把表中唯一标识记录的表头设置为主键[行号表]&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3.1 主键的创建、查看、删除、添加、验证主键&lt;/h3&gt;
&lt;h4&gt;创建表时创建主键&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//语法格式1
create【克瑞特】  table【忒-部】  库.表（ 表头名 数据类型  primary【普赖莫瑞】 key【kì】  , 表头名  数据类型 , ..... ）;

//建表
mysql&amp;gt;  create【克瑞特】 table【忒-部】 db1.t35(
    -&amp;gt; name char【查尔】(10) , 
    -&amp;gt; hz_id  char【查尔】(10) primary【普赖莫瑞】 key【kì】  , 
    -&amp;gt; class【克拉斯】 char【查尔】(10) 
    -&amp;gt; );
-- mysql&amp;gt; create table db1.t35(
--     -&amp;gt; name char(10),
--     -&amp;gt; hz_id char(10) primary key,
--     -&amp;gt; class char(10));
Query OK, 0 rows affected (0.49 sec)

//查看表头
mysql&amp;gt; desc db1.t35;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| name  | char(10) | YES  |     | NULL    |       |
| hz_id | char(10) | NO   | PRI | NULL    |       |
| class | char(10) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

//语法格式2
create【克瑞特】  table【忒-部】  库.表（ 字段名 类型 , 字段名 类型 , primary【普赖莫瑞】 key【kì】（字段名） ）;

//建表
mysql&amp;gt; create【克瑞特】 table【忒-部】 db1.t36(
    -&amp;gt; name char【查尔】(10) , 
    -&amp;gt; hz_id  char【查尔】(10) , 
    -&amp;gt; class【克拉斯】 char【查尔】(10),
    -&amp;gt; primary【普赖莫瑞】 key【kì】(hz_id)  
    -&amp;gt; );
-- mysql&amp;gt; create table db1.t36(
--     -&amp;gt; name char(10),
--     -&amp;gt; hz_id char(10),
--     -&amp;gt; class char(10),
--     -&amp;gt; primary key(hz_id));
Query OK, 0 rows affected (0.39 sec)

//查看表头
mysql&amp;gt; desc db1.t36;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| name  | char(10) | YES  |     | NULL    |       |
| hz_id | char(10) | NO   | PRI | NULL    |       |
| class | char(10) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;删除主键&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//删除主键命令格式
mysql&amp;gt; alter【奥-特】  table【忒-部】   库.表   drop【卓-普】 primary【普赖莫瑞】 key【kì】 ;

//例子
mysql&amp;gt;  alter【奥-特】  table【忒-部】 db1.t36  drop【卓-普】 primary【普赖莫瑞】 key【kì】 ;
-- mysql&amp;gt; alter table db1.t36 drop primary key;
Query OK, 0 rows affected (1.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

//查看表头
mysql&amp;gt; desc  db1.t36;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| name  | char(10) | YES  |     | NULL    |       |
| hz_id | char(10) | NO   |     | NULL    |       |
| class | char(10) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql&amp;gt; 

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;添加主键&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//添加主键命令格式
mysql&amp;gt; alter【奥-特】  table【忒-部】  库.表  add  primary【普赖莫瑞】 key【kì】(表头名);

//例子
mysql&amp;gt; alter【奥-特】  table【忒-部】  db1.t36  add  primary【普赖莫瑞】 key【kì】(hz_id);
-- mysql&amp;gt; alter table db1.t36 add primary key(hz_id);
mysql&amp;gt; desc db1.t36;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| name  | char(10) | YES  |     | NULL    |       |
| hz_id | char(10) | NO   | PRI | NULL    |       |
| class | char(10) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;验证主键约束&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//使用t35表 验证主键约束
//查看主键表头
mysql&amp;gt; desc db1.t35;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| name  | char(10) | YES  |     | NULL    |       |
| hz_id | char(10) | NO   | PRI | NULL    |       |
| class | char(10) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

-- 插入第1条记录 正常
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t35  values【挖柳斯】 (&quot;bob&quot;,&quot;888&quot;,&quot;nsd2107&quot;);
-- mysql&amp;gt; insert into db1.t35 values(&quot;bob&quot;,&quot;888&quot;,&quot;nsd2107&quot;);
Query OK, 1 row affected (0.05 sec)

-- 主键表头值不允许为null【nò】，否则插入失败
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t35  values【挖柳斯】 (&quot;john&quot;,null【nò】,&quot;nsd2107&quot;); 
-- mysql&amp;gt; insert into db1.t35 values(&quot;john&quot;,null,&quot;nsd2107&quot;);
ERROR 1048 (23000): Column &apos;hz_id&apos; cannot be null【nò】
mysql&amp;gt; 

-- 主键表头值不允许重复，否则插入失败
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t35  values【挖柳斯】 (&quot;john&quot;,&quot;888&quot;,&quot;nsd2107&quot;); 
-- mysql&amp;gt; insert into db1.t35 values(&quot;john&quot;,&quot;888&quot;,&quot;nsd2107&quot;);
ERROR 1062 (23000): Duplicate entry &apos;888&apos; for key【kì】 &apos;primary【普赖莫瑞】&apos;

-- 主键表头值不重复也不是null【nò】可以
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t35  values【挖柳斯】 (&quot;john&quot;,&quot;988&quot;,&quot;nsd2107&quot;); 
-- mysql&amp;gt; insert into db1.t35 values(&quot;john&quot;,&quot;988&quot;,&quot;nsd2107&quot;);
Query OK, 1 row affected (0.07 sec)

-- 查看表记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.t35 ;
-- mysql&amp;gt; select * from db1.t35;
+------+-------+---------+
| name | hz_id | class   |
+------+-------+---------+
| bob  | 888   | nsd2107 |
| john | 988   | nsd2107 |
+------+-------+---------+
2 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 复合主键的使用&lt;/h3&gt;
&lt;h4&gt;创建表时创建复合主键&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;-- 创建复合主键 表头依次是客户端ip 、服务端口号、访问状态
mysql&amp;gt; create【克瑞特】  table【忒-部】  db1.t39(
cip   varchar【瓦儿-查儿】(15) , 
port【破特】  smallint【斯莫尔因特】,  
status【s 塔丢】  enum【ing纽某】(&quot;deny【迪奈】&quot;,&quot;allow【饿劳】&quot;) , 
primary【普赖莫瑞】 key【kì】(cip,port【破特】)
);
-- mysql&amp;gt; create table db1.t39(
--     -&amp;gt; cip varchar(15),
--     -&amp;gt; port smallint,
--     -&amp;gt; status enum(&quot;deny&quot;,&quot;allow&quot;),
--     -&amp;gt; primary key(cip,port));

-- 插入记录验证
insert【因涩特】 into【因兔】  db1.t39  values【挖柳斯】 (&quot;1.1.1.1&quot;,22,&quot;deny【迪奈】&quot;);
-- mysql&amp;gt; insert into db1.t39 values(&quot;1.1.1.1&quot;,22,&quot;deny&quot;);
-- Query OK, 1 row affected (0.09 sec)

insert【因涩特】 into【因兔】  db1.t39  values【挖柳斯】 (&quot;1.1.1.1&quot;,22,&quot;deny【迪奈】&quot;); --两个复合主键相同报错
-- mysql&amp;gt; insert into db1.t39 values(&quot;1.1.1.1&quot;,22,&quot;deny&quot;);
-- ERROR 1062 (23000): Duplicate entry &apos;1.1.1.1-22&apos; for key &apos;t39.PRIMARY&apos;

insert【因涩特】 into【因兔】  db1.t39  values【挖柳斯】 (&quot;1.1.1.1&quot;,80,&quot;deny【迪奈】&quot;); -- 单个复合主键相同可以插入
-- mysql&amp;gt; insert into db1.t39 values(&quot;1.1.1.1&quot;,80,&quot;deny&quot;);
-- Query OK, 1 row affected (0.10 sec)

insert【因涩特】 into【因兔】  db1.t39  values【挖柳斯】 (&quot;2.1.1.1&quot;,80,&quot;allow【饿劳】&quot;); -- 单个复合主键相同可以插入
-- mysql&amp;gt; insert into db1.t39 values(&quot;2.1.1.1&quot;,80,&quot;allow&quot;);
-- Query OK, 1 row affected (0.10 sec)

-- 查看记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.t39;
-- mysql&amp;gt; select * from db1.t39;
+---------+------+--------+
| cip     | port | status |
+---------+------+--------+
| 1.1.1.1 |   22 | deny   |
| 1.1.1.1 |   80 | deny   |
| 2.1.1.1 |   80 | allow  |
+---------+------+--------+
3 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;删除复合主键&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//删除复合主键
mysql&amp;gt; alter【奥-特】 table【忒-部】  db1.t39 drop【卓-普】 primary【普赖莫瑞】 key【kì】;
-- mysql&amp;gt; alter table db1.t39 drop primary key;
Query OK, 3 rows affected (1.10 sec)
Records: 3  Duplicates: 0  Warnings: 0

//查看表头
mysql&amp;gt;  desc  db1.t39;
-- mysql&amp;gt; desc db1.t39; 
+--------+----------------------+------+-----+---------+-------+
| Field  | Type                 | Null | Key | Default | Extra |
+--------+----------------------+------+-----+---------+-------+
| cip    | varchar(15)          | NO   |     | NULL    |       |
| port   | smallint             | NO   |     | NULL    |       |
| status | enum(&apos;deny&apos;,&apos;allow&apos;) | YES  |     | NULL    |       |
+--------+----------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

//没有复合主键约束后 ，插入记录不受限制了
mysql&amp;gt;  insert【因涩特】 into【因兔】 db1.t39 values【挖柳斯】(&quot;2.1.1.1&quot;,80,&quot;allow【饿劳】&quot;);
-- mysql&amp;gt; insert into db1.t39 values(&quot;2.1.1.1&quot;,80,&quot;allow&quot;); 
Query OK, 1 row affected (0.06 sec)
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t39 values【挖柳斯】(&quot;2.1.1.1&quot;,80,&quot;deny【迪奈】&quot;);
--mysql&amp;gt; insert into db1.t39 values(&quot;2.1.1.1&quot;,80,&quot;deny&quot;);  
Query OK, 1 row affected (0.08 sec)

//查看表记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】  db1.t39;
-- mysql&amp;gt; select * from db1.t39;
+---------+------+--------+
| cip     | port | status |
+---------+------+--------+
| 1.1.1.1 |   22 | deny   |
| 1.1.1.1 |   80 | deny   |
| 2.1.1.1 |   80 | allow  |
| 2.1.1.1 |   80 | allow  |
| 2.1.1.1 |   80 | deny   |
+---------+------+--------+
5 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;添加复合主键&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//添加复合主键时 字段下的数据与主键约束冲突 不允许添加
mysql&amp;gt; alter【奥-特】 table【忒-部】  db1.t39 add primary【普赖莫瑞】 key【kì】(cip,port【破特】);
-- mysql&amp;gt; alter table db1.t39 add primary key(cip,port); 
ERROR 1062 (23000): Duplicate entry &apos;2.1.1.1-80&apos; for key【kì】 &apos;t39.primary【普赖莫瑞】&apos;

//删除重复的数据
mysql&amp;gt; delete【迪  利 特】 from【弗乱】 db1.t39 where【威尔】 cip=&quot;2.1.1.1&quot;;
-- mysql&amp;gt; delete from db1.t39 where cip=&quot;2.1.1.1&quot;; 
Query OK, 3 rows affected (0.05 sec)

mysql&amp;gt; select【涩莱克特】  * from【弗乱】  db1.t39;
-- mysql&amp;gt; select * from db1.t39;
+---------+------+--------+
| cip     | port | status |
+---------+------+--------+
| 1.1.1.1 |   22 | deny   |
| 1.1.1.1 |   80 | deny   |
+---------+------+--------+
2 rows in set (0.00 sec)

//添加复合主键
mysql&amp;gt; alter【奥-特】 table【忒-部】  db1.t39 add primary【普赖莫瑞】 key【kì】(cip,port【破特】);
-- mysql&amp;gt; alter table db1.t39 add primary key(cip,port);
Query OK, 0 rows affected (0.67 sec)
Records: 0  Duplicates: 0  Warnings: 0

//查看表头
mysql&amp;gt;  desc  db1.t39;
-- mysql&amp;gt; desc db1.t39;
+--------+----------------------+------+-----+---------+-------+
| Field  | Type                 | Null | Key | Default | Extra |
+--------+----------------------+------+-----+---------+-------+
| cip    | varchar(15)          | NO   | PRI | NULL    |       |
| port   | smallint             | NO   | PRI | NULL    |       |
| status | enum(&apos;deny&apos;,&apos;allow&apos;) | YES  |     | NULL    |       |
+--------+----------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3  auto_increment【奥特欧_因克瑞门特】的使用&lt;/h3&gt;
&lt;p&gt;表头设置了auto_increment【奥特欧_因克瑞门特】属性后，&lt;/p&gt;
&lt;p&gt;插入记录时，如果不给表头赋值表头通过自加1的计算结果赋值&lt;/p&gt;
&lt;p&gt;要想让表头有自增长 表头必须有主键设置才可以&lt;/p&gt;
&lt;p&gt;查看表结构时 在 Extra【埃斯处了】 （额外设置） 位置显示&lt;/p&gt;
&lt;p&gt;建表时 创建有auto_increment【奥特欧_因克瑞门特】 属性的表头。实现的效果如下：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;行号&lt;/th&gt;
&lt;th&gt;姓名&lt;/th&gt;
&lt;th&gt;班级&lt;/th&gt;
&lt;th&gt;住址&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;bob&lt;/td&gt;
&lt;td&gt;nsd2107&lt;/td&gt;
&lt;td&gt;bj&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;bob&lt;/td&gt;
&lt;td&gt;nsd2107&lt;/td&gt;
&lt;td&gt;bj&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;bob&lt;/td&gt;
&lt;td&gt;nsd2107&lt;/td&gt;
&lt;td&gt;bj&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;bob&lt;/td&gt;
&lt;td&gt;nsd2107&lt;/td&gt;
&lt;td&gt;bj&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;1）建表&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】     table【忒-部】   db1.t38 (
    -&amp;gt; 行号   int【因特】   primary【普赖莫瑞】 key【kì】  auto_increment【奥特欧_因克瑞门特】, 
    -&amp;gt; 姓名   char【查尔】(10) , 
    -&amp;gt; 班级   char【查尔】(7) , 
    -&amp;gt; 住址   char【查尔】(10)
    -&amp;gt; );
-- mysql&amp;gt; create table db1.t38(
--     -&amp;gt; 行号 int primary key auto_increment,
--     -&amp;gt; 姓名 char(10),
--     -&amp;gt; 班级 char(7),
--     -&amp;gt; 住址 char(10));
Query OK, 0 rows affected (0.76 sec)

//查看表头
mysql&amp;gt; desc db1.t38 ;
-- mysql&amp;gt; desc db1.t38;
+--------+----------+------+-----+---------+----------------+
| Field  | Type     | Null | Key | Default | Extra          |
+--------+----------+------+-----+---------+----------------+
| 行号   | int      | NO   | PRI | NULL    | auto_increment |
| 姓名   | char(10) | YES  |     | NULL    |                |
| 班级   | char(7)  | YES  |     | NULL    |                |
| 住址   | char(10) | YES  |     | NULL    |                |
+--------+----------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

//插入表记录 不给自增长表头赋值
mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址)  values【挖柳斯】(&quot;bob&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;bob&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
Query OK, 1 row affected (0.05 sec)

mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;bob&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;bob&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
Query OK, 1 row affected (0.04 sec)

mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;tom&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;tom&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
Query OK, 1 row affected (0.05 sec)

//查看表记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.t38;
-- mysql&amp;gt; select * from db1.t38;
+--------+--------+---------+--------+
| 行号   | 姓名   | 班级    | 住址   |
+--------+--------+---------+--------+
|      1 | bob    | nsd2107 | bj     |
|      2 | bob    | nsd2107 | bj     |
|      3 | tom    | nsd2107 | bj     |
+--------+--------+---------+--------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;自增长使用注意事项&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//给自增长字段的赋值
mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(行号,姓名,班级,住址) values【挖柳斯】(5,&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);  
-- mysql&amp;gt; insert into db1.t38(行号,姓名,班级,住址) values(5,&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);  
Query OK, 1 row affected (0.26 sec)

//不赋值后 用最后1条件记录表头的值+1结果赋值
mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);  
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);  
Query OK, 1 row affected (0.03 sec)

//查看记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.t38 ;
-- mysql&amp;gt; select * from db1.t38;
+--------+--------+---------+--------+
| 行号   | 姓名   | 班级    | 住址   |
+--------+--------+---------+--------+
|      1 | bob    | nsd2107 | bj     |
|      2 | bob    | nsd2107 | bj     |
|      3 | tom    | nsd2107 | bj     |
|      5 | lucy   | nsd2107 | bj     |
|      6 | lucy   | nsd2107 | bj     |
+--------+--------+---------+--------+
5 rows in set (0.00 sec)

//删除所有行
mysql&amp;gt; delete【迪  利 特】  from【弗乱】  db1.t38 ； 
-- mysql&amp;gt; delete from db1.t38; 

//再添加行 继续行号 而不是从 1 开始 
mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);

mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);

mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);

//查看记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.t38;
-- mysql&amp;gt; select * from db1.t38;
+--------+--------+---------+--------+
| 行号   | 姓名   | 班级    | 住址   |
+--------+--------+---------+--------+
|      8 | lucy   | nsd2107 | bj     |
|      9 | lucy   | nsd2107 | bj     |
|     10 | lucy   | nsd2107 | bj     |
+--------+--------+---------+--------+
3 rows in set (0.01 sec)


-- truncate【创kí特】删除行，会同时重置auto_increment值为1开始
//truncate【创kí特】删除行 再添加行 从1开始 
mysql&amp;gt; truncate【创kí特】 table【忒-部】  db1.t38;  
-- mysql&amp;gt; truncate table db1.t38;
Query OK, 0 rows affected (2.66 sec)

//插入记录
mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
Query OK, 1 row affected (0.04 sec)

mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;); 
Query OK, 1 row affected (0.30 sec)

//查看记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.t38;
-- mysql&amp;gt; select * from db1.t38;
+--------+--------+---------+--------+
| 行号   | 姓名   | 班级    | 住址   |
+--------+--------+---------+--------+
|      1 | lucy   | nsd2107 | bj     |
|      2 | lucy   | nsd2107 | bj     |
+--------+--------+---------+--------+
2 rows in set (0.01 sec)
mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、外键&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[主键外键索引]
        direction LR
        A[主键] --&amp;gt; B[外键] --&amp;gt; C[MySQL索引]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class B highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;外键使用规则：&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;表存储引擎必须是innodb【伊诺 DB】&lt;/li&gt;
&lt;li&gt;表头数据类型要一致&lt;/li&gt;
&lt;li&gt;被参照表头必须要是索引类型的一种(primary【普赖莫瑞】 key【kì】)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;作用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;插入记录时，表头值在另一个表的表头值范围内选择。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.1 外键的创建、查看、删除、添加&lt;/h3&gt;
&lt;h4&gt;创建外键命令&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;create【克瑞特】 table【忒-部】   库.表(
表头列表 , 
foreign【佛润】 key【kì】(表头名)        #指定外键
references【略粉谁斯】 库.表(表头名)   #指定参考的表头名
on【昂】 update【阿普 dei 特】  cascade【卡斯kèi】         #同步更新
on【昂】  delete【迪  利 特】  cascade【卡斯kèi】        #同步删除
)engine【恩-京】=innodb【伊诺 DB】;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需求： 仅给公司里已经入职的员工发工资&lt;/p&gt;
&lt;p&gt;首先创建存储员工信息的员工表&lt;/p&gt;
&lt;p&gt;表名 yg&lt;/p&gt;
&lt;p&gt;员工编号 yg_id&lt;/p&gt;
&lt;p&gt;姓名 name&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#创建员工表
create【克瑞特】 table【忒-部】  db1.yg (
yg_id   int【因特】  primary【普赖莫瑞】 key【kì】  auto_increment【奥特欧_因克瑞门特】, 
name  char【查尔】(16) 
) engine【恩-京】=innodb【伊诺 DB】;
-- mysql&amp;gt; create table db1.yg (
--     -&amp;gt; yg_id int primary key auto_increment,
--     -&amp;gt; name char(16)
--     -&amp;gt; )engine=innodb;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建工资表&lt;/p&gt;
&lt;p&gt;表名 gz&lt;/p&gt;
&lt;p&gt;员工编号 gz_id&lt;/p&gt;
&lt;p&gt;工资 pay&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#创建工资表 指定外键表头
-- 语句一
mysql&amp;gt; create【克瑞特】 table【忒-部】 db1.gz(
  gz_id int【因特】 primary【普赖莫瑞】 key【kì】 auto_increment【奥特欧_因克瑞门特】,  -- 指定主键
  pay  float【弗洛特】,
foreign【佛润】 key【kì】(gz_id)  references【略粉谁斯】 db1.yg(yg_id)  -- 指定外键值为主键，即yg表的yg_id值为gz表的gz_id
on【昂】 update【阿普 dei 特】 cascade【卡斯kèi】                       -- 同步更新
on【昂】 delete【迪  利 特】 cascade【卡斯kèi】                         -- 同步删除
)engine【恩-京】=innodb【伊诺 DB】 ;                                   -- 指定存储引擎
-- mysql&amp;gt; create table db1.gz(
--     -&amp;gt; gz_id int primary key auto_increment,  
--     -&amp;gt; pay float,
--     -&amp;gt; foreign key(gz_id) references db1.yg(yg_id)
--     -&amp;gt; on update cascade
--     -&amp;gt; on delete cascade
--     -&amp;gt; )engine=innodb;


-- 语句二（推荐）
mysql&amp;gt; create【克瑞特】 table【忒-部】 db1.gz (
    -&amp;gt; gz_id int【因特】 primary【普赖莫瑞】 key【kì】 auto_increment【奥特欧_因克瑞门特】,  -- 指定主键
    -&amp;gt; pay float【弗洛特】, 
    -&amp;gt; yg_id int【因特】, 
    -&amp;gt; foreign【佛润】 key【kì】(yg_id) references【略粉谁斯】 db1.yg(yg_id)  -- 指定外键
    -&amp;gt; on【昂】 update【阿普 dei 特】 cascade【卡斯kèi】  -- 同步更新
    -&amp;gt; on【昂】 delete【迪  利 特】 cascade【卡斯kèi】-- 同步删除
    -&amp;gt; )engine【恩-京】=innodb【伊诺 DB】;  -- 指定存储引擎
-- mysql&amp;gt; create table db1.gz(
--     -&amp;gt; gz_id int primary key auto_increment,  
--     -&amp;gt; pay float,
--     -&amp;gt; yg_id int,
--     -&amp;gt; foreign key(yg_id) references db1.yg(yg_id)
--     -&amp;gt; on update cascade
--     -&amp;gt; on delete cascade
--     -&amp;gt; )engine=innodb;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;查看外键&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//查看工资表外键
mysql&amp;gt; show【瘦】 create【克瑞特】  table【忒-部】 db1.gz \G
-- mysql&amp;gt; show create table db1.gz \G
*************************** 1. row ***************************
       Table: gz
Create Table: CREATE TABLE `gz` (
  `gz_id` int NOT NULL AUTO_INCREMENT,
  `pay` float DEFAULT NULL,
  `yg_id` int DEFAULT NULL,
  PRIMARY KEY (`gz_id`),
  KEY `yg_id` (`yg_id`),
  CONSTRAINT `gz_ibfk_1` FOREIGN KEY (`yg_id`) REFERENCES `yg` (`yg_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.022 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;删除外键&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//删除外键
mysql&amp;gt; alter【奥-特】 table【忒-部】 db1.gz drop【卓-普】 FOREIGN【佛润】 KEY【kì】  gz_ibfk_1;
-- mysql&amp;gt; alter table db1.gz drop foreign key gz_ibfk_1;

-- 手动命名：在创建外键时，使用 CONSTRAINT关键字后面跟一个自定义的名称，例如 CONSTRAINT fk_student_class。这样做的好处是名称有意义，便于记忆和管理 
--             CREATE TABLE db1.gz(
--                 gz_id INT PRIMARY KEY AUTO_INCREMENT,  
--                 pay FLOAT,
--                 yg_id INT,
--                 CONSTRAINT fk_gz_yg_id                     -- 这里添加了显式的外键约束名
--                 FOREIGN KEY(yg_id) REFERENCES db1.yg(yg_id)
--                 ON UPDATE CASCADE
--                 ON DELETE CASCADE
--             ) ENGINE=InnoDB;

-- 自动生成：创建外键时没有指定名称（即省略了 CONSTRAINT [symbol]部分），MySQL 会自动生成一个约束名。自动生成的名称通常遵循 表名_ibfk_序号的规则 
-- 在MySQL中，当创建一个外键时，无论是手动命名还是系统自动生成，数据库都会为这个约束关系分配一个唯一的名称。这个名称就是外键约束的标识符。
-- 在MySQL中，外键约束的标识符是以表名和外键列名作为前缀，后跟一个下划线和一个数字作为后缀。

-- 在上面的示例中，外键约束的标识符是 gz_ibfk_1。
--  gz：这是您当前表（从表）的名字。
--  ibfk：这是 InnoDB 存储引擎为外键（InnoDB Foreign Key）生成的标识符，表示这是一个外键约束。
--  1：这是一个数字，表示这是该表中第一个外键约束,如果表中有多个外键，序号会依次递增（如 gz_ibfk_2, gz_ibfk_3）。

-- 可以使用 SHOW CREATE TABLE 语句来查看外键约束的标识符。


//查看不到外键
mysql&amp;gt; show【瘦】 create【克瑞特】  table【忒-部】 db1.gz \G
-- mysql&amp;gt; show create table db1.gz \G
*************************** 1. row ***************************
       Table: gz
Create Table: CREATE TABLE `gz` (
  `gz_id` int NOT NULL AUTO_INCREMENT,
  `pay` float DEFAULT NULL,
  `yg_id` int DEFAULT NULL,
  PRIMARY KEY (`gz_id`),
  KEY `yg_id` (`yg_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;添加外键&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//添加外键
mysql&amp;gt; alter【奥-特】 table【忒-部】 db1.gz 
add  foreign【佛润】 key【kì】(yg_id)  references【略粉谁斯】 db1.yg(yg_id)  
on【昂】 update【阿普 dei 特】 cascade【卡斯kèi】  on【昂】 delete【迪  利 特】 cascade【卡斯kèi】 ;
-- mysql&amp;gt; alter table db1.gz
--     -&amp;gt; add foreign key(yg_id) references db1.yg(yg_id) 
--     -&amp;gt; on update cascade on delete cascade;


//查看外键
mysql&amp;gt; show【瘦】 create【克瑞特】  table【忒-部】 db1.gz \G
-- mysql&amp;gt; show create table db1.gz \G
*************************** 1. row ***************************
       Table: gz
Create Table: CREATE TABLE `gz` (
  `gz_id` int NOT NULL AUTO_INCREMENT,
  `pay` float DEFAULT NULL,
  `yg_id` int DEFAULT NULL,
  PRIMARY KEY (`gz_id`),
  KEY `yg_id` (`yg_id`),
  CONSTRAINT `gz_ibfk_1` FOREIGN KEY (`yg_id`) REFERENCES `yg` (`yg_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 验证外键功能&lt;/h3&gt;
&lt;h4&gt;1)、外键字段的值必须在参考表字段值范围内&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;-- 员工表插入记录
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.yg (name) values【挖柳斯】 (&quot;jerry&quot;),(&quot;tom&quot;);
-- mysql&amp;gt; insert into db1.yg(name) values(&quot;jerry&quot;),(&quot;tom&quot;);
-- Query OK, 2 rows affected (0.15 sec)
-- Records: 2  Duplicates: 0  Warnings: 0

mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.yg;
-- mysql&amp;gt; select *from db1.yg;
-- +-------+-------+
-- | yg_id | name  |
-- +-------+-------+
-- |     1 | jerry |
-- |     2 | tom   |
-- +-------+-------+
-- 2 rows in set (0.00 sec)

-- 工资表插入记录
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.gz values【挖柳斯】(1,50000);
-- mysql&amp;gt; insert into db1.gz values(1,50000,1);
-- Query OK, 1 row affected (0.15 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 db1.gz values【挖柳斯】(2,60000);
-- mysql&amp;gt; insert into db1.gz values(2,50000,2);
-- Query OK, 1 row affected (0.16 sec)

mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.gz;
-- mysql&amp;gt; select * from db1.gz;
+-------+-------+-------+
| gz_id | pay   | yg_id |
+-------+-------+-------+
|     1 | 50000 |     1 |
|     2 | 50000 |     2 |
+-------+-------+-------+
2 rows in set (0.00 sec)

-- 没有的3号员工 工资表插入记录报错(因为yg表中没有3号员工数据，需要先插入3号员工数据)
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.gz values【挖柳斯】(3,50000);  
-- mysql&amp;gt; insert into db1.gz values(3,50000,3);
ERROR 1452 (23000): Cannot add or update【阿普 dei 特】 a child row: a foreign key【kì】 constraint fails (`db1`.`gz`, CONSTRAINT `gz_ibfk_1` FOREIGN KEY【kì】 (`gz_id`) REFERENCES【略粉谁斯】 `yg` (`yg_id`) ON【昂】 DELETE【迪  利 特】 CASCADE【卡斯kèi】 ON【昂】 UPDATE【阿普 dei 特】 CASCADE【卡斯kèi】)


-- 员工表 插入编号3的员工
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.yg (name) values【挖柳斯】 (&quot;Lucy&quot;); 
-- mysql&amp;gt; insert into db1.yg(name) values(&quot;Lucy&quot;);
-- Query OK, 1 row affected (0.14 sec)

mysql&amp;gt; select【涩莱克特】  * from【弗乱】  db1.yg;  
-- mysql&amp;gt; select * from yg;
-- +-------+-------+
-- | yg_id | name  |
-- +-------+-------+
-- |     1 | jerry |
-- |     2 | tom   |
-- |     3 | Lucy  |
-- +-------+-------+
-- 3 rows in set (0.00 sec)


-- 可以给3号员工 发工资了 
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.gz values【挖柳斯】(3,40000,3);
-- mysql&amp;gt; insert into db1.gz values(3,40000,3); 
-- Query OK, 1 row affected (0.12 sec) 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2)、验证同步更新&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;-- 查看员工表记录
mysql&amp;gt; select【涩莱克特】 * from【弗乱】 db1.yg;
-- mysql&amp;gt; select * from db1.yg;
+-------+-------+
| yg_id | name  |
+-------+-------+
|     1 | jerry |
|     2 | tom   |
|     3 | lucy  |
+-------+-------+
3 rows in set (0.00 sec)

-- 把yg表里编号是3的改成9 
mysql&amp;gt; update【阿普 dei 特】 db1.yg set yg_id=9 where【威尔】 yg_id=3;  
-- mysql&amp;gt; update db1.yg set yg_id=9 where yg_id=3;
-- Query OK, 1 row affected (0.17 sec)
-- Rows matched: 1  Changed: 1  Warnings: 0

mysql&amp;gt; select【涩莱克特】 * from【弗乱】 db1.yg;
-- mysql&amp;gt; select * from db1.yg;
+-------+-------+
| yg_id | name  |
+-------+-------+
|     1 | jerry |
|     2 | tom   |
|     9 | Lucy  |
+-------+-------+
3 rows in set (0.00 sec)

-- 工资表里编号是3的自动变成 9 
mysql&amp;gt; select【涩莱克特】 * from【弗乱】 db1.gz;
-- mysql&amp;gt; select * from db1.gz;
+-------+-------+-------+
| gz_id | pay   | yg_id |
+-------+-------+-------+
|     1 | 50000 |     1 |
|     2 | 50000 |     2 |
|     3 | 40000 |     9 |
+-------+-------+-------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3)、验证同步删除&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;-- 删除前查看员工表记录
mysql&amp;gt; select【涩莱克特】 * from【弗乱】 db1.yg;  
-- mysql&amp;gt; select * from db1.yg;
+-------+-------+
| yg_id | name  |
+-------+-------+
|     1 | jerry |
|     2 | tom   |
|     9 | Lucy  |
+-------+-------+
3 rows in set (0.00 sec)

-- 删除编号2的员工
mysql&amp;gt; delete【迪  利 特】 from【弗乱】 db1.yg where【威尔】 yg_id=2; 
-- mysql&amp;gt; delete from db1.yg where yg_id=2;
-- Query OK, 1 row affected (0.19 sec)


-- 删除后查看
mysql&amp;gt; select【涩莱克特】 * from【弗乱】 db1.yg; 
-- mysql&amp;gt; select * from db1.yg;
+-------+-------+
| yg_id | name  |
+-------+-------+
|     1 | jerry |
|     9 | Lucy  |
+-------+-------+
2 rows in set (0.00 sec)


-- 查看工资表也没有编号2的工资了
mysql&amp;gt; select【涩莱克特】 * from【弗乱】 db1.gz; 
-- mysql&amp;gt; select * from db1.gz;
+-------+-------+-------+
| gz_id | pay   | yg_id |
+-------+-------+-------+
|     1 | 50000 |     1 |
|     3 | 40000 |     9 |
+-------+-------+-------+
2 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4)、外键使用注意事项&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;-- 被参考的表不能删除
mysql&amp;gt; drop【卓-普】 table【忒-部】 db1.yg;
-- mysql&amp;gt; drop table db1.yg;  --因为db1.yg的yg_id表被db1.gz表的yg_id参考引用为外键，所以不能删除，只能先解除外键或者先删除gz表
ERROR 1217 (23000): Cannot delete【迪  利 特】 or update【阿普 dei 特】 a parent row: a foreign key【kì】 constraint fails
mysql&amp;gt; 



-- 给gz表的gz_id表头 加主键标签
-- 保证每个员工只能发1遍工资  且有员工编号的员工才能发工资
-- 如果重复发工资和没有编号的发了工资 删除记录后 再添加主键 
mysql&amp;gt; delete【迪  利 特】 form db1.gz;
-- mysql&amp;gt; delete from db1.gz;
-- Query OK, 2 rows affected (0.15 sec)

-- 删除主键
-- 先查看表头
mysql&amp;gt; desc db1.gz;
+-------+-------+------+-----+---------+----------------+
| Field | Type  | Null | Key | Default | Extra          |
+-------+-------+------+-----+---------+----------------+
| gz_id | int   | NO   | PRI | NULL    | auto_increment |
| pay   | float | YES  |     | NULL    |                |
| yg_id | int   | YES  | MUL | NULL    |                |
+-------+-------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

-- 删除auto_increment（一个列是auto_increment自增长，该列就必须定义为主键，所有要删除该主键必须先删除auto_increment属性）
mysql&amp;gt; alter table db1.gz modify gz_id int;
Query OK, 0 rows affected (2.83 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 再次查看表头属性（现在自增长属性已删除，可以开始删除主键了）
mysql&amp;gt; desc db1.gz;
+-------+-------+------+-----+---------+-------+
| Field | Type  | Null | Key | Default | Extra |
+-------+-------+------+-----+---------+-------+
| gz_id | int   | NO   | PRI | NULL    |       |
| pay   | float | YES  |     | NULL    |       |
| yg_id | int   | YES  | MUL | NULL    |       |
+-------+-------+------+-----+---------+-------+
3 rows in set (0.00 sec)

-- 删除主键
mysql&amp;gt; alter table db1.gz drop primary key;
Query OK, 0 rows affected (2.82 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 查看表头属性(已删除，没有PRI标识)
mysql&amp;gt; desc db1.gz;
+-------+-------+------+-----+---------+-------+
| Field | Type  | Null | Key | Default | Extra |
+-------+-------+------+-----+---------+-------+
| gz_id | int   | NO   |     | NULL    |       |
| pay   | float | YES  |     | NULL    |       |
| yg_id | int   | YES  | MUL | NULL    |       |
+-------+-------+------+-----+---------+-------+
3 rows in set (0.00 sec)

--添加主键
mysql&amp;gt; alter【奥-特】 table【忒-部】 db1.gz add primary【普赖莫瑞】 key【kì】(gz_id);
-- mysql&amp;gt; alter table db1.gz add primary key(gz_id);
Query OK, 0 rows affected (2.21 sec)
Records: 0  Duplicates: 0  Warnings: 0 

-- 查看表头属性
mysql&amp;gt; desc db1.gz;
+-------+-------+------+-----+---------+-------+
| Field | Type  | Null | Key | Default | Extra |
+-------+-------+------+-----+---------+-------+
| gz_id | int   | NO   | PRI | NULL    |       |
| pay   | float | YES  |     | NULL    |       |
| yg_id | int   | YES  | MUL | NULL    |       |
+-------+-------+------+-----+---------+-------+
3 rows in set (0.00 sec)

-- 添加auto_increment自增长属性
mysql&amp;gt; alter table db1.gz modify gz_id int auto_increment;
Query OK, 0 rows affected (2.75 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 查看表头属性
mysql&amp;gt; desc db1.gz;
+-------+-------+------+-----+---------+----------------+
| Field | Type  | Null | Key | Default | Extra          |
+-------+-------+------+-----+---------+----------------+
| gz_id | int   | NO   | PRI | NULL    | auto_increment |
| pay   | float | YES  |     | NULL    |                |
| yg_id | int   | YES  | MUL | NULL    |                |
+-------+-------+------+-----+---------+----------------+
3 rows in set (0.00 sec)




-- 保证每个员工只能发1遍工资  且有员工编号的员工才能发工资
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.gz values【挖柳斯】 (1,53000);  报错
-- mysql&amp;gt; insert into db1.gz values(1,53000);
-- ERROR 1136 (21S01): Column count doesn&apos;t match value count at row 1


mysql&amp;gt; insert into db1.gz values(1,53000,9);
Query OK, 1 row affected (0.19 sec)

mysql&amp;gt; select * from gz;
+-------+-------+-------+
| gz_id | pay   | yg_id |
+-------+-------+-------+
|     1 | 53000 |     9 |
+-------+-------+-------+
Query OK, 1 row affected (0.10 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 db1.gz values【挖柳斯】 (NULL【nò】,53000,2); 报错
-- mysql&amp;gt; insert into db1.gz values(NULL,53000,2);        -- 主键值不能为空
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`db1`.`gz`, CONSTRAINT `gz_ibfk_1` FOREIGN KEY (`yg_id`) REFERENCES `yg` (`yg_id`) ON DELETE CASCADE ON UPDATE CASCADE)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、MySQL索引&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[主键外键索引]
        direction LR
        A[主键] --&amp;gt; B[外键] --&amp;gt; C[MySQL索引]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class C highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;使用规则：&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;一个表中可以有多个index【因戴克斯】&lt;/li&gt;
&lt;li&gt;任何数据类型的表头都可以设置索引&lt;/li&gt;
&lt;li&gt;表头值可以重复，也可以赋NULL【nò】值&lt;/li&gt;
&lt;li&gt;通常在where【威尔】条件中的表头上设置Index【因戴克斯】&lt;/li&gt;
&lt;li&gt;index【因戴克斯】索引标志MUL&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;主键和唯一索引和普通索引的区别&lt;/h3&gt;
&lt;p&gt;主键和唯一索引是数据库设计中两个核心但易混淆的概念。下面这个表格能帮你快速把握它们的核心区别。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性维度&lt;/th&gt;
&lt;th&gt;主键 (&lt;code&gt;PRIMARY KEY&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;外键 (&lt;code&gt;FOREIGN KEY&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;唯一索引 (&lt;code&gt;UNIQUE INDEX&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;普通索引 (&lt;code&gt;INDEX&lt;/code&gt;)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;本质&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;约束，用于唯一标识每条记录&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;引用约束&lt;/strong&gt;，用于建立和加强表间的数据关联&lt;/td&gt;
&lt;td&gt;索引，附带唯一性保证&lt;/td&gt;
&lt;td&gt;最基本的索引类型，没有唯一性约束&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;数量限制&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一个表&lt;strong&gt;只能有一个&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一个表&lt;strong&gt;可以有多个&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一个表&lt;strong&gt;可以有多个&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一个表&lt;strong&gt;可以有多个&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;空值处理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;不允许&lt;/strong&gt;为 &lt;code&gt;NULL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;允许&lt;/strong&gt;为 &lt;code&gt;NULL&lt;/code&gt;，表示该记录无关联记录&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;允许&lt;/strong&gt;为 &lt;code&gt;NULL&lt;/code&gt;，且可包含多个 &lt;code&gt;NULL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;允许&lt;/strong&gt;出现重复值和空值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;核心功能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;唯一标识&lt;/strong&gt;表中的每一行记录，保证实体完整性&lt;/td&gt;
&lt;td&gt;维护&lt;strong&gt;引用完整性&lt;/strong&gt;，确保值必须在另一表的主键中存在&lt;/td&gt;
&lt;td&gt;确保&lt;strong&gt;索引列的数据唯一&lt;/strong&gt;，防止重复&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;加速查询&lt;/strong&gt;，提高查询效率，不做任何约束&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;外键引用&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;可以被&lt;/strong&gt;其他表的外键引用&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;定义表间关系&lt;/strong&gt;（如一对多），外键是另一表主键的引用&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;不可以&lt;/strong&gt;直接作为外键引用目标&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;不可以&lt;/strong&gt;直接作为外键引用目标&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;核心语句&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ALTER TABLE 表名 ADD PRIMARY KEY (字段);&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ALTER TABLE 从表 ADD FOREIGN KEY (外键字段) REFERENCES 主表(主键字段);&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ALTER TABLE 表名 ADD UNIQUE [索引名] (字段);&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ALTER TABLE 表名 ADD INDEX [索引名] (字段);&lt;/code&gt; 或 &lt;code&gt;CREATE INDEX 索引名 ON 表名 (字段);&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;核心内涵与进阶理解&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主键：数据存储的基石&lt;/strong&gt;
“主键还充当聚簇索引”非常关键。在InnoDB存储引擎中，表数据本身就是按主键顺序组织存储的。这使得主键查询极快，但同时也意味着如果主键值是随机的（如UUID），可能导致频繁的页分裂，影响插入性能并产生碎片。因此，使用与业务无关的&lt;strong&gt;自增主键&lt;/strong&gt;往往是性能最佳实践。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;外键：表间关系的纽带与数据一致性的守护者&lt;/strong&gt;
外键的本质是一个&lt;strong&gt;约束&lt;/strong&gt;，它通过强制要求子表（从表）中的外键字段值必须存在于主表（被引用表）的主键中，来维护&lt;strong&gt;参照完整性&lt;/strong&gt;。这有效防止了“孤立数据”的产生，例如，确保了不会有一条订单记录指向一个不存在的客户ID。外键关系通常用于实现“一对多”的关联，例如，一个客户（主表）可以拥有多个订单（子表）。
在实现上，定义外键时通常可以指定&lt;strong&gt;级联操作&lt;/strong&gt;（如 &lt;code&gt;ON DELETE CASCADE&lt;/code&gt; 或 &lt;code&gt;ON UPDATE SET NULL&lt;/code&gt;），这允许在主表数据变更时自动处理子表中的关联数据，但使用时需谨慎，以免导致非预期的数据修改。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;唯一索引：业务规则的守护者&lt;/strong&gt;
它的强大之处在于将业务唯一性要求（如“手机号不可重复”）固化在数据库层，从根源上防止了脏数据的产生。与主键不同，一个表可以有多个唯一索引，为多个业务字段提供唯一性保障。它也可以是&lt;strong&gt;复合索引&lt;/strong&gt;（多列组合），确保几个字段的组合值唯一，例如防止同一用户对同一商品重复评论 &lt;code&gt;(user_id, product_id)&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;普通索引：纯粹的查询加速器&lt;/strong&gt;
它唯一的目标就是“快”。其核心价值在于&lt;strong&gt;大幅减少磁盘I/O&lt;/strong&gt;，通过索引数据结构（如B+Tree）快速定位数据，避免全表扫描。创建普通索引时，应考虑字段的“&lt;strong&gt;区分度&lt;/strong&gt;”（选择性），即不重复值的比例。区分度越高，索引筛选效率越好。像“性别”这种区分度很低的字段创建索引意义不大。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;创建唯一索引&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;-- 语法一
mysql&amp;gt; alter table db1.customers add unique index email_index(email);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 语法二
mysql&amp;gt; alter table db1.customers add unique (email); 
Query OK, 0 rows affected (4.387 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 建表时创建
 CREATE TABLE 库.表 (
  id INT, 
  表头名 VARCHAR(255), 
  ..., 
  UNIQUE INDEX 索引名 (表头名)
  );
-- 或 
 CREATE TABLE 库.表 (
  id INT, 
  表头名 VARCHAR(255) 
  UNIQUE, ...);

-- 为已存在表添加
  ALTER TABLE 库.表 ADD UNIQUE INDEX 索引名 (表头名);
-- 或 
  ALTER TABLE 库.表 ADD UNIQUE (表头名);
--或 
  CREATE UNIQUE INDEX 索引名 ON 库.表 (表头名);

-- 删除唯一索引
  DROP INDEX 索引名 ON 库.表;
-- 或
  ALTER TABLE 库.表 DROP INDEX 索引名;

-- 修改唯一索引
-- MySQL 不直接支持修改索引。通常需要先删除旧索引，再添加新索引。
-- 例如，先 
  DROP INDEX 旧索引名 ON 库.表;
--   再 
  CREATE UNIQUE INDEX 新索引名 ON 库.表 (表头名);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.1 索引的创建、查看、删除、添加&lt;/h3&gt;
&lt;h4&gt;1)建表时创建索引命令格式&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;CREATE【克瑞特】 TABLE【忒-部】  库.表(
字段列表 ,
INDEX【因戴克斯】(字段名) ,
INDEX【因戴克斯】(字段名) 
);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Create【克瑞特】 database  home;
Use home;
CREATE【克瑞特】 TABLE【忒-部】 tea4(
id char【查尔】(6),
name varchar【瓦儿-查儿】(6),
age int(3),
gender enum【ing纽某】(&apos;boy&apos;,&apos;girl&apos;) DEFAULT【迪-佛特】 &apos;boy&apos;,
INDEX【因戴克斯】(id),INDEX【因戴克斯】(name)
);
-- mysql&amp;gt; create database home;
-- Query OK, 1 row affected (0.17 sec)

-- mysql&amp;gt; use home;
-- Database changed
-- mysql&amp;gt; create table tea4(
--     -&amp;gt; id char(6),
--     -&amp;gt; name varchar(6),
--     -&amp;gt; age int(3),
--     -&amp;gt; gender enum(&apos;boy&apos;,&apos;girl&apos;) default &apos;boy&apos;,
--     -&amp;gt; index(id),index(name));-- 创建名为 `id`和`name` 的普通索引
-- Query OK, 0 rows affected, 1 warning (1.70 sec)

-- mysql&amp;gt; desc tea4;
-- +--------+--------------------+------+-----+---------+-------+
-- | Field  | Type               | Null | Key | Default | Extra |
-- +--------+--------------------+------+-----+---------+-------+
-- | id     | char(6)            | YES  | MUL | NULL    |       |
-- | name   | varchar(6)         | YES  | MUL | NULL    |       |
-- | age    | int                | YES  |     | NULL    |       |
-- | gender | enum(&apos;boy&apos;,&apos;girl&apos;) | YES  |     | boy     |       |
-- +--------+--------------------+------+-----+---------+-------+
-- 4 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2）查看索引&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;des  库.表；
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; desc home.tea4;
+--------+--------------------+------+-----+---------+-------+
| Field  | Type               | Null | Key | Default | Extra |
+--------+--------------------+------+-----+---------+-------+
| id     | char(6)            | YES   | MUL | NULL    |       |
| name   | varchar(6)         | YES  | MUL | NULL    |       |
| age    | int(3)              | YES |     | NULL    |       |
| gender | enum(&apos;boy&apos;,&apos;girl&apos;) | YES  |     | boy     |       |
+--------+--------------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

mysql&amp;gt; system ls /var/lib/mysql/home/tea4.ibd  保存排队信息的文件
/var/lib/mysql/home/tea4.ibd
mysql&amp;gt;


&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3）查看索引详细信息&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;show【瘦】 index【因戴克斯】   from【弗乱】   库.表； 
-- mysql&amp;gt; show index from home.tea4;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| tea4  |          1 | id       |            1 | id          | A         |           0 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tea4  |          1 | name     |            1 | name        | A         |           0 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
2 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;show【瘦】  index【因戴克斯】   from【弗乱】  home.tea4 \G
-- mysql&amp;gt; show index from home.tea4 \G
*************************** 1. row ***************************
        Table: tea4         -- 表名
   Non_unique: 1
     Key_name: id           -- 索引名   （默认索引名和表头名相同，删除索引时，使用的索引名）
 Seq_in_index: 1
  Column_name: id           -- 表头名
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE        -- 索引类型
      Comment: 
Index_comment: 
*************************** 2. row ***************************
        Table: tea4         -- 表名
   Non_unique: 1
     Key_name: name         -- 索引名
 Seq_in_index: 1
  Column_name: name         -- 表头名
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE        -- 排队算法
      Comment: 
Index_comment: 
2 rows in set (0.00 sec)
mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4）删除索引&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;命令格式   DROP【卓-普】  INDEX【因戴克斯】   索引名   ON【昂】  库.表；
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; drop【卓-普】 index【因戴克斯】 id on【昂】 home.tea4 ;
-- mysql&amp;gt; drop index id on home.tea4;
-- Query OK, 0 rows affected (0.48 sec)
-- Records: 0  Duplicates: 0  Warnings: 0

mysql&amp;gt; desc  home.tea4;
-- mysql&amp;gt; desc home.tea4;
+--------+--------------------+------+-----+---------+-------+
| Field  | Type               | Null | Key | Default | Extra |
+--------+--------------------+------+-----+---------+-------+
| id     | char(6)            | YES   |     | NULL    |       |
| name   | varchar(6)         | YES  | MUL | NULL    |       |
| age    | int(3)             | YES |     | NULL    |       |
| gender | enum(&apos;boy&apos;,&apos;girl&apos;) | YES  |     | boy     |       |
+--------+--------------------+------+-----+---------+-------+
4 rows in set (0.14 sec)

mysql&amp;gt; show【瘦】  index【因戴克斯】   from【弗乱】  home.tea4 \G
-- mysql&amp;gt; show index from home.tea4 \G
*************************** 1. row ***************************
        Table: tea4
   Non_unique: 1
     Key_name: name
 Seq_in_index: 1
  Column_name: name
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
1 row in set (0.00 sec)
mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;5）已有表添加索引命令&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;CREATE【克瑞特】  INDEX【因戴克斯】  索引名  ON【昂】  库.表(字段名)；
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】  index【因戴克斯】 nianling on【昂】 home.tea4(age);
-- mysql&amp;gt; create index nianling on home.tea4(age);    -- 给age创建一个索引，索引命令为&quot;nianling&quot;
-- Query OK, 0 rows affected (0.50 sec)
-- Records: 0  Duplicates: 0  Warnings: 0

mysql&amp;gt; desc home.tea4;
+--------+--------------------+------+-----+---------+-------+
| Field  | Type               | Null | Key | Default | Extra |
+--------+--------------------+------+-----+---------+-------+
| id     | char(6)            | YES   |     | NULL    |       |
| name   | varchar(6)         | YES  | MUL | NULL    |       |
| age    | int(3)             | YES | MUL | NULL    |       |
| gender | enum(&apos;boy&apos;,&apos;girl&apos;) | YES  |     | boy     |       |
+--------+--------------------+------+-----+---------+-------+
4 rows in set (0.00 sec)



mysql&amp;gt; show【瘦】 create【克瑞特】 table【忒-部】 home.tea4 \G
-- mysql&amp;gt; show create table home.tea4 \G
*************************** 1. row ***************************
       Table: tea4
Create Table: CREATE TABLE `tea4` (
  `id` char(6) DEFAULT NULL,
  `name` varchar(6) DEFAULT NULL,
  `age` int DEFAULT NULL,
  `gender` enum(&apos;boy&apos;,&apos;girl&apos;) DEFAULT &apos;boy&apos;,
  KEY `name` (`name`),
  KEY `nianling` (`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

mysql&amp;gt; show【瘦】 index【因戴克斯】 from【弗乱】 home.tea4;
mysql&amp;gt; show index from home.tea4;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| tea4  |          1 | name     |            1 | name        | A         |           0 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tea4  |          1 | nianling |            1 | age         | A         |           0 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
2 rows in set (0.07 sec)

mysql&amp;gt; show【瘦】  index【因戴克斯】   from【弗乱】  home.tea4 \G
-- mysql&amp;gt; show index from home.tea4 \G
*************************** 1. row ***************************
        Table: tea4
   Non_unique: 1
     Key_name: name
 Seq_in_index: 1
  Column_name: name
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
*************************** 2. row ***************************
        Table: tea4
   Non_unique: 1
     Key_name: nianling       -- 设置的索引名
 Seq_in_index: 1
  Column_name: age            -- 表头名
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
2 rows in set (0.00 sec)
mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;6）验证索引&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; explain【e 斯 波 类】 select【涩莱克特】  * from【弗乱】 moershi.user where【威尔】 name=&quot;sshd&quot; \G
-- mysql&amp;gt; explain select * from moershi.user where name=&quot;sshd&quot; \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: user         -- 表名
   partitions: NULL
         type: ref
possible_keys: name
          key: name         -- 使用的索引名
      key_len: 21
          ref: const
         rows: 1            -- 查找的总行数
     filtered: 100.00
        Extra: NULL         -- 额外说明
1 row in set, 1 warning (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、作业&lt;/h2&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;以下关于主键的描述，正确的是（ C ）
A. 一个表可以有多个主键
B. 主键的值可以为 NULL
C. 主键用于唯一标识表中的每一行记录
D. 主键只能由一个字段组成&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;主键的核心作用是
  唯一标识表中的每一行记录
  一个表只能有一个主键（不论是单字段还是多字段联合主键），
  且主键值不可重复、不可为NULL
  主键可以由多个字段组成（联合主键）
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;外键的作用是（ B ）
A. 保证表中数据的唯一性
B. 建立表与表之间的关联
C. 提高数据的查询速度
D. 对数据进行加密&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;外键的主要作用是
  建立并维护表与表之间的关联关系
  从而保证数据的参照完整性，防止产生“孤立数据”。
  保证数据唯一性是主键或唯一约束的作用
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;以下哪种情况适合创建索引（ C ）
A. 经常进行更新操作的字段
B. 数据量很小的表
C. 经常作为查询条件的字段
D. 很少使用的字段&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;为频繁作为查询条件（WHERE子句） 的字段创建索引，可以显著提高查询速度。
而经常更新的字段、数据量小的表或很少使用的字段创建索引，可能无法带来性能提升，反而增加维护开销
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;在 MySQL 中，创建主键的关键字是（ B ）
A. PRIMARY
B. PRIMARY KEY
C. UNIQUE
D. FOREIGN KEY&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;在MySQL中，定义主键的语法关键字是 PRIMARY KEY
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;若要删除表中的外键约束，应使用的关键字是（ A ）
A. DROP FOREIGN KEY
B. DELETE FOREIGN KEY
C. REMOVE FOREIGN KEY
D. ALTER FOREIGN KEY&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;删除外键约束需要使用 ALTER TABLE 库.表 DROP FOREIGN KEY(表头名);语句，后接具体的外键约束名
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;简述主键和唯一索引的区别。
答：
主键：
是一种约束，用于唯一标识每条记录，可以作为外键的引用。一个表只能有一个主键（但可以是复合主键），主键值不可重复、不可为NULL。&lt;/p&gt;
&lt;p&gt;唯一索引：
是一种索引，附带唯一性保证，用于确保索引列的数据唯一。一个表可以有多个唯一索引，也可以作为外键的引用（只要它满足唯一性）。唯一索引允许NULL值，并且可以包含多个NULL（但具体取决于数据库系统，如MySQL中唯一索引允许多个NULL）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;说明外键约束在数据库设计中的重要性。
答：
外键约束通过强制要求子表（从表）中的外键字段值必须存在于主表（被引用表）的主键中，来维护&lt;strong&gt;参照完整性&lt;/strong&gt;，这有效防止了&quot;孤立数据&quot;的产生。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;索引在什么情况下会失效？如何避免索引失效？
答：
索引在以下情况下会失效：
索引在以下情况下会失效（针对WHERE条件）：
查询条件中使用了函数或表达式，如 WHERE YEAR(date_column) = 2020。
查询条件中使用了通配符（以%开头），如 WHERE name LIKE &apos;%John%&apos;。
查询条件中使用了不等于操作符（如 !=或 &amp;lt;&amp;gt;），但如果是覆盖索引可能有效。
数据类型隐式转换（如字符串列与数字比较）。
OR条件连接多个索引列（如果未优化）。&lt;/p&gt;
&lt;p&gt;为了避免索引失效，可以采取以下措施：
避免在查询条件中使用函数或表达式，尽量使用索引列原始值。
尽量使用等值查询，避免通配符开头；如果必须用LIKE，尝试用前缀匹配（如 LIKE &apos;John%&apos;）。
确保ORDER BY或GROUP BY的列上有索引，以利用索引排序。
使用覆盖索引（索引包含所有查询字段）来优化不等于查询。
避免数据类型转换，确保比较时类型一致。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3 操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;创建一个名为 &lt;code&gt;customers&lt;/code&gt; 的表，包含 &lt;code&gt;customer_id&lt;/code&gt;（作为主键）、&lt;code&gt;customer_name&lt;/code&gt;、&lt;code&gt;email&lt;/code&gt; 字段。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create table db1.customers (
    -&amp;gt; customer_id int primary key auto_increment,
    -&amp;gt; customer_name char(10),
    -&amp;gt; email varchar(255)
    -&amp;gt; )engine=innodb;
Query OK, 0 rows affected (1.44 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;创建一个 &lt;code&gt;orders&lt;/code&gt; 表，包含 &lt;code&gt;order_id&lt;/code&gt;、&lt;code&gt;customer_id&lt;/code&gt;（作为外键关联 &lt;code&gt;customers&lt;/code&gt; 表的 &lt;code&gt;customer_id&lt;/code&gt;）、&lt;code&gt;order_date&lt;/code&gt; 字段。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create table db1.orders (
    -&amp;gt; order_id int primary key auto_increment,
    -&amp;gt; customer_id int,
    -&amp;gt; order_date datetime,
    -&amp;gt; foreign key (customer_id) references customers(customer_id)
    -&amp;gt; )engine=innodb;
Query OK, 0 rows affected (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;在 &lt;code&gt;customers&lt;/code&gt; 表的 &lt;code&gt;email&lt;/code&gt; 字段上创建一个唯一索引。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; 
mysql&amp;gt; alter table db1.customers add unique (email); 
Query OK, 0 rows affected (4.387 sec)
Records: 0  Duplicates: 0  Warnings: 0
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;修改 &lt;code&gt;orders&lt;/code&gt; 表，添加一个新的外键约束，关联 &lt;code&gt;products&lt;/code&gt; 表（假设 &lt;code&gt;products&lt;/code&gt; 表已存在，有 &lt;code&gt;product_id&lt;/code&gt; 字段）。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;-- 添加product_id字段
mysql&amp;gt; alter table db1.orders add product_id int;
Query OK, 0 rows affected (5.441 sec)
Records: 0  Duplicates: 0  Warnings: 0
-- 创建product表
mysql&amp;gt; create table db1.products(
    -&amp;gt; product_id int primary key auto_increment
    -&amp;gt; )engine=innodb;
Query OK, 0 rows affected (0.689 sec)
-- 添加外键约束
mysql&amp;gt; alter table db1.orders
    -&amp;gt; add foreign key(product_id) references db1.products(product_id)
    -&amp;gt; on update cascade;
Query OK, 0 rows affected (2.100 sec)
Records: 0  Duplicates: 0  Warnings: 0
-- 查看orders表
mysql&amp;gt; show create table db1.orders \G
*************************** 1. row ***************************
       Table: orders
Create Table: CREATE TABLE `orders` (
  `order_id` int NOT NULL AUTO_INCREMENT,
  `customer_id` int DEFAULT NULL,
  `order_date` datetime DEFAULT NULL,
  `product_id` int DEFAULT NULL,
  PRIMARY KEY (`order_id`),
  KEY `customer_id` (`customer_id`),
  KEY `product_id` (`product_id`),
  CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`customer_id`),
  CONSTRAINT `orders_ibfk_2` FOREIGN KEY (`product_id`) REFERENCES `products` (`product_id`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.065 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;删除 &lt;code&gt;customers&lt;/code&gt; 表上的索引。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;-- 查看`customers` 表索引
mysql&amp;gt; show index from db1.customers;
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table     | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| customers |          0 | PRIMARY  |            1 | customer_id | A         |           0 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| customers |          0 | email    |            1 | email       | A         |           0 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
2 rows in set (1.751 sec)
-- 删除email唯一索引
mysql&amp;gt; alter table db1.customers drop index email;
Query OK, 0 rows affected (2.905 sec)
Records: 0  Duplicates: 0  Warnings: 0
-- 查看`customers` 表索引
mysql&amp;gt; show index from db1.customers;
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table     | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| customers |          0 | PRIMARY  |            1 | customer_id | A         |           0 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
1 row in set (0.256 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;删除 &lt;code&gt;orders&lt;/code&gt; 表上的索引。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 查看外键属性
mysql&amp;gt; show create table db1.orders \G    
*************************** 1. row ***************************
       Table: orders
Create Table: CREATE TABLE `orders` (
  `order_id` int NOT NULL AUTO_INCREMENT,
  `customer_id` int DEFAULT NULL,
  `order_date` datetime DEFAULT NULL,
  `product_id` int DEFAULT NULL,
  PRIMARY KEY (`order_id`),
  KEY `customer_id` (`customer_id`),
  KEY `product_id` (`product_id`),
  CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`customer_id`),
  CONSTRAINT `orders_ibfk_2` FOREIGN KEY (`product_id`) REFERENCES `products` (`product_id`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (1.279 sec)

-- 删除外键orders_ibfk_1
mysql&amp;gt; alter table db1.orders drop foreign key orders_ibfk_1;
Query OK, 0 rows affected (1.222 sec)
Records: 0  Duplicates: 0  Warnings: 0
-- 删除外键orders_ibfk_2
mysql&amp;gt; alter table db1.orders drop foreign key orders_ibfk_2; 
Query OK, 0 rows affected (0.342 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 查看索引名
mysql&amp;gt; show index from db1.orders;
+--------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table  | Non_unique | Key_name    | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+--------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| orders |          0 | PRIMARY     |            1 | order_id    | A         |           0 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| orders |          1 | product_id  |            1 | product_id  | A         |           0 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| orders |          1 | customer_id |            1 | customer_id | A         |           0 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
+--------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
3 rows in set (1.037 sec)

-- 删除索引 product_id
mysql&amp;gt; drop index product_id on db1.orders;
Query OK, 0 rows affected (1.191 sec)
Records: 0  Duplicates: 0  Warnings: 0
-- 删除索引 customer_id
mysql&amp;gt; drop index customer_id on db1.orders; 
Query OK, 0 rows affected (0.326 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 查看索引属性
mysql&amp;gt; show index from db1.orders;           
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table  | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| orders |          0 | PRIMARY  |            1 | order_id    | A         |           0 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
1 row in set (0.392 sec)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>07 mysql之数据导入导出与用户管理</title><link>https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/07-mysql%E4%B9%8B%E6%95%B0%E6%8D%AE%E5%AF%BC%E5%85%A5%E5%AF%BC%E5%87%BA%E4%B8%8E%E7%94%A8%E6%88%B7%E7%AE%A1%E7%90%86/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/07-mysql%E4%B9%8B%E6%95%B0%E6%8D%AE%E5%AF%BC%E5%85%A5%E5%AF%BC%E5%87%BA%E4%B8%8E%E7%94%A8%E6%88%B7%E7%AE%A1%E7%90%86/</guid><description>07 mysql之数据导入导出与用户管理 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 08:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1&gt;07 mysql之数据导入导出与用户管理&lt;/h1&gt;
&lt;p&gt;今天工作任务路线图&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[数据导入导出与用户管理]
        direction LR
        A[数据导入导出] --&amp;gt; B[用户管理]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class E highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;小李是一家电商公司的数据库管理员。最近公司要对业务系统进行升级，需要将旧数据库中的商品信息、订单记录等数据迁移到新数据库，这就需要他运用数据导出与导入功能。小李使用 &lt;code&gt;SELECT【涩莱克特】 ... INTO【因兔】 OUTFILE【奥特-伐尔】&lt;/code&gt; 语句把旧数据库的数据导出到文件，再用 &lt;code&gt;LOAD【漏德】 DATA INFILE【因-伐尔】&lt;/code&gt; 语句将数据导入新数据库，保证数据完整迁移。&lt;/p&gt;
&lt;p&gt;同时，公司业务拓展后新成立了营销和客服部门，需要为这些新员工创建数据库账户。小李使用 &lt;code&gt;CREATE【克瑞特】 USER&lt;/code&gt; 语句创建用户，用 &lt;code&gt;grant【古亮普】&lt;/code&gt; 语句根据岗位需求赋予不同权限，确保数据的安全性和员工操作的规范性。&lt;/p&gt;
&lt;h2&gt;二、为什么学呢&lt;/h2&gt;
&lt;p&gt;学习 MySQL 数据导入导出与用户管理具有很强的现实意义。在数据迁移场景中，当公司更换数据库系统或升级服务器时，掌握数据导入导出技能，能确保数据完整、准确地从旧环境过渡到新环境，避免业务中断。比如电商平台促销活动前后，要灵活调整数据存储。&lt;/p&gt;
&lt;p&gt;在数据共享方面，可与合作伙伴安全、高效地交换数据。而用户管理是数据库安全的关键，合理设置用户权限，能防止未经授权的访问和数据泄露，保护公司核心数据。掌握这些技能，可提升数据库管理能力，为企业的稳定运行保驾护航，也增强个人在职场上的竞争力。&lt;/p&gt;
&lt;h2&gt;三、数据导入导出&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[数据导入导出与用户管理]
        direction LR
        A[数据导入导出] --&amp;gt; B[用户管理]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class A highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;secure【瑟Q儿】_file【伐尔】_priv【破略夫】&lt;/code&gt; 是 MySQL 中的一个系统变量，主要用于控制数据导入和导出操作的安全性。下面为你详细介绍：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;它限定了 MySQL 服务器在执行数据导入（&lt;code&gt;LOAD【漏德】 DATA INFILE【因-伐尔】&lt;/code&gt;）和导出（&lt;code&gt;SELECT【涩莱克特】 ... INTO【因兔】 OUTFILE【奥特-伐尔】&lt;/code&gt;）操作时，可以访问的文件路径。通过设置该变量，可以防止 MySQL 服务器随意访问系统上的文件，从而增强系统的安全性，避免潜在的文件访问风险。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;查看与修改&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;查看&lt;/strong&gt;：可以使用 &lt;code&gt;SHOW【瘦】 VARIABLES【wèi 利 bóu 斯】 LIKE【赖特】 &apos;secure【瑟Q儿】_file【伐尔】_priv【破略夫】&apos;;&lt;/code&gt; 语句查看当前 &lt;code&gt;secure【瑟Q儿】_file【伐尔】_priv【破略夫】&lt;/code&gt; 的值。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;修改&lt;/strong&gt;：要修改该变量的值，需要编辑 MySQL 的配置文件，在其中添加或修改 &lt;code&gt;secure【瑟Q儿】_file【伐尔】_priv【破略夫】&lt;/code&gt; 参数，然后重启 MySQL 服务器使修改生效。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3.1 修改文件存储路径&lt;/h3&gt;
&lt;p&gt;修改检索目录为/myload【my漏德】。&lt;/p&gt;
&lt;p&gt;检查目录存放导入导出数据时存放数据的文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# mysql -uroot -pNSD123456...a
mysql&amp;gt; show【瘦】 variables【wèi 利 bóu 斯】 like【赖特】 &quot;%file【伐尔】%&quot;;    -- 查看与文件相关的配置项
-- mysql&amp;gt; show variables like &quot;%file%&quot;; 
+---------------------------------------+---------------------------------+
| Variable_name                         | Value                           |
+---------------------------------------+---------------------------------+
| character_set_filesystem              | binary                          |
| core_file                             | OFF                             |
| ft_stopword_file                      | (built-in)                      |
| general_log_file                      | /var/lib/mysql/mysql50.log      |
| init_file                             |                                 |
| innodb_buffer_pool_filename           | ib_buffer_pool                  |
| innodb_buffer_pool_in_core_file       | ON                              |
| innodb_data_file_path                 | ibdata1:12M:autoextend          |
| innodb_disable_sort_file_cache        | OFF                             |
| innodb_doublewrite_files              | 2                               |
| innodb_file_per_table                 | ON                              |
| innodb_log_file_size                  | 50331648                        |
| innodb_log_files_in_group             | 2                               |
| innodb_open_files                     | 4000                            |
| innodb_temp_data_file_path            | ibtmp1:12M:autoextend           |
| keep_files_on_create                  | OFF                             |
| large_files_support                   | ON                              |
| local_infile                          | OFF                             |
| lower_case_file_system                | OFF                             |
| myisam_max_sort_file_size             | 9223372036853727232             |
| open_files_limit                      | 10000                           |
| performance_schema_max_file_classes   | 80                              |
| performance_schema_max_file_handles   | 32768                           |
| performance_schema_max_file_instances | -1                              |
| pid_file                              | /run/mysqld/mysqld.pid          |
| relay_log_info_file                   | relay-log.info                  |
| secure_file_priv                      | /var/lib/mysql-files/           |
| slow_query_log_file                   | /var/lib/mysql/mysql50-slow.log |
+---------------------------------------+---------------------------------+
28 rows in set (0.00 sec)

-- 查看默认检索目录
mysql&amp;gt; show【瘦】 variables【wèi 利 bóu 斯】 like【赖特】 &quot;secure【瑟Q儿】_file【伐尔】_priv【破略夫】&quot;;
-- mysql&amp;gt; show variables like &quot;secure_file_priv&quot;; 
+------------------+-----------------------+
| Variable_name    | Value                 |
+------------------+-----------------------+
| secure_file_priv | /var/lib/mysql-files/ |
+------------------+-----------------------+
1 row in set (0.00 sec)
mysql&amp;gt; exit【诶西特】

-- 安装MySQL服务软件时自动创建
[root@mysql50 ~]# ls -ld /var/lib/mysql-files【伐尔】/
-- [root@mha ~]# ls -ld /var/lib/mysql-files/
drwxr-x--- 2 mysql mysql 6 Sep 22  2021 /var/lib/mysql-files【伐尔】/


-- 修改主配置文件
[root@mysql50 ~]# vim /etc/my.cnf.d/mysql-server.cnf
[mysqld]
secure【瑟Q儿】_file【伐尔】_priv【破略夫】=/myload【my漏德】  -- 添加此行
:wq

-- 创建目录并修改所有者为mysql用户 ,并保证mysql用户对父目录有rx
[root@mysql50 ~]# mkdir /myload【my漏德】
-- [root@mha ~]# mkdir /myload
[root@mysql50 ~]# chown【吃-昂】 mysql /myload【my漏德】
-- [root@mha ~]# chown mysql /myload

-- 关闭selinux
[root@mysql50 ~]# setenforce【赛特-因佛尔斯】 0
-- [root@mha ~]# setenforce 0
setenforce: SELinux is disabled

-- 重启服务
[root@mysql50 ~]# systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld
-- [root@mha ~]# systemctl restart mysqld

-- 管理员员登陆查看目录
[root@mysql50 ~]# mysql -uroot -pNSD123456...a
mysql&amp;gt; show【瘦】 variables【wèi 利 bóu 斯】 like【赖特】 &quot;secure【瑟Q儿】_file【伐尔】_priv【破略夫】&quot;;
-- mysql&amp;gt; show variables like &quot;secure_file_priv&quot;;
+------------------+----------+
| Variable_name    | Value    |
+------------------+----------+
| secure_file_priv | /myload/ |
+------------------+----------+
1 row in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 导入数据&lt;/h3&gt;
&lt;p&gt;将/etc/passwd文件导入db1库的user3表里。&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# mysql -uroot -pNSD123456...a
mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】 db1;
-- mysql&amp;gt; create database db1;
-- Query OK, 1 row affected (0.01 sec)

-- 建表（ 根据导入的文件内容 创建表头）
mysql&amp;gt; create【克瑞特】 table【忒-部】 db1.user3(
   name varchar【瓦儿-查儿】(30),
   password【帕斯沃德】 char【查尔】(1),
   uid int【因特】 , 
   gid int【因特】 , 
   comment【坑门特】 varchar【瓦儿-查儿】(200),
   homedir【home-跌儿】 varchar【瓦儿-查儿】(50),
   shell varchar【瓦儿-查儿】(30));
Query OK, 0 rows affected (0.41 sec)
-- mysql&amp;gt; create table db1.user3(
--    name varchar(30),
--    password char(1),
--    uid int,
--    gid int,
--    comment varchar(200),
--    homedir varchar(50),
--    shell varchar(30));
-- Query OK, 0 rows affected (0.06 sec)

-- 查看表头
mysql&amp;gt; desc db1.user3;
-- mysql&amp;gt; desc db1.user3;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| name     | varchar(30)  | YES  |     | NULL    |       |
| password | char(1)      | YES  |     | NULL    |       |
| uid      | int          | YES  |     | NULL    |       |
| gid      | int          | YES  |     | NULL    |       |
| comment  | varchar(200) | YES  |     | NULL    |       |
| homedir  | varchar(50)  | YES  |     | NULL    |       |
| shell    | varchar(30)  | YES  |     | NULL    |       |
+----------+--------------+------+-----+---------+-------+
7 rows in set (0.01 sec)

-- 没有数据
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.user3;
-- mysql&amp;gt; select * from db1.user3;
Empty set (0.01 sec)

-- 拷贝文件到检索目录 system【西斯屯】 在MySQL 里执行系统命令
mysql&amp;gt; system【西斯屯】 cp /etc/passwd  /myload【my漏德】/
-- mysql&amp;gt; system cp /etc/passwd /myload
-- mysql&amp;gt; 

-- mysql&amp;gt; system cp /etc/passwd /myload   
-- cp: cannot stat &apos;/etc/passwd&apos;: No such file or directory -- 提示该报错是因为一、没有权限，需要修改权限，二、没有文件，需要拷贝文件，三、当前登录的mysql账号没有权限，需要修改权限
-- 一、修改权限 
-- mysql&amp;gt; system【西斯屯】 chmod【吃-默德】 777 /myload【my漏德】/
-- mysql&amp;gt; system chmod 777 /myload
-- 三、修改mysql用户权限
-- mysql&amp;gt; grant【格拉特】 all【阿尔】 on /myload【my漏德】/* to【托 敏 内提】 mysql@&apos;%&apos;【托 敏 内提】;
-- mysql&amp;gt; grant all on /myload/* to mysql@&apos;%&apos;;
-- 或者切换有权限用户
-- mysql&amp;gt; system whoami --查看当前登录用户
-- sf\ta206682

mysql&amp;gt; system【西斯屯】 ls /myload【my漏德】/  -- 查看文件
-- mysql&amp;gt; system ls /myload
passwd
mysql&amp;gt;

-- 导入数据
mysql&amp;gt; load【漏德】 data  infile【因-伐尔】 &quot;/myload【my漏德】/passwd&quot; into【因兔】 table【忒-部】 db1.user3 fields【菲尔兹】 terminated【托 敏 内提】 by【拜】 &quot;:&quot; lines【赖嗯 s】 terminated【托 敏 内提】 by【拜】 &quot;\n&quot; ;
-- mysql&amp;gt; load data infile &quot;/myload/passwd&quot; into table db1.user3 fields terminated by &quot;:&quot; lines terminated by &quot;\n&quot;;
Query OK, 23 rows affected (0.06 sec)
Records: 23  Deleted: 0  Skipped: 0  Warnings: 0

-- 查看表记录
mysql&amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】  db1.user3;
-- mysql&amp;gt; select count(*) from db1.user3;
+----------+
| count(*) |
+----------+
|       23 |
+----------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.user3;
-- mysql&amp;gt; select * from db1.user3;
+------------------+----------+-------+-------+-----------------------------+-----------------+----------------+
| name             | password | uid   | gid   | comment                     | homedir         | shell          |
+------------------+----------+-------+-------+-----------------------------+-----------------+----------------+
| root             | x        |     0 |     0 | root                        | /root           | /bin/bash      |
| bin              | x        |     1 |     1 | bin                         | /bin            | /sbin/nologin  |
| daemon           | x        |     2 |     2 | daemon                      | /sbin           | /sbin/nologin  |
| adm              | x        |     3 |     4 | adm                         | /var/adm        | /sbin/nologin  |
| lp               | x        |     4 |     7 | lp                          | /var/spool/lpd  | /sbin/nologin  |
| sync             | x        |     5 |     0 | sync                        | /sbin           | /bin/sync      |
| shutdown         | x        |     6 |     0 | shutdown                    | /sbin           | /sbin/shutdown |
| halt             | x        |     7 |     0 | halt                        | /sbin           | /sbin/halt     |
| mail             | x        |     8 |    12 | mail                        | /var/spool/mail | /sbin/nologin  |
| operator         | x        |    11 |     0 | operator                    | /root           | /sbin/nologin  |
| games            | x        |    12 |   100 | games                       | /usr/games      | /sbin/nologin  |
| ftp              | x        |    14 |    50 | FTP User                    | /var/ftp        | /sbin/nologin  |
| nobody           | x        | 65534 | 65534 | Kernel Overflow User        | /               | /sbin/nologin  |
| dbus             | x        |    81 |    81 | System message bus          | /               | /sbin/nologin  |
| systemd-coredump | x        |   999 |   997 | systemd Core Dumper         | /               | /sbin/nologin  |
| systemd-resolve  | x        |   193 |   193 | systemd Resolver            | /               | /sbin/nologin  |
| polkitd          | x        |   998 |   995 | User for polkitd            | /               | /sbin/nologin  |
| unbound          | x        |   997 |   994 | Unbound DNS resolver        | /etc/unbound    | /sbin/nologin  |
| tss              | x        |    59 |    59 | Account used for TPM access | /dev/null       | /sbin/nologin  |
| chrony           | x        |   996 |   993 |                             | /var/lib/chrony | /sbin/nologin  |
| sshd             | x        |    74 |    74 | Privilege-separated SSH     | /var/empty/sshd | /sbin/nologin  |
| tcpdump          | x        |    72 |    72 |                             | /               | /sbin/nologin  |
| mysql            | x        |    27 |    27 | MySQL Server                | /var/lib/mysql  | /sbin/nologin  |
+------------------+----------+-------+-------+-----------------------------+-----------------+----------------+
23 rows in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3 导出数据&lt;/h3&gt;
&lt;p&gt;将db1库user3表所有记录导出, 存到/myload【my漏德】/user.txt文件里。&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.user3 into【因兔】 outfile【奥特-伐尔】 &quot;/myload【my漏德】/user.txt&quot; ;
-- mysql&amp;gt; select * from db1.user3 into outfile &quot;/myload/user.txt&quot;;
Query OK, 23 rows affected (0.00 sec)

mysql&amp;gt; system【西斯屯】 ls /myload【my漏德】/
-- mysql&amp;gt; system ls /myload/
passwd  user.txt

mysql&amp;gt; system【西斯屯】 wc -l  /myload【my漏德】/user.txt
-- mysql&amp;gt; system wc -l /myload/user.txt
23 /myload/user.txt

mysql&amp;gt;
mysql&amp;gt; system【西斯屯】 vim /myload【my漏德】/user.txt
-- mysql&amp;gt; system vim /myload/user.txt
root    x       0       0       root    /root   /bin/bash
bin     x       1       1       bin     /bin    /sbin/nologin
daemon  x       2       2       daemon  /sbin   /sbin/nologin
adm     x       3       4       adm     /var/adm        /sbin/nologin
lp      x       4       7       lp      /var/spool/lpd  /sbin/nologin
sync    x       5       0       sync    /sbin   /bin/sync
shutdown        x       6       0       shutdown        /sbin   /sbin/shutdown
halt    x       7       0       halt    /sbin   /sbin/halt
mail    x       8       12      mail    /var/spool/mail /sbin/nologin
operator        x       11      0       operator        /root   /sbin/nologin
games   x       12      100     games   /usr/games      /sbin/nologin
ftp     x       14      50      FTP User        /var/ftp        /sbin/nologin
nobody  x       65534   65534   Kernel Overflow User    /       /sbin/nologin
dbus    x       81      81      System message bus      /       /sbin/nologin
systemd-coredump        x       999     997     systemd Core Dumper     /       /sbin/nologin
systemd-resolve x       193     193     systemd Resolver        /       /sbin/nologin
polkitd x       998     995     User for polkitd        /       /sbin/nologin
unbound x       997     994     Unbound DNS resolver    /etc/unbound    /sbin/nologin
tss     x       59      59      Account used for TPM access     /dev/null       /sbin/nologin
chrony  x       996     993             /var/lib/chrony /sbin/nologin
sshd    x       74      74      Privilege-separated SSH /var/empty/sshd /sbin/nologin
tcpdump x       72      72              /       /sbin/nologin
mysql   x       27      27      MySQL Server    /var/lib/mysql  /sbin/nologin
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、用户管理&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[数据导入导出与用户管理]
        direction LR
        A[数据导入导出] --&amp;gt; B[用户管理]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class B highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.1 问题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;允许所有主机使用root连接数据库服务，对所有库和所有表有完全权限、密码为123qqq…A&lt;/li&gt;
&lt;li&gt;允许192.168.90.0/24网段主机使用jam连接数据库服务，仅对gamedb库有完全权限、密码为moershi&lt;/li&gt;
&lt;li&gt;允许在本机使用jamadmin用户连接数据库服务器，仅对moershi库有查询、插入、更新、删除记录的权限，密码为NSD123456…a&lt;/li&gt;
&lt;li&gt;允许192.168.90.51主机使用yaya用户连接数据库服务，仅对moershi库有查询权限，密码为moershi1&lt;/li&gt;
&lt;li&gt;给yaya用户追加，插入记录的权限&lt;/li&gt;
&lt;li&gt;撤销jam用户删库、删表、删记录的权限&lt;/li&gt;
&lt;li&gt;删除jamadmin用户&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;4.2 方案&lt;/h3&gt;
&lt;p&gt;授权是在数据库服务器里添加用户并设置权限及密码；重复执行grant【古亮普】命令时如果库名和用户名不变时，是追加权限。授权步骤如下：&lt;/p&gt;
&lt;p&gt;授权信息保存在mysql库的如下表里：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;user表 保存已有的授权用户及用户对所有库的权限&lt;/li&gt;
&lt;li&gt;db表 保存已有授权用户对某一个库的访问权限&lt;/li&gt;
&lt;li&gt;tables【忒-部s】_priv【破略夫】表 记录已有授权用户对某一张表的访问权限&lt;/li&gt;
&lt;li&gt;columns【科勒姆 s】_priv【破略夫】表 记录已有授权用户对某一个表头的访问权限&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在192.168.90.50 数据库服务器练习用户授权&lt;/p&gt;
&lt;p&gt;在192.168.90.51 数据库服务器测试&lt;/p&gt;
&lt;p&gt;通过模板机克隆一台机器，修改主机名和IP地址&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.51/24 autoconnect【奥特欧 坑聂特】 yes
#[root@mha ~]# nmcli connection modify ens160 ipv4.addresses 192.168.90.51/24 autoconnect yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
#[root@mha ~]# nmcli connection up ens160
[root@mysql51 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql51
#[root@mha ~]# hostnamectl set-hostname mysql51
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装mysql-server服务软件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# yum -y install【因-斯多】 mysql-server【涩·沃】
#[root@mysql51 ~]# yum -y install mysql-server

#启动服务
[root@mysql51 ~]# systemctl【西斯屯-ctl】 start【s 达儿】 mysqld
#[root@mysql51 ~]# systemctl start mysqld

#设置开机自启
[root@mysql51 ~]# systemctl【西斯屯-ctl】 enable【ing 内 步】 mysqld
#[root@mysql51 ~]# systemctl enable mysqld
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.3 步骤&lt;/h3&gt;
&lt;p&gt;实现此案例需要按照如下步骤进行。&lt;/p&gt;
&lt;h4&gt;步骤一：在192.168.90.50 数据库服务器做如下授权练习&lt;/h4&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 数据库管理员登陆
[root@mysql51 ~]# mysql -uroot -pNSD123456...a
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;1）允许所有主机使用root连接数据库服务，对所有库和所有表有完全权限、密码为123qqq…A&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】 user root@&quot;%&quot; identified【爱-丹-提伐】 by【拜】 &quot;123qqq...A&quot;;    -- 创建用户
-- mysql&amp;gt; create user root@&quot;%&quot; identified by &quot;123qqq...A&quot;;
Query OK, 0 rows affected (0.08 sec)

mysql&amp;gt; grant【古亮普】 all【ò】 on【昂】 *.* to root@&quot;%&quot; ;    -- 授予权限
-- mysql&amp;gt; grant all on *.* to root@&quot;%&quot;;
Query OK, 0 rows affected (0.13 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在 MySQL 中，使用 &lt;code&gt;GRANT&lt;/code&gt; 语句来分配权限。其核心语法结构如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;GRANT 权限列表 ON 数据库对象 TO &apos;用户名&apos;@&apos;主机名&apos; [IDENTIFIED BY &apos;密码&apos;];
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;权限类别&lt;/th&gt;
&lt;th&gt;具体权限&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;数据定义 (DDL)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CREATE&lt;/code&gt;, &lt;code&gt;ALTER&lt;/code&gt;, &lt;code&gt;INDEX&lt;/code&gt;, &lt;code&gt;REFERENCES&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;允许创建、修改、删除表；创建和删除索引；创建外键 。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;数据操作 (DML)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT&lt;/code&gt;, &lt;code&gt;INSERT&lt;/code&gt;, &lt;code&gt;UPDATE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;允许对数据进行查询、插入和更新 。&lt;strong&gt;注意&lt;/strong&gt;：输出中不包含 &lt;code&gt;DELETE&lt;/code&gt; 权限，因此该用户不能删除数据行。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;存储程序与高级对象&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CREATE ROUTINE&lt;/code&gt;, &lt;code&gt;ALTER ROUTINE&lt;/code&gt;, &lt;code&gt;EXECUTE&lt;/code&gt;, &lt;code&gt;EVENT&lt;/code&gt;, &lt;code&gt;TRIGGER&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;允许创建、修改和执行存储过程和函数；创建和管理事件（定时任务）；创建和管理触发器 。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;视图管理&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CREATE VIEW&lt;/code&gt;, &lt;code&gt;SHOW VIEW&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;允许创建和查看视图的定义 。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;其他操作&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CREATE TEMPORARY TABLES&lt;/code&gt;, &lt;code&gt;LOCK TABLES&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;允许在操作时创建临时表，并显式锁定表 。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;基本连接&lt;/td&gt;
&lt;td&gt;&lt;code&gt;USAGE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;仅表示该用户账户存在，并允许其连接数据库。默认情况下，此权限不授予任何数据库操作权限 。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;权限列表&lt;/strong&gt;：指定要授予的具体操作权限。对于记录的增删改查，主要涉及以下四种：
-   &lt;code&gt;SELECT&lt;/code&gt;：允许查询（检索）数据。
-   &lt;code&gt;INSERT&lt;/code&gt;：允许插入（添加）新记录。
-   &lt;code&gt;UPDATE&lt;/code&gt;：允许更新（修改）现有记录。
-   &lt;code&gt;DELETE&lt;/code&gt;：允许删除记录。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;数据库对象&lt;/strong&gt;：定义权限的作用范围，使用 &lt;code&gt;数据库名.表名&lt;/code&gt; 的格式指定。
-   &lt;code&gt;mydb.mytable&lt;/code&gt;：授权针对 &lt;code&gt;mydb&lt;/code&gt; 数据库下的 &lt;code&gt;mytable&lt;/code&gt; 表。
-   &lt;code&gt;mydb.*&lt;/code&gt;：授权针对 &lt;code&gt;mydb&lt;/code&gt; 数据库下的所有表（这是最常用的场景）。
-   &lt;code&gt;*.*&lt;/code&gt;：授权针对服务器上所有数据库的所有表（通常仅限管理员用户）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;用户与主机&lt;/strong&gt;：指定被授权的用户及其允许连接的主机，格式为 &lt;code&gt;&apos;用户名&apos;@&apos;主机名&apos;&lt;/code&gt;。
-   &lt;code&gt;&apos;user1&apos;@&apos;localhost&apos;&lt;/code&gt;：仅允许用户 &lt;code&gt;user1&lt;/code&gt; 从数据库服务器本机连接。
-   &lt;code&gt;&apos;user1&apos;@&apos;%&apos;&lt;/code&gt;：允许用户 &lt;code&gt;user1&lt;/code&gt; 从任何远程主机连接。&lt;code&gt;%&lt;/code&gt; 在这里是一个通配符。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;密码设置（可选）&lt;/strong&gt;：在 &lt;code&gt;GRANT&lt;/code&gt; 语句中直接指定或修改用户的密码。更推荐的做法是先使用 &lt;code&gt;CREATE USER&lt;/code&gt; 语句明确创建用户。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;授予特定数据库的所有表权限&lt;/strong&gt;
假设想让用户 &lt;code&gt;report_user&lt;/code&gt; 可以从任何主机连接，并拥有对数据库 &lt;code&gt;samp_db&lt;/code&gt; 中所有表进行增删改查的权限，可以使用以下命令：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;  ```sql
  GRANT SELECT, INSERT, UPDATE, DELETE ON samp_db.* TO &apos;report_user&apos;@&apos;%&apos;;
  ```
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;创建用户并授权（完整步骤）&lt;/strong&gt;
这是一个更清晰、安全的做法，将创建用户和授权分步进行：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;  ```sql
  -- 1. 创建用户
  CREATE USER &apos;dev_user&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;secure_password&apos;;
  -- 2. 授予特定权限（例如，对test_db数据库的所有表）
  GRANT SELECT, INSERT, UPDATE, DELETE ON test_db.* TO &apos;dev_user&apos;@&apos;localhost&apos;;
  -- 3. 使权限设置立即生效
  FLUSH PRIVILEGES;
  ```
  执行 `FLUSH PRIVILEGES;` 命令是为了让服务器重新加载权限表，确保新的权限设置立即生效。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;查看用户权限&lt;/strong&gt;
授权完成后，可以验证权限是否已正确分配：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;  ```sql
  SHOW GRANTS FOR &apos;dev_user&apos;@&apos;localhost&apos;;
  ```
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;撤销权限&lt;/strong&gt;
如果需要收回某些权限，可以使用 &lt;code&gt;REVOKE【瑞 - 沃克】&lt;/code&gt; 语句。例如，撤销 &lt;code&gt;dev_user&lt;/code&gt; 对 &lt;code&gt;test_db&lt;/code&gt; 的删除权限：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;  ```sql
  REVOKE【瑞 - 沃克】 DELETE ON test_db.* FROM &apos;dev_user&apos;@&apos;localhost&apos;;
  FLUSH PRIVILEGES;
  ```
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;2）允许192.168.90.0/24网段主机使用jam连接数据库服务，仅对gamedb库有完全权限、密码为moershi&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】 user jam@&quot;192.168.90.0/24&quot; identified【爱-丹-提伐】 by【拜】 &quot;moershi&quot;;    -- 创建用户
-- mysql&amp;gt; create user jam@&quot;192.168.88.0/24&quot; identified by &quot;moershi&quot;;
Query OK, 0 rows affected (0.06 sec)

mysql&amp;gt; grant【古亮普】 all【ò】 on【昂】  gamedb.*  to jam@&quot;192.168.90.0/24&quot;;    -- 授予权限
-- mysql&amp;gt; grant all on gamedb.* to jam@&quot;192.168.88.0/24&quot;;
Query OK, 0 rows affected (0.05 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;3）允许在本机使用jamadmin用户连接数据库服务器，仅对moershi库有查询、插入、更新、删除记录的权限，密码为NSD123456…a&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】 user jamadmin@&quot;localhost&quot; identified【爱-丹-提伐】 by【拜】 &quot;NSD123456...a&quot;;    -- 创建用户
-- mysql&amp;gt; create user jamadmin@&quot;localhost&quot; identified by &quot;NSD123456...a&quot;;
Query OK, 0 rows affected (0.05 sec)

mysql&amp;gt; grant【古亮普】  select【涩莱克特】 , insert【因涩特】 , update【阿普 dei 特】,delete【迪  利 特】 on【昂】 moershi.* to jamadmin@&quot;localhost&quot;;   -- 授予权限
-- mysql&amp;gt; grant select,insert,update,delete on moershi.* to jamadmin@&quot;localhost&quot;;
Query OK, 0 rows affected (0.06 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;4）允许192.168.90.51主机使用yaya用户连接数据库服务，仅对moershi库有查询权限，密码为moershi1&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】 user yaya@&quot;192.168.90.51&quot;  identified【爱-丹-提伐】 by【拜】 &quot;moershi1&quot; ;    -- 创建用户
-- mysql&amp;gt; create user yaya@&quot;192.168.88.40&quot; identified by &quot;moershi&quot;;
Query OK, 0 rows affected (0.10 sec)

mysql&amp;gt; grant【古亮普】 select【涩莱克特】 on【昂】 moershi.* to yaya@&quot;192.168.90.51&quot;;    -- 授予权限
-- mysql&amp;gt; grant select on moershi.* to yaya@&quot;192.168.88.40&quot;;
Query OK, 0 rows affected (0.07 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;5）给yaya用户追加，插入记录的权限&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; grant【古亮普】 insert【因涩特】 on【昂】 moershi.* to yaya@&quot;192.168.90.51&quot;;
-- mysql&amp;gt; grant insert on moershi.* to yaya@&quot;192.168.88.40&quot;;
Query OK, 0 rows affected (0.05 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;6）查看添加的用户&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;-- 添加的用户保存在 mysql库的user表里
mysql&amp;gt; select【涩莱克特】  host,user from【弗乱】  mysql.user; 
-- mysql&amp;gt; select user,host from mysql.user;
+-----------------+------------------+
| host            | user             |
+-----------------+------------------+
| %               | root             |
| 192.168.90.0/24 | jam              |
| 192.168.90.51   | yaya             |
| localhost       | mysql.infoschema |
| localhost       | mysql.session    |
| localhost       | mysql.sys        |
| localhost       | jamadmin         |
| localhost       | root             |
+-----------------+------------------+
8 rows in set (0.00 sec)

-- 查看已有用户的访问权限
mysql&amp;gt; show【瘦】 grants【哥亮特s】 for【fò】 yaya@&quot;192.168.90.51&quot;; 
-- mysql&amp;gt; show grants for yaya@&quot;192.168.88.40&quot;;
-- +---------------------------------------------------------------+
-- | Grants for yaya@192.168.88.40                                 |
-- +---------------------------------------------------------------+
-- | GRANT USAGE ON *.* TO &apos;yaya&apos;@&apos;192.168.88.40&apos;                  |
-- | GRANT SELECT, INSERT ON `moershi`.* TO &apos;yaya&apos;@&apos;192.168.88.40&apos; |
-- +---------------------------------------------------------------+
-- 2 rows in set (0.00 sec)

-- 用户对某一个库的访问权限保存在mysql库的db表里
mysql&amp;gt; select【涩莱克特】  * from【弗乱】  mysql.db where【威尔】 db=&quot;moershi&quot;  and user=&quot;yaya&quot; \G
-- mysql&amp;gt; select * from mysql.db where db=&quot;moershi&quot; and user=&quot;yaya&quot; \G
*************************** 1. row ***************************
                 Host: 192.168.88.40
                   Db: moershi
                 User: yaya
          Select_priv: Y
          Insert_priv: Y
          Update_priv: N
          Delete_priv: N
          Create_priv: N
            Drop_priv: N
           Grant_priv: N
      References_priv: N
           Index_priv: N
           Alter_priv: N
Create_tmp_table_priv: N
     Lock_tables_priv: N
     Create_view_priv: N
       Show_view_priv: N
  Create_routine_priv: N
   Alter_routine_priv: N
         Execute_priv: N
           Event_priv: N
         Trigger_priv: N
1 row in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;7）撤销jam用户删库、删表、删记录的权限&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;-- 先查看jam用户的权限
-- mysql&amp;gt; show grants for jam@&quot;192.168.88.0/24&quot;;
-- +---------------------------------------------------------------+
-- | Grants for jam@192.168.88.0/24                                |
-- +---------------------------------------------------------------+
-- | GRANT USAGE ON *.* TO &apos;jam&apos;@&apos;192.168.88.0/24&apos;                 |
-- | GRANT ALL PRIVILEGES ON `gamedb`.* TO &apos;jam&apos;@&apos;192.168.88.0/24&apos; |
-- +---------------------------------------------------------------+
-- 2 rows in set (0.01 sec)
-- 撤销权限
mysql&amp;gt; revoke【瑞 - 沃克】 delete【迪  利 特】,drop【卓-普】 on【昂】 gamedb.* from【弗乱】 jam@&quot;192.168.90.0/24&quot; ;
-- mysql&amp;gt; revoke delete,drop on gamedb.* from jam@&quot;192.168.88.0/24&quot;;

-- 查看撤销后jam用户的权限
-- mysql&amp;gt; show grants for jam@&quot;192.168.88.0/24&quot;;
-- +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- | Grants for jam@192.168.88.0/24                                                                                                                                                                                                |
-- +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- | GRANT USAGE ON *.* TO &apos;jam&apos;@&apos;192.168.88.0/24&apos;                                                                                                                                                                                 |
-- | GRANT SELECT, INSERT, UPDATE, CREATE, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON `gamedb`.* TO &apos;jam&apos;@&apos;192.168.88.0/24&apos; |
-- +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- 2 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;8）修改yaya用户的登陆密码为123456&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; set【赛特】 password【帕斯沃德】 for【fò】 yaya@&quot;192.168.90.51&quot;=&quot;123456&quot; ;
-- mysql&amp;gt; set password for yaya@&quot;192.168.88.40&quot;=&quot;123456&quot;;
Query OK, 0 rows affected (0.05 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;9）删除jamadmin用户&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; drop【卓-普】 user jamadmin@&quot;localhost&quot; ;
-- mysql&amp;gt; drop user jamadmin@&quot;localhost&quot;;
Query OK, 0 rows affected (0.04 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;步骤二：在192.168.90.51测试授权&lt;/h4&gt;
&lt;p&gt;命令格式 mysql -h数据库服务器ip地址 –u用户名 -p密码&lt;/p&gt;
&lt;h5&gt;1）在mysql51连接mysql50 （使用50 添加的yaya 用户）&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# mysql -h192.168.90.50 -uyaya -p123456
#[root@mysql51 ~]# mysql -h 192.168.88.10 -uyaya -p123456
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; show【瘦】 grants【哥亮特】; //查看权限
-- mysql&amp;gt; show grants;
-- +---------------------------------------------------------------+
-- | Grants for yaya@192.168.88.40                                 |
-- +---------------------------------------------------------------+
-- | GRANT USAGE ON *.* TO &apos;yaya&apos;@&apos;192.168.88.40&apos;                  |
-- | GRANT SELECT, INSERT ON `moershi`.* TO &apos;yaya&apos;@&apos;192.168.88.40&apos; |
-- +---------------------------------------------------------------+
-- 2 rows in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 user();   -- 查看登陆信息
-- mysql&amp;gt; select user();
-- +--------------------+
-- | user()             |
-- +--------------------+
-- | yaya@192.168.88.40 |
-- +--------------------+
-- 1 row in set (0.00 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】  moershi.user(name,uid) values【挖柳斯】(&quot;jim&quot;,11);    -- 插入数据权限内可以执行
-- mysql&amp;gt; insert into moershi.user(name,uid) values(&quot;jim&quot;,11);
Query OK, 1 row affected (0.06 sec)

mysql&amp;gt; delete【迪  利 特】 from【弗乱】  moershi.salary【晒了瑞】 ;    -- 删表超出权限 报错
-- mysql&amp;gt; delete from moershi.salary;
-- ERROR 1142 (42000): DELETE command denied to user &apos;yaya&apos;@&apos;192.168.88.40&apos; for table &apos;salary&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、作业&lt;/h2&gt;
&lt;h3&gt;选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;在 MySQL 里，若要创建一个新用户 &apos;test_user&apos; 并指定其可从任意主机登录，使用的命令是（ A ）
A. CREATE USER &apos;test_user&apos;@&apos;%&apos; IDENTIFIED BY &apos;password&apos;;
B. CREATE USER &apos;test_user&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;password&apos;;
C. CREATE USER &apos;test_user&apos; IDENTIFIED BY &apos;password&apos;;
D. ADD USER &apos;test_user&apos;@&apos;%&apos; IDENTIFIED BY &apos;password&apos;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;下列哪种情况最适合使用 &lt;code&gt;LOAD DATA INFILE&lt;/code&gt; 进行数据导入？（ C ）
A. 导入从网页爬取的不规则数据
B. 把 Excel 文件中的数据导入 MySQL
C. 从 MySQL 导出的数据文件重新导入数据库
D. 导入图片数据到 MySQL&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;LOAD DATA INFILE最适合处理格式规整的文本文件
MySQL 导出的数据文件（如使用 SELECT ... INTO OUTFILE导出的）格式规整，最适合用此命令重新导入
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;想要撤销用户 &apos;user1&apos; 对 &apos;db1&apos; 数据库下 &apos;table1&apos; 表的所有权限，正确的 SQL 语句是（ A ）
A. REVOKE ALL PRIVILEGES ON db1.table1 FROM &apos;user1&apos;@&apos;%&apos;;
B. REMOVE ALL PRIVILEGES ON db1.table1 FROM &apos;user1&apos;@&apos;%&apos;;
C. DELETE ALL PRIVILEGES ON db1.table1 FROM &apos;user1&apos;@&apos;%&apos;;
D. CANCEL ALL PRIVILEGES ON db1.table1 FROM &apos;user1&apos;@&apos;%&apos;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;若要查看当前 MySQL 服务器上所有用户，应执行的命令是（ B ）
A. SHOW USERS;
B. SELECT * FROM mysql.user;
C. SHOW ALL USERS;
D. LIST USERS;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;执行数据导出时，若使用 &lt;code&gt;SELECT ... INTO OUTFILE&lt;/code&gt; 语句，对导出文件所在目录的要求是（ C ）
A. 必须是 MySQL 安装目录
B. 必须是系统临时目录
C. 该目录必须是 MySQL 进程有写入权限的目录
D. 该目录必须是用户主目录&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;阐述 MySQL 中用户管理的重要性以及主要的管理内容。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在 MySQL 中，实施有效的用户管理是保障数据库安全的核心环节。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;重要性：如果所有操作都使用拥有最高权限的 &lt;code&gt;root&lt;/code&gt; 账户，会带来极大的安全隐患。一旦此账户泄露，攻击者可能完全控制数据库。通过用户管理，可以实现权限分离（不同用户只能访问其职责范围内的数据）、安全控制（防止误操作或恶意操作）和审计追踪（记录谁在何时做了什么）。&lt;/li&gt;
&lt;li&gt;主要管理内容：用户管理主要涉及用户账户的创建、修改、删除以及权限的授予与回收。具体操作包括使用 &lt;code&gt;CREATE USER&lt;/code&gt; 创建用户（需指定用户名、允许登录的主机及密码），使用 &lt;code&gt;DROP USER&lt;/code&gt; 删除用户（必须同时指定用户名和主机名），以及使用 &lt;code&gt;ALTER USER&lt;/code&gt; 或 &lt;code&gt;SET PASSWORD&lt;/code&gt; 修改用户密码。所有用户信息都存储在 &lt;code&gt;mysql&lt;/code&gt; 系统数据库的 &lt;code&gt;user&lt;/code&gt; 表中。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;说明 &lt;code&gt;LOAD DATA INFILE&lt;/code&gt; 和 &lt;code&gt;SELECT ... INTO OUTFILE&lt;/code&gt; 在数据导入导出方面的区别与联系。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;LOAD DATA INFILE&lt;/code&gt; 和 &lt;code&gt;SELECT ... INTO OUTFILE&lt;/code&gt; 是 MySQL 中用于高效数据导入和导出的两个互补命令。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;功能区别：&lt;code&gt;SELECT ... INTO OUTFILE&lt;/code&gt; 主要用于将数据库查询结果导出到服务器主机上的指定格式文件中。而 &lt;code&gt;LOAD DATA INFILE&lt;/code&gt; 则是其逆操作，用于将格式化的数据文件从服务器主机快速导入到数据库表中，执行效率通常远高于逐条 &lt;code&gt;INSERT&lt;/code&gt; 语句。使用 &lt;code&gt;LOCAL&lt;/code&gt; 关键字时，&lt;code&gt;LOAD DATA LOCAL INFILE&lt;/code&gt; 可以从客户端主机读取文件。&lt;/li&gt;
&lt;li&gt;语法联系：这两个命令在指定数据格式时使用相似的子句，可以定义字段和行的处理方式，例如 &lt;code&gt;FIELDS TERMINATED BY&lt;/code&gt;（字段分隔符）、&lt;code&gt;LINES TERMINATED BY&lt;/code&gt;（行终止符）等。这意味着可以方便地使用 &lt;code&gt;SELECT ... INTO OUTFILE&lt;/code&gt; 导出数据后，再用 &lt;code&gt;LOAD DATA INFILE&lt;/code&gt; 按相同格式将其导入。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;当在数据导入过程中遇到数据格式不匹配的问题，你会采取哪些解决办法？&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在使用 &lt;code&gt;LOAD DATA INFILE&lt;/code&gt; 导入数据时，如果遇到数据格式不匹配（如字段不对应、分隔符错误等），可以通过以下方式解决：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;明确指定格式选项：在 &lt;code&gt;LOAD DATA INFILE&lt;/code&gt; 语句中，通过 &lt;code&gt;FIELDS TERMINATED BY&lt;/code&gt;、&lt;code&gt;ENCLOSED BY&lt;/code&gt;、&lt;code&gt;ESCAPED BY&lt;/code&gt; 以及 &lt;code&gt;LINES TERMINATED BY&lt;/code&gt; 等子句，确保指定的格式与源文件的实际格式完全匹配。&lt;/li&gt;
&lt;li&gt;忽略文件标题行：如果数据文件包含标题行，可以使用 &lt;code&gt;IGNORE number LINES&lt;/code&gt; 子句跳过文件开头指定行数的内容。&lt;/li&gt;
&lt;li&gt;指定列映射：如果文件中的列顺序与数据库表中的列顺序不一致，可以在 &lt;code&gt;LOAD DATA INFILE&lt;/code&gt; 语句末尾的 &lt;code&gt;(col_name1, col_name2, ...)&lt;/code&gt; 部分明确指定列的顺序映射。&lt;/li&gt;
&lt;li&gt;字符集处理：如果文件编码与数据库字符集不匹配，可能产生乱码。可以使用 &lt;code&gt;CHARACTER SET&lt;/code&gt; 子句指定输入文件的正确字符集。&lt;/li&gt;
&lt;li&gt;数据转换：&lt;code&gt;LOAD DATA INFILE&lt;/code&gt; 支持在导入时通过 &lt;code&gt;SET&lt;/code&gt; 子句对数据进行简单转换或计算，例如 &lt;code&gt;SET id=id+5&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;描述如何对 MySQL 用户权限进行精细管理，以保障数据库安全。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;为保障数据库安全，对用户权限进行精细化管理至关重要，核心原则是最小权限原则，即只授予用户完成其工作所必需的最小权限。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;权限层级：MySQL 的权限可以在不同层级进行设置，包括全局层级（所有数据库，如 &lt;code&gt;*.*&lt;/code&gt;）、数据库层级（指定数据库的所有对象，如 &lt;code&gt;mydb.*&lt;/code&gt;）、表层级（特定表）、列层级（表的特定列）甚至存储过程层级。例如，可以只授予某个用户对员工表的 &lt;code&gt;姓名&lt;/code&gt; 和 &lt;code&gt;部门&lt;/code&gt; 列有 &lt;code&gt;SELECT&lt;/code&gt; 权限，而无权查看 &lt;code&gt;薪资&lt;/code&gt; 列。&lt;/li&gt;
&lt;li&gt;使用角色：可以创建角色，将一组常用的权限授予角色，然后再将角色授予用户，这极大地简化了权限管理。&lt;/li&gt;
&lt;li&gt;授权与回收：使用 &lt;code&gt;GRANT&lt;/code&gt; 语句授予权限，使用 &lt;code&gt;REVOKE&lt;/code&gt; 语句回收权限。授权后通常需要执行 &lt;code&gt;FLUSH PRIVILEGES;&lt;/code&gt; 命令使新权限立即生效（在某些情况下 MySQL 会自动刷新）。&lt;/li&gt;
&lt;li&gt;网络限制：创建用户时，应通过 &lt;code&gt;&apos;用户名&apos;@&apos;主机名&apos;&lt;/code&gt; 的格式限制用户只能从特定的 IP 地址或网段登录数据库，例如 &lt;code&gt;&apos;app_user&apos;@&apos;192.168.1.%&apos;&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;定期审计：定期检查用户权限，及时回收不必要的权限。可以使用 &lt;code&gt;SHOW GRANTS FOR &apos;username&apos;@&apos;hostname&apos;;&lt;/code&gt; 命令查看特定用户的权限。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;简述在数据导出时，设置不同字段和行分隔符的作用及方法。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在数据导出时，通过 &lt;code&gt;SELECT ... INTO OUTFILE&lt;/code&gt; 语句设置字段和行分隔符，主要是为了控制导出文件的格式，使其易于被其他程序（如 Excel、其他数据库系统或自定义脚本）正确解析和读取。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;作用：
&lt;ul&gt;
&lt;li&gt;字段分隔符：定义了文件中每个字段（列）之间的分隔符号，默认为制表符 &lt;code&gt;\t&lt;/code&gt;。常用符号有逗号 (&lt;code&gt;,&lt;/code&gt;) 用于生成 CSV 文件。&lt;/li&gt;
&lt;li&gt;行分隔符：定义了文件中每条记录（行）之间的分隔符号，默认为换行符 &lt;code&gt;\n&lt;/code&gt;。在不同操作系统中可能有所不同，例如在 Windows 系统中可能需要设置为 &lt;code&gt;\r\n&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;设置方法：在 &lt;code&gt;SELECT ... INTO OUTFILE&lt;/code&gt; 语句中使用 &lt;code&gt;FIELDS&lt;/code&gt; 和 &lt;code&gt;LINES&lt;/code&gt; 子句进行定义。&lt;pre&gt;&lt;code&gt;SELECT * FROM your_table
INTO OUTFILE &apos;/path/to/export/file.csv&apos;
FIELDS TERMINATED BY &apos;,&apos; OPTIONALLY ENCLOSED BY &apos;&quot;&apos; -- 字段由逗号分隔，并用双引号包围
LINES TERMINATED BY &apos;\n&apos;; -- 行以换行符结束
&lt;/code&gt;&lt;/pre&gt;
通过合理设置这些分隔符和包围字符，可以确保导出的数据格式规整，避免因数据本身包含分隔符而导致解析错误。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;创建一个名为 &apos;new_db&apos; 的数据库，接着创建用户 &apos;admin_user&apos; 并赋予其对 &apos;new_db&apos; 数据库的所有权限，然后创建用户 &apos;guest_user&apos; 仅赋予对 &apos;new_db&apos; 中 &apos;table1&apos; 表的查询权限。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;实战案例：MySQL 用户权限管理&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这是一个完整的MySQL用户权限管理实战示例，展示如何创建数据库、用户，并分配不同级别的权限。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 数据库创建
mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】 new_db【牛-滴比】;
-- mysql&amp;gt; create database new_db;
Query OK, 1 row affected (6.379 sec)

-- admin_user 用户创建
mysql&amp;gt; create【克瑞特】 user【右瑟】 admin_user【admin-右瑟】@&quot;%&quot; identified【爱-丹-提伐】 by【拜】 &quot;admin_user&quot;; 
-- mysql&amp;gt; create user admin_user@&quot;%&quot; identified by &quot;admin_user&quot;;
Query OK, 0 rows affected (7.111 sec)

-- admin_user 用户赋予权限
mysql&amp;gt; grant【古亮普】 all【ò】 on【昂】 new_db【牛-滴比】.* to admin_user【admin-右瑟】@&quot;%&quot;; 
-- mysql&amp;gt; grant all on new_db.* to admin_user@&quot;%&quot;;
Query OK, 0 rows affected (0.680 sec)

-- guest_user 用户创建
mysql&amp;gt; create【克瑞特】 user【右瑟】 guest_user【盖斯特-右瑟】@&quot;%&quot; identified【爱-丹-提伐】 by【拜】 &quot;guest_user【盖斯特-右瑟】&quot;;
-- mysql&amp;gt; create user guest_user@&quot;%&quot; identified by &quot;guest_user&quot;;
Query OK, 0 rows affected (0.224 sec)

-- 创建new_db.table1
mysql&amp;gt; create【克瑞特】 table【忒-部】 new_db【牛-滴比】.table1【忒-部-万】(id int【因特】); 
-- mysql&amp;gt; create table new_db.table1(id int);
Query OK, 0 rows affected (2.602 sec)

-- guest_user 用户赋予权限
mysql&amp;gt; grant【古亮普】 select【涩莱克特】 on【昂】 new_db【牛-滴比】.table1【忒-部-万】 to guest_user【盖斯特-右瑟】@&quot;%&quot;;
-- mysql&amp;gt; grant select on new_db.table1 to guest_user@&quot;%&quot;;
Query OK, 0 rows affected (0.295 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;权限验证&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;检查创建的用户和权限：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 查看用户列表
mysql&amp;gt; select【涩莱克特】 user【右瑟】, host【厚斯特】 from【弗乱】 mysql.user【右瑟】 where【威尔】 user【右瑟】 like【赖特】 &apos;%admin%&apos; or user【右瑟】 like【赖特】 &apos;%guest%&apos;;
-- mysql&amp;gt; select user, host from mysql.user where user like &apos;%admin%&apos; or user like &apos;%guest%&apos;;
+-------------+------+
| user        | host |
+-------------+------+
| admin_user  | %    |
| guest_user  | %    |
+-------------+------+
2 rows in set (0.00 sec)

-- 查看 admin_user 权限
mysql&amp;gt; show【瘦】 grants【古亮普 s】 for【fó】 admin_user【admin-右瑟】@&quot;%&quot;;
-- mysql&amp;gt; show grants for admin_user@&quot;%&quot;;
+-------------------------------------------------------------+
| Grants for admin_user@%                                     |
+-------------------------------------------------------------+
| GRANT USAGE ON *.* TO &apos;admin_user&apos;@&apos;%&apos;                      |
| GRANT ALL PRIVILEGES ON `new_db`.* TO &apos;admin_user&apos;@&apos;%&apos;      |
+-------------------------------------------------------------+

-- 查看 guest_user 权限
mysql&amp;gt; show【瘦】 grants【古亮普 s】 for【fó】 guest_user【盖斯特-右瑟】@&quot;%&quot;;
-- mysql&amp;gt; show grants for guest_user@&quot;%&quot;;
+-------------------------------------------------------------+
| Grants for guest_user@%                                     |
+-------------------------------------------------------------+
| GRANT USAGE ON *.* TO &apos;guest_user&apos;@&apos;%&apos;                      |
| GRANT SELECT ON `new_db`.`table1` TO &apos;guest_user&apos;@&apos;%&apos;      |
+-------------------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;功能说明&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;admin_user&lt;/strong&gt;：拥有对 &lt;code&gt;new_db&lt;/code&gt; 数据库的&lt;strong&gt;完全权限&lt;/strong&gt;（包括创建表、插入、更新、删除等所有操作）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;guest_user&lt;/strong&gt;：仅拥有对 &lt;code&gt;new_db.table1&lt;/code&gt; 表的&lt;strong&gt;查询权限&lt;/strong&gt;（只能查看数据，不能修改）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;权限级别&lt;/strong&gt;：展示了从数据库级别到表级别的权限控制&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全实践&lt;/strong&gt;：体现了最小权限原则，只为用户分配完成工作所需的最小权限&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;mysql&amp;gt; -- guest_user 用户创建
mysql&amp;gt; create user guest_user@&quot;%&quot; identified by &quot;guest_user&quot;;
Query OK, 0 rows affected (0.224 sec)&lt;/p&gt;
&lt;p&gt;mysql&amp;gt; -- 创建new_db.table1
mysql&amp;gt; create table new_db.table1(id int);
Query OK, 0 rows affected (2.602 sec)&lt;/p&gt;
&lt;p&gt;mysql&amp;gt; -- guest_user 用户赋予查询权限
mysql&amp;gt; grant select on new_db.table1 to guest_user@&quot;%&quot;;
Query OK, 0 rows affected (0.295 sec)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
2. 从 &apos;employees&apos; 表中导出员工的每一列信息到一个 TXT 文件，要求使用逗号作为字段分隔符，换行符作为行分隔符。之后将这个 TXT 文件中的数据导入到新创建的 &apos;employees_backup&apos; 表。
```sql
mysql&amp;gt;-- 导出moershi.employees
mysql&amp;gt; select * from moershi.employees into outfile &quot;/myload/employees.txt&quot; fields terminated by &quot;,&quot; lines terminated by &quot;\n&quot;; 
Query OK, 136 rows affected (0.200 sec)

mysql&amp;gt;-- 创建new_db.employees_backup
mysql&amp;gt; create table new_db.employees_backup like moershi.employees;
Query OK, 0 rows affected (3.269 sec)

mysql&amp;gt; -- 导入
mysql&amp;gt; load data infile &quot;/myload/employees.txt&quot; into table new_db.employees_backup fields terminated by &quot;,&quot; lines terminated by &quot;\n&quot;; 
Query OK, 136 rows affected (1.059 sec)
Records: 136  Deleted: 0  Skipped: 0  Warnings: 0

mysql&amp;gt; select count(*) from new_db.employees_backup; 
+----------+
| count(*) |
+----------+
|      136 |
+----------+
1 row in set (0.351 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;对用户 &apos;editor_user&apos; 的权限进行调整，撤销其对 &apos;news&apos; 数据库下 &apos;articles&apos; 表的删除权限，同时增加更新权限。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; --创建数据库
mysql&amp;gt; create database news;
Query OK, 1 row affected (0.664 sec)

mysql&amp;gt;-- 创建表
mysql&amp;gt; create table news.articles(id int,name varchar(9));
Query OK, 0 rows affected (2.513 sec)

mysql&amp;gt;-- 创建用户
mysql&amp;gt; create user editor_user@&quot;%&quot; identified by &quot;editor_user&quot;; 
Query OK, 0 rows affected (1.115 sec)

mysql&amp;gt;-- 赋予权限
mysql&amp;gt; grant all on news.articles to editor_user@&quot;%&quot;; 
Query OK, 0 rows affected (0.571 sec)

mysql&amp;gt;-- 撤销权限
mysql&amp;gt; revoke delete on news.articles from editor_user@&quot;%&quot;;  
Query OK, 0 rows affected (0.438 sec)

mysql&amp;gt;-- 增加权限
mysql&amp;gt; grant update on news.articles to editor_user@&quot;%&quot;;   
Query OK, 0 rows affected (0.469 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;先创建一个新用户 &apos;temp_user&apos;，仅赋予其对 &apos;test_db&apos; 数据库下 &apos;logs&apos; 表的插入权限，在完成数据插入任务后，删除该用户。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; --创建数据库
mysql&amp;gt; create database test_db;
Query OK, 1 row affected (0.648 sec)

mysql&amp;gt; -- 创建表
mysql&amp;gt; create table test_db.logs(
    -&amp;gt; id int,
    -&amp;gt; logs varchar(200));
Query OK, 0 rows affected (1.589 sec)

mysql&amp;gt; 创建用户
mysql&amp;gt; create user temp_user@&quot;%&quot; identified by &quot;temp_user&quot;;
Query OK, 0 rows affected (0.760 sec)

mysql&amp;gt; --赋予权限
mysql&amp;gt; grant insert on  test_db.logs to temp_user@&quot;%&quot;;
Query OK, 0 rows affected (0.676 sec)

mysql&amp;gt; --插入数据
mysql&amp;gt; insert into test_db.logs values(1,&quot;程序卡死&quot;); 
Query OK, 1 row affected (0.291 sec)

mysql&amp;gt; --删除用户
mysql&amp;gt; drop user temp_user@&quot;%&quot;;
Query OK, 0 rows affected (0.693 sec)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>08：mysql之备份与恢复</title><link>https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/08-mysql%E4%B9%8B%E5%A4%87%E4%BB%BD%E4%B8%8E%E6%81%A2%E5%A4%8D/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/08-mysql%E4%B9%8B%E5%A4%87%E4%BB%BD%E4%B8%8E%E6%81%A2%E5%A4%8D/</guid><description>08：mysql之备份与恢复 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 07:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1&gt;08：mysql之备份与恢复&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[mysql之备份与恢复]
        direction LR
        A[mysqldump&amp;lt;br/&amp;gt;备份与恢复] --&amp;gt; B[增量备份&amp;lt;br/&amp;gt;与恢复] --&amp;gt; C[差分备份&amp;lt;br/&amp;gt;与恢复]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class E highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;在一家电商公司的运营过程中，数据库管理员小张日常负责 MySQL 数据库的维护。某天，开发团队要对数据库进行大规模的架构升级，为防止升级过程中出现数据丢失或损坏，小张决定对 MySQL 数据库进行备份。他使用 mysqldump【mysql-当普】 工具，将数据库中的数据和结构导出到一个 SQL 文件中，并把文件存储在多个安全的存储位置。然而，升级过程中出现了意外，数据库中的部分数据丢失。小张迅速行动，利用之前备份的 SQL 文件，使用 mysql 命令将数据恢复到升级前的状态，确保了公司业务的正常运行。&lt;/p&gt;
&lt;h2&gt;二、为什么学&lt;/h2&gt;
&lt;p&gt;学习 MySQL 备份与恢复意义重大。在实际工作里，数据是企业的核心资产，一旦数据库因系统故障、人为误操作、硬件损坏、黑客攻击等原因出现数据丢失或损坏，将给企业带来巨大损失。掌握 MySQL 备份与恢复技术，能在数据丢失时及时恢复，保障业务连续性。同时，在对数据库进行升级、迁移或维护时，提前备份可防止数据意外丢失。此外，学习此技术也是数据库管理员、运维工程师等相关岗位的基本要求，有助于提升个人职业技能，增强在职场上的竞争力。&lt;/p&gt;
&lt;h2&gt;三、mysqldump【mysql-当普】备份与恢复&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[mysql之备份与恢复]
        direction LR
        A[mysqldump&amp;lt;br/&amp;gt;备份与恢复] --&amp;gt; B[增量备份&amp;lt;br/&amp;gt;与恢复] --&amp;gt; C[差分备份&amp;lt;br/&amp;gt;与恢复]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class A highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;热备份，备份和恢复数据库服务必须是运行的&lt;/p&gt;
&lt;h3&gt;3.1 备份数据&lt;/h3&gt;
&lt;p&gt;mysqldump【mysql-当普】 主要是把数据导出成一个sql脚本
可以针对某一个表或多个表
也可以针对某一个或多个库&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参数&lt;/th&gt;
&lt;th&gt;命令示例&lt;/th&gt;
&lt;th&gt;备份范围&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;无参数&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mysqldump 库名 表名&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;单个数据库的&lt;strong&gt;表的内容&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;日常单个数据&lt;strong&gt;表&lt;/strong&gt;备份&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;无参数&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mysqldump 库名 表名 表名...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;数据库的多个&lt;strong&gt;表的内容&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;日常多个数据&lt;strong&gt;表&lt;/strong&gt;备份&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;无参数&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mysqldump 库名&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;单个数据库的&lt;strong&gt;内容&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;日常单个数据库备份&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mysqldump -B 库名&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;单个数据库的&lt;strong&gt;完整结构+内容&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;数据库迁移&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mysqldump -B 库名 库名...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;多个数据库的&lt;strong&gt;完整结构+内容&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;数据库迁移&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-A&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mysqldump -A&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;所有数据库&lt;/strong&gt;的完整结构+内容&lt;/td&gt;
&lt;td&gt;全服务器备份、灾难恢复&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;#备份1张表 
[root@mysql50 ~]# mysqldump【mysql-当普】 -uroot -pNSD123456...a  moershi salary【晒了瑞】 &amp;gt; /bakdir/moershi_salary【晒了瑞】.sql
#[root@mha ~]# mysqldump -uroot -p123 moershi salary &amp;gt; /root/moershi_salary.sql
#mysqldump【mysql-当普】: [Warning] Using a password on the command line interface can be insecure.

#备份多张表
[root@mysql50 ~]# mysqldump【mysql-当普】 -uroot -pNSD123456...a  moershi employees【ing普洛伊s】 departments【迪帕踢门特】 &amp;gt; /bakdir/moershi_employees【ing普洛伊s】_deparments.sql
#[root@mha ~]# mysqldump -uroot -p123 moershi employees departments &amp;gt; /root/moershi_employees_deparments.sql
#mysqldump【mysql-当普】: [Warning] Using a password on the command line interface can be insecure.

#备份1个库 
[root@mysql50 ~]# mysqldump【mysql-当普】 -uroot -pNSD123456...a  -B moershi &amp;gt; /bakdir/moershi.sql 
#[root@mha ~]# mysqldump -uroot -p123 -B moershi &amp;gt; /root/moershi.sql
#mysqldump【mysql-当普】: [Warning] Using a password on the command line interface can be insecure.

#备份多个库
[root@mysql50 ~]# mysqldump【mysql-当普】 -uroot -pNSD123456...a  -B studb db1 &amp;gt; /bakdir/studb_db1.sql 
#[root@mha ~]# mysqldump -uroot -p123 -B studb db1 &amp;gt; /root/studb_db1.sql
#mysqldump【mysql-当普】: [Warning] Using a password on the command line interface can be insecure.

#备份所有库 
[root@mysql50 ~]# mysqldump【mysql-当普】 -uroot -pNSD123456...a  -A  &amp;gt; /bakdir/allbak.sql 
#[root@mha ~]# mysqldump -uroot -p123 -A &amp;gt; /root/allbak.sql
#mysqldump【mysql-当普】: [Warning] Using a password on the command line interface can be insecure.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 恢复数据&lt;/h3&gt;
&lt;p&gt;分析：&lt;/p&gt;
&lt;p&gt;特点：
mysqldump【mysql-当普】 备份和恢复数据时会锁表，锁表期间无法对表做写访问
mysqldump【mysql-当普】适合备份数据量比较小的数据或在数据库服务器访问量少的时候备份。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# mysql -uroot -pNSD123456...a
-- [root@mha ~]# mysql -uroot -p123
-- 删除库
mysql&amp;gt; drop【卓-普】  database【得塔-贝斯】 moershi; 
-- mysql&amp;gt; drop database moershi;
-- Query OK, 6 rows affected (0.57 sec)
mysql&amp;gt; exit【诶西特】
Bye

-- 恢复数据
[root@mysql50 ~]# mysql -uroot -pNSD123456...a &amp;lt; /bakdir/moershi.sql
-- [root@mha ~]# mysql -uroot -p123 &amp;lt; /root/moershi.sql 
-- mysql: [Warning] Using a password on the command line interface can be insecure.

-- 登陆
[root@mysql50 ~]# mysql -uroot -pNSD123456...a 
-- [root@mha ~]# mysql -uroot -p123

-- 进库
mysql&amp;gt; use moershi; 
-- mysql&amp;gt; use moershi;

-- 看表
mysql&amp;gt; show【瘦】 tables【忒-部s】; 
-- mysql&amp;gt; show tables;
+------------------+
| Tables_in_moershi |
+------------------+
| departments      |
| employees        |
| salary           |
| stu4             |
| user             |
| wage_grade       |
+------------------+
6 rows in set (0.00 sec)

-- 删除表记录
mysql&amp;gt; delete【迪利特】 from【弗乱】 salary【晒了瑞】; 
Query OK, 8055 rows affected (0.11 sec)
mysql&amp;gt; exit【诶西特】
Bye

-- 使用备份文件恢复数据
[root@mysql50 ~]# mysql -uroot -pNSD123456...a  moershi &amp;lt; /bakdir/moershi_salary【晒了瑞】.sql 
-- mysql: [Warning] Using a password on the command line interface can be insecure.

-- 登陆服务
[root@mysql50 ~]# mysql -uroot -pNSD123456...a 
-- [root@mha ~]# mysql -uroot -p123

-- 查看行数
mysql&amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】 moershi.salary【晒了瑞】; 
-- mysql&amp;gt; select count(*) from moershi.salary;
+----------+
| count(*) |
+----------+
|     8055 |
+----------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、增量备份与恢复&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[mysql之备份与恢复]
        direction LR
        A[mysqldump&amp;lt;br/&amp;gt;备份与恢复] --&amp;gt; B[增量备份&amp;lt;br/&amp;gt;与恢复] --&amp;gt; C[差分备份&amp;lt;br/&amp;gt;与恢复]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class B highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.1 准备2台数据库服务器&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;mysql50&lt;/td&gt;
&lt;td&gt;192.168.90.50&lt;/td&gt;
&lt;td&gt;用于备份数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mysql51&lt;/td&gt;
&lt;td&gt;192.168.90.51&lt;/td&gt;
&lt;td&gt;用于恢复数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;mysql51机器的IP配置和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.51/24 autoconnect【奥特欧 坑聂特】 yes
#[root@mha ~]# nmcli connection modify eth0 ipv4.addresses 192.168.88.40/24 autoconnect yes

[root@localhost ~]# nmcli connection【肯耐申】 up【啊普】 ens160
#[root@mha ~]# nmcli connection up eth1

[root@mysql51 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql51
#[root@mha ~]# hostnamectl set-hostname mha
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;增量备份和差异备份优缺点&lt;/h3&gt;
&lt;p&gt;增量备份&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;定义：增量备份只备份自上一次备份（无论是完全备份、增量备份还是差异备份）以来发生变化的数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;工作原理：首先需要一个完整的备份（基础备份），然后每次增量备份都只备份相对于上一次备份后变化的数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;优点：备份速度快，占用空间小，因为每次只备份变化的数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;缺点：恢复数据时，需要先恢复完整备份，然后按照时间顺序依次恢复所有的增量备份，直到指定的时间点。恢复过程复杂且耗时，如果中间任何一个备份损坏，可能导致整个恢复链失效。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;适用场景：数据量大，备份窗口短，但对恢复时间要求不高的场景。&lt;/p&gt;
&lt;p&gt;当前的备份是基于上一次备份做增量的备份
一般第一次备份要完全备份
第一次：全量--&amp;gt;增加了a
第二次:  备份a---&amp;gt;增加了b
第三次:  备份b---&amp;gt;增加了c
第四次:  备份c---&amp;gt;增加了d&lt;/p&gt;
&lt;p&gt;增量备份做数据恢复
全量&amp;lt;---备份a
全量&amp;lt;---备份b
全量&amp;lt;---备份c
最终 全量(abc)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;差异备份&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;定义：差异备份备份自上一次完整备份以来所有发生变化的数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;工作原理：首先需要一个完整备份，然后每次差异备份都会备份自上次完整备份以来所有变化的数据。因此，第二次差异备份会包含第一次差异备份的内容，第三次会包含第一次和第二次的内容，以此类推。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;优点：恢复时只需要完整备份和最近一次的差异备份，恢复过程相对简单。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;缺点：随着时间推移，差异备份的大小会越来越大，因为每次都要备份自完整备份以来的所有变化。备份时间可能会逐渐增加。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;适用场景：数据量变化不大，且希望恢复过程相对简单的场景。&lt;/p&gt;
&lt;p&gt;当前的备份是基于第一次备份做增量的备份
一般第一次备份要完全备份
第一次：全量--&amp;gt;增加了a
第二次:  备份a---&amp;gt;增加了b
第三次:  备份ab---&amp;gt;增加了c
第四次:  备份abc---&amp;gt;增加了d
全量&amp;lt;--备份abc
最终 全量(abc)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对比总结：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;备份内容：增量备份只备份上一次备份后的变化，而差异备份备份自上次完整备份后的所有变化。&lt;/li&gt;
&lt;li&gt;备份空间和速度：增量备份占用空间小，速度快；差异备份随着时间推移，占用空间和备份时间都会增加。&lt;/li&gt;
&lt;li&gt;恢复过程：增量恢复需要完整备份和所有增量备份，步骤多，易出错；差异恢复只需要完整备份和最近一次差异备份，相对简单。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;PERCONA【帕扣娜】 xtrabackup【xtra-拜克阿普】是一款强大的在线热备份工具，备份过程中不锁库表，适合生产环境。支持完全备份与恢复、增量备份与恢复、差异备份与恢复。&lt;/p&gt;
&lt;p&gt;在192.168.90.50主机完成备份与恢复的练习 。&lt;/p&gt;
&lt;h3&gt;4.2 数据增量备份&lt;/h3&gt;
&lt;p&gt;安装软件（在mysql50 、MySQL51 两台主机都要安装）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#一、使用YUM下载方式，下载RPM包：
[root@mysql50 ~]# yum -y install【因-斯多】 https://repo.percona.com/yum/percona-release-latest.noarch.rpm
#[root@mha ~]# yum -y install https://repo.percona.com/yum/percona-release-latest.noarch.rpm

#二、启用percona【帕扣娜】库：
[root@mysql50 ~]# percona【帕扣娜】-release【率利斯】 enable【ing 内 步】-only【欧利】 tools【兔斯】 release【率利斯】
#[root@mha ~]# percona-release enable-only tools release

#三、依赖包下载
[root@mysql50 ~]#  yum -y install【因-斯多】 lz4 zstd
#[root@mha ~]# yum -y install lz4 zstd

#四、安装percona【帕扣娜】-xtrabackup【xtra-拜克阿普】
[root@mysql50 ~]#  yum -y install【因-斯多】 percona【帕扣娜】-xtrabackup【xtra-拜克阿普】-80
#[root@mha ~]# yum -y install percona-xtrabackup-80
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;增量备份（在mysql50主机 完成增量备份练习）&lt;/p&gt;
&lt;p&gt;--host：备份的主机IP&lt;/p&gt;
&lt;p&gt;--user:  数据库的用户&lt;/p&gt;
&lt;p&gt;--password【帕斯沃德】: 数据库的密码&lt;/p&gt;
&lt;p&gt;--backup【拜克阿普】:启动备份过程，是最基本的备份启动选项&lt;/p&gt;
&lt;p&gt;--target【塔géi特】-dir【迪尔】: 指定备份文件的存储目录&lt;/p&gt;
&lt;p&gt;--datadir【得塔-迪尔】: 数据库文件目录&lt;/p&gt;
&lt;p&gt;--incremental【因葵孟透】-basedir【贝斯迪尔】：指定增量备份的基础目录，即上一次备份的目录&lt;/p&gt;
&lt;p&gt;周一完全备份（备份所有数据）&lt;/p&gt;
&lt;p&gt;对数据做增量备份前，必须先有一次备份，也就是首次备份，通常是备份所有数据；比如每周周一完全备份，周二到周日增量备份。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#全量备份
[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】 --datadir【得塔-迪尔】=/var/lib/mysql
#[root@mha ~]# xtrabackup --host=127.0.0.1 --user=root --password=123 --backup --target-dir=/fullbak --datadir=/var/lib/mysql
……
230530 18:18:48 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24822878) to (24822898) was copied.
230530 18:18:50 completed OK!

#插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250610&quot;,18,25000,8000);
#mysql&amp;gt; insert into moershi.salary(date,employee_id,basic,bonus) values(&quot;20250610&quot;,18,25000,8000);
#Query OK, 1 row affected (0.05 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周二增量备份（备份周一备份后新产生的数据）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/new2 --incremental【因葵孟透】-basedir【贝斯迪尔】=/fullbak【fò-拜克】  --datadir【得塔-迪尔】=/var/lib/mysql
#[root@mha ~]# xtrabackup --host=127.0.0.1 --user=root --password=123 --backup --target-dir=/new2 --incremental-basedir=/fullbak --datadir=/var/lib/mysql
……
……
230530 18:33:52 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24827173) to (24827183) was copied.
230530 18:33:53 completed OK!

#插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250710&quot;,18,25000,8000);
#mysql&amp;gt; insert into moershi.salary(date,employee_id,basic,bonus) values(&quot;20250710&quot;,18,25000,8000);
#Query OK, 1 row affected (0.11 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周三增量备份（备份周二备份后新产生的数据）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/new3 --incremental【因葵孟透】-basedir【贝斯迪尔】=/new2  --datadir【得塔-迪尔】=/var/lib/mysql
#[root@mha ~]# xtrabackup --host=127.0.0.1 --user=root --password=123 --backup --target-dir=/new3 --incremental-basedir=/fullbak --datadir=/var/lib/mysql
……
……
230530 18:46:17 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24832526) to (24832536) was copied.
230530 18:46:18 completed OK!

#插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250710&quot;,18,25000,8000);
#mysql&amp;gt; insert into moershi.salary(date,employee_id,basic,bonus) values(&quot;20250710&quot;,18,25000,8000);
#Query OK, 1 row affected (0.08 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周四增量备份（备份周三备份后新产生的数据）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/new4 --incremental【因葵孟透】-basedir【贝斯迪尔】=/new3  --datadir【得塔-迪尔】=/var/lib/mysql
#[root@mha ~]# xtrabackup --host=127.0.0.1 --user=root --password=123 --backup --target-dir=/new4 --incremental-basedir=/fullbak --datadir=/var/lib/mysql
……
……
230530 18:53:41 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24837561) to (24837571) was copied.
230530 18:53:42 completed OK!

#插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250710&quot;,18,25000,8000);
#mysql&amp;gt; insert into moershi.salary(date,employee_id,basic,bonus) values(&quot;20250710&quot;,18,25000,8000);
#Query OK, 1 row affected (0.05 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周五增量备份（备份周四备份后新产生的数据）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/new5 --incremental【因葵孟透】-basedir【贝斯迪尔】=/new4  --datadir【得塔-迪尔】=/var/lib/mysql
#[root@mha ~]# xtrabackup --host=127.0.0.1 --user=root --password=123 --backup --target-dir=/new5 --incremental-basedir=/fullbak --datadir=/var/lib/mysql
……
……
230530 18:58:50 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24841645) to (24841655) was copied.
230530 18:58:51 completed OK!

#插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250710&quot;,18,25000,8000);
#mysql&amp;gt; insert into moershi.salary(date,employee_id,basic,bonus) values(&quot;20250710&quot;,18,25000,8000);
#Query OK, 1 row affected (0.04 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周六增量备份（备份周五备份后新产生的数据）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/new6 --incremental【因葵孟透】-basedir【贝斯迪尔】=/new5  --datadir【得塔-迪尔】=/var/lib/mysql
#[root@mha ~]# xtrabackup --host=127.0.0.1 --user=root --password=123 --backup --target-dir=/new6 --incremental-basedir=/fullbak --datadir=/var/lib/mysql
……
……
230530 19:00:55 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24848404) to (24848414) was copied.
230530 19:00:56 completed OK!

#插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250710&quot;,18,25000,8000);
#mysql&amp;gt; insert into moershi.salary(date,employee_id,basic,bonus) values(&quot;20250710&quot;,18,25000,8000);
#Query OK, 1 row affected (0.06 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周日增量备份（备份周六备份后新产生的数据）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/new7 --incremental【因葵孟透】-basedir【贝斯迪尔】=/new6  --datadir【得塔-迪尔】=/var/lib/mysql
#[root@mha ~]# xtrabackup --host=127.0.0.1 --user=root --password=123 --backup --target-dir=/new7 --incremental-basedir=/fullbak --datadir=/var/lib/mysql
……
……
230530 19:00:55 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24848404) to (24848414) was copied.
230530 19:00:56 completed OK!
[root@mysql50 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.3 数据增量恢复&lt;/h3&gt;
&lt;p&gt;增量恢复数据步骤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;准备恢复数据&lt;/li&gt;
&lt;li&gt;合并数据&lt;/li&gt;
&lt;li&gt;清空数据库目录&lt;/li&gt;
&lt;li&gt;拷贝数据&lt;/li&gt;
&lt;li&gt;修改数据库目录所有者/组用户为mysql&lt;/li&gt;
&lt;li&gt;重启数据库服务&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;具体操作如下：&lt;/p&gt;
&lt;p&gt;MySQL51 拷贝 MySQL50 的备份文件到 本机的根目录下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# scp –r  root@192.168.90.50:/fullbak【fò-拜克】  /
[root@mysql51 ~]# scp –r  root@192.168.90.50:/new2  /
[root@mysql51 ~]# scp –r  root@192.168.90.50:/new3  /
[root@mysql51 ~]# scp –r  root@192.168.90.50:/new4  /
[root@mysql51 ~]# scp –r  root@192.168.90.50:/new5  /
[root@mysql51 ~]# scp –r  root@192.168.90.50:/new6  /
[root@mysql51 ~]# scp –r  root@192.168.90.50:/new7  /
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在MySQL51主机使用备份文件恢复数据&lt;/p&gt;
&lt;p&gt;--prepare【普瑞-撇尔】：对备份数据进行预处理，回滚未提交的事务并同步已提交的事务至数据文件，使数据文件处于一致性状态，以便用于恢复&lt;/p&gt;
&lt;p&gt;--apply-log-only【欧利】：在准备备份时使用，表示只应用重做日志（redo log），不回滚未提交的事务，常用于增量备份准备&lt;/p&gt;
&lt;p&gt;--target【塔géi特】-dir【迪尔】：指定备份文件的存储目录&lt;/p&gt;
&lt;p&gt;--incremental【因葵孟透】-dir【迪尔】：指定增量备份的存储目录&lt;/p&gt;
&lt;p&gt;1)、准备恢复数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --apply-log-only【欧利】 --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】
……
……
Log background threads are being closed...
Shutdown completed; log sequence number 24822898
Number of pools: 1
250630 14:32:14 completed OK!
[root@mysql51 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）、合并数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//将周二的增量数据拷贝到周一备份目录里，合并后周一的目录里存放的是周一 + 周二 的数据
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --apply-log-only【欧利】 --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】 --incremental【因葵孟透】-dir【迪尔】=/new2
……
……
250630 14:40:05 [00] Copying /new2/binlog.index to ./binlog.index
250630 14:40:05 [00]        ...done
250630 14:40:05 completed OK!
[root@mysql51 ~]#
//将周三的增量数据拷贝到周一备份目录里，合并后周一的目录里存放的是周一 + 周二 + 周三 的数据
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --apply-log-only【欧利】 --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】 --incremental【因葵孟透】-dir【迪尔】=/new3
……
……
250630 15:00:37 [00] Copying /new3/binlog.index to ./binlog.index
250630 15:00:37 [00]        ...done
250630 15:00:37 completed OK!
[root@mysql51 ~]#
//将周四的增量数据拷贝到周一备份目录里，合并后周一的目录里存放的是周一 + 周二 + 周三 +周四的数据
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --apply-log-only【欧利】 --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】 --incremental【因葵孟透】-dir【迪尔】=/new4
……
……
250630 15:00:37 [00] Copying /new4/binlog.index to ./binlog.index
250630 15:00:37 [00]        ...done
250630 15:00:37 completed OK!
[root@mysql51 ~]#
//将周五的增量数据拷贝到周一备份目录里，合并后周一的目录里存放的是周一 + 周二 + 周三 +周四+周五的数据
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --apply-log-only【欧利】 --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】 --incremental【因葵孟透】-dir【迪尔】=/new5
……
……
250630 15:00:37 [00] Copying /new5/binlog.index to ./binlog.index
250630 15:00:37 [00]        ...done
250630 15:00:37 completed OK!
[root@mysql51 ~]#
//将周六的增量数据拷贝到周一备份目录里，合并后周一的目录里存放的是周一 + 周二 + 周三 +周四+周五+周六的数据
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --apply-log-only【欧利】 --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】 --incremental【因葵孟透】-dir【迪尔】=/new6
……
……
250630 15:00:37 [00] Copying /new6/binlog.index to ./binlog.index
250630 15:00:37 [00]        ...done
250630 15:00:37 completed OK!
[root@mysql51 ~]#
//将周日的增量数据拷贝到周一备份目录里，合并后周一的目录里存放的是周一 + 周二 + 周三 +周四+周五+周六+周日的数据
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --apply-log-only【欧利】 --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】 --incremental【因葵孟透】-dir【迪尔】=/new7
……
……
250630 15:00:37 [00] Copying /new7/binlog.index to ./binlog.index
250630 15:00:37 [00]        ...done
250630 15:00:37 completed OK!
[root@mysql51 ~]#

[root@mysql51 ~]# rm -rf /var/lib/mysql/*
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --copy-back --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】
[root@mysql51 ~]# chown -R mysql:mysql /var/lib/mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;6）重启数据库服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# systemctl  restart  mysqld
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;7）连接服务查看数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# mysql -uroot -pNSD123456...a
mysql&amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】 moershi.salary【晒了瑞】 where date=20250710;
+----------+
| count(*) |
+----------+
|       75 |
+----------+
1 row in set (0.01 sec)
mysql&amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】 moershi.salary【晒了瑞】 where not  date=20250710;
+----------+
| count(*) |
+----------+
|     8067 |
+----------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、差异备份与恢复&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[mysql之备份与恢复]
        direction LR
        A[mysqldump&amp;lt;br/&amp;gt;备份与恢复] --&amp;gt; B[增量备份&amp;lt;br/&amp;gt;与恢复] --&amp;gt; C[差分备份&amp;lt;br/&amp;gt;与恢复]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class C highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;差异备份：备份完全备份后，新产生的数据。&lt;/p&gt;
&lt;p&gt;PERCONA【帕扣娜】 xtrabackup【xtra-拜克阿普】是一款强大的在线热备份工具，备份过程中不锁库表，适合生产环境。支持差异备份与恢复。&lt;/p&gt;
&lt;p&gt;在192.168.90.50主机完成差异备份&lt;/p&gt;
&lt;h3&gt;5.1 差异备份&lt;/h3&gt;
&lt;p&gt;差异备份&lt;/p&gt;
&lt;p&gt;对数据做差异备份前，必须先有一次备份，也就是首次备份，通常是备份所有数据；比如每周周一完全备份，周二到周日差异备份。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//周一完全备份
[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/allbak --datadir【得塔-迪尔】=/var/lib/mysql
……
……
260630 17:10:02 [00] Writing /allbak/xtrabackup【xtra-拜克阿普】_info
260630 17:10:02 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24881353) to (24881373) was copied.
260630 17:10:03 completed OK!
[root@mysql50 ~]# 
//插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 tarena.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250810&quot;,18,25000,8000);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周二差异备份，备份周一备份后新产生的数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/dir2 --incremental【因葵孟透】-basedir【贝斯迪尔】=/allbak --datadir【得塔-迪尔】=/var/lib/mysql
……
……
260630 17:23:56 [00] Writing /dir2/xtrabackup【xtra-拜克阿普】_info
260630 17:23:56 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24886741) to (24886751) was copied.
260630 17:23:58 completed OK!
[root@mysql50 ~]# 
//插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 tarena.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250810&quot;,18,25000,8000);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周三差异备份，备份周一备份后新产生的数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/dir3 --incremental【因葵孟透】-basedir【贝斯迪尔】=/allbak  --datadir【得塔-迪尔】=/var/lib/mysql
……
……
260630 17:27:10 [00] Writing /dir3/xtrabackup【xtra-拜克阿普】_info
260630 17:27:10 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24892043) to (24892063) was copied.
260630 17:27:11 completed OK!
[root@mysql50 ~]# 
//插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 tarena.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250810&quot;,18,25000,8000);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周四差异备份，备份周一备份后新产生的数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/dir4 --incremental【因葵孟透】-basedir【贝斯迪尔】=/allbak  --datadir【得塔-迪尔】=/var/lib/mysql
……
……
230531 17:31:00 [00] Writing /dir4/xtrabackup【xtra-拜克阿普】_info
230531 17:31:00 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24900560) to (24900580) was copied.
230531 17:31:01 completed OK!
[root@mysql50 ~]# 
//插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 tarena.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250810&quot;,18,25000,8000);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周五差异备份，备份周一备份后新产生的数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/dir5 --incremental【因葵孟透】-basedir【贝斯迪尔】=/allbak  --datadir【得塔-迪尔】=/var/lib/mysql
……
……
230531 17:32:38 [00] Writing /dir5/xtrabackup【xtra-拜克阿普】_info
230531 17:32:38 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24906902) to (24906912) was copied.
230531 17:32:39 completed OK!
[root@mysql50 ~]# 
//插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 tarena.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250810&quot;,18,25000,8000);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周六差异备份，备份周一备份后新产生的数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/dir6 --incremental【因葵孟透】-basedir【贝斯迪尔】=/allbak  --datadir【得塔-迪尔】=/var/lib/mysql
……
……
230531 17:41:01 [00] Writing /dir6/xtrabackup【xtra-拜克阿普】_info
230531 17:41:01 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24914729) to (24914739) was copied.
230531 17:41:02 completed OK!

[root@mysql50 ~]#
-- 插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 tarena.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250810&quot;,18,25000,8000);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周日差异，备份备份周一备份后新产生的数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/dir7 --incremental【因葵孟透】-basedir【贝斯迪尔】=/allbak  --datadir【得塔-迪尔】=/var/lib/mysql
……
……
230531 17:43:16 [00] Writing /dir7/xtrabackup【xtra-拜克阿普】_info
230531 17:43:16 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24920772) to (24920782) was copied.
230531 17:43:17 completed OK!
[root@mysql50 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 差异恢复&lt;/h3&gt;
&lt;p&gt;差异恢复数据步骤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;准备恢复数据&lt;/li&gt;
&lt;li&gt;合并数据&lt;/li&gt;
&lt;li&gt;清空数据库目录&lt;/li&gt;
&lt;li&gt;拷贝数据&lt;/li&gt;
&lt;li&gt;修改数据库目录所有者/组用户为mysql&lt;/li&gt;
&lt;li&gt;重启数据库服务&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;具体操作如下：&lt;/p&gt;
&lt;p&gt;MySQL51 拷贝 MySQL50 的备份文件到 本机的根目录下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# scp –r  root@192.168.90.50:/allbak  /
[root@mysql51 ~]# scp –r  root@192.168.90.50:/dir7  /
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在MySQL51主机使用备份文件恢复数据&lt;/p&gt;
&lt;p&gt;1)、准备恢复数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --apply-log-only【欧利】 --target【塔géi特】-dir【迪尔】=/allbak
……
……
Log background threads are being closed...
Shutdown completed; log sequence number 24881373
Number of pools: 1
230531 17:59:06 completed OK!
[root@mysql51 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）、合并数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//将周日的差异备份与周一的完全备份合并，因为周日的差异备份包扩周二+周日的所有数据
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --apply-log-only【欧利】 --target【塔géi特】-dir【迪尔】=/allbak --incremental【因葵孟透】-dir【迪尔】=/dir7
……
……
230531 18:05:08 [00] Copying /dir7/binlog.000029 to ./binlog.000029
230531 18:05:08 [00]        ...done
230531 18:05:08 [00] Copying /dir7/binlog.index to ./binlog.index
230531 18:05:08 [00]        ...done
230531 18:05:08 completed OK!

[root@mysql51 ~]#
[root@mysql51 ~]# rm -rf /var/lib/mysql/*
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --target【塔géi特】-dir【迪尔】=/allbak
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --copy-back --target【塔géi特】-dir【迪尔】=/allbak
[root@mysql51 ~]# chown -R mysql:mysql /var/lib/mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3）重启数据库服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# systemctl  restart  mysqld
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4）连接服务查看数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# mysql -uroot -pNSD123456...a
mysql&amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】 tarena.salary【晒了瑞】 where date=20250810;
+----------+
| count(*) |
+----------+
|       75 |
+----------+
1 row in set (0.01 sec)

mysql&amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】 tarena.salary【晒了瑞】 where not  date=20250810;
+----------+
| count(*) |
+----------+
|     8067 |
+----------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;全量备份&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;	### 全量备份步骤
	以下是使用 `xtrabackup` 进行全量备份的命令：
	[root@mha ~]# xtrabackup --backup --target-dir=/path/to/backup
	
	#- `--backup`：表示执行备份操作。
	#- `--target-dir`：指定备份文件的存储目录。
	备份完成后，需要对备份进行准备，以确保备份数据处于一致状态：
	
	[root@mha ~]# xtrabackup --prepare --target-dir=/path/to/backup
	
	#- `--prepare`：对备份数据进行准备，应用事务日志。
	
	### 恢复步骤
	#### 1. 停止 MySQL 服务
	在恢复备份之前，需要停止正在运行的 MySQL 服务，以避免数据冲突。
	[root@mha ~]# sudo systemctl stop mysql
	
	#### 2. 清空 MySQL 数据目录
	为了确保恢复的数据是完整的，需要清空 MySQL 数据目录中的现有数据。
	[root@mha ~]# sudo rm -rf /var/lib/mysql/*
	
	#### 3. 恢复备份数据
	将备份数据复制到 MySQL 数据目录。
	[root@mha ~]# sudo xtrabackup --copy-back --target-dir=/path/to/backup
	
	#- `--copy-back`：将备份数据复制回 MySQL 数据目录。
	
	#### 4. 修改文件权限
	恢复数据后，需要确保 MySQL 数据目录及其文件的权限正确。
	[root@mha ~]# sudo chown -R mysql:mysql /var/lib/mysql
	
	#### 5. 启动 MySQL 服务
	完成上述步骤后，可以启动 MySQL 服务。
	[root@mha ~]# sudo systemctl start mysql
	
	#### 6. 验证恢复结果
	可以登录 MySQL 并检查数据库和表是否已成功恢复。
	[root@mha ~]# mysql -u root -p
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;增量备份恢复&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;	#准备恢复数据。使用 `--apply-log-only`只应用重做日志，不回滚为后续增量备份应用做准备。因为在增量备份中，基础备份必须保持事务状态，以便后续的增量备份能够正确应用。如果提前回滚了未提交事务，那么增量备份应用时可能会丢失一些事务信息。
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak
	#合并增量数据，需要把所有的增量备份数据全部合并，不然会造成数据缺失
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak --incremental-dir=/new1
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak --incremental-dir=/new2
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak --incremental-dir=/new3
	# 停止 MySQL 服务。在恢复备份之前，需要停止正在运行的 MySQL 服务，以避免数据冲突。
	[root@mha ~]# sudo systemctl stop mysql
	# 清空 MySQL 数据目录。为了确保恢复的数据是完整的，需要清空 MySQL 数据目录中的现有数据。
	[root@mha ~]# sudo rm -rf /var/lib/mysql/*
	# 最终准备预处理备份数据。应用重做日志（redo log）到数据文件，将数据文件前滚到备份结束时的状态，使备份数据处于一致状态，可以用于恢复。
	[root@mha ~]# sudo xtrabackup --prepare --target-dir=/fullbak
	# 恢复备份数据。将备份数据复制到 MySQL 数据目录。
	[root@mha ~]# sudo xtrabackup --copy-back --target-dir=/fullbak
	# 修改文件权限。恢复数据后，需要确保 MySQL 数据目录及其文件的权限正确。
	[root@mha ~]# sudo chown -R mysql:mysql /var/lib/mysql
	# 启动 MySQL 服务。完成上述步骤后，可以启动 MySQL 服务。
	[root@mha ~]# sudo systemctl start mysql
	# 验证恢复结果。可以登录 MySQL 并检查数据库和表是否已成功恢复。
	[root@mha ~]# mysql -u root -p
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;差异备份恢复&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;	# 差异备份恢复步骤：
	
	# 1. 准备基础全量备份（使用 --apply-log-only 保持事务状态）
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak
	# 原因：基础备份必须保持事务状态，以便后续的差异备份能够正确应用。
	#       如果提前回滚了未提交事务，差异备份应用时可能会丢失事务信息。
	
	# 2. 应用最后一次差异备份（直接完整准备，不使用 --apply-log-only）
	[root@mha ~]# sudo xtrabackup --prepare --target-dir=/fullbak --incremental-dir=/diff_backup
	# 原因：差异备份基于同一个全量备份，这是最后一个备份步骤，需要完成事务回滚，使数据达到一致状态。
	#       不需要使用 --apply-log-only，因为后面没有更多的备份要应用。
	
	# 3. 停止 MySQL 服务
	[root@mha ~]# sudo systemctl stop mysql
	# 原因：在恢复备份之前，需要停止正在运行的 MySQL 服务，以避免数据冲突。
	
	# 4. 备份并清空 MySQL 数据目录
	[root@mha ~]# sudo mv /var/lib/mysql /var/lib/mysql_backup_$(date +%Y%m%d)
	[root@mha ~]# sudo mkdir /var/lib/mysql
	# 原因：为了确保恢复的数据是完整的，需要清空 MySQL 数据目录中的现有数据。
	
	# 5. 恢复备份数据到 MySQL 数据目录
	[root@mha ~]# sudo xtrabackup --copy-back --target-dir=/fullbak
	# 原因：将已准备好的备份数据复制到 MySQL 数据目录。
	
	# 6. 修改文件权限
	[root@mha ~]# sudo chown -R mysql:mysql /var/lib/mysql
	# 原因：恢复数据后，需要确保 MySQL 数据目录及其文件的权限正确。
	
	# 7. 启动 MySQL 服务
	[root@mha ~]# sudo systemctl start mysql
	# 原因：完成上述步骤后，可以启动 MySQL 服务。
	
	# 8. 验证恢复结果
	[root@mha ~]# mysql -u root -p -e &quot;SHOW DATABASES;&quot;
	# 原因：验证数据库和表是否已成功恢复。
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;备份完整性验证&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;	# 1. 准备备份
	# 在验证之前，需要对备份进行准备操作，以应用事务日志，使备份数据处于一致状态。此步骤适用于全量备份和差异备份。
	
	[root@mha ~]# xtrabackup --prepare --target-dir=/path/to/backup
	# - `--prepare`：该参数用于对备份数据进行准备操作。
	# - `--target-dir`：指定备份文件所在的目录。
	
	#  2. 检查备份元数据文件
	# 备份完成后，XtraBackup 会生成一个名为 `xtrabackup_info` 的元数据文件，该文件包含了备份的相关信息，如备份类型、开始时间、结束时间等。你可以查看这个文件来初步验证备份的基本信息是否正确。
	
	[root@mha ~]# cat /path/to/backup/xtrabackup_info
	# 查看输出内容，确认备份类型为差异备份（`incremental`），并且各项时间信息和其他元数据是否合理。
	
	# 3. 检查备份文件的完整性
	# 可以使用 `xtrabackup --stats` 命令来检查备份文件中的数据页和事务日志的完整性。
	
	[root@mha ~]# xtrabackup --stats --target-dir=/path/to/backup
	
	# - `--stats`：该参数用于显示备份文件的统计信息。
	# - `--target-dir`：指定备份文件所在的目录。
	# 如果备份文件完整，命令执行后会输出详细的统计信息，包括数据页的数量、事务日志的大小等。如果备份文件存在损坏，该命令可能会报错。
	
	# 4. 模拟恢复操作
	# 模拟恢复操作是验证备份完整性的最可靠方法。虽然不会真正覆盖现有的 MySQL 数据目录，但可以检查备份数据是否能够正确恢复。
	
	# 停止 MySQL 服务（如果正在运行）
	[root@mha ~]# sudo systemctl stop mysql
	
	# 创建一个临时目录用于模拟恢复
	[root@mha ~]# mkdir /tmp/restore-test
	
	# 执行模拟恢复操作
	[root@mha ~]# xtrabackup --copy-back --target-dir=/path/to/backup --datadir=/tmp/restore-test
	# - `--copy-back`：将备份数据复制到指定的数据目录。
	# - `--target-dir`：指定备份文件所在的目录。
	# - `--datadir`：指定模拟恢复的数据目录。
	# 如果模拟恢复过程中没有报错，说明备份文件可以正常恢复，完整性得到验证。恢复完成后，你可以查看临时目录中的文件是否与预期一致。
	
	# 5. 清理临时目录
	# 模拟恢复验证完成后，清理临时目录。
	[root@mha ~]# rm -rf /tmp/restore-test
	
	# 6. 启动 MySQL 服务
	# 如果之前停止了 MySQL 服务，现在可以启动它。
	[root@mha ~]# sudo systemctl start mysql
	
	# 通过以上步骤，你可以全面验证 Percona XtraBackup 差异备份文件的完整性，确保在需要恢复数据时能够顺利进行。 
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;备份方案案例&lt;/h2&gt;
&lt;p&gt;以下是一个完整的 MySQL 备份与恢复方案，包含使用 &lt;code&gt;mysqldump&lt;/code&gt; 进行定期全量备份、&lt;code&gt;Percona XtraBackup&lt;/code&gt; 进行日常增量和差异备份，以及在数据丢失时的恢复方法。&lt;/p&gt;
&lt;h3&gt;1. 环境准备&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;安装 &lt;code&gt;mysqldump&lt;/code&gt;&lt;/strong&gt;：&lt;code&gt;mysqldump&lt;/code&gt; 是 MySQL 自带的备份工具，通常在安装 MySQL 时会一并安装。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安装 &lt;code&gt;Percona XtraBackup&lt;/code&gt;&lt;/strong&gt;：根据你的操作系统，按照 Percona 官方文档进行安装。例如，在 Ubuntu 上可以使用以下命令：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb
sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb
sudo apt-get update
sudo apt-get install percona-xtrabackup-80
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 备份方案&lt;/h3&gt;
&lt;h4&gt;2.1 使用 &lt;code&gt;mysqldump&lt;/code&gt; 进行定期全量备份&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;mysqldump&lt;/code&gt; 适合进行全量备份，特别是对于较小的数据库。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;脚本示例（&lt;code&gt;full_backup.sh&lt;/code&gt;）&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash

# 数据库连接信息
DB_USER=&quot;your_username&quot;
DB_PASSWORD=&quot;your_password&quot;
DB_NAME=&quot;your_database_name&quot;
BACKUP_DIR=&quot;/path/to/backup&quot;

# 创建备份目录
mkdir -p $BACKUP_DIR

# 生成备份文件名
BACKUP_FILE=&quot;$BACKUP_DIR/$(date +%Y%m%d)_full_backup.sql&quot;

# 执行全量备份
mysqldump -u$DB_USER -p$DB_PASSWORD $DB_NAME &amp;gt; $BACKUP_FILE

# 检查备份是否成功
if [ $? -eq 0 ]; then
    echo &quot;Full backup completed successfully.&quot;
else
    echo &quot;Full backup failed.&quot;
fi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;定时任务&lt;/strong&gt;：使用 &lt;code&gt;crontab&lt;/code&gt; 每周执行一次全量备份。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 2 * * 0 /path/to/full_backup.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2.2 使用 &lt;code&gt;Percona XtraBackup&lt;/code&gt; 进行日常增量和差异备份&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;全量备份脚本（&lt;code&gt;full_xtrabackup.sh&lt;/code&gt;）&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash

# 数据库连接信息
DB_USER=&quot;your_username&quot;
DB_PASSWORD=&quot;your_password&quot;
BACKUP_DIR=&quot;/path/to/backup/xtrabackup&quot;

# 创建备份目录
mkdir -p $BACKUP_DIR

# 生成备份文件名
FULL_BACKUP_DIR=&quot;$BACKUP_DIR/$(date +%Y%m%d)_full&quot;
mkdir -p $FULL_BACKUP_DIR

# 执行全量备份
xtrabackup --user=$DB_USER --password=$DB_PASSWORD --backup --target-dir=$FULL_BACKUP_DIR

# 检查备份是否成功
if [ $? -eq 0 ]; then
    echo &quot;Full XtraBackup completed successfully.&quot;
else
    echo &quot;Full XtraBackup failed.&quot;
fi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;增量备份脚本（&lt;code&gt;incremental_backup.sh&lt;/code&gt;）&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash

# 数据库连接信息
DB_USER=&quot;your_username&quot;
DB_PASSWORD=&quot;your_password&quot;
BACKUP_DIR=&quot;/path/to/backup/xtrabackup&quot;

# 获取最新的全量备份目录
LAST_FULL_BACKUP=$(ls -d $BACKUP_DIR/*_full | tail -n 1)

# 生成增量备份目录
INCREMENTAL_BACKUP_DIR=&quot;$BACKUP_DIR/$(date +%Y%m%d)_incremental&quot;
mkdir -p $INCREMENTAL_BACKUP_DIR

# 执行增量备份
xtrabackup --user=$DB_USER --password=$DB_PASSWORD --backup --target-dir=$INCREMENTAL_BACKUP_DIR --incremental-basedir=$LAST_FULL_BACKUP

# 检查备份是否成功
if [ $? -eq 0 ]; then
    echo &quot;Incremental backup completed successfully.&quot;
else
    echo &quot;Incremental backup failed.&quot;
fi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;定时任务&lt;/strong&gt;：每周执行一次全量备份，每天执行一次增量备份。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 2 * * 0 /path/to/full_xtrabackup.sh
0 3 * * 1-6 /path/to/incremental_backup.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 恢复方案&lt;/h3&gt;
&lt;h4&gt;3.1 使用 &lt;code&gt;mysqldump&lt;/code&gt; 恢复数据&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql -u your_username -p your_password your_database_name &amp;lt; /path/to/backup/20240101_full_backup.sql
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3.2 使用 &lt;code&gt;Percona XtraBackup&lt;/code&gt; 恢复数据&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;步骤 1：准备全量备份&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;xtrabackup --prepare --target-dir=/path/to/backup/xtrabackup/20240101_full
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤 2：应用增量备份&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;xtrabackup --prepare --target-dir=/path/to/backup/xtrabackup/20240101_full --incremental-dir=/path/to/backup/xtrabackup/20240102_incremental
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤 3：停止 MySQL 服务&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl stop mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤 4：恢复备份数据&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo rm -rf /var/lib/mysql/*
sudo xtrabackup --copy-back --target-dir=/path/to/backup/xtrabackup/20240101_full
sudo chown -R mysql:mysql /var/lib/mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤 5：启动 MySQL 服务&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl start mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、作业&lt;/h2&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;以下哪种备份方式能在备份时不锁表，从而不影响 MySQL 数据库的正常读写操作？ B
A. mysqldump 全量备份
B. PERCONA Xtrabackup 全量备份
C. mysqldump 增量备份
D. 以上都不能&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用 PERCONA Xtrabackup 进行增量备份时，基于的基础备份是？A
A. 上一次的全量备份
B. 上一次的增量备份
C. 上一次的差异备份
D. 任意一次备份&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;当使用 mysqldump 备份数据库时，若要备份所有数据库，应使用以下哪个参数？ A
A. --all-databases
B. --database-all
C. --full-databases
D. --every-database&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PERCONA Xtrabackup 的差异备份恢复时，依赖于？A
A. 最新的全量备份和后续的差异备份
B. 最新的增量备份和后续的差异备份
C. 最早的全量备份和所有后续备份
D. 任意一次全量备份和差异备份&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;若要使用 PERCONA Xtrabackup 进行增量备份，需要记录上一次备份的什么信息？ C
A. 备份文件大小
B. 备份文件位置
C. 备份的 LSN（日志序列号）
D. 备份的时间戳&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;简述 mysqldump、PERCONA Xtrabackup 增量备份和差异备份的优缺点。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;	答：
	 mysqldump：
		 优点：灵活，可以针对单表或多表和单数据库或多数据进行备份还原
		 缺点：备份和恢复数据时会锁表，锁表期间无法对表做写访问。只适合备份数据量比较小的数据或在数据库服务器访问量少的时候备份。
		 
	 PERCONA Xtrabackup 增量备份：
		 优点：备份速度快，占用空间小，因为每次只备份变化的数据。
		 缺点：恢复数据时，需要先恢复完整备份，然后按照时间顺序依次恢复所有的增量备份，直到指定的时间点。恢复过程复杂且耗时，如果中间任何一个备份损坏，可能导致整个恢复链失效。
		 
	 PERCONA Xtrabackup 差异备份：
		 优点：恢复时只需要完整备份和最近一次的差异备份，恢复过程相对简单。
		 缺点：随着时间推移，差异备份的大小会越来越大，因为每次都要备份自完整备份以来的所有变化。备份时间可能会逐渐增加。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;阐述在什么业务场景下适合使用 PERCONA Xtrabackup 的增量备份，什么场景适合使用差异备份。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;	答：
	增量备份：
		 数据量大，备份窗口短，但对恢复时间要求不高的场景。
			
	差异备份：
		数据量变化不大，且希望恢复过程相对简单的场景。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;说明在进行 MySQL 数据库恢复时，全量备份、增量备份和差异备份的恢复顺序及原因。
答：
全量备份恢复步骤：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;	# 停止 MySQL 服务。在恢复备份之前，需要停止正在运行的 MySQL 服务，以避免数据冲突。
	[root@mha ~]# sudo systemctl stop mysql
	# 清空 MySQL 数据目录。为了确保恢复的数据是完整的，需要清空 MySQL 数据目录中的现有数据。
	[root@mha ~]# sudo rm -rf /var/lib/mysql/*
	# 预处理备份数据。应用重做日志（redo log）到数据文件，将数据文件前滚到备份结束时的状态，使备份数据处于一致状态，可以用于恢复。
	[root@mha ~]# sudo xtrabackup --prepare --target-dir=/path/to/backup
	# 恢复备份数据。将备份数据复制到 MySQL 数据目录。
	[root@mha ~]# sudo xtrabackup --copy-back --target-dir=/path/to/backup
	# 修改文件权限。恢复数据后，需要确保 MySQL 数据目录及其文件的权限正确。
	[root@mha ~]# sudo chown -R mysql:mysql /var/lib/mysql
	# 启动 MySQL 服务。完成上述步骤后，可以启动 MySQL 服务。
	[root@mha ~]# sudo systemctl start mysql
	# 验证恢复结果。可以登录 MySQL 并检查数据库和表是否已成功恢复。
	[root@mha ~]# mysql -u root -p
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;增量备份恢复步骤：
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;	#准备恢复数据。使用 `--apply-log-only`只应用重做日志，不回滚为后续增量备份应用做准备。因为在增量备份中，基础备份必须保持事务状态，以便后续的增量备份能够正确应用。如果提前回滚了未提交事务，那么增量备份应用时可能会丢失一些事务信息。
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak
	#合并增量数据，需要把所有的增量备份数据全部合并，不然会造成数据缺失
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak --incremental-dir=/new1
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak --incremental-dir=/new2
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak --incremental-dir=/new3
	# 停止 MySQL 服务。在恢复备份之前，需要停止正在运行的 MySQL 服务，以避免数据冲突。
	[root@mha ~]# sudo systemctl stop mysql
	# 清空 MySQL 数据目录。为了确保恢复的数据是完整的，需要清空 MySQL 数据目录中的现有数据。
	[root@mha ~]# sudo rm -rf /var/lib/mysql/*
	# 最终准备预处理备份数据。应用重做日志（redo log）到数据文件，将数据文件前滚到备份结束时的状态，使备份数据处于一致状态，可以用于恢复。
	[root@mha ~]# sudo xtrabackup --prepare --target-dir=/fullbak
	# 恢复备份数据。将备份数据复制到 MySQL 数据目录。
	[root@mha ~]# sudo xtrabackup --copy-back --target-dir=/fullbak
	# 修改文件权限。恢复数据后，需要确保 MySQL 数据目录及其文件的权限正确。
	[root@mha ~]# sudo chown -R mysql:mysql /var/lib/mysql
	# 启动 MySQL 服务。完成上述步骤后，可以启动 MySQL 服务。
	[root@mha ~]# sudo systemctl start mysql
	# 验证恢复结果。可以登录 MySQL 并检查数据库和表是否已成功恢复。
	[root@mha ~]# mysql -u root -p
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;差异备份恢复步骤：
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;	#准备恢复数据。使用 `--apply-log-only`只应用重做日志，不回滚为后续增量备份应用做准备。因为在增量备份中，基础备份必须保持事务状态，以便后续的增量备份能够正确应用。如果提前回滚了未提交事务，那么增量备份应用时可能会丢失一些事务信息。
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak
	#合并差异数据，只需要把全量数据和最后一次的差异数据合并，但暂不完成最终一致性
	[root@mha ~]# sudo xtrabackup --prepare --target-dir=/fullbak --incremental-dir=/dir7
	# 停止 MySQL 服务。在恢复备份之前，需要停止正在运行的 MySQL 服务，以避免数据冲突。
	[root@mha ~]# sudo systemctl stop mysql
	# 清空 MySQL 数据目录。为了确保恢复的数据是完整的，需要清空 MySQL 数据目录中的现有数据。
	[root@mha ~]# sudo rm -rf /var/lib/mysql/*
	# 最终准备预处理备份数据。应用重做日志（redo log）到数据文件，将数据文件前滚到备份结束时的状态，使备份数据处于一致状态，可以用于恢复。
	[root@mha ~]# sudo xtrabackup --prepare --target-dir=/fullbak
	# 恢复备份数据。将备份数据复制到 MySQL 数据目录。
	[root@mha ~]# sudo xtrabackup --copy-back --target-dir=/fullbak
	# 修改文件权限。恢复数据后，需要确保 MySQL 数据目录及其文件的权限正确。
	[root@mha ~]# sudo chown -R mysql:mysql /var/lib/mysql
	# 启动 MySQL 服务。完成上述步骤后，可以启动 MySQL 服务。
	[root@mha ~]# sudo systemctl start mysql
	# 验证恢复结果。可以登录 MySQL 并检查数据库和表是否已成功恢复。
	[root@mha ~]# mysql -u root -p
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;比较 mysqldump 和 PERCONA Xtrabackup 在备份和恢复过程中对数据库性能的影响。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;答：
	mysqldump：
		在备份和恢复数据时会通过锁表保证一致性，影响写操作，锁表期间无法对表做写访问
	PERCONA Xtrabackup：
		利用InnoDB的MVCC机制，实现热备份，几乎不影响业务
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3 操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;请写出使用 mysqldump 对指定一个数据库进行全量备份，并将备份文件存储到“/backup/sales_full_backup.sql”的完整命令。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;	[root@mha ~]# mysqldump -uroot -p123 -B moershi &amp;gt; /backup/sales_full_backup.sql
	mysqldump: [Warning] Using a password on the command line interface can be insecure.
	[root@mha ~]# ls /backup
	sales_full_backup.sql
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;假设已经有一个 PERCONA Xtrabackup 的全量备份，之后数据库有了新的数据更新，写出进行一次增量备份的操作步骤和相应命令。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;	[root@mha ~]# xtrabackup --host=127.0.0.1 --user=root --password=123 --backup --target-dir=/增量备份保存路径 --incremenntal-basedir=/全量备份保存路径 --datadir=/mysql数据路径
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;若数据库因磁盘故障丢失部分数据，现有一个全量备份和若干个 PERCONA Xtrabackup 的差异备份文件，请详细描述恢复数据库的操作过程和命令。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;	1.准备恢复数据,预处理只应用重做日志，不回滚为后续备份应用做准备。
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/全量备份数据
	
	2.合并差异数据，只需要把一个全量备份数据和最后一次的差异备份数据合并，但暂不完成最终一致性
	[root@mha ~]# sudo xtrabackup --prepare --target-dir=/全量备份数据 --incremental-dir=/差异备份数据
	
	3.停止 MySQL 服务。在恢复备份之前，需要停止正在运行的 MySQL 服务，以避免数据冲突。
	[root@mha ~]# sudo systemctl stop mysql
	
	4.清空 MySQL 数据目录。为了确保恢复的数据是完整的，需要清空 MySQL 数据目录中的现有数据。
	[root@mha ~]# sudo rm -rf /var/lib/mysql/*
	
	5.最终准备预处理备份数据。应用重做日志（redo log）到数据文件，将数据文件前滚到备份结束时的状态，使备份数据处于一致状态，可以用于恢复。
	[root@mha ~]# sudo xtrabackup --prepare --target-dir=/全量备份数据
	
	6.恢复备份数据。将备份数据复制到 MySQL 数据目录。
	[root@mha ~]# sudo xtrabackup --copy-back --target-dir=/全量备份数据
	
	7.修改文件权限。恢复数据后，需要确保 MySQL 数据目录及其文件的权限正确。
	[root@mha ~]# sudo chown -R mysql:mysql /var/lib/mysql
	
	8.启动 MySQL 服务。完成上述步骤后，可以启动 MySQL 服务。
	[root@mha ~]# sudo systemctl start mysql
	
	9.验证恢复结果。可以登录 MySQL 并检查数据库和表是否已成功恢复。
	[root@mha ~]# mysql -u root -p
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;使用 PERCONA Xtrabackup 进行差异备份时，如何验证备份文件的完整性？写出具体步骤和命令。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;	1. 准备备份
	在验证之前，需要对备份进行准备操作，以应用事务日志，使备份数据处于一致状态。

	[root@mha ~]# xtrabackup --prepare --target-dir=/path/to/backup

	
	2. 检查备份元数据文件
	备份完成后，XtraBackup 会生成一个名为 `xtrabackup_info` 的元数据文件，该文件包含了备份的相关信息，如备份类型、开始时间、结束时间等。可以查看这个文件来初步验证备份的基本信息是否正确。

	[root@mha ~]# cat /path/to/backup/xtrabackup_info

	查看输出内容，确认备份类型为差异备份（`incremental`），并且各项时间信息和其他元数据是否合理。
	
	3. 检查备份文件的完整性
	可以使用 `xtrabackup --stats` 命令来检查备份文件中的数据页和事务日志的完整性。

	[root@mha ~]# xtrabackup --stats --target-dir=/path/to/backup

	如果备份文件完整，命令执行后会输出详细的统计信息，包括数据页的数量、事务日志的大小等。如果备份文件存在损坏，该命令可能会报错。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;请设计一个完整的 MySQL 备份与恢复方案，包括使用 mysqldump 进行定期全量备份、PERCONA Xtrabackup 进行日常增量和差异备份，并描述在数据丢失时如何利用这些备份进行恢复。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;一。备份方案
1 使用 `crontab` 和 `mysqldump` 进行定期全量备份
0 2 * * 0 /bin/mysqldump -uroot -p123 -A &amp;gt; /backup/sql/all_$(date +%Y-%m-%d_%H-%M-%S).sql 

2 使用 `Percona XtraBackup` 进行日常增量和差异备份

全量备份脚本
#!/bin/bash

# 数据库连接信息
DB_USER=&quot;root&quot;
DB_PASSWORD=&quot;123&quot;
BACKUP_DIR=&quot;/fullbak&quot;

# 创建备份目录
mkdir -p $BACKUP_DIR

# 生成备份文件名
FULL_BACKUP_DIR=&quot;$BACKUP_DIR/$(date +%Y%m%d)_full&quot;
mkdir -p $FULL_BACKUP_DIR

# 执行全量备份
xtrabackup --host=127.0.0.1  --user=$DB_USER --password=$DB_PASSWORD --backup --target-dir=$FULL_BACKUP_DIR --datadir=/var/lib/mysql

# 检查备份是否成功
if [ $? -eq 0 ]; then
    echo &quot;Full XtraBackup completed successfully.&quot;
else
    echo &quot;Full XtraBackup failed.&quot;
fi


增量备份脚本
#!/bin/bash

# 数据库连接信息
DB_USER=&quot;root&quot;
DB_PASSWORD=&quot;123&quot;
BACKUP_DIR=&quot;/fullbak&quot;

# 获取最新的全量备份目录
LAST_FULL_BACKUP=$(ls -d $BACKUP_DIR/*_full | tail -n 1)

# 生成增量备份目录
INCREMENTAL_BACKUP_DIR=&quot;$BACKUP_DIR/$(date +%Y%m%d)_incremental&quot;
mkdir -p $INCREMENTAL_BACKUP_DIR

# 执行增量备份
xtrabackup --host=127.0.0.1 --user=$DB_USER --password=$DB_PASSWORD --backup --target-dir=$INCREMENTAL_BACKUP_DIR --incremental-basedir=$LAST_FULL_BACKUP --datadir=/var/lib/mysql

# 检查备份是否成功
if [ $? -eq 0 ]; then
    echo &quot;Incremental backup completed successfully.&quot;
else
    echo &quot;Incremental backup failed.&quot;
fi


定时任务：每周执行一次全量备份，每天执行一次增量备份。
0 2 * * 0 /全量备份脚本
0 3 * * 1-6 /增量备份脚本


二. 恢复方案

1 使用 `mysqldump` 恢复数据
	mysql -uroot -p123 -A &amp;lt; /backup/sql/all_指定恢复时间版本.sql 

2 使用 `Percona XtraBackup` 恢复数据

	#准备恢复数据。
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/全量备份路径
	#合并增量数据
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/全量备份路径 --incremental-dir=/增量备份路径1
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/全量备份路径 --incremental-dir=/增量备份路径2
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/全量备份路径 --incremental-dir=/增量备份路径3
	# 停止 MySQL 服务。
	[root@mha ~]# sudo systemctl stop mysql
	# 清空 MySQL 数据目录。
	[root@mha ~]# sudo rm -rf /var/lib/mysql/*
	# 最终准备预处理备份数据。
	[root@mha ~]# sudo xtrabackup --prepare --target-dir=/全量备份路径
	# 恢复备份数据。
	[root@mha ~]# sudo xtrabackup --copy-back --target-dir=/全量备份路径
	# 修改文件权限。
	[root@mha ~]# sudo chown -R mysql:mysql /var/lib/mysql
	# 启动 MySQL 服务。
	[root@mha ~]# sudo systemctl start mysql
	# 验证恢复结果。
	[root@mha ~]# mysql -u root -p
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;作业的详细检查&lt;/h1&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;第 1 题&lt;/strong&gt;：答案正确。&lt;code&gt;PERCONA Xtrabackup&lt;/code&gt; 全量备份利用 InnoDB 的 MVCC 机制实现热备份，备份时不锁表，不影响数据库正常读写操作；而 &lt;code&gt;mysqldump&lt;/code&gt; 备份时会锁表。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 2 题&lt;/strong&gt;：答案正确。&lt;code&gt;PERCONA Xtrabackup&lt;/code&gt; 进行增量备份时，基于上一次的全量备份。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 3 题&lt;/strong&gt;：答案正确。&lt;code&gt;--all - databases&lt;/code&gt; 是 &lt;code&gt;mysqldump&lt;/code&gt; 用于备份所有数据库的参数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 4 题&lt;/strong&gt;：答案正确。&lt;code&gt;PERCONA Xtrabackup&lt;/code&gt; 的差异备份恢复时，依赖于最新的全量备份和后续的差异备份。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 5 题&lt;/strong&gt;：答案错误。若要使用 &lt;code&gt;PERCONA Xtrabackup&lt;/code&gt; 进行增量备份，需要记录上一次备份的 LSN（日志序列号），而不是备份文件位置。所以正确答案选 C。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;第 1 题&lt;/strong&gt;：回答准确，清晰阐述了 &lt;code&gt;mysqldump&lt;/code&gt;、&lt;code&gt;PERCONA Xtrabackup&lt;/code&gt; 增量备份和差异备份的优缺点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 2 题&lt;/strong&gt;：回答合理，增量备份适合数据量大、备份窗口短且对恢复时间要求不高的场景；差异备份适合数据量变化不大且希望恢复过程相对简单的场景。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 3 题&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;回答内容整体正确，但存在一个小问题，在增量备份和差异备份准备恢复数据的注释中，提到“因为在增量备份中，基础备份必须保持事务状态，以便后续的增量备份能够正确应用”，这里应该是为了后续的增量或差异备份能够正确应用，表述不够严谨。&lt;/li&gt;
&lt;li&gt;另外，在代码中路径使用 &lt;code&gt;/fullbak&lt;/code&gt;、&lt;code&gt;/new1&lt;/code&gt; 等应该是示例，实际操作需要替换为真实路径。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 4 题&lt;/strong&gt;：回答正确，准确比较了 &lt;code&gt;mysqldump&lt;/code&gt; 和 &lt;code&gt;PERCONA Xtrabackup&lt;/code&gt; 在备份和恢复过程中对数据库性能的影响。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3 操作题&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;第 1 题&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;命令基本正确，但需要注意的是，使用 &lt;code&gt;-p&lt;/code&gt; 后面直接跟密码会有安全风险，实际操作中建议不直接写密码，而是在提示时输入。同时，&lt;code&gt;-B&lt;/code&gt; 选项用于指定数据库，这里 &lt;code&gt;moershi&lt;/code&gt; 应该是你要备份的数据库名，如果需要备份 &lt;code&gt;sales&lt;/code&gt; 数据库，应该将 &lt;code&gt;moershi&lt;/code&gt; 替换为 &lt;code&gt;sales&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 2 题&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;命令存在拼写错误，&lt;code&gt;--incremenntal - basefir&lt;/code&gt; 应该为 &lt;code&gt;--incremental - basedir&lt;/code&gt;。正确的命令为：&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;[root@mha ~]# xtrabackup --host=127.0.0.1 --user=root --password=123 --backup --target-dir=/增量备份保存路径 --incremental-basedir=/全量备份保存路径 --datadir=/mysql数据路径
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;- 同样，路径需要替换为实际路径。
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;第 3 题&lt;/strong&gt;：回答正确，详细描述了使用全量备份和差异备份恢复数据库的操作过程和命令。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 4 题&lt;/strong&gt;：回答正确，给出了验证 &lt;code&gt;PERCONA Xtrabackup&lt;/code&gt; 差异备份文件完整性的具体步骤和命令。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 5 题&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;备份方案：
&lt;ul&gt;
&lt;li&gt;使用 &lt;code&gt;crontab&lt;/code&gt; 和 &lt;code&gt;mysqldump&lt;/code&gt; 进行定期全量备份的命令基本正确，但密码使用方式存在安全风险，建议使用更安全的方式存储密码。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Percona XtraBackup&lt;/code&gt; 进行全量、增量备份脚本和定时任务设置思路正确，但路径需要替换为实际路径。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;恢复方案：
&lt;ul&gt;
&lt;li&gt;使用 &lt;code&gt;mysqldump&lt;/code&gt; 恢复数据的命令中，&lt;code&gt;$(date +%Y - %m - %d_%H - %M - %S)&lt;/code&gt; 会获取当前时间，应该指定具体的备份文件时间，而不是当前时间。&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;Percona XtraBackup&lt;/code&gt; 恢复数据的步骤正确，但路径需要替换为实际路径。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;总体来说，作业完成情况较好，但存在一些小错误和需要注意的安全问题，希望你能及时修改完善。&lt;/p&gt;
</content:encoded></item><item><title>09：mysql之主从复制</title><link>https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/09-mysql%E4%B9%8B%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/09-mysql%E4%B9%8B%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6/</guid><description>09：mysql之主从复制 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 06:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1&gt;09：mysql之主从复制&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/09-mysql%E4%B9%8B%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6/image-20250616165058217.webp&quot; alt=&quot;image-20250616165058217&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;在一家电商公司，其业务涵盖商品展示、订单处理、用户管理等，数据库中存储着海量的商品信息、用户数据和交易记录。随着业务的快速发展，数据库的读写压力与日俱增。为了缓解数据库压力，提高系统的可用性和数据安全性，公司决定采用 MySQL 主从复制架构。&lt;/p&gt;
&lt;p&gt;主数据库负责处理所有的写操作，如商品信息更新、订单创建等。从数据库则实时同步主数据库的数据，负责处理大量的读操作，如商品查询、用户信息展示等。通过这种方式，有效地分担了数据库的负载，提高了系统的响应速度。同时，当主数据库出现故障时，可以快速将业务切换到从数据库，保障业务的连续性。&lt;/p&gt;
&lt;h2&gt;二、为什么学&lt;/h2&gt;
&lt;p&gt;学习 MySQL 主从复制有诸多重要意义。在企业应用层面，随着业务增长，数据库面临读写压力大的问题，主从复制可将读操作分发到从库，减轻主库负担，提升系统性能和响应速度，保障业务流畅运行。在数据安全与备份方面，从库是主库数据的实时副本，当主库出现故障，可快速切换到从库继续服务，降低数据丢失风险，保证业务连续性。此外，掌握主从复制也是提升个人技术能力的关键一步，如今数据库技术广泛应用，精通此技术能增强职场竞争力，为从事数据库管理、开发等工作奠定坚实基础。&lt;/p&gt;
&lt;h2&gt;三、binlog【宾-劳格】日志&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/09-mysql%E4%B9%8B%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6/image-20250616165129789.webp&quot; alt=&quot;image-20250616165129789&quot; /&gt;&lt;/p&gt;
&lt;p&gt;binlog【宾-劳格】日志介绍：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;也称做 二进制日志&lt;/li&gt;
&lt;li&gt;MySQL服务日志文件的一种&lt;/li&gt;
&lt;li&gt;保存除查询之外的所有SQL命令m&lt;/li&gt;
&lt;li&gt;可用于数据的备份和恢复&lt;/li&gt;
&lt;li&gt;配置mysql主从同步的必要条件&lt;/li&gt;
&lt;li&gt;准备新的数据库服务器如表-1，做binlog【宾-劳格】&lt;/li&gt;
&lt;/ol&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;mysql52&lt;/td&gt;
&lt;td&gt;192.168.90.52&lt;/td&gt;
&lt;td&gt;练习binlog【宾-劳格】日志&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;mysql52的IP配置和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.52/24 autoconnect【奥特欧 坑聂特】 yes
#[root@slave2 ~]# nmcli connection modify ens160 ipv4.addresses 192.168.90.52/24 autoconnect yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
#[root@slave2 ~]# nmcli connection up ens160
[root@mysql52 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql52
#[root@slave2 ~]# hostnamectl set-hostname mysql52
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.1 查看正在使用的binlog【宾-劳格】日志文件&lt;/h3&gt;
&lt;p&gt;在新创建的数据库服务器做如下操作:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 安装软件 
[root@mysql52 ~]# yum -y install【因-斯多】 mysql-server  
# [root@slave2 ~]# yum -y install mysql-server 

# 启动服务
[root@mysql52 ~]# systemctl【西斯屯-ctl】   start【s 达儿】 mysqld  
# [root@slave2 ~]# systemctl status mysqld

# 连接服务
[root@mysql52 ~]# mysql  
# [root@mysql52 ~]# mysql

# 查看日志文件
mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】; 
# mysql&amp;gt; show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| binlog.000001 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

# 执行查询命令 
mysql&amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】  mysql.user;
# mysql&amp;gt; select count(*) from mysql.user;
+-------------------+
| count【kàn特】(*) |
+-------------------+
|        4          |
+-------------------+
1 row in set (0.00 sec)

# 执行查询命令 日志偏移量不变
mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】; 
# mysql&amp;gt; show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| binlog.000001 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

# 执行建库、建表命令
mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】  db1;
# mysql&amp;gt; create database db1;
Query OK, 1 row affected (0.07 sec)

mysql&amp;gt; create【克瑞特】 table【忒-部】 db1.user(name char【查尔】(10));
# mysql&amp;gt; create table db1.user(name char(10));
Query OK, 0 rows affected (0.52 sec)

# 执行写命令 日志偏移量改变
mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】; 
# mysql&amp;gt; show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| binlog.000001 |      535 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

# 插入记录
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.user values【挖柳斯】(&quot;jim&quot;); 
# mysql&amp;gt; insert into db1.user values(&quot;jim&quot;);
Query OK, 1 row affected (0.10 sec)

# 执行写命令 日志偏移量改变
mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】; 
# mysql&amp;gt; show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| binlog.000001 |      809 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 自定义日志目录和日志名&lt;/h3&gt;
&lt;p&gt;日志文件默认保存在/var/lib/mysql目录下，默认日志名binlog【宾-劳格】&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql52 ~]# vim /etc/my.cnf.d/mysql-server.cnf 
[mysqld]
log-bin=/mylog/mysql52   #定义日志目录和日志文件名(手动添加)
:wq

[root@mysql52 ~]# mkdir【摸克跌儿】 /mylog  创建目录
[root@mysql52 ~]# chown【吃-昂】  mysql  /mylog   修改目录所有者mysql用户
[root@mysql52 ~]# setenforce【赛特-因佛尔斯】  0   关闭selinux
[root@mysql52 ~]# systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld   重启服务
[root@mysql52 ~]# ls /mylog/  查看日志目录
mysql52.000001  mysql52.index
[root@mysql52 ~]# mysql  登陆服务

Mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】 ； 查看日志信息
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql52.000001 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3 手动创建新的日志文件&lt;/h3&gt;
&lt;p&gt;默认日志文件容量大于1G时会自动创建新的日志文件，在日志文件没写满时，执行的所有写命令都会保存到当前使用的日志文件里。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#刷新前查看
mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql52.000001 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql&amp;gt; flush【福 辣 徐】 logs【劳格斯】; #刷新日志
Query OK, 0 rows affected (0.22 sec)

mysql&amp;gt; flush【福 辣 徐】 logs【劳格斯】; #刷新日志
Query OK, 0 rows affected (0.16 sec)

mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】; #刷新一次创建一个新日志
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql52.000003 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

#只要服务重启就会创建新日志
[root@mysql52 ~]# systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld 
[root@mysql52 ~]# mysql  连接服务

Mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】; 查看日志
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql52.000004 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
[root@mysql52 ~]#

#完全备份后创建新的日志文件，创建的日志个数和备份库的个数一致
[root@mysql52 ~]# mysqldump【mysql-当普】  --flush【福 辣 徐】-logs【劳格斯】  mysql user &amp;gt; user.sql

[root@mysql52 ~]# mysql -e &apos;show【瘦】  master【马斯特】 status【 斯dèi 特斯】&apos;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql52.000005 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
[root@mysql52 ~]# mysqldump【mysql-当普】  --flush【福 辣 徐】-logs【劳格斯】  -B mysql db1 &amp;gt; db_2.sql

[root@mysql52 ~]# mysql -e &apos;show【瘦】  master【马斯特】 status【 斯dèi 特斯】&apos;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql52.000007 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
[root@mysql52 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.4 日志相关命令的使用&lt;/h3&gt;
&lt;p&gt;MySQL服务提供了管理日志的专属命令，具体练习如下:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#查看已有的日志文件
mysql&amp;gt;  show【瘦】 binary【拜讷瑞】  logs【劳格斯】;
日志文件名        日志大小(字节)  加密（no/yes）
+----------------+-----------+-----------+
| Log_name       | File_size | Encrypted |
+----------------+-----------+-----------+
| mysql52.000001 |       201 | No        |
| mysql52.000002 |       201 | No        |
| mysql52.000003 |       179 | No        |
| mysql52.000004 |       201 | No        |
| mysql52.000005 |       201 | No        |
| mysql52.000006 |       201 | No        |
| mysql52.000007 |       156 | No        |
+----------------+-----------+-----------+
7 rows in set (0.00 sec)

#查看正在使用的日志
mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql52.000007 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

#插入记录
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.user values【挖柳斯】(&quot;yaya&quot;);
Query OK, 1 row affected (0.04 sec)

#查看日志文件内容
mysql&amp;gt;  show【瘦】 binlog【宾-劳格】 events【伊文茨】 in  &quot;mysql52.000007&quot;;
Log_name：   日志文件名。
Pos：         命令在日志文件中的起始位置。
Event_type： 事件类型，例如 Query、Table_map、Write_rows 等。
Server_id：  服务器 ID。
End_log_pos：命令在文件中的结束位置，以字节为单位。
Info：执行命令信息。
+----------------+-----+----------------+-----------+-------------+--------------------------------------+
| Log_name       | Pos | Event_type     | Server_id | End_log_pos | Info                                 |
+----------------+-----+----------------+-----------+-------------+--------------------------------------+
| mysql52.000007 |   4 | Format_desc    |         1 |         125 | Server ver: 8.0.26, Binlog ver: 4    |
| mysql52.000007 | 125 | Previous_gtids |         1 |         156 |                                      |
| mysql52.000007 | 156 | Anonymous_Gtid |         1 |         235 | SET @@SESSION.GTID_NEXT= &apos;ANONYMOUS&apos; |
| mysql52.000007 | 235 | Query          |         1 |         306 | BEGIN                                |
| mysql52.000007 | 306 | Table_map      |         1 |         359 | table_id: 108 (db1.user)             |
| mysql52.000007 | 359 | Write_rows     |         1 |         400 | table_id: 108 flags: STMT_END_F      |
| mysql52.000007 | 400 | Xid            |         1 |         431 | COMMIT /* xid=649 */                 |
+----------------+-----+----------------+-----------+-------------+--------------------------------------+
7 rows in set (0.00 sec)

#删除日志文件名之前的所有日志文件
mysql&amp;gt; purge【pò取】  master【马斯特】 logs【劳格斯】  to  &quot;mysql52.000004&quot;;
Query OK, 0 rows affected (0.10 sec)

#查看已有的日志文件
mysql&amp;gt;  show【瘦】 binary【拜讷瑞】 logs【劳格斯】;
+----------------+-----------+-----------+
| Log_name       | File_size | Encrypted |
+----------------+-----------+-----------+
| mysql52.000004 |       201 | No        |
| mysql52.000005 |       201 | No        |
| mysql52.000006 |       201 | No        |
| mysql52.000007 |       431 | No        |
+----------------+-----------+-----------+
4 rows in set (0.00 sec)

#删除所有日志文件，并重新创建日志文件
mysql&amp;gt; reset【瑞 赛特】 master【马斯特】;
Query OK, 0 rows affected (0.14 sec)

#查看已有的日志文件 ，仅有第1个文件了
mysql&amp;gt;  show【瘦】 binary【拜讷瑞】 logs【劳格斯】;
+----------------+-----------+-----------+
| Log_name       | File_size | Encrypted |
+----------------+-----------+-----------+
| mysql52.000001 |       156 | No        |
+----------------+-----------+-----------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.5 使用日志恢复数据&lt;/h3&gt;
&lt;p&gt;把查看到的文件内容管道给连接mysql服务的命令执行&lt;/p&gt;
&lt;p&gt;恢复数据命令：&lt;/p&gt;
&lt;p&gt;mysqlbinlog【宾-劳格】 /目录/文件名 | mysql –uroot -p密码&lt;/p&gt;
&lt;p&gt;1）在mysql52主机执行如下操：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#重置日志
mysql&amp;gt; reset【瑞 赛特】 master【马斯特】;
Query OK, 0 rows affected (0.09 sec)

#查看日志
mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql52.000001 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

#建库、
mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】 gamedb;
Query OK, 1 row affected (0.07 sec)

#建表
mysql&amp;gt; create【克瑞特】 table【忒-部】 gamedb.t1(name char【查尔】(10),class【克拉斯】 char【查尔】(3));
Query OK, 0 rows affected (0.55 sec)

#插入记录
mysql&amp;gt; insert【因涩特】 into【因兔】 gamedb.t1 values【挖柳斯】 (&quot;yaya&quot;,&quot;nsd&quot;);
Query OK, 1 row affected (0.08 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 gamedb.t1 values【挖柳斯】 (&quot;yaya&quot;,&quot;nsd&quot;);
Query OK, 1 row affected (0.04 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 gamedb.t1 values【挖柳斯】 (&quot;yaya&quot;,&quot;nsd&quot;);
Query OK, 1 row affected (0.08 sec)

#查看表记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 gamedb.t1;
+------+----------------+
| name | class【克拉斯】 |
+------+----------------+
| yaya | nsd            |
| yaya | nsd            |
| yaya | nsd            |
+------+----------------+
3 rows in set (0.00 sec)
mysql&amp;gt; exit【诶西特】
#把日志文件拷贝给恢复数据的服务器,比如 mysql50
[root@mysql52 ~]# scp  /mylog/mysql52.000001 root@192.168.90.50:/root/
The authenticity of host &apos;192.168.90.50 (192.168.90.50)&apos; can&apos;t be established.
ECDSA key fingerprint is SHA256:t7J3okFd0o+9zTmFCIetvDl6mxGCmc43VoD6C65zico.
Are you sure you want to continue connecting (yes/no/[fingerprint])? Yes 同意
Warning: Permanently added &apos;192.168.90.50&apos; (ECDSA) to the list of known hosts.
root@192.168.90.50&apos;s password:  mysql50的密码
mysql52.000001                                                              100% 1410     1.6MB/s   00:00    
[root@mysql52 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）在MySQL50 使用日志恢复数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#查看日志
[root@mysql50 ~]# ls /root/mysql52.000001 
/root/mysql52.000001

#执行日志恢复数据
[root@mysql50 ~]# mysqlbinlog【mtsql宾-劳格】 /root/mysql52.000001 | mysql -uroot -pNSD123456...a
mysql: [Warning] Using a password on【昂】 the command line interface can be insecure.

#连接服务查看数据
[root@mysql50 ~]# mysql -uroot -pNSD123456...a -e &apos;selectt【涩莱克特】 * from【弗乱】 gamedb.t1&apos;
mysql: [Warning] Using a password on【昂】 the command line interface can be insecure.
 +------+----------------+
| name | class【克拉斯】  |
 +------+----------------+
| yaya | nsd             |
| yaya | nsd             |
| yaya | nsd             |
 +------+----------------+
[root@mysql50 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、MySQL一主一从&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/09-mysql%E4%B9%8B%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6/image-20250616165155177.webp&quot; alt=&quot;image-20250616165155177&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;4.1 mysql主从复制原理&lt;/h3&gt;
&lt;p&gt;MySQL主从复制基于二进制日志（binlog【宾-劳格】）实现。主要分为三步：
首先，主库上执行更新操作时，会将变更记录到二进制日志日志里。
其次，从库的I/O线程会连接主库，请求主库发送二进制日志日志。主库的二进制日志转储线程将日志内容发送给从库I/O线程，I/O线程把接收的日志写入从库的中继日志(Relay Log)。
最后，从库的SQL线程读取中继日志中的事件，并在从库上重放，实现主从数据一致。&lt;/p&gt;
&lt;p&gt;mysql主从复制原理&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;主库将数据变更（DDL和DML）记录到二进制日志（binlog）中。&lt;/li&gt;
&lt;li&gt;从库的I/O线程向主库的log dump线程请求binlog。&lt;/li&gt;
&lt;li&gt;主库的log dump线程将binlog事件发送给从库的I/O线程。&lt;/li&gt;
&lt;li&gt;从库的I/O线程将接收到的事件写入中继日志（relay log）。&lt;/li&gt;
&lt;li&gt;从库的SQL线程读取并解析relay log中的事件，在从库上执行这些事件，从而使从库与主库的数据保持同步。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/09-mysql%E4%B9%8B%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6/image-20250616160307840.webp&quot; alt=&quot;image-20250616160307840&quot; /&gt;&lt;/p&gt;
&lt;p&gt;准备两台服务器&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;mysql53&lt;/td&gt;
&lt;td&gt;192.168.90.53&lt;/td&gt;
&lt;td&gt;master【马斯特】数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mysql54&lt;/td&gt;
&lt;td&gt;192.168.90.54&lt;/td&gt;
&lt;td&gt;slave【斯累夫】数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;mysql53的IP配置和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.53/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mysql53 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql53
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mysql54的IP配置和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.54/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mysql54 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql54
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 配置为主数据库服务器&lt;/h3&gt;
&lt;p&gt;数据库服务器192.168.90.53配置为主数据库服务器&lt;/p&gt;
&lt;p&gt;1）启用binlog【宾-劳格】日志&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql53 ~]# yum -y  install【因-斯多】 mysql-server  mysql
[root@mysql53 ~]# systemctl【西斯屯-ctl】  start【s 达儿】 mysqld
[root@mysql53 ~]# vim /etc/my.cnf.d/mysql-server.cnf
[mysqld]
server-id=53
log-bin=mysql53
:wq
[root@mysql53 ~]# systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）用户授权&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql53 ~]# mysql

mysql&amp;gt; create【克瑞特】 user repluser@&quot;%&quot; identified【爱-丹-提伐】 WITH【威付】 mysql_native_password by &quot;123qqq...A&quot;;
Query OK, 0 rows affected (0.11 sec)

mysql&amp;gt; grant【古亮普】 replication【瑞普利K申】 slave【斯累夫】 on【昂】 *.*  to repluser@&quot;%&quot;;
Query OK, 0 rows affected (0.09 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3）查看日志信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql53.000001 |      667 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.3 配置为从数据库服务&lt;/h3&gt;
&lt;p&gt;数据库服务器192.168.90.54配置为从数据库服务&lt;/p&gt;
&lt;p&gt;1)指定server-id 并重启数据库服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql54 ~]# yum -y  install【因-斯多】 mysql-server  mysql
[root@mysql54 ~]# systemctl【西斯屯-ctl】  start【s 达儿】 mysqld
[root@mysql54 ~]# vim /etc/my.cnf.d/mysql-server.cnf
[mysqld]
server-id=54
:wq
[root@mysql54 ~]# systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2)登陆服务指定主服务器信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql54 ~]# mysql
mysql&amp;gt; change【趁(chèn)吉】  master【马斯特】 to  master【马斯特】_host=&quot;192.168.90.53&quot; , master【马斯特】_user=&quot;repluser&quot; , master【马斯特】_password=&quot;123qqq...A&quot; ,master【马斯特】_log_file=&quot;mysql53.000001&quot; , master【马斯特】_log_pos=667;
Query OK, 0 rows affected, 8 warnings (0.34 sec)

mysql&amp;gt;  start【s 达儿】 slave【斯累夫】 ; #启动slave【斯累夫】进程
Query OK, 0 rows affected, 1 warning (0.04 sec)

mysql&amp;gt;  show【瘦】 slave【斯累夫】 status【 斯dèi 特斯】 \G  #查看状态信息
*************************** 1. row ***************************
               Slave【斯累夫】_IO_State: Waiting for source to send event
                  master【马斯特】_Host: 192.168.90.53
                  master【马斯特】_User: repluser
                  master【马斯特】_Port: 3306
                Connect_Retry: 60
              master【马斯特】_Log_File: mysql53.000001
          Read_master【马斯特】_Log_Pos: 667
               Relay_Log_File: mysql54-relay-bin.000002
                Relay_Log_Pos: 322
        Relay_master【马斯特】_Log_File: mysql53.000001
             Slave【斯累夫】_IO_Running: Yes   #IO线程
            Slave【斯累夫】_SQL_Running: Yes   #SQL线程
              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: 667
              Relay_Log_Space: 533
              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: 53
                  master【马斯特】_UUID: 38c02165-005e-11ee-bd2d-525400007271
             master【马斯特】_Info_File: mysql.slave【斯累夫】_master【马斯特】_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave【斯累夫】_SQL_Running_State: Replica 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: 
       master【马斯特】_public_key_path: 
        Get_master【马斯特】_public_key: 0
            Network_Namespace: 
1 row in set, 1 warning (0.00 sec)
mysql&amp;gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.4 客户端192.168.90.50测试配置&lt;/h3&gt;
&lt;p&gt;1）在主服务器添加用户，给客户端连接使用&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql53 ~]# mysql
mysql&amp;gt; create【克瑞特】 user jam@&quot;%&quot; identified【爱-丹-提伐】 by &quot;123456&quot;;
Query OK, 0 rows affected (0.14 sec)

mysql&amp;gt; grant【古亮普】 all【ò】 on【昂】 gamedb.* to jam@&quot;%&quot; ;
Query OK, 0 rows affected (0.12 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）客户端连接主服务器存储数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# mysql -h192.168.90.53 -ujam -p123456
mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】 gamedb;
Query OK, 1 row affected (0.24 sec)

mysql&amp;gt; create【克瑞特】 table【忒-部】 gamedb.user(name char【查尔】(10) , class【克拉斯】 char【查尔】(3));
Query OK, 0 rows affected (1.71 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 gamedb.user values【挖柳斯】 (&quot;yaya&quot;,&quot;nsd&quot;);
Query OK, 1 row affected (0.14 sec)

mysql&amp;gt; select【涩莱克特】  * from【弗乱】 gamedb.user;
+------+-------+
| name | class【克拉斯】 |
+------+-------+
| yaya | nsd   |
+------+-------+
1 row in set (0.01 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3）客户端连接从服务器查看数据&lt;/p&gt;
&lt;p&gt;-e 命令行下执行数据库命令&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# mysql -h192.168.90.54 -ujam -p123456 –e ‘select【涩莱克特】  * from【弗乱】 gamedb.user’
+------+-------+
| name | class【克拉斯】 |
+------+-------+
| yaya | nsd   |
+------+-------+
[root@mysql54 ~]# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、配置一主多从结构&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/09-mysql%E4%B9%8B%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6/image-20250616165031927.webp&quot; alt=&quot;image-20250616165031927&quot; /&gt;&lt;/p&gt;
&lt;p&gt;准备新的服务器&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;mysql55&lt;/td&gt;
&lt;td&gt;192.168.90.55&lt;/td&gt;
&lt;td&gt;从数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;mysql55的IP配置和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.55/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mysql55 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql55
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/09-mysql%E4%B9%8B%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6/image-20250616163452783.webp&quot; alt=&quot;image-20250616163452783&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;5.1 配置192.168.90.55从服务器&lt;/h3&gt;
&lt;p&gt;1)指定MySQL55主机的server-id 并重启数据库服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@mysql55 ~]# yum -y  install【因-斯多】 mysql-server
[root@mysql55 ~]# systemctl【西斯屯-ctl】  start【s 达儿】 mysqld
[root@mysql55 ~]# vim /etc/my.cnf.d/mysql-server.cnf
[mysqld]
server-id=55
:wq
[root@mysql55 ~]# systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）确保与主服务器数据一致。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#在mysql53执行备份命令前查看日志名和偏移量 ，mysql55 在当前查看到的位置同步数据
[root@mysql53 ~]# mysql -e &apos;show【瘦】  master【马斯特】 status【 斯dèi 特斯】&apos;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql53.000002 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
[root@mysql53 ~]#

#在主服务器存做完全备份
[root@mysql53 ~]# mysqldump【mysql-当普】  -B gamedb &amp;gt; /root/gamedb.sql 

#主服务器把备份文件拷贝给从服务器mysql55
[root@mysql53 ~]# scp  /root/gamedb.sql  root@192.168.90.55:/root/
[root@mysql55 ~]# mysql &amp;lt; /root/gamedb.sql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3）在MySQL55主机指定主服务器信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql55 ~]# mysql 

mysql&amp;gt; change【趁(chèn)吉】  master【马斯特】 to  master【马斯特】_host=&quot;192.168.90.53&quot; , master【马斯特】_user=&quot;repluser&quot; , master【马斯特】_password=&quot;123qqq...A&quot; , master【马斯特】_log_file=&quot;mysql53.000002&quot; , master【马斯特】_log_pos=156;
Query OK, 0 rows affected, 8 warnings (0.44 sec)

注意:日志名和偏移量 要写 在mysql53主机执行完全备份之前查看到的日志名和偏移量

mysql&amp;gt;  start【s 达儿】 slave【斯累夫】; #启动slave【斯累夫】进程
Query OK, 0 rows affected, 1 warning (0.02 sec)

#查看状态信息
mysql&amp;gt;  show【瘦】 slave【斯累夫】 status【 斯dèi 特斯】 \G
*************************** 1. row ***************************
               Slave【斯累夫】_IO_State: Waiting for source to send event
                  master【马斯特】_Host: 192.168.90.53
                  master【马斯特】_User: repluser
                  master【马斯特】_Port: 3306
                Connect_Retry: 60
              master【马斯特】_Log_File: mysql53.000002
          Read_master【马斯特】_Log_Pos: 156
               Relay_Log_File: mysql55-relay-bin.000002
                Relay_Log_Pos: 322
        Relay_master【马斯特】_Log_File: mysql53.000002
             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: 156
              Relay_Log_Space: 533
              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: 53
                  master【马斯特】_UUID: 38c02165-005e-11ee-bd2d-525400007271
             master【马斯特】_Info_File: mysql.slave【斯累夫】_master【马斯特】_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave【斯累夫】_SQL_Running_State: Replica 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: 
       master【马斯特】_public_key_path: 
        Get_master【马斯特】_public_key: 0
            Network_Namespace: 
1 row in set, 1 warning (0.00 sec)

#添加客户端访问时使用的用户
mysql&amp;gt; create【克瑞特】 user jam@&quot;%&quot; identified【爱-丹-提伐】 by &quot;123456&quot;;
Query OK, 0 rows affected (0.08 sec)

mysql&amp;gt; grant【古亮普】 all【ò】 on【昂】 gamedb.* to jam@&quot;%&quot; ;
Query OK, 0 rows affected (0.04 sec)
Mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 客户端测试配置&lt;/h3&gt;
&lt;p&gt;1）在mysql50 连接主服务器mysql53 存储数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#连接主服务器存储数据
[root@mysql50 ~]# mysql -h192.168.90.53 -ujam -p123456

mysql&amp;gt; insert【因涩特】 into【因兔】  gamedb.user values【挖柳斯】(&quot;tt&quot;,&quot;aid&quot;);
Query OK, 1 row affected (0.14 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】  gamedb.user values【挖柳斯】(&quot;mm&quot;,&quot;uid&quot;);
Query OK, 1 row affected (0.13 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）在client50 分别连接2个从服务器查看数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#连接从服务器54查看数据
[root@mysql50 ~]# mysql -h192.168.90.54 -ujam -p123456 -e &apos;select【涩莱克特】 * from【弗乱】 gamedb.user&apos;
mysql: [Warning] Using a password on【昂】 the command line interface can be insecure.
+------+-------+
| name | class【克拉斯】 |
+------+-------+
| yaya | nsd   |
| tt   | aid   |
| mm   | uid   |
+------+-------+

#连接从服务器55查看数据
[root@mysql50 ~]# mysql -h192.168.90.55 -ujam -p123456 -e &apos;select【涩莱克特】 * from【弗乱】 gamedb.user&apos;
mysql: [Warning] Using a password on【昂】 the command line interface can be insecure.
+------+-------+
| name | class【克拉斯】 |
+------+-------+
| yaya | nsd   |
| tt   | aid   |
| mm   | uid   |
+------+-------+
[root@mysql50 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/09-mysql%E4%B9%8B%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6/image002.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;#我 : 按照上面的方法设置主从同步，之后新加的数据会同步从库，那要是在设置主从之前的数据呢？也会同步吗？&lt;/p&gt;
&lt;p&gt;#Doubao :
在设置 MySQL 主从同步时，设置同步之前主库已存在的数据是否会同步到从库，取决于具体的配置和操作步骤，下面为你详细分析不同情况：&lt;/p&gt;
&lt;h2&gt;设置主从同步之前的数据不会自动同步&lt;/h2&gt;
&lt;p&gt;如果只是简单地配置主从同步的连接信息（如设置从库的 &lt;code&gt;CHANGE MASTER TO&lt;/code&gt; 语句），而没有做额外的数据初始化操作，那么设置主从同步之前主库上已存在的数据不会自动同步到从库。这是因为主从同步是基于二进制日志（binlog）来记录和同步主库上的更改操作，在配置主从同步时，从库会从指定的二进制日志文件和位置开始读取并应用主库的更改，而设置之前的历史数据并没有被包含在这个起始点之后的二进制日志中。&lt;/p&gt;
&lt;h3&gt;可以通过特定操作实现同步&lt;/h3&gt;
&lt;p&gt;为了让设置主从同步之前主库上的数据也能同步到从库，可以采取以下常见方法：&lt;/p&gt;
&lt;h4&gt;1. 使用 &lt;code&gt;mysqldump&lt;/code&gt; 备份和恢复&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;步骤&lt;/strong&gt;：
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;在主库上锁定表并进行备份&lt;/strong&gt;：为了保证数据的一致性，在备份过程中需要锁定主库上的表，防止数据被修改。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;# 登录主库，锁定所有表
mysql -u root -p -e &quot;FLUSH TABLES WITH READ LOCK;&quot;
# 记录当前二进制日志文件和位置
mysql -u root -p -e &quot;SHOW MASTER STATUS;&quot;
# 使用 mysqldump 备份主库数据
mysqldump -u root -p --all-databases &amp;gt; master_backup.sql
# 解锁主库上的表
mysql -u root -p -e &quot;UNLOCK TABLES;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;2. **将备份文件传输到从库**：可以使用 `scp` 等工具将备份文件从主库复制到从库。
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;scp master_backup.sql user@slave_ip:/path/to/destination
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;3. **在从库上恢复备份数据**：登录从库，执行备份文件中的 SQL 语句。
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mysql -u root -p &amp;lt; master_backup.sql
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;4. **配置从库连接主库**：使用之前记录的二进制日志文件和位置，配置从库连接主库。
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CHANGE MASTER TO
    MASTER_HOST=&apos;master_ip&apos;,
    MASTER_USER=&apos;replication_user&apos;,
    MASTER_PASSWORD=&apos;replication_password&apos;,
    MASTER_LOG_FILE=&apos;binlog_file_name&apos;,
    MASTER_LOG_POS=binlog_position;
START SLAVE;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2. 使用 &lt;code&gt;rsync&lt;/code&gt; 复制数据文件（适用于 InnoDB 存储引擎）&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;步骤&lt;/strong&gt;：
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;停止主库和从库的 MySQL 服务&lt;/strong&gt;：为了避免数据冲突，需要先停止主库和从库的 MySQL 服务。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;systemctl stop mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;2. **使用 `rsync` 复制主库的数据文件到从库**：确保主库和从库的数据目录结构一致。
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;rsync -avz /var/lib/mysql/ user@slave_ip:/var/lib/mysql/
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;3. **启动从库的 MySQL 服务**：启动从库的 MySQL 服务，并配置从库连接主库。
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;systemctl start mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CHANGE MASTER TO
    MASTER_HOST=&apos;master_ip&apos;,
    MASTER_USER=&apos;replication_user&apos;,
    MASTER_PASSWORD=&apos;replication_password&apos;,
    MASTER_LOG_FILE=&apos;binlog_file_name&apos;,
    MASTER_LOG_POS=binlog_position;
START SLAVE;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过以上方法，可以将设置主从同步之前主库上的数据同步到从库，实现主从库数据的一致性。&lt;/p&gt;
&lt;h2&gt;异步复制、半同步复制、完全同步复制&lt;/h2&gt;
&lt;p&gt;#我 : MySQL 主从复制采用异步复制是什么？有同步复制吗？区别和优缺点是什么？&lt;/p&gt;
&lt;p&gt;#Doubao :&lt;/p&gt;
&lt;h3&gt;MySQL 主从复制中的异步复制&lt;/h3&gt;
&lt;h4&gt;概念&lt;/h4&gt;
&lt;p&gt;在 MySQL 主从复制的异步复制模式下，主库在执行完客户端提交的事务后，会立即将结果返回给客户端，而不会等待从库接收并处理该事务的二进制日志（binlog）。主库会将事务的变更记录到二进制日志中，然后异步地将这些日志发送给从库，从库会在自己的线程中独立地接收和应用这些日志。&lt;/p&gt;
&lt;h4&gt;示例代码配置&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;-- 在主库上创建用于复制的用户
CREATE USER &apos;repl_user&apos;@&apos;%&apos; IDENTIFIED BY &apos;password&apos;;
GRANT REPLICATION SLAVE ON *.* TO &apos;repl_user&apos;@&apos;%&apos;;
FLUSH PRIVILEGES;

-- 查看主库的二进制日志信息
SHOW MASTER STATUS;

-- 在从库上配置主从复制
CHANGE MASTER TO
    MASTER_HOST=&apos;master_ip&apos;,
    MASTER_USER=&apos;repl_user&apos;,
    MASTER_PASSWORD=&apos;password&apos;,
    MASTER_LOG_FILE=&apos;master_binlog_file_name&apos;,
    MASTER_LOG_POS=master_binlog_position;

START SLAVE;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;MySQL 中的同步复制&lt;/h3&gt;
&lt;h4&gt;概念&lt;/h4&gt;
&lt;p&gt;严格意义上，MySQL 原生的复制模式默认是异步复制，但 MySQL 也提供了半同步复制（Semi-synchronous Replication），可以看作是一种介于异步和完全同步之间的模式。在半同步复制中，主库在提交事务后，会等待至少一个从库确认已经接收到该事务的二进制日志后，才会向客户端返回操作成功的信息。&lt;/p&gt;
&lt;h4&gt;示例代码配置&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;-- 在主库和从库上都要安装半同步复制插件
INSTALL PLUGIN rpl_semi_sync_master SONAME &apos;semisync_master.so&apos;;
INSTALL PLUGIN rpl_semi_sync_slave SONAME &apos;semisync_slave.so&apos;;

-- 在主库上启用半同步复制
SET GLOBAL rpl_semi_sync_master_enabled = 1;
SET GLOBAL rpl_semi_sync_master_timeout = 10000;  -- 设置超时时间

-- 在从库上启用半同步复制
SET GLOBAL rpl_semi_sync_slave_enabled = 1;

-- 重启从库的复制线程
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;区别&lt;/h3&gt;
&lt;h4&gt;数据一致性&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;异步复制&lt;/strong&gt;：主库和从库之间存在一定的数据延迟，因为主库不会等待从库接收和应用事务。在主库发生故障时，从库可能没有完全同步主库的最新数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;半同步复制&lt;/strong&gt;：在一定程度上保证了数据的一致性，因为主库会等待至少一个从库确认接收事务。但如果所有从库都出现问题，主库会在超时后自动切换回异步复制模式。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;性能影响&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;异步复制&lt;/strong&gt;：对主库的性能影响较小，因为主库不需要等待从库的响应，可以立即返回结果给客户端。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;半同步复制&lt;/strong&gt;：会对主库的性能产生一定的影响，因为主库需要等待从库的确认信息，增加了事务的提交时间。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;优缺点&lt;/h3&gt;
&lt;h4&gt;异步复制&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;优点&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;性能高，主库可以快速响应客户端请求，不会因为从库的性能问题而受到影响。&lt;/li&gt;
&lt;li&gt;配置简单，是 MySQL 默认的复制模式，不需要额外的插件和复杂的配置。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺点&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;数据一致性较差，在主库故障时可能会导致数据丢失。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;半同步复制&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;优点&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;提高了数据的一致性，减少了主库故障时数据丢失的风险。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺点&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;性能相对较低，因为主库需要等待从库的确认信息。&lt;/li&gt;
&lt;li&gt;配置相对复杂，需要安装和启用半同步复制插件。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;完全同步复制&lt;/h3&gt;
&lt;p&gt;除了半同步复制，还有一些第三方解决方案可以实现完全同步复制，即主库必须等待所有从库都成功应用事务后才会提交。但这种方式会对性能产生极大的影响，实际应用中较少使用。&lt;/p&gt;
&lt;h2&gt;binlog 的三种格式&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;格式&lt;/th&gt;
&lt;th&gt;记录内容&lt;/th&gt;
&lt;th&gt;优点&lt;/th&gt;
&lt;th&gt;缺点&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;**STATEMENT (SBR)**​&lt;/td&gt;
&lt;td&gt;记录造成数据变更的&lt;strong&gt;SQL语句本身&lt;/strong&gt;​&lt;/td&gt;
&lt;td&gt;日志量小，节省磁盘和网络I/O；易于查看和审计&lt;/td&gt;
&lt;td&gt;可能引起主从不一致（如使用&lt;code&gt;NOW()&lt;/code&gt;, &lt;code&gt;UUID()&lt;/code&gt;等非确定性函数时）&lt;/td&gt;
&lt;td&gt;数据结构简单、SQL模式固定、更新量大但涉及行少的场景&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;**ROW (RBR)**​&lt;/td&gt;
&lt;td&gt;记录每一行数据&lt;strong&gt;如何被修改&lt;/strong&gt;（如修改前/后的镜像）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;数据安全性和一致性最高&lt;/strong&gt;，可可靠地复制任何变更&lt;/td&gt;
&lt;td&gt;日志量可能非常大（特别是批量更新或表结构变更时）&lt;/td&gt;
&lt;td&gt;对数据一致性要求极高的场景（如金融业务），或使用了可能引起不一致的函数/存储过程时&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;**MIXED (MBR)**​&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;智能混合&lt;/strong&gt;使用STATEMENT和ROW模式&lt;/td&gt;
&lt;td&gt;在安全性和性能间取得平衡；多数情况下日志量小，特定情况下自动转为ROW模式以保证安全&lt;/td&gt;
&lt;td&gt;仍存在极小概率在混合模式下出现不一致&lt;/td&gt;
&lt;td&gt;希望兼顾性能和数据安全性的通用业务场景，&lt;strong&gt;MySQL 5.7.7及以上版本默认采用此格式&lt;/strong&gt;​&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;#我 : . 列举 MySQL 主从复制中 binlog 的三种格式，并说明各自特点。&lt;/p&gt;
&lt;p&gt;#Doubao :
在 MySQL 主从复制中，binlog（二进制日志）有三种格式，分别是 &lt;code&gt;STATEMENT&lt;/code&gt;（语句级）、&lt;code&gt;ROW&lt;/code&gt;（行级）和 &lt;code&gt;MIXED&lt;/code&gt;（混合级），以下是它们各自的特点：&lt;/p&gt;
&lt;h3&gt;1. STATEMENT（语句级）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特点&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;日志记录方式&lt;/strong&gt;：记录的是主库上执行的 SQL 语句。也就是说，主库在执行一条 SQL 语句后，会将该语句本身记录到 binlog 中，从库在复制时，会重新执行这些 SQL 语句来达到与主库数据一致的目的。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;优点&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;日志量小&lt;/strong&gt;：由于只记录 SQL 语句，相比于记录每行数据变化的 ROW 格式，日志量通常要小很多，这可以减少磁盘 I/O 和网络传输的压力，同时也能节省存储空间。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可读性高&lt;/strong&gt;：SQL 语句本身是人类可读的，因此查看和分析 binlog 内容相对容易，便于进行故障排查和审计。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺点&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;部分语句复制可能存在问题&lt;/strong&gt;：一些依赖于主库当前环境的 SQL 语句，如 &lt;code&gt;NOW()&lt;/code&gt;、&lt;code&gt;UUID()&lt;/code&gt; 等函数，在主从库上执行时可能会产生不同的结果，因为主从库的系统时间、随机数种子等可能不同。此外，一些存储过程、触发器等也可能因为主从库环境差异而导致复制不一致。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;并发复制性能受限&lt;/strong&gt;：在高并发场景下，由于从库需要重新执行 SQL 语句，可能会受到锁和并发控制的影响，导致复制性能下降。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. ROW（行级）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特点&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;日志记录方式&lt;/strong&gt;：记录的是每行数据的变化情况，即哪些行被插入、更新或删除，以及具体的变更内容。而不是像 STATEMENT 格式那样记录 SQL 语句。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;优点&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;复制一致性高&lt;/strong&gt;：由于记录的是实际的数据变更，不依赖于 SQL 语句的执行环境，因此可以保证主从库数据的高度一致性，避免了 STATEMENT 格式中因环境差异导致的复制问题。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;并发复制性能好&lt;/strong&gt;：从库可以并行地应用这些行级变更，而不需要像执行 SQL 语句那样考虑锁和并发控制，因此在高并发场景下，复制性能通常比 STATEMENT 格式要好。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺点&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;日志量大&lt;/strong&gt;：需要记录每行数据的变化，对于大规模的数据更新操作，日志量会非常大，这会增加磁盘 I/O 和网络传输的负担，同时也需要更多的存储空间。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可读性差&lt;/strong&gt;：由于记录的是数据行的变化，而不是 SQL 语句，因此 binlog 的内容难以直接阅读和理解，不利于故障排查和审计。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. MIXED（混合级）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特点&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;日志记录方式&lt;/strong&gt;：结合了 STATEMENT 和 ROW 两种格式的优点。MySQL 会根据具体的 SQL 语句和执行情况，自动选择使用 STATEMENT 格式还是 ROW 格式来记录 binlog。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;优点&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;灵活性高&lt;/strong&gt;：对于大多数普通的 SQL 语句，会使用 STATEMENT 格式记录，以减少日志量；而对于那些可能导致复制不一致的 SQL 语句，如包含不确定函数的语句，则会使用 ROW 格式记录，以保证复制的一致性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能和一致性的平衡&lt;/strong&gt;：在保证复制一致性的同时，尽可能地减少日志量，提高复制性能和效率。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺点&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;难以预测日志格式&lt;/strong&gt;：由于是自动选择日志格式，在某些情况下可能会让人难以预测具体使用的是哪种格式，增加了故障排查和管理的难度。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以通过以下命令来查看和设置 binlog 的格式：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 查看当前 binlog 格式
SHOW VARIABLES LIKE &apos;binlog_format&apos;;

-- 设置 binlog 格式为 STATEMENT
SET GLOBAL binlog_format = &apos;STATEMENT&apos;;
-- 设置 binlog 格式为 ROW
SET GLOBAL binlog_format = &apos;ROW&apos;;
-- 设置 binlog 格式为 MIXED
SET GLOBAL binlog_format = &apos;MIXED&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需要注意的是，设置全局变量后，新的设置只会对新建立的会话生效，对于已经存在的会话，需要重新连接才能应用新的设置。&lt;/p&gt;
&lt;h2&gt;主库宕机如何保证业务&lt;/h2&gt;
&lt;p&gt;#我 : 主从复制中，若主库宕机，应如何进行故障切换以保证业务继续运行？&lt;/p&gt;
&lt;p&gt;#Doubao :
在 MySQL 主从复制架构中，当主库宕机时，为了保证业务能够继续运行，需要进行故障切换。以下是详细的故障切换步骤和方法：&lt;/p&gt;
&lt;h3&gt;1. 确认主库宕机&lt;/h3&gt;
&lt;p&gt;首先要通过监控系统、日志或者手动检查等方式，确认主库确实已经无法正常工作。例如，可以尝试连接主库，查看是否能够正常响应查询请求；查看主库的系统日志和 MySQL 日志，确认是否有异常信息。&lt;/p&gt;
&lt;h3&gt;2. 选择新的主库&lt;/h3&gt;
&lt;p&gt;从多个从库中选择一个合适的从库作为新的主库，通常会考虑以下因素：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;数据同步情况&lt;/strong&gt;：选择与原主库数据最接近同步的从库，以减少数据丢失。可以通过查看从库的 &lt;code&gt;SHOW SLAVE STATUS&lt;/code&gt; 命令输出，比较 &lt;code&gt;Seconds_Behind_Master&lt;/code&gt; 的值，选择该值最小的从库。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;硬件资源&lt;/strong&gt;：选择硬件配置较好、性能较高的从库，以确保新主库能够稳定运行。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 停止从库复制&lt;/h3&gt;
&lt;p&gt;在将选定的从库提升为新主库之前，需要先停止该从库的复制进程，避免后续出现数据冲突。在选定的从库上执行以下命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;STOP SLAVE;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. 提升从库为新主库&lt;/h3&gt;
&lt;p&gt;将选定的从库设置为独立的主库，需要重置二进制日志和中继日志。在选定的从库上执行以下命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;RESET MASTER;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5. 配置其他从库指向新主库&lt;/h3&gt;
&lt;p&gt;将其他从库配置为连接到新的主库，继续进行复制。在每个从库上执行以下命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 停止当前的复制进程
STOP SLAVE;
-- 配置新主库的连接信息
CHANGE MASTER TO
    MASTER_HOST=&apos;新主库的 IP 地址&apos;,
    MASTER_USER=&apos;复制用户&apos;,
    MASTER_PASSWORD=&apos;复制用户密码&apos;,
    MASTER_LOG_FILE=&apos;新主库当前的二进制日志文件名&apos;,
    MASTER_LOG_POS=新主库当前的二进制日志位置;
-- 启动复制进程
START SLAVE;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以通过 &lt;code&gt;SHOW SLAVE STATUS&lt;/code&gt; 命令检查复制是否正常工作，确保 &lt;code&gt;Slave_IO_Running&lt;/code&gt; 和 &lt;code&gt;Slave_SQL_Running&lt;/code&gt; 都为 &lt;code&gt;Yes&lt;/code&gt;。&lt;/p&gt;
&lt;h3&gt;6. 更新应用程序配置&lt;/h3&gt;
&lt;p&gt;将应用程序连接的数据库地址从原主库更新为新主库的地址，确保应用程序能够正常连接到新的主库。这可能需要修改应用程序的配置文件，并重新启动应用程序。&lt;/p&gt;
&lt;h3&gt;7. 恢复原主库&lt;/h3&gt;
&lt;p&gt;在故障切换完成后，可以对原主库进行故障排查和修复。修复完成后，将原主库配置为新主库的从库，继续进行复制。在原主库上执行以下命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 停止当前的复制进程
STOP SLAVE;
-- 重置二进制日志和中继日志
RESET SLAVE ALL;
-- 配置新主库的连接信息
CHANGE MASTER TO
    MASTER_HOST=&apos;新主库的 IP 地址&apos;,
    MASTER_USER=&apos;复制用户&apos;,
    MASTER_PASSWORD=&apos;复制用户密码&apos;,
    MASTER_LOG_FILE=&apos;新主库当前的二进制日志文件名&apos;,
    MASTER_LOG_POS=新主库当前的二进制日志位置;
-- 启动复制进程
START SLAVE;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;自动化故障切换&lt;/h3&gt;
&lt;p&gt;为了提高故障切换的效率和准确性，可以使用一些自动化工具来实现故障切换，例如 MHA（Master High Availability）、PXC（Percona XtraDB Cluster）等。这些工具可以自动检测主库的故障，并在主库宕机时自动进行故障切换，减少人工干预的时间和错误。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@master /]# cat  /usr/local/mysql/my.cnf 
[mysqld]
basedir=/usr/local/mysql                    # MySQL安装目录
datadir=/usr/local/mysql/data               # 数据文件存储目录
socket=/tmp/mysql.sock                      # 本地连接使用的socket文件
port=3306                                   # 服务监听端口
log_error=/usr/local/mysql/data/master.err  # 指定错误日志文件的路径。错误日志记录了MySQL启动、运行和停止过程中的错误信息。
log_bin=/usr/local/mysql/data/binlog        # 指定二进制日志（binlog）文件的基本路径和名称。二进制日志记录了所有更改数据的SQL语句（或数据变更），用于主从复制和数据恢复。
server_id=10                                # 设置服务器的唯一标识符，在主从复制拓扑中，每个服务器必须有一个唯一的server_id。
character_set_server=utf8mb4                # 设置服务器默认的字符集为utf8mb4，它支持更广泛的Unicode字符（如emoji表情）
gtid_mode=on                                # 启用全局事务标识符（GTID）模式。GTID为每个事务分配一个全局唯一的标识符，简化了主从复制的管理
log_slave_updates=1                         # 允许从库将其从主库接收到的更新记录到自己的二进制日志中。这通常用于链式复制（例如，A-&amp;gt;B-&amp;gt;C）或备份从库
enforce_gtid_consistency                    # 强制GTID一致性，确保只有能够安全记录GTID的事务才会被执行。这有助于保证复制的可靠性。
# 复制核心参数
log_bin=/usr/local/mysql/data/binlog
relay_log=/usr/local/mysql/data/relaylog
server_id=20
#字符集
character_set_server=utf8mb4
# 可靠性参数
relay_log_recovery = ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
#设置从库只读
read_only=1

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;#我 : 检查下面作业是否有问题&lt;/p&gt;
&lt;h2&gt;六、作业&lt;/h2&gt;
&lt;h3&gt;选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;在 MySQL 主从复制中，主服务器记录数据变更的二进制日志文件是（ A ）。
A. binlog
B. relay-bin
C. binlog.index
D. relay-bin.log&lt;/li&gt;
&lt;li&gt;若要开启 MySQL 主从复制，主从服务器的以下哪个参数必须不同（ A ）。
A. server-id
B. log-bin
C. sync-binlog
D. relay-log&lt;/li&gt;
&lt;li&gt;MySQL 主从复制中，从服务器将接收到的主服务器 binlog 日志写入的文件是（ B ）。
A. binlog
B. relay log
C. binlog.index
D. relay-bin.log&lt;/li&gt;
&lt;li&gt;主从复制中，主库执行写操作后，以下哪个线程负责把 binlog 的内容发送到从库（ A ）。
A. binlog dump thread
B. I/O 线程
C. SQL 线程
D. log dump 线程&lt;/li&gt;
&lt;li&gt;MySQL 主从复制采用异步复制时，可能出现的问题是（ A ）。
A. 数据丢失
B. 性能严重下降
C. 无法实现复制
D. 主从服务器无法连接&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;简述 MySQL 主从复制的基本原理。
答：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;主库将数据变更（DDL和DML）记录到二进制日志（binlog）中。&lt;/li&gt;
&lt;li&gt;从库的I/O线程向主库的binlog dump线程请求binlog。&lt;/li&gt;
&lt;li&gt;主库的binlog dump线程将binlog事件发送给从库的I/O线程。&lt;/li&gt;
&lt;li&gt;从库的I/O线程将接收到的事件写入中继日志（relay log）。&lt;/li&gt;
&lt;li&gt;从库的SQL线程读取并解析relay log中的事件，在从库上执行这些事件，从而使从库与主库的数据保持同步。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;列举 MySQL 主从复制中 binlog 的三种格式，并说明各自特点。
答：
binlog的三种格式，&lt;code&gt;STATEMENT&lt;/code&gt;（语句级）、&lt;code&gt;ROW&lt;/code&gt;（行级）和 &lt;code&gt;MIXED&lt;/code&gt;（混合级）
&lt;code&gt;STATEMENT&lt;/code&gt;（语句级）：日志量小、可读性高
&lt;code&gt;ROW&lt;/code&gt;（行级）：复制一致性高、并发复制性能好
&lt;code&gt;MIXED&lt;/code&gt;（混合级）：灵活性高、性能和一致性的平衡&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;主从复制中，若主库宕机，应如何进行故障切换以保证业务继续运行？
答：
1、确认主库宕机之后，第一时间选择一个从库作为新主库以承接服务
2、停止新主库上的从库配置改为主库，同事配置其它从库指向新主库
3、更新业务服务的数据库配置指向新主库&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;请详细描述搭建一主一从 MySQL 主从复制环境的步骤，包括主从服务器的配置、用户创建、同步启动等。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;# 清理mariadb
[root@master ~]# rpm -qa | grep mariadb | xargs rpm -e --nodeps
# 基本环境安装
[root@master ~]# yum install -y libaio-devel numactl wget
# 下载安装官方源
[root@master ~]# wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
[root@master ~]# rpm -ivh mysql80-community-release-el7-3.noarch.rpm
# 下载并导入 MySQL 官方 GPG 密钥 
[root@master ~]# rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023
[root@master ~]# yum repolist enabled | grep mysql
mysql-connectors-community/x86_64       MySQL Connectors Community           293
mysql-tools-community/x86_64            MySQL Tools Community                118
mysql80-community/x86_64                MySQL 8.0 Community Server           598
[root@master ~]# 

# 主从安装mysql服务
[root@master ~]# yum install -y mysql-community-server 
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
Resolving Dependencies
--&amp;gt; Running transaction check
---&amp;gt; Package mysql-community-server.x86_64 0:8.0.44-1.el7 will be installed
--&amp;gt; Processing Dependency: mysql-community-common(x86-64) = 8.0.44-1.el7 for package: mysql-community-server-8.0.44-1.el7.x86_64
--&amp;gt; Processing Dependency: mysql-community-icu-data-files = 8.0.44-1.el7 for package: mysql-community-server-8.0.44-1.el7.x86_64
--&amp;gt; Processing Dependency: mysql-community-client(x86-64) &amp;gt;= 8.0.11 for package: mysql-community-server-8.0.44-1.el7.x86_64

# 配置主库，指定server_id和开启binlog日记
[root@master ~]# grep -vE &quot;#&quot; /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

server_id=10
log_bin=/var/lib/mysql/binlog


#启动和添加开机启动mysql服务
[root@master /]# systemctl enable mysqld
[root@master /]# systemctl status mysqld



[root@master /]# mysql -uroot -p
........
# 第一次登陆需先修改默认密码
mysql&amp;gt; alter user &apos;root&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;mysql123!&apos;;
Query OK, 0 rows affected (0.01 sec)

# 创建用户同步的repluser账号密码repluser
mysql&amp;gt; create user repluser@&quot;%&quot; identified WITH mysql_native_password by &quot;repluser&quot;;
Query OK, 0 rows affected (0.09 sec)
# 给repluser用户赋权
mysql&amp;gt; grant replication slave on *.*  to repluser@&quot;%&quot;;
Query OK, 0 rows affected (0.05 sec)
# 查询binlog名称和偏移量
mysql&amp;gt; show  master status;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000002 |     1307 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)





# 从库安装mysql服务
# 清理mariadb
[root@slave1 ~]# rpm -qa | grep mariadb | xargs rpm -e --nodeps
# 基本环境安装
[root@slave1 ~]# yum install -y libaio-devel numactl wget
# 下载安装官方源
[root@slave1 ~]# wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
[root@slave1 ~]# rpm -ivh mysql80-community-release-el7-3.noarch.rpm
# 下载并导入 MySQL 官方 GPG 密钥 
[root@slave1 ~]# rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023
[root@slave1 ~]# yum repolist enabled | grep mysql
mysql-connectors-community/x86_64       MySQL Connectors Community           293
mysql-tools-community/x86_64            MySQL Tools Community                118
mysql80-community/x86_64                MySQL 8.0 Community Server           598
[root@slave1 ~]# 

# 主从安装mysql服务
[root@slave1 ~]# yum install -y mysql-community-server 
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
Resolving Dependencies
--&amp;gt; Running transaction check
---&amp;gt; Package mysql-community-server.x86_64 0:8.0.44-1.el7 will be installed
--&amp;gt; Processing Dependency: mysql-community-common(x86-64) = 8.0.44-1.el7 for package: mysql-community-server-8.0.44-1.el7.x86_64
--&amp;gt; Processing Dependency: mysql-community-icu-data-files = 8.0.44-1.el7 for package: mysql-community-server-8.0.44-1.el7.x86_64
--&amp;gt; Processing Dependency: mysql-community-client(x86-64) &amp;gt;= 8.0.11 for package: mysql-community-server-8.0.44-1.el7.x86_64



# 配置从库，指定server_id和开启binlog日记
[root@slave1 ~]# vim /etc/my.cnf
[root@slave1 ~]# grep -vE &quot;#&quot; /etc/my.cnf

[mysqld]

datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

server_id=20
log_bin=/var/lib/mysql/binlog
relay_log=/var/lib/mysql/relaylog

[root@slave1 ~]# systemctl enable mysqld
[root@slave1 ~]# systemctl start mysqld

# 从库配置
# 修改默认密码
mysql&amp;gt; alter user &apos;root&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;Mysql123!&apos;;
Query OK, 0 rows affected (0.01 sec)

# 配置 MySQL 主从复制
mysql&amp;gt; change  master to  master_host=&quot;192.168.99.10&quot; , master_user=&quot;repluser&quot; , master_password=&quot;repluser&quot; ,master_log_file=&quot;binlog.000002&quot; , master_log_pos=1307;
Query OK, 0 rows affected, 8 warnings (0.06 sec)

# 启动slave进程
mysql&amp;gt; start slave ;
Query OK, 0 rows affected, 1 warning (0.32 sec)

# 同步查看状态信息
mysql&amp;gt; show slave status \G  
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: 192.168.99.10
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000002
          Read_Master_Log_Pos: 1307
               Relay_Log_File: relaylog.000002
                Relay_Log_Pos: 323
        Relay_Master_Log_File: binlog.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 


# 测试

# 在主服务器创建text数据库
mysql&amp;gt; create database text;
Query OK, 1 row affected (0.06 sec)

# 从库查看是否同步
mysql&amp;gt; show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| text               |
+--------------------+
5 rows in set (0.06 sec)


&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;假设已有一主多从的 MySQL 主从复制环境，现在需要新增一个从服务器，写出具体操作步骤。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;# 查看主库当前binlog和偏移量
mysql&amp;gt; show  master status;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000002 |     1492 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.04 sec)


# 从库安装mysql服务
# 清理mariadb
[root@slave1 ~]# rpm -qa | grep mariadb | xargs rpm -e --nodeps
# 基本环境安装
[root@slave1 ~]# yum install -y libaio-devel numactl wget
# 下载安装官方源
[root@slave1 ~]# wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
[root@slave1 ~]# rpm -ivh mysql80-community-release-el7-3.noarch.rpm
# 下载并导入 MySQL 官方 GPG 密钥 
[root@slave1 ~]# rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023
[root@slave1 ~]# yum repolist enabled | grep mysql
mysql-connectors-community/x86_64       MySQL Connectors Community           293
mysql-tools-community/x86_64            MySQL Tools Community                118
mysql80-community/x86_64                MySQL 8.0 Community Server           598
[root@slave1 ~]# 

# 主从安装mysql服务
[root@slave1 ~]# yum install -y mysql-community-server 
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
Resolving Dependencies
--&amp;gt; Running transaction check
---&amp;gt; Package mysql-community-server.x86_64 0:8.0.44-1.el7 will be installed
--&amp;gt; Processing Dependency: mysql-community-common(x86-64) = 8.0.44-1.el7 for package: mysql-community-server-8.0.44-1.el7.x86_64
--&amp;gt; Processing Dependency: mysql-community-icu-data-files = 8.0.44-1.el7 for package: mysql-community-server-8.0.44-1.el7.x86_64
--&amp;gt; Processing Dependency: mysql-community-client(x86-64) &amp;gt;= 8.0.11 for package: mysql-community-server-8.0.44-1.el7.x86_64



# 配置从库，指定server_id和开启binlog日记
[root@slave1 ~]# vim /etc/my.cnf
[root@slave1 ~]# grep -vE &quot;#&quot; /etc/my.cnf

[mysqld]

datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

server_id=30
log_bin=/var/lib/mysql/binlog
relay_log=/var/lib/mysql/relaylog

[root@slave1 ~]# systemctl enable mysqld
[root@slave1 ~]# systemctl start mysqld

# 从库配置
# 修改默认密码
mysql&amp;gt; alter user &apos;root&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;Mysql123!&apos;;
Query OK, 0 rows affected (0.01 sec)

# 配置 MySQL 主从复制
mysql&amp;gt; change  master to  master_host=&quot;192.168.99.10&quot; , master_user=&quot;repluser&quot; , master_password=&quot;repluser&quot; ,master_log_file=&quot;binlog.000002&quot; , master_log_pos=1492;
Query OK, 0 rows affected, 8 warnings (0.04 sec)

# 启动slave进程
mysql&amp;gt; start slave;
Query OK, 0 rows affected, 1 warning (0.63 sec)

# 同步查看状态信息
mysql&amp;gt; show slave status \G  
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: 192.168.99.10
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000002
          Read_Master_Log_Pos: 1492
               Relay_Log_File: relaylog.000002
                Relay_Log_Pos: 323
        Relay_Master_Log_File: binlog.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

# 测试

# 在主服务器创建text数据库
mysql&amp;gt; create database text2;
Query OK, 1 row affected (0.09 sec)

# 从库1 查看是否同步
mysql&amp;gt; show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| text               |
| text2              |
+--------------------+
6 rows in set (0.12 sec)

# 新增从库2 查看是否同步
mysql&amp;gt; show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| text2              |
+--------------------+
5 rows in set (0.02 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;#Doubao : 以下是对这份作业的详细检查分析：&lt;/p&gt;
&lt;h3&gt;选择题&lt;/h3&gt;
&lt;p&gt;所有选择题答案均正确，对 MySQL 主从复制的基本概念掌握较好。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;第 1 题&lt;/strong&gt;：主服务器记录数据变更的二进制日志文件是 &lt;code&gt;binlog&lt;/code&gt;，选项 A 正确。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 2 题&lt;/strong&gt;：在 MySQL 主从复制中，主从服务器的 &lt;code&gt;server-id&lt;/code&gt; 必须不同，用于唯一标识每个服务器，选项 A 正确。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 3 题&lt;/strong&gt;：从服务器将接收到的主服务器 &lt;code&gt;binlog&lt;/code&gt; 日志写入 &lt;code&gt;relay log&lt;/code&gt;，选项 B 正确。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 4 题&lt;/strong&gt;：主库执行写操作后，&lt;code&gt;binlog dump thread&lt;/code&gt; 负责把 &lt;code&gt;binlog&lt;/code&gt; 的内容发送到从库，选项 A 正确。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 5 题&lt;/strong&gt;：MySQL 主从复制采用异步复制时，主库不等待从库确认，可能出现数据丢失的问题，选项 A 正确。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;简答题&lt;/h3&gt;
&lt;h4&gt;1. 简述 MySQL 主从复制的基本原理&lt;/h4&gt;
&lt;p&gt;答案准确完整，清晰地阐述了 MySQL 主从复制的基本流程，包括主库记录 &lt;code&gt;binlog&lt;/code&gt;、从库请求和接收 &lt;code&gt;binlog&lt;/code&gt;、写入中继日志以及执行事件等步骤。&lt;/p&gt;
&lt;h4&gt;2. 列举 MySQL 主从复制中 binlog 的三种格式，并说明各自特点&lt;/h4&gt;
&lt;p&gt;答案基本正确，但不够详细。对于每种格式的优缺点可以进一步展开说明，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;STATEMENT&lt;/code&gt;（语句级）&lt;/strong&gt;：日志量小、可读性高，但部分依赖主库环境的 SQL 语句（如含 &lt;code&gt;NOW()&lt;/code&gt;、&lt;code&gt;UUID()&lt;/code&gt; 等函数）可能导致主从复制不一致，在高并发场景下并发复制性能受限。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;ROW&lt;/code&gt;（行级）&lt;/strong&gt;：复制一致性高、并发复制性能好，但日志量大，可读性差，对于大规模数据更新操作会增加磁盘 I/O 和网络传输负担。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;MIXED&lt;/code&gt;（混合级）&lt;/strong&gt;：灵活性高、性能和一致性的平衡，会根据具体 SQL 语句自动选择 &lt;code&gt;STATEMENT&lt;/code&gt; 或 &lt;code&gt;ROW&lt;/code&gt; 格式，但难以预测具体使用的日志格式，增加了故障排查和管理难度。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;3. 主从复制中，若主库宕机，应如何进行故障切换以保证业务继续运行&lt;/h4&gt;
&lt;p&gt;答案步骤不够详细，可能会导致实际操作时出现问题。可以补充以下内容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;确认主库宕机&lt;/strong&gt;：通过监控系统、日志或者手动检查等方式，确认主库确实无法正常工作。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;选择新的主库&lt;/strong&gt;：考虑数据同步情况（查看 &lt;code&gt;Seconds_Behind_Master&lt;/code&gt;）和硬件资源，选择合适的从库作为新主库。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;停止从库复制&lt;/strong&gt;：在选定的从库上执行 &lt;code&gt;STOP SLAVE&lt;/code&gt; 命令。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;提升从库为新主库&lt;/strong&gt;：执行 &lt;code&gt;RESET MASTER&lt;/code&gt; 命令。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配置其他从库指向新主库&lt;/strong&gt;：在每个从库上执行 &lt;code&gt;CHANGE MASTER TO&lt;/code&gt; 命令，更新主库连接信息，然后执行 &lt;code&gt;START SLAVE&lt;/code&gt; 命令。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;更新应用程序配置&lt;/strong&gt;：将应用程序连接的数据库地址从原主库更新为新主库的地址。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;恢复原主库&lt;/strong&gt;：对原主库进行故障排查和修复，修复完成后将其配置为新主库的从库。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;操作题&lt;/h3&gt;
&lt;h4&gt;1. 请详细描述搭建一主一从 MySQL 主从复制环境的步骤，包括主从服务器的配置、用户创建、同步启动等&lt;/h4&gt;
&lt;p&gt;整体步骤基本正确，但存在一些小问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;数据库名拼写错误&lt;/strong&gt;：在测试部分创建数据库时，写成了 &lt;code&gt;text&lt;/code&gt;，推测可能是想写 &lt;code&gt;test&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺少权限刷新&lt;/strong&gt;：在主库创建用户并赋权后，应执行 &lt;code&gt;FLUSH PRIVILEGES&lt;/code&gt; 命令使权限生效。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;日志记录&lt;/strong&gt;：在安装和配置过程中，应检查命令执行结果，确保没有报错，并且可以记录关键步骤的日志，方便后续排查问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;2. 假设已有一主多从的 MySQL 主从复制环境，现在需要新增一个从服务器，写出具体操作步骤&lt;/h4&gt;
&lt;p&gt;整体步骤基本正确，同样存在以下问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;数据库名拼写错误&lt;/strong&gt;：同第一题，测试部分创建数据库写成 &lt;code&gt;text2&lt;/code&gt;，可能是 &lt;code&gt;test2&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺少权限刷新&lt;/strong&gt;：在主库创建用户并赋权后，应执行 &lt;code&gt;FLUSH PRIVILEGES&lt;/code&gt; 命令使权限生效。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;日志记录&lt;/strong&gt;：在安装和配置过程中，应检查命令执行结果，确保没有报错，并且可以记录关键步骤的日志，方便后续排查问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;综上所述，作业对 MySQL 主从复制的基本概念和操作有较好的理解，但在一些细节和完整性方面还有提升空间。&lt;/p&gt;
</content:encoded></item><item><title>10：mysql之读写分离</title><link>https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/10-mysql%E4%B9%8B%E8%AF%BB%E5%86%99%E5%88%86%E7%A6%BB/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/10-mysql%E4%B9%8B%E8%AF%BB%E5%86%99%E5%88%86%E7%A6%BB/</guid><description>10：mysql之读写分离 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 05:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1&gt;10：mysql之读写分离&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/10-mysql%E4%B9%8B%E8%AF%BB%E5%86%99%E5%88%86%E7%A6%BB/image-20250616174238077.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;MySQL读写分离在多种工作场景中优势明显。在高并发读场景里，如电商平台商品浏览、社交媒体内容加载，大量读请求可由从库处理，减轻主库压力，提升系统响应速度 。对于数据实时性要求低的报表生成、数据分析场景，允许主从短暂延迟，能充分发挥读写分离的优势 。在容灾与备份方面，从库可作为主库实时备份，主库故障时能快速切换，保障业务持续运行 。另外，全球分布式架构中，将读操作路由到离用户近的从库，可减少网络延迟。&lt;/p&gt;
&lt;h2&gt;二、为什么学&lt;/h2&gt;
&lt;p&gt;学习 MySQL 读写分离很有必要。在高并发场景下，数据库面临大量读写请求，读写分离可将读操作分配到从库，有效减轻主库压力，提升系统整体性能与响应速度。对于有海量数据处理需求的企业，能提升业务处理效率。它还能增强系统的可扩展性，可通过增加从库数量来应对不断增长的读请求。在数据备份与恢复方面，从库可充当主库的实时副本，一旦主库出现故障，能快速恢复数据，保障业务连续性。掌握这一技术，有助于提升数据库管理和运维能力。&lt;/p&gt;
&lt;h2&gt;三、准备环境&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/10-mysql%E4%B9%8B%E8%AF%BB%E5%86%99%E5%88%86%E7%A6%BB/image-20250616174302014.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3.1 准备新的虚拟机&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;mysql56&lt;/td&gt;
&lt;td&gt;192.168.90.56&lt;/td&gt;
&lt;td&gt;master【马斯特】数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mysql57&lt;/td&gt;
&lt;td&gt;192.168.90.57&lt;/td&gt;
&lt;td&gt;slave【斯累夫】数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mycat58&lt;/td&gt;
&lt;td&gt;192.168.90.58&lt;/td&gt;
&lt;td&gt;读写分离服务&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;mysql56配置IP地址和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.56/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mysql56 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql56
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mysql57配置IP地址和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.57/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mysql57 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql57
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mycat58配置IP地址和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.58/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mycat ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mycat58
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 读写分离原理&lt;/h3&gt;
&lt;p&gt;Mycat【麦-凯特】 读写分离原理基于对 MySQL 主从复制的利用。
Mycat【麦-凯特】 作为中间件，介于应用程序和 MySQL 数据库之间。
当应用程序发起 SQL 请求时，Mycat【麦-凯特】 会根据 SQL 语句类型进行判断。对于读操作，如 SELECT【涩莱克特】 语句，Mycat【麦-凯特】 将请求路由到从库处理，从库可有多台，能实现负载均衡，以此减轻主库读压力。而对于写操作，如 INSERT【因涩特】、UPDATE【阿普 dei 特】、DELETE【迪  利 特】 语句，Mycat【麦-凯特】 会将请求转发到主库，确保数据写入的一致性。
主库数据更新后，通过 MySQL 主从复制机制同步到从库，保证数据的实时性和准确性。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/10-mysql%E4%B9%8B%E8%AF%BB%E5%86%99%E5%88%86%E7%A6%BB/image-20250616170530176.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;四、搭建一主一从结构&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/10-mysql%E4%B9%8B%E8%AF%BB%E5%86%99%E5%88%86%E7%A6%BB/image-20250616174211732.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;因为数据的查询和存储分别访问不同的数据库服务器，所以要通过主从同步来保证负责读访问的服务与负责写访问的服务器数据一致。&lt;/p&gt;
&lt;h3&gt;4.1 配置主数据库服务器&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql56 ~]# yum -y  install【因-斯多】  mysql-server mysql
[root@mysql56 ~]#  systemctl【西斯屯-ctl】  start【s 达儿】 mysqld

# 启用binlog日志
[root@mysql56 ~]# vim /etc/my.cnf.d/mysql-server.cnf
# [root@mysql56 ~]# vim /etc/my.cnf
[mysqld]
server-id=56
log-bin=mysql56
:wq

[root@mysql56 ~]#  systemctl【西斯屯-ctl】 restart【 率 s 达r】 mysqld
# [root@mysql56 ~]# systemctl restart mysqld

# 用户授权
[root@mysql56 ~]# mysql
# [root@mysql56 ~]# mysql -uroot -p123

mysql&amp;gt; create【克瑞特】 user repluser@&quot;%&quot;  identified【爱-丹-提伐】 with【威付】 mysql_native_password by【拜】  &quot;123qqq...A&quot;;
# mysql&amp;gt; create user repluser@&apos;%&apos; identified with mysql_native_password by &apos;repluser&apos;;
# Query OK, 0 rows affected (0.26 sec)

mysql&amp;gt;  grant【古亮普】 replication【瑞普利K申】 slave【斯累夫】 on  *.* to  repluser@&quot;%&quot; ;
# mysql&amp;gt; grant replication slave on *.* to repluser@&apos;%&apos;;
# Query OK, 0 rows affected (0.15 sec)

# 查看日志信息
mysql&amp;gt; show【瘦】 master【马斯特】 status【 斯dèi 特斯】;
# mysql&amp;gt; show master status;
# +----------------+----------+--------------+------------------+-------------------+
# | File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
# +----------------+----------+--------------+------------------+-------------------+
# | mysql56.000001 |      668 |              |                  |                   |
# +----------------+----------+--------------+------------------+-------------------+
# 1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 配置从数据库服务器&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 指定server-id 并重启数据库服务
[root@mysql57 ~]# yum -y install【因-斯多】 mysql-server mysql
[root@mysql57 ~]# systemctl【西斯屯-ctl】 start【s 达儿】 mysqld
[root@mysql57 ~]# vim /etc/my.cnf.d/mysql-server.cnf
# [root@mysql57 ~]# vim /etc/my.cnf
[mysqld]
server-id=57
:wq

[root@mysql57 ~]#  systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld
# [root@mysql57 ~]# systemctl restart mysqld

# 管理员登陆，指定主服务器信息
[root@mysql57 ~]# mysql
# [root@mysql57 ~]# mysql -uroot -p123

mysql&amp;gt; change【趁(chèn)吉】 master【马斯特】 to master【马斯特】_host=&quot;192.168.90.56&quot;, master【马斯特】_user=&quot;repluser&quot;, master【马斯特】_password=&quot;123qqq...A&quot;, master【马斯特】_log_file=&quot;mysql56.000001&quot;,master【马斯特】_log_pos=667;
# mysql&amp;gt; change master to master_host=&apos;192.168.88.10&apos;,master_user=&apos;repluser&apos;,master_password=&apos;repluser&apos;,master_log_file=&quot;mysql56.000001&quot;,master_log_pos=668;
# Query OK, 0 rows affected, 8 warnings (9.74 sec)

# 启动slave【斯累夫】进程
mysql&amp;gt;  start【s 达儿】 slave【斯累夫】;
# mysql&amp;gt; start slave;
# Query OK, 0 rows affected, 1 warning (0.95 sec)

# 查看状态信息
mysql&amp;gt; show【瘦】 slave【斯累夫】 status【 斯dèi 特斯】 \G
# mysql&amp;gt; show slave status \G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: 192.168.90.56
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql56.000001
          Read_Master_Log_Pos: 667
               Relay_Log_File: mysql57-relay-bin.000002
                Relay_Log_Pos: 322
        Relay_Master_Log_File: mysql56.000001
             Slave_IO_Running: Yes   //IO线程
            Slave_SQL_Running: Yes   //SQL线程
              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: 667
              Relay_Log_Space: 533
              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: 56
                  Master_UUID: e0ab8dc4-0109-11ee-87e7-525400ad7ed3
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates【阿普 dei 特s】
           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: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set, 1 warning (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、配置mycat【麦-凯特】服务器&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/10-mysql%E4%B9%8B%E8%AF%BB%E5%86%99%E5%88%86%E7%A6%BB/image-20250616174346754.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;5.1 拷贝软件到mycat【麦-凯特】58主机&lt;/h3&gt;
&lt;p&gt;mycat2-1.21-release-jar-with-dependencies.jar&lt;/p&gt;
&lt;p&gt;mycat2**-&lt;strong&gt;install&lt;/strong&gt;-**template-1.21.zip&lt;/p&gt;
&lt;h3&gt;5.2 安装mycat【麦-凯特】软件&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 安装jdk
[root@mycat58 upload]# yum -y install【因-斯多】 java-1.8.0-openjdk.x86_64
# [root@mycat58 ~]# yum -y install java-1.8.0-openjdk.x86_64
# 安装解压命令
[root@mycat58 upload]# which【维曲】 unzip || yum -y  install【因-斯多】 unzip
# [root@mycat58 ~]# which unzip || yum -y install unzip
# 安装mycat
[root@mycat58 upload]# unzip mycat2-install-template-1.21.zip
# [root@mycat58 ~]# unzip mycat2-install-template-1.21.zip 
[root@mycat58 upload]# mv mycat【麦-凯特】 /usr/local/
# [root@mycat58 ~]# mv mycat /usr/local/
# 安装依赖
[root@mycat58 upload]# cp mycat2-1.21-release-jar-with-dependencies.jar  /usr/local/mycat/lib/
# [root@mycat58 ~]# cp mycat2-1.21-release-jar-with-dependencies.jar /usr/local/mycat/lib/
# 修改权限
[root@mycat58 upload]# chmod -R 777 /usr/local/mycat/ 
# [root@mycat58 ~]# chmod -R 777 /usr/local/mycat/ 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.3 配置mycat【麦-凯特】密码&lt;/h3&gt;
&lt;p&gt;定义客户端连接mycat【麦-凯特】服务使用用户及密码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# vim  /usr/local/mycat/conf/users/root.user.json
{
        &quot;dialect&quot;:&quot;mysql&quot;,
        &quot;ip&quot;:null,
        &quot;password&quot;:&quot;654321&quot;, 密码
        &quot;transactionType&quot;:&quot;proxy&quot;,
        &quot;username&quot;:&quot;mycat&quot; 用户名
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mycat【麦-凯特】连接本机数据库配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# vim /usr/local/mycat/conf/datasources/prototypeDs.datasource.json
{
        &quot;dbType&quot;:&quot;mysql&quot;,
        &quot;idleTimeout&quot;:60000,
        &quot;initSqls&quot;:[],
        &quot;initSqlsGetConnection&quot;:true,
        &quot;instanceType&quot;:&quot;READ_WRITE&quot;,
        &quot;maxCon&quot;:1000,
        &quot;maxConnectTimeout&quot;:3000,
        &quot;maxRetryCount&quot;:5,
        &quot;minCon&quot;:1,
        &quot;name&quot;:&quot;prototypeDs&quot;,
        &quot;password&quot;:&quot;123456&quot;, 密码
        &quot;type&quot;:&quot;JDBC&quot;,
        &quot;url&quot;:&quot;jdbc:mysql://localhost:3306/mysql?useUnicode=true&amp;amp;serverTimezone=Asia/Shanghai&amp;amp;characterEncoding=UTF-8&quot;, 连接本机的数据库服务
        &quot;user&quot;:&quot;jam&quot;, 用户名
        &quot;weight&quot;:0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.4 mycat58主机mysql安装&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#  安装软件
[root@mycat58 ~]# yum -y  install【因-斯多】  mysql-server  mysql
# 启动服务
[root@mycat58 ~]#  systemctl【西斯屯-ctl】  start【s 达儿】 mysqld
#  连接服务
[root@mycat58 ~]# mysql 
# [root@mycat58 ~]# mysql -uroot -p123

#  创建jam用户
mysql&amp;gt; create【克瑞特】 user jam@&quot;%&quot;  identified【爱-丹-提伐】 by【拜】 &quot;123456&quot;;
# mysql&amp;gt; create user jam@&apos;%&apos; identified by &apos;123456&apos;;
# Query OK, 0 rows affected (0.52 sec)

#  授予权限
mysql&amp;gt;  grant【古亮普】 all on *.* to jam@&quot;%&quot; ;
# mysql&amp;gt; grant all on *.* to jam@&apos;%&apos;;
# Query OK, 0 rows affected (1.14 sec)

# 断开连接
mysql&amp;gt;  exit【诶西特】
# mysql&amp;gt; exit
Bye
[root@mycat58 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.5 mycat【麦-凯特】服务启动和连接&lt;/h3&gt;
&lt;p&gt;启动mycat【麦-凯特】服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# /usr/local/mycat/bin/mycat help
# [root@mycat58 ~]# /usr/local/mycat/bin/mycat help
Usage: /usr/local/mycat/bin/mycat { console |  start【s 达儿】 | stop | restart【 率 s 达r】 | status【 斯dèi 特斯】 | dump }

[root@mycat58 ~]# /usr/local/mycat/bin/mycat start
# [root@mycat58 ~]# /usr/local/mycat/bin/mycat start
# Starting mycat2...

# 半分钟左右 能看到端口
[root@mycat58 ~]# netstat  -utnlp  | grep 8066
# [root@mycat58 ~]# netstat -tunlp | grep 8066
# tcp6       0      0 :::8066                 :::*                    LISTEN      30687/java          
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;连接mycat【麦-凯特】服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321
# [root@mycat58 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321

mysql&amp;gt; show【瘦】 databases;
# mysql&amp;gt; show databases;
+--------------------+
| `Database`         |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.11 sec)
Mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、配置读写分离&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/10-mysql%E4%B9%8B%E8%AF%BB%E5%86%99%E5%88%86%E7%A6%BB/image-20250616174409311.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;6.1 添加数据源&lt;/h3&gt;
&lt;p&gt;添加数据源：连接mycat【麦-凯特】服务后做如下操作&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 连接mycat【麦-凯特】服务
[root@mycat58 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321
# [root@mycat58 ~]# mysql -h 127.0.0.1 -P8066 -umycat -p654321

# 添加mysql56数据库服务器
MySQL&amp;gt; /*+ mycat:createdatasource{
&quot;name&quot;:&quot;whost56&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.90.56:3306&quot;,&quot;user&quot;:&quot;jama&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;whost56&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.10:3306&quot;,&quot;user&quot;:&quot;jama&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# Query OK, 0 rows affected (0.86 sec)

# 添加mysql57数据库服务器
Mysql&amp;gt;/*+ mycat:createdatasource{
&quot;name&quot;:&quot;rhost57&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.90.57:3306&quot;,&quot;user&quot;:&quot;jama&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;rhost57&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.20:3306&quot;,&quot;user&quot;:&quot;jama&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# Query OK, 0 rows affected (0.06 sec)

# 查看数据源
mysql&amp;gt; /*+mycat:showDataSources{}*/ \G
# mysql&amp;gt; /*+mycat:showDataSources{}*/ \G
*************************** 1. row ***************************
                   NAME: whost56
               USERNAME: jama
               PASSWORD: 123456
                MAX_CON: 1000
                MIN_CON: 1
              EXIST_CON: 0
                USE_CON: 0
        MAX_RETRY_COUNT: 5
    MAX_CONNECT_TIMEOUT: 30000
                DB_TYPE: mysql
                    URL: jdbc:mysql://192.168.90.56:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
                 WEIGHT: 0
               INIT_SQL: 
INIT_SQL_GET_CONNECTION: true
          INSTANCE_TYPE: READ_WRITE
           IDLE_TIMEOUT: 60000
                 DRIVER: {
        CreateTime:&quot;2023-06-02 17:01:14&quot;,
        ActiveCount:0,
        PoolingCount:0,
        CreateCount:0,
        DestroyCount:0,
        CloseCount:0,
        ConnectCount:0,
        Connections:[
        ]
}
                   TYPE: JDBC
               IS_MYSQL: true
*************************** 2. row ***************************
                   NAME: rhost57
               USERNAME: jama
               PASSWORD: 123456
                MAX_CON: 1000
                MIN_CON: 1
              EXIST_CON: 0
                USE_CON: 0
        MAX_RETRY_COUNT: 5
    MAX_CONNECT_TIMEOUT: 30000
                DB_TYPE: mysql
                    URL: jdbc:mysql://192.168.90.57:3306?useUnicode=true&amp;amp;serverTimezone=Asia/Shanghai&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
                 WEIGHT: 0
               INIT_SQL: 
INIT_SQL_GET_CONNECTION: true
          INSTANCE_TYPE: READ_WRITE
           IDLE_TIMEOUT: 60000
                 DRIVER: {
        CreateTime:&quot;2023-06-02 17:01:14&quot;,
        ActiveCount:0,
        PoolingCount:0,
        CreateCount:0,
        DestroyCount:0,
        CloseCount:0,
        ConnectCount:0,
        Connections:[
        ]
}
                   TYPE: JDBC
               IS_MYSQL: true
*************************** 3. row ***************************
                   NAME: prototypeDs
               USERNAME: jam
               PASSWORD: 123456
                MAX_CON: 1000
                MIN_CON: 1
              EXIST_CON: 0
                USE_CON: 0
        MAX_RETRY_COUNT: 5
    MAX_CONNECT_TIMEOUT: 3000
                DB_TYPE: mysql
                    URL: jdbc:mysql://localhost:3306/mysql?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
                 WEIGHT: 0
               INIT_SQL: 
INIT_SQL_GET_CONNECTION: true
          INSTANCE_TYPE: READ_WRITE
           IDLE_TIMEOUT: 60000
                 DRIVER: {
        CreateTime:&quot;2023-06-02 17:01:14&quot;,
        ActiveCount:0,
        PoolingCount:0,
        CreateCount:0,
        DestroyCount:0,
        CloseCount:0,
        ConnectCount:0,
        Connections:[
        ]
}
                   TYPE: JDBC
               IS_MYSQL: true
3 rows in set (0.00 sec)
mysql&amp;gt;

# 添加的数据源以文件的形式保存在安装目录下
[root@mycat58 conf]# ls /usr/local/mycat/conf/datasources/
# [root@mycat58 ~]# ls /usr/local/mycat/conf/datasources/
# prototypeDs.datasource.json  rhost57.datasource.json  whost56.datasource.json

[root@mycat58 conf]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.2 配置数据库服务器添加jama用户&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 在master【马斯特】服务器添加
[root@mysql56 ~]# mysql 

mysql&amp;gt; create【克瑞特】 user jama@&quot;%&quot;  identified【爱-丹-提伐】 by【拜】 &quot;123456&quot;;
# mysql&amp;gt; create user jama@&quot;%&quot;  identified by &quot;123456&quot;;
# Query OK, 0 rows affected (0.24 sec)

mysql&amp;gt;  grant【古亮普】 all on *.* to  jama@&quot;%&quot;;
# mysql&amp;gt; grant  all on *.* to  jama@&quot;%&quot;;
# Query OK, 0 rows affected (0.19 sec)

mysql&amp;gt; exit【诶西特】
[root@mysql56 ~]#

# 在slave【斯累夫】服务器查看是否同步成功
[root@mysql57 ~]# mysql -e &apos;select【涩莱克特】 user , host from【弗乱】 mysql.user where user=&quot;jama&quot;&apos;
+------+------+
| user | host |
+------+------+
| jama | %    |
+------+------+
[root@mysql57 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.3 创建集群&lt;/h3&gt;
&lt;p&gt;创建集群,连接mycat【麦-凯特】服务后做如下配置:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321

# 创建集群
mysql&amp;gt;/*!mycat:createcluster{
&quot;name&quot;:&quot;rwcluster&quot;,
&quot;masters&quot;:[&quot;whost56&quot;],
&quot;replicas&quot;:[&quot;rhost57&quot;]
}*/ ;


# 查看集群信息
mysql&amp;gt; /*+ mycat:showClusters{}*/ \G
*************************** 1. row ***************************
             NAME: rwcluster
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 2000
             TYPE: BALANCE_ALL
         WRITE_DS: whost56
          READ_DS: whost56,rhost57
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
*************************** 2. row ***************************
             NAME: prototype
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 200
             TYPE: BALANCE_ALL
         WRITE_DS: prototypeDs
          READ_DS: prototypeDs
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
2 rows in set (0.00 sec)
mysql&amp;gt;

# 创建的集群以文件的形式保存在目录下
[root@mycat58 conf]# ls /usr/local/mycat/conf/clusters/
prototype.cluster.json  rwcluster.cluster.json
[root@mycat58 conf]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.4 指定主机角色&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 修改master【马斯特】角色主机仅负责写访问
[root@mycat58 ~]# vim /usr/local/mycat/conf/datasources/whost56.datasource.json
{
        &quot;dbType&quot;:&quot;mysql&quot;,
        &quot;idleTimeout&quot;:60000,
        &quot;initSqls&quot;:[],
        &quot;initSqlsGetConnection&quot;:true,
        &quot;instanceType&quot;:&quot;WRITE&quot;, 仅负责写访问
        &quot;logAbandoned&quot;:true,
        &quot;maxCon&quot;:1000,
        &quot;maxConnectTimeout&quot;:30000,
        &quot;maxRetryCount&quot;:5,
        &quot;minCon&quot;:1,
        &quot;name&quot;:&quot;whost56&quot;,
        &quot;password&quot;:&quot;123456&quot;,
        &quot;queryTimeout&quot;:0,
        &quot;removeAbandoned&quot;:false,
        &quot;removeAbandonedTimeoutSecond&quot;:180,
        &quot;type&quot;:&quot;JDBC&quot;,
        &quot;url&quot;:&quot;jdbc:mysql://192.168.90.56:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&quot;,
        &quot;user&quot;:&quot;jama&quot;,
        &quot;weight&quot;:0
}
:wq

# 修改slave【斯累夫】角色主机仅负责读访问
[root@mycat58 ~]# vim /usr/local/mycat/conf/datasources/rhost57.datasource.json
{
        &quot;dbType&quot;:&quot;mysql&quot;,
        &quot;idleTimeout&quot;:60000,
        &quot;initSqls&quot;:[],
        &quot;initSqlsGetConnection&quot;:true,
        &quot;instanceType&quot;:&quot;READ&quot;,仅负责读访问
        &quot;logAbandoned&quot;:true,
        &quot;maxCon&quot;:1000,
        &quot;maxConnectTimeout&quot;:30000,
        &quot;maxRetryCount&quot;:5,
        &quot;minCon&quot;:1,
        &quot;name&quot;:&quot;rhost57&quot;,
        &quot;password&quot;:&quot;123456&quot;,
        &quot;queryTimeout&quot;:0,
        &quot;removeAbandoned&quot;:false,
        &quot;removeAbandonedTimeoutSecond&quot;:180,
        &quot;type&quot;:&quot;JDBC&quot;,
        &quot;url&quot;:&quot;jdbc:mysql://192.168.90.57:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&quot;,
        &quot;user&quot;:&quot;jama&quot;,
        &quot;weight&quot;:0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.5 修改读策略&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;readBalanceType&lt;/code&gt;参数值&lt;/th&gt;
&lt;th&gt;负载均衡策略说明&lt;/th&gt;
&lt;th&gt;行为描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;BALANCE_ALL_READ&lt;/strong&gt;​&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;在所有从库（Replicas）间均衡&lt;/strong&gt;​&lt;/td&gt;
&lt;td&gt;所有的 &lt;code&gt;SELECT&lt;/code&gt;查询请求会在 &lt;code&gt;replicas&lt;/code&gt;列表配置的所有从库上进行负载均衡。写节点（&lt;code&gt;masters&lt;/code&gt;）不参与读流量的分担。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;BALANCE_ALL&lt;/strong&gt;​ (如果支持)&lt;/td&gt;
&lt;td&gt;在所有节点（主和从）间均衡&lt;/td&gt;
&lt;td&gt;读请求会随机地在所有数据库节点（包括写节点 &lt;code&gt;masters&lt;/code&gt;和读节点 &lt;code&gt;replicas&lt;/code&gt;）上进行分发。这种模式允许主库也承担一部分读压力。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;BALANCE_MASTER&lt;/strong&gt;​ (如果支持)&lt;/td&gt;
&lt;td&gt;仅从主库读取&lt;/td&gt;
&lt;td&gt;所有读请求都会发往配置的写节点（&lt;code&gt;masters&lt;/code&gt;）。这通常用于需要强一致性读的场景，或者尚未配置从库的情况。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# vim /usr/local/mycat/conf/clusters/rwcluster.cluster.json 
{
        &quot;clusterType&quot;:&quot;MASTER_SLAVE&quot;,
        &quot;heartbeat&quot;:{
                &quot;heartbeatTimeout&quot;:1000,
                &quot;maxRetryCount&quot;:3,
                &quot;minSwitchTimeInterval&quot;:300,
                &quot;showLog&quot;:false,
                &quot;slaveThreshold&quot;:0.0
        },
        &quot;masters&quot;:[
                &quot;whost56&quot;
        ],
        &quot;maxCon&quot;:2000,
        &quot;name&quot;:&quot;rwcluster&quot;,
        &quot;readBalanceType&quot;:&quot;BALANCE_ALL_READ&quot;,# _READ将查询语句分发到从数据库节点
        &quot;replicas&quot;:[
                &quot;rhost57&quot;
        ],
        &quot;switchType&quot;:&quot;SWITCH&quot;
}
:wq

# 重启mycat【麦-凯特】服务
[root@mycat58 ~]# /usr/local/mycat/bin/mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...

[root@mycat58 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;七、测试读写分离&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/10-mysql%E4%B9%8B%E8%AF%BB%E5%86%99%E5%88%86%E7%A6%BB/image-20250616174434099.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;7.1 指定testdb库存储数据使用的集群&lt;/h3&gt;
&lt;p&gt;具体操作如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321 

mysql&amp;gt; create【克瑞特】 database testdb;
# mysql&amp;gt; create database testdb;
# Query OK, 0 rows affected (0.54 sec)

mysql&amp;gt;  exit【诶西特】


# 指定testdb库存储数据使用的集群
[root@mycat58 ~]# vim /usr/local/mycat/conf/schemas/testdb.schema.json
{
        &quot;customTables&quot;:{},
        &quot;globalTables&quot;:{},
        &quot;normalProcedures&quot;:{},
        &quot;normalTables&quot;:{},
        &quot;schemaName&quot;:&quot;testdb&quot;,
        &quot;targetName&quot;:&quot;rwcluster&quot;, 添加此行,之前创建的集群名rwcluster
        &quot;shardingTables&quot;:{},
        &quot;views&quot;:{}
}
:wq

[root@mycat58 ~]# /usr/local/mycat/bin/mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...

[root@mycat58 ~]#

# 连接mycat【麦-凯特】服务建表插入记录
[root@client50 ~]# mysql -h192.168.90.58 -P8066 -umycat -p654321

mysql&amp;gt; create【克瑞特】 table【忒-部】 testdb.user (name varchar【瓦儿-查儿】(10) , password varchar【瓦儿-查儿】(10));
# mysql&amp;gt; create table testdb.user (name varchar(10), password varchar(10));
# Query OK, 0 rows affected (3.65 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】  testdb.user values【挖柳斯】(&quot;yaya&quot;,&quot;123456&quot;);
# mysql&amp;gt; insert into testdb.user values(&quot;yaya&quot;,&quot;123456&quot;);
# Query OK, 1 row affected (0.28 sec)

mysql&amp;gt; select【涩莱克特】 * from【弗乱】 testdb.user;
# mysql&amp;gt; select * from testdb.user;
# +------+----------+
# | name | password |
# +------+----------+
# | yaya | 123456   |
# +------+----------+
# 1 row in set (0.01 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.2 测试读写分离&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 在从服务器本机插入记录，数据仅在从服务器有，主服务器没有
[root@mysql57 ~]# mysql -e &apos;insert【因涩特】 into【因兔】 testdb.user values【挖柳斯】 (&quot;yayaA&quot;,&quot;654321&quot;)&apos;
# [root@mysql57 ~]# mysql -uroot -p123 -e &apos;insert into testdb.user values(&quot;yayaA&quot;,&quot;654321&quot;)&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.

[root@mysql57 ~]# mysql -e &apos;select【涩莱克特】 * from【弗乱】 testdb.user&apos;
# [root@mysql57 ~]# mysql -uroot -p123 -e &apos;select * from testdb.user&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +-------+----------+
# | name  | password |
# +-------+----------+
# | yaya  | 123456   |
# | yayaA | 654321   |
# +-------+----------+


# 主服务器数据不变，日志偏移量不不变
[root@mysql56 ~]# mysql -e &apos;select【涩莱克特】 * from【弗乱】 testdb.user&apos;
# [root@mysql56 ~]# mysql -uroot -p123 -e &apos;select * from testdb.user&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +------+----------+
# | name | password |
# +------+----------+
# | yaya | 123456   |
# +------+----------+

[root@mysql56 ~]# mysql -e &apos;show【瘦】 master【马斯特】 status【 斯dèi 特斯】&apos;
# [root@mysql56 ~]# mysql -uroot -p123 -e &apos;show master status&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +----------------+----------+--------------+------------------+-------------------+
# | File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
# +----------------+----------+--------------+------------------+-------------------+
# | mysql56.000002 |     1910 |              |                  |                   |
# +----------------+----------+--------------+------------------+-------------------+

# 客户端连接mycat【麦-凯特】服务读/写数据
[root@client50 ~]# mysql -h192.168.90.58 -P8066 -umycat -p654321
# [root@mycat58 ~]# mysql -h 127.0.0.1 -P8066 -umycat -p654321

#  查看到的是2条记录的行
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 testdb.user;
# mysql&amp;gt; select * from testdb.user;
# +-------+----------+
# | name  | password |
# +-------+----------+
# | yaya  | 123456   |
# | yayaA | 654321   |
# +-------+----------+
# 2 rows in set (1.34 sec)

#   插入记录
mysql&amp;gt; insert【因涩特】 into【因兔】 testdb.user values【挖柳斯】(&quot;yayaB&quot;,&quot;123456&quot;);
# mysql&amp;gt; insert into testdb.user values(&quot;yayaB&quot;,&quot;123456&quot;);
# Query OK, 1 row affected (0.14 sec)

mysql&amp;gt; select【涩莱克特】  * from【弗乱】 testdb.user;
# mysql&amp;gt; select * from testdb.user;
# +-------+----------+
# | name  | password |
# +-------+----------+
# | yaya  | 123456   |
# | yayaB | 123456   |
# +-------+----------+
# 2 rows in set (0.00 sec)

# 在主服务器查看数据和日志偏移量
[root@mysql56 ~]# mysql -e &apos;select【涩莱克特】 * from【弗乱】 testdb.user&apos;
# [root@mysql56 ~]# mysql -uroot -p123 -e &apos;select * from testdb.user&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +-------+----------+
# | name  | password |
# +-------+----------+
# | yaya  | 123456   |
# | yayaB | 123456   |
# +-------+----------+

[root@mysql56 ~]# mysql -e &apos;show【瘦】 master【马斯特】 status【 斯dèi 特斯】&apos;
# [root@mysql56 ~]# mysql -uroot -p123 -e &apos;show master status&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +----------------+----------+--------------+------------------+-------------------+
# | File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
# +----------------+----------+--------------+------------------+-------------------+
# | mysql56.000002 |     2203 |              |                  |                   |
# +----------------+----------+--------------+------------------+-------------------+

# 客户端连接mycat【麦-凯特】服务查看到的是3条记录
[root@client50 ~]# mysql -h192.168.90.58 -P8066 -umycat -p654321 -e &apos;select【涩莱克特】  * from【弗乱】 testdb.user&apos;
# [root@mycat58 mycat]# mysql -h192.168.88.30 -P8066 -umycat -p654321 -e &apos;select * from testdb.user&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +-------+----------+
# | name  | password |
# +-------+----------+
# | yaya  | 123456   |
# | yayaA | 654321   |
# +-------+----------+
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;MyCat 核心配置文件功能总结&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;配置文件&lt;/th&gt;
&lt;th&gt;核心功能&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;server.xml&lt;/td&gt;
&lt;td&gt;系统级配置（账户、密码、逻辑库、序列、连接参数）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;schema.xml&lt;/td&gt;
&lt;td&gt;逻辑库-物理库映射、表配置、分片规则关联、数据节点/主机配置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rule.xml&lt;/td&gt;
&lt;td&gt;分片规则定义与参数配置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dataHost.xml（可选）&lt;/td&gt;
&lt;td&gt;独立配置数据主机（部分版本将 DataHost 配置拆分到该文件，默认在 schema.xml 中）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;MySQL 读写分离的原理与优势&lt;/h2&gt;
&lt;h3&gt;一、核心原理&lt;/h3&gt;
&lt;p&gt;MySQL 读写分离基于 &lt;strong&gt;主从复制&lt;/strong&gt; 机制，通过中间件（如 MyCat、ProxySQL、MaxScale）实现请求分流，核心逻辑如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;架构基础&lt;/strong&gt;：部署1台主库（Master）和1+台从库（Slave），主库负责写操作，从库仅负责读操作；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据同步&lt;/strong&gt;：主库执行写操作（INSERT/UPDATE/DELETE）后，通过二进制日志（binlog）将数据变更同步到所有从库，保障主从数据一致性；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;请求路由&lt;/strong&gt;：应用程序的SQL请求统一发送至中间件，中间件根据SQL类型分流：
&lt;ul&gt;
&lt;li&gt;写请求（含事务类读请求）直接路由到主库，确保数据写入的原子性和一致性；&lt;/li&gt;
&lt;li&gt;读请求（SELECT）分发到任意从库，支持多从库负载均衡；&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;故障兼容&lt;/strong&gt;：中间件实时监测主从节点状态，自动剔除故障从库，主库故障时可配合主从切换机制保障业务连续性。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;二、核心优势&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;提升并发承载能力&lt;/strong&gt;：读操作（占业务请求80%以上）分流至多从库，主库专注处理写操作，避免读写冲突排队，系统整体并发量显著提升；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;减轻主库负载压力&lt;/strong&gt;：主库无需承担大量读请求的CPU、IO资源消耗，降低主库因负载过高导致的卡顿、超时风险；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高可用与容错&lt;/strong&gt;：从库故障仅影响部分读业务，主库故障可快速切换读请求至从库，避免单点故障导致系统瘫痪；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;优化响应速度&lt;/strong&gt;：从库可就近部署（异地多活），降低网络延迟；且从库可关闭写日志、优化索引，专项提升读性能；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;灵活横向扩展&lt;/strong&gt;：读压力增长时，无需升级主库硬件，仅需新增从库节点接入集群，扩展成本低、效率高；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;简化维护与数据安全&lt;/strong&gt;：从库可作为灾备节点，主库数据丢失时可从从库恢复；报表统计、数据备份等非核心操作可在从库执行，不影响主库业务。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Mycat 在 MySQL 读写分离中的核心作用&lt;/h2&gt;
&lt;p&gt;Mycat 作为开源分布式数据库中间件，是 MySQL 读写分离架构的 &lt;strong&gt;核心枢纽&lt;/strong&gt;，其核心价值是屏蔽底层主从集群复杂度，实现请求智能分流、数据一致性保障和高可用调度，让应用无需感知主从架构即可享受读写分离带来的性能提升。具体作用如下：&lt;/p&gt;
&lt;h3&gt;一、请求路由：读写操作智能分流（核心功能）&lt;/h3&gt;
&lt;p&gt;Mycat 是应用与 MySQL 集群之间的“流量分发器”，实现读写请求的精准拆分：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;SQL 类型识别&lt;/strong&gt;：自动解析应用发送的 SQL 语句，区分读操作（SELECT、SHOW 等）和写操作（INSERT、UPDATE、DELETE、DDL 等）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;路由规则执行&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;写请求（含事务类读请求，如 &lt;code&gt;SELECT ... FOR UPDATE&lt;/code&gt;）强制路由到 &lt;strong&gt;主库&lt;/strong&gt;，确保数据写入的原子性和一致性，避免写操作分散导致的数据冲突；&lt;/li&gt;
&lt;li&gt;读请求默认路由到 &lt;strong&gt;从库&lt;/strong&gt;，并支持多从库负载均衡（如轮询、加权轮询、一致性哈希等算法），将读压力均匀分摊到多个从库，减轻主库负担；&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;灵活路由扩展&lt;/strong&gt;：支持自定义路由规则（如指定某类查询走特定从库、分库分表场景下的联合路由），适配复杂业务需求。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;二、数据一致性保障：解决主从同步延迟问题&lt;/h3&gt;
&lt;p&gt;MySQL 主从复制存在天然的同步延迟（毫秒级到秒级），可能导致“主库写入数据后，从库未及时同步，读请求获取旧数据”的问题。Mycat 提供多种机制保障数据一致性：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;强制走主库策略&lt;/strong&gt;：支持通过 SQL 注解（如 &lt;code&gt;/*MASTER*/ SELECT * FROM table&lt;/code&gt;）或配置规则，让关键读请求（如刚写入后需立即查询的场景）强制路由到主库，避免延迟导致的数据不一致；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;延迟判断机制&lt;/strong&gt;：可配置从库同步延迟阈值（如 1 秒），Mycat 实时监测主从延迟，若从库延迟超过阈值，自动将读请求切换到其他低延迟从库或主库，确保读取数据的时效性；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;事务一致性控制&lt;/strong&gt;：事务内的所有操作（无论读写）均路由到主库，避免事务跨主从执行导致的隔离级别失效或数据不一致。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;三、负载均衡：提升集群并发处理能力&lt;/h3&gt;
&lt;p&gt;针对多从库架构，Mycat 提供成熟的负载均衡策略，最大化利用从库资源：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;读负载均衡&lt;/strong&gt;：将海量读请求均匀分发到多个从库，避免单台从库过载，提升整体读并发能力（如 3 台从库可承载 3 倍于单从库的读请求）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;权重配置支持&lt;/strong&gt;：可根据从库硬件性能（CPU、内存、IO）配置权重（如高性能从库权重设为 3，普通从库设为 1），让资源更优的从库承担更多请求；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;动态负载调整&lt;/strong&gt;：支持在线新增/下线从库节点，Mycat 自动感知节点变化并调整负载分发策略，无需重启应用或中间件。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;四、高可用调度：避免单点故障，保障业务连续性&lt;/h3&gt;
&lt;p&gt;Mycat 实时监测主从节点状态，提供故障自动切换和容错能力，提升集群可用性：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;节点健康检查&lt;/strong&gt;：通过心跳检测（如定期执行 &lt;code&gt;SELECT 1&lt;/code&gt;）监测主从库是否存活，若发现节点故障（如从库宕机、主库离线），自动将其从集群中剔除，避免请求路由到故障节点导致的业务报错；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主从切换支持&lt;/strong&gt;：配合 MGR（MySQL Group Replication）或第三方高可用工具（如 Keepalived），主库故障时，Mycat 可自动识别新主库并切换路由规则，写请求无缝迁移到新主库，读请求继续由正常从库处理，实现业务“无感知”恢复；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;故障恢复自动接入&lt;/strong&gt;：当故障节点修复后，Mycat 可自动检测并将其重新纳入集群，恢复负载均衡，无需人工干预。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;五、透明接入：降低应用改造成本&lt;/h3&gt;
&lt;p&gt;Mycat 对应用完全透明，无需修改应用代码即可实现读写分离：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;协议兼容&lt;/strong&gt;：完全兼容 MySQL 协议，应用可像连接普通 MySQL 数据库一样连接 Mycat（仅需修改数据库连接地址为 Mycat 服务地址，端口为 Mycat 监听端口），无需调整 SQL 语法或数据库驱动；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;逻辑库抽象&lt;/strong&gt;：Mycat 将底层多个主从库抽象为一个“逻辑库”，应用仅需面向逻辑库开发，无需关心底层主从节点的数量、地址和部署架构，降低架构复杂度和运维成本。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;六、辅助功能：强化读写分离架构的稳定性与可维护性&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;权限集中管理&lt;/strong&gt;：在 Mycat 层面统一配置应用访问权限（如某应用仅允许读从库、某账户仅允许写主库），无需在每个 MySQL 节点单独配置，简化权限管理；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SQL 拦截与过滤&lt;/strong&gt;：支持拦截非法 SQL（如高风险 DDL、慢查询）或不符合规则的请求（如写请求路由到从库），避免恶意操作或误操作破坏集群稳定性；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;监控与审计&lt;/strong&gt;：提供完善的日志（如路由日志、错误日志、访问日志）和监控指标（如请求量、路由命中率、节点状态），方便运维人员排查问题、优化性能；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分库分表兼容&lt;/strong&gt;：Mycat 不仅支持读写分离，还可与分库分表功能结合，实现“读写分离+分库分表”的复杂架构，满足海量数据存储和高并发访问的场景（如电商订单库）。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;Mycat 在 MySQL 读写分离架构中的核心作用是 &lt;strong&gt;“承上启下”&lt;/strong&gt;：向上屏蔽底层主从集群的复杂性，让应用无需改造即可享受读写分离的性能红利；向下通过智能路由、负载均衡、高可用调度和一致性保障，最大化发挥主从集群的资源价值，解决“主库负载高、读并发不足、单点故障”等核心问题，是中小型企业实现 MySQL 高可用、高并发架构的优选中间件。&lt;/p&gt;
&lt;h3&gt;Mycat 在 MySQL 读写分离中的核心作用（简洁版）&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;读写请求智能分流&lt;/strong&gt;&lt;br /&gt;
自动解析 SQL 类型，写操作（INSERT/UPDATE/DELETE）路由到主库保证数据一致，读操作（SELECT）分发到从库，避免主库读压力过载。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;保障数据一致与读负载均衡&lt;/strong&gt;&lt;br /&gt;
通过“关键读请求强制走主库”解决主从同步延迟问题；支持多从库按权重分摊读请求，最大化利用从库资源，提升读并发能力。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;透明接入与高可用兜底&lt;/strong&gt;&lt;br /&gt;
应用无需改代码，仅需将连接地址指向 Mycat（兼容 MySQL 协议）；实时监测主从节点状态，故障节点自动剔除，主库故障时配合切换保障业务不中断。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Mycat 读写分离 schema.xml 核心配置项及作用（简洁版）&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;1. **&amp;lt;schema&amp;gt; 标签**  
   - 核心属性：`name`（逻辑库名称）、`checkSQLschema`（是否校验SQL库名）  
   - 作用：定义应用访问的**逻辑库**，关联底层数据节点，屏蔽物理库集群复杂度。

2. **&amp;lt;table&amp;gt; 标签**  
   - 核心属性：`name`（逻辑表名）、`dataNode`（关联的数据节点）、`primaryKey`（主键）、`autoIncrement`（是否自增）  
   - 作用：映射逻辑表与物理表，指定表所属数据节点，配置主键和自增规则（读写分离场景中主要用于关联数据节点）。

3. **&amp;lt;dataNode&amp;gt; 标签**  
   - 核心属性：`name`（数据节点名称）、`dataHost`（关联的数据主机）、`database`（物理库名称）  
   - 作用：关联**数据主机**与**物理库**，是逻辑表到物理库的中间映射。

4. **&amp;lt;dataHost&amp;gt; 标签**（读写分离核心配置）  
   - 核心属性：`name`（数据主机名称）、`balance`（读负载均衡策略）、`writeType`（写路由规则）、`switchType`（主从切换策略）  
   - 作用：配置主从库集群信息，控制读负载分发、写请求路由、主从故障切换。

5. **&amp;lt;writeHost&amp;gt; 标签**  
   - 核心属性：`host`（主机标识）、`url`（主库地址:端口）、`user`（数据库用户名）、`password`（密码）  
   - 作用：定义**主库**连接信息，接收所有写请求（INSERT/UPDATE/DELETE）。

6. **&amp;lt;readHost&amp;gt; 标签**  
   - 核心属性：`host`（主机标识）、`url`（从库地址:端口）、`user`（数据库用户名）、`password`（密码）  
   - 作用：定义**从库**连接信息，接收读请求（SELECT），配合 `balance` 实现负载均衡。

7. **关键属性补充**  
   - `balance=&quot;1&quot;`：开启读负载均衡（主从库均参与读）；  
   - `writeType=&quot;0&quot;`：写请求路由到第一个 &amp;lt;writeHost&amp;gt;（主库）；  
   - `switchType=&quot;1&quot;`：主库故障时自动切换到备用主库/从库。
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Mycat balance 属性（负载均衡策略）取值含义与适用场景&lt;/h2&gt;
&lt;p&gt;balance 是 Mycat &lt;code&gt;schema.xml&lt;/code&gt; 中 &lt;code&gt;&amp;lt;dataHost&amp;gt;&lt;/code&gt; 标签的核心属性，专门控制 &lt;strong&gt;读请求的负载均衡规则&lt;/strong&gt;，取值仅支持 &lt;code&gt;0、1、2、3&lt;/code&gt; 四种，不同取值对应不同的集群架构和业务需求，具体如下：&lt;/p&gt;
&lt;h3&gt;1. balance=&quot;0&quot;：关闭读负载均衡&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;含义&lt;/strong&gt;：不开启读负载分发，所有读请求（SELECT）均路由到当前活跃的 &lt;code&gt;writeHost&lt;/code&gt;（主库），从库（&lt;code&gt;readHost&lt;/code&gt;）不参与读请求处理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;从库未部署（仅单主库架构）；&lt;/li&gt;
&lt;li&gt;主从同步延迟极高（如跨地域主从，延迟秒级以上），读从库会导致数据不一致；&lt;/li&gt;
&lt;li&gt;业务需要 &lt;strong&gt;强一致性读&lt;/strong&gt;（如刚写入数据后立即查询、核心交易查询），必须读主库。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. balance=&quot;1&quot;：主从库混合读负载（推荐默认）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;含义&lt;/strong&gt;：开启读负载均衡，读请求分发到所有 &lt;code&gt;readHost&lt;/code&gt;（从库）和 &lt;strong&gt;备用 &lt;code&gt;writeHost&lt;/code&gt;（备用主库）&lt;/strong&gt;；当前活跃的主库（默认 &lt;code&gt;writeHost&lt;/code&gt;）不参与读请求，仅负责写操作。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;典型主从架构（1主多从 + 1备用主库），需最大化利用从库和备用主库资源；&lt;/li&gt;
&lt;li&gt;读请求占比高（如电商商品查询、新闻列表、用户信息查询），需分摊主库读压力；&lt;/li&gt;
&lt;li&gt;大多数中小型业务的默认选择，兼顾性能和数据一致性（配合主从同步延迟阈值使用）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. balance=&quot;2&quot;：全节点读负载（不分主从）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;含义&lt;/strong&gt;：不区分主库（&lt;code&gt;writeHost&lt;/code&gt;）和从库（&lt;code&gt;readHost&lt;/code&gt;），所有可用的 &lt;code&gt;writeHost&lt;/code&gt;（主库、备用主库）和 &lt;code&gt;readHost&lt;/code&gt;（从库）均参与读负载，读请求随机分发到所有节点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;主库硬件配置充足（CPU/内存/IO 资源未饱和），允许承担部分读请求；&lt;/li&gt;
&lt;li&gt;备用主库长期闲置，需利用其资源分担读压力；&lt;/li&gt;
&lt;li&gt;读压力较大但未达到需要部署多从库的规模，适合中小型集群（如 1主1从 + 1备用主库）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. balance=&quot;3&quot;：仅从库读负载&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;含义&lt;/strong&gt;：读请求仅分发到&lt;code&gt;readHost&lt;/code&gt;（从库），主库（&lt;code&gt;writeHost&lt;/code&gt;）和备用主库&lt;strong&gt;完全不参与&lt;/strong&gt;读负载&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;主库写压力极大（如高频插入/更新），需完全隔离读请求（主库仅负责写）；&lt;/li&gt;
&lt;li&gt;对读数据时效性有要求（需避免主从延迟导致的旧数据），如金融交易查询、订单状态查询；&lt;/li&gt;
&lt;li&gt;多从库架构（1主多从），且从库性能均衡，适合中大型业务的读密集场景。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;balance=&quot;3&quot;&lt;/code&gt;是&lt;strong&gt;最常用的读写分离策略&lt;/strong&gt;，特别适合读多写少的业务场景，它能有效降低主库压力，提升系统整体性能。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;核心总结（快速选型）&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;balance&lt;/code&gt; 值&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;读请求负载策略&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;核心工作机制&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;最适用场景&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;不开启读写分离&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;所有读、写操作均发送至当前可用的主库 (&lt;code&gt;writeHost&lt;/code&gt;)。&lt;/td&gt;
&lt;td&gt;单点数据库、要求强一致性读、从库延迟不可接受。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;主从库混合读负载&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;读请求在所有从库 (&lt;code&gt;readHost&lt;/code&gt;) 及&lt;strong&gt;备用主库&lt;/strong&gt; (&lt;code&gt;standby writeHost&lt;/code&gt;) 间负载均衡，&lt;strong&gt;当前主库不参与读&lt;/strong&gt;。&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;双主双从&lt;/strong&gt;等高可用架构，最大化利用从库和备用主库资源。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;全节点随机读负载&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;所有读请求随机分发到配置内&lt;strong&gt;所有&lt;/strong&gt;数据库节点（包括主库和从库）。&lt;/td&gt;
&lt;td&gt;读压力大，且主库性能充足，允许主库分担读请求。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;仅从库读负载&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;读请求&lt;strong&gt;只&lt;/strong&gt;分发到当前主库对应的从库 (&lt;code&gt;readHost&lt;/code&gt;) 上，&lt;strong&gt;主库完全不负担任何读压力&lt;/strong&gt;。&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;一主多从&lt;/strong&gt;架构，且希望&lt;strong&gt;严格分离读写&lt;/strong&gt;、保障主库写性能的场景。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;八、作业&lt;/h2&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;h4&gt;1&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在 Mycat 读写分离配置中，schema.xml 文件里 datahost 标签的 balance 属性值为 3 时，表示（ D ）。
A. 不开启读写分离机制，所有读操作都可发送到当前可用的 writeHost 上
B. 全部的 readHost 与备用的 writeHost 都参与 select 语句的负载均衡
C. 所有的读写操作都随机在 writeHost，readHost 上分发
D. 所有的读请求随机分发到 writeHost 对应的 readHost 上执行，writeHost 不负担读压力&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;2&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Mycat 的默认数据端口和管理端口分别是（ A ）。
A. 8066 和 9066
B. 9066 和 8066
C. 3306 和 8066
D. 8066 和 3306&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;3&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在 Mycat 配置中，server.xml 文件主要用于（ A ）。
A. 配置 Mycat 所需要的服务器信息，如序列生成方式、逻辑数据库、访问账户和密码等
B. 配置逻辑数据库的映射、表、分片规则、数据结点及真实的数据库信息
C. 定义分片规则
D. 配置负载均衡策略&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;4&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在 Mycat 读写分离配置前，需要确保（ A ）。
A. MySQL 主从复制已完成并正常运行
B. MySQL 版本为 8.0
C. Mycat 安装在 Windows 系统上
D. 所有数据库服务器的 server-id 相同&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;h4&gt;1&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;简述 MySQL 读写分离的原理和优势。
答：
核心原理
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;架构基础&lt;/strong&gt;：部署1台主库（Master）和1+台从库（Slave），主库负责写操作，从库仅负责读操作；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据同步&lt;/strong&gt;：主库执行写操作（INSERT/UPDATE/DELETE）后，通过二进制日志（binlog）将数据变更同步到所有从库，保障主从数据一致性；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;请求路由&lt;/strong&gt;：应用程序的SQL请求统一发送至中间件，中间件根据SQL类型分流：
&lt;ul&gt;
&lt;li&gt;写请求（含事务类读请求）直接路由到主库，确保数据写入的原子性和一致性；&lt;/li&gt;
&lt;li&gt;读请求（SELECT）分发到任意从库，支持多从库负载均衡；&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;故障兼容&lt;/strong&gt;：中间件实时监测主从节点状态，自动剔除故障从库，主库故障时可配合主从切换机制保障业务连续性。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;核心优势
1. &lt;strong&gt;提升并发承载能力&lt;/strong&gt;：读操作（占业务请求80%以上）分流至多从库，主库专注处理写操作，避免读写冲突排队，系统整体并发量显著提升；
2. &lt;strong&gt;减轻主库负载压力&lt;/strong&gt;：主库无需承担大量读请求的CPU、IO资源消耗，降低主库因负载过高导致的卡顿、超时风险；
3. &lt;strong&gt;高可用与容错&lt;/strong&gt;：从库故障仅影响部分读业务，主库故障可快速切换读请求至从库，避免单点故障导致系统瘫痪；
4. &lt;strong&gt;优化响应速度&lt;/strong&gt;：从库可就近部署（异地多活），降低网络延迟；且从库可关闭写日志、优化索引，专项提升读性能；
5. &lt;strong&gt;灵活横向扩展&lt;/strong&gt;：读压力增长时，无需升级主库硬件，仅需新增从库节点接入集群，扩展成本低、效率高；
6. &lt;strong&gt;简化维护与数据安全&lt;/strong&gt;：从库可作为灾备节点，主库数据丢失时可从从库恢复；报表统计、数据备份等非核心操作可在从库执行，不影响主库业务。&lt;/p&gt;
&lt;h4&gt;2&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;说明 Mycat 在 MySQL 读写分离中的作用。
答：
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;读写请求智能分流&lt;/strong&gt;&lt;br /&gt;
自动解析 SQL 类型，写操作（INSERT/UPDATE/DELETE）路由到主库保证数据一致，读操作（SELECT）分发到从库，避免主库读压力过载。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保障数据一致与读负载均衡&lt;/strong&gt;&lt;br /&gt;
通过“关键读请求强制走主库”解决主从同步延迟问题；支持多从库按权重分摊读请求，最大化利用从库资源，提升读并发能力。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;透明接入与高可用兜底&lt;/strong&gt;&lt;br /&gt;
应用无需改代码，仅需将连接地址指向 Mycat（兼容 MySQL 协议）；实时监测主从节点状态，故障节点自动剔除，主库故障时配合切换保障业务不中断。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;3&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;列举 Mycat 读写分离配置中 schema.xml 文件的主要配置项及其作用。
答：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;schema&amp;gt; 标签&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;核心属性：&lt;code&gt;name&lt;/code&gt;（逻辑库名称）、&lt;code&gt;checkSQLschema&lt;/code&gt;（是否校验SQL库名）&lt;/li&gt;
&lt;li&gt;作用：定义应用访问的&lt;strong&gt;逻辑库&lt;/strong&gt;，关联底层数据节点，屏蔽物理库集群复杂度。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;table&amp;gt; 标签&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;核心属性：&lt;code&gt;name&lt;/code&gt;（逻辑表名）、&lt;code&gt;dataNode&lt;/code&gt;（关联的数据节点）、&lt;code&gt;primaryKey&lt;/code&gt;（主键）、&lt;code&gt;autoIncrement&lt;/code&gt;（是否自增）&lt;/li&gt;
&lt;li&gt;作用：映射逻辑表与物理表，指定表所属数据节点，配置主键和自增规则（读写分离场景中主要用于关联数据节点）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;dataNode&amp;gt; 标签&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;核心属性：&lt;code&gt;name&lt;/code&gt;（数据节点名称）、&lt;code&gt;dataHost&lt;/code&gt;（关联的数据主机）、&lt;code&gt;database&lt;/code&gt;（物理库名称）&lt;/li&gt;
&lt;li&gt;作用：关联&lt;strong&gt;数据主机&lt;/strong&gt;与&lt;strong&gt;物理库&lt;/strong&gt;，是逻辑表到物理库的中间映射。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;dataHost&amp;gt; 标签&lt;/strong&gt;（读写分离核心配置）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;核心属性：&lt;code&gt;name&lt;/code&gt;（数据主机名称）、&lt;code&gt;balance&lt;/code&gt;（读负载均衡策略）、&lt;code&gt;writeType&lt;/code&gt;（写路由规则）、&lt;code&gt;switchType&lt;/code&gt;（主从切换策略）&lt;/li&gt;
&lt;li&gt;作用：配置主从库集群信息，控制读负载分发、写请求路由、主从故障切换。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;writeHost&amp;gt; 标签&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;核心属性：&lt;code&gt;host&lt;/code&gt;（主机标识）、&lt;code&gt;url&lt;/code&gt;（主库地址:端口）、&lt;code&gt;user&lt;/code&gt;（数据库用户名）、&lt;code&gt;password&lt;/code&gt;（密码）&lt;/li&gt;
&lt;li&gt;作用：定义&lt;strong&gt;主库&lt;/strong&gt;连接信息，接收所有写请求（INSERT/UPDATE/DELETE）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;readHost&amp;gt; 标签&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;核心属性：&lt;code&gt;host&lt;/code&gt;（主机标识）、&lt;code&gt;url&lt;/code&gt;（从库地址:端口）、&lt;code&gt;user&lt;/code&gt;（数据库用户名）、&lt;code&gt;password&lt;/code&gt;（密码）&lt;/li&gt;
&lt;li&gt;作用：定义&lt;strong&gt;从库&lt;/strong&gt;连接信息，接收读请求（SELECT），配合 &lt;code&gt;balance&lt;/code&gt; 实现负载均衡。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;关键属性补充&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;balance=&quot;1&quot;&lt;/code&gt;：开启读负载均衡（主从库均参与读）；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;writeType=&quot;0&quot;&lt;/code&gt;：写请求路由到第一个 &amp;lt;writeHost&amp;gt;（主库）；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;switchType=&quot;1&quot;&lt;/code&gt;：主库故障时自动切换到备用主库/从库。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;4&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;阐述 Mycat 读写分离中负载均衡策略 balance 属性不同取值的含义和适用场景。
答：
balance 取值 “0”，核心含义为“读请求仅走主库，从库不参与”，适用场景为单主库、强一致性读、主从延迟极高
balance 取值 “1”，核心含义为“读请求走从库+备用主库，主库只读不写”，适用场景为1主多从+备用主库、常规读写分离
balance 取值 “2”，核心含义为“所有主从节点均分担读请求”，适用场景为主库资源充足、读压力适中
balance 取值 “3”，核心含义为“读请求&lt;strong&gt;只&lt;/strong&gt;分发到当前主库对应的从库 (&lt;code&gt;readHost&lt;/code&gt;) 上，&lt;strong&gt;主库完全不负担任何读压力&lt;/strong&gt;。”，适用场景为&lt;strong&gt;一主多从&lt;/strong&gt;架构，且希望&lt;strong&gt;严格分离读写&lt;/strong&gt;、保障主库写性能的场景&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3 操作题&lt;/h3&gt;
&lt;h4&gt;1&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;请详细描述在 Linux 环境下使用 Mycat 实现 MySQL 一主一从读写分离的完整操作步骤，包括 MySQL 主从复制配置、Mycat 安装与配置、测试验证等。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;// **MySQL 主从复制配置**

# 配置主库，指定server_id和开启binlog日记
[root@master ~]# grep -vE &quot;#&quot; /etc/my.cnf
[mysqld]
server-id=56
log-bin=mysql56

# 重启服务
[root@master /]# systemctl restart mysqld

# 创建用户同步的repluser账号密码repluser
mysql&amp;gt; create user repluser@&quot;%&quot; identified WITH mysql_native_password by &quot;repluser&quot;;
Query OK, 0 rows affected (0.09 sec)
# 给repluser用户赋权
mysql&amp;gt; grant replication slave on *.*  to repluser@&quot;%&quot;;
Query OK, 0 rows affected (0.05 sec)
# 查询binlog名称和偏移量
mysql&amp;gt; show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql56.000002 |      157 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)



// **从库安装mysql服务**

# 配置从库，指定server_id和开启binlog日记
[root@slave1 ~]# vim /etc/my.cnf
[root@slave1 ~]# grep -vE &quot;#&quot; /etc/my.cnf
[mysqld]
server-id=57
log_bin=/var/lib/mysql/binlog
relay_log=/var/lib/mysql/relaylog

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

# 从库配置
# 修改默认密码
[root@slave1 ~]# mysql -uroot -p123
# 配置 MySQL 主从复制
mysql&amp;gt; change  master to  master_host=&quot;192.168.88.10&quot; , master_user=&quot;repluser&quot; , master_password=&quot;repluser&quot; ,master_log_file=&quot;mysql56.000002&quot; , master_log_pos=157;
Query OK, 0 rows affected, 8 warnings (0.06 sec)

# 启动slave进程
mysql&amp;gt; start slave;
Query OK, 0 rows affected, 1 warning (0.32 sec)

# 同步查看状态信息
mysql&amp;gt; show slave status \G
......
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
......


# 配置mycat服务jama用户
# 在master 服务器添加
mysql&amp;gt; create user jama@&quot;%&quot;  identified by &quot;123456&quot;;
Query OK, 0 rows affected (0.24 sec)

mysql&amp;gt; grant  all on *.* to  jama@&quot;%&quot;;
Query OK, 0 rows affected (0.19 sec)

# 在slave 服务器查看是否同步成功
[root@slave1 ~]# mysql -e &apos;select user , host from mysql.user where user=&quot;jama&quot;&apos;
+------+------+
| user | host |
+------+------+
| jama | %    |
+------+------+
[root@slave1 ~]#





// **Mycat 安装与配置、测试验证**

# 安装mycat 软件和环境
# 安装jdk64和unzip
[root@mycat ~]# yum -y install java-1.8.0-openjdk.x86_64 unzip
# 安装mycat
[root@mycat ~]# unzip mycat2-install-template-1.21.zip 
[root@mycat ~]# mv mycat /usr/local/
# 安装依赖
[root@mycat ~]# cp mycat2-1.21-release-jar-with-dependencies.jar /usr/local/mycat/lib/
[root@mycat ~]# chmod -R 777 /usr/local/mycat/ 

# 配置mycat 密码
# 定义客户端连接mycat 服务使用用户及密码：
[root@mycat ~]# vim  /usr/local/mycat/conf/users/root.user.json
{
        &quot;dialect&quot;:&quot;mysql&quot;,
        &quot;ip&quot;:null,
        &quot;password&quot;:&quot;654321&quot;, # 密码
        &quot;transactionType&quot;:&quot;proxy&quot;,
        &quot;username&quot;:&quot;mycat&quot; # 用户名
}

# mycat【麦-凯特】连接本机数据库配置
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/prototypeDs.datasource.json
{
        &quot;dbType&quot;:&quot;mysql&quot;,
        &quot;idleTimeout&quot;:60000,
        &quot;initSqls&quot;:[],
        &quot;initSqlsGetConnection&quot;:true,
        &quot;instanceType&quot;:&quot;READ_WRITE&quot;,
        &quot;maxCon&quot;:1000,
        &quot;maxConnectTimeout&quot;:3000,
        &quot;maxRetryCount&quot;:5,
        &quot;minCon&quot;:1,
        &quot;name&quot;:&quot;prototypeDs&quot;,
        &quot;password&quot;:&quot;123456&quot;, # 密码
        &quot;type&quot;:&quot;JDBC&quot;,
        &quot;url&quot;:&quot;jdbc:mysql://localhost:3306/mysql?useUnicode=true&amp;amp;serverTimezone=Asia/Shanghai&amp;amp;characterEncoding=UTF-8&quot;, # 连接本机的数据库服务
        &quot;user&quot;:&quot;jam&quot;, # 用户名
        &quot;weight&quot;:0
}



# mycat58主机mysql配置
[root@mycat ~]# mysql -uroot -p123
#  创建jam用户
mysql&amp;gt; create user jam@&apos;%&apos; identified by &apos;123456&apos;;
Query OK, 0 rows affected (0.52 sec)
#  授予权限
mysql&amp;gt; grant all on *.* to jam@&apos;%&apos;;
Query OK, 0 rows affected (1.14 sec)

# 断开连接
mysql&amp;gt; exit


# 启动mycat 服务
[root@mycat ~]# /usr/local/mycat/bin/mycat start
Starting mycat2...

# 半分钟左右 能看到端口     
[root@mycat ~]# netstat -tunlp | grep -E &quot;8066|9066&quot;
tcp6       0      0 :::8066                 :::*                    LISTEN      18159/java          
tcp6       0      0 127.0.0.1:9066          :::*                    LISTEN      18159/java       


# 连接mycat 服务
[root@mycat ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321

mysql&amp;gt; show databases;
+--------------------+
| `Database`         |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.11 sec)


# 配置读写分离
# 添加数据源
# 连接mycat 服务
[root@mycat ~]# mysql -h 127.0.0.1 -P8066 -umycat -p654321

# 添加mysql56数据库服务器
mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;whost56&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.10:3306&quot;,&quot;user&quot;:&quot;jama&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
Query OK, 0 rows affected (0.86 sec)

# 添加mysql57数据库服务器
mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;rhost57&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.20:3306&quot;,&quot;user&quot;:&quot;jama&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
Query OK, 0 rows affected (0.06 sec)

# 查看数据源
mysql&amp;gt; /*+mycat:showDataSources{}*/ \G
*************************** 1. row ***************************
                   NAME: whost56
               USERNAME: jama
               PASSWORD: 123456
......
                DB_TYPE: mysql
                    URL: jdbc:mysql://192.168.88.10:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
......
*************************** 2. row ***************************
                   NAME: prototypeDs
               USERNAME: jam
               PASSWORD: 123456
......
                DB_TYPE: mysql
                    URL: jdbc:mysql://localhost:3306/mysql?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
......
*************************** 3. row ***************************
                   NAME: rhost57
               USERNAME: jama
               PASSWORD: 123456
......
                DB_TYPE: mysql
                    URL: jdbc:mysql://192.168.88.20:3306?useUnicode=true&amp;amp;serverTimezone=Asia/Shanghai&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
......
3 rows in set (0.01 sec)

# 创建集群
[root@mycat ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321

# 创建集群
mysql&amp;gt;/*!mycat:createcluster{
&quot;name&quot;:&quot;rwcluster&quot;,
&quot;masters&quot;:[&quot;whost56&quot;],
&quot;replicas&quot;:[&quot;rhost57&quot;]
}*/ ;


# 查看集群信息
mysql&amp;gt; /*+ mycat:showClusters{}*/ \G
*************************** 1. row ***************************
             NAME: rwcluster
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 2000
             TYPE: BALANCE_ALL
         WRITE_DS: whost56
          READ_DS: whost56,rhost57
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
*************************** 2. row ***************************
             NAME: prototype
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 200
             TYPE: BALANCE_ALL
         WRITE_DS: prototypeDs
          READ_DS: prototypeDs
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
2 rows in set (0.01 sec)


# 指定主机角色
# 修改master 角色主机仅负责写访问
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/whost56.datasource.json
{
        &quot;dbType&quot;:&quot;mysql&quot;,
        &quot;idleTimeout&quot;:60000,
        &quot;initSqls&quot;:[],
        &quot;initSqlsGetConnection&quot;:true,
        &quot;instanceType&quot;:&quot;WRITE&quot;, 仅负责写访问
        &quot;logAbandoned&quot;:true,
        &quot;maxCon&quot;:1000,
        &quot;maxConnectTimeout&quot;:30000,
        &quot;maxRetryCount&quot;:5,
        &quot;minCon&quot;:1,
        &quot;name&quot;:&quot;whost56&quot;,
        &quot;password&quot;:&quot;123456&quot;,
        &quot;queryTimeout&quot;:0,
        &quot;removeAbandoned&quot;:false,
        &quot;removeAbandonedTimeoutSecond&quot;:180,
        &quot;type&quot;:&quot;JDBC&quot;,
        &quot;url&quot;:&quot;jdbc:mysql://192.168.90.56:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&quot;,
        &quot;user&quot;:&quot;jama&quot;,
        &quot;weight&quot;:0
}
:wq

# 修改slave 角色主机仅负责读访问
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/rhost57.datasource.json
{
        &quot;dbType&quot;:&quot;mysql&quot;,
        &quot;idleTimeout&quot;:60000,
        &quot;initSqls&quot;:[],
        &quot;initSqlsGetConnection&quot;:true,
        &quot;instanceType&quot;:&quot;READ&quot;,仅负责读访问
        &quot;logAbandoned&quot;:true,
        &quot;maxCon&quot;:1000,
        &quot;maxConnectTimeout&quot;:30000,
        &quot;maxRetryCount&quot;:5,
        &quot;minCon&quot;:1,
        &quot;name&quot;:&quot;rhost57&quot;,
        &quot;password&quot;:&quot;123456&quot;,
        &quot;queryTimeout&quot;:0,
        &quot;removeAbandoned&quot;:false,
        &quot;removeAbandonedTimeoutSecond&quot;:180,
        &quot;type&quot;:&quot;JDBC&quot;,
        &quot;url&quot;:&quot;jdbc:mysql://192.168.90.57:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&quot;,
        &quot;user&quot;:&quot;jama&quot;,
        &quot;weight&quot;:0
}


# 修改读策略
[root@mycat ~]# vim /usr/local/mycat/conf/clusters/rwcluster.cluster.json 
{
        &quot;clusterType&quot;:&quot;MASTER_SLAVE&quot;,
        &quot;heartbeat&quot;:{
                &quot;heartbeatTimeout&quot;:1000,
                &quot;maxRetryCount&quot;:3,
                &quot;minSwitchTimeInterval&quot;:300,
                &quot;showLog&quot;:false,
                &quot;slaveThreshold&quot;:0.0
        },
        &quot;masters&quot;:[
                &quot;whost56&quot;
        ],
        &quot;maxCon&quot;:2000,
        &quot;name&quot;:&quot;rwcluster&quot;,
        &quot;readBalanceType&quot;:&quot;BALANCE_ALL_READ&quot;,# _READ将查询语句分发到从数据库节点
        &quot;replicas&quot;:[
                &quot;rhost57&quot;
        ],
        &quot;switchType&quot;:&quot;SWITCH&quot;
}
:wq

# 重启mycat 服务
[root@mycat ~]# /usr/local/mycat/bin/mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...

[root@mycat ~]#







// **测试读写分离测试读写分离**
# 指定testdb库存储数据使用的集群
[root@mycat ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321 
mysql&amp;gt; create database testdb;
Query OK, 0 rows affected (0.54 sec)

mysql&amp;gt; exit
Bye
# 指定testdb库存储数据使用的集群
[root@mycat ~]# vim /usr/local/mycat/conf/schemas/testdb.schema.json
{
        &quot;customTables&quot;:{},
        &quot;globalTables&quot;:{},
        &quot;normalProcedures&quot;:{},
        &quot;normalTables&quot;:{},
        &quot;schemaName&quot;:&quot;testdb&quot;,
        &quot;targetName&quot;:&quot;rwcluster&quot;, 添加此行,之前创建的集群名rwcluster
        &quot;shardingTables&quot;:{},
        &quot;views&quot;:{}
}
:wq

[root@mycat ~]# /usr/local/mycat/bin/mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...


# 连接mycat 服务建表插入记录
[root@mycat ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321 
mysql&amp;gt; create table testdb.user (name varchar(10), password varchar(10));
Query OK, 0 rows affected (3.52 sec)

mysql&amp;gt; insert into testdb.user values(&quot;yaya&quot;,&quot;123456&quot;);
Query OK, 1 row affected (0.39 sec)

mysql&amp;gt; select * from testdb.user;
+------+----------+
| name | password |
+------+----------+
| yaya | 123456   |
+------+----------+
1 row in set (0.02 sec)


# 测试读写分离
# 在从服务器本机插入记录，数据仅在从服务器有，主服务器没有
[root@slave1 ~]# mysql -uroot -p123 -e &apos;insert into testdb.user values(&quot;yayaA&quot;,&quot;654321&quot;)&apos;
mysql: [Warning] Using a password on the command line interface can be insecure.

[root@slave1 ~]# mysql -uroot -p123 -e &apos;select * from testdb.user&apos;
mysql: [Warning] Using a password on the command line interface can be insecure.
+-------+----------+
| name  | password |
+-------+----------+
| yaya  | 123456   |
| yayaA | 654321   |
+-------+----------+


# 主服务器数据不变，日志偏移量不不变
[root@master ~]# mysql -uroot -p123 -e &apos;select * from testdb.user&apos;
mysql: [Warning] Using a password on the command line interface can be insecure.
+------+----------+
| name | password |
+------+----------+
| yaya | 123456   |
+------+----------+

[root@master ~]# mysql -uroot -p123 -e &apos;show master status&apos;
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql56.000002 |     1503 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+

# 客户端连接mycat 服务读/写数据
#  查看到的是2条记录的行
mysql&amp;gt; select * from testdb.user;
+-------+----------+
| name  | password |
+-------+----------+
| yaya  | 123456   |
| yayaA | 654321   |
+-------+----------+
2 rows in set (1.34 sec)

#   插入记录
mysql&amp;gt; insert into testdb.user values(&quot;yayaB&quot;,&quot;123456&quot;);
Query OK, 1 row affected (0.14 sec)

mysql&amp;gt; select * from testdb.user;
+-------+----------+
| name  | password |
+-------+----------+
| yaya  | 123456   |
| yayaB | 123456   |
+-------+----------+
2 rows in set (0.00 sec)

# 在主服务器查看数据和日志偏移量
[root@master ~]# mysql -uroot -p123 -e &apos;select * from testdb.user&apos;
mysql: [Warning] Using a password on the command line interface can be insecure.
+-------+----------+
| name  | password |
+-------+----------+
| yaya  | 123456   |
| yayaB | 123456   |
+-------+----------+

[root@master ~]# mysql -uroot -p123 -e &apos;show master status&apos;
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql56.000002 |     1796 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+

# 客户端连接mycat 服务查看到的是3条记录
mysql&amp;gt; select * from testdb.user;
+-------+----------+
| name  | password |
+-------+----------+
| yaya  | 123456   |
| yayaA | 654321   |
| yayaB | 123456   |
+-------+----------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;假设已有一个 MySQL 双主双从的主从复制环境，现要使用 Mycat 实现读写分离，请写出 Mycat 的具体配置步骤和配置文件示例。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;# Mycat 核心配置步骤
# 1：确认 Mycat 环境（已安装 JDK 1.8+，Mycat 已部署）

# 2：配置 Mycat 数据源（4个节点，每个节点1个配置文件）
# 2.1 主库1数据源：masterA.datasource.json
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/masterA.datasource.json
{
  &quot;dbType&quot;: &quot;mysql&quot;,
  &quot;idleTimeout&quot;: 60000,
  &quot;initSqls&quot;: [],
  &quot;initSqlsGetConnection&quot;: true,
  &quot;instanceType&quot;: &quot;WRITE&quot;,  # 主库：写角色
  &quot;maxCon&quot;: 1000,
  &quot;maxConnectTimeout&quot;: 30000,
  &quot;maxRetryCount&quot;: 5,
  &quot;minCon&quot;: 1,
  &quot;name&quot;: &quot;masterA&quot;,  # 数据源名称（与拓扑标识一致）
  &quot;password&quot;: &quot;Mycat@123&quot;,
  &quot;type&quot;: &quot;JDBC&quot;,
  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.61:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
  &quot;user&quot;: &quot;mycat_user&quot;,
  &quot;weight&quot;: 1  # 写负载权重（双主权重相同，均分写请求）
}

# 2.2 主库2数据源：masterB.datasource.json
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/masterB.datasource.json
{
  &quot;dbType&quot;: &quot;mysql&quot;,
  &quot;idleTimeout&quot;: 60000,
  &quot;initSqls&quot;: [],
  &quot;initSqlsGetConnection&quot;: true,
  &quot;instanceType&quot;: &quot;WRITE&quot;,  # 主库：写角色（双主互备）
  &quot;maxCon&quot;: 1000,
  &quot;maxConnectTimeout&quot;: 30000,
  &quot;maxRetryCount&quot;: 5,
  &quot;minCon&quot;: 1,
  &quot;name&quot;: &quot;masterB&quot;,  # 数据源名称
  &quot;password&quot;: &quot;Mycat@123&quot;,
  &quot;type&quot;: &quot;JDBC&quot;,
  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.62:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
  &quot;user&quot;: &quot;mycat_user&quot;,
  &quot;weight&quot;: 1  # 与主库1权重一致，实现写负载均衡
}

# 2.3 从库1数据源：slaveA.datasource.json
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/slaveA.datasource.json
{
  &quot;dbType&quot;: &quot;mysql&quot;,
  &quot;idleTimeout&quot;: 60000,
  &quot;initSqls&quot;: [],
  &quot;initSqlsGetConnection&quot;: true,
  &quot;instanceType&quot;: &quot;READ&quot;,  # 从库：读角色
  &quot;maxCon&quot;: 1000,
  &quot;maxConnectTimeout&quot;: 30000,
  &quot;maxRetryCount&quot;: 5,
  &quot;minCon&quot;: 1,
  &quot;name&quot;: &quot;slaveA&quot;,  # 数据源名称
  &quot;password&quot;: &quot;Mycat@123&quot;,
  &quot;type&quot;: &quot;JDBC&quot;,
  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.63:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
  &quot;user&quot;: &quot;mycat_user&quot;,
  &quot;weight&quot;: 1  # 读负载权重（双从权重相同，均分读请求）
}

# 2.4 从库2数据源：slaveB.datasource.json
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/slaveB.datasource.json
{
  &quot;dbType&quot;: &quot;mysql&quot;,
  &quot;idleTimeout&quot;: 60000,
  &quot;initSqls&quot;: [],
  &quot;initSqlsGetConnection&quot;: true,
  &quot;instanceType&quot;: &quot;READ&quot;,  # 从库：读角色
  &quot;maxCon&quot;: 1000,
  &quot;maxConnectTimeout&quot;: 30000,
  &quot;maxRetryCount&quot;: 5,
  &quot;minCon&quot;: 1,
  &quot;name&quot;: &quot;slaveB&quot;,  # 数据源名称
  &quot;password&quot;: &quot;Mycat@123&quot;,
  &quot;type&quot;: &quot;JDBC&quot;,
  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.64:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
  &quot;user&quot;: &quot;mycat_user&quot;,
  &quot;weight&quot;: 1  # 与从库1权重一致，实现读负载均衡
}

# 3：配置 Mycat 集群（核心：双主双从读写策略）
[root@mycat ~]# vim /usr/local/mycat/conf/clusters/dual_master_dual_slave.cluster.json
{
  &quot;clusterType&quot;: &quot;MASTER_SLAVE&quot;,  # 集群类型：主从架构（支持双主）
  &quot;heartbeat&quot;: {  # 心跳检测（监测节点存活）
    &quot;heartbeatTimeout&quot;: 1000,
    &quot;maxRetryCount&quot;: 3,
    &quot;minSwitchTimeInterval&quot;: 300,  # 故障切换最小间隔（毫秒）
    &quot;showLog&quot;: false,
    &quot;slaveThreshold&quot;: 0.5  # 从库同步延迟阈值（秒），超过则剔除
  },
  &quot;masters&quot;: [&quot;masterA&quot;, &quot;masterB&quot;],  # 双主数据源名称（写请求路由到这里）
  &quot;maxCon&quot;: 4000,  # 集群最大连接数（4个节点总和）
  &quot;name&quot;: &quot;dual_master_dual_slave&quot;,  # 集群名称（后续关联逻辑库用）
  &quot;readBalanceType&quot;: &quot;BALANCE_ALL_READ&quot;,  # 读负载策略：所有从库均分读请求
  &quot;replicas&quot;: [&quot;slaveA&quot;, &quot;slaveB&quot;],  # 双从数据源名称（读请求路由到这里）
  &quot;switchType&quot;: &quot;SWITCH&quot;,  # 故障切换策略：自动切换（主库故障时切换到备用主库）
  &quot;writeBalanceType&quot;: &quot;BALANCE_ALL_WRITE&quot;  # 写负载策略：双主均分写请求（核心！双主特色）
}

# 4：配置 Mycat 逻辑库（关联集群）
[root@mycat mycat]# vim /usr/local/mycat/conf/schemas/business.schema.json
{
  &quot;customTables&quot;: {},
  &quot;globalTables&quot;: {},
  &quot;normalProcedures&quot;: {},
  &quot;normalTables&quot;: {},
  &quot;schemaName&quot;: &quot;business&quot;,  # 逻辑库名称（应用连接 Mycat 时使用）
  &quot;targetName&quot;: &quot;dual_master_dual_slave&quot;,  # 关联上面创建的集群名称
  &quot;shardingTables&quot;: {},
  &quot;views&quot;: {}
}

# 5：配置 Mycat 访问用户（可选，若已配置可跳过）
[root@mycat ~]# vim /usr/local/mycat/conf/users/mycat_user.user.json
{
  &quot;dialect&quot;: &quot;mysql&quot;,
  &quot;ip&quot;: null,  # 允许所有IP访问（生产环境可指定IP）
  &quot;password&quot;: &quot;Mycat@666&quot;,  # 应用连接 Mycat 的密码
  &quot;transactionType&quot;: &quot;proxy&quot;,
  &quot;username&quot;: &quot;mycat_app&quot;  # 应用连接 Mycat 的用户名
}

# **启动与验证**
# 重启 Mycat 加载配置
[root@mycat ~]# /usr/local/mycat/bin/mycat restart

# 2.1 连接 Mycat 逻辑库
[root@mycat ~]# mysql -h 127.0.0.1 -P 8066 -u mycat_app -pMycat@666
mysql&amp;gt; -- 查看逻辑库
mysql&amp;gt; show databases;
mysql&amp;gt; -- 查看 Mycat 数据源状态
mysql&amp;gt; /*+ mycat:showDataSources{}*/ \G
mysql&amp;gt; -- 查看集群状态
mysql&amp;gt; /*+ mycat:showClusters{}*/ \G

-- **验证读写分离效果**
mysql&amp;gt; -- 写操作（插入数据，会路由到双主之一）
mysql&amp;gt; use business;
mysql&amp;gt; create table test_user (id int primary key auto_increment, name varchar(20));
mysql&amp;gt; insert into test_user (name) values (&quot;user1&quot;), (&quot;user2&quot;);

# 直接连接 masterA 查看双主数据
[root@mycat ~]# mysql -h 192.168.90.61 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
# 直接连接 masterB 查看双主数据
[root@mycat ~]# mysql -h 192.168.90.62 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;

# 查看双从数据
[root@mycat ~]# mysql -h 192.168.90.63 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
[root@mycat ~]# mysql -h 192.168.90.64 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# Mycat 实现 MySQL 双主双从读写分离（配置步骤+文件示例）
## 一、环境前提（已就绪）
假设双主双从复制环境已搭建完成（**核心前提：双主互为主从，主从数据同步正常**），拓扑如下：
| 节点角色       | IP地址         | 端口 | 数据库用户 | 密码   | 实例标识（Mycat中用） |
|----------------|----------------|------|------------|--------|-----------------------|
| 主库1（MasterA） | 192.168.90.61  | 3306 | mycat_user | Mycat@123 | masterA               |
| 主库2（MasterB） | 192.168.90.62  | 3306 | mycat_user | Mycat@123 | masterB               |
| 从库1（SlaveA）  | 192.168.90.63  | 3306 | mycat_user | Mycat@123 | slaveA                |
| 从库2（SlaveB）  | 192.168.90.64  | 3306 | mycat_user | Mycat@123 | slaveB                |

### 双主双从复制要求
- 双主已配置 **互为主从**（MasterA → MasterB 同步，MasterB → MasterA 同步），支持写负载或故障切换；
- 每个主库对应从库同步正常（MasterA → SlaveA，MasterB → SlaveB），`Slave_IO_Running=Yes` 且 `Slave_SQL_Running=Yes`；
- 所有节点已创建 Mycat 访问用户（`mycat_user`），并授予权限：`GRANT ALL ON *.* TO &apos;mycat_user&apos;@&apos;%&apos; IDENTIFIED WITH mysql_native_password BY &apos;Mycat@123&apos;;`

## 二、Mycat 核心配置步骤（基于 Mycat 2.x，与你之前版本一致）
### 步骤1：确认 Mycat 环境（已安装 JDK 1.8+，Mycat 2.x 已部署）
无需额外安装，仅需配置以下文件（路径：`/usr/local/mycat/conf/`）。

### 步骤2：配置 Mycat 数据源（4个节点，每个节点1个配置文件）
在 `conf/datasources/` 目录下，创建4个数据源配置文件（描述每个 MySQL 节点的连接信息）。

#### 2.1 主库1数据源：masterA.datasource.json
	```json
	{
	  &quot;dbType&quot;: &quot;mysql&quot;,
	  &quot;idleTimeout&quot;: 60000,
	  &quot;initSqls&quot;: [],
	  &quot;initSqlsGetConnection&quot;: true,
	  &quot;instanceType&quot;: &quot;WRITE&quot;,  // 主库：写角色
	  &quot;maxCon&quot;: 1000,
	  &quot;maxConnectTimeout&quot;: 30000,
	  &quot;maxRetryCount&quot;: 5,
	  &quot;minCon&quot;: 1,
	  &quot;name&quot;: &quot;masterA&quot;,  // 数据源名称（与拓扑标识一致）
	  &quot;password&quot;: &quot;Mycat@123&quot;,
	  &quot;type&quot;: &quot;JDBC&quot;,
	  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.61:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
	  &quot;user&quot;: &quot;mycat_user&quot;,
	  &quot;weight&quot;: 1  // 写负载权重（双主权重相同，均分写请求）
	}
	```

#### 2.2 主库2数据源：masterB.datasource.json
	```json
	{
	  &quot;dbType&quot;: &quot;mysql&quot;,
	  &quot;idleTimeout&quot;: 60000,
	  &quot;initSqls&quot;: [],
	  &quot;initSqlsGetConnection&quot;: true,
	  &quot;instanceType&quot;: &quot;WRITE&quot;,  // 主库：写角色（双主互备）
	  &quot;maxCon&quot;: 1000,
	  &quot;maxConnectTimeout&quot;: 30000,
	  &quot;maxRetryCount&quot;: 5,
	  &quot;minCon&quot;: 1,
	  &quot;name&quot;: &quot;masterB&quot;,  // 数据源名称
	  &quot;password&quot;: &quot;Mycat@123&quot;,
	  &quot;type&quot;: &quot;JDBC&quot;,
	  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.62:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
	  &quot;user&quot;: &quot;mycat_user&quot;,
	  &quot;weight&quot;: 1  // 与主库1权重一致，实现写负载均衡
	}
	```

#### 2.3 从库1数据源：slaveA.datasource.json
	```json
	{
	  &quot;dbType&quot;: &quot;mysql&quot;,
	  &quot;idleTimeout&quot;: 60000,
	  &quot;initSqls&quot;: [],
	  &quot;initSqlsGetConnection&quot;: true,
	  &quot;instanceType&quot;: &quot;READ&quot;,  // 从库：读角色
	  &quot;maxCon&quot;: 1000,
	  &quot;maxConnectTimeout&quot;: 30000,
	  &quot;maxRetryCount&quot;: 5,
	  &quot;minCon&quot;: 1,
	  &quot;name&quot;: &quot;slaveA&quot;,  // 数据源名称
	  &quot;password&quot;: &quot;Mycat@123&quot;,
	  &quot;type&quot;: &quot;JDBC&quot;,
	  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.63:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
	  &quot;user&quot;: &quot;mycat_user&quot;,
	  &quot;weight&quot;: 1  // 读负载权重（双从权重相同，均分读请求）
	}
	```

#### 2.4 从库2数据源：slaveB.datasource.json
	```json
	{
	  &quot;dbType&quot;: &quot;mysql&quot;,
	  &quot;idleTimeout&quot;: 60000,
	  &quot;initSqls&quot;: [],
	  &quot;initSqlsGetConnection&quot;: true,
	  &quot;instanceType&quot;: &quot;READ&quot;,  // 从库：读角色
	  &quot;maxCon&quot;: 1000,
	  &quot;maxConnectTimeout&quot;: 30000,
	  &quot;maxRetryCount&quot;: 5,
	  &quot;minCon&quot;: 1,
	  &quot;name&quot;: &quot;slaveB&quot;,  // 数据源名称
	  &quot;password&quot;: &quot;Mycat@123&quot;,
	  &quot;type&quot;: &quot;JDBC&quot;,
	  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.64:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
	  &quot;user&quot;: &quot;mycat_user&quot;,
	  &quot;weight&quot;: 1  // 与从库1权重一致，实现读负载均衡
	}
	```

### 步骤3：配置 Mycat 集群（核心：双主双从读写策略）
在 `conf/clusters/` 目录下，创建集群配置文件 `dual_master_dual_slave.cluster.json`，定义主从关系、负载策略、故障切换规则。

	```json
	{
	  &quot;clusterType&quot;: &quot;MASTER_SLAVE&quot;,  // 集群类型：主从架构（支持双主）
	  &quot;heartbeat&quot;: {  // 心跳检测（监测节点存活）
	    &quot;heartbeatTimeout&quot;: 1000,
	    &quot;maxRetryCount&quot;: 3,
	    &quot;minSwitchTimeInterval&quot;: 300,  // 故障切换最小间隔（秒）
	    &quot;showLog&quot;: false,
	    &quot;slaveThreshold&quot;: 0.5  // 从库同步延迟阈值（秒），超过则剔除
	  },
	  &quot;masters&quot;: [&quot;masterA&quot;, &quot;masterB&quot;],  // 双主数据源名称（写请求路由到这里）
	  &quot;maxCon&quot;: 4000,  // 集群最大连接数（4个节点总和）
	  &quot;name&quot;: &quot;dual_master_dual_slave&quot;,  // 集群名称（后续关联逻辑库用）
	  &quot;readBalanceType&quot;: &quot;BALANCE_ALL_READ&quot;,  // 读负载策略：所有从库均分读请求
	  &quot;replicas&quot;: [&quot;slaveA&quot;, &quot;slaveB&quot;],  // 双从数据源名称（读请求路由到这里）
	  &quot;switchType&quot;: &quot;SWITCH&quot;,  // 故障切换策略：自动切换（主库故障时切换到备用主库）
	  &quot;writeBalanceType&quot;: &quot;BALANCE_ALL_WRITE&quot;  // 写负载策略：双主均分写请求（核心！双主特色）
	}
	```

### 步骤4：配置 Mycat 逻辑库（关联集群）
在 `conf/schemas/` 目录下，创建逻辑库配置文件（例如 `business.schema.json`），指定业务逻辑库与集群的关联。

	```json
	{
	  &quot;customTables&quot;: {},
	  &quot;globalTables&quot;: {},
	  &quot;normalProcedures&quot;: {},
	  &quot;normalTables&quot;: {},
	  &quot;schemaName&quot;: &quot;business&quot;,  // 逻辑库名称（应用连接 Mycat 时使用）
	  &quot;targetName&quot;: &quot;dual_master_dual_slave&quot;,  // 关联上面创建的集群名称
	  &quot;shardingTables&quot;: {},
	  &quot;views&quot;: {}
	}
	```

### 步骤5：配置 Mycat 访问用户（可选，若已配置可跳过）
在 `conf/users/` 目录下，创建用户配置文件 `mycat_user.user.json`，定义应用连接 Mycat 的账号密码。

	```json
	{
	  &quot;dialect&quot;: &quot;mysql&quot;,
	  &quot;ip&quot;: null,  // 允许所有IP访问（生产环境可指定IP）
	  &quot;password&quot;: &quot;Mycat@666&quot;,  // 应用连接 Mycat 的密码
	  &quot;transactionType&quot;: &quot;proxy&quot;,
	  &quot;username&quot;: &quot;mycat_app&quot;  // 应用连接 Mycat 的用户名
	}
	```

## 三、关键配置说明（双主双从核心亮点）
1. **双主写负载均衡**：通过 `writeBalanceType: &quot;BALANCE_ALL_WRITE&quot;` + 双主 `instanceType: &quot;WRITE&quot;`，写请求会均匀分发到两个主库，分摊写压力；
2. **双从读负载均衡**：通过 `readBalanceType: &quot;BALANCE_ALL_READ&quot;` + 双从 `instanceType: &quot;READ&quot;`，读请求均匀分发到两个从库，最大化读性能；
3. **故障自动切换**：
   - 主库故障（如 masterA 宕机）：Mycat 通过心跳检测发现后，自动将写请求切换到 masterB，业务无感知；
   - 从库故障（如 slaveA 宕机）：自动剔除故障从库，读请求仅分发到正常从库（slaveB），不影响业务；
4. **同步延迟过滤**：`slaveThreshold: 0.5` 表示从库同步延迟超过 0.5 秒时，Mycat 会暂时剔除该从库，避免读旧数据。

## 四、启动与验证
### 1. 启动 Mycat
	```bash
	# 重启 Mycat 加载配置
	/usr/local/mycat/bin/mycat restart
	
	# 查看启动状态（确保 8066 端口监听）
	netstat -tunlp | grep 8066
	```

### 2. 验证配置正确性
#### 2.1 连接 Mycat 逻辑库
	```bash
	mysql -h 192.168.90.58 -P 8066 -u mycat_app -pMycat@666
	```

#### 2.2 验证逻辑库与集群关联
	```sql
	-- 查看逻辑库
	show databases;
	-- 应输出：business（配置的逻辑库名称）
	
	-- 查看 Mycat 数据源状态（Mycat 2.x 专用命令）
	/*+ mycat:showDataSources{}*/ \G
	-- 应显示 4 个数据源（masterA、masterB、slaveA、slaveB），状态为 OK
	
	-- 查看集群状态
	/*+ mycat:showClusters{}*/ \G
	-- 应显示集群 dual_master_dual_slave，主从节点正常
	```

#### 2.3 验证读写分离效果
	```sql
	-- 1. 写操作（插入数据，会路由到双主之一）
	use business;
	create table test_user (id int primary key auto_increment, name varchar(20));
	insert into test_user (name) values (&quot;user1&quot;), (&quot;user2&quot;);
	
	-- 2. 查看双主数据（均应存在插入的数据，证明双主同步正常）
	-- 直接连接 masterA 查看
	mysql -h 192.168.90.61 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
	-- 直接连接 masterB 查看
	mysql -h 192.168.90.62 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
	
	-- 3. 查看双从数据（均应同步主库数据，证明主从同步正常）
	mysql -h 192.168.90.63 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
	mysql -h 192.168.90.64 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
	
	-- 4. 读操作（通过 Mycat 查询，会路由到双从之一）
	-- 多次执行，观察 Mycat 日志（conf/logs/mycat.log），确认读请求分流到 slaveA/slaveB
	select * from test_user;
	```

## 五、注意事项
1. **双主复制前提**：必须确保双主互为主从配置正确（开启 GTID 模式最佳，避免同步冲突）；
2. **权限统一**：所有 MySQL 节点的 `mycat_user` 权限必须一致（至少拥有业务库的读写权限）；
3. **生产环境优化**：
   - 限制 Mycat 访问 IP（在用户配置文件中指定 `ip: &quot;192.168.90.0/24&quot;`）；
   - 调整 `maxCon`（连接数）、`idleTimeout`（空闲超时）适配业务压力；
   - 开启 Mycat 日志审计，便于排查问题；
4. **避免写冲突**：双主架构下，若同一表存在并发写，需确保表有主键（或唯一索引），避免同步报错。

## 总结
双主双从的 Mycat 配置核心是 **“数据源分角色（双主WRITE/双从READ）+ 集群配置写负载/读负载/故障切换”**，配置步骤与单主多从一致，仅需在集群中增加主库数据源、启用写负载策略即可。你的单主多从配置思路完全可复用，只需扩展数据源和调整集群参数，放心按此方案提交作业！
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;当 Mycat 服务启动失败，如何进行故障排查和解决，请给出详细的操作流程。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
### 一、检查启动状态与基础环境
1. **查看启动状态与错误提示**
    - 用`/usr/local/mycat/bin/mycat status`查看运行状态。
    - 手动启动并观察报错：`/usr/local/mycat/bin/mycat start 2&amp;gt;&amp;amp;1 | grep -E &quot;ERROR|Exception&quot;`。
    - 若提示“command not found”，用`find / -name &quot;mycat&quot; 2&amp;gt;/dev/null`找正确路径。
2. **验证 JDK 环境**
    - 检查版本：`java -version`。
    - 检查环境变量：`echo $JAVA_HOME`。
    - 未配置则临时配置：`export JAVA_HOME=/usr/lib/jvm/java - 1.8.0 - openjdk; export PATH=$PATH:$JAVA_HOME/bin`。
    - 永久配置：在`/etc/profile`添加配置并`source /etc/profile`。

### 二、查看核心日志
日志默认路径`/usr/local/mycat/conf/logs/`：
1. **主日志 mycat.log**：`tail -100 /usr/local/mycat/conf/logs/mycat.log | grep -E &quot;ERROR|WARN|Exception&quot;`。
2. **启动器日志 wrapper.log**：`tail -100 /usr/local/mycat/conf/logs/wrapper.log | grep -E &quot;ERROR|FATAL&quot;`。

### 三、排查配置文件错误
1. **检查语法**：用`jq`工具校验 JSON 格式配置文件。
2. **检查关键参数**：核对`datasources`、`clusters`、`schemas`、`users`配置文件参数。

### 四、排查端口占用问题
Mycat 默认用 8066 和 9066 端口：
1. 用`netstat -tunlp | grep`或`lsof -i:`检查端口占用。
2. 停止占用进程或修改`/usr/local/mycat/conf/mycat.properties`中的端口。

### 五、排查权限与目录访问问题
1. 检查目录权限，不足则`chmod -R 755 /usr/local/mycat/`。
2. 检查日志目录写入权限，可`chmod 777 /usr/local/mycat/conf/logs/`。
3. 检查运行用户，必要时修改目录所有者。

### 六、排查数据源连接问题
1. 测试网络连通性：`telnet`或`nc`。
2. 验证账号密码，检查账号存在性、权限和服务状态。
3. 检查防火墙/安全组，放行 3306 端口。

### 七、排查依赖与元数据问题（Mycat 2.x 特有）
1. 检查原型库配置文件。
2. 验证原型库连接。
3. 检查依赖 jar 包，缺失则手动下载。

### 八、极端情况：恢复默认配置，逐步测试
1. 备份当前配置。
2. 删除自定义配置。
3. 恢复默认原型库配置。
4. 启动 Mycat。
5. 逐步添加自定义配置并测试。
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# Mycat 服务启动失败：故障排查与解决完整操作流程
Mycat 启动失败的核心原因集中在 **环境依赖、配置错误、端口占用、权限不足、数据源连接异常** 五类，排查需遵循“从基础到深入、从日志到配置”的逻辑，逐步定位问题。以下是详细操作流程（基于 Mycat 2.x，兼容 1.x 核心思路）：


## 一、第一步：检查启动状态与基础环境（快速排除低级问题）
### 1. 查看 Mycat 启动状态与错误提示
首先通过官方命令查看启动状态，获取直接报错信息：
	```bash
	# 1. 查看 Mycat 运行状态（Mycat 2.x 命令）
	/usr/local/mycat/bin/mycat status
	
	# 2. 尝试手动启动，观察实时报错（关键！直接输出启动失败原因）
	/usr/local/mycat/bin/mycat start 2&amp;gt;&amp;amp;1 | grep -E &quot;ERROR|Exception&quot;
	
	# 3. 若提示“command not found”，确认 Mycat 安装路径正确
	find / -name &quot;mycat&quot; 2&amp;gt;/dev/null  # 找到正确路径（如 /opt/mycat），替换执行
	```
#### 常见状态与初步判断：
- 提示“not running”：服务未启动，需进一步查日志；
- 提示“Invalid JAVA_HOME”：JDK 环境未配置；
- 提示“Address already in use”：端口被占用；
- 提示“Could not load configuration”：配置文件错误。

### 2. 验证核心依赖：JDK 环境（Mycat 必需）
Mycat 依赖 JDK 1.8+（1.x 支持 1.7，2.x 强制 1.8+），先确认环境：
	```bash
	# 1. 检查 JDK 版本
	java -version
	# 正常输出示例：openjdk version &quot;1.8.0_382&quot;（需 1.8+，低于则报错）
	
	# 2. 检查 JAVA_HOME 环境变量
	echo $JAVA_HOME
	# 正常输出示例：/usr/lib/jvm/java-1.8.0-openjdk
	
	# 3. 若未配置 JAVA_HOME，手动配置（临时生效）
	export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk
	export PATH=$PATH:$JAVA_HOME/bin
	
	# 4. 永久配置（避免重启失效）
	echo &apos;export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk&apos; &amp;gt;&amp;gt; /etc/profile
	echo &apos;export PATH=$PATH:$JAVA_HOME/bin&apos; &amp;gt;&amp;gt; /etc/profile
	source /etc/profile
	```
#### 问题解决：
- 无 JDK：执行 `yum -y install java-1.8.0-openjdk.x86_64`（CentOS）安装；
- JDK 版本过低：卸载旧版本，重新安装 1.8+。


## 二、第二步：查看核心日志（定位问题关键）
Mycat 启动失败的详细原因会记录在日志中，优先查看以下 2 个核心日志文件（默认路径：`/usr/local/mycat/conf/logs/`）：

### 1. 主日志：mycat.log（记录配置加载、数据源连接、启动流程错误）
	```bash
	# 查看日志最后 100 行（聚焦最新错误）
	tail -100 /usr/local/mycat/conf/logs/mycat.log | grep -E &quot;ERROR|WARN|Exception&quot;
	
	# 若日志过大，搜索关键词定位
	grep -n &quot;Failed to&quot; /usr/local/mycat/conf/logs/mycat.log  # 搜索失败相关记录
	```

### 2. 启动器日志：wrapper.log（记录 JVM 启动、进程启动失败原因）
	```bash
	tail -100 /usr/local/mycat/conf/logs/wrapper.log | grep -E &quot;ERROR|FATAL&quot;
	```

#### 日志常见错误与对应解决：
| 日志错误关键词                | 问题原因                          | 快速解决                          |
|-----------------------------|-----------------------------------|-----------------------------------|
| Invalid JSON syntax         | 配置文件（.json）语法错误          | 检查对应 JSON 文件的逗号、引号闭合 |
| Could not connect to datasource | 数据源（MySQL）连接失败           | 验证 MySQL 地址、账号密码、网络连通性 |
| Address already in use: 8066 | 8066/9066 端口被占用              | 查找并停止占用进程，或修改 Mycat 端口 |
| Permission denied           | Mycat 目录/文件权限不足            | 赋予读写权限：chmod -R 755 /usr/local/mycat |
| Missing jar包名              | 依赖 jar 包缺失                    | 从安装包复制缺失 jar 到 lib 目录  |


## 三、第三步：排查配置文件错误（最常见原因）
Mycat 启动时会加载 `datasources`（数据源）、`clusters`（集群）、`schemas`（逻辑库）、`users`（用户）四类核心配置文件，JSON 语法错误、参数配置错误是主要诱因。

### 1. 检查配置文件语法（JSON 格式必须严格）
Mycat 2.x 配置文件均为 JSON 格式，逗号、引号、大括号不闭合会直接导致启动失败，用 `jq` 工具验证：
	```bash
	# 1. 安装 jq 工具（JSON 语法校验）
	yum -y install jq
	
	# 2. 逐个校验核心配置文件（以 datasources 为例）
	# 校验数据源配置（所有 .datasource.json 文件）
	for file in /usr/local/mycat/conf/datasources/*.json; do
	  echo &quot;校验文件：$file&quot;
	  jq . $file  # 语法错误会直接提示行号
	done
	
	# 3. 同理校验集群、逻辑库、用户配置
	for file in /usr/local/mycat/conf/clusters/*.json; do jq . $file; done
	for file in /usr/local/mycat/conf/schemas/*.json; do jq . $file; done
	for file in /usr/local/mycat/conf/users/*.json; do jq . $file; done
	```
#### 语法错误示例与修复：
- 错误：`{&quot;name&quot;:&quot;masterA&quot;, &quot;password&quot;:&quot;123&quot;}`（末尾多逗号）
- 修复：`{&quot;name&quot;:&quot;masterA&quot;, &quot;password&quot;:&quot;123&quot;}`（删除末尾逗号）

### 2. 检查关键配置参数（参数错误导致启动失败）
重点核对以下核心参数（配置文件中最易出错）：
#### 2.1 数据源配置（datasources/*.json）
	```json
	{
	  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.61:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&quot;,  // 确保 IP、端口正确
	  &quot;user&quot;: &quot;mycat_user&quot;,  // MySQL 账号存在且有权限
	  &quot;password&quot;: &quot;Mycat@123&quot;,  // 密码正确
	  &quot;instanceType&quot;: &quot;WRITE&quot;,  // 取值只能是 WRITE/READ/READ_WRITE（大小写敏感）
	  &quot;dbType&quot;: &quot;mysql&quot;  // 不能写错（如写成 &quot;mysql8&quot; 无效）
	}
	```

#### 2.2 集群配置（clusters/*.json）
	```json
	{
	  &quot;name&quot;: &quot;dual_master_dual_slave&quot;,
	  &quot;masters&quot;: [&quot;masterA&quot;, &quot;masterB&quot;],  // 数据源名称必须与 datasources 中一致
	  &quot;replicas&quot;: [&quot;slaveA&quot;, &quot;slaveB&quot;],  // 同上，不能拼写错误
	  &quot;clusterType&quot;: &quot;MASTER_SLAVE&quot;,  // 取值只能是 MASTER_SLAVE/SINGLE/CLUSTER
	  &quot;writeBalanceType&quot;: &quot;BALANCE_ALL_WRITE&quot;  // 取值符合 Mycat 规则
	}
	```

#### 2.3 逻辑库配置（schemas/*.json）
	```json
	{
	  &quot;schemaName&quot;: &quot;business&quot;,
	  &quot;targetName&quot;: &quot;dual_master_dual_slave&quot;  // 集群名称必须与 clusters 中一致
	}
	```

#### 2.4 用户配置（users/*.json）
	```json
	{
	  &quot;username&quot;: &quot;mycat_app&quot;,
	  &quot;password&quot;: &quot;Mycat@666&quot;,  // 不能包含特殊字符（如 @ 需转义，或直接用简单密码测试）
	  &quot;dialect&quot;: &quot;mysql&quot;  // 不能写错
	}
	```


## 四、第四步：排查端口占用问题
Mycat 默认占用 2 个端口：
- 8066：业务端口（应用连接 Mycat 用）
- 9066：管理端口（Mycat 管理命令用）
端口被占用会直接导致启动失败，排查流程：
	```bash
	# 1. 检查 8066 端口占用情况
	netstat -tunlp | grep 8066
	# 或用 lsof（更详细）
	lsof -i:8066
	
	# 2. 检查 9066 端口占用情况
	netstat -tunlp | grep 9066
	
	# 3. 若有占用进程，停止该进程（示例：PID 为 1234）
	kill -9 1234
	
	# 4. 若无法停止占用进程，修改 Mycat 端口（Mycat 2.x 配置）
	vi /usr/local/mycat/conf/mycat.properties
	# 修改以下参数（自定义未占用端口）
	server.port=8067  # 新业务端口
	manager.port=9067  # 新管理端口
	
	# 5. 重启 Mycat 测试
	/usr/local/mycat/bin/mycat restart
	```


## 五、第五步：排查权限与目录访问问题
Mycat 启动时需要读取配置文件、写入日志，权限不足会导致“Permission denied”错误：
	```bash
	# 1. 检查 Mycat 安装目录权限
	ls -ld /usr/local/mycat/
	# 正常权限：drwxr-xr-x（所有者、组有读写执行权限）
	
	# 2. 赋予完整权限（临时测试，生产环境可收紧）
	chmod -R 755 /usr/local/mycat/
	
	# 3. 检查日志目录写入权限（关键！日志写不进去会启动失败）
	ls -ld /usr/local/mycat/conf/logs/
	chmod 777 /usr/local/mycat/conf/logs/  # 临时赋予最大权限测试
	
	# 4. 检查运行用户（若用非 root 用户启动，需确保用户有目录权限）
	ps -ef | grep mycat  # 查看运行用户
	chown -R mycat:mycat /usr/local/mycat/  # 若用 mycat 用户，修改目录所有者
	```


## 六、第六步：排查数据源连接问题
若数据源（MySQL 主从节点）配置错误或无法连通，Mycat 启动时会因“连接数据源失败”报错：
	```bash
	# 1. 手动测试 Mycat 到 MySQL 数据源的网络连通性（以 masterA 为例）
	telnet 192.168.90.61 3306
	# 或用 nc 命令
	nc -zv 192.168.90.61 3306
	# 正常输出：succeeded!（失败则检查防火墙/安全组）
	
	# 2. 手动验证 MySQL 账号密码正确性（用 Mycat 配置的账号）
	mysql -h 192.168.90.61 -u mycat_user -pMycat@123
	# 若登录失败，检查：
	# - MySQL 账号是否存在：SELECT user, host FROM mysql.user WHERE user=&apos;mycat_user&apos;;
	# - 账号权限是否足够：GRANT ALL ON *.* TO &apos;mycat_user&apos;@&apos;%&apos; IDENTIFIED WITH mysql_native_password BY &apos;Mycat@123&apos;;
	# - MySQL 服务是否正常：systemctl status mysqld
	
	# 3. 检查 MySQL 防火墙/安全组（放行 3306 端口）
	firewall-cmd --zone=public --add-port=3306/tcp --permanent
	firewall-cmd --reload
	```


## 七、第七步：排查依赖与元数据问题（Mycat 2.x 特有）
Mycat 2.x 依赖“原型库（prototypeDs）”存储元数据，原型库配置错误会导致启动失败：
	```bash
	# 1. 检查原型库配置文件
	cat /usr/local/mycat/conf/datasources/prototypeDs.datasource.json
	# 核心要求：原型库必须是可连接的 MySQL 实例（可复用主库/独立库）
	
	# 2. 验证原型库连接
	mysql -h 192.168.90.61 -u mycat_user -pMycat@123  # 原型库配置的账号密码
	
	# 3. 检查依赖 jar 包（缺失会导致类加载失败）
	ls /usr/local/mycat/lib/ | grep -E &quot;mycat2|mysql-connector-java&quot;
	# 若缺失 mysql-connector-java（MySQL 驱动），手动下载放入 lib 目录
	wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.33/mysql-connector-java-8.0.33.jar -P /usr/local/mycat/lib/
	```


## 八、第八步：极端情况：恢复默认配置，逐步测试
若以上排查均无效，可能是配置文件错乱，可通过“恢复默认+逐步添加配置”定位问题：
	```bash
	# 1. 备份当前配置（避免丢失）
	cp -r /usr/local/mycat/conf /usr/local/mycat/conf_bak_$(date +%Y%m%d)
	
	# 2. 删除自定义配置（保留默认原型库和用户配置）
	rm -rf /usr/local/mycat/conf/datasources/*.json
	rm -rf /usr/local/mycat/conf/clusters/*.json
	rm -rf /usr/local/mycat/conf/schemas/*.json
	
	# 3. 恢复默认原型库配置（从安装包复制，或手动创建）
	cat &amp;gt; /usr/local/mycat/conf/datasources/prototypeDs.datasource.json &amp;lt;&amp;lt; EOF
	{
	  &quot;dbType&quot;:&quot;mysql&quot;,
	  &quot;idleTimeout&quot;:60000,
	  &quot;initSqls&quot;:[],
	  &quot;initSqlsGetConnection&quot;:true,
	  &quot;instanceType&quot;:&quot;READ_WRITE&quot;,
	  &quot;maxCon&quot;:1000,
	  &quot;maxConnectTimeout&quot;:3000,
	  &quot;maxRetryCount&quot;:5,
	  &quot;minCon&quot;:1,
	  &quot;name&quot;:&quot;prototypeDs&quot;,
	  &quot;password&quot;:&quot;Mycat@123&quot;,
	  &quot;type&quot;:&quot;JDBC&quot;,
	  &quot;url&quot;:&quot;jdbc:mysql://192.168.90.61:3306/mysql?serverTimezone=Asia/Shanghai&quot;,
	  &quot;user&quot;:&quot;mycat_user&quot;,
	  &quot;weight&quot;:0
	}
	EOF
	
	# 4. 启动 Mycat（若能启动，说明默认配置正常，问题在自定义配置）
	/usr/local/mycat/bin/mycat start
	
	# 5. 逐步添加自定义配置（每次添加一个文件，重启测试）
	# 先添加一个数据源 → 启动测试
	# 再添加集群 → 启动测试
	# 最后添加逻辑库 → 启动测试
	# 定位到导致失败的具体配置文件，针对性修改
	```


## 九、常见故障案例与快速解决
| 故障现象                          | 排查流程                          | 解决方法                          |
|-----------------------------------|-----------------------------------|-----------------------------------|
| 执行 mycat start 无反应，日志无输出 | 1. 检查 JAVA_HOME；2. 检查 wrapper.log | 配置 JAVA_HOME，或重新安装 Mycat 启动器 |
| 启动提示“数据源连接失败”           | 1. telnet 测试 MySQL 端口；2. 验证账号密码 | 放行 3306 端口，重新创建 MySQL 账号并授权 |
| JSON 语法错误导致启动失败          | 用 jq 工具校验所有配置文件         | 修复逗号、引号、大括号闭合问题    |
| 8066 端口被占用                    | netstat 查找占用进程               | 停止占用进程，或修改 Mycat 端口   |
| 权限不足“Permission denied”        | 检查 Mycat 目录权限               | chmod -R 755 /usr/local/mycat     |


## 十、排查总结（核心逻辑）
Mycat 启动失败排查遵循“**先基础（环境、端口、权限）→ 再日志（定位方向）→ 最后配置（精准修复）** ”的逻辑，90% 的问题集中在：
1. JDK 环境未配置或版本过低；
2. 配置文件（JSON）语法错误；
3. 数据源（MySQL）连接失败（IP/端口/账号/防火墙）；
4. 8066/9066 端口被占用；
5. Mycat 目录权限不足。

按以上流程逐步排查，均可定位并解决问题。若仍失败，可提供 `mycat.log` 和 `wrapper.log` 中的错误关键词，进一步精准分析。
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>11：mysql之分库分表</title><link>https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/11-mysql%E4%B9%8B%E5%88%86%E5%BA%93%E5%88%86%E8%A1%A8/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/11-mysql%E4%B9%8B%E5%88%86%E5%BA%93%E5%88%86%E8%A1%A8/</guid><description>11：mysql之分库分表 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 04:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1&gt;10：mysql之读写分离&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/11-mysql%E4%B9%8B%E5%88%86%E5%BA%93%E5%88%86%E8%A1%A8/image-20250617154629207.webp&quot; alt=&quot;image-20250617154629207&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;MySQL读写分离在多种工作场景中优势明显。在高并发读场景里，如电商平台商品浏览、社交媒体内容加载，大量读请求可由从库处理，减轻主库压力，提升系统响应速度 。对于数据实时性要求低的报表生成、数据分析场景，允许主从短暂延迟，能充分发挥读写分离的优势 。在容灾与备份方面，从库可作为主库实时备份，主库故障时能快速切换，保障业务持续运行 。另外，全球分布式架构中，将读操作路由到离用户近的从库，可减少网络延迟。&lt;/p&gt;
&lt;h2&gt;二、为什么学&lt;/h2&gt;
&lt;p&gt;学习 MySQL 读写分离很有必要。在高并发场景下，数据库面临大量读写请求，读写分离可将读操作分配到从库，有效减轻主库压力，提升系统整体性能与响应速度。对于有海量数据处理需求的企业，能提升业务处理效率。它还能增强系统的可扩展性，可通过增加从库数量来应对不断增长的读请求。在数据备份与恢复方面，从库可充当主库的实时副本，一旦主库出现故障，能快速恢复数据，保障业务连续性。掌握这一技术，有助于提升数据库管理和运维能力。&lt;/p&gt;
&lt;h2&gt;三、准备环境&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/11-mysql%E4%B9%8B%E5%88%86%E5%BA%93%E5%88%86%E8%A1%A8/image-20250617154653018.webp&quot; alt=&quot;image-20250617154653018&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3.1 准备新的虚拟机&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;mysql56&lt;/td&gt;
&lt;td&gt;192.168.90.56&lt;/td&gt;
&lt;td&gt;master【马斯特】数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mysql57&lt;/td&gt;
&lt;td&gt;192.168.90.57&lt;/td&gt;
&lt;td&gt;slave【斯累夫】数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mycat58&lt;/td&gt;
&lt;td&gt;192.168.90.58&lt;/td&gt;
&lt;td&gt;读写分离服务&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;mysql56配置IP地址和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.56/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mysql56 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql56
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mysql57配置IP地址和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.57/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mysql57 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql57
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mycat58配置IP地址和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.58/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mycat ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mycat58
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 读写分离原理&lt;/h3&gt;
&lt;p&gt;Mycat【麦-凯特】 读写分离原理基于对 MySQL 主从复制的利用。
Mycat【麦-凯特】 作为中间件，介于应用程序和 MySQL 数据库之间。
当应用程序发起 SQL 请求时，Mycat【麦-凯特】 会根据 SQL 语句类型进行判断。对于读操作，如 SELECT【涩莱克特】 语句，Mycat【麦-凯特】 将请求路由到从库处理，从库可有多台，能实现负载均衡，以此减轻主库读压力。而对于写操作，如 INSERT【因涩特】、UPDATE【阿普 dei 特】、DELETE【迪  利 特】 语句，Mycat【麦-凯特】 会将请求转发到主库，确保数据写入的一致性。
主库数据更新后，通过 MySQL 主从复制机制同步到从库，保证数据的实时性和准确性。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/11-mysql%E4%B9%8B%E5%88%86%E5%BA%93%E5%88%86%E8%A1%A8/image-20250617135010626.webp&quot; alt=&quot;image-20250617135010626&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;四、搭建一主一从结构&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/11-mysql%E4%B9%8B%E5%88%86%E5%BA%93%E5%88%86%E8%A1%A8/image-20250617154724356.webp&quot; alt=&quot;image-20250617154724356&quot; /&gt;&lt;/p&gt;
&lt;p&gt;因为数据的查询和存储分别访问不同的数据库服务器，所以要通过主从同步来保证负责读访问的服务与负责写访问的服务器数据一致。&lt;/p&gt;
&lt;h3&gt;4.1 配置主数据库服务器&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql56 ~]# yum -y  install【因-斯多】  mysql-server mysql
[root@mysql56 ~]#  systemctl【西斯屯-ctl】  start【s 达儿】 mysqld

# 启用binlog日志
[root@mysql56 ~]# vim /etc/my.cnf.d/mysql-server.cnf
# [root@mysql56 ~]# vim /etc/my.cnf
[mysqld]
server-id=56
log-bin=mysql56
:wq

[root@mysql56 ~]#  systemctl【西斯屯-ctl】 restart【 率 s 达r】 mysqld
# [root@mysql56 ~]# systemctl restart mysqld

# 用户授权
[root@mysql56 ~]# mysql
# [root@mysql56 ~]# mysql -uroot -p123

mysql&amp;gt; create【克瑞特】 user repluser@&quot;%&quot;  identified【爱-丹-提伐】 with【威付】 mysql_native_password by【拜】  &quot;123qqq...A&quot;;
# mysql&amp;gt; create user repluser@&apos;%&apos; identified with mysql_native_password by &apos;repluser&apos;;
# Query OK, 0 rows affected (0.26 sec)

mysql&amp;gt;  grant【古亮普】 replication【瑞普利K申】 slave【斯累夫】 on  *.* to  repluser@&quot;%&quot; ;
# mysql&amp;gt; grant replication slave on *.* to repluser@&apos;%&apos;;
# Query OK, 0 rows affected (0.15 sec)

# 查看日志信息
mysql&amp;gt; show【瘦】 master【马斯特】 status【 斯dèi 特斯】;
# mysql&amp;gt; show master status;
# +----------------+----------+--------------+------------------+-------------------+
# | File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
# +----------------+----------+--------------+------------------+-------------------+
# | mysql56.000001 |      668 |              |                  |                   |
# +----------------+----------+--------------+------------------+-------------------+
# 1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 配置从数据库服务器&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 指定server-id 并重启数据库服务
[root@mysql57 ~]# yum -y install【因-斯多】 mysql-server mysql
[root@mysql57 ~]# systemctl【西斯屯-ctl】 start【s 达儿】 mysqld
[root@mysql57 ~]# vim /etc/my.cnf.d/mysql-server.cnf
# [root@mysql57 ~]# vim /etc/my.cnf
[mysqld]
server-id=57
:wq

[root@mysql57 ~]#  systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld
# [root@mysql57 ~]# systemctl restart mysqld

# 管理员登陆，指定主服务器信息
[root@mysql57 ~]# mysql
# [root@mysql57 ~]# mysql -uroot -p123

mysql&amp;gt; change【趁(chèn)吉】 master【马斯特】 to master【马斯特】_host=&quot;192.168.90.56&quot;, master【马斯特】_user=&quot;repluser&quot;, master【马斯特】_password=&quot;123qqq...A&quot;, master【马斯特】_log_file=&quot;mysql56.000001&quot;,master【马斯特】_log_pos=667;
# mysql&amp;gt; change master to master_host=&apos;192.168.88.10&apos;,master_user=&apos;repluser&apos;,master_password=&apos;repluser&apos;,master_log_file=&quot;mysql56.000001&quot;,master_log_pos=668;
# Query OK, 0 rows affected, 8 warnings (9.74 sec)

# 启动slave【斯累夫】进程
mysql&amp;gt;  start【s 达儿】 slave【斯累夫】;
# mysql&amp;gt; start slave;
# Query OK, 0 rows affected, 1 warning (0.95 sec)

# 查看状态信息
mysql&amp;gt; show【瘦】 slave【斯累夫】 status【 斯dèi 特斯】 \G
# mysql&amp;gt; show slave status \G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: 192.168.90.56
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql56.000001
          Read_Master_Log_Pos: 667
               Relay_Log_File: mysql57-relay-bin.000002
                Relay_Log_Pos: 322
        Relay_Master_Log_File: mysql56.000001
             Slave_IO_Running: Yes   //IO线程
            Slave_SQL_Running: Yes   //SQL线程
              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: 667
              Relay_Log_Space: 533
              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: 56
                  Master_UUID: e0ab8dc4-0109-11ee-87e7-525400ad7ed3
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates【阿普 dei 特s】
           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: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set, 1 warning (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、配置mycat【麦-凯特】服务器&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/11-mysql%E4%B9%8B%E5%88%86%E5%BA%93%E5%88%86%E8%A1%A8/image-20250617154747875.webp&quot; alt=&quot;image-20250617154747875&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;5.1 拷贝软件到mycat【麦-凯特】58主机&lt;/h3&gt;
&lt;p&gt;mycat2-1.21-release-jar-with-dependencies.jar&lt;/p&gt;
&lt;p&gt;mycat2**-&lt;strong&gt;install&lt;/strong&gt;-**template-1.21.zip&lt;/p&gt;
&lt;h3&gt;5.2 安装mycat【麦-凯特】软件&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 安装jdk
[root@mycat58 upload]# yum -y install【因-斯多】 java-1.8.0-openjdk.x86_64
# [root@mycat58 ~]# yum -y install java-1.8.0-openjdk.x86_64
# 安装解压命令
[root@mycat58 upload]# which【维曲】 unzip || yum -y  install【因-斯多】 unzip
# [root@mycat58 ~]# which unzip || yum -y install unzip
# 安装mycat
[root@mycat58 upload]# unzip mycat2-install-template-1.21.zip
# [root@mycat58 ~]# unzip mycat2-install-template-1.21.zip 
[root@mycat58 upload]# mv mycat【麦-凯特】 /usr/local/
# [root@mycat58 ~]# mv mycat /usr/local/
# 安装依赖
[root@mycat58 upload]# cp mycat2-1.21-release-jar-with-dependencies.jar  /usr/local/mycat/lib/
# [root@mycat58 ~]# cp mycat2-1.21-release-jar-with-dependencies.jar /usr/local/mycat/lib/
# 修改权限
[root@mycat58 upload]# chmod -R 777 /usr/local/mycat/ 
# [root@mycat58 ~]# chmod -R 777 /usr/local/mycat/ 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.3 配置mycat【麦-凯特】密码&lt;/h3&gt;
&lt;p&gt;定义客户端连接mycat【麦-凯特】服务使用用户及密码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# vim  /usr/local/mycat/conf/users/root.user.json
{
        &quot;dialect&quot;:&quot;mysql&quot;,
        &quot;ip&quot;:null,
        &quot;password&quot;:&quot;654321&quot;, 密码
        &quot;transactionType&quot;:&quot;proxy&quot;,
        &quot;username&quot;:&quot;mycat&quot; 用户名
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mycat【麦-凯特】连接本机数据库配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# vim /usr/local/mycat/conf/datasources/prototypeDs.datasource.json
{
        &quot;dbType&quot;:&quot;mysql&quot;,
        &quot;idleTimeout&quot;:60000,
        &quot;initSqls&quot;:[],
        &quot;initSqlsGetConnection&quot;:true,
        &quot;instanceType&quot;:&quot;READ_WRITE&quot;,
        &quot;maxCon&quot;:1000,
        &quot;maxConnectTimeout&quot;:3000,
        &quot;maxRetryCount&quot;:5,
        &quot;minCon&quot;:1,
        &quot;name&quot;:&quot;prototypeDs&quot;,
        &quot;password&quot;:&quot;123456&quot;, 密码
        &quot;type&quot;:&quot;JDBC&quot;,
        &quot;url&quot;:&quot;jdbc:mysql://localhost:3306/mysql?useUnicode=true&amp;amp;serverTimezone=Asia/Shanghai&amp;amp;characterEncoding=UTF-8&quot;, 连接本机的数据库服务
        &quot;user&quot;:&quot;jam&quot;, 用户名
        &quot;weight&quot;:0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.4 mycat58主机mysql安装&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#  安装软件
[root@mycat58 ~]# yum -y  install【因-斯多】  mysql-server  mysql
# 启动服务
[root@mycat58 ~]#  systemctl【西斯屯-ctl】  start【s 达儿】 mysqld
#  连接服务
[root@mycat58 ~]# mysql 
# [root@mycat58 ~]# mysql -uroot -p123

#  创建jam用户
mysql&amp;gt; create【克瑞特】 user jam@&quot;%&quot;  identified【爱-丹-提伐】 by【拜】 &quot;123456&quot;;
# mysql&amp;gt; create user jam@&apos;%&apos; identified by &apos;123456&apos;;
# Query OK, 0 rows affected (0.52 sec)

#  授予权限
mysql&amp;gt;  grant【古亮普】 all on *.* to jam@&quot;%&quot; ;
# mysql&amp;gt; grant all on *.* to jam@&apos;%&apos;;
# Query OK, 0 rows affected (1.14 sec)

# 断开连接
mysql&amp;gt;  exit【诶西特】
# mysql&amp;gt; exit
Bye
[root@mycat58 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.5 mycat【麦-凯特】服务启动和连接&lt;/h3&gt;
&lt;p&gt;启动mycat【麦-凯特】服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# /usr/local/mycat/bin/mycat help
# [root@mycat58 ~]# /usr/local/mycat/bin/mycat help
Usage: /usr/local/mycat/bin/mycat { console |  start【s 达儿】 | stop | restart【 率 s 达r】 | status【 斯dèi 特斯】 | dump }

[root@mycat58 ~]# /usr/local/mycat/bin/mycat start
# [root@mycat58 ~]# /usr/local/mycat/bin/mycat start
# Starting mycat2...

# 半分钟左右 能看到端口
[root@mycat58 ~]# netstat  -utnlp  | grep 8066
# [root@mycat58 ~]# netstat -tunlp | grep 8066
# tcp6       0      0 :::8066                 :::*                    LISTEN      30687/java          
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;连接mycat【麦-凯特】服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321
# [root@mycat58 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321

mysql&amp;gt; show【瘦】 databases;
# mysql&amp;gt; show databases;
+--------------------+
| `Database`         |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.11 sec)
Mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、配置读写分离&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/11-mysql%E4%B9%8B%E5%88%86%E5%BA%93%E5%88%86%E8%A1%A8/image-20250617154816238.webp&quot; alt=&quot;image-20250617154816238&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;6.1 添加数据源&lt;/h3&gt;
&lt;p&gt;添加数据源：连接mycat【麦-凯特】服务后做如下操作&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 连接mycat【麦-凯特】服务
[root@mycat58 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321
# [root@mycat58 ~]# mysql -h 127.0.0.1 -P8066 -umycat -p654321

# 添加mysql56数据库服务器
MySQL&amp;gt; /*+ mycat:createdatasource{
&quot;name&quot;:&quot;whost56&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.90.56:3306&quot;,&quot;user&quot;:&quot;jama&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;whost56&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.10:3306&quot;,&quot;user&quot;:&quot;jama&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# Query OK, 0 rows affected (0.86 sec)

# 添加mysql57数据库服务器
Mysql&amp;gt;/*+ mycat:createdatasource{
&quot;name&quot;:&quot;rhost57&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.90.57:3306&quot;,&quot;user&quot;:&quot;jama&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;rhost57&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.20:3306&quot;,&quot;user&quot;:&quot;jama&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# Query OK, 0 rows affected (0.06 sec)

# 查看数据源
mysql&amp;gt; /*+mycat:showDataSources{}*/ \G
# mysql&amp;gt; /*+mycat:showDataSources{}*/ \G
*************************** 1. row ***************************
                   NAME: whost56
               USERNAME: jama
               PASSWORD: 123456
                MAX_CON: 1000
                MIN_CON: 1
              EXIST_CON: 0
                USE_CON: 0
        MAX_RETRY_COUNT: 5
    MAX_CONNECT_TIMEOUT: 30000
                DB_TYPE: mysql
                    URL: jdbc:mysql://192.168.90.56:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
                 WEIGHT: 0
               INIT_SQL: 
INIT_SQL_GET_CONNECTION: true
          INSTANCE_TYPE: READ_WRITE
           IDLE_TIMEOUT: 60000
                 DRIVER: {
        CreateTime:&quot;2023-06-02 17:01:14&quot;,
        ActiveCount:0,
        PoolingCount:0,
        CreateCount:0,
        DestroyCount:0,
        CloseCount:0,
        ConnectCount:0,
        Connections:[
        ]
}
                   TYPE: JDBC
               IS_MYSQL: true
*************************** 2. row ***************************
                   NAME: rhost57
               USERNAME: jama
               PASSWORD: 123456
                MAX_CON: 1000
                MIN_CON: 1
              EXIST_CON: 0
                USE_CON: 0
        MAX_RETRY_COUNT: 5
    MAX_CONNECT_TIMEOUT: 30000
                DB_TYPE: mysql
                    URL: jdbc:mysql://192.168.90.57:3306?useUnicode=true&amp;amp;serverTimezone=Asia/Shanghai&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
                 WEIGHT: 0
               INIT_SQL: 
INIT_SQL_GET_CONNECTION: true
          INSTANCE_TYPE: READ_WRITE
           IDLE_TIMEOUT: 60000
                 DRIVER: {
        CreateTime:&quot;2023-06-02 17:01:14&quot;,
        ActiveCount:0,
        PoolingCount:0,
        CreateCount:0,
        DestroyCount:0,
        CloseCount:0,
        ConnectCount:0,
        Connections:[
        ]
}
                   TYPE: JDBC
               IS_MYSQL: true
*************************** 3. row ***************************
                   NAME: prototypeDs
               USERNAME: jam
               PASSWORD: 123456
                MAX_CON: 1000
                MIN_CON: 1
              EXIST_CON: 0
                USE_CON: 0
        MAX_RETRY_COUNT: 5
    MAX_CONNECT_TIMEOUT: 3000
                DB_TYPE: mysql
                    URL: jdbc:mysql://localhost:3306/mysql?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
                 WEIGHT: 0
               INIT_SQL: 
INIT_SQL_GET_CONNECTION: true
          INSTANCE_TYPE: READ_WRITE
           IDLE_TIMEOUT: 60000
                 DRIVER: {
        CreateTime:&quot;2023-06-02 17:01:14&quot;,
        ActiveCount:0,
        PoolingCount:0,
        CreateCount:0,
        DestroyCount:0,
        CloseCount:0,
        ConnectCount:0,
        Connections:[
        ]
}
                   TYPE: JDBC
               IS_MYSQL: true
3 rows in set (0.00 sec)
mysql&amp;gt;

# 添加的数据源以文件的形式保存在安装目录下
[root@mycat58 conf]# ls /usr/local/mycat/conf/datasources/
# [root@mycat58 ~]# ls /usr/local/mycat/conf/datasources/
# prototypeDs.datasource.json  rhost57.datasource.json  whost56.datasource.json

[root@mycat58 conf]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.2 配置数据库服务器添加jama用户&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 在master【马斯特】服务器添加
[root@mysql56 ~]# mysql 

mysql&amp;gt; create【克瑞特】 user jama@&quot;%&quot;  identified【爱-丹-提伐】 by【拜】 &quot;123456&quot;;
# mysql&amp;gt; create user jama@&quot;%&quot;  identified by &quot;123456&quot;;
# Query OK, 0 rows affected (0.24 sec)

mysql&amp;gt;  grant【古亮普】 all on *.* to  jama@&quot;%&quot;;
# mysql&amp;gt; grant  all on *.* to  jama@&quot;%&quot;;
# Query OK, 0 rows affected (0.19 sec)

mysql&amp;gt; exit【诶西特】
[root@mysql56 ~]#

# 在slave【斯累夫】服务器查看是否同步成功
[root@mysql57 ~]# mysql -e &apos;select【涩莱克特】 user , host from【弗乱】 mysql.user where user=&quot;jama&quot;&apos;
+------+------+
| user | host |
+------+------+
| jama | %    |
+------+------+
[root@mysql57 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.3 创建集群&lt;/h3&gt;
&lt;p&gt;创建集群,连接mycat【麦-凯特】服务后做如下配置:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321

# 创建集群
mysql&amp;gt;/*!mycat:createcluster{
&quot;name&quot;:&quot;rwcluster&quot;,
&quot;masters&quot;:[&quot;whost56&quot;],
&quot;replicas&quot;:[&quot;rhost57&quot;]
}*/ ;


# 查看集群信息
mysql&amp;gt; /*+ mycat:showClusters{}*/ \G
*************************** 1. row ***************************
             NAME: rwcluster
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 2000
             TYPE: BALANCE_ALL
         WRITE_DS: whost56
          READ_DS: whost56,rhost57
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
*************************** 2. row ***************************
             NAME: prototype
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 200
             TYPE: BALANCE_ALL
         WRITE_DS: prototypeDs
          READ_DS: prototypeDs
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
2 rows in set (0.00 sec)
mysql&amp;gt;

# 创建的集群以文件的形式保存在目录下
[root@mycat58 conf]# ls /usr/local/mycat/conf/clusters/
prototype.cluster.json  rwcluster.cluster.json
[root@mycat58 conf]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.4 指定主机角色&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 修改master【马斯特】角色主机仅负责写访问
[root@mycat58 ~]# vim /usr/local/mycat/conf/datasources/whost56.datasource.json
{
        &quot;dbType&quot;:&quot;mysql&quot;,
        &quot;idleTimeout&quot;:60000,
        &quot;initSqls&quot;:[],
        &quot;initSqlsGetConnection&quot;:true,
        &quot;instanceType&quot;:&quot;WRITE&quot;, 仅负责写访问
        &quot;logAbandoned&quot;:true,
        &quot;maxCon&quot;:1000,
        &quot;maxConnectTimeout&quot;:30000,
        &quot;maxRetryCount&quot;:5,
        &quot;minCon&quot;:1,
        &quot;name&quot;:&quot;whost56&quot;,
        &quot;password&quot;:&quot;123456&quot;,
        &quot;queryTimeout&quot;:0,
        &quot;removeAbandoned&quot;:false,
        &quot;removeAbandonedTimeoutSecond&quot;:180,
        &quot;type&quot;:&quot;JDBC&quot;,
        &quot;url&quot;:&quot;jdbc:mysql://192.168.90.56:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&quot;,
        &quot;user&quot;:&quot;jama&quot;,
        &quot;weight&quot;:0
}
:wq

# 修改slave【斯累夫】角色主机仅负责读访问
[root@mycat58 ~]# vim /usr/local/mycat/conf/datasources/rhost57.datasource.json
{
        &quot;dbType&quot;:&quot;mysql&quot;,
        &quot;idleTimeout&quot;:60000,
        &quot;initSqls&quot;:[],
        &quot;initSqlsGetConnection&quot;:true,
        &quot;instanceType&quot;:&quot;READ&quot;,仅负责读访问
        &quot;logAbandoned&quot;:true,
        &quot;maxCon&quot;:1000,
        &quot;maxConnectTimeout&quot;:30000,
        &quot;maxRetryCount&quot;:5,
        &quot;minCon&quot;:1,
        &quot;name&quot;:&quot;rhost57&quot;,
        &quot;password&quot;:&quot;123456&quot;,
        &quot;queryTimeout&quot;:0,
        &quot;removeAbandoned&quot;:false,
        &quot;removeAbandonedTimeoutSecond&quot;:180,
        &quot;type&quot;:&quot;JDBC&quot;,
        &quot;url&quot;:&quot;jdbc:mysql://192.168.90.57:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&quot;,
        &quot;user&quot;:&quot;jama&quot;,
        &quot;weight&quot;:0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.5 修改读策略&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;readBalanceType&lt;/code&gt;参数值&lt;/th&gt;
&lt;th&gt;负载均衡策略说明&lt;/th&gt;
&lt;th&gt;行为描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;BALANCE_ALL_READ&lt;/strong&gt;​&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;在所有从库（Replicas）间均衡&lt;/strong&gt;​&lt;/td&gt;
&lt;td&gt;所有的 &lt;code&gt;SELECT&lt;/code&gt;查询请求会在 &lt;code&gt;replicas&lt;/code&gt;列表配置的所有从库上进行负载均衡。写节点（&lt;code&gt;masters&lt;/code&gt;）不参与读流量的分担。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;BALANCE_ALL&lt;/strong&gt;​ (如果支持)&lt;/td&gt;
&lt;td&gt;在所有节点（主和从）间均衡&lt;/td&gt;
&lt;td&gt;读请求会随机地在所有数据库节点（包括写节点 &lt;code&gt;masters&lt;/code&gt;和读节点 &lt;code&gt;replicas&lt;/code&gt;）上进行分发。这种模式允许主库也承担一部分读压力。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;BALANCE_MASTER&lt;/strong&gt;​ (如果支持)&lt;/td&gt;
&lt;td&gt;仅从主库读取&lt;/td&gt;
&lt;td&gt;所有读请求都会发往配置的写节点（&lt;code&gt;masters&lt;/code&gt;）。这通常用于需要强一致性读的场景，或者尚未配置从库的情况。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# vim /usr/local/mycat/conf/clusters/rwcluster.cluster.json 
{
        &quot;clusterType&quot;:&quot;MASTER_SLAVE&quot;,
        &quot;heartbeat&quot;:{
                &quot;heartbeatTimeout&quot;:1000,
                &quot;maxRetryCount&quot;:3,
                &quot;minSwitchTimeInterval&quot;:300,
                &quot;showLog&quot;:false,
                &quot;slaveThreshold&quot;:0.0
        },
        &quot;masters&quot;:[
                &quot;whost56&quot;
        ],
        &quot;maxCon&quot;:2000,
        &quot;name&quot;:&quot;rwcluster&quot;,
        &quot;readBalanceType&quot;:&quot;BALANCE_ALL_READ&quot;,# _READ将查询语句分发到从数据库节点
        &quot;replicas&quot;:[
                &quot;rhost57&quot;
        ],
        &quot;switchType&quot;:&quot;SWITCH&quot;
}
:wq

# 重启mycat【麦-凯特】服务
[root@mycat58 ~]# /usr/local/mycat/bin/mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...

[root@mycat58 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;七、测试读写分离&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/11-mysql%E4%B9%8B%E5%88%86%E5%BA%93%E5%88%86%E8%A1%A8/image-20250617154556706.webp&quot; alt=&quot;image-20250617154556706&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;7.1 指定testdb库存储数据使用的集群&lt;/h3&gt;
&lt;p&gt;具体操作如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321 

mysql&amp;gt; create【克瑞特】 database testdb;
# mysql&amp;gt; create database testdb;
# Query OK, 0 rows affected (0.54 sec)

mysql&amp;gt;  exit【诶西特】


# 指定testdb库存储数据使用的集群
[root@mycat58 ~]# vim /usr/local/mycat/conf/schemas/testdb.schema.json
{
        &quot;customTables&quot;:{},
        &quot;globalTables&quot;:{},
        &quot;normalProcedures&quot;:{},
        &quot;normalTables&quot;:{},
        &quot;schemaName&quot;:&quot;testdb&quot;,
        &quot;targetName&quot;:&quot;rwcluster&quot;, 添加此行,之前创建的集群名rwcluster
        &quot;shardingTables&quot;:{},
        &quot;views&quot;:{}
}
:wq

[root@mycat58 ~]# /usr/local/mycat/bin/mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...

[root@mycat58 ~]#

# 连接mycat【麦-凯特】服务建表插入记录
[root@client50 ~]# mysql -h192.168.90.58 -P8066 -umycat -p654321

mysql&amp;gt; create【克瑞特】 table【忒-部】 testdb.user (name varchar【瓦儿-查儿】(10) , password varchar【瓦儿-查儿】(10));
# mysql&amp;gt; create table testdb.user (name varchar(10), password varchar(10));
# Query OK, 0 rows affected (3.65 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】  testdb.user values【挖柳斯】(&quot;yaya&quot;,&quot;123456&quot;);
# mysql&amp;gt; insert into testdb.user values(&quot;yaya&quot;,&quot;123456&quot;);
# Query OK, 1 row affected (0.28 sec)

mysql&amp;gt; select【涩莱克特】 * from【弗乱】 testdb.user;
# mysql&amp;gt; select * from testdb.user;
# +------+----------+
# | name | password |
# +------+----------+
# | yaya | 123456   |
# +------+----------+
# 1 row in set (0.01 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.2 测试读写分离&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 在从服务器本机插入记录，数据仅在从服务器有，主服务器没有
[root@mysql57 ~]# mysql -e &apos;insert【因涩特】 into【因兔】 testdb.user values【挖柳斯】 (&quot;yayaA&quot;,&quot;654321&quot;)&apos;
# [root@mysql57 ~]# mysql -uroot -p123 -e &apos;insert into testdb.user values(&quot;yayaA&quot;,&quot;654321&quot;)&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.

[root@mysql57 ~]# mysql -e &apos;select【涩莱克特】 * from【弗乱】 testdb.user&apos;
# [root@mysql57 ~]# mysql -uroot -p123 -e &apos;select * from testdb.user&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +-------+----------+
# | name  | password |
# +-------+----------+
# | yaya  | 123456   |
# | yayaA | 654321   |
# +-------+----------+


# 主服务器数据不变，日志偏移量不不变
[root@mysql56 ~]# mysql -e &apos;select【涩莱克特】 * from【弗乱】 testdb.user&apos;
# [root@mysql56 ~]# mysql -uroot -p123 -e &apos;select * from testdb.user&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +------+----------+
# | name | password |
# +------+----------+
# | yaya | 123456   |
# +------+----------+

[root@mysql56 ~]# mysql -e &apos;show【瘦】 master【马斯特】 status【 斯dèi 特斯】&apos;
# [root@mysql56 ~]# mysql -uroot -p123 -e &apos;show master status&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +----------------+----------+--------------+------------------+-------------------+
# | File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
# +----------------+----------+--------------+------------------+-------------------+
# | mysql56.000002 |     1910 |              |                  |                   |
# +----------------+----------+--------------+------------------+-------------------+

# 客户端连接mycat【麦-凯特】服务读/写数据
[root@client50 ~]# mysql -h192.168.90.58 -P8066 -umycat -p654321
# [root@mycat58 ~]# mysql -h 127.0.0.1 -P8066 -umycat -p654321

#  查看到的是2条记录的行
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 testdb.user;
# mysql&amp;gt; select * from testdb.user;
# +-------+----------+
# | name  | password |
# +-------+----------+
# | yaya  | 123456   |
# | yayaA | 654321   |
# +-------+----------+
# 2 rows in set (1.34 sec)

#   插入记录
mysql&amp;gt; insert【因涩特】 into【因兔】 testdb.user values【挖柳斯】(&quot;yayaB&quot;,&quot;123456&quot;);
# mysql&amp;gt; insert into testdb.user values(&quot;yayaB&quot;,&quot;123456&quot;);
# Query OK, 1 row affected (0.14 sec)

mysql&amp;gt; select【涩莱克特】  * from【弗乱】 testdb.user;
# mysql&amp;gt; select * from testdb.user;
# +-------+----------+
# | name  | password |
# +-------+----------+
# | yaya  | 123456   |
# | yayaB | 123456   |
# +-------+----------+
# 2 rows in set (0.00 sec)

# 在主服务器查看数据和日志偏移量
[root@mysql56 ~]# mysql -e &apos;select【涩莱克特】 * from【弗乱】 testdb.user&apos;
# [root@mysql56 ~]# mysql -uroot -p123 -e &apos;select * from testdb.user&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +-------+----------+
# | name  | password |
# +-------+----------+
# | yaya  | 123456   |
# | yayaB | 123456   |
# +-------+----------+

[root@mysql56 ~]# mysql -e &apos;show【瘦】 master【马斯特】 status【 斯dèi 特斯】&apos;
# [root@mysql56 ~]# mysql -uroot -p123 -e &apos;show master status&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +----------------+----------+--------------+------------------+-------------------+
# | File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
# +----------------+----------+--------------+------------------+-------------------+
# | mysql56.000002 |     2203 |              |                  |                   |
# +----------------+----------+--------------+------------------+-------------------+

# 客户端连接mycat【麦-凯特】服务查看到的是3条记录
[root@client50 ~]# mysql -h192.168.90.58 -P8066 -umycat -p654321 -e &apos;select【涩莱克特】  * from【弗乱】 testdb.user&apos;
# [root@mycat58 mycat]# mysql -h192.168.88.30 -P8066 -umycat -p654321 -e &apos;select * from testdb.user&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +-------+----------+
# | name  | password |
# +-------+----------+
# | yaya  | 123456   |
# | yayaA | 654321   |
# +-------+----------+
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;MyCat 核心配置文件功能总结&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;配置文件&lt;/th&gt;
&lt;th&gt;核心功能&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;server.xml&lt;/td&gt;
&lt;td&gt;系统级配置（账户、密码、逻辑库、序列、连接参数）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;schema.xml&lt;/td&gt;
&lt;td&gt;逻辑库-物理库映射、表配置、分片规则关联、数据节点/主机配置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rule.xml&lt;/td&gt;
&lt;td&gt;分片规则定义与参数配置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dataHost.xml（可选）&lt;/td&gt;
&lt;td&gt;独立配置数据主机（部分版本将 DataHost 配置拆分到该文件，默认在 schema.xml 中）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;MySQL 读写分离的原理与优势&lt;/h2&gt;
&lt;h3&gt;一、核心原理&lt;/h3&gt;
&lt;p&gt;MySQL 读写分离基于 &lt;strong&gt;主从复制&lt;/strong&gt; 机制，通过中间件（如 MyCat、ProxySQL、MaxScale）实现请求分流，核心逻辑如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;架构基础&lt;/strong&gt;：部署1台主库（Master）和1+台从库（Slave），主库负责写操作，从库仅负责读操作；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据同步&lt;/strong&gt;：主库执行写操作（INSERT/UPDATE/DELETE）后，通过二进制日志（binlog）将数据变更同步到所有从库，保障主从数据一致性；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;请求路由&lt;/strong&gt;：应用程序的SQL请求统一发送至中间件，中间件根据SQL类型分流：
&lt;ul&gt;
&lt;li&gt;写请求（含事务类读请求）直接路由到主库，确保数据写入的原子性和一致性；&lt;/li&gt;
&lt;li&gt;读请求（SELECT）分发到任意从库，支持多从库负载均衡；&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;故障兼容&lt;/strong&gt;：中间件实时监测主从节点状态，自动剔除故障从库，主库故障时可配合主从切换机制保障业务连续性。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;二、核心优势&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;提升并发承载能力&lt;/strong&gt;：读操作（占业务请求80%以上）分流至多从库，主库专注处理写操作，避免读写冲突排队，系统整体并发量显著提升；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;减轻主库负载压力&lt;/strong&gt;：主库无需承担大量读请求的CPU、IO资源消耗，降低主库因负载过高导致的卡顿、超时风险；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高可用与容错&lt;/strong&gt;：从库故障仅影响部分读业务，主库故障可快速切换读请求至从库，避免单点故障导致系统瘫痪；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;优化响应速度&lt;/strong&gt;：从库可就近部署（异地多活），降低网络延迟；且从库可关闭写日志、优化索引，专项提升读性能；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;灵活横向扩展&lt;/strong&gt;：读压力增长时，无需升级主库硬件，仅需新增从库节点接入集群，扩展成本低、效率高；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;简化维护与数据安全&lt;/strong&gt;：从库可作为灾备节点，主库数据丢失时可从从库恢复；报表统计、数据备份等非核心操作可在从库执行，不影响主库业务。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Mycat 在 MySQL 读写分离中的核心作用&lt;/h2&gt;
&lt;p&gt;Mycat 作为开源分布式数据库中间件，是 MySQL 读写分离架构的 &lt;strong&gt;核心枢纽&lt;/strong&gt;，其核心价值是屏蔽底层主从集群复杂度，实现请求智能分流、数据一致性保障和高可用调度，让应用无需感知主从架构即可享受读写分离带来的性能提升。具体作用如下：&lt;/p&gt;
&lt;h3&gt;一、请求路由：读写操作智能分流（核心功能）&lt;/h3&gt;
&lt;p&gt;Mycat 是应用与 MySQL 集群之间的“流量分发器”，实现读写请求的精准拆分：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;SQL 类型识别&lt;/strong&gt;：自动解析应用发送的 SQL 语句，区分读操作（SELECT、SHOW 等）和写操作（INSERT、UPDATE、DELETE、DDL 等）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;路由规则执行&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;写请求（含事务类读请求，如 &lt;code&gt;SELECT ... FOR UPDATE&lt;/code&gt;）强制路由到 &lt;strong&gt;主库&lt;/strong&gt;，确保数据写入的原子性和一致性，避免写操作分散导致的数据冲突；&lt;/li&gt;
&lt;li&gt;读请求默认路由到 &lt;strong&gt;从库&lt;/strong&gt;，并支持多从库负载均衡（如轮询、加权轮询、一致性哈希等算法），将读压力均匀分摊到多个从库，减轻主库负担；&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;灵活路由扩展&lt;/strong&gt;：支持自定义路由规则（如指定某类查询走特定从库、分库分表场景下的联合路由），适配复杂业务需求。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;二、数据一致性保障：解决主从同步延迟问题&lt;/h3&gt;
&lt;p&gt;MySQL 主从复制存在天然的同步延迟（毫秒级到秒级），可能导致“主库写入数据后，从库未及时同步，读请求获取旧数据”的问题。Mycat 提供多种机制保障数据一致性：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;强制走主库策略&lt;/strong&gt;：支持通过 SQL 注解（如 &lt;code&gt;/*MASTER*/ SELECT * FROM table&lt;/code&gt;）或配置规则，让关键读请求（如刚写入后需立即查询的场景）强制路由到主库，避免延迟导致的数据不一致；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;延迟判断机制&lt;/strong&gt;：可配置从库同步延迟阈值（如 1 秒），Mycat 实时监测主从延迟，若从库延迟超过阈值，自动将读请求切换到其他低延迟从库或主库，确保读取数据的时效性；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;事务一致性控制&lt;/strong&gt;：事务内的所有操作（无论读写）均路由到主库，避免事务跨主从执行导致的隔离级别失效或数据不一致。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;三、负载均衡：提升集群并发处理能力&lt;/h3&gt;
&lt;p&gt;针对多从库架构，Mycat 提供成熟的负载均衡策略，最大化利用从库资源：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;读负载均衡&lt;/strong&gt;：将海量读请求均匀分发到多个从库，避免单台从库过载，提升整体读并发能力（如 3 台从库可承载 3 倍于单从库的读请求）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;权重配置支持&lt;/strong&gt;：可根据从库硬件性能（CPU、内存、IO）配置权重（如高性能从库权重设为 3，普通从库设为 1），让资源更优的从库承担更多请求；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;动态负载调整&lt;/strong&gt;：支持在线新增/下线从库节点，Mycat 自动感知节点变化并调整负载分发策略，无需重启应用或中间件。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;四、高可用调度：避免单点故障，保障业务连续性&lt;/h3&gt;
&lt;p&gt;Mycat 实时监测主从节点状态，提供故障自动切换和容错能力，提升集群可用性：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;节点健康检查&lt;/strong&gt;：通过心跳检测（如定期执行 &lt;code&gt;SELECT 1&lt;/code&gt;）监测主从库是否存活，若发现节点故障（如从库宕机、主库离线），自动将其从集群中剔除，避免请求路由到故障节点导致的业务报错；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主从切换支持&lt;/strong&gt;：配合 MGR（MySQL Group Replication）或第三方高可用工具（如 Keepalived），主库故障时，Mycat 可自动识别新主库并切换路由规则，写请求无缝迁移到新主库，读请求继续由正常从库处理，实现业务“无感知”恢复；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;故障恢复自动接入&lt;/strong&gt;：当故障节点修复后，Mycat 可自动检测并将其重新纳入集群，恢复负载均衡，无需人工干预。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;五、透明接入：降低应用改造成本&lt;/h3&gt;
&lt;p&gt;Mycat 对应用完全透明，无需修改应用代码即可实现读写分离：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;协议兼容&lt;/strong&gt;：完全兼容 MySQL 协议，应用可像连接普通 MySQL 数据库一样连接 Mycat（仅需修改数据库连接地址为 Mycat 服务地址，端口为 Mycat 监听端口），无需调整 SQL 语法或数据库驱动；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;逻辑库抽象&lt;/strong&gt;：Mycat 将底层多个主从库抽象为一个“逻辑库”，应用仅需面向逻辑库开发，无需关心底层主从节点的数量、地址和部署架构，降低架构复杂度和运维成本。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;六、辅助功能：强化读写分离架构的稳定性与可维护性&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;权限集中管理&lt;/strong&gt;：在 Mycat 层面统一配置应用访问权限（如某应用仅允许读从库、某账户仅允许写主库），无需在每个 MySQL 节点单独配置，简化权限管理；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SQL 拦截与过滤&lt;/strong&gt;：支持拦截非法 SQL（如高风险 DDL、慢查询）或不符合规则的请求（如写请求路由到从库），避免恶意操作或误操作破坏集群稳定性；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;监控与审计&lt;/strong&gt;：提供完善的日志（如路由日志、错误日志、访问日志）和监控指标（如请求量、路由命中率、节点状态），方便运维人员排查问题、优化性能；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分库分表兼容&lt;/strong&gt;：Mycat 不仅支持读写分离，还可与分库分表功能结合，实现“读写分离+分库分表”的复杂架构，满足海量数据存储和高并发访问的场景（如电商订单库）。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;Mycat 在 MySQL 读写分离架构中的核心作用是 &lt;strong&gt;“承上启下”&lt;/strong&gt;：向上屏蔽底层主从集群的复杂性，让应用无需改造即可享受读写分离的性能红利；向下通过智能路由、负载均衡、高可用调度和一致性保障，最大化发挥主从集群的资源价值，解决“主库负载高、读并发不足、单点故障”等核心问题，是中小型企业实现 MySQL 高可用、高并发架构的优选中间件。&lt;/p&gt;
&lt;h3&gt;Mycat 在 MySQL 读写分离中的核心作用（简洁版）&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;读写请求智能分流&lt;/strong&gt;&lt;br /&gt;
自动解析 SQL 类型，写操作（INSERT/UPDATE/DELETE）路由到主库保证数据一致，读操作（SELECT）分发到从库，避免主库读压力过载。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;保障数据一致与读负载均衡&lt;/strong&gt;&lt;br /&gt;
通过“关键读请求强制走主库”解决主从同步延迟问题；支持多从库按权重分摊读请求，最大化利用从库资源，提升读并发能力。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;透明接入与高可用兜底&lt;/strong&gt;&lt;br /&gt;
应用无需改代码，仅需将连接地址指向 Mycat（兼容 MySQL 协议）；实时监测主从节点状态，故障节点自动剔除，主库故障时配合切换保障业务不中断。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Mycat 读写分离 schema.xml 核心配置项及作用（简洁版）&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;1. **&amp;lt;schema&amp;gt; 标签**  
   - 核心属性：`name`（逻辑库名称）、`checkSQLschema`（是否校验SQL库名）  
   - 作用：定义应用访问的**逻辑库**，关联底层数据节点，屏蔽物理库集群复杂度。

2. **&amp;lt;table&amp;gt; 标签**  
   - 核心属性：`name`（逻辑表名）、`dataNode`（关联的数据节点）、`primaryKey`（主键）、`autoIncrement`（是否自增）  
   - 作用：映射逻辑表与物理表，指定表所属数据节点，配置主键和自增规则（读写分离场景中主要用于关联数据节点）。

3. **&amp;lt;dataNode&amp;gt; 标签**  
   - 核心属性：`name`（数据节点名称）、`dataHost`（关联的数据主机）、`database`（物理库名称）  
   - 作用：关联**数据主机**与**物理库**，是逻辑表到物理库的中间映射。

4. **&amp;lt;dataHost&amp;gt; 标签**（读写分离核心配置）  
   - 核心属性：`name`（数据主机名称）、`balance`（读负载均衡策略）、`writeType`（写路由规则）、`switchType`（主从切换策略）  
   - 作用：配置主从库集群信息，控制读负载分发、写请求路由、主从故障切换。

5. **&amp;lt;writeHost&amp;gt; 标签**  
   - 核心属性：`host`（主机标识）、`url`（主库地址:端口）、`user`（数据库用户名）、`password`（密码）  
   - 作用：定义**主库**连接信息，接收所有写请求（INSERT/UPDATE/DELETE）。

6. **&amp;lt;readHost&amp;gt; 标签**  
   - 核心属性：`host`（主机标识）、`url`（从库地址:端口）、`user`（数据库用户名）、`password`（密码）  
   - 作用：定义**从库**连接信息，接收读请求（SELECT），配合 `balance` 实现负载均衡。

7. **关键属性补充**  
   - `balance=&quot;1&quot;`：开启读负载均衡（主从库均参与读）；  
   - `writeType=&quot;0&quot;`：写请求路由到第一个 &amp;lt;writeHost&amp;gt;（主库）；  
   - `switchType=&quot;1&quot;`：主库故障时自动切换到备用主库/从库。
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Mycat balance 属性（负载均衡策略）取值含义与适用场景&lt;/h2&gt;
&lt;p&gt;balance 是 Mycat &lt;code&gt;schema.xml&lt;/code&gt; 中 &lt;code&gt;&amp;lt;dataHost&amp;gt;&lt;/code&gt; 标签的核心属性，专门控制 &lt;strong&gt;读请求的负载均衡规则&lt;/strong&gt;，取值仅支持 &lt;code&gt;0、1、2、3&lt;/code&gt; 四种，不同取值对应不同的集群架构和业务需求，具体如下：&lt;/p&gt;
&lt;h3&gt;1. balance=&quot;0&quot;：关闭读负载均衡&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;含义&lt;/strong&gt;：不开启读负载分发，所有读请求（SELECT）均路由到当前活跃的 &lt;code&gt;writeHost&lt;/code&gt;（主库），从库（&lt;code&gt;readHost&lt;/code&gt;）不参与读请求处理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;从库未部署（仅单主库架构）；&lt;/li&gt;
&lt;li&gt;主从同步延迟极高（如跨地域主从，延迟秒级以上），读从库会导致数据不一致；&lt;/li&gt;
&lt;li&gt;业务需要 &lt;strong&gt;强一致性读&lt;/strong&gt;（如刚写入数据后立即查询、核心交易查询），必须读主库。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. balance=&quot;1&quot;：主从库混合读负载（推荐默认）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;含义&lt;/strong&gt;：开启读负载均衡，读请求分发到所有 &lt;code&gt;readHost&lt;/code&gt;（从库）和 &lt;strong&gt;备用 &lt;code&gt;writeHost&lt;/code&gt;（备用主库）&lt;/strong&gt;；当前活跃的主库（默认 &lt;code&gt;writeHost&lt;/code&gt;）不参与读请求，仅负责写操作。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;典型主从架构（1主多从 + 1备用主库），需最大化利用从库和备用主库资源；&lt;/li&gt;
&lt;li&gt;读请求占比高（如电商商品查询、新闻列表、用户信息查询），需分摊主库读压力；&lt;/li&gt;
&lt;li&gt;大多数中小型业务的默认选择，兼顾性能和数据一致性（配合主从同步延迟阈值使用）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. balance=&quot;2&quot;：全节点读负载（不分主从）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;含义&lt;/strong&gt;：不区分主库（&lt;code&gt;writeHost&lt;/code&gt;）和从库（&lt;code&gt;readHost&lt;/code&gt;），所有可用的 &lt;code&gt;writeHost&lt;/code&gt;（主库、备用主库）和 &lt;code&gt;readHost&lt;/code&gt;（从库）均参与读负载，读请求随机分发到所有节点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;主库硬件配置充足（CPU/内存/IO 资源未饱和），允许承担部分读请求；&lt;/li&gt;
&lt;li&gt;备用主库长期闲置，需利用其资源分担读压力；&lt;/li&gt;
&lt;li&gt;读压力较大但未达到需要部署多从库的规模，适合中小型集群（如 1主1从 + 1备用主库）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. balance=&quot;3&quot;：仅从库读负载&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;含义&lt;/strong&gt;：读请求仅分发到&lt;code&gt;readHost&lt;/code&gt;（从库），主库（&lt;code&gt;writeHost&lt;/code&gt;）和备用主库&lt;strong&gt;完全不参与&lt;/strong&gt;读负载&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;主库写压力极大（如高频插入/更新），需完全隔离读请求（主库仅负责写）；&lt;/li&gt;
&lt;li&gt;对读数据时效性有要求（需避免主从延迟导致的旧数据），如金融交易查询、订单状态查询；&lt;/li&gt;
&lt;li&gt;多从库架构（1主多从），且从库性能均衡，适合中大型业务的读密集场景。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;balance=&quot;3&quot;&lt;/code&gt;是&lt;strong&gt;最常用的读写分离策略&lt;/strong&gt;，特别适合读多写少的业务场景，它能有效降低主库压力，提升系统整体性能。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;核心总结（快速选型）&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;balance&lt;/code&gt; 值&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;读请求负载策略&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;核心工作机制&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;最适用场景&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;不开启读写分离&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;所有读、写操作均发送至当前可用的主库 (&lt;code&gt;writeHost&lt;/code&gt;)。&lt;/td&gt;
&lt;td&gt;单点数据库、要求强一致性读、从库延迟不可接受。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;主从库混合读负载&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;读请求在所有从库 (&lt;code&gt;readHost&lt;/code&gt;) 及&lt;strong&gt;备用主库&lt;/strong&gt; (&lt;code&gt;standby writeHost&lt;/code&gt;) 间负载均衡，&lt;strong&gt;当前主库不参与读&lt;/strong&gt;。&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;双主双从&lt;/strong&gt;等高可用架构，最大化利用从库和备用主库资源。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;全节点随机读负载&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;所有读请求随机分发到配置内&lt;strong&gt;所有&lt;/strong&gt;数据库节点（包括主库和从库）。&lt;/td&gt;
&lt;td&gt;读压力大，且主库性能充足，允许主库分担读请求。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;仅从库读负载&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;读请求&lt;strong&gt;只&lt;/strong&gt;分发到当前主库对应的从库 (&lt;code&gt;readHost&lt;/code&gt;) 上，&lt;strong&gt;主库完全不负担任何读压力&lt;/strong&gt;。&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;一主多从&lt;/strong&gt;架构，且希望&lt;strong&gt;严格分离读写&lt;/strong&gt;、保障主库写性能的场景。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;八、作业&lt;/h2&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;h4&gt;1&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在 Mycat 读写分离配置中，schema.xml 文件里 datahost 标签的 balance 属性值为 3 时，表示（ D ）。
A. 不开启读写分离机制，所有读操作都可发送到当前可用的 writeHost 上
B. 全部的 readHost 与备用的 writeHost 都参与 select 语句的负载均衡
C. 所有的读写操作都随机在 writeHost，readHost 上分发
D. 所有的读请求随机分发到 writeHost 对应的 readHost 上执行，writeHost 不负担读压力&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;2&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Mycat 的默认数据端口和管理端口分别是（ A ）。
A. 8066 和 9066
B. 9066 和 8066
C. 3306 和 8066
D. 8066 和 3306&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;3&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在 Mycat 配置中，server.xml 文件主要用于（ A ）。
A. 配置 Mycat 所需要的服务器信息，如序列生成方式、逻辑数据库、访问账户和密码等
B. 配置逻辑数据库的映射、表、分片规则、数据结点及真实的数据库信息
C. 定义分片规则
D. 配置负载均衡策略&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;4&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在 Mycat 读写分离配置前，需要确保（ A ）。
A. MySQL 主从复制已完成并正常运行
B. MySQL 版本为 8.0
C. Mycat 安装在 Windows 系统上
D. 所有数据库服务器的 server-id 相同&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;h4&gt;1&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;简述 MySQL 读写分离的原理和优势。
答：
核心原理
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;架构基础&lt;/strong&gt;：部署1台主库（Master）和1+台从库（Slave），主库负责写操作，从库仅负责读操作；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据同步&lt;/strong&gt;：主库执行写操作（INSERT/UPDATE/DELETE）后，通过二进制日志（binlog）将数据变更同步到所有从库，保障主从数据一致性；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;请求路由&lt;/strong&gt;：应用程序的SQL请求统一发送至中间件，中间件根据SQL类型分流：
&lt;ul&gt;
&lt;li&gt;写请求（含事务类读请求）直接路由到主库，确保数据写入的原子性和一致性；&lt;/li&gt;
&lt;li&gt;读请求（SELECT）分发到任意从库，支持多从库负载均衡；&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;故障兼容&lt;/strong&gt;：中间件实时监测主从节点状态，自动剔除故障从库，主库故障时可配合主从切换机制保障业务连续性。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;核心优势
1. &lt;strong&gt;提升并发承载能力&lt;/strong&gt;：读操作（占业务请求80%以上）分流至多从库，主库专注处理写操作，避免读写冲突排队，系统整体并发量显著提升；
2. &lt;strong&gt;减轻主库负载压力&lt;/strong&gt;：主库无需承担大量读请求的CPU、IO资源消耗，降低主库因负载过高导致的卡顿、超时风险；
3. &lt;strong&gt;高可用与容错&lt;/strong&gt;：从库故障仅影响部分读业务，主库故障可快速切换读请求至从库，避免单点故障导致系统瘫痪；
4. &lt;strong&gt;优化响应速度&lt;/strong&gt;：从库可就近部署（异地多活），降低网络延迟；且从库可关闭写日志、优化索引，专项提升读性能；
5. &lt;strong&gt;灵活横向扩展&lt;/strong&gt;：读压力增长时，无需升级主库硬件，仅需新增从库节点接入集群，扩展成本低、效率高；
6. &lt;strong&gt;简化维护与数据安全&lt;/strong&gt;：从库可作为灾备节点，主库数据丢失时可从从库恢复；报表统计、数据备份等非核心操作可在从库执行，不影响主库业务。&lt;/p&gt;
&lt;h4&gt;2&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;说明 Mycat 在 MySQL 读写分离中的作用。
答：
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;读写请求智能分流&lt;/strong&gt;&lt;br /&gt;
自动解析 SQL 类型，写操作（INSERT/UPDATE/DELETE）路由到主库保证数据一致，读操作（SELECT）分发到从库，避免主库读压力过载。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保障数据一致与读负载均衡&lt;/strong&gt;&lt;br /&gt;
通过“关键读请求强制走主库”解决主从同步延迟问题；支持多从库按权重分摊读请求，最大化利用从库资源，提升读并发能力。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;透明接入与高可用兜底&lt;/strong&gt;&lt;br /&gt;
应用无需改代码，仅需将连接地址指向 Mycat（兼容 MySQL 协议）；实时监测主从节点状态，故障节点自动剔除，主库故障时配合切换保障业务不中断。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;3&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;列举 Mycat 读写分离配置中 schema.xml 文件的主要配置项及其作用。
答：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;schema&amp;gt; 标签&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;核心属性：&lt;code&gt;name&lt;/code&gt;（逻辑库名称）、&lt;code&gt;checkSQLschema&lt;/code&gt;（是否校验SQL库名）&lt;/li&gt;
&lt;li&gt;作用：定义应用访问的&lt;strong&gt;逻辑库&lt;/strong&gt;，关联底层数据节点，屏蔽物理库集群复杂度。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;table&amp;gt; 标签&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;核心属性：&lt;code&gt;name&lt;/code&gt;（逻辑表名）、&lt;code&gt;dataNode&lt;/code&gt;（关联的数据节点）、&lt;code&gt;primaryKey&lt;/code&gt;（主键）、&lt;code&gt;autoIncrement&lt;/code&gt;（是否自增）&lt;/li&gt;
&lt;li&gt;作用：映射逻辑表与物理表，指定表所属数据节点，配置主键和自增规则（读写分离场景中主要用于关联数据节点）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;dataNode&amp;gt; 标签&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;核心属性：&lt;code&gt;name&lt;/code&gt;（数据节点名称）、&lt;code&gt;dataHost&lt;/code&gt;（关联的数据主机）、&lt;code&gt;database&lt;/code&gt;（物理库名称）&lt;/li&gt;
&lt;li&gt;作用：关联&lt;strong&gt;数据主机&lt;/strong&gt;与&lt;strong&gt;物理库&lt;/strong&gt;，是逻辑表到物理库的中间映射。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;dataHost&amp;gt; 标签&lt;/strong&gt;（读写分离核心配置）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;核心属性：&lt;code&gt;name&lt;/code&gt;（数据主机名称）、&lt;code&gt;balance&lt;/code&gt;（读负载均衡策略）、&lt;code&gt;writeType&lt;/code&gt;（写路由规则）、&lt;code&gt;switchType&lt;/code&gt;（主从切换策略）&lt;/li&gt;
&lt;li&gt;作用：配置主从库集群信息，控制读负载分发、写请求路由、主从故障切换。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;writeHost&amp;gt; 标签&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;核心属性：&lt;code&gt;host&lt;/code&gt;（主机标识）、&lt;code&gt;url&lt;/code&gt;（主库地址:端口）、&lt;code&gt;user&lt;/code&gt;（数据库用户名）、&lt;code&gt;password&lt;/code&gt;（密码）&lt;/li&gt;
&lt;li&gt;作用：定义&lt;strong&gt;主库&lt;/strong&gt;连接信息，接收所有写请求（INSERT/UPDATE/DELETE）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;readHost&amp;gt; 标签&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;核心属性：&lt;code&gt;host&lt;/code&gt;（主机标识）、&lt;code&gt;url&lt;/code&gt;（从库地址:端口）、&lt;code&gt;user&lt;/code&gt;（数据库用户名）、&lt;code&gt;password&lt;/code&gt;（密码）&lt;/li&gt;
&lt;li&gt;作用：定义&lt;strong&gt;从库&lt;/strong&gt;连接信息，接收读请求（SELECT），配合 &lt;code&gt;balance&lt;/code&gt; 实现负载均衡。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;关键属性补充&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;balance=&quot;1&quot;&lt;/code&gt;：开启读负载均衡（主从库均参与读）；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;writeType=&quot;0&quot;&lt;/code&gt;：写请求路由到第一个 &amp;lt;writeHost&amp;gt;（主库）；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;switchType=&quot;1&quot;&lt;/code&gt;：主库故障时自动切换到备用主库/从库。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;4&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;阐述 Mycat 读写分离中负载均衡策略 balance 属性不同取值的含义和适用场景。
答：
balance 取值 “0”，核心含义为“读请求仅走主库，从库不参与”，适用场景为单主库、强一致性读、主从延迟极高
balance 取值 “1”，核心含义为“读请求走从库+备用主库，主库只读不写”，适用场景为1主多从+备用主库、常规读写分离
balance 取值 “2”，核心含义为“所有主从节点均分担读请求”，适用场景为主库资源充足、读压力适中
balance 取值 “3”，核心含义为“读请求&lt;strong&gt;只&lt;/strong&gt;分发到当前主库对应的从库 (&lt;code&gt;readHost&lt;/code&gt;) 上，&lt;strong&gt;主库完全不负担任何读压力&lt;/strong&gt;。”，适用场景为&lt;strong&gt;一主多从&lt;/strong&gt;架构，且希望&lt;strong&gt;严格分离读写&lt;/strong&gt;、保障主库写性能的场景&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3 操作题&lt;/h3&gt;
&lt;h4&gt;1&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;请详细描述在 Linux 环境下使用 Mycat 实现 MySQL 一主一从读写分离的完整操作步骤，包括 MySQL 主从复制配置、Mycat 安装与配置、测试验证等。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;// **MySQL 主从复制配置**

# 配置主库，指定server_id和开启binlog日记
[root@master ~]# grep -vE &quot;#&quot; /etc/my.cnf
[mysqld]
server-id=56
log-bin=mysql56

# 重启服务
[root@master /]# systemctl restart mysqld

# 创建用户同步的repluser账号密码repluser
mysql&amp;gt; create user repluser@&quot;%&quot; identified WITH mysql_native_password by &quot;repluser&quot;;
Query OK, 0 rows affected (0.09 sec)
# 给repluser用户赋权
mysql&amp;gt; grant replication slave on *.*  to repluser@&quot;%&quot;;
Query OK, 0 rows affected (0.05 sec)
# 查询binlog名称和偏移量
mysql&amp;gt; show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql56.000002 |      157 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)



// **从库安装mysql服务**

# 配置从库，指定server_id和开启binlog日记
[root@slave1 ~]# vim /etc/my.cnf
[root@slave1 ~]# grep -vE &quot;#&quot; /etc/my.cnf
[mysqld]
server-id=57
log_bin=/var/lib/mysql/binlog
relay_log=/var/lib/mysql/relaylog

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

# 从库配置
# 修改默认密码
[root@slave1 ~]# mysql -uroot -p123
# 配置 MySQL 主从复制
mysql&amp;gt; change  master to  master_host=&quot;192.168.88.10&quot; , master_user=&quot;repluser&quot; , master_password=&quot;repluser&quot; ,master_log_file=&quot;mysql56.000002&quot; , master_log_pos=157;
Query OK, 0 rows affected, 8 warnings (0.06 sec)

# 启动slave进程
mysql&amp;gt; start slave;
Query OK, 0 rows affected, 1 warning (0.32 sec)

# 同步查看状态信息
mysql&amp;gt; show slave status \G
......
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
......


# 配置mycat服务jama用户
# 在master 服务器添加
mysql&amp;gt; create user jama@&quot;%&quot;  identified by &quot;123456&quot;;
Query OK, 0 rows affected (0.24 sec)

mysql&amp;gt; grant  all on *.* to  jama@&quot;%&quot;;
Query OK, 0 rows affected (0.19 sec)

# 在slave 服务器查看是否同步成功
[root@slave1 ~]# mysql -e &apos;select user , host from mysql.user where user=&quot;jama&quot;&apos;
+------+------+
| user | host |
+------+------+
| jama | %    |
+------+------+
[root@slave1 ~]#





// **Mycat 安装与配置、测试验证**

# 安装mycat 软件和环境
# 安装jdk64和unzip
[root@mycat ~]# yum -y install java-1.8.0-openjdk.x86_64 unzip
# 安装mycat
[root@mycat ~]# unzip mycat2-install-template-1.21.zip 
[root@mycat ~]# mv mycat /usr/local/
# 安装依赖
[root@mycat ~]# cp mycat2-1.21-release-jar-with-dependencies.jar /usr/local/mycat/lib/
[root@mycat ~]# chmod -R 777 /usr/local/mycat/ 

# 配置mycat 密码
# 定义客户端连接mycat 服务使用用户及密码：
[root@mycat ~]# vim  /usr/local/mycat/conf/users/root.user.json
{
        &quot;dialect&quot;:&quot;mysql&quot;,
        &quot;ip&quot;:null,
        &quot;password&quot;:&quot;654321&quot;, # 密码
        &quot;transactionType&quot;:&quot;proxy&quot;,
        &quot;username&quot;:&quot;mycat&quot; # 用户名
}

# mycat【麦-凯特】连接本机数据库配置
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/prototypeDs.datasource.json
{
        &quot;dbType&quot;:&quot;mysql&quot;,
        &quot;idleTimeout&quot;:60000,
        &quot;initSqls&quot;:[],
        &quot;initSqlsGetConnection&quot;:true,
        &quot;instanceType&quot;:&quot;READ_WRITE&quot;,
        &quot;maxCon&quot;:1000,
        &quot;maxConnectTimeout&quot;:3000,
        &quot;maxRetryCount&quot;:5,
        &quot;minCon&quot;:1,
        &quot;name&quot;:&quot;prototypeDs&quot;,
        &quot;password&quot;:&quot;123456&quot;, # 密码
        &quot;type&quot;:&quot;JDBC&quot;,
        &quot;url&quot;:&quot;jdbc:mysql://localhost:3306/mysql?useUnicode=true&amp;amp;serverTimezone=Asia/Shanghai&amp;amp;characterEncoding=UTF-8&quot;, # 连接本机的数据库服务
        &quot;user&quot;:&quot;jam&quot;, # 用户名
        &quot;weight&quot;:0
}



# mycat58主机mysql配置
[root@mycat ~]# mysql -uroot -p123
#  创建jam用户
mysql&amp;gt; create user jam@&apos;%&apos; identified by &apos;123456&apos;;
Query OK, 0 rows affected (0.52 sec)
#  授予权限
mysql&amp;gt; grant all on *.* to jam@&apos;%&apos;;
Query OK, 0 rows affected (1.14 sec)

# 断开连接
mysql&amp;gt; exit


# 启动mycat 服务
[root@mycat ~]# /usr/local/mycat/bin/mycat start
Starting mycat2...

# 半分钟左右 能看到端口     
[root@mycat ~]# netstat -tunlp | grep -E &quot;8066|9066&quot;
tcp6       0      0 :::8066                 :::*                    LISTEN      18159/java          
tcp6       0      0 127.0.0.1:9066          :::*                    LISTEN      18159/java       


# 连接mycat 服务
[root@mycat ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321

mysql&amp;gt; show databases;
+--------------------+
| `Database`         |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.11 sec)


# 配置读写分离
# 添加数据源
# 连接mycat 服务
[root@mycat ~]# mysql -h 127.0.0.1 -P8066 -umycat -p654321

# 添加mysql56数据库服务器
mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;whost56&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.10:3306&quot;,&quot;user&quot;:&quot;jama&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
Query OK, 0 rows affected (0.86 sec)

# 添加mysql57数据库服务器
mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;rhost57&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.20:3306&quot;,&quot;user&quot;:&quot;jama&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
Query OK, 0 rows affected (0.06 sec)

# 查看数据源
mysql&amp;gt; /*+mycat:showDataSources{}*/ \G
*************************** 1. row ***************************
                   NAME: whost56
               USERNAME: jama
               PASSWORD: 123456
......
                DB_TYPE: mysql
                    URL: jdbc:mysql://192.168.88.10:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
......
*************************** 2. row ***************************
                   NAME: prototypeDs
               USERNAME: jam
               PASSWORD: 123456
......
                DB_TYPE: mysql
                    URL: jdbc:mysql://localhost:3306/mysql?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
......
*************************** 3. row ***************************
                   NAME: rhost57
               USERNAME: jama
               PASSWORD: 123456
......
                DB_TYPE: mysql
                    URL: jdbc:mysql://192.168.88.20:3306?useUnicode=true&amp;amp;serverTimezone=Asia/Shanghai&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
......
3 rows in set (0.01 sec)

# 创建集群
[root@mycat ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321

# 创建集群
mysql&amp;gt;/*!mycat:createcluster{
&quot;name&quot;:&quot;rwcluster&quot;,
&quot;masters&quot;:[&quot;whost56&quot;],
&quot;replicas&quot;:[&quot;rhost57&quot;]
}*/ ;


# 查看集群信息
mysql&amp;gt; /*+ mycat:showClusters{}*/ \G
*************************** 1. row ***************************
             NAME: rwcluster
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 2000
             TYPE: BALANCE_ALL
         WRITE_DS: whost56
          READ_DS: whost56,rhost57
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
*************************** 2. row ***************************
             NAME: prototype
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 200
             TYPE: BALANCE_ALL
         WRITE_DS: prototypeDs
          READ_DS: prototypeDs
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
2 rows in set (0.01 sec)


# 指定主机角色
# 修改master 角色主机仅负责写访问
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/whost56.datasource.json
{
        &quot;dbType&quot;:&quot;mysql&quot;,
        &quot;idleTimeout&quot;:60000,
        &quot;initSqls&quot;:[],
        &quot;initSqlsGetConnection&quot;:true,
        &quot;instanceType&quot;:&quot;WRITE&quot;, 仅负责写访问
        &quot;logAbandoned&quot;:true,
        &quot;maxCon&quot;:1000,
        &quot;maxConnectTimeout&quot;:30000,
        &quot;maxRetryCount&quot;:5,
        &quot;minCon&quot;:1,
        &quot;name&quot;:&quot;whost56&quot;,
        &quot;password&quot;:&quot;123456&quot;,
        &quot;queryTimeout&quot;:0,
        &quot;removeAbandoned&quot;:false,
        &quot;removeAbandonedTimeoutSecond&quot;:180,
        &quot;type&quot;:&quot;JDBC&quot;,
        &quot;url&quot;:&quot;jdbc:mysql://192.168.90.56:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&quot;,
        &quot;user&quot;:&quot;jama&quot;,
        &quot;weight&quot;:0
}
:wq

# 修改slave 角色主机仅负责读访问
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/rhost57.datasource.json
{
        &quot;dbType&quot;:&quot;mysql&quot;,
        &quot;idleTimeout&quot;:60000,
        &quot;initSqls&quot;:[],
        &quot;initSqlsGetConnection&quot;:true,
        &quot;instanceType&quot;:&quot;READ&quot;,仅负责读访问
        &quot;logAbandoned&quot;:true,
        &quot;maxCon&quot;:1000,
        &quot;maxConnectTimeout&quot;:30000,
        &quot;maxRetryCount&quot;:5,
        &quot;minCon&quot;:1,
        &quot;name&quot;:&quot;rhost57&quot;,
        &quot;password&quot;:&quot;123456&quot;,
        &quot;queryTimeout&quot;:0,
        &quot;removeAbandoned&quot;:false,
        &quot;removeAbandonedTimeoutSecond&quot;:180,
        &quot;type&quot;:&quot;JDBC&quot;,
        &quot;url&quot;:&quot;jdbc:mysql://192.168.90.57:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&quot;,
        &quot;user&quot;:&quot;jama&quot;,
        &quot;weight&quot;:0
}


# 修改读策略
[root@mycat ~]# vim /usr/local/mycat/conf/clusters/rwcluster.cluster.json 
{
        &quot;clusterType&quot;:&quot;MASTER_SLAVE&quot;,
        &quot;heartbeat&quot;:{
                &quot;heartbeatTimeout&quot;:1000,
                &quot;maxRetryCount&quot;:3,
                &quot;minSwitchTimeInterval&quot;:300,
                &quot;showLog&quot;:false,
                &quot;slaveThreshold&quot;:0.0
        },
        &quot;masters&quot;:[
                &quot;whost56&quot;
        ],
        &quot;maxCon&quot;:2000,
        &quot;name&quot;:&quot;rwcluster&quot;,
        &quot;readBalanceType&quot;:&quot;BALANCE_ALL_READ&quot;,# _READ将查询语句分发到从数据库节点
        &quot;replicas&quot;:[
                &quot;rhost57&quot;
        ],
        &quot;switchType&quot;:&quot;SWITCH&quot;
}
:wq

# 重启mycat 服务
[root@mycat ~]# /usr/local/mycat/bin/mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...

[root@mycat ~]#







// **测试读写分离测试读写分离**
# 指定testdb库存储数据使用的集群
[root@mycat ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321 
mysql&amp;gt; create database testdb;
Query OK, 0 rows affected (0.54 sec)

mysql&amp;gt; exit
Bye
# 指定testdb库存储数据使用的集群
[root@mycat ~]# vim /usr/local/mycat/conf/schemas/testdb.schema.json
{
        &quot;customTables&quot;:{},
        &quot;globalTables&quot;:{},
        &quot;normalProcedures&quot;:{},
        &quot;normalTables&quot;:{},
        &quot;schemaName&quot;:&quot;testdb&quot;,
        &quot;targetName&quot;:&quot;rwcluster&quot;, 添加此行,之前创建的集群名rwcluster
        &quot;shardingTables&quot;:{},
        &quot;views&quot;:{}
}
:wq

[root@mycat ~]# /usr/local/mycat/bin/mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...


# 连接mycat 服务建表插入记录
[root@mycat ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321 
mysql&amp;gt; create table testdb.user (name varchar(10), password varchar(10));
Query OK, 0 rows affected (3.52 sec)

mysql&amp;gt; insert into testdb.user values(&quot;yaya&quot;,&quot;123456&quot;);
Query OK, 1 row affected (0.39 sec)

mysql&amp;gt; select * from testdb.user;
+------+----------+
| name | password |
+------+----------+
| yaya | 123456   |
+------+----------+
1 row in set (0.02 sec)


# 测试读写分离
# 在从服务器本机插入记录，数据仅在从服务器有，主服务器没有
[root@slave1 ~]# mysql -uroot -p123 -e &apos;insert into testdb.user values(&quot;yayaA&quot;,&quot;654321&quot;)&apos;
mysql: [Warning] Using a password on the command line interface can be insecure.

[root@slave1 ~]# mysql -uroot -p123 -e &apos;select * from testdb.user&apos;
mysql: [Warning] Using a password on the command line interface can be insecure.
+-------+----------+
| name  | password |
+-------+----------+
| yaya  | 123456   |
| yayaA | 654321   |
+-------+----------+


# 主服务器数据不变，日志偏移量不不变
[root@master ~]# mysql -uroot -p123 -e &apos;select * from testdb.user&apos;
mysql: [Warning] Using a password on the command line interface can be insecure.
+------+----------+
| name | password |
+------+----------+
| yaya | 123456   |
+------+----------+

[root@master ~]# mysql -uroot -p123 -e &apos;show master status&apos;
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql56.000002 |     1503 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+

# 客户端连接mycat 服务读/写数据
#  查看到的是2条记录的行
mysql&amp;gt; select * from testdb.user;
+-------+----------+
| name  | password |
+-------+----------+
| yaya  | 123456   |
| yayaA | 654321   |
+-------+----------+
2 rows in set (1.34 sec)

#   插入记录
mysql&amp;gt; insert into testdb.user values(&quot;yayaB&quot;,&quot;123456&quot;);
Query OK, 1 row affected (0.14 sec)

mysql&amp;gt; select * from testdb.user;
+-------+----------+
| name  | password |
+-------+----------+
| yaya  | 123456   |
| yayaB | 123456   |
+-------+----------+
2 rows in set (0.00 sec)

# 在主服务器查看数据和日志偏移量
[root@master ~]# mysql -uroot -p123 -e &apos;select * from testdb.user&apos;
mysql: [Warning] Using a password on the command line interface can be insecure.
+-------+----------+
| name  | password |
+-------+----------+
| yaya  | 123456   |
| yayaB | 123456   |
+-------+----------+

[root@master ~]# mysql -uroot -p123 -e &apos;show master status&apos;
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql56.000002 |     1796 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+

# 客户端连接mycat 服务查看到的是3条记录
mysql&amp;gt; select * from testdb.user;
+-------+----------+
| name  | password |
+-------+----------+
| yaya  | 123456   |
| yayaA | 654321   |
| yayaB | 123456   |
+-------+----------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;假设已有一个 MySQL 双主双从的主从复制环境，现要使用 Mycat 实现读写分离，请写出 Mycat 的具体配置步骤和配置文件示例。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;# Mycat 核心配置步骤
# 1：确认 Mycat 环境（已安装 JDK 1.8+，Mycat 已部署）

# 2：配置 Mycat 数据源（4个节点，每个节点1个配置文件）
# 2.1 主库1数据源：masterA.datasource.json
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/masterA.datasource.json
{
  &quot;dbType&quot;: &quot;mysql&quot;,
  &quot;idleTimeout&quot;: 60000,
  &quot;initSqls&quot;: [],
  &quot;initSqlsGetConnection&quot;: true,
  &quot;instanceType&quot;: &quot;WRITE&quot;,  # 主库：写角色
  &quot;maxCon&quot;: 1000,
  &quot;maxConnectTimeout&quot;: 30000,
  &quot;maxRetryCount&quot;: 5,
  &quot;minCon&quot;: 1,
  &quot;name&quot;: &quot;masterA&quot;,  # 数据源名称（与拓扑标识一致）
  &quot;password&quot;: &quot;Mycat@123&quot;,
  &quot;type&quot;: &quot;JDBC&quot;,
  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.61:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
  &quot;user&quot;: &quot;mycat_user&quot;,
  &quot;weight&quot;: 1  # 写负载权重（双主权重相同，均分写请求）
}

# 2.2 主库2数据源：masterB.datasource.json
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/masterB.datasource.json
{
  &quot;dbType&quot;: &quot;mysql&quot;,
  &quot;idleTimeout&quot;: 60000,
  &quot;initSqls&quot;: [],
  &quot;initSqlsGetConnection&quot;: true,
  &quot;instanceType&quot;: &quot;WRITE&quot;,  # 主库：写角色（双主互备）
  &quot;maxCon&quot;: 1000,
  &quot;maxConnectTimeout&quot;: 30000,
  &quot;maxRetryCount&quot;: 5,
  &quot;minCon&quot;: 1,
  &quot;name&quot;: &quot;masterB&quot;,  # 数据源名称
  &quot;password&quot;: &quot;Mycat@123&quot;,
  &quot;type&quot;: &quot;JDBC&quot;,
  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.62:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
  &quot;user&quot;: &quot;mycat_user&quot;,
  &quot;weight&quot;: 1  # 与主库1权重一致，实现写负载均衡
}

# 2.3 从库1数据源：slaveA.datasource.json
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/slaveA.datasource.json
{
  &quot;dbType&quot;: &quot;mysql&quot;,
  &quot;idleTimeout&quot;: 60000,
  &quot;initSqls&quot;: [],
  &quot;initSqlsGetConnection&quot;: true,
  &quot;instanceType&quot;: &quot;READ&quot;,  # 从库：读角色
  &quot;maxCon&quot;: 1000,
  &quot;maxConnectTimeout&quot;: 30000,
  &quot;maxRetryCount&quot;: 5,
  &quot;minCon&quot;: 1,
  &quot;name&quot;: &quot;slaveA&quot;,  # 数据源名称
  &quot;password&quot;: &quot;Mycat@123&quot;,
  &quot;type&quot;: &quot;JDBC&quot;,
  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.63:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
  &quot;user&quot;: &quot;mycat_user&quot;,
  &quot;weight&quot;: 1  # 读负载权重（双从权重相同，均分读请求）
}

# 2.4 从库2数据源：slaveB.datasource.json
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/slaveB.datasource.json
{
  &quot;dbType&quot;: &quot;mysql&quot;,
  &quot;idleTimeout&quot;: 60000,
  &quot;initSqls&quot;: [],
  &quot;initSqlsGetConnection&quot;: true,
  &quot;instanceType&quot;: &quot;READ&quot;,  # 从库：读角色
  &quot;maxCon&quot;: 1000,
  &quot;maxConnectTimeout&quot;: 30000,
  &quot;maxRetryCount&quot;: 5,
  &quot;minCon&quot;: 1,
  &quot;name&quot;: &quot;slaveB&quot;,  # 数据源名称
  &quot;password&quot;: &quot;Mycat@123&quot;,
  &quot;type&quot;: &quot;JDBC&quot;,
  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.64:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
  &quot;user&quot;: &quot;mycat_user&quot;,
  &quot;weight&quot;: 1  # 与从库1权重一致，实现读负载均衡
}

# 3：配置 Mycat 集群（核心：双主双从读写策略）
[root@mycat ~]# vim /usr/local/mycat/conf/clusters/dual_master_dual_slave.cluster.json
{
  &quot;clusterType&quot;: &quot;MASTER_SLAVE&quot;,  # 集群类型：主从架构（支持双主）
  &quot;heartbeat&quot;: {  # 心跳检测（监测节点存活）
    &quot;heartbeatTimeout&quot;: 1000,
    &quot;maxRetryCount&quot;: 3,
    &quot;minSwitchTimeInterval&quot;: 300,  # 故障切换最小间隔（毫秒）
    &quot;showLog&quot;: false,
    &quot;slaveThreshold&quot;: 0.5  # 从库同步延迟阈值（秒），超过则剔除
  },
  &quot;masters&quot;: [&quot;masterA&quot;, &quot;masterB&quot;],  # 双主数据源名称（写请求路由到这里）
  &quot;maxCon&quot;: 4000,  # 集群最大连接数（4个节点总和）
  &quot;name&quot;: &quot;dual_master_dual_slave&quot;,  # 集群名称（后续关联逻辑库用）
  &quot;readBalanceType&quot;: &quot;BALANCE_ALL_READ&quot;,  # 读负载策略：所有从库均分读请求
  &quot;replicas&quot;: [&quot;slaveA&quot;, &quot;slaveB&quot;],  # 双从数据源名称（读请求路由到这里）
  &quot;switchType&quot;: &quot;SWITCH&quot;,  # 故障切换策略：自动切换（主库故障时切换到备用主库）
  &quot;writeBalanceType&quot;: &quot;BALANCE_ALL_WRITE&quot;  # 写负载策略：双主均分写请求（核心！双主特色）
}

# 4：配置 Mycat 逻辑库（关联集群）
[root@mycat mycat]# vim /usr/local/mycat/conf/schemas/business.schema.json
{
  &quot;customTables&quot;: {},
  &quot;globalTables&quot;: {},
  &quot;normalProcedures&quot;: {},
  &quot;normalTables&quot;: {},
  &quot;schemaName&quot;: &quot;business&quot;,  # 逻辑库名称（应用连接 Mycat 时使用）
  &quot;targetName&quot;: &quot;dual_master_dual_slave&quot;,  # 关联上面创建的集群名称
  &quot;shardingTables&quot;: {},
  &quot;views&quot;: {}
}

# 5：配置 Mycat 访问用户（可选，若已配置可跳过）
[root@mycat ~]# vim /usr/local/mycat/conf/users/mycat_user.user.json
{
  &quot;dialect&quot;: &quot;mysql&quot;,
  &quot;ip&quot;: null,  # 允许所有IP访问（生产环境可指定IP）
  &quot;password&quot;: &quot;Mycat@666&quot;,  # 应用连接 Mycat 的密码
  &quot;transactionType&quot;: &quot;proxy&quot;,
  &quot;username&quot;: &quot;mycat_app&quot;  # 应用连接 Mycat 的用户名
}

# **启动与验证**
# 重启 Mycat 加载配置
[root@mycat ~]# /usr/local/mycat/bin/mycat restart

# 2.1 连接 Mycat 逻辑库
[root@mycat ~]# mysql -h 127.0.0.1 -P 8066 -u mycat_app -pMycat@666
mysql&amp;gt; -- 查看逻辑库
mysql&amp;gt; show databases;
mysql&amp;gt; -- 查看 Mycat 数据源状态
mysql&amp;gt; /*+ mycat:showDataSources{}*/ \G
mysql&amp;gt; -- 查看集群状态
mysql&amp;gt; /*+ mycat:showClusters{}*/ \G

-- **验证读写分离效果**
mysql&amp;gt; -- 写操作（插入数据，会路由到双主之一）
mysql&amp;gt; use business;
mysql&amp;gt; create table test_user (id int primary key auto_increment, name varchar(20));
mysql&amp;gt; insert into test_user (name) values (&quot;user1&quot;), (&quot;user2&quot;);

# 直接连接 masterA 查看双主数据
[root@mycat ~]# mysql -h 192.168.90.61 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
# 直接连接 masterB 查看双主数据
[root@mycat ~]# mysql -h 192.168.90.62 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;

# 查看双从数据
[root@mycat ~]# mysql -h 192.168.90.63 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
[root@mycat ~]# mysql -h 192.168.90.64 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# Mycat 实现 MySQL 双主双从读写分离（配置步骤+文件示例）
## 一、环境前提（已就绪）
假设双主双从复制环境已搭建完成（**核心前提：双主互为主从，主从数据同步正常**），拓扑如下：
| 节点角色       | IP地址         | 端口 | 数据库用户 | 密码   | 实例标识（Mycat中用） |
|----------------|----------------|------|------------|--------|-----------------------|
| 主库1（MasterA） | 192.168.90.61  | 3306 | mycat_user | Mycat@123 | masterA               |
| 主库2（MasterB） | 192.168.90.62  | 3306 | mycat_user | Mycat@123 | masterB               |
| 从库1（SlaveA）  | 192.168.90.63  | 3306 | mycat_user | Mycat@123 | slaveA                |
| 从库2（SlaveB）  | 192.168.90.64  | 3306 | mycat_user | Mycat@123 | slaveB                |

### 双主双从复制要求
- 双主已配置 **互为主从**（MasterA → MasterB 同步，MasterB → MasterA 同步），支持写负载或故障切换；
- 每个主库对应从库同步正常（MasterA → SlaveA，MasterB → SlaveB），`Slave_IO_Running=Yes` 且 `Slave_SQL_Running=Yes`；
- 所有节点已创建 Mycat 访问用户（`mycat_user`），并授予权限：`GRANT ALL ON *.* TO &apos;mycat_user&apos;@&apos;%&apos; IDENTIFIED WITH mysql_native_password BY &apos;Mycat@123&apos;;`

## 二、Mycat 核心配置步骤（基于 Mycat 2.x，与你之前版本一致）
### 步骤1：确认 Mycat 环境（已安装 JDK 1.8+，Mycat 2.x 已部署）
无需额外安装，仅需配置以下文件（路径：`/usr/local/mycat/conf/`）。

### 步骤2：配置 Mycat 数据源（4个节点，每个节点1个配置文件）
在 `conf/datasources/` 目录下，创建4个数据源配置文件（描述每个 MySQL 节点的连接信息）。

#### 2.1 主库1数据源：masterA.datasource.json
	```json
	{
	  &quot;dbType&quot;: &quot;mysql&quot;,
	  &quot;idleTimeout&quot;: 60000,
	  &quot;initSqls&quot;: [],
	  &quot;initSqlsGetConnection&quot;: true,
	  &quot;instanceType&quot;: &quot;WRITE&quot;,  // 主库：写角色
	  &quot;maxCon&quot;: 1000,
	  &quot;maxConnectTimeout&quot;: 30000,
	  &quot;maxRetryCount&quot;: 5,
	  &quot;minCon&quot;: 1,
	  &quot;name&quot;: &quot;masterA&quot;,  // 数据源名称（与拓扑标识一致）
	  &quot;password&quot;: &quot;Mycat@123&quot;,
	  &quot;type&quot;: &quot;JDBC&quot;,
	  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.61:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
	  &quot;user&quot;: &quot;mycat_user&quot;,
	  &quot;weight&quot;: 1  // 写负载权重（双主权重相同，均分写请求）
	}
	```

#### 2.2 主库2数据源：masterB.datasource.json
	```json
	{
	  &quot;dbType&quot;: &quot;mysql&quot;,
	  &quot;idleTimeout&quot;: 60000,
	  &quot;initSqls&quot;: [],
	  &quot;initSqlsGetConnection&quot;: true,
	  &quot;instanceType&quot;: &quot;WRITE&quot;,  // 主库：写角色（双主互备）
	  &quot;maxCon&quot;: 1000,
	  &quot;maxConnectTimeout&quot;: 30000,
	  &quot;maxRetryCount&quot;: 5,
	  &quot;minCon&quot;: 1,
	  &quot;name&quot;: &quot;masterB&quot;,  // 数据源名称
	  &quot;password&quot;: &quot;Mycat@123&quot;,
	  &quot;type&quot;: &quot;JDBC&quot;,
	  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.62:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
	  &quot;user&quot;: &quot;mycat_user&quot;,
	  &quot;weight&quot;: 1  // 与主库1权重一致，实现写负载均衡
	}
	```

#### 2.3 从库1数据源：slaveA.datasource.json
	```json
	{
	  &quot;dbType&quot;: &quot;mysql&quot;,
	  &quot;idleTimeout&quot;: 60000,
	  &quot;initSqls&quot;: [],
	  &quot;initSqlsGetConnection&quot;: true,
	  &quot;instanceType&quot;: &quot;READ&quot;,  // 从库：读角色
	  &quot;maxCon&quot;: 1000,
	  &quot;maxConnectTimeout&quot;: 30000,
	  &quot;maxRetryCount&quot;: 5,
	  &quot;minCon&quot;: 1,
	  &quot;name&quot;: &quot;slaveA&quot;,  // 数据源名称
	  &quot;password&quot;: &quot;Mycat@123&quot;,
	  &quot;type&quot;: &quot;JDBC&quot;,
	  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.63:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
	  &quot;user&quot;: &quot;mycat_user&quot;,
	  &quot;weight&quot;: 1  // 读负载权重（双从权重相同，均分读请求）
	}
	```

#### 2.4 从库2数据源：slaveB.datasource.json
	```json
	{
	  &quot;dbType&quot;: &quot;mysql&quot;,
	  &quot;idleTimeout&quot;: 60000,
	  &quot;initSqls&quot;: [],
	  &quot;initSqlsGetConnection&quot;: true,
	  &quot;instanceType&quot;: &quot;READ&quot;,  // 从库：读角色
	  &quot;maxCon&quot;: 1000,
	  &quot;maxConnectTimeout&quot;: 30000,
	  &quot;maxRetryCount&quot;: 5,
	  &quot;minCon&quot;: 1,
	  &quot;name&quot;: &quot;slaveB&quot;,  // 数据源名称
	  &quot;password&quot;: &quot;Mycat@123&quot;,
	  &quot;type&quot;: &quot;JDBC&quot;,
	  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.64:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
	  &quot;user&quot;: &quot;mycat_user&quot;,
	  &quot;weight&quot;: 1  // 与从库1权重一致，实现读负载均衡
	}
	```

### 步骤3：配置 Mycat 集群（核心：双主双从读写策略）
在 `conf/clusters/` 目录下，创建集群配置文件 `dual_master_dual_slave.cluster.json`，定义主从关系、负载策略、故障切换规则。

	```json
	{
	  &quot;clusterType&quot;: &quot;MASTER_SLAVE&quot;,  // 集群类型：主从架构（支持双主）
	  &quot;heartbeat&quot;: {  // 心跳检测（监测节点存活）
	    &quot;heartbeatTimeout&quot;: 1000,
	    &quot;maxRetryCount&quot;: 3,
	    &quot;minSwitchTimeInterval&quot;: 300,  // 故障切换最小间隔（秒）
	    &quot;showLog&quot;: false,
	    &quot;slaveThreshold&quot;: 0.5  // 从库同步延迟阈值（秒），超过则剔除
	  },
	  &quot;masters&quot;: [&quot;masterA&quot;, &quot;masterB&quot;],  // 双主数据源名称（写请求路由到这里）
	  &quot;maxCon&quot;: 4000,  // 集群最大连接数（4个节点总和）
	  &quot;name&quot;: &quot;dual_master_dual_slave&quot;,  // 集群名称（后续关联逻辑库用）
	  &quot;readBalanceType&quot;: &quot;BALANCE_ALL_READ&quot;,  // 读负载策略：所有从库均分读请求
	  &quot;replicas&quot;: [&quot;slaveA&quot;, &quot;slaveB&quot;],  // 双从数据源名称（读请求路由到这里）
	  &quot;switchType&quot;: &quot;SWITCH&quot;,  // 故障切换策略：自动切换（主库故障时切换到备用主库）
	  &quot;writeBalanceType&quot;: &quot;BALANCE_ALL_WRITE&quot;  // 写负载策略：双主均分写请求（核心！双主特色）
	}
	```

### 步骤4：配置 Mycat 逻辑库（关联集群）
在 `conf/schemas/` 目录下，创建逻辑库配置文件（例如 `business.schema.json`），指定业务逻辑库与集群的关联。

	```json
	{
	  &quot;customTables&quot;: {},
	  &quot;globalTables&quot;: {},
	  &quot;normalProcedures&quot;: {},
	  &quot;normalTables&quot;: {},
	  &quot;schemaName&quot;: &quot;business&quot;,  // 逻辑库名称（应用连接 Mycat 时使用）
	  &quot;targetName&quot;: &quot;dual_master_dual_slave&quot;,  // 关联上面创建的集群名称
	  &quot;shardingTables&quot;: {},
	  &quot;views&quot;: {}
	}
	```

### 步骤5：配置 Mycat 访问用户（可选，若已配置可跳过）
在 `conf/users/` 目录下，创建用户配置文件 `mycat_user.user.json`，定义应用连接 Mycat 的账号密码。

	```json
	{
	  &quot;dialect&quot;: &quot;mysql&quot;,
	  &quot;ip&quot;: null,  // 允许所有IP访问（生产环境可指定IP）
	  &quot;password&quot;: &quot;Mycat@666&quot;,  // 应用连接 Mycat 的密码
	  &quot;transactionType&quot;: &quot;proxy&quot;,
	  &quot;username&quot;: &quot;mycat_app&quot;  // 应用连接 Mycat 的用户名
	}
	```

## 三、关键配置说明（双主双从核心亮点）
1. **双主写负载均衡**：通过 `writeBalanceType: &quot;BALANCE_ALL_WRITE&quot;` + 双主 `instanceType: &quot;WRITE&quot;`，写请求会均匀分发到两个主库，分摊写压力；
2. **双从读负载均衡**：通过 `readBalanceType: &quot;BALANCE_ALL_READ&quot;` + 双从 `instanceType: &quot;READ&quot;`，读请求均匀分发到两个从库，最大化读性能；
3. **故障自动切换**：
   - 主库故障（如 masterA 宕机）：Mycat 通过心跳检测发现后，自动将写请求切换到 masterB，业务无感知；
   - 从库故障（如 slaveA 宕机）：自动剔除故障从库，读请求仅分发到正常从库（slaveB），不影响业务；
4. **同步延迟过滤**：`slaveThreshold: 0.5` 表示从库同步延迟超过 0.5 秒时，Mycat 会暂时剔除该从库，避免读旧数据。

## 四、启动与验证
### 1. 启动 Mycat
	```bash
	# 重启 Mycat 加载配置
	/usr/local/mycat/bin/mycat restart
	
	# 查看启动状态（确保 8066 端口监听）
	netstat -tunlp | grep 8066
	```

### 2. 验证配置正确性
#### 2.1 连接 Mycat 逻辑库
	```bash
	mysql -h 192.168.90.58 -P 8066 -u mycat_app -pMycat@666
	```

#### 2.2 验证逻辑库与集群关联
	```sql
	-- 查看逻辑库
	show databases;
	-- 应输出：business（配置的逻辑库名称）
	
	-- 查看 Mycat 数据源状态（Mycat 2.x 专用命令）
	/*+ mycat:showDataSources{}*/ \G
	-- 应显示 4 个数据源（masterA、masterB、slaveA、slaveB），状态为 OK
	
	-- 查看集群状态
	/*+ mycat:showClusters{}*/ \G
	-- 应显示集群 dual_master_dual_slave，主从节点正常
	```

#### 2.3 验证读写分离效果
	```sql
	-- 1. 写操作（插入数据，会路由到双主之一）
	use business;
	create table test_user (id int primary key auto_increment, name varchar(20));
	insert into test_user (name) values (&quot;user1&quot;), (&quot;user2&quot;);
	
	-- 2. 查看双主数据（均应存在插入的数据，证明双主同步正常）
	-- 直接连接 masterA 查看
	mysql -h 192.168.90.61 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
	-- 直接连接 masterB 查看
	mysql -h 192.168.90.62 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
	
	-- 3. 查看双从数据（均应同步主库数据，证明主从同步正常）
	mysql -h 192.168.90.63 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
	mysql -h 192.168.90.64 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
	
	-- 4. 读操作（通过 Mycat 查询，会路由到双从之一）
	-- 多次执行，观察 Mycat 日志（conf/logs/mycat.log），确认读请求分流到 slaveA/slaveB
	select * from test_user;
	```

## 五、注意事项
1. **双主复制前提**：必须确保双主互为主从配置正确（开启 GTID 模式最佳，避免同步冲突）；
2. **权限统一**：所有 MySQL 节点的 `mycat_user` 权限必须一致（至少拥有业务库的读写权限）；
3. **生产环境优化**：
   - 限制 Mycat 访问 IP（在用户配置文件中指定 `ip: &quot;192.168.90.0/24&quot;`）；
   - 调整 `maxCon`（连接数）、`idleTimeout`（空闲超时）适配业务压力；
   - 开启 Mycat 日志审计，便于排查问题；
4. **避免写冲突**：双主架构下，若同一表存在并发写，需确保表有主键（或唯一索引），避免同步报错。

## 总结
双主双从的 Mycat 配置核心是 **“数据源分角色（双主WRITE/双从READ）+ 集群配置写负载/读负载/故障切换”**，配置步骤与单主多从一致，仅需在集群中增加主库数据源、启用写负载策略即可。你的单主多从配置思路完全可复用，只需扩展数据源和调整集群参数，放心按此方案提交作业！
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;当 Mycat 服务启动失败，如何进行故障排查和解决，请给出详细的操作流程。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
### 一、检查启动状态与基础环境
1. **查看启动状态与错误提示**
    - 用`/usr/local/mycat/bin/mycat status`查看运行状态。
    - 手动启动并观察报错：`/usr/local/mycat/bin/mycat start 2&amp;gt;&amp;amp;1 | grep -E &quot;ERROR|Exception&quot;`。
    - 若提示“command not found”，用`find / -name &quot;mycat&quot; 2&amp;gt;/dev/null`找正确路径。
2. **验证 JDK 环境**
    - 检查版本：`java -version`。
    - 检查环境变量：`echo $JAVA_HOME`。
    - 未配置则临时配置：`export JAVA_HOME=/usr/lib/jvm/java - 1.8.0 - openjdk; export PATH=$PATH:$JAVA_HOME/bin`。
    - 永久配置：在`/etc/profile`添加配置并`source /etc/profile`。

### 二、查看核心日志
日志默认路径`/usr/local/mycat/conf/logs/`：
1. **主日志 mycat.log**：`tail -100 /usr/local/mycat/conf/logs/mycat.log | grep -E &quot;ERROR|WARN|Exception&quot;`。
2. **启动器日志 wrapper.log**：`tail -100 /usr/local/mycat/conf/logs/wrapper.log | grep -E &quot;ERROR|FATAL&quot;`。

### 三、排查配置文件错误
1. **检查语法**：用`jq`工具校验 JSON 格式配置文件。
2. **检查关键参数**：核对`datasources`、`clusters`、`schemas`、`users`配置文件参数。

### 四、排查端口占用问题
Mycat 默认用 8066 和 9066 端口：
1. 用`netstat -tunlp | grep`或`lsof -i:`检查端口占用。
2. 停止占用进程或修改`/usr/local/mycat/conf/mycat.properties`中的端口。

### 五、排查权限与目录访问问题
1. 检查目录权限，不足则`chmod -R 755 /usr/local/mycat/`。
2. 检查日志目录写入权限，可`chmod 777 /usr/local/mycat/conf/logs/`。
3. 检查运行用户，必要时修改目录所有者。

### 六、排查数据源连接问题
1. 测试网络连通性：`telnet`或`nc`。
2. 验证账号密码，检查账号存在性、权限和服务状态。
3. 检查防火墙/安全组，放行 3306 端口。

### 七、排查依赖与元数据问题（Mycat 2.x 特有）
1. 检查原型库配置文件。
2. 验证原型库连接。
3. 检查依赖 jar 包，缺失则手动下载。

### 八、极端情况：恢复默认配置，逐步测试
1. 备份当前配置。
2. 删除自定义配置。
3. 恢复默认原型库配置。
4. 启动 Mycat。
5. 逐步添加自定义配置并测试。
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# Mycat 服务启动失败：故障排查与解决完整操作流程
Mycat 启动失败的核心原因集中在 **环境依赖、配置错误、端口占用、权限不足、数据源连接异常** 五类，排查需遵循“从基础到深入、从日志到配置”的逻辑，逐步定位问题。以下是详细操作流程（基于 Mycat 2.x，兼容 1.x 核心思路）：


## 一、第一步：检查启动状态与基础环境（快速排除低级问题）
### 1. 查看 Mycat 启动状态与错误提示
首先通过官方命令查看启动状态，获取直接报错信息：
	```bash
	# 1. 查看 Mycat 运行状态（Mycat 2.x 命令）
	/usr/local/mycat/bin/mycat status
	
	# 2. 尝试手动启动，观察实时报错（关键！直接输出启动失败原因）
	/usr/local/mycat/bin/mycat start 2&amp;gt;&amp;amp;1 | grep -E &quot;ERROR|Exception&quot;
	
	# 3. 若提示“command not found”，确认 Mycat 安装路径正确
	find / -name &quot;mycat&quot; 2&amp;gt;/dev/null  # 找到正确路径（如 /opt/mycat），替换执行
	```
#### 常见状态与初步判断：
- 提示“not running”：服务未启动，需进一步查日志；
- 提示“Invalid JAVA_HOME”：JDK 环境未配置；
- 提示“Address already in use”：端口被占用；
- 提示“Could not load configuration”：配置文件错误。

### 2. 验证核心依赖：JDK 环境（Mycat 必需）
Mycat 依赖 JDK 1.8+（1.x 支持 1.7，2.x 强制 1.8+），先确认环境：
	```bash
	# 1. 检查 JDK 版本
	java -version
	# 正常输出示例：openjdk version &quot;1.8.0_382&quot;（需 1.8+，低于则报错）
	
	# 2. 检查 JAVA_HOME 环境变量
	echo $JAVA_HOME
	# 正常输出示例：/usr/lib/jvm/java-1.8.0-openjdk
	
	# 3. 若未配置 JAVA_HOME，手动配置（临时生效）
	export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk
	export PATH=$PATH:$JAVA_HOME/bin
	
	# 4. 永久配置（避免重启失效）
	echo &apos;export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk&apos; &amp;gt;&amp;gt; /etc/profile
	echo &apos;export PATH=$PATH:$JAVA_HOME/bin&apos; &amp;gt;&amp;gt; /etc/profile
	source /etc/profile
	```
#### 问题解决：
- 无 JDK：执行 `yum -y install java-1.8.0-openjdk.x86_64`（CentOS）安装；
- JDK 版本过低：卸载旧版本，重新安装 1.8+。


## 二、第二步：查看核心日志（定位问题关键）
Mycat 启动失败的详细原因会记录在日志中，优先查看以下 2 个核心日志文件（默认路径：`/usr/local/mycat/conf/logs/`）：

### 1. 主日志：mycat.log（记录配置加载、数据源连接、启动流程错误）
	```bash
	# 查看日志最后 100 行（聚焦最新错误）
	tail -100 /usr/local/mycat/conf/logs/mycat.log | grep -E &quot;ERROR|WARN|Exception&quot;
	
	# 若日志过大，搜索关键词定位
	grep -n &quot;Failed to&quot; /usr/local/mycat/conf/logs/mycat.log  # 搜索失败相关记录
	```

### 2. 启动器日志：wrapper.log（记录 JVM 启动、进程启动失败原因）
	```bash
	tail -100 /usr/local/mycat/conf/logs/wrapper.log | grep -E &quot;ERROR|FATAL&quot;
	```

#### 日志常见错误与对应解决：
| 日志错误关键词                | 问题原因                          | 快速解决                          |
|-----------------------------|-----------------------------------|-----------------------------------|
| Invalid JSON syntax         | 配置文件（.json）语法错误          | 检查对应 JSON 文件的逗号、引号闭合 |
| Could not connect to datasource | 数据源（MySQL）连接失败           | 验证 MySQL 地址、账号密码、网络连通性 |
| Address already in use: 8066 | 8066/9066 端口被占用              | 查找并停止占用进程，或修改 Mycat 端口 |
| Permission denied           | Mycat 目录/文件权限不足            | 赋予读写权限：chmod -R 755 /usr/local/mycat |
| Missing jar包名              | 依赖 jar 包缺失                    | 从安装包复制缺失 jar 到 lib 目录  |


## 三、第三步：排查配置文件错误（最常见原因）
Mycat 启动时会加载 `datasources`（数据源）、`clusters`（集群）、`schemas`（逻辑库）、`users`（用户）四类核心配置文件，JSON 语法错误、参数配置错误是主要诱因。

### 1. 检查配置文件语法（JSON 格式必须严格）
Mycat 2.x 配置文件均为 JSON 格式，逗号、引号、大括号不闭合会直接导致启动失败，用 `jq` 工具验证：
	```bash
	# 1. 安装 jq 工具（JSON 语法校验）
	yum -y install jq
	
	# 2. 逐个校验核心配置文件（以 datasources 为例）
	# 校验数据源配置（所有 .datasource.json 文件）
	for file in /usr/local/mycat/conf/datasources/*.json; do
	  echo &quot;校验文件：$file&quot;
	  jq . $file  # 语法错误会直接提示行号
	done
	
	# 3. 同理校验集群、逻辑库、用户配置
	for file in /usr/local/mycat/conf/clusters/*.json; do jq . $file; done
	for file in /usr/local/mycat/conf/schemas/*.json; do jq . $file; done
	for file in /usr/local/mycat/conf/users/*.json; do jq . $file; done
	```
#### 语法错误示例与修复：
- 错误：`{&quot;name&quot;:&quot;masterA&quot;, &quot;password&quot;:&quot;123&quot;}`（末尾多逗号）
- 修复：`{&quot;name&quot;:&quot;masterA&quot;, &quot;password&quot;:&quot;123&quot;}`（删除末尾逗号）

### 2. 检查关键配置参数（参数错误导致启动失败）
重点核对以下核心参数（配置文件中最易出错）：
#### 2.1 数据源配置（datasources/*.json）
	```json
	{
	  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.61:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&quot;,  // 确保 IP、端口正确
	  &quot;user&quot;: &quot;mycat_user&quot;,  // MySQL 账号存在且有权限
	  &quot;password&quot;: &quot;Mycat@123&quot;,  // 密码正确
	  &quot;instanceType&quot;: &quot;WRITE&quot;,  // 取值只能是 WRITE/READ/READ_WRITE（大小写敏感）
	  &quot;dbType&quot;: &quot;mysql&quot;  // 不能写错（如写成 &quot;mysql8&quot; 无效）
	}
	```

#### 2.2 集群配置（clusters/*.json）
	```json
	{
	  &quot;name&quot;: &quot;dual_master_dual_slave&quot;,
	  &quot;masters&quot;: [&quot;masterA&quot;, &quot;masterB&quot;],  // 数据源名称必须与 datasources 中一致
	  &quot;replicas&quot;: [&quot;slaveA&quot;, &quot;slaveB&quot;],  // 同上，不能拼写错误
	  &quot;clusterType&quot;: &quot;MASTER_SLAVE&quot;,  // 取值只能是 MASTER_SLAVE/SINGLE/CLUSTER
	  &quot;writeBalanceType&quot;: &quot;BALANCE_ALL_WRITE&quot;  // 取值符合 Mycat 规则
	}
	```

#### 2.3 逻辑库配置（schemas/*.json）
	```json
	{
	  &quot;schemaName&quot;: &quot;business&quot;,
	  &quot;targetName&quot;: &quot;dual_master_dual_slave&quot;  // 集群名称必须与 clusters 中一致
	}
	```

#### 2.4 用户配置（users/*.json）
	```json
	{
	  &quot;username&quot;: &quot;mycat_app&quot;,
	  &quot;password&quot;: &quot;Mycat@666&quot;,  // 不能包含特殊字符（如 @ 需转义，或直接用简单密码测试）
	  &quot;dialect&quot;: &quot;mysql&quot;  // 不能写错
	}
	```


## 四、第四步：排查端口占用问题
Mycat 默认占用 2 个端口：
- 8066：业务端口（应用连接 Mycat 用）
- 9066：管理端口（Mycat 管理命令用）
端口被占用会直接导致启动失败，排查流程：
	```bash
	# 1. 检查 8066 端口占用情况
	netstat -tunlp | grep 8066
	# 或用 lsof（更详细）
	lsof -i:8066
	
	# 2. 检查 9066 端口占用情况
	netstat -tunlp | grep 9066
	
	# 3. 若有占用进程，停止该进程（示例：PID 为 1234）
	kill -9 1234
	
	# 4. 若无法停止占用进程，修改 Mycat 端口（Mycat 2.x 配置）
	vi /usr/local/mycat/conf/mycat.properties
	# 修改以下参数（自定义未占用端口）
	server.port=8067  # 新业务端口
	manager.port=9067  # 新管理端口
	
	# 5. 重启 Mycat 测试
	/usr/local/mycat/bin/mycat restart
	```


## 五、第五步：排查权限与目录访问问题
Mycat 启动时需要读取配置文件、写入日志，权限不足会导致“Permission denied”错误：
	```bash
	# 1. 检查 Mycat 安装目录权限
	ls -ld /usr/local/mycat/
	# 正常权限：drwxr-xr-x（所有者、组有读写执行权限）
	
	# 2. 赋予完整权限（临时测试，生产环境可收紧）
	chmod -R 755 /usr/local/mycat/
	
	# 3. 检查日志目录写入权限（关键！日志写不进去会启动失败）
	ls -ld /usr/local/mycat/conf/logs/
	chmod 777 /usr/local/mycat/conf/logs/  # 临时赋予最大权限测试
	
	# 4. 检查运行用户（若用非 root 用户启动，需确保用户有目录权限）
	ps -ef | grep mycat  # 查看运行用户
	chown -R mycat:mycat /usr/local/mycat/  # 若用 mycat 用户，修改目录所有者
	```


## 六、第六步：排查数据源连接问题
若数据源（MySQL 主从节点）配置错误或无法连通，Mycat 启动时会因“连接数据源失败”报错：
	```bash
	# 1. 手动测试 Mycat 到 MySQL 数据源的网络连通性（以 masterA 为例）
	telnet 192.168.90.61 3306
	# 或用 nc 命令
	nc -zv 192.168.90.61 3306
	# 正常输出：succeeded!（失败则检查防火墙/安全组）
	
	# 2. 手动验证 MySQL 账号密码正确性（用 Mycat 配置的账号）
	mysql -h 192.168.90.61 -u mycat_user -pMycat@123
	# 若登录失败，检查：
	# - MySQL 账号是否存在：SELECT user, host FROM mysql.user WHERE user=&apos;mycat_user&apos;;
	# - 账号权限是否足够：GRANT ALL ON *.* TO &apos;mycat_user&apos;@&apos;%&apos; IDENTIFIED WITH mysql_native_password BY &apos;Mycat@123&apos;;
	# - MySQL 服务是否正常：systemctl status mysqld
	
	# 3. 检查 MySQL 防火墙/安全组（放行 3306 端口）
	firewall-cmd --zone=public --add-port=3306/tcp --permanent
	firewall-cmd --reload
	```


## 七、第七步：排查依赖与元数据问题（Mycat 2.x 特有）
Mycat 2.x 依赖“原型库（prototypeDs）”存储元数据，原型库配置错误会导致启动失败：
	```bash
	# 1. 检查原型库配置文件
	cat /usr/local/mycat/conf/datasources/prototypeDs.datasource.json
	# 核心要求：原型库必须是可连接的 MySQL 实例（可复用主库/独立库）
	
	# 2. 验证原型库连接
	mysql -h 192.168.90.61 -u mycat_user -pMycat@123  # 原型库配置的账号密码
	
	# 3. 检查依赖 jar 包（缺失会导致类加载失败）
	ls /usr/local/mycat/lib/ | grep -E &quot;mycat2|mysql-connector-java&quot;
	# 若缺失 mysql-connector-java（MySQL 驱动），手动下载放入 lib 目录
	wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.33/mysql-connector-java-8.0.33.jar -P /usr/local/mycat/lib/
	```


## 八、第八步：极端情况：恢复默认配置，逐步测试
若以上排查均无效，可能是配置文件错乱，可通过“恢复默认+逐步添加配置”定位问题：
	```bash
	# 1. 备份当前配置（避免丢失）
	cp -r /usr/local/mycat/conf /usr/local/mycat/conf_bak_$(date +%Y%m%d)
	
	# 2. 删除自定义配置（保留默认原型库和用户配置）
	rm -rf /usr/local/mycat/conf/datasources/*.json
	rm -rf /usr/local/mycat/conf/clusters/*.json
	rm -rf /usr/local/mycat/conf/schemas/*.json
	
	# 3. 恢复默认原型库配置（从安装包复制，或手动创建）
	cat &amp;gt; /usr/local/mycat/conf/datasources/prototypeDs.datasource.json &amp;lt;&amp;lt; EOF
	{
	  &quot;dbType&quot;:&quot;mysql&quot;,
	  &quot;idleTimeout&quot;:60000,
	  &quot;initSqls&quot;:[],
	  &quot;initSqlsGetConnection&quot;:true,
	  &quot;instanceType&quot;:&quot;READ_WRITE&quot;,
	  &quot;maxCon&quot;:1000,
	  &quot;maxConnectTimeout&quot;:3000,
	  &quot;maxRetryCount&quot;:5,
	  &quot;minCon&quot;:1,
	  &quot;name&quot;:&quot;prototypeDs&quot;,
	  &quot;password&quot;:&quot;Mycat@123&quot;,
	  &quot;type&quot;:&quot;JDBC&quot;,
	  &quot;url&quot;:&quot;jdbc:mysql://192.168.90.61:3306/mysql?serverTimezone=Asia/Shanghai&quot;,
	  &quot;user&quot;:&quot;mycat_user&quot;,
	  &quot;weight&quot;:0
	}
	EOF
	
	# 4. 启动 Mycat（若能启动，说明默认配置正常，问题在自定义配置）
	/usr/local/mycat/bin/mycat start
	
	# 5. 逐步添加自定义配置（每次添加一个文件，重启测试）
	# 先添加一个数据源 → 启动测试
	# 再添加集群 → 启动测试
	# 最后添加逻辑库 → 启动测试
	# 定位到导致失败的具体配置文件，针对性修改
	```


## 九、常见故障案例与快速解决
| 故障现象                          | 排查流程                          | 解决方法                          |
|-----------------------------------|-----------------------------------|-----------------------------------|
| 执行 mycat start 无反应，日志无输出 | 1. 检查 JAVA_HOME；2. 检查 wrapper.log | 配置 JAVA_HOME，或重新安装 Mycat 启动器 |
| 启动提示“数据源连接失败”           | 1. telnet 测试 MySQL 端口；2. 验证账号密码 | 放行 3306 端口，重新创建 MySQL 账号并授权 |
| JSON 语法错误导致启动失败          | 用 jq 工具校验所有配置文件         | 修复逗号、引号、大括号闭合问题    |
| 8066 端口被占用                    | netstat 查找占用进程               | 停止占用进程，或修改 Mycat 端口   |
| 权限不足“Permission denied”        | 检查 Mycat 目录权限               | chmod -R 755 /usr/local/mycat     |


## 十、排查总结（核心逻辑）
Mycat 启动失败排查遵循“**先基础（环境、端口、权限）→ 再日志（定位方向）→ 最后配置（精准修复）** ”的逻辑，90% 的问题集中在：
1. JDK 环境未配置或版本过低；
2. 配置文件（JSON）语法错误；
3. 数据源（MySQL）连接失败（IP/端口/账号/防火墙）；
4. 8066/9066 端口被占用；
5. Mycat 目录权限不足。

按以上流程逐步排查，均可定位并解决问题。若仍失败，可提供 `mycat.log` 和 `wrapper.log` 中的错误关键词，进一步精准分析。
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>12：redis【瑞迪斯】数据类型</title><link>https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/12-redis%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/12-redis%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B/</guid><description>12：redis【瑞迪斯】数据类型 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 03:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1&gt;12：redis【瑞迪斯】数据类型&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/12-redis%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B/image-20250621155239718.webp&quot; alt=&quot;image-20250621155239718&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;h3&gt;1.1 电商平台场景&lt;/h3&gt;
&lt;p&gt;在电商平台中，会大量使用 Redis【瑞迪斯】 来提升性能和处理并发。用字符串类型缓存商品的基本信息，减轻数据库压力；用列表类型实现消息队列，处理订单任务；用散列类型存储商品的多维度属性，方便单独查询和修改；用集合类型实现商品标签系统，便于用户根据标签搜索商品；用有序集合类型实现商品销量排行榜。&lt;/p&gt;
&lt;h3&gt;1.2 社交平台场景&lt;/h3&gt;
&lt;p&gt;社交平台利用 Redis【瑞迪斯】 来实现各种功能。字符串类型用于存储用户的会话信息，保证用户登录状态一致；列表类型存储用户的动态历史记录，方便用户查看；散列类型存储用户的详细资料；集合类型存储用户的好友列表，实现共同好友推荐；有序集合类型实现用户活跃度排行榜。&lt;/p&gt;
&lt;h2&gt;二、为什么学&lt;/h2&gt;
&lt;p&gt;学习 Redis【瑞迪斯】 数据类型具有多方面重要意义。从性能上看，Redis【瑞迪斯】 作为基于内存的键值型 NoSQL 数据库，读写速度极快，官方数据显示读取速度达 110000 次/秒，写速度 81000 次/秒，掌握其数据类型能让我们在开发中充分利用这一优势，提升系统性能。&lt;/p&gt;
&lt;p&gt;从应用场景来说，不同数据类型适用场景广泛。比如字符串类型可用于缓存、计数器、分布式锁等；列表类型能实现消息队列、排行榜、历史记录存储等；散列类型适合存储用户信息、商品属性等；集合类型可用于用户管理、唯一性检查等；有序集合类型能实现排行榜、分数统计等。学习这些数据类型，能让我们在面对各种业务需求时，选择合适的数据类型解决问题。&lt;/p&gt;
&lt;p&gt;从就业角度看，Redis【瑞迪斯】 在互联网领域应用广泛，掌握 Redis【瑞迪斯】 数据类型及其应用，能增强我们在职场上的竞争力，为从事相关工作打下坚实基础。&lt;/p&gt;
&lt;h2&gt;三、搭建redis【瑞迪斯】 服务器&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/12-redis%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B/image-20250621155333031.webp&quot; alt=&quot;image-20250621155333031&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3.1 什么是redis【瑞迪斯】&lt;/h3&gt;
&lt;p&gt;Redis【瑞迪斯】 即远程字典服务，是开源的基于内存的键值型NoSQL数据库，用C语言编写。它将数据存于内存，读写快，官方数据显示读取速度达110000次/秒，写速度81000次/秒 。支持字符串、哈希、列表、集合、有序集合等丰富数据结构，每种都有专门操作命令。提供RDB和AOF两种持久化机制，还支持主从复制、哨兵机制、集群模式等。采用单线程架构结合IO多路复用技术处理请求，避免多线程开销。广泛用于缓存、会话管理、排行榜等场景。&lt;/p&gt;
&lt;h3&gt;3.2 准备环境&lt;/h3&gt;
&lt;p&gt;克隆1台新虚拟机&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;redis64&lt;/td&gt;
&lt;td&gt;192.168.90.64&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;修改IP地址和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis64 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis64
[root@redis64 ~]# nmcli connection【肯耐申】 modify【莫迪fái】ens160 ipv4.addresses【额拽西斯】 192.168.90.64/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis64~]# nmcli connection【肯耐申】 up ens160 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3 安装和运行redis【瑞迪斯】&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#安装redis【瑞迪斯】
[root@redis64 ~]# yum -y install【因-斯多】 redis【瑞迪斯】

#查看redis【瑞迪斯】 版本
[root@redis64 ~]# rpm -q redis【瑞迪斯】
redis-6.2.18-1.el9_6.x86_64

#设置开机自启，并立即启动
[root@redis64 ~]# systemctl【西斯屯-ctl】 enable【ing 内 步】 redis【瑞迪斯】 --now

#查看redis端口
[root@redis64 ~]# netstat【劣 s 塔】 -antlup | grep【哥瑞普】 redis【瑞迪斯】
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      34578/redis-server  
tcp6       0      0 ::1:6379                :::*                    LISTEN      34578/redis-server
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.4 连接redis【瑞迪斯】 服务&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#连接redis【瑞迪斯】
[root@redis64 ~]# redis-cli

#检查能否正在访问
127.0.0.1:6379&amp;gt; ping   
PONG

#断开连接
127.0.0.1:6379&amp;gt; exit【诶西特】  
[root@redis64 ~]# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;完整的连接redis&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#发现通过IP无法连接
[root@redis64 ~]# redis-cli -h 192.168.90.64 -p 6379
Could not connect to Redis at 192.168.90.64:6379: Connection refused
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改redis【瑞迪斯】 配置文件，使得redis【瑞迪斯】 可以被任何机器连接&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#修改前
[root@redis64 ~]# vim /etc/redis/redis.conf 
  72 # IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
  73 # JUST COMMENT OUT THE FOLLOWING LINE.
  74 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  75 bind 127.0.0.1 -::1   #修改75行

#修改后
[root@redis64 ~]# vim /etc/redis/redis.conf 
  72 # IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
  73 # JUST COMMENT OUT THE FOLLOWING LINE.
  74 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  75 bind 0.0.0.0

#修改配置文件后重启
[root@redis64 ~]# systemctl【西斯屯-ctl】 restart【 率 s 达r】 redis【瑞迪斯】

 #现在可以连接
[root@redis64 ~]# redis-cli -h 192.168.90.64 -p 6379
192.168.90.64:6379&amp;gt; ping
PONG

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.5 给redis【瑞迪斯】 设置密码&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#修改903行
[root@redis64 ~]# vim /etc/redis/redis.conf 
 900 # The requirepass is not compatable with aclfile option and the ACL LOAD
 901 # command, these will cause requirepass to be ignored.
 902 #
 903  requirepass 123456

#修改后重启
[root@redis64 ~]# systemctl【西斯屯-ctl】 restart【 率 s 达r】 redis【瑞迪斯】

#连接redis【瑞迪斯】
[root@redis64 ~]# redis-cli

# 这时候操作失败
127.0.0.1:6379&amp;gt; ping  
(error) NOAUTH Authentication required.

# 输入密码认证
127.0.0.1:6379&amp;gt; auth 123456  
OK
127.0.0.1:6379&amp;gt; ping
PONG
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、字符串类型（string【斯jǘn】 类型）&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/12-redis%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B/image-20250621155359980.webp&quot; alt=&quot;image-20250621155359980&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;4.1 应用场景&lt;/h3&gt;
&lt;p&gt;Redis【瑞迪斯】 字符串类型是最基本的数据类型，支持存储整数、浮点数和字符串，适用于多种应用场景，以下是一些常见的应用场景：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;缓存&lt;/strong&gt;：可存储用户名、密码、会话标识符等简短字符串，也能缓存数据库查询结果、网页内容、用户信息等常用数据，减轻数据库压力，提高访问速度。例如在商品系统中，用 Redis【瑞迪斯】 String【斯jǘn】 类型缓存商品的静态信息，商品信息更新时，同步更新或使缓存失效 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;计数器&lt;/strong&gt;：利用 incr【因kuì儿】 和 decr【迪kuì儿】 命令实现计数功能，适用于统计网页访问量、点赞数、文章浏览量、商品库存数量等。比如在文章浏览量统计中，每次文章被访问，文章 ID 对应的浏览次数在 Redis【瑞迪斯】 中递增，还可定期将浏览次数同步到数据库用于历史数据分析 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分布式锁&lt;/strong&gt;：结合 setNX 命令，使用字符串实现简单的分布式锁，保证在分布式系统中的数据一致性和并发控制。例如在电商的秒杀活动或库存管理中，确保同一时间只有一个进程或线程可以修改共享资源，避免数据不一致 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;共享会话（Session【塞-神】）&lt;/strong&gt;：在分布式 Web 应用里，可集中管理用户的 Session【塞-神】 信息（如登录信息），确保用户无论访问哪台服务器都能保持一致的会话状态，避免因负载均衡到不同服务器而需重新登录。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;手机验证码&lt;/strong&gt;：存储短信验证码并设置过期时间，还可限制用户获取验证码的频率，例如限制每分钟获取不超过 5 次 。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;4.2 设置单个值&lt;/h3&gt;
&lt;p&gt;设置单个值，命令格式：&lt;/p&gt;
&lt;p&gt;set【赛特】   key【kì】   value【挖柳】&lt;/p&gt;
&lt;p&gt;查看key【kì】 对应的值&lt;/p&gt;
&lt;p&gt;get【脚(白话)特】 key【kì】&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis64 ~]# redis-cli -h 192.168.90.64 -p 6379
192.168.90.64:6379&amp;gt; auth 123456
OK
192.168.90.64:6379&amp;gt; set【赛特】 school【斯故】 moershi
OK
192.168.90.64:6379&amp;gt; get【脚(白话)特】 school【斯故】
&quot;moershi&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.4 设置多个值&lt;/h3&gt;
&lt;p&gt;设置多个值，命令格式：&lt;/p&gt;
&lt;p&gt;mset key1  value【挖柳】1  key2  value【挖柳】2  key3  value【挖柳】3...&lt;/p&gt;
&lt;p&gt;查看多个key【kì】 对应的值&lt;/p&gt;
&lt;p&gt;mget key1  key2  key3&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; mset name jam age 30 class yjs001
OK
192.168.90.64:6379&amp;gt; mget name age class
1) &quot;jam&quot;
2) &quot;30&quot;
3) &quot;yjs001&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.5 设置值的有效期&lt;/h3&gt;
&lt;p&gt;存储变量时 设置变量的有效期 px(毫秒) ex (秒)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; set【赛特】 name jam ex 10   #变量10秒过期
OK
192.168.90.64:6379&amp;gt; set【赛特】 class  nsd  px 10   #变量10毫秒过期
OK
192.168.90.64:6379&amp;gt;

# NX 不覆盖赋值
192.168.90.64:6379&amp;gt; set【赛特】 name xiaohong NX
(nil)
192.168.90.64:6379&amp;gt; get【脚(白话)特】 name
&quot;jam&quot;

# XX 覆盖赋值
192.168.90.64:6379&amp;gt; set【赛特】 name yaya XX
OK
192.168.90.64:6379&amp;gt; get【脚(白话)特】 name
&quot;yaya&quot;
192.168.90.64:6379&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;set【赛特】 命令完整格式演示&lt;/p&gt;
&lt;p&gt;set    名称        值     有效期类型     有效时间     是否覆盖
set    gender    girl        ex                20                NX&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; set【赛特】 gender girl  ex 20  NX
OK
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.6 数字增减操作&lt;/h3&gt;
&lt;h4&gt;incr【因kuì儿】 递增数字&lt;/h4&gt;
&lt;p&gt;- 递增数字：字符串类型可以存储任何形式的字符串，当存储的字符串是整数形式时，&lt;/p&gt;
&lt;p&gt;Redis【瑞迪斯】 提供了一个实用的命令 incr【因kuì儿】，其作用是让当前键值递增，并返回递增后的值。&lt;/p&gt;
&lt;p&gt;当要操作的键不存在时会默认键值为0，所以第一次递增后的结果是1。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 创建变量
192.168.90.64:6379&amp;gt; set【赛特】  num 1 
192.168.90.64:6379&amp;gt; incr【因kuì儿】 num    #+1
(integer) 2
192.168.90.64:6379&amp;gt; incr【因kuì儿】 num    #+1
(integer) 3
192.168.90.64:6379&amp;gt; get【脚(白话)特】 num     
&quot;3&quot;

# 复数递增数字 incrby
192.168.90.64:6379&amp;gt; incrby【因kuì儿 by】 num 2   #+2
(integer) 5
192.168.90.64:6379&amp;gt; incrby【因kuì儿 by】 num 3   #+3
(integer) 8
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;decr【迪kuì儿】 递减数字&lt;/h4&gt;
&lt;p&gt;- 增加指定的整数&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;- 递减数字
192.168.90.64:6379&amp;gt; decr【迪kuì儿】 num     #-1
(integer) 7

# 复数递减数字 decrby
192.168.90.64:6379&amp;gt; decrby num 3   #
(integer) 4
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;append【额 篇的】 尾部追加值&lt;/h4&gt;
&lt;p&gt;- 向尾部追加值
&lt;code&gt;append【额 篇的】&lt;/code&gt;通常指追加操作。在文件处理方面，可将数据添加到已有文件的末尾，而不是覆盖原内容。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 创建变量hi
192.168.90.64:6379&amp;gt; set【赛特】 hi Hello   
OK

# 因为字符串包含空格，需要使用引号
192.168.90.64:6379&amp;gt; append【额 篇的】 hi &quot; World&quot;   
(integer) 11        # 返回值为hi的总长度

192.168.90.64:6379&amp;gt; get【脚(白话)特】 hi
&quot;Hello World&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.7 字符串处理&lt;/h3&gt;
&lt;h4&gt;strlen【斯拽轮】 获取字符串长度&lt;/h4&gt;
&lt;p&gt;- 获取字符串长度
&lt;code&gt;strlen【斯拽轮】&lt;/code&gt;是用于获取存储在指定键的字符串值的长度的命令&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; strlen【斯拽轮】 hi
(integer) 11
- 中文字符返回字节数
192.168.90.64:6379&amp;gt; set【赛特】 name 张三
OK
192.168.90.64:6379&amp;gt; strlen【斯拽轮】 name
(integer) 6   # UTF-8编码的中文，由于“张”和“三”两个字的UTF-8编码的长度都是3，所以此例中会返回6。
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;getrange 获取变量部分数据&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;getrange【脚(白话) cùn局】&lt;/code&gt;命令用于获取存储在指定键的字符串值的子字符串。它的核心用途是按指定的起始和结束位置提取字符串的一部分。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 创建变量
192.168.90.64:6379&amp;gt; set【赛特】 zfc  ABCEF   
OK

# 输出变量值
192.168.90.64:6379&amp;gt; get zfc  
&quot;ABCEF&quot;

# 输出第1个到第2个字符
192.168.90.64:6379&amp;gt; getrange【脚(白话) cùn局】 zfc 0 1  
&quot;AB&quot;

# 输出第3个到第5个字符
192.168.90.64:6379&amp;gt; getrange【脚(白话) cùn局】 zfc 2 4  
&quot;CEF&quot;

# 输出倒数第2个到第1个字符
192.168.90.64:6379&amp;gt; getrange【脚(白话) cùn局】 zfc -2 -1 
&quot;EF&quot;
192.168.90.64:6379&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、Key【kì】的操作&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/12-redis%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B/image-20250621155426054.webp&quot; alt=&quot;image-20250621155426054&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;5.1 keys 列出所有的key【kì】&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; keys *
1) &quot;age&quot;
2) &quot;classs&quot;
3) &quot;name&quot;
4) &quot;school【斯故】&quot;

#keys 使用统配符查看变量, * 匹配所有变量名, ? 一个字符

# 变量名是3个字符
192.168.90.64:6379&amp;gt; keys ???  
1) &quot;age&quot;

# 变量名是a 开头的
192.168.90.64:6379&amp;gt; keys a*   
1) &quot;age&quot;

# 查看指定变量是否存在
192.168.90.64:6379&amp;gt; keys gender  
(empty list or set) # 说明变量没有定义

192.168.90.64:6379&amp;gt; keys name
1) &quot;name&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 select【涩莱克特】 选择数据库&lt;/h3&gt;
&lt;p&gt;（redis【瑞迪斯】总共有15个库，从0到15）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# select【涩莱克特】 切换库 默认库编号 0-15 

# 切换到 1号库里
192.168.90.64:6379&amp;gt; select【涩莱克特】 1  
OK

# 查看数据没有数据
192.168.90.64:6379[1]&amp;gt; keys * 
(empty list or set)
192.168.90.64:6379[1]&amp;gt; 
192.168.90.64:6379[1]&amp;gt; select【涩莱克特】 0  
OK
192.168.90.64:6379&amp;gt; select【涩莱克特】 16
(error) ERR DB index is out of range

# move 命令 移动变量到其他库里
192.168.90.64:6379&amp;gt; keys *
1) &quot;age&quot;
2) &quot;classs&quot;
3) &quot;name&quot;
4) &quot;school【斯故】&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.3 move 把某个key【kì】移动到某个库中&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;move&lt;/code&gt; 命令 移动变量到其他库里&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; keys *
1) &quot;age&quot;
2) &quot;classs&quot;
3) &quot;name&quot;
4) &quot;school【斯故】&quot;


# 把age 变量移动到1 号库里
192.168.90.64:6379&amp;gt; move age 1   
(integer) 1 
192.168.90.64:6379&amp;gt; keys *
1) &quot;classs&quot;
2) &quot;name&quot;
3) &quot;school【斯故】&quot;
192.168.90.64:6379&amp;gt; select【涩莱克特】  1
OK
192.168.90.64:6379[1]&amp;gt; keys *
1) &quot;age&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.4 exists【伊贼谁斯】  判断一个key【kì】是否存在&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#exists【伊贼谁斯】 检查变量是否存储  返回值1  变量存储 返回值是0 变量不存在
192.168.90.64:6379[1]&amp;gt; select【涩莱克特】 0
OK
192.168.90.64:6379&amp;gt; EXISTS【伊贼谁斯】 name  # 检查name变量是否存在
(integer) 1
192.168.90.64:6379&amp;gt; get【脚(白话)特】 name
&quot;plj&quot;
192.168.90.64:6379&amp;gt; set【赛特】 name bob
OK
192.168.90.64:6379&amp;gt; get【脚(白话)特】 name
&quot;bob&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.5 key【kì】的过期时间&lt;/h3&gt;
&lt;p&gt;expire【ī 斯 拜尔】 设置一个key【kì】的过期时间&lt;/p&gt;
&lt;p&gt;ttl  查看一个剩余的过期时间&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#EXPIRE【ī 斯 拜尔】 命令设置变量的过期时间 不设置变量永不过期
#ttl   检查变量可以在内存里存多久
192.168.90.64:6379&amp;gt; set【赛特】 sex girl
OK
192.168.90.64:6379&amp;gt; ttl sex
(integer) -1  #表示永不过期

192.168.90.64:6379&amp;gt; EXPIRE【ī 斯 拜尔】 sex 15   #设置过期时间15 秒
(integer) 1

192.168.90.64:6379&amp;gt; keys sex
1) &quot;sex&quot;

192.168.90.64:6379&amp;gt; ttl sex
(integer) 8  #还剩下8秒时间过期

192.168.90.64:6379&amp;gt; ttl sex
(integer) -2  #表示已经过期被删除

192.168.90.64:6379&amp;gt; keys  sex
(empty list or set)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;衍生命令（高频扩展）&lt;br /&gt;
Redis针对过期时间提供了更灵活的衍生命令，补充&lt;code&gt;EXPIRE&lt;/code&gt;的不足：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PEXPIRE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置毫秒级过期时间（更高精度）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PEXPIRE user:session:100 1800000&lt;/code&gt;（30分钟）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;EXPIREAT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置Key在指定Unix时间戳（秒）过期&lt;/td&gt;
&lt;td&gt;&lt;code&gt;EXPIREAT order:1001 1716643200&lt;/code&gt;（2024-05-26 00:00:00）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PEXPIREAT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置Key在指定Unix时间戳（毫秒）过期&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PEXPIREAT order:1001 1716643200000&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TTL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;查看Key剩余过期时间（秒，-1=永不过期，-2=已删除）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TTL user:session:100&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PTTL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;查看Key剩余过期时间（毫秒）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PTTL user:session:100&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PERSIST&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;移除Key的过期时间（设为永不过期）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PERSIST user:session:100&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;5.6 type【泰 普】  查看某个key【kì】是属于哪个数据类型&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#type【泰 普】 命令检查变量存储数据的类型  
#使用set【赛特】  mset命令存储的数据都字符类型。
#数据的类型不同 管理的命令也不同 
#明天讲数据类型。

192.168.90.64:6379&amp;gt; set【赛特】 x 99
OK
192.168.90.64:6379&amp;gt; mset y 108
OK
192.168.90.64:6379&amp;gt; type【泰 普】 x
string
192.168.90.64:6379&amp;gt; type【泰 普】 y
string
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.7 del  删除一个key【kì】&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#del 删除内存里的变量
192.168.90.64:6379&amp;gt; keys *
1) &quot;y&quot;
2) &quot;tea&quot;
3) &quot;name&quot;
4) &quot;school【斯故】&quot;
5) &quot;x&quot;
6) &quot;classs&quot;
192.168.90.64:6379&amp;gt; del tea y school【斯故】
(integer) 3
192.168.90.64:6379&amp;gt; keys *
1) &quot;name&quot;
2) &quot;x&quot;
3) &quot;classs&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.8 flushdb【福 辣 徐 db】 删除本库的所有的key【kì】&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#flushdb【福 辣 徐 db】  删除当前所在库的所有数据
192.168.90.64:6379&amp;gt; keys *
1) &quot;name&quot;
2) &quot;x&quot;
3) &quot;classs&quot;
192.168.90.64:6379&amp;gt; flushdb【福 辣 徐 db】
OK
192.168.90.64:6379&amp;gt; keys *
(empty list or set)
192.168.90.64:6379&amp;gt; SELECT【涩莱克特】 1
OK
192.168.90.64:6379[1]&amp;gt; keys *
1) &quot;age&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.9 flushall【福 辣 徐 ò】 删除所有库的key【kì】&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379[1]&amp;gt; flushall【福 辣 徐 ò】 #删除内存里的所有内存里所有数据 （慎用）
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、列表类型（list【lì斯特】类型）&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/12-redis%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B/image-20250621155454906.webp&quot; alt=&quot;image-20250621155454906&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;6.1 应用场景&lt;/h3&gt;
&lt;p&gt;Redis【瑞迪斯】 列表类型是一种简单的数据结构，可用来实现队列、栈和日志记录等功能。其应用场景广泛，以下是一些常见的场景：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;消息队列&lt;/strong&gt;：适合实现生产者 - 消费者模式。生产者使用LPUSH【L 普斯】 命令将消息从列表左端插入，消费者使用BRPOP或RPOP【R 扑】命令从右端取出消息处理。如在微服务架构里，一个服务可将任务作为消息放入列表，另一个服务作为消费者取出任务执行。还能用于任务队列，像电商网站中，用户下单后将订单处理任务放入列表，后台工作进程取出任务进行库存更新、订单确认等操作，避免用户等待，提升体验。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;排行榜&lt;/strong&gt;：可用于时间序列排行榜，如在游戏里将玩家得分和时间戳作为元素放入列表，对列表排序可得不同时间段的玩家排行榜。也能实现动态排行榜，在直播平台中，观众送礼物增加主播人气值，人气值变化实时反映在排行榜上，通过快速插入新元素和删除旧元素实现榜单实时更新。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;历史记录存储&lt;/strong&gt;：可存储用户操作历史，如文档编辑系统中，用LPUSH【L 普斯】 命令将用户每次编辑操作记录插入列表，用LRANGE【L 轮局】 命令获取一定范围的历史记录，方便用户查看历史版本或撤销操作。还能用于系统日志记录，Web应用中，将用户登录日志、请求日志等存储在列表，便于进行日志查询和分析，故障排查时可快速获取相关日志信息。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;栈和队列数据结构的实现&lt;/strong&gt;：可作为栈使用，用LPUSH【L 普斯】 命令将元素插入列表头部，用LPOP【L 扑】 命令从头部弹出元素，实现后进先出的栈结构，用于一些算法实现。也能当作队列，用LPUSH【L 普斯】 命令将元素插入头部，用RPOP【R 扑】 命令从尾部弹出元素，实现先进先出的队列结构，如任务调度系统中，将任务按提交顺序放入队列，工作进程依次取出执行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;社交平台相关场景&lt;/strong&gt;：如微信朋友圈点赞，按点赞顺序显示点赞好友信息，取消点赞时移除对应好友信息；Twitter、微博等社交平台中，个人用户的关注列表按关注顺序展示，粉丝列表将最近关注的粉丝列在前面。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;待办事项与购物车&lt;/strong&gt;：可以作为待办事项列表使用，用户添加待办事项时用LPUSH【L 普斯】 或RPUSH【R 普斯】插入列表，完成事项后用LPOP【L 扑】 或RPOP【R 扑】 移除。购物车也可使用列表实现，商品添加到购物车时插入列表，结算或移除商品时从列表移除 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;秒杀抢购&lt;/strong&gt;：将商品ID作为key【kì】，商品数目作为value【挖柳】 存储在列表中，在秒杀场景中使用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实时在线用户管理&lt;/strong&gt;：可用于存储实时在线用户的列表，实现实时更新和查询在线用户信息。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;日志记录&lt;/strong&gt;：在Web应用中，将用户请求的URL和请求时间push到列表，并设置列表长度为一定值，查看日志时通过lrange【L 轮局】 命令获取之前请求过的URL和请求时间。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;6.2 向列表左边增加元素&lt;/h3&gt;
&lt;h4&gt;&lt;code&gt;lpush【L 普斯】&lt;/code&gt;向列表左边增加元素&lt;/h4&gt;
&lt;p&gt;LPUSH【L 普斯】 命令用来向列表左边增加元素，返回值表示增加元素后列表的长度
&lt;code&gt;lpush【L 普斯】&lt;/code&gt;是“left push”的缩写，用于将一个或多个值插入到列表的头部（左侧）
命令格式为&lt;code&gt;LPUSH key value1 value2...&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 创建变量
192.168.90.64:6379&amp;gt; lpush【L 普斯】  letter A B C 
(integer) 3

# 查看类型
192.168.90.64:6379&amp;gt; type【泰 普】 letter  
list【lì斯特】


# 头部追加元素
192.168.90.64:6379&amp;gt; lpush【L 普斯】 letter d e
(integer) 5
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;&lt;code&gt;lrange【L 轮局】&lt;/code&gt;取出列表所有元素&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;lrange【L 轮局】&lt;/code&gt;用于获取列表指定范围内的元素。它能按索引范围提取列表中的部分或全部元素。
命令格式为&lt;code&gt;LRANGE key 开始 结束&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 起始下标为0，结束下标为-1
192.168.90.64:6379&amp;gt; lrange【L 轮局】 letter 0 -1
1) &quot;e&quot;
2) &quot;d&quot;
3) &quot;C&quot;
4) &quot;B&quot;
5) &quot;A&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;&lt;code&gt;llen【L 轮】&lt;/code&gt;统计元素个数&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;llen【L 轮】&lt;/code&gt;是用于获取列表长度的命令。它返回存储在指定键的列表中的元素数量。
格式：有一个名为&lt;code&gt;my_list&lt;/code&gt;的列表，执行&lt;code&gt;LLEN my_list&lt;/code&gt;命令，就能知道&lt;code&gt;my_list&lt;/code&gt;中有多少个元素。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; llen【L 轮】 letter
(integer) 5
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.3 lindex索引元素&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;lindex【L 因戴克斯】&lt;/code&gt;命令用于获取列表中指定索引位置的元素。
通过下标输出单个元素 第1个元素下标用0表示 第2个元素下标用1表示&lt;/p&gt;
&lt;p&gt;最后一个元素下标用-1表示&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; lindex【L 因戴克斯】 letter 0
&quot;e&quot;
192.168.90.64:6379&amp;gt; lindex【L 因戴克斯】 letter 2
&quot;C&quot;

# 最后1个
192.168.90.64:6379&amp;gt; lindex【L 因戴克斯】 letter -1 
&quot;A&quot;

# 倒数第2个
192.168.90.64:6379&amp;gt; lindex【L 因戴克斯】 letter -2 
&quot;B&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.4 lset【L 赛特】修改元素&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;lset【L 赛特】&lt;/code&gt;用于设置列表中指定索引位置的元素值。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 修改前查看
192.168.90.64:6379&amp;gt; lrange【L 轮局】 letter 0 -1  
1) &quot;e&quot;
2) &quot;d&quot;
3) &quot;C&quot;
4) &quot;B&quot;
5) &quot;A&quot;

# 修改第1元素
192.168.90.64:6379&amp;gt; lset letter 0 E  
OK

# 修改最后1个元素
192.168.90.64:6379&amp;gt; lset letter -1 a 
OK

# 修改后查看
192.168.90.64:6379&amp;gt; lrange【L 轮局】 letter 0 -1 
1) &quot;E&quot;
2) &quot;d&quot;
3) &quot;C&quot;
4) &quot;B&quot;
5) &quot;a&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.5 弹出元素（删除元素）&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;lpop【L 扑】&lt;/code&gt;是“left pop”的缩写，用于从列表的头部（左侧）移除并返回一个元素。
&lt;code&gt;rpop【R 扑】&lt;/code&gt;即“right pop”的缩写，用于从列表的尾部（右侧）移除并返回一个元素。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; lrange【L 轮局】 letter 0 -1  #修改前查看
1) &quot;E&quot;
2) &quot;d&quot;
3) &quot;C&quot;
4) &quot;B&quot;
5) &quot;a&quot;
192.168.90.64:6379&amp;gt; lpop【L 扑】 letter  #弹出头部元素
&quot;E&quot;
192.168.90.64:6379&amp;gt; rpop【R 扑】 letter  #弹出尾部元素
&quot;a&quot;
192.168.90.64:6379&amp;gt; lrange【L 轮局】 letter 0 -1  #修改后查看
1) &quot;d&quot;
2) &quot;C&quot;
3) &quot;B&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.6 尾部追加元素&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;rpush&lt;/code&gt;是“right push”的缩写，用于将一个或多个值插入到列表的尾部（右侧） 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; rpush【R 普斯】 letter e f #尾部追加元素
(integer) 5
192.168.90.64:6379&amp;gt; lrange【L 轮局】 letter 0 -1 #追加后查看
1) &quot;d&quot;
2) &quot;C&quot;
3) &quot;B&quot;
4) &quot;e&quot;
5) &quot;f&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.7 插入元素&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;linsert【L 因涩特】&lt;/code&gt;用于在列表指定元素的前或后插入新元素。
&lt;code&gt;before【B fò】&lt;/code&gt;表示在……之前。
&lt;code&gt;after【啊夫特】&lt;/code&gt; 常用于表达在……之后。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; lrange【L 轮局】 letter 0 -1 #插入前查看
1) &quot;d&quot;
2) &quot;C&quot;
3) &quot;B&quot;
4) &quot;e&quot;
5) &quot;f&quot;
192.168.90.64:6379&amp;gt; 
192.168.90.64:6379&amp;gt; linsert【L 因涩特】 letter before【B fò】 C C2   #值C前插入C2
(integer) 6
192.168.90.64:6379&amp;gt; lrange【L 轮局】 letter 0 -1  #插入后查看
1) &quot;d&quot;
2) &quot;C2&quot;
3) &quot;C&quot;
4) &quot;B&quot;
5) &quot;e&quot;
6) &quot;f&quot;
192.168.90.64:6379&amp;gt;
192.168.90.64:6379&amp;gt; linsert【L 因涩特】 letter after【啊夫特】 C C3  #值C后插入C3
(integer) 7
192.168.90.64:6379&amp;gt; lrange【L 轮局】 letter 0 -1 #插入后查看
1) &quot;d&quot;
2) &quot;C2&quot;
3) &quot;C&quot;
4) &quot;C3&quot;
5) &quot;B&quot;
6) &quot;e&quot;
7) &quot;f&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;七、散列类型（hash【哈希】类型）&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/12-redis%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B/image-20250621155520850.webp&quot; alt=&quot;image-20250621155520850&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;7.1 应用场景&lt;/h3&gt;
&lt;p&gt;Redis【瑞迪斯】 散列类型是字符串字段和字符串值之间的映射，类似 Python 字典或 Java 的 HashMap，适合存储对象，且可像数据库更新记录一样只修改特定字段。其具体应用场景如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;用户信息存储&lt;/strong&gt;：每个用户对应一个 Hash【哈希】，以用户 ID 为键名，使用字段表示用户的属性，如姓名、年龄、生日等，而字段值则存储属性值。相比用普通的 key【kì】/value【挖柳】 结构存储，避免了序列化/反序列化的开销，且在修改其中一项信息时，无需把整个对象取回，也无需引入复杂的并发保护机制。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;商品属性存储&lt;/strong&gt;：可用于存储商品的多维度属性，如价格、库存、描述等。通过散列类型，能方便地对商品的各个属性进行单独的查询、修改和更新操作，提高数据处理的效率和灵活性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配置管理&lt;/strong&gt;：适用于动态更新配置字段的场景，无需反序列化整个对象。系统的配置信息可存储在散列中，当配置发生变化时，只需更新相应的字段即可，保证系统的配置信息能实时生效，且操作简单高效。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;购物车&lt;/strong&gt;：以用户 ID 为 key【kì】，商品 ID 为 field，商品数量为 value【挖柳】。用户向购物车中添加商品时，可通过操作散列类型来记录商品信息和数量；修改商品数量或删除商品时，也能方便地对散列中的对应字段进行更新或删除操作。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文章内容存储&lt;/strong&gt;：对于文章的各种属性，如标题、作者、发布时间、内容摘要等，可以使用散列类型进行存储，以文章 ID 作为键名，各个属性作为字段和字段值，便于对文章信息进行管理和查询。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;7.2 存储数据和获取数据&lt;/h3&gt;
&lt;p&gt;赋值与取值
&lt;code&gt;hset【h 赛特】&lt;/code&gt;用于在哈希表（hash）中设置一个字段（field）的值。
&lt;code&gt;hmset【hm 赛特】&lt;/code&gt;用于同时设置哈希表中的多个字段值。
&lt;code&gt;hget【h 脚(白话)特】&lt;/code&gt;用于从哈希表中获取指定字段的值。
&lt;code&gt;hmget【hm 脚(白话)特】&lt;/code&gt;用于从哈希表中获取一个或多个指定字段的值。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; hset【h 赛特】 user1 name bob  #创建变量
(integer) 1
192.168.90.64:6379&amp;gt; type【泰 普】 user1 #查看类型
hash
192.168.90.64:6379&amp;gt;
192.168.90.64:6379&amp;gt; hset【h 赛特】 user1 gender man #赋新值
(integer) 1
192.168.90.64:6379&amp;gt; hget【h 脚(白话)特】 user1 name  #查看name列的值
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;设置多个字段&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; hmset【hm 赛特】 user1 email bob@qcjy.cn phone 13412345678
OK
192.168.90.64:6379&amp;gt; hmget【hm 脚(白话)特】 user1 email phone
1) &quot;bob@qcjy.cn&quot;
2) &quot;13412345678&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;获取所有列名及对应的值
&lt;code&gt;hgetall【h 脚(白话)特 ò】&lt;/code&gt;用于获取哈希表中所有的字段和值。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; hgetall【h 脚(白话)特 ò】 user1
1) &quot;name&quot;
2) &quot;bob&quot;
3) &quot;gender&quot;
4) &quot;male&quot;
5) &quot;email&quot;
6) &quot;bob@qcjy.cn&quot;
7) &quot;phone&quot;
8) &quot;13412345678&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.3 其他操作&lt;/h3&gt;
&lt;h4&gt;hdel删除列&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;hdel【h 戴尔】&lt;/code&gt;用于删除哈希表中的一个或多个字段。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; hdel【h 戴尔】 user1 age
(integer) 1
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;只获取列名&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;hkeys【h kì s】&lt;/code&gt;用于获取哈希表中的所有字段名。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; hkeys【h kì s】 user1
1) &quot;name&quot;
2) &quot;gender&quot;
3) &quot;email&quot;
4) &quot;phone&quot;
5) &quot;address&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;只获取值&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;hvals【h 瓦尔兹】&lt;/code&gt;命令用于获取哈希表中所有字段的值。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; hvals【h 瓦尔兹】 user1
1) &quot;bob&quot;
2) &quot;male&quot;
3) &quot;bob@qcjy.cn&quot;
4) &quot;13412345678&quot;
5) &quot;beijing&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;获得列数量&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;hlen【h 轮】&lt;/code&gt;用于获取哈希表中字段的数量。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; hlen【h 轮】 user1
(integer) 5
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;八、集合类型&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/12-redis%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B/image-20250621155548936.webp&quot; alt=&quot;image-20250621155548936&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;8.1 应用场景&lt;/h3&gt;
&lt;p&gt;Redis【瑞迪斯】 集合类型是一种不允许重复元素的非线性结构，可用于存储和管理元素集合，其应用场景广泛，以下是一些常见的场景：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;用户管理&lt;/strong&gt;：在社交网络中可存储用户特征和记录，轻松检索用户 ID、用户名等信息；也能用于会员管理，保护和检索会员记录。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;网站流量监控&lt;/strong&gt;：将客户端 IP 等唯一标识添加到 Redis【瑞迪斯】 集合中，可有效跟踪网站流量，检测重复访客或恶意行为。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;奖励管理&lt;/strong&gt;：可以跟踪和管理奖励，方便对奖励信息进行添加、查询等操作。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;排行榜&lt;/strong&gt;：在搜索引擎、电影、游戏等场景中，可维护实时热门排行榜榜单。如在游戏里，可存储玩家得分或排名信息，通过集合操作实现排行榜的更新和查询。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;标签系统&lt;/strong&gt;：可用于存储每篇文章或商品的标签，方便根据标签进行分类和搜索。例如新闻网站可以为每篇新闻文章添加标签，用户可以根据标签快速找到感兴趣的文章。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;社交应用&lt;/strong&gt;：可存储用户的好友列表，通过求交集来找出共同的好友，实现共同兴趣的推荐；还能存储关注者信息，进行关注和取消关注的操作。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;唯一性检查&lt;/strong&gt;：集合中的元素具有唯一性，可用于检查元素是否已存在。如在注册系统中，检查用户名是否已被使用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;抽奖活动&lt;/strong&gt;：将参与抽奖的用户 ID 存储在集合中，通过随机获取集合中的元素来实现抽奖功能，保证每个用户只有一次中奖机会。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;点赞和共同关注&lt;/strong&gt;：存储点赞用户的 ID 集合，判断某个用户是否点赞；也可通过集合操作找出多个用户的共同关注对象。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;8.2 无序集合&lt;/h3&gt;
&lt;p&gt;无序集合中的每个元素都是不同的，且没有顺序&lt;/p&gt;
&lt;h4&gt;8.2.1 创建/追加/删除/查看&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;sadd&lt;/code&gt;用于向集合（set）中添加一个或多个成员。集合是一个无序且唯一的字符串集合。命令格式为SADD key member1 member2... 。
例如，执行SADD myset &quot;apple&quot; &quot;banana&quot;，就会将 “apple” 和 “banana” 添加到名为myset的集合中。当需要维护一个唯一值的集合，比如用户标签集合，使用sadd添加标签，可保证标签的唯一性。
&lt;code&gt;srem【s 轮姆】&lt;/code&gt;命令用于移除集合中的一个或多个成员。集合是无序且元素唯一的结构。比如有集合&lt;code&gt;my_set&lt;/code&gt;，执行命令&lt;code&gt;SREM【s 轮姆】 my_set value1 value2&lt;/code&gt;，就会从&lt;code&gt;my_set&lt;/code&gt;集合中移除&lt;code&gt;value1&lt;/code&gt;和&lt;code&gt;value2&lt;/code&gt;。这在管理集合数据，像用户兴趣标签集合，需要删除某些用户不再感兴趣的标签时非常有用。
&lt;code&gt;smembers【s 门伯兹】&lt;/code&gt;用于获取集合中的所有成员。命令格式为&lt;code&gt;SMEMBERS key&lt;/code&gt;。例如，执行&lt;code&gt;SMEMBERS myset&lt;/code&gt;，会返回名为&lt;code&gt;myset&lt;/code&gt;集合中的所有元素。当你需要查看集合内的所有数据，比如查看用户拥有的所有标签时，&lt;code&gt;smembers&lt;/code&gt;就十分有用。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; sadd mylike film muisc game  #创建
(integer) 3
192.168.90.64:6379&amp;gt; type【泰 普】 mylike  #查看数据类型
set
192.168.90.64:6379&amp;gt; sadd mylike sleep game it  #追加，自动删除重复的值
(integer) 2
192.168.90.64:6379&amp;gt; srem【s 轮姆】 mylike sleep game #删除成员
(integer) 2
192.168.90.64:6379&amp;gt; smembers【s 门伯兹】 mylike #查看成员
1) &quot;film&quot;
2) &quot;it&quot;
3) &quot;muisc&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.2.2 判断元素是否在集合中&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;sismember【sis 门伯】&lt;/code&gt;是一个用于判断指定成员是否存在于集合中的命令 。其命令格式为&lt;code&gt;SISMEMBER key member&lt;/code&gt;。假设你有一个名为&lt;code&gt;fruits&lt;/code&gt;的集合，执行&lt;code&gt;SISMEMBER fruits &quot;banana&quot;&lt;/code&gt;，若&lt;code&gt;banana&lt;/code&gt;存在于&lt;code&gt;fruits&lt;/code&gt;集合，该命令返回1；若不存在，则返回0 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; sismember【sis 门伯】 mylike game  #输出0表示不存在
(integer) 0
192.168.90.64:6379&amp;gt; sismember【sis 门伯】 mylike music #输出1表示存在
(integer) 1
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.2.2.1输出成员个数&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;scard【s 卡德】&lt;/code&gt;用于获取集合中成员的数量。命令格式为&lt;code&gt;SCARD key&lt;/code&gt;。例如，对于名为&lt;code&gt;my_set&lt;/code&gt;的集合，执行&lt;code&gt;SCARD my_set&lt;/code&gt;，就会返回该集合包含的元素个数。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; scard【s 卡德】 mylike
(integer) 3
192.168.90.64:6379&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.2.3 集合运算&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; smembers mylike
1) &quot;film&quot;
2) &quot;it&quot;
3) &quot;muisc&quot;
192.168.90.64:6379&amp;gt; sadd helike film music game  sleep
(integer) 4
192.168.90.64:6379&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;合集 sunion【s U凝】&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;sunion【s U凝】&lt;/code&gt;用于返回一个集合的并集，即多个集合中所有不同的元素组成的集合。命令格式为&lt;code&gt;SUNION key1 key2...&lt;/code&gt;。例如，有集合&lt;code&gt;set1&lt;/code&gt;包含元素&lt;code&gt;a&lt;/code&gt;、&lt;code&gt;b&lt;/code&gt;，集合&lt;code&gt;set2&lt;/code&gt;包含元素&lt;code&gt;b&lt;/code&gt;、&lt;code&gt;c&lt;/code&gt;，执行&lt;code&gt;SUNION set1 set2&lt;/code&gt;会返回包含&lt;code&gt;a&lt;/code&gt;、&lt;code&gt;b&lt;/code&gt;、&lt;code&gt;c&lt;/code&gt;的集合。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#合集 重复的只显示一次
192.168.90.64:6379&amp;gt; sunion【s U凝】 mylike helike
1) &quot;game&quot;
2) &quot;it&quot;
3) &quot;muisc&quot;
4) &quot;film&quot;
5) &quot;sleep&quot;
6) &quot;music&quot;
192.168.90.64:6379&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;交集sinter【s 因特尔】&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;sinter【s 因特尔】&lt;/code&gt;用于返回多个集合的交集，即所有给定集合中都存在的元素组成的集合。命令格式为&lt;code&gt;SINTER key1 key2...&lt;/code&gt; 。例如，集合&lt;code&gt;set1&lt;/code&gt;包含&lt;code&gt;a&lt;/code&gt;、&lt;code&gt;b&lt;/code&gt;、&lt;code&gt;c&lt;/code&gt;，集合&lt;code&gt;set2&lt;/code&gt;包含&lt;code&gt;b&lt;/code&gt;、&lt;code&gt;c&lt;/code&gt;、&lt;code&gt;d&lt;/code&gt;，执行&lt;code&gt;SINTER set1 set2&lt;/code&gt;，返回的集合将包含&lt;code&gt;b&lt;/code&gt;、&lt;code&gt;c&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#交集
192.168.90.64:6379&amp;gt; sinter【s 因特尔】 mylike helike
1) &quot;film&quot;
192.168.90.64:6379&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;差集sdiff【s 迪夫】&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;sdiff【s 迪夫】&lt;/code&gt;用于返回给定集合之间的差集。命令格式为&lt;code&gt;SDIFF key1 key2...&lt;/code&gt; 。以两个集合为例，&lt;code&gt;sdiff&lt;/code&gt;会返回在&lt;code&gt;key1&lt;/code&gt;集合中，但不在&lt;code&gt;key2&lt;/code&gt;及后续集合中的所有元素。比如集合&lt;code&gt;set1&lt;/code&gt;包含&lt;code&gt;a&lt;/code&gt;、&lt;code&gt;b&lt;/code&gt;、&lt;code&gt;c&lt;/code&gt;，集合&lt;code&gt;set2&lt;/code&gt;包含&lt;code&gt;b&lt;/code&gt;、&lt;code&gt;c&lt;/code&gt;，执行&lt;code&gt;SDIFF set1 set2&lt;/code&gt;，返回的集合将只包含&lt;code&gt;a&lt;/code&gt; 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#差集: 用第1列的变量和第2列的变量比
192.168.90.64:6379&amp;gt; sdiff【s 迪夫】 mylike helike
1) &quot;it&quot;
2) &quot;muisc&quot;
192.168.90.64:6379&amp;gt; sdiff【s 迪夫】 helike mylike
1) &quot;game&quot;
2) &quot;sleep&quot;
3) &quot;music&quot;
192.168.90.64:6379&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.2.4 随机获得集合中的元素&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;srandmember【s 轮 门伯】&lt;/code&gt;用于从集合中随机返回一个或多个成员。命令格式为&lt;code&gt;SRANDMEMBER key [count]&lt;/code&gt;。若不指定&lt;code&gt;count&lt;/code&gt;，则随机返回一个成员；若指定&lt;code&gt;count&lt;/code&gt;，且为正数，会返回指定数量不重复的成员（若集合元素不足，返回实际数量）；若&lt;code&gt;count&lt;/code&gt;为负数，会返回指定数量可能重复的成员。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 在集合helike中随机取出两个不同元素。
192.168.90.64:6379&amp;gt; srandmember【s 轮 门伯】 helike 2
1) &quot;sleep&quot;
2) &quot;music&quot;
192.168.90.64:6379&amp;gt; srandmember【s 轮 门伯】 helike 2
1) &quot;game&quot;
2) &quot;music&quot;
192.168.90.64:6379&amp;gt; 
# 在集合helike中随机取出两个有可能相同元素。
192.168.90.64:6379&amp;gt; srandmember【s 轮 门伯】 helike -2
1) &quot;film&quot;
2) &quot;music&quot;
192.168.90.64:6379&amp;gt; srandmember【s 轮 门伯】 helike -2
1) &quot;music&quot;
2) &quot;music&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.2.5 集合中随机弹出一个元素&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;spop【s 扑】&lt;/code&gt;用于从集合中随机移除并返回一个成员。命令格式为&lt;code&gt;SPOP key&lt;/code&gt;。例如，对于名为&lt;code&gt;my_set&lt;/code&gt;的集合，执行&lt;code&gt;SPOP my_set&lt;/code&gt;，会从&lt;code&gt;my_set&lt;/code&gt;集合里随机挑选一个元素并删除它，同时返回该元素。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; spop【s 扑】 helike #第1次弹出
&quot;music&quot;
192.168.90.64:6379&amp;gt; spop【s 扑】 helike #第2次弹出
&quot;game&quot;
192.168.90.64:6379&amp;gt; smembers【s 门伯兹】 helike #查看
1) &quot;film&quot;
2) &quot;sleep&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;8.3 有序集合&lt;/h3&gt;
&lt;h4&gt;8.3.1 zadd命令的返回值是新加入到集合中的元素个数&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;zadd&lt;/code&gt;用于向有序集合（Sorted Set）中添加一个或多个成员，同时为每个成员关联一个分数（score），有序集合会根据分数对成员进行排序。命令格式为&lt;code&gt;ZADD key score1 member1 [score2 member2 ...]&lt;/code&gt; 。例如，执行&lt;code&gt;ZADD myzset 10 &quot;apple&quot; 20 &quot;banana&quot;&lt;/code&gt;，就会将“apple”和“banana”添加到名为&lt;code&gt;myzset&lt;/code&gt;的有序集合中，“apple”的分数是10，“banana”的分数是20 。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;zcard&lt;/code&gt;用于获取有序集合中的成员数量。命令格式为&lt;code&gt;ZCARD key&lt;/code&gt;。例如，对于名为&lt;code&gt;myzset&lt;/code&gt;的有序集合，执行&lt;code&gt;ZCARD myzset&lt;/code&gt;，会返回&lt;code&gt;myzset&lt;/code&gt;集合中的元素个数。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;zrange&lt;/code&gt;用于返回有序集合中指定区间内的成员。有序集合成员按分数值递增（从小到大）顺序排列。命令格式为&lt;code&gt;ZRANGE key start stop [WITHSCORES]&lt;/code&gt;。&lt;code&gt;start&lt;/code&gt;和&lt;code&gt;stop&lt;/code&gt;是元素的索引值，索引从0开始，负数表示从集合尾部开始计数， -1 代表最后一个元素。例如，执行&lt;code&gt;ZRANGE myzset 0 2 WITHSCORES&lt;/code&gt;，会返回名为&lt;code&gt;myzset&lt;/code&gt;的有序集合中索引0到2的成员及其分数
&lt;code&gt;withscores&lt;/code&gt;是一个可选参数。当使用它时，命令在返回有序集合成员的同时，还会返回每个成员对应的分数。例如&lt;code&gt;ZRANGE myzset 0 -1 WITHSCORES&lt;/code&gt;，会返回&lt;code&gt;myzset&lt;/code&gt;有序集合中所有成员及其对应的分数。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; zadd scores 88 tom 90 jerry 75 bob 92 alice  #创建变量
(integer) 4
192.168.90.64:6379&amp;gt; type【泰 普】 scores #查看类型
zset
192.168.90.64:6379&amp;gt; zcard【z 卡德】 scores #统计成员个数
(integer) 4
192.168.90.64:6379&amp;gt; zrange【z 轮局】 scores 0 -1  #输出成员名称
1) &quot;bob&quot;
2) &quot;tom&quot;
3) &quot;jerry&quot;
4) &quot;alice&quot;
192.168.90.64:6379&amp;gt; zrange【z 轮局】 scores 0 -1 withscores【维s 科s】  #输出成员名称及对应的值
1) &quot;bob&quot;
2) &quot;75&quot;
3) &quot;tom&quot;
4) &quot;88&quot;
5) &quot;jerry&quot;
6) &quot;90&quot;
7) &quot;alice&quot;
8) &quot;92&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.3.2 获得某个成员的值&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; zscore【z s科】 scores tom
&quot;88&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.3.3  获得指定分数范围的元素&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;zrangebyscore&lt;/code&gt;用于返回有序集合中指定分数区间内的成员。命令格式为&lt;code&gt;ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]&lt;/code&gt; 。&lt;code&gt;min&lt;/code&gt;和&lt;code&gt;max&lt;/code&gt;是分数范围，比如执行&lt;code&gt;ZRANGEBYSCORE myzset 80 100 WITHSCORES&lt;/code&gt;，会返回名为&lt;code&gt;myzset&lt;/code&gt;的有序集合中分数在80（含）到100（含）之间的成员及其分数。&lt;code&gt;WITHSCORES&lt;/code&gt;可选，用于显示成员对应的分数，&lt;code&gt;LIMIT&lt;/code&gt;用于指定返回结果的偏移量和数量。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; zrangebyscore【z 轮局 拜 s科】 scores 80 90 WITHSCORES【维s 科s】
1) &quot;jerry&quot;
2) &quot;85&quot;
3) &quot;tom&quot;
4) &quot;88&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.3.4 增加某个元素的分数&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;zincrby【z 因kuì儿 拜】&lt;/code&gt;用于为有序集合中的成员增加指定的分数。命令格式为&lt;code&gt;ZINCRBY key increment member&lt;/code&gt; 。例如，执行&lt;code&gt;ZINCRBY myzset 5 &quot;player1&quot;&lt;/code&gt;，会将有序集合&lt;code&gt;myzset&lt;/code&gt;中的成员“player1”的分数增加5 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; zincrby【z 因kuì儿 拜】 scores 3 bob
&quot;78&quot;
192.168.90.64:6379&amp;gt; zscore【z s科】 scores bob
&quot;78&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.3.5 获得指定分数范围内的元素个数&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;zcount【z kàn特】&lt;/code&gt;用于统计有序集合中指定分数区间内成员的数量。命令格式为&lt;code&gt;ZCOUNT key min max&lt;/code&gt;。比如执行&lt;code&gt;ZCOUNT myzset 60 80&lt;/code&gt;，就会返回名为&lt;code&gt;myzset&lt;/code&gt;的有序集合中分数在60（含）到80（含）之间的成员数量。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; zcount【z kàn特】 scores 80 90
(integer) 2
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.3.6 删除元素&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;zrem【z 轮姆】&lt;/code&gt;用于从有序集合中移除一个或多个成员。命令格式为&lt;code&gt;ZREM key member [member ...]&lt;/code&gt; 。例如，执行&lt;code&gt;ZREM myzset &quot;member1&quot; &quot;member2&quot;&lt;/code&gt;，会从名为&lt;code&gt;myzset&lt;/code&gt;的有序集合中移除“member1”和“member2” 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; zrem【z 轮姆】 scores bob
(integer) 1
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.3.7 获得元素的排名&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;zrank【z 软克】&lt;/code&gt;用于获取有序集合中指定成员的排名。排名从0开始，是按分数从小到大排列的索引值。命令格式为&lt;code&gt;ZRANK key member&lt;/code&gt;。例如，对于有序集合&lt;code&gt;myzset&lt;/code&gt;，执行&lt;code&gt;ZRANK myzset &quot;member1&quot;&lt;/code&gt;，会返回“member1”在&lt;code&gt;myzset&lt;/code&gt;集合中的排名。
&lt;code&gt;zrevrank【z 瑞乌 软克】&lt;/code&gt;与&lt;code&gt;zrank【z 软克】&lt;/code&gt;类似，但它是获取有序集合中指定成员按分数从大到小排列的排名。命令格式为&lt;code&gt;ZREVRANK key member&lt;/code&gt;。例如，在名为&lt;code&gt;myzset&lt;/code&gt;的有序集合里执行&lt;code&gt;ZREVRANK myzset &quot;member1&quot;&lt;/code&gt;，会返回“member1”在&lt;code&gt;myzset&lt;/code&gt;集合中按分数降序排列的排名。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; zrank【z 软克】 scores tom   # 获取tom的排名
(integer) 1   # 升序排列，从0开始计数

192.168.90.64:6379&amp;gt; zrevrank【z 瑞乌 软克】 scores alice   # 获取alice的排名
(integer) 0   # 降序排列，从0开始计数
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;九、作业&lt;/h2&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Redis 集合类型中，以下哪个命令用于判断元素是否在集合中？ B
A. sunion
B. sismember
C. sinter
D. sdiff&lt;/li&gt;
&lt;li&gt;若要在 Redis 列表类型中从尾部追加元素，应使用以下哪个命令？C
A. LPUSH
B. RPOP
C. RPUSH
D. LPOP&lt;/li&gt;
&lt;li&gt;Redis 散列类型适合存储以下哪种数据？ C
A. 单一的字符串
B. 有序的元素列表
C. 具有多个属性的对象
D. 不允许重复的无序元素&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2 填空题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Redis 字符串类型中，使用__incr__命令可以让存储的整数值递增。&lt;/li&gt;
&lt;li&gt;在 Redis 列表类型中，用__lpop__命令可以从列表头部弹出元素。&lt;/li&gt;
&lt;li&gt;Redis 集合类型中，用于获取两个集合交集的命令是__sinter__。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3 简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;简述 Redis 散列类型在存储用户信息方面相较于普通 key/value 结构的优势。
答：
相比用普通的 key /value  结构存储， 散列类型存储每个用户对应一个 Hash，以用户 ID 为键名，使用字段表示用户的属性，如姓名、年龄、生日等，而字段值则存储属性值。避免了序列化/反序列化的开销，且在修改其中一项信息时，无需把整个对象取回，也无需引入复杂的并发保护机制。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;请说明 Redis 列表类型可以实现哪些数据结构，以及对应的命令操作。
答：&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;1. 队列：
    127.0.0.1:6379&amp;gt; lpush test3 1 2 3 4    #在列队头部插入元素
    (integer) 7
    127.0.0.1:6379&amp;gt; rpush test3 1 2 3 4    #在列队尾部插入元素
    (integer) 11
    127.0.0.1:6379&amp;gt; lpop test3             #移除并返回队列的第一个元素
    &quot;4&quot;
    127.0.0.1:6379&amp;gt; rpop test3             #移除并返回队列的最后一个元素
    &quot;4&quot;

2. 栈： 

    127.0.0.1:6379&amp;gt; lpush test3 1 2 3 4     #列表左侧（头部） 插入元素
    (integer) 4
    127.0.0.1:6379&amp;gt; lpop test3              #列表左侧（头部） 移除并获取元素
    &quot;4&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;列举 Redis 集合类型的三个常见应用场景。
答：
社交应用
唯一性检查
抽奖活动&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;4 操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;假设你已经连接到 Redis 服务，现在要创建一个散列类型的数据，键名为“product1”，包含字段“name”值为“手机”，“price”值为“3000”，“stock”值为“50”，请写出对应的 Redis 命令。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; hmset product1 name 手机 price 3000 stock 50
OK
127.0.0.1:6379&amp;gt; hmget product1 name price stock
1) &quot;\xe6\x89\x8b\xe6\x9c\xba&quot;
2) &quot;3000&quot;
3) &quot;50&quot;
127.0.0.1:6379&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;有一个 Redis 列表类型的数据“history_list”，请写出命令将元素“操作 1”插入到列表头部，并从列表尾部弹出一个元素。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; lpush history_list A B C
(integer) 3
127.0.0.1:6379&amp;gt; lrange history_list 0 -1 
1) &quot;C&quot;
2) &quot;B&quot;
3) &quot;A&quot;
127.0.0.1:6379&amp;gt; lpush history_list 操作1
(integer) 4
127.0.0.1:6379&amp;gt; lrange history_list 0 -1 
1) &quot;\xe6\x93\x8d\xe4\xbd\x9c1&quot;
2) &quot;C&quot;
3) &quot;B&quot;
4) &quot;A&quot;
127.0.0.1:6379&amp;gt; rpop history_list
&quot;A&quot;
127.0.0.1:6379&amp;gt; lrange history_list 0 -1 
1) &quot;\xe6\x93\x8d\xe4\xbd\x9c1&quot;
2) &quot;C&quot;
3) &quot;B&quot;
127.0.0.1:6379&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;现有两个 Redis 集合“set1”包含元素“a”“b”“c”，“set2”包含元素“b”“c”“d”，请写出命令获取它们的并集、交集和差集。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; sadd set1 a b c
(integer) 3
127.0.0.1:6379&amp;gt; sadd set2 b c d
(integer) 3
127.0.0.1:6379&amp;gt; sunion set1 set2    #并集
1) &quot;b&quot;
2) &quot;a&quot;
3) &quot;d&quot;
4) &quot;c&quot;
127.0.0.1:6379&amp;gt; sinter set1 set2    #交集
1) &quot;b&quot;
2) &quot;c&quot;
127.0.0.1:6379&amp;gt; sdiff set1 set2    #差集
1) &quot;a&quot;
127.0.0.1:6379&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>13：redis集群高可用</title><link>https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/13-redis%E9%9B%86%E7%BE%A4/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/13-redis%E9%9B%86%E7%BE%A4/</guid><description>13：redis集群高可用 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 02:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1&gt;13：redis集群高可用&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/13-redis%E9%9B%86%E7%BE%A4/image-20250623164731874.webp&quot; alt=&quot;image-20250623164731874&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;为确保 Redis 服务的高可用和数据持久化，运维团队开始一系列操作。首先，团队搭建了一主一从的 Redis 结构，将 redis67 配置为主服务器，redis68 作为从服务器，实现数据的实时同步和备份。接着，为进一步提高服务的可靠性，在 redis69 上配置了哨兵服务。在一次突发状况中，主服务器 redis67 出现故障，哨兵服务迅速响应，自动将从服务器 redis68 升级为主服务器，保障业务不受影响。当 redis67 恢复后，又自动成为新主服务器的从服务器，确保整个 Redis 服务的稳定运行。&lt;/p&gt;
&lt;h2&gt;二、为什么学&lt;/h2&gt;
&lt;p&gt;在当今数据量激增的时代，企业对数据存储和访问的效率与稳定性要求极高。从文档可知，Redis 若没有高可用机制，一旦主节点故障，业务会中断，数据也可能丢失。而 Redis 高可用方案，如主从复制、哨兵服务、集群部署等，能保障数据的自动备份与实时同步。像哨兵服务可自动监控节点状态，在主节点故障时快速实现故障转移，将从节点提升为主节点。集群部署则能实现数据的分布式存储，避免单点性能瓶颈，让 Redis 服务在各种复杂环境下稳定运行，确保业务的连续性。&lt;/p&gt;
&lt;h2&gt;三、Redis持久化&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/13-redis%E9%9B%86%E7%BE%A4/image-20250623164803993.webp&quot; alt=&quot;image-20250623164803993&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3.1 使用RDB文件恢复数据&lt;/h3&gt;
&lt;p&gt;创建1台虚拟机&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;redis50&lt;/td&gt;
&lt;td&gt;192.168.90.50&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;配置服务器192.168.90.50&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis50 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis50
[root@redis50 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.50/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis50~]# nmcli connection【肯耐申】 up ens160 

#配置DNS
[root@redis50 ~]# vim /etc/resolv.conf
nameserver 192.168.90.2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤一：设置存盘间隔为120秒且10个key改变数据自动存盘&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;查看 redis服务存储数据到硬盘的存盘频率&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;配置行&lt;/th&gt;
&lt;th&gt;含义&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;save 3600 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;如果 &lt;strong&gt;3600 秒（1 小时）内&lt;/strong&gt;，至少有 &lt;strong&gt;1 个 key 被修改&lt;/strong&gt;，则保存快照。&lt;/td&gt;
&lt;td&gt;最宽松的持久化，防止长时间无备份&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;save 300 100&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;如果 &lt;strong&gt;300 秒（5 分钟）内&lt;/strong&gt;，至少有 &lt;strong&gt;100 个 key 被修改&lt;/strong&gt;，则保存快照。&lt;/td&gt;
&lt;td&gt;中等频率，平衡性能与安全性&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;save 60 10000&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;如果 &lt;strong&gt;60 秒（1 分钟）内&lt;/strong&gt;，至少有 &lt;strong&gt;10,000 个 key 被修改&lt;/strong&gt;，则保存快照。&lt;/td&gt;
&lt;td&gt;高频写入场景下的快速保护&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;[root@redis50 ~]# yum -y install【因-斯多】 redis

#修改之前
[root@redis50 ~]# vim /etc/redis/redis.conf
 383 # save 3600 1
 384 # save 300 100
 385 # save 60 10000
 
#修改之后
[root@redis50 ~]# vim /etc/redis/redis.conf
 383 # save 3600 1
 384 save 120 10
 385 # save 60 10000
 
#启动redis
[root@redis50 ~]# systemctl【西斯屯-ctl】 start【s 达儿】 redis

#目前还没有rdb文件
[root@redis50 ~]# ls /var/lib/redis/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在服务启动后，要在2分钟内存储大于等10个变量&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#存上4个变量
[root@redis50 ~]# redis-cli
127.0.0.1:6379&amp;gt; mset a 1 b 2 c 3 d 4
OK
127.0.0.1:6379&amp;gt; exit

#还没有达到存储的条件，还没有rdb文件
[root@redis50 ~]# ls /var/lib/redis/

#继续存上6个变量
[root@redis50 ~]# redis-cli
127.0.0.1:6379&amp;gt; mset   x 1 y 2  z 3 k 6  i 7  z 9   f 22  zz 99  cc  66
OK
127.0.0.1:6379&amp;gt; exit

#达到条件，数据已经持久化到rdb文件中了
[root@redis50 ~]# ls /var/lib/redis/
dump.rdb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤二：使用RDB文件恢复数据&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#第1步：拷贝 dump.rdb 文件就是对数据的备份
[root@redis50 ~]# cp /var/lib/redis/dump.rdb /opt/
[root@redis50 ~]# ls /opt/
dump.rdb

#第2步：清空数据
[root@redis50 ~]# redis-cli
127.0.0.1:6379&amp;gt; flushall
OK
127.0.0.1:6379&amp;gt; keys *
(empty array)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用备份的dump.rdb文件恢复&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#第1步 停止内存没有数据的redis服务
[root@redis50 ~]# systemctl【西斯屯-ctl】 stop【 s 多】 redis

#第2步 把没有数据的dump.rdb文件删除
[root@redis50 ~]# rm -rf /var/lib/redis/dump.rdb 

#第3步 把备份dump.rdb文件拷贝到数据库目录下
[root@redis50 ~]# cp /opt/dump.rdb /var/lib/redis/

#第4步 启动redis服务 并连接服务查看数据
[root@redis50 ~]# systemctl【西斯屯-ctl】 start【s 达儿】 redis
[root@redis50 ~]# redis-cli
127.0.0.1:6379&amp;gt; keys *
 1) &quot;x&quot;
 2) &quot;a&quot;
 3) &quot;y&quot;
 4) &quot;cc&quot;
 5) &quot;f&quot;
 6) &quot;c&quot;
 7) &quot;zz&quot;
 8) &quot;z&quot;
 9) &quot;d&quot;
10) &quot;i&quot;
11) &quot;k&quot;
12) &quot;b&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 使用AOF文件恢复数据&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;操作步骤
# 1. 在 A 节点（源）安全关闭 Redis（确保 AOF 完整）
redis-cli -h A_host shutdown

# 2. 拷贝 AOF 文件到 B 节点
scp /path/to/appendonly.aof user@B_host:/redis/data/

# 3. 在 B 节点（目标）：
#    - 停止 Redis
#    - 备份/删除原有 AOF 和 RDB
#    - 放入新 AOF 文件
#    - 确保 redis.conf 中 appendonly yes
#    - 启动 Redis

redis-server /etc/redis.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤一：启用AOF&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis50 ~]# redis-cli

#启用aof文件
127.0.0.1:6379&amp;gt; config set appendonly yes  
OK

#查看是否启用
192.168.88.50:6379&amp;gt; config get  appendonly  
1) &quot;appendonly&quot;
2) &quot;yes&quot;

#保存配置
127.0.0.1:6379&amp;gt; config rewrite  
OK
127.0.0.1:6379&amp;gt; exit

#数据库目录多了.aof文件
[root@redis50 ~]# ls /var/lib/redis/
appendonly.aof  dump.rdb

#查看文件行数
[root@redis50 ~]# wc -l /var/lib/redis/appendonly.aof 
2 /var/lib/redis/appendonly.aof

#存放数据
[root@redis50 ~]# redis-cli
127.0.0.1:6379&amp;gt; mset x 1 y 2 z 3
OK
127.0.0.1:6379&amp;gt; keys *
 1) &quot;x&quot;
 2) &quot;a&quot;
 3) &quot;y&quot;
 4) &quot;cc&quot;
 5) &quot;f&quot;
 6) &quot;c&quot;
 7) &quot;zz&quot;
 8) &quot;z&quot;
 9) &quot;d&quot;
10) &quot;i&quot;
11) &quot;k&quot;
12) &quot;b&quot;
127.0.0.1:6379&amp;gt; exit

#查看文件行数
[root@redis50 ~]# wc -l /var/lib/redis/appendonly.aof 
22 /var/lib/redis/appendonly.aof

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤二：使用AOF文件恢复数据&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1）备份aof文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis50 ~]# cp /var/lib/redis/appendonly.aof /opt/
[root@redis50 ~]# ls /opt/
appendonly.aof  dump.rdb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）清空数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis50 ~]# redis-cli
127.0.0.1:6379&amp;gt; flushall
OK
127.0.0.1:6379&amp;gt; exit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3）恢复数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; [root@redis50 ~]# rm -rf  /var/lib/redis/*
 [root@redis70 ~]# cp /opt/appendonly.aof  /var/lib/redis/
 [root@redis70 ~]# chown -R redis:redis /var/lib/redis
 [root@redis50 ~]# systemctl【西斯屯-ctl】 restart redis
 [root@redis50 ~]# redis-cli
 127.0.0.1:6379&amp;gt; keys *
 1) &quot;x&quot;
 2) &quot;a&quot;
 3) &quot;y&quot;
 4) &quot;cc&quot;
 5) &quot;f&quot;
 6) &quot;c&quot;
 7) &quot;zz&quot;
 8) &quot;z&quot;
 9) &quot;d&quot;
10) &quot;i&quot;
11) &quot;k&quot;
12) &quot;b&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、redis高可用集群&lt;/h2&gt;
&lt;p&gt;&amp;lt;img src=&quot;/images/数据库/13-redis集群/redis高可用集群.webp&quot; alt=&quot;Redis高可用集群&quot; width=&quot;90%&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/13-redis%E9%9B%86%E7%BE%A4/image-20250623164832292.webp&quot; alt=&quot;image-20250623164832292&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;4.1 准备环境&lt;/h3&gt;
&lt;p&gt;创建6台新虚拟机&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;redis51&lt;/td&gt;
&lt;td&gt;192.168.90.51&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redis52&lt;/td&gt;
&lt;td&gt;192.168.90.52&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redis53&lt;/td&gt;
&lt;td&gt;192.168.90.53&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redis54&lt;/td&gt;
&lt;td&gt;192.168.90.54&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redis55&lt;/td&gt;
&lt;td&gt;192.168.90.55&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redis56&lt;/td&gt;
&lt;td&gt;192.168.90.56&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;4.1.1 配置redis51&lt;/h4&gt;
&lt;p&gt;配置服务器192.168.90.51&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis51 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis51
[root@redis51 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.51/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis51~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装redis和配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis51 ~]# yum -y install【因-斯多】 redis
#修改4行配置
[root@redis51 ~]# vim /etc/redis/redis.conf
75 bind 0.0.0.0
1387 cluster-enabled yes   #启用集群功能  
1395 cluster-config-file nodes-6379.conf  #存储集群信息文件
1401 cluster-node-timeout 5000  #集群中主机通信超时时间

[root@redis51 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis51 ~]# netstat -utnlp  | grep redis-serve
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      1793/redis-server 0 
tcp        0      0 0.0.0.0:16379           0.0.0.0:*               LISTEN      1793/redis-server 0  
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4.1.1 配置redis52&lt;/h4&gt;
&lt;p&gt;配置服务器192.168.90.52&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis52 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis52
[root@redis52 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.52/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis52~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装redis和配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis52 ~]# yum -y install【因-斯多】 redis
#修改4行配置
[root@redis52 ~]# vim /etc/redis/redis.conf
75 bind 0.0.0.0
1387 cluster-enabled yes   #启用集群功能  
1395 cluster-config-file nodes-6379.conf  #存储集群信息文件
1401 cluster-node-timeout 5000  #集群中主机通信超时时间

[root@redis52 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis52 ~]# netstat -utnlp  | grep redis-serve
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      1758/redis-server 0 
tcp        0      0 0.0.0.0:16379           0.0.0.0:*               LISTEN      1758/redis-server 0   
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4.1.1 配置redis53&lt;/h4&gt;
&lt;p&gt;配置服务器192.168.90.53&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis53 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis53
[root@redis53 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.53/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis53~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装redis和配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis53 ~]# yum -y install【因-斯多】 redis
#修改4行配置
[root@redis53 ~]# vim /etc/redis/redis.conf
75 bind 0.0.0.0
1387 cluster-enabled yes   #启用集群功能  
1395 cluster-config-file nodes-6379.conf  #存储集群信息文件
1401 cluster-node-timeout 5000  #集群中主机通信超时时间

[root@redis53 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis53 ~]# netstat -utnlp  | grep redis-serve
tcp        0      0 0.0.0.0:16379           0.0.0.0:*               LISTEN      1785/redis-server 0 
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      1785/redis-server 0  
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4.1.1 配置redis54&lt;/h4&gt;
&lt;p&gt;配置服务器192.168.90.54&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis54 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis54
[root@redis54 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.54/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis54~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装redis和配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis54 ~]# yum -y install【因-斯多】 redis
#修改4行配置
[root@redis54 ~]# vim /etc/redis/redis.conf
75 bind 0.0.0.0
1387 cluster-enabled yes   #启用集群功能  
1395 cluster-config-file nodes-6379.conf  #存储集群信息文件
1401 cluster-node-timeout 5000  #集群中主机通信超时时间

[root@redis54 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis54 ~]# netstat -utnlp  | grep redis-serve
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      1745/redis-server 0 
tcp        0      0 0.0.0.0:16379           0.0.0.0:*               LISTEN      1745/redis-server 0  
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4.1.1 配置redis55&lt;/h4&gt;
&lt;p&gt;配置服务器192.168.90.55&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis55 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis55
[root@redis55 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.55/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis55~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装redis和配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis55 ~]# yum -y install【因-斯多】 redis
#修改4行配置
[root@redis55 ~]# vim /etc/redis/redis.conf
75 bind 0.0.0.0
1387 cluster-enabled yes   #启用集群功能  
1395 cluster-config-file nodes-6379.conf  #存储集群信息文件
1401 cluster-node-timeout 5000  #集群中主机通信超时时间

[root@redis55 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis55 ~]# netstat -utnlp  | grep redis-serve
tcp        0      0 0.0.0.0:16379           0.0.0.0:*               LISTEN      1778/redis-server 0 
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      1778/redis-server 0  
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4.1.1 配置redis56&lt;/h4&gt;
&lt;p&gt;配置服务器192.168.90.56&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis56 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis56
[root@redis56 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.56/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis56~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装redis和配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis56 ~]# yum -y install【因-斯多】 redis
#修改4行配置
[root@redis56 ~]# vim /etc/redis/redis.conf
75 bind 0.0.0.0
1387 cluster-enabled yes   #启用集群功能  
1395 cluster-config-file nodes-6379.conf  #存储集群信息文件
1401 cluster-node-timeout 5000  #集群中主机通信超时时间

[root@redis56 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis56 ~]# netstat -utnlp  | grep redis-serve
tcp        0      0 0.0.0.0:16379           0.0.0.0:*               LISTEN      1793/redis-server 0 
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      1793/redis-server 0
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 高可用集群原理&lt;/h3&gt;
&lt;h4&gt;4.2.1 架构与节点连接&lt;/h4&gt;
&lt;p&gt;Redis Cluster 采用无中心结构，每个节点保存数据和整个集群状态，且每个节点都和其他所有节点连接。一组三主三从集群由 6 个 Redis 实例组成，其中 3 个为主节点，3 个为从节点，每个主节点至少对应一个从节点 。&lt;/p&gt;
&lt;h4&gt;4.2.2 分布式数据分片&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;哈希槽机制&lt;/strong&gt;：Redis Cluster 将数据划分为 16384 个槽位，每个主节点负责部分槽位。例如，主节点 1 管理槽 0 - 5460，主节点 2 管理 5461 - 10922，主节点 3 管理 10923 - 16383 。当存储一个 key 时，会使用 CRC16 算法计算该 key 的哈希值，然后对 16384 取模，得到所属的槽位，进而将这个 key 分到对应槽位区间的节点上 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自动负载均衡&lt;/strong&gt;：数据按哈希值分配到不同节点，避免单点性能瓶颈。当新增节点时，还可以进行动态地、无中断地数据重新分片 。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;分布式数据分片核心好处&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;水平扩展（Scalability）&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;突破单机性能瓶颈&lt;/strong&gt;：数据和请求负载分散到多个节点，可线性提升吞吐量（QPS）和存储容量。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;动态扩容/缩容&lt;/strong&gt;：通过迁移槽位（如 &lt;code&gt;redis-cli --cluster reshard&lt;/code&gt;），可在不停服的情况下增减节点。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;高可用性（High Availability）&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;自动故障转移&lt;/strong&gt;：每个主节点可配置从节点（replica），主节点宕机时，从节点自动升主（由集群内部 Gossip 协议协调）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;无单点故障&lt;/strong&gt;：即使部分节点失效，其余节点仍可提供服务（只要大多数主节点存活）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;数据分布均衡&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;确定性分片&lt;/strong&gt;：&lt;code&gt;slot = CRC16(key) % 16384&lt;/code&gt; 确保相同 key 总路由到同一节点，避免数据重复。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;均匀分布&lt;/strong&gt;：哈希算法使 key 在槽位间近似均匀分布，结合槽位均分到节点，实现负载均衡。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;客户端智能路由&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MOVED 重定向&lt;/strong&gt;：客户端首次访问错误节点时，返回正确节点地址，后续直接连接目标节点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;本地缓存槽位映射&lt;/strong&gt;：客户端（如 &lt;code&gt;redis-py-cluster&lt;/code&gt;）缓存 &lt;code&gt;slot → node&lt;/code&gt; 映射，减少重定向开销。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;简化运维&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;去中心化架构&lt;/strong&gt;：无中心调度节点，所有节点对等通信（Gossip 协议），避免单点瓶颈。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自动发现与状态同步&lt;/strong&gt;：节点通过 &lt;code&gt;PING/PONG&lt;/code&gt; 消息交换拓扑、故障信息，无需人工干预。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;总结&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Redis 集群的分片机制在 &lt;strong&gt;性能、容量、可用性&lt;/strong&gt; 三者间取得平衡：&lt;br /&gt;
&lt;strong&gt;通过哈希槽实现数据分布式存储，既支持弹性扩展，又保障高可用，同时保持协议简洁高效&lt;/strong&gt;，是 Redis 大规模部署的核心方案。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;4.2.3 主从复制&lt;/h4&gt;
&lt;p&gt;主从节点的数据准实时一致，通过异步的主备复制保证。从节点启动时会连接主节点，发送 SYNC 命令。主节点接收到后，开始执行 BGSAVE 命令生成 RDB 文件，并使用缓冲区记录此后执行的所有写命令。主节点 BGSAVE 执行完后，向从节点发送快照文件，发送期间继续记录写命令。从节点收到快照文件后丢弃旧数据，载入快照。主节点快照发送完毕后，向从节点发送缓冲区中的写命令。之后主节点每执行一个写命令，都会向从节点发送相同的写命令 。&lt;/p&gt;
&lt;p&gt;Redis 主从复制通过异步方式实现数据准实时同步，过程如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;建立连接：从节点启动后，向主节点发起连接，并发送 PSYNC 命令（首次为 PSYNC ? -1）。&lt;/li&gt;
&lt;li&gt;全量同步（必要时）：
主节点收到首次 PSYNC 后，执行 BGSAVE 生成 RDB 快照；
同时将新写命令缓存在复制积压缓冲区（repl_backlog）；
RDB 生成后，主节点将其发送给从节点；
从节点清空本地数据，加载 RDB。&lt;/li&gt;
&lt;li&gt;增量同步：
主节点将 RDB 生成期间及之后的写命令持续发送给从节点；
从节点执行这些命令，保持与主节点一致。&lt;/li&gt;
&lt;li&gt;断线重连优化：
若网络闪断，从节点通过 PSYNC &amp;lt;runid&amp;gt; &amp;lt;offset&amp;gt; 请求部分重同步；
主节点若在 repl_backlog 中找到对应偏移量，则仅发送缺失命令，避免全量同步。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;4.2.4读写分离&lt;/h4&gt;
&lt;p&gt;在 Redis 集群中，写操作只能由主节点处理；读操作既可以在主节点上进行，也可以在从节点上进行，以此分载主节点的读操作压力 。&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/images/数据库/13-redis集群/image-20250621174815737.webp&quot; alt=&quot;image-20250621174815737&quot; style=&quot;zoom:200%;&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/13-redis%E9%9B%86%E7%BE%A4/image-20250621174815737.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;4.3 创建集群&lt;/h3&gt;
&lt;h4&gt;启用集群配置&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# 1. 绑定所有接口（允许外部连接）
bind 0.0.0.0

# 2. 禁用保护模式（因未设密码，有密码情况下可以设置为yes）
protected-mode no

# 3. 监听端口
port 6379

# 4. 不以守护进程方式运行（由 systemd 管理）
daemonize no

# 5. 启用集群模式（核心！）
cluster-enabled yes

# 6. 集群节点超时（毫秒），默认 15000，可调小测试用
cluster-node-timeout 5000

# 7. 集群配置文件（自动生成，不要手动创建）
cluster-config-file nodes-6379.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;说明：&lt;/p&gt;
&lt;p&gt;1、在任意一台redis服务器上都可以执行创建集群的命令。&lt;/p&gt;
&lt;p&gt;2、--cluster-replicas 1 给每个master服务器分配一台slave服务器，每个主至少要分配1台slave服务器，不然无法实现redis服务的高可用。&lt;/p&gt;
&lt;p&gt;3、创建集群时，会自动创建主从角色，默认把主机列表中的前3台服务器创建为 Master角色的redis服务器，剩下的均配置为slave角色服务器。&lt;/p&gt;
&lt;p&gt;4、创建集群时，会自动给master角色的主机分配hash槽 ，通过hash槽实现数据的分布式存储。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis51 ~]# redis-cli --cluster【克拉斯特】 create 192.168.90.51:6379 192.168.90.52:6379 192.168.90.53:6379 192.168.90.54:6379 192.168.90.55:6379 192.168.90.56:6379 --cluster-replicas 1
&amp;gt;&amp;gt;&amp;gt; Creating cluster
&amp;gt;&amp;gt;&amp;gt; Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.90.51:6379
192.168.90.52:6379
192.168.90.53:6379
Adding replica 192.168.90.55:6379 to 192.168.90.51:6379
Adding replica 192.168.90.56:6379 to 192.168.90.52:6379
Adding replica 192.168.90.54:6379 to 192.168.90.53:6379
M: 0eb3b7aa0493a19189cba35b0c658202cc20884b 192.168.90.51:6379
   slots:0-5460 (5461 slots) master
M: a9cb8ccd31bf3eb70433c00906c9f1a99b5e8441 192.168.90.52:6379
   slots:5461-10922 (5462 slots) master
M: f2c1bdb78d8d224c3666fa6440bdf80ba563c581 192.168.90.53:6379
   slots:10923-16383 (5461 slots) master
S: bdba77868965371680fa825badff59bf8ef95a81 192.168.90.54:6379
   replicates f2c1bdb78d8d224c3666fa6440bdf80ba563c581
S: 11510f42bfd9cf667bab5f31c01476d94984200a 192.168.90.55:6379
   replicates 0eb3b7aa0493a19189cba35b0c658202cc20884b
S: fe572ce003ee634c52adc4b42d92d15f847937d7 192.168.90.56:6379
   replicates a9cb8ccd31bf3eb70433c00906c9f1a99b5e8441
Can I set the above configuration? (type &apos;yes&apos; to accept): yes #同意 
....
....
[OK] All nodes agree about slots configuration.
&amp;gt;&amp;gt;&amp;gt; Check for open slots...
&amp;gt;&amp;gt;&amp;gt; Check slots coverage...
[OK] All 16384 slots covered.  //创建成功的提示
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.4 查看集群信息&lt;/h3&gt;
&lt;p&gt;第一列：主服务器ip地址&lt;/p&gt;
&lt;p&gt;第二列：主服务器ID&lt;/p&gt;
&lt;p&gt;第三列：存储变量个数&lt;/p&gt;
&lt;p&gt;第四列：hash槽个数 （hash槽的作用在集群存储工程过程里讲）&lt;/p&gt;
&lt;p&gt;第五列：从服务器数量&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis51 ~]# redis-cli --cluster【克拉斯特】  info【因否】  192.168.90.51:6379
192.168.90.53:6379 (f2c1bdb7...) -&amp;gt; 0 keys | 5461 slots | 1 slaves.
192.168.90.51:6379 (0eb3b7aa...) -&amp;gt; 0 keys | 5461 slots | 1 slaves.
192.168.90.52:6379 (a9cb8ccd...) -&amp;gt; 0 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.5 访问集群&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[root@redis51 ~]# redis-cli  -c -h 192.168.90.51 -p 6379
192.168.90.51:6379&amp;gt; set school  moershi
-&amp;gt; Redirected to slot [8455] located at 192.168.90.52:6379
OK
192.168.90.52:6379&amp;gt; set teacher jam
-&amp;gt; Redirected to slot [12541] located at 192.168.90.53:6379
OK
192.168.90.53:6379&amp;gt; set class NSD
-&amp;gt; Redirected to slot [741] located at 192.168.90.51:6379
OK
192.168.90.51:6379&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;会发现3个变量被分别存储到集群中的3台master服务器上，实现了数据的分布式存储。当连接集群中的任意一台redis服务器存储数据时，会调用集群CRC16算法 得出此次存储变量使用的hash 槽，然后连接hash 槽 所在的master服务器存储变量。
在创建集群时会把默认的16384个槽平均的分配给集群中的3个master服务器。可以通过查看集群信息查看每个master服务器占用hash槽的个数。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis51 ~]# redis-cli  --cluster【克拉斯特】  info【因否】  192.168.90.51:6379
192.168.90.53:6379 (f2c1bdb7...) -&amp;gt; 0 keys | 5461 slots | 1 slaves.
192.168.90.51:6379 (0eb3b7aa...) -&amp;gt; 0 keys | 5461 slots | 1 slaves.
192.168.90.52:6379 (a9cb8ccd...) -&amp;gt; 0 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;集群中slave角色的主机会自动同步master角色主机的数据，实现数据的自动备份，&lt;/p&gt;
&lt;p&gt;分别连接集群中的3台slave服务器查看变量&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis54 ~]# redis-cli -c -h 192.168.90.54 -p 6379
192.168.90.54:6379&amp;gt; keys *
1) &quot;class&quot;
[root@redis55 ~]# redis-cli -c -h 192.168.90.55 -p 6379
192.168.90.55:6379&amp;gt; keys *
1) &quot;school&quot;
[root@redis56 ~]# redis-cli -c -h 192.168.90.56 -p 6379
192.168.90.56:6379&amp;gt; keys *
1) &quot;teacher&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当master角色的服务器宕机时，对应的slave服务器会升级为master 并接手对应的hash槽，实现redis服务的高可用，例如停止host53主机的redis服务，对应的从会升级为master 。(当宕机的master恢复后 自动做当前主的从服务器)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#停止redis服务
[root@redis53 ~]# systemctl【西斯屯-ctl】  stop【 s 多】  redis  
#查看集群信息
[root@redis51 ~]#]# redis-cli --cluster【克拉斯特】  info【因否】  192.168.90.51:6379
192.168.90.54:6379 (f2c1bdb7...) -&amp;gt; 1 keys | 5461 slots | 0 slaves.
192.168.90.51:6379 (0eb3b7aa...) -&amp;gt; 1 keys | 5461 slots | 1 slaves.
192.168.90.52:6379 (a9cb8ccd...) -&amp;gt; 1 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
keys per slot on average.
#启动redis服务
[root@redis53 ~]# systemctl【西斯屯-ctl】  start【s 达儿】  redis 
#查看集群信息
[root@redis51 ~]#]# redis-cli --cluster【克拉斯特】  info【因否】  192.168.90.51:6379
192.168.90.54:6379 (f2c1bdb7...) -&amp;gt; 1 keys | 5461 slots | 1 slaves.
192.168.90.51:6379 (0eb3b7aa...) -&amp;gt; 1 keys | 5461 slots | 1 slaves.
192.168.90.52:6379 (a9cb8ccd...) -&amp;gt; 1 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
keys per slot on average.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、配置主从复制&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/13-redis%E9%9B%86%E7%BE%A4/image-20250623164908097.webp&quot; alt=&quot;image-20250623164908097&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;5.1 环境准备&lt;/h3&gt;
&lt;p&gt;准备3台新虚拟机&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;redis61&lt;/td&gt;
&lt;td&gt;192.168.90.61&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redis62&lt;/td&gt;
&lt;td&gt;192.168.90.62&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redis63&lt;/td&gt;
&lt;td&gt;192.168.90.63&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;配置服务器192.168.90.61&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis61 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis61
[root@redis61 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.61/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis61~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置服务器192.168.90.62&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis62 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis62
[root@redis62 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.62/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis62~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置服务器192.168.90.63&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis63 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis63
[root@redis63 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.63/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis63~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 配置一主一从结构&lt;/h3&gt;
&lt;p&gt;1）配置redis61为主服务器&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis61 ~]# yum -y install【因-斯多】 redis
[root@redis61 ~]# vim /etc/redis/redis.conf
75 bind 0.0.0.0
[root@redis61 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis61 ~]# redis-cli
127.0.0.1:6379&amp;gt; info【因否】 replication  #查看主从关系信息
# Replication
role:master   # 默认就是主服务器
connected_slaves:0  #没有从服务器
master_failover_state:no-failover
master_replid:bd86b885e9e6b21e452696d472e2b2852c7fea72
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）配置redids62为redis61的从服务器&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis62 ~]# yum -y install【因-斯多】 redis
[root@redis62 ~]# vim /etc/redis/redis.conf
75 bind 0.0.0.0
[root@redis62 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis62 ~]# redis-cli
127.0.0.1:6379&amp;gt; replicaof 192.168.90.61 6379  #指定主服务器ip和端口
OK
127.0.0.1:6379&amp;gt; config rewrite  #永久保存配置
OK
127.0.0.1:6379&amp;gt; exit
#查看文件末尾
[root@redis62 ~]# tail -1 /etc/redis/redis.conf  
replicaof 192.168.90.61 6379
[root@redis62 ~]# redis-cli
127.0.0.1:6379&amp;gt; info【因否】 replication  #查看主从关系信息
# Replication
role:slave   #从角色
master_host:192.168.90.61  #主服务器ip地址 
master_port:6379  #主服务器端口号
master_link_status:up  #与主服务器连接状态 （up 正常  down 连接失败）
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_read_repl_offset:84
slave_repl_offset:84
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:f2fde7a2f3f7c6b3a20b1223b0c35ba55b245d0c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:84
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:84
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3）在主服务器redis61查看复制信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:master  #主角色
connected_slaves:1  #一个从
slave0:ip=192.168.90.62,port=6379,state=online,offset=98,lag=0 #从服务器信息
master_failover_state:no-failover
master_replid:f2fde7a2f3f7c6b3a20b1223b0c35ba55b245d0c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:98
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:98
127.0.0.1:6379&amp;gt; mset x 1 y 2 z 3  #存储数据
OK
127.0.0.1:6379&amp;gt; keys *
1) &quot;x&quot;
2) &quot;z&quot;
3) &quot;y&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4）在从服务器查看是否同步数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; keys *
1) &quot;x&quot;
2) &quot;z&quot;
3) &quot;y&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.3 配置一主多从结构&lt;/h3&gt;
&lt;p&gt;把redis63也配置为redis61的从服务器&lt;/p&gt;
&lt;p&gt;1）配置redis63为redis61的从服务器&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis63 ~]# yum -y install【因-斯多】 redis
[root@redis63 ~]# vim /etc/redis/redis.conf
75 bind 0.0.0.0
[root@redis63 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis63 ~]# redis-cli
127.0.0.1:6379&amp;gt; replicaof 192.168.90.61 6379  #指定主服务器ip和端口
OK
127.0.0.1:6379&amp;gt; config rewrite  #永久保存配置
OK
127.0.0.1:6379&amp;gt; exit
#查看文件末尾
[root@redis62 ~]# tail -1 /etc/redis/redis.conf  
replicaof 192.168.90.61 6379
[root@redis63 ~]# redis-cli
127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:slave
master_host:192.168.90.61
master_port:6379
master_link_status:up
master_last_io_seconds_ago:10
master_sync_in_progress:0
slave_read_repl_offset:1507
slave_repl_offset:1507
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:f2fde7a2f3f7c6b3a20b1223b0c35ba55b245d0c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1507
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1466
127.0.0.1:6379&amp;gt; keys *
1) &quot;y&quot;
2) &quot;z&quot;
3) &quot;x&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在redis61 查看到有2台从服务器&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:master
connected_slaves:2  #2个从服务器
slave0:ip=192.168.90.62,port=6379,state=online,offset=1591,lag=0  #从1
slave1:ip=192.168.90.63,port=6379,state=online,offset=1591,lag=1  #从2
master_failover_state:no-failover
master_replid:f2fde7a2f3f7c6b3a20b1223b0c35ba55b245d0c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1591
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1591

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.4 配置主从从结构&lt;/h3&gt;
&lt;p&gt;把redis63恢复为独立的redis服务器，然后配置为redis62的从服务器&lt;/p&gt;
&lt;p&gt;1）配置redis63&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; replicaof no one #恢复为独立的数据库服务器
OK
127.0.0.1:6379&amp;gt; replicaof 192.168.90.62 6379  #指定主服务器为62
OK
127.0.0.1:6379&amp;gt; config rewrite #保存配置
OK
127.0.0.1:6379&amp;gt; exit
@查看是否保存
[root@redis63 ~]# tail -1 /etc/redis/redis.conf
replicaof 192.168.90.62 6379
[root@redis63 ~]# redis-cli
127.0.0.1:6379&amp;gt; info【因否】 replication  #查看主从关系信息
# Replication
role:slave #从角色
master_host:192.168.90.62 #主服务器IP
master_port:6379  #主服务端口
master_link_status:up #与主服务器连接状态
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_read_repl_offset:2025
slave_repl_offset:2025
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:f2fde7a2f3f7c6b3a20b1223b0c35ba55b245d0c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2025
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1956
repl_backlog_histlen:70
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）在redis62查看复制信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:slave  #本身是从服务器
master_host:192.168.90.61  #主服务器ip
master_port:6379  #主服务器redis服务端口
master_link_status:up   #与主服务器连接状态
master_last_io_seconds_ago:6
master_sync_in_progress:0
slave_read_repl_offset:2291
slave_repl_offset:2291
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:1  #本身有一个从服务器
slave0:ip=192.168.90.63,port=6379,state=online,offset=2291,lag=0 #从服务器信息
master_failover_state:no-failover
master_replid:f2fde7a2f3f7c6b3a20b1223b0c35ba55b245d0c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2291
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2291
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3)在redis61上查看信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:master
connected_slaves:1 #只有一个从了
slave0:ip=192.168.90.62,port=6379,state=online,offset=2403,lag=0
master_failover_state:no-failover
master_replid:f2fde7a2f3f7c6b3a20b1223b0c35ba55b245d0c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2403
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2403
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、置带验证的主从复制&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/13-redis%E9%9B%86%E7%BE%A4/image-20250623164933059.webp&quot; alt=&quot;image-20250623164933059&quot; /&gt;&lt;/p&gt;
&lt;p&gt;基于案例1做如下配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;配置主机redis61，redis服务连接密码为123456&lt;/li&gt;
&lt;li&gt;主机redis62设置连接redis61的redis服务密码&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;给redis61主机的Redis服务设置连接密码，如果从服务器不指定连接密码无法同步数据。&lt;/p&gt;
&lt;h3&gt;6.1 配置主机redis61&lt;/h3&gt;
&lt;p&gt;redis服务连接密码为123456&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis61 ~]# redis-cli
127.0.0.1:6379&amp;gt; config get requirepass  #查看密码，默认服务没有密码
1) &quot;requirepass&quot;
2) &quot;&quot;
127.0.0.1:6379&amp;gt; config set requirepass 123456  #设置密码
OK
127.0.0.1:6379&amp;gt; auth 123456  #密码登录
OK
127.0.0.1:6379&amp;gt; config rewrite #保存配置
OK
127.0.0.1:6379&amp;gt; exit
#保存到文件的的密码
[root@redis61 ~]# grep &quot;123456&quot; /etc/redis/redis.conf 
requirepass &quot;123456&quot;
#重启redis服务
[root@redis61 ~]# systemctl【西斯屯-ctl】 restart redis  
[root@redis61 ~]# redis-cli
127.0.0.1:6379&amp;gt; auth 123456 
OK
127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:master
connected_slaves:0 # 没有从服务器了 因为从没有输入连接密码连接不上主服务器
master_failover_state:no-failover
master_replid:7f7c394d93a5df791bbdfb207cdeaf1eb506358f
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.2 主机redis62设置连接redis61的redis服务密码&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#重启redis服务
[root@redis62 ~]# systemctl【西斯屯-ctl】 restart redis
[root@redis62 ~]# redis-cli
127.0.0.1:6379&amp;gt; info【因否】 replication  #查看主从关系信息
# Replication
role:slave
master_host:192.168.90.61
master_port:6379
master_link_status:down  #没设置密码 与master主机是断开状态
master_last_io_seconds_ago:-1
master_sync_in_progress:1
slave_read_repl_offset:1
slave_repl_offset:1
master_sync_total_bytes:-1
master_sync_read_bytes:0
master_sync_left_bytes:-1
master_sync_perc:-0.00
master_sync_last_io_seconds_ago:0
master_link_down_since_seconds:-1
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:f2fde7a2f3f7c6b3a20b1223b0c35ba55b245d0c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:3383
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;指定主服务器的密码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; config set masterauth 123456  #指定主服务器密码
OK
127.0.0.1:6379&amp;gt; config rewrite  #保存配置
OK
127.0.0.1:6379&amp;gt; info【因否】 replication  #查看主从信息
# Replication
role:slave
master_host:192.168.90.61
master_port:6379
master_link_status:up  #现在是启动状态
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_read_repl_offset:28
slave_repl_offset:28
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:1
slave0:ip=192.168.90.63,port=6379,state=online,offset=28,lag=1
master_failover_state:no-failover
master_replid:a288cad0a8747569f147c06bb63237b2751a9fb4
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:28
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:28
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3)在redis61上查看信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis61 ~]# redis-cli
127.0.0.1:6379&amp;gt; auth 123456
OK
127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.90.62,port=6379,state=online,offset=70,lag=1
master_failover_state:no-failover
master_replid:a288cad0a8747569f147c06bb63237b2751a9fb4
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:70
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:70

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;七、哨兵服务&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/13-redis%E9%9B%86%E7%BE%A4/image-20250623164956680.webp&quot; alt=&quot;image-20250623164956680&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;7.1环境准备&lt;/h3&gt;
&lt;p&gt;准备3台新的虚拟机&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;redis67&lt;/td&gt;
&lt;td&gt;192.168.90.67&lt;/td&gt;
&lt;td&gt;Master服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redis68&lt;/td&gt;
&lt;td&gt;192.168.90.68&lt;/td&gt;
&lt;td&gt;Slave服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redis69&lt;/td&gt;
&lt;td&gt;192.168.90.69&lt;/td&gt;
&lt;td&gt;哨兵服务&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;说明：&lt;/p&gt;
&lt;p&gt;1）可以使用一主一从或 一主多从 或 主从从 + 哨兵服务 做服务的高可用 和 数据自动备份&lt;/p&gt;
&lt;p&gt;2）如果主从结构中的redis服务设置连接密码的话必须全每台数据库都要设置密码且密码要一样，要么全都不设置密码。&lt;/p&gt;
&lt;p&gt;3）如果Redis服务有密码宕机的服务器启动服务后，要人为指定主服务器的连接密码。&lt;/p&gt;
&lt;p&gt;配置服务器192.168.90.67&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis67 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis67
[root@redis67 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.67/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis67~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置服务器192.168.90.68&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis68 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis68
[root@redis68 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.68/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis68~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置服务器192.168.90.69&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis69 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis69
[root@redis69 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.69/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis69~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.2 哨兵服务的原理&lt;/h3&gt;
&lt;p&gt;Redis哨兵是一种分布式高可用解决方案，用于实现主从自动故障转移、集群监控以及充当配置中心自动更新客户端连接信息。其工作原理主要分为三个阶段：监控、共识和故障转移 。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;监控（Monitoring）&lt;/strong&gt;：哨兵每秒向主/从节点发送PING命令，若节点超时（down-after-milliseconds，默认30s）无响应，该哨兵会将其标记为主观下线（SDOWN）。即单个哨兵认为实例不可用（PING无响应超过 down-after-milliseconds 配置） 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;共识（Agreement）&lt;/strong&gt;：哨兵集群通过Gossip协议交换节点状态。当多数哨兵（≥ quorum）都认为主节点下线时，会将其标记为客观下线（ODOWN）。也就是当足够数量（quorum配置）的哨兵都认为主节点不可用时，才判定主节点真正不可用 。&lt;/li&gt;
&lt;li&gt;故障转移（Failover）
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;选举领导者哨兵&lt;/strong&gt;：基于Raft协议进行选举。发现主节点ODOWN的哨兵发起选举，每个哨兵在每个配置纪元（epoch）仅投一票，最先获得多数票（≥ N/2 + 1）的哨兵当选为领导者哨兵来执行故障转移；若选举超时（默认100ms），则会重新发起选举 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;选择新主节点&lt;/strong&gt;：从从节点中选出新主节点，选择规则依次基于优先级（slave-priority配置）、复制偏移量（选择数据最新的）、运行ID（选择较小的）。先排除已下线节点和replica-priority = 0的节点，然后选择优先级最高、复制偏移量最大、Run ID最小的节点 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;重新配置&lt;/strong&gt;：领导者哨兵将选中的从节点提升为主节点（执行SLAVEOF NO ONE命令）；通知其他从节点复制新的主节点（执行SLAVEOF new_master_ip port命令）；当旧主节点恢复时，将其配置为新主节点的从节点 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;通知客户端&lt;/strong&gt;：通过Redis的发布/订阅机制，将新主节点的IP和端口信息推送给客户端，让客户端更新配置，连接到新的主节点 。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;7.3 配置主机redis67为master服务器&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis67 ~]# yum -y install【因-斯多】 redis
#替换掉75行
[root@redis67 ~]# sed -i &quot;75c bind 0.0.0.0&quot; /etc/redis/redis.conf
[root@redis67 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis67 ~]# redis-cli
127.0.0.1:6379&amp;gt; info【因否】 replication  #查看主从关系信息
# Replication
role:master   # 默认就是主服务器
connected_slaves:0  #没有从服务器
master_failover_state:no-failover
master_replid:bd86b885e9e6b21e452696d472e2b2852c7fea72
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.4 配置主机redis68为redis67的slave服务器&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis68 ~]# yum -y install【因-斯多】 redis
[root@redis68 ~]# sed -i &quot;75c bind 0.0.0.0&quot; /etc/redis/redis.conf
[root@redis68 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis68 ~]# redis-cli
127.0.0.1:6379&amp;gt; replicaof 192.168.90.67 6379  #指定主服务器ip和端口
OK
127.0.0.1:6379&amp;gt; config rewrite  #永久保存配置
OK
127.0.0.1:6379&amp;gt; exit
#查看文件末尾
[root@redis68 ~]# tail -1 /etc/redis/redis.conf  
replicaof 192.168.90.67 6379
[root@redis62 ~]# redis-cli
127.0.0.1:6379&amp;gt; info【因否】 replication  #查看主从关系信息
# Replication
role:slave   #从角色
master_host:192.168.90.67  #主服务器ip地址 
master_port:6379  #主服务器端口号
master_link_status:up  #与主服务器连接状态 （up 正常  down 连接失败）
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_read_repl_offset:84
slave_repl_offset:84
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:f2fde7a2f3f7c6b3a20b1223b0c35ba55b245d0c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:84
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:84
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.5 配置主机redis69运行哨兵服务&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;安装redis软件，启动哨兵服务&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;[root@redis68 ~]# yum -y install【因-斯多】 redis
#哨兵配置文件
[root@redis69 ~]# vim /etc/redis/sentinel.conf 
15 bind 0.0.0.0
26 daemonize yes
84 sentinel monitor mymaster 192.168.90.67 6379 1

#启动哨兵服务
[root@redis69 ~]# systemctl【西斯屯-ctl】  start【s 达儿】 redis-sentinel
#查看端口号
[root@redis69 ~]#  netstat  -utnlp  | grep 26379  
tcp        0      0 0.0.0.0:26379           0.0.0.0:*               LISTEN      2179/redis-sentinel 
[root@redis69 ~]# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）查看日志获取监视信息&lt;/p&gt;
&lt;p&gt;复制一个终端会话&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis69 ~]# tail -f /var/log/redis/sentinel.log 
2179:X 23 Jun 2025 15:47:44.301 * Supervised by systemd. Please make sure you set appropriate values for TimeoutStartSec and TimeoutStopSec in your service unit.
2179:X 23 Jun 2025 15:47:44.301 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2179:X 23 Jun 2025 15:47:44.301 # Redis version=6.2.18, bits=64, commit=00000000, modified=0, pid=2179, just started
2179:X 23 Jun 2025 15:47:44.301 # Configuration loaded
2179:X 23 Jun 2025 15:47:44.302 * monotonic clock: POSIX clock_gettime
2179:X 23 Jun 2025 15:47:44.302 * Running mode=sentinel, port=26379.
2179:X 23 Jun 2025 15:47:44.304 # Sentinel ID is 5ab8d490e1e7b600170a2a725b4679d25186b4d1
2179:X 23 Jun 2025 15:47:44.304 # +monitor master mymaster 192.168.90.67 6379 quorum 1
2179:X 23 Jun 2025 15:47:44.306 * +slave slave 192.168.90.68:6379 192.168.90.68 6379 @ mymaster 192.168.90.67 6379
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.6 测试配置&lt;/h3&gt;
&lt;p&gt;思路：停止master主机的redis 服务，原slave角色会升级为主，哨兵服务会自动监视新的master服务，宕机的master 主机恢复后自动配置为当前主的从服务器。&lt;/p&gt;
&lt;p&gt;停止master主机的redis 服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis67 ~]# systemctl【西斯屯-ctl】 stop【 s 多】 redis
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看slave&lt;/p&gt;
&lt;p&gt;原slave角色会升级为主&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:slave
master_host:192.168.90.67
master_port:6379
master_link_status:down  #master宕机了
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_read_repl_offset:22602
slave_repl_offset:22602
master_link_down_since_seconds:27
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:0f9c32408bfd386ab9c9ef00617298a969e89c73
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:22602
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1

#重新登录
[root@redis68 ~]#  redis-cli
127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:master #升级为master
connected_slaves:0
master_failover_state:no-failover
master_replid:8289cfb1acb8573be217df886ac24732f2bdb6a9
master_replid2:0f9c32408bfd386ab9c9ef00617298a969e89c73
master_repl_offset:25586
second_repl_offset:22603
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;哨兵服务会自动监视新的master服务&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/13-redis%E9%9B%86%E7%BE%A4/image-20250623155722362.webp&quot; alt=&quot;image-20250623155722362&quot; /&gt;&lt;/p&gt;
&lt;p&gt;宕机的master 主机恢复后自动配置为当前主的从服务器。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis67 ~]# redis-cli
127.0.0.1:6379&amp;gt; info【因否】 replication
Error: Server closed the connection【肯耐申】
127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:slave  #变成从服务器
master_host:192.168.90.68  #现在主服务器是192.168.90.68 
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_read_repl_offset:41965
slave_repl_offset:41965
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:8289cfb1acb8573be217df886ac24732f2bdb6a9
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:41965
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:41520
repl_backlog_histlen:446

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;八、作业&lt;/h2&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Redis 哨兵将主节点标记为客观下线（ODOWN）的条件是？ B
A. 单个哨兵认为主节点不可用
B. 多数哨兵（≥ quorum）都认为主节点下线
C. 主节点主动发出下线通知
D. 主节点超过 1 分钟无响应&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Redis Cluster 采用的分布式数据分片机制是？ A
A. 哈希槽机制
B. 随机分配机制
C. 轮询机制
D. 顺序分配机制&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 Redis 主从复制中，从节点启动时会向主节点发送什么命令？ A
A. SYNC 命令
B. SAVE 命令
C. FLUSHALL 命令
D. info 命令&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;简述 Redis 哨兵服务的工作原理。
答：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;监控（Monitoring）：哨兵每秒向主/从节点发送PING命令，若节点超时（down-after-milliseconds，默认30s）无响应，该哨兵会将其标记为主观下线（SDOWN）。即单个哨兵认为实例不可用（PING无响应超过 down-after-milliseconds 配置） 。&lt;/li&gt;
&lt;li&gt;共识（Agreement）：哨兵集群通过Gossip协议交换节点状态。当多数哨兵（≥ quorum）都认为主节点下线时，会将其标记为客观下线（ODOWN）。也就是当足够数量（quorum配置）的哨兵都认为主节点不可用时，才判定主节点真正不可用 。&lt;/li&gt;
&lt;li&gt;故障转移（Failover）
&lt;ul&gt;
&lt;li&gt;选举领导者哨兵：基于Raft协议进行选举。发现主节点ODOWN的哨兵发起选举，每个哨兵在每个配置纪元（epoch）仅投一票，最先获得多数票（≥ N/2 + 1）的哨兵当选为领导者哨兵来执行故障转移；若选举超时（默认100ms），则会重新发起选举 。&lt;/li&gt;
&lt;li&gt;选择新主节点：从从节点中选出新主节点，选择规则依次基于优先级（slave-priority配置）、复制偏移量（选择数据最新的）、运行ID（选择较小的）。先排除已下线节点和replica-priority = 0的节点，然后选择优先级最高、复制偏移量最大、Run ID最小的节点 。&lt;/li&gt;
&lt;li&gt;重新配置：领导者哨兵将选中的从节点提升为主节点（执行SLAVEOF NO ONE命令）；通知其他从节点复制新的主节点（执行SLAVEOF new_master_ip port命令）；当旧主节点恢复时，将其配置为新主节点的从节点 。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;通知客户端：通过Redis的发布/订阅机制，将新主节点的IP和端口信息推送给客户端，让客户端更新配置，连接到新的主节点 。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;说明 Redis 集群中分布式数据分片的好处。
答：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;水平扩展：突破单机性能瓶颈，将数据和请求负载分散到多个节点，可线性提升吞吐量（QPS）和存储容量。动态扩容在通过迁移槽位（如 redis-cli --cluster reshard），可在不停服的情况下增减节点。&lt;/li&gt;
&lt;li&gt;高可用性：自动故障转移，每个主节点可配置从节点（replica），主节点宕机时，从节点自动升主，主节点恢复自从加入新主节点的从节点。无单点故障，即使部分节点失效，其余节点仍可提供服务（只要大多数主节点存活）。&lt;/li&gt;
&lt;li&gt;数据分布均衡：确定性分片，如slot = CRC16(key) % 16384 确保相同 key 总路由到同一节点，避免数据重复。均匀分布，哈希算法使 key 在槽位间近似均匀分布，结合槽位均分到节点，实现负载均衡。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;请阐述 Redis 主从复制的过程。
答：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;建立连接：从节点启动后，向主节点发起连接，并发送 PSYNC 命令（首次为 PSYNC ? -1）。&lt;/li&gt;
&lt;li&gt;主节点收到首次 PSYNC 后，执行 BGSAVE 生成 RDB 快照，同时将新写命令缓存在复制积压缓冲区（repl_backlog），DB 生成后，主节点将其发送给从节点，从节点清空本地数据，加载 RDB。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3 操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;请写出配置 Redis 一主一从结构的详细步骤。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;[root@redis60 ~]#     主配置
[root@redis60 ~]# systemctl start redis.service 
[root@redis60 ~]# redis-cli
127.0.0.1:6379&amp;gt; config set protected-mode no
OK
127.0.0.1:6379&amp;gt; config rewrite
OK
127.0.0.1:6379&amp;gt; info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:2aae21339753d355129c78fab17bd7a1c547aedf
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0



[root@redis61 ~]#     从配置
[root@redis61 ~]# systemctl start redis.service 
[root@redis61 ~]# redis-cli 
127.0.0.1:6379&amp;gt; config set protected-mode no
OK
127.0.0.1:6379&amp;gt; config rewrite
OK
127.0.0.1:6379&amp;gt; replicaof 192.168.88.60 6379
OK
127.0.0.1:6379&amp;gt; config rewrite
OK
127.0.0.1:6379&amp;gt; info replication
# Replication
role:slave
master_host:192.168.88.60
master_port:6379
master_link_status:up
master_last_io_seconds_ago:9
master_sync_in_progress:0
slave_read_repl_offset:224
slave_repl_offset:224
replica_full_sync_buffer_size:0
replica_full_sync_buffer_peak:0
master_current_sync_attempts:160
master_total_sync_attempts:160
master_link_up_since_seconds:154
total_disconnect_time_sec:0
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:a321b83129695ff3cea398fd398097e9b99f63f5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:224
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:210
127.0.0.1:6379&amp;gt; 


127.0.0.1:6379&amp;gt;    主redis状态检查
127.0.0.1:6379&amp;gt; info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.88.61,port=6379,state=online,offset=266,lag=1
master_failover_state:no-failover
master_replid:a321b83129695ff3cea398fd398097e9b99f63f5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:266
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:266
127.0.0.1:6379&amp;gt; 



127.0.0.1:6379&amp;gt;     验证：主写入数据
127.0.0.1:6379&amp;gt; mset a 1 b 2 c 3 d 4 e 5 f 6 
OK
127.0.0.1:6379&amp;gt; 

127.0.0.1:6379&amp;gt;     验证：从数据读取
127.0.0.1:6379&amp;gt; keys *
1) &quot;a&quot;
2) &quot;d&quot;
3) &quot;f&quot;
4) &quot;b&quot;
5) &quot;c&quot;
6) &quot;e&quot;
127.0.0.1:6379&amp;gt; mget a b c d e f
1) &quot;1&quot;
2) &quot;2&quot;
3) &quot;3&quot;
4) &quot;4&quot;
5) &quot;5&quot;
6) &quot;6&quot;
127.0.0.1:6379&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;描述创建 Redis 高可用集群的具体操作过程。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;# 集群配置

[root@redis59 ~]# 
[root@redis59 ~]# grep -vE &quot;^\s*($|#)&quot; /opt/redis/conf/redis.conf | grep -nE &quot;bind|protected-mode|port|daemonize|cluster&quot;
1:bind 0.0.0.0
2:protected-mode no
3:port 6379
7:daemonize no
51:cluster-enabled yes
52:cluster-config-file nodes-6379.conf
53:cluster-node-timeout 5000
[root@redis59 ~]# systemctl start redis.service

[root@redis60 ~]# 
[root@redis60 ~]# grep -vE &quot;^\s*($|#)&quot; /opt/redis/conf/redis.conf | grep -nE &quot;bind|protected-mode|port|daemonize|cluster&quot;
1:bind 0.0.0.0
2:protected-mode no
3:port 6379
7:daemonize no
51:cluster-enabled yes
52:cluster-config-file nodes-6379.conf
53:cluster-node-timeout 5000
[root@redis60 ~]# systemctl start redis.service

[root@redis61 ~]# 
[root@redis61 ~]# grep -vE &quot;^\s*($|#)&quot; /opt/redis/conf/redis.conf | grep -nE &quot;bind|protected-mode|port|daemonize|cluster&quot;
1:bind 0.0.0.0
2:protected-mode no
3:port 6379
7:daemonize no
51:cluster-enabled yes
52:cluster-config-file nodes-6379.conf
53:cluster-node-timeout 5000
[root@redis61 ~]# systemctl start redis.service

[root@redis62 ~]# 
[root@redis62 ~]# grep -vE &quot;^\s*($|#)&quot; /opt/redis/conf/redis.conf | grep -nE &quot;bind|protected-mode|port|daemonize|cluster&quot;
1:bind 0.0.0.0
2:protected-mode no
3:port 6379
7:daemonize no
51:cluster-enabled yes
52:cluster-config-file nodes-6379.conf
53:cluster-node-timeout 5000
[root@redis62 ~]# systemctl start redis.service

[root@redis63 ~]# 
[root@redis63 ~]# grep -vE &quot;^\s*($|#)&quot; /opt/redis/conf/redis.conf | grep -nE &quot;bind|protected-mode|port|daemonize|cluster&quot;
1:bind 0.0.0.0
2:protected-mode no
3:port 6379
7:daemonize no
51:cluster-enabled yes
52:cluster-config-file nodes-6379.conf
53:cluster-node-timeout 5000
[root@redis63 ~]# systemctl start redis.service

[root@redis64 ~]# 
[root@redis64 ~]# grep -vE &quot;^\s*($|#)&quot; /opt/redis/conf/redis.conf | grep -nE &quot;bind|protected-mode|port|daemonize|cluster&quot;
1:bind 0.0.0.0
2:protected-mode no
3:port 6379
7:daemonize no
51:cluster-enabled yes
52:cluster-config-file nodes-6379.conf
53:cluster-node-timeout 5000
[root@redis64 ~]# systemctl start redis.service


[root@redis59 ~]#     搭建集群 
[root@redis59 ~]# redis-cli --cluster create 192.168.88.59:6379 192.168.88.60:6379 192.168.88.61:6379 192.168.88.62:6379 192.168.88.63:6379 192.168.88.64:6379 --cluster-replicas 1
&amp;gt;&amp;gt;&amp;gt; Performing hash slots allocation on 6 nodes...
Master[0] -&amp;gt; Slots 0 - 5460
Master[1] -&amp;gt; Slots 5461 - 10922
Master[2] -&amp;gt; Slots 10923 - 16383
Adding replica 192.168.88.63:6379 to 192.168.88.59:6379
Adding replica 192.168.88.64:6379 to 192.168.88.60:6379
Adding replica 192.168.88.62:6379 to 192.168.88.61:6379
M: 4f75181056b5aefd90f2b1cc242e105f929ec5b4 192.168.88.59:6379
   slots:[0-5460] (5461 slots) master
M: e92ce91b5b3b4587c5520482e7a825b050d02dee 192.168.88.60:6379
   slots:[5461-10922] (5462 slots) master
M: 8f23c1c05cda60f570d70543c5ea3e5bf643c89c 192.168.88.61:6379
   slots:[10923-16383] (5461 slots) master
S: fa61df96aea2f9a53427eae75fd0c82e4b916ffb 192.168.88.62:6379
   replicates 8f23c1c05cda60f570d70543c5ea3e5bf643c89c
S: 1ca6b10204e7df92340b5c8318416340d4c5ec6b 192.168.88.63:6379
   replicates 4f75181056b5aefd90f2b1cc242e105f929ec5b4
S: 0d342ee7810cadea394eb62a7da4e3a1f320f680 192.168.88.64:6379
   replicates e92ce91b5b3b4587c5520482e7a825b050d02dee
Can I set the above configuration? (type &apos;yes&apos; to accept): yes
&amp;gt;&amp;gt;&amp;gt; Nodes configuration updated
&amp;gt;&amp;gt;&amp;gt; Assign a different config epoch to each node
&amp;gt;&amp;gt;&amp;gt; Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join

&amp;gt;&amp;gt;&amp;gt; Performing Cluster Check (using node 192.168.88.59:6379)
M: 4f75181056b5aefd90f2b1cc242e105f929ec5b4 192.168.88.59:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: e92ce91b5b3b4587c5520482e7a825b050d02dee 192.168.88.60:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
M: 8f23c1c05cda60f570d70543c5ea3e5bf643c89c 192.168.88.61:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 0d342ee7810cadea394eb62a7da4e3a1f320f680 192.168.88.64:6379
   slots: (0 slots) slave
   replicates e92ce91b5b3b4587c5520482e7a825b050d02dee
S: fa61df96aea2f9a53427eae75fd0c82e4b916ffb 192.168.88.62:6379
   slots: (0 slots) slave
   replicates 8f23c1c05cda60f570d70543c5ea3e5bf643c89c
S: 1ca6b10204e7df92340b5c8318416340d4c5ec6b 192.168.88.63:6379
   slots: (0 slots) slave
   replicates 4f75181056b5aefd90f2b1cc242e105f929ec5b4
[OK] All nodes agree about slots configuration.
&amp;gt;&amp;gt;&amp;gt; Check for open slots...
&amp;gt;&amp;gt;&amp;gt; Check slots coverage...
[OK] All 16384 slots covered.
[root@redis59 ~]# 


[root@redis59 ~]#      查看集群信息
[root@redis59 ~]# redis-cli --cluster info 192.168.88.59:6379
192.168.88.59:6379 (4f751810...) -&amp;gt; 0 keys | 5461 slots | 1 slaves.
192.168.88.60:6379 (e92ce91b...) -&amp;gt; 0 keys | 5462 slots | 1 slaves.
192.168.88.61:6379 (8f23c1c0...) -&amp;gt; 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
[root@redis59 ~]# 


[root@redis59 ~]#  访问集群验证数据
[root@redis59 ~]# redis-cli -c -h 192.168.88.59 -p 6379
192.168.88.59:6379&amp;gt; set a 1
-&amp;gt; Redirected to slot [15495] located at 192.168.88.61:6379
OK
192.168.88.61:6379&amp;gt; set b 2
-&amp;gt; Redirected to slot [3300] located at 192.168.88.59:6379
OK
192.168.88.59:6379&amp;gt; set c 3
-&amp;gt; Redirected to slot [7365] located at 192.168.88.60:6379
OK
192.168.88.60:6379&amp;gt; get a
-&amp;gt; Redirected to slot [15495] located at 192.168.88.61:6379
&quot;1&quot;
192.168.88.61:6379&amp;gt; get a
&quot;1&quot;
192.168.88.61:6379&amp;gt; get b
-&amp;gt; Redirected to slot [3300] located at 192.168.88.59:6379
&quot;2&quot;
192.168.88.59:6379&amp;gt; get c
-&amp;gt; Redirected to slot [7365] located at 192.168.88.60:6379
&quot;3&quot;
192.168.88.60:6379&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;说明如何使用 RDB 文件恢复 Redis 数据。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
[root@redis59 ~]# grep -vE &quot;^\s*($|#)&quot; /opt/redis/conf/redis.conf | grep save
save 3600 1 120 10 60 10000
stop-writes-on-bgsave-error yes
rdb-save-incremental-fsync yes
[root@redis59 ~]# systemctl start redis.service 
[root@redis59 ~]# ls /opt/redis/data/
[root@redis59 ~]# redis-cli 
127.0.0.1:6379&amp;gt; keys *
(empty array)
127.0.0.1:6379&amp;gt; mset a 1 b 2 c 3 d 4 x 1 y 2  z 3 k 6  i 7  z 9   f 22  zz 99  cc  66
OK
127.0.0.1:6379&amp;gt; keys * 
 1) &quot;c&quot;
 2) &quot;d&quot;
 3) &quot;k&quot;
 4) &quot;a&quot;
 5) &quot;cc&quot;
 6) &quot;x&quot;
 7) &quot;zz&quot;
 8) &quot;f&quot;
 9) &quot;y&quot;
10) &quot;b&quot;
11) &quot;i&quot;
12) &quot;z&quot;
127.0.0.1:6379&amp;gt; exit
[root@redis59 ~]# ls /opt/redis/data/
dump.rdb
[root@redis59 ~]# 


#  在60服务器上恢复数据
[root@redis60 ~]# 
[root@redis60 ~]# grep -vE &quot;^\s*($|#)&quot; /opt/redis/conf/redis.conf | grep save
save 3600 1 120 10 60 10000
stop-writes-on-bgsave-error yes
rdb-save-incremental-fsync yes
[root@redis60 ~]# systemctl start redis.service 
[root@redis60 ~]# redis-cli 
127.0.0.1:6379&amp;gt; keys *
(empty array)
127.0.0.1:6379&amp;gt; exit
[root@redis60 ~]# systemctl stop redis.service 
[root@redis60 ~]# ls /opt/redis/data/
dump.rdb
[root@redis60 ~]# rm -rf /opt/redis/data/dump.rdb 
[root@redis60 ~]# scp root@192.168.88.59:/opt/redis/data/dump.rdb /opt/redis/data/
root@192.168.88.59&apos;s password: 
dump.rdb                                                           100%  157    84.3KB/s   00:00    
[root@redis60 ~]# ll /opt/redis/data/
总用量 4
-rw-r--r-- 1 root root 157 1月  22 10:15 dump.rdb
[root@redis60 ~]# systemctl start redis.service 
[root@redis60 ~]# redis-cli 
127.0.0.1:6379&amp;gt; keys *
 1) &quot;y&quot;
 2) &quot;f&quot;
 3) &quot;c&quot;
 4) &quot;a&quot;
 5) &quot;b&quot;
 6) &quot;zz&quot;
 7) &quot;z&quot;
 8) &quot;i&quot;
 9) &quot;cc&quot;
10) &quot;x&quot;
11) &quot;k&quot;
12) &quot;d&quot;
127.0.0.1:6379&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>数据库和监控平台笔记</title><link>https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0%E7%AC%94%E8%AE%B0/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0%E7%AC%94%E8%AE%B0/</guid><description>一、数据库基础 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 01:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;一、数据库基础&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;mysql&lt;/code&gt;  登录到mysql终端
默认情况：&lt;code&gt;root&lt;/code&gt;（mysql服务的用户）
默认没有密码&lt;/p&gt;
&lt;p&gt;退出mysql终端
&lt;code&gt;exit&lt;/code&gt;
&lt;code&gt;quit&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select&lt;/code&gt; 查询
&lt;code&gt;select version();&lt;/code&gt;  查询版本号
&lt;code&gt;select user();&lt;/code&gt;  查询当前登录的用户
&lt;code&gt;select database();&lt;/code&gt;  查询当前正在使用的数据库&lt;/p&gt;
&lt;p&gt;&lt;code&gt;show&lt;/code&gt;  显示
&lt;code&gt;show databases;&lt;/code&gt;  显示所有的数据库
&lt;code&gt;show tables;&lt;/code&gt;  显示当前库下面的表&lt;/p&gt;
&lt;p&gt;&lt;code&gt;use  mysql&lt;/code&gt;  使用mysql数据库&lt;/p&gt;
&lt;p&gt;数据库中是由一张张表组成的&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mysqladmin&lt;/code&gt;  mysql管理员命令&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mysqladmin -uroot -p password &quot;moershi&quot;&lt;/code&gt;  修改密码&lt;/p&gt;
&lt;p&gt;有密码登录
&lt;code&gt;mysql -uroot -p密码&lt;/code&gt;（不安全）
&lt;code&gt;mysql -uroot -p&lt;/code&gt;  （安全）
输入密码&lt;/p&gt;
&lt;p&gt;修改密码
&lt;code&gt;mysqladmin -uroot -p原始密码  password &quot;新密码&apos;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;mysql
user 表：用来存储mysql账号的表
&lt;code&gt;select  User,authentication_string  from mysql.user;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;总结
忘记密码&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;修改mysql配置文件
&lt;code&gt;vim /etc/my.cnf.d/mysql-server.cnf  &lt;/code&gt;
&lt;code&gt;skip-grant-tables  不需要密码验证&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;重启mysql服务
&lt;code&gt;systemctl restart mysqld&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;无密码登录
&lt;code&gt;mysql&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;把密码修改为空
&lt;code&gt;update user set authentication_string=&quot;&quot; where user=&quot;root&quot;;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;修改mysql配置文件
&lt;code&gt;vim /etc/my.cnf.d/mysql-server.cnf  &lt;/code&gt;
去掉skip-grant-tables&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;重启mysql服务
&lt;code&gt;systemctl restart mysqld&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;无密码登录
&lt;code&gt;mysql&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在mysql终端里面设置密码
&lt;code&gt;alter user root@&quot;localhost&quot; identified by  &quot;NSD123456...a&quot;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;数据导入
&lt;code&gt;mysql -uroot -pNSD123456...a &amp;lt; moershi.sql &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查看表结构
&lt;code&gt;desc 表名&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;多个判断条件
&lt;code&gt;and  并且（多个条件同时满足）&lt;/code&gt;
&lt;code&gt;or  或（多个条件满足一个就可以）&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;如果有括号
先执行括号里面的，在过结果对括号外面的进行过滤&lt;/p&gt;
&lt;p&gt;为空
字符串空  “”
用 !=或= 来判断
真空&lt;br /&gt;
is null   等于空
is not null 不等于空&lt;/p&gt;
&lt;p&gt;合并表头
&lt;code&gt;concat(..)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;distinct&lt;/code&gt; 去重，对行的去重（每列值都相同的才去重）&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;二、数据库函数&lt;/h1&gt;
&lt;p&gt;字符串函数
用于处理字段类型为&lt;code&gt;char&lt;/code&gt;或&lt;code&gt;varchar&lt;/code&gt;的字段内容
一个字母占用1个字节
&lt;code&gt;length()  &lt;/code&gt;求字节长度
一个汉字占用3个字节（字符编码格式&lt;code&gt;utf-8&lt;/code&gt;）
一个汉字占用2个字节（字符编码格式&lt;code&gt;gbk&lt;/code&gt;）
&lt;code&gt;char_length()&lt;/code&gt;  求字符长度
一个字母一个字符
一个汉字一个字符&lt;/p&gt;
&lt;p&gt;针对英文字母
&lt;code&gt;upper   ucase &lt;/code&gt; 转大写
&lt;code&gt;lower    lcase&lt;/code&gt;  转小写
substr(变量,位置,长度)  字符串截取&lt;/p&gt;
&lt;p&gt;&lt;code&gt;instr(变量,&quot;内容&quot;) &lt;/code&gt; 求内容在变量值的什么位置
&lt;code&gt;trim() &lt;/code&gt; 去掉两边的空格&lt;/p&gt;
&lt;p&gt;聚合函数：用来统计数据的
&lt;code&gt;sum&lt;/code&gt;
&lt;code&gt;avg&lt;/code&gt;
&lt;code&gt;min&lt;/code&gt;
&lt;code&gt;max&lt;/code&gt;
&lt;code&gt;count&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;三、单表增删改查&lt;/h1&gt;
&lt;p&gt;比如说
一个班级有男生和女生（男生30，女生20）
根据一个特定数据类型来统计&lt;code&gt;（sum,avg,min,max,count）&lt;/code&gt;
&lt;code&gt;select sex,count(1) from 表  group by sex&lt;/code&gt;
&lt;code&gt;sex  count(1)&lt;/code&gt;
男   30
女  20&lt;/p&gt;
&lt;p&gt;&lt;code&gt;group by&lt;/code&gt; 用来分组的关键字&lt;/p&gt;
&lt;p&gt;排序
&lt;code&gt;order by&lt;/code&gt;
&lt;code&gt;desc&lt;/code&gt; 降序排序（从大到小）
&lt;code&gt;asc&lt;/code&gt;  升序排序（从小到大）默认情况
逻辑是
先查询结果
然后对结果进行排序&lt;/p&gt;
&lt;p&gt;查看2015年1月10号员工编号小于10的工资总额
&lt;code&gt;select basic+bonus from salary where employee_id&amp;lt;10 and date=&apos;20150110&apos;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;分组后条件过滤
先分组查询结果
然后对分组的结果（通过聚合函数获得的结果进行条件过滤）
&lt;code&gt;having&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查找部门总人数少于10人的部门编号及人数
&lt;code&gt;select dept_id,count(1) 部门人数 from employees group by dept_id;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select dept_id,count(1) 部门人数 from employees group by dept_id having 部门人数&amp;lt;10;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;limit&lt;/code&gt;  起始条数-1，每页显示总行数
&lt;code&gt;limit  0   10&lt;/code&gt;
&lt;code&gt;limit  [0] &lt;/code&gt; 每页显示总行数,  默认从0开始
假设每页显示10条数据，第一页，第二页...
&lt;code&gt;limit 0,10&lt;/code&gt;
&lt;code&gt;limit 10,10&lt;/code&gt;
&lt;code&gt;limit 20,10&lt;/code&gt;
....&lt;/p&gt;
&lt;p&gt;新增数据
&lt;code&gt;insert into  表名(列名1，列名2..)  values(a,b,...)&lt;/code&gt;
&lt;code&gt;insert into  表名  values(a,b,c,d,e)&lt;/code&gt;
批量新增
&lt;code&gt;insert into  表名  values(a,b,c,d,e),(1,2,3,4,5)....&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;修改数据
&lt;code&gt;update 表名  set 列名1=值, 列名2=值  where 条件&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;update user  set homedir=concat(&quot;/home/&quot;,name)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;删除数据
&lt;code&gt;delete from 表  where 条件&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;四、综合查询&lt;/h1&gt;
&lt;p&gt;两个表中有共同的属性就可以关联查询
ER图
表与表直接的关系图&lt;/p&gt;
&lt;p&gt;内连接
&lt;code&gt;inner join&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查询每个员工所在的部门名
&lt;code&gt;select name,dept_name from employees  inner join departments on employees.dept_id=departments.dept_id;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查询员工编号8 的 员工所在部门的部门名称
&lt;code&gt;select name,dept_name from employees  inner join departments on employees.dept_id=departments.dept_id where employee_id=8;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select e.dept_id,name,dept_name from employees e  inner join departments d on e.dept_id=d.dept_id where employee_id=8;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查询11号员工的名字及2018年每个月总工资
&lt;code&gt;select s.employee_id,name,basic+bonus as total from salary s inner join employees e on s.employee_id=e.employee_id where year(date)=2018 and s.employee_id=11;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查询每个员工2018年的总工资(员工姓名，员工id,总工资)
&lt;code&gt;sum&lt;/code&gt;求和，根据员工分组
&lt;code&gt;select s.employee_id,name,sum(basic+bonus)  as total from salary s inner join employees e on s.employee_id=e.employee_id where year(date)=2018  group by s.employee_id;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查询每个员工2018年的总工资，按总工资升序排列
&lt;code&gt;select s.employee_id,name,sum(basic+bonus)  as total from salary s inner join employees e on s.employee_id=e.employee_id where year(date)=2018 group by s.employee_id order by  total ;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查询2018年总工资大于30万的员工，按2018年总工资降序排列
&lt;code&gt;select s.employee_id,name,sum(basic+bonus)  as total from salary s inner join employees e on s.employee_id=e.employee_id where year(date)=2018  group by s.employee_id having total &amp;gt; 300000 order by  total ;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;左连接查询例子：输出没有员工的部门名
&lt;code&gt;select dept_name,name from departments d left join employees e on d.dept_id=e.dept_id;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;统计每个部门的员工人数
&lt;code&gt;select dept_name,count(e.name) 人数 from departments d left join  employees e on d.dept_id=e.dept_id group by dept_name;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;输出2018年基本工资的最大值和最小值
&lt;code&gt;select &quot;最高工资&quot; 工资级别, max(basic) 基本工资 from salary where year(date)=2018 union select &quot;最低工资&quot; 工资级别, min(basic)  基本工资 from salary where year(date)=2018;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;输出2018年1月10号 基本工资的最大值和最小值
&lt;code&gt;select date,&quot;最高工资&quot; 工资级别, max(basic) 基本工资 from salary where date=&apos;2018-1-10&apos; union select date,&quot;最低工资&quot; 工资级别, min(basic)  基本工资 from salary where date=&apos;2018-1-10&apos;;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select employee_id , name , birth_date from employees where employee_id &amp;lt;= 5 union all select employee_id , name , birth_date from employees where employee_id &amp;lt;= 6;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查询运维部所有员工信息
&lt;code&gt;select dept_id from departments where dept_name =&quot;运维部&quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select * from employees  where dept_id=(select dept_id from departments where dept_name =&quot;运维部&quot;);&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查询人事部2018年12月所有员工工资
&lt;code&gt;select dept_id from departments where dept_name =&quot;人事部&quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select employee_id from employees  where dept_id= (select dept_id from departments where dept_name =&quot;人事部&quot;)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select * from salary where year(date)=2018 and month(date)=12  and employee_id in (select employee_id from employees   where dept_id= (select dept_id from departments where dept_name =&quot;人事部&quot;))&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查询人事部和财务部员工信息
&lt;code&gt;select dept_id from departments where dept_name in (&quot;人事部&quot;,&quot;财务部&quot;)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select * from employees  where dept_id in (select dept_id from departments where dept_name in (&quot;人事部&quot;,&quot;财务部&quot;));&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查询2018年12月所有比100号员工基本工资高的工资信息
&lt;code&gt;select basic from salary where employee_id =100 and year(date)=2018 and month(date)=12 &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select * from salary where year(date)=2018 and month(date)=12  and basic &amp;gt; (select basic from salary where employee_id =100 and year(date)=2018 and month(date)=12)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查询部门员工总人数比开发部总人数少 的 部门名称和人数&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select dept_id from departments where dept_name =&quot;开发部&quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select count(1) from employees  where dept_id = (select dept_id from departments where dept_name =&quot;开发部&quot;);&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select dept_id,count(1) total from employees where  dept_id is not null group by dept_id having total &amp;lt; (select count(1) from employees  where dept_id = (select dept_id from departments where dept_name =&quot;开发部&quot;)); &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查询3号部门 、部门名称 及其部门内 员工的编号、名字 和 email&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select   dept_name,employee_id,name,email from ( select dept_name,e.* from employees e inner join departments d on e.dept_id=d.dept_id ) tmp_table where dept_id=3 &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查询每个部门的人数： dept_id dept_name 部门人数
&lt;code&gt;select count(1) from employees where dept_id= ? &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select *,(select count(1) from employees where dept_id= d.dept_id)  部门人数  from departments d ; &lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;五、表结构管理&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;drop database&lt;/code&gt; 数据库名&lt;/p&gt;
&lt;p&gt;总结
建库的时候要加 &lt;code&gt;if not exists&lt;/code&gt;
删除的时候要加 &lt;code&gt; if exists&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;字段熟悉
名字，类型，长度，约束，默认值
&lt;code&gt;char(11)&lt;/code&gt;  是固定长度   a
&lt;code&gt;varchar(100)&lt;/code&gt;  不固定长度  a&lt;/p&gt;
&lt;p&gt;修改表
&lt;code&gt;alter table  表名&lt;/code&gt;
&lt;code&gt;rename 重命名&lt;/code&gt;
&lt;code&gt;drop 字段名&lt;/code&gt;
&lt;code&gt;add  字段名 &lt;/code&gt;
&lt;code&gt;after  字段名 在某个字段后面添加&lt;/code&gt;
&lt;code&gt;modify  修改字段熟悉&lt;/code&gt;
&lt;code&gt;change  改表头的名字&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;复制表
&lt;code&gt;create table 表名  select * from 表名&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;如何看建表语句
&lt;code&gt;desc  查看表结构&lt;/code&gt;
&lt;code&gt;show create table t2&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;数值类型
整形
&lt;code&gt;tinyint unsigned&lt;/code&gt; 最大255  可以是小数，四舍五入取整
&lt;code&gt;int&lt;/code&gt;
&lt;code&gt;long&lt;/code&gt;    长整形
&lt;code&gt;bigint&lt;/code&gt;  超长整形
浮点&lt;/p&gt;
&lt;p&gt;枚举类型
&lt;code&gt;enum  单项&lt;/code&gt;
&lt;code&gt;set  多选&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;时间日期类型
&lt;code&gt;date  日期&lt;/code&gt;
&lt;code&gt;time  时间&lt;/code&gt;
&lt;code&gt;datetime  日期时间&lt;/code&gt;
&lt;code&gt;year  年份&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;primary key  主键&lt;/code&gt;
&lt;code&gt;auto_increment 自增长&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;六、主键外键索引&lt;/h1&gt;
&lt;p&gt;255.255.255.255&lt;/p&gt;
&lt;p&gt;&lt;code&gt;truncate&lt;/code&gt; 删除数据，会把AUTO_INCREMENT设置为1&lt;/p&gt;
&lt;p&gt;&lt;code&gt;explain&lt;/code&gt;  执行计划，用来验证一个sql语句有没有用到索引&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;七、数据导入导出与用户管理&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;grant 权限  on   库.表  to  用户&lt;/code&gt;
&lt;code&gt;all&lt;/code&gt;  拥有所有权限
&lt;code&gt;*.*&lt;/code&gt;  所有库所有表
&lt;code&gt;数据库名.*&lt;/code&gt;  某个库的所有表
&lt;code&gt;数据库名.表名&lt;/code&gt; ：针对某个有权限&lt;/p&gt;
&lt;p&gt;&lt;code&gt;revoke&lt;/code&gt; 撤销权限
通过管理员去修改普通用户的密码
&lt;code&gt;set password for  用户=&quot;密码&quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;drop:&lt;/code&gt;  删除用户，删除表，删除数据库，删除表中字段&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;八、备份和恢复&lt;/h1&gt;
&lt;p&gt;优点：灵活
&lt;code&gt;mysqldump&lt;/code&gt; 主要是把数据导出成一个sql脚本
针对某一个表  &lt;code&gt;mysqldump  库名  表1 表2 &amp;gt;  xxx.sql&lt;/code&gt;
针对某一个库  &lt;code&gt;mysqldump -B  库1 库2 &amp;gt;  xxx.sql&lt;/code&gt;
针对所有库   &lt;code&gt;mysqldump -A  &amp;gt;  xxx.sql&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysqldump【mysql-当普】 备份和恢复数据时会锁表，锁表期间无法对表做写访问
mysqldump【mysql-当普】适合备份数据量比较小的数据或在数据库服务器访问量少的时候备份。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;增量备份
当前的备份是基于上一次备份做增量的备份
一般第一次备份要完全备份
第一次：全量--&amp;gt;增加了a
第二次:  备份a---&amp;gt;增加了b
第三次:  备份b---&amp;gt;增加了c
第四次:  备份c---&amp;gt;增加了d
增量备份做数据恢复
全量&amp;lt;---备份a
全量&amp;lt;---备份b
全量&amp;lt;---备份c
最终 全量(abc)&lt;/p&gt;
&lt;p&gt;差异备份
当前的备份是基于第一次备份做增量的备份
一般第一次备份要完全备份
第一次：全量--&amp;gt;增加了a
第二次:  备份a---&amp;gt;增加了b
第三次:  备份ab---&amp;gt;增加了c
第四次:  备份abc---&amp;gt;增加了d
全量&amp;lt;--备份abc
最终 全量(abc)&lt;/p&gt;
&lt;p&gt;增量备份&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;定义：增量备份只备份自上一次备份（无论是完全备份、增量备份还是差异备份）以来发生变化的数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;工作原理：首先需要一个完整的备份（基础备份），然后每次增量备份都只备份相对于上一次备份后变化的数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;优点：备份速度快，占用空间小，因为每次只备份变化的数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;缺点：恢复数据时，需要先恢复完整备份，然后按照时间顺序依次恢复所有的增量备份，直到指定的时间点。恢复过程复杂且耗时，如果中间任何一个备份损坏，可能导致整个恢复链失效。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;适用场景：数据量大，备份窗口短，但对恢复时间要求不高的场景。&lt;/p&gt;
&lt;p&gt;当前的备份是基于上一次备份做增量的备份
一般第一次备份要完全备份
第一次：全量--&amp;gt;增加了a
第二次:  备份a---&amp;gt;增加了b
第三次:  备份b---&amp;gt;增加了c
第四次:  备份c---&amp;gt;增加了d&lt;/p&gt;
&lt;p&gt;增量备份做数据恢复
全量&amp;lt;---备份a
全量&amp;lt;---备份b
全量&amp;lt;---备份c
最终 全量(abc)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;差异备份&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;定义：差异备份备份自上一次完整备份以来所有发生变化的数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;工作原理：首先需要一个完整备份，然后每次差异备份都会备份自上次完整备份以来所有变化的数据。因此，第二次差异备份会包含第一次差异备份的内容，第三次会包含第一次和第二次的内容，以此类推。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;优点：恢复时只需要完整备份和最近一次的差异备份，恢复过程相对简单。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;缺点：随着时间推移，差异备份的大小会越来越大，因为每次都要备份自完整备份以来的所有变化。备份时间可能会逐渐增加。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;适用场景：数据量变化不大，且希望恢复过程相对简单的场景。&lt;/p&gt;
&lt;p&gt;当前的备份是基于第一次备份做增量的备份
一般第一次备份要完全备份
第一次：全量--&amp;gt;增加了a
第二次:  备份a---&amp;gt;增加了b
第三次:  备份ab---&amp;gt;增加了c
第四次:  备份abc---&amp;gt;增加了d
全量&amp;lt;--备份abc
最终 全量(abc)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对比总结：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;备份内容：增量备份只备份上一次备份后的变化，而差异备份备份自上次完整备份后的所有变化。&lt;/li&gt;
&lt;li&gt;备份空间和速度：增量备份占用空间小，速度快；差异备份随着时间推移，占用空间和备份时间都会增加。&lt;/li&gt;
&lt;li&gt;恢复过程：增量恢复需要完整备份和所有增量备份，步骤多，易出错；差异恢复只需要完整备份和最近一次差异备份，相对简单。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;PERCONA【帕扣娜】 xtrabackup【xtra-拜克阿普】是一款强大的在线热备份工具，备份过程中不锁库表，适合生产环境。支持完全备份与恢复、增量备份与恢复、差异备份与恢复。&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;九、数据库主从同步&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;   create database db1;      create table db1.user(name char(10));         insert into db1.user values(&quot;jim&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;157------------------------339--------------------------------------------535---------------------------------------809&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;10、数据库读写分离&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;mycat&lt;/code&gt; 本身一个Java应用程序
需要Java运行的环境
&lt;code&gt;jdk&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;如果mycat启动失败，可以参考
&lt;code&gt;https://blog.csdn.net/weixin_46897073/article/details/120678560&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;11、数据库分库分表&lt;/h1&gt;
&lt;p&gt;分表的策略
垂直分表（不需要技术含量，会涉及到原来代码修改）
50列，把一些表头拆分另外一张表
拆分的表跟原表做关联关系
水平分表（需要技术来实现）
一张表（500万），现在数据远超过了500万&lt;/p&gt;
&lt;p&gt;平摊
user1  （id%3=0）
user2   （id%3=1）
user3  （id%3=2）&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;12、redis数据类型&lt;/h1&gt;
&lt;p&gt;字符串类型
新增数据
&lt;code&gt;set   key   value&lt;/code&gt;
查询数据
&lt;code&gt;get  key&lt;/code&gt;
批量新增
&lt;code&gt;mset key1  value1  key2  value2  key3  value3...&lt;/code&gt;
批量获取
&lt;code&gt;mget  key1  key2  key3...&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;有效期
&lt;code&gt; px(毫秒) ex (秒)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;不存在就是写入
&lt;code&gt;NX&lt;/code&gt;
覆盖
&lt;code&gt;XX&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;递增
&lt;code&gt;incr  key&lt;/code&gt;  每次+1
&lt;code&gt;incrby key  n&lt;/code&gt;   每次+n
递减
&lt;code&gt;decr key&lt;/code&gt;  每次-1
&lt;code&gt;decrby key   n&lt;/code&gt;   每次-n&lt;/p&gt;
&lt;p&gt;尾部追加或者拼接
&lt;code&gt;append key &quot; 值&quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;strlen key&lt;/code&gt; 求长度&lt;/p&gt;
&lt;p&gt;求范围
&lt;code&gt;0123456&lt;/code&gt;
&lt;code&gt;ABCDEF&lt;/code&gt;
&lt;code&gt;-7-6-5-4-3-2-1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;keys&lt;br /&gt;
&lt;code&gt;*&lt;/code&gt;  任意
&lt;code&gt;?&lt;/code&gt;  一个代表一个字符&lt;/p&gt;
&lt;p&gt;&lt;code&gt;redis&lt;/code&gt; 默认就有16个数据库
&lt;code&gt;0-15&lt;/code&gt;
默认0号库
&lt;code&gt;select 选择数据库&lt;/code&gt;
数据库之间有隔离性&lt;/p&gt;
&lt;p&gt;&lt;code&gt;move  key&lt;/code&gt; 把某一个key移动到其他库&lt;/p&gt;
&lt;p&gt;&lt;code&gt;exists&lt;/code&gt;  判断一个key是否存在
&lt;code&gt;1&lt;/code&gt;  存在
&lt;code&gt;0&lt;/code&gt;  不存在&lt;/p&gt;
&lt;p&gt;先有&lt;code&gt;key&lt;/code&gt;, 后设置过期时间
&lt;code&gt;expire&lt;/code&gt;
&lt;code&gt;ttl&lt;/code&gt;  查看一个数据存储剩余时间
&lt;code&gt;-1&lt;/code&gt;  永久不过期
&lt;code&gt;-2&lt;/code&gt;  已经过期或者不存在
正数：剩余的时间&lt;/p&gt;
&lt;p&gt;&lt;code&gt;type&lt;/code&gt;  查看某个key是属于哪个数据类型&lt;/p&gt;
&lt;p&gt;&lt;code&gt;del  key1 key2...&lt;/code&gt; 删除一个key&lt;/p&gt;
&lt;p&gt;&lt;code&gt;flushdb&lt;/code&gt; 删除本库的所有的key&lt;/p&gt;
&lt;p&gt;&lt;code&gt;flushall&lt;/code&gt; 删除所有库的key&lt;/p&gt;
&lt;p&gt;&lt;code&gt;list&lt;/code&gt;数据类型
&lt;code&gt;lpush&lt;/code&gt;  存放数据，从左往右放数据
&lt;code&gt;llen&lt;/code&gt;  求数据库数量
&lt;code&gt;lindex&lt;/code&gt;  下标  获取某个下标的值
&lt;code&gt;lrange&lt;/code&gt; 根据下标范围取出数据
&lt;code&gt;lset&lt;/code&gt;  根据下标修改数据&lt;/p&gt;
&lt;p&gt;&lt;code&gt;lpush&lt;/code&gt; 看做生产者
&lt;code&gt;lpop&lt;/code&gt;  看做消费者&lt;/p&gt;
&lt;p&gt;&lt;code&gt;rpush&lt;/code&gt; 存放数据，从右往左放数据
&lt;code&gt;linsert&lt;/code&gt;  插入&lt;/p&gt;
&lt;p&gt;散列类型&lt;/p&gt;
&lt;p&gt;&lt;code&gt;key : {k1:v1,k2:v2,k3:v3}&lt;/code&gt;
&lt;code&gt;stu1:{name:张三，age: 12,  class: yjs1}&lt;/code&gt;
&lt;code&gt;stu2:{name:李四,   age:16,  class: yjs2}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;hset user1 name zs  age 15&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;获取数据
&lt;code&gt;hget&lt;/code&gt; 只能获取一个
&lt;code&gt;hmget&lt;/code&gt; 获取多个
&lt;code&gt;hdel&lt;/code&gt;  删除一个元素
&lt;code&gt;hlen&lt;/code&gt;  获取个数&lt;/p&gt;
&lt;p&gt;集合
无序集合
&lt;code&gt;sadd&lt;/code&gt; 向集合中添加元素
&lt;code&gt;smembers&lt;/code&gt; 列出集合的元素
&lt;code&gt;sismember key&lt;/code&gt; 元素，判断一个元素是否存在，存1  不存在0
&lt;code&gt;scard&lt;/code&gt; 获取原生的个数&lt;/p&gt;
&lt;p&gt;集合运算
交集 &lt;code&gt;sinter&lt;/code&gt;
差集 &lt;code&gt;sdiff&lt;/code&gt;
合集  &lt;code&gt;sunion&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;srandmember&lt;/code&gt;  随机获取元素&lt;/p&gt;
&lt;p&gt;有序集合
&lt;code&gt;key:  数字1 字符串1     数字2 字符串2 ...&lt;/code&gt;
数字1作用用来区分大小 ，通过数字来排序，只有能排序才称之为有序
&lt;code&gt;zadd&lt;/code&gt;  添加集合元素
&lt;code&gt;zcard&lt;/code&gt; 统计个数
&lt;code&gt;zrange&lt;/code&gt;  根据下标获取数据
&lt;code&gt;withscores&lt;/code&gt;  显示数值
&lt;code&gt;zrangebyscore&lt;/code&gt;  根据数值范围获取数据
&lt;code&gt;zincrby&lt;/code&gt;  增加数值
&lt;code&gt;zcount&lt;/code&gt;  根据数值范围求个数
&lt;code&gt;zrem&lt;/code&gt;  删除一个元素
&lt;code&gt;zrank&lt;/code&gt;  获取排名  升序排列
&lt;code&gt;zrevrank&lt;/code&gt;  获取排名  降序排列&lt;/p&gt;
&lt;h1&gt;13、redis集群&lt;/h1&gt;
&lt;p&gt;RDB持久化
&lt;code&gt;#save 3600 1&lt;/code&gt;   3600秒时，这个只有1条数据更新，才去保存到磁盘中
&lt;code&gt;#save 300 100&lt;/code&gt;   300秒时，有100条数据更新， 去保存到磁盘中
&lt;code&gt;#save 60 10000&lt;/code&gt;   60秒时， 有1万条数据更新， 去保存到磁盘中&lt;/p&gt;
&lt;p&gt;如果你在1分钟出现500条数据，这个要到300秒的时候才去保存，
如果在1分钟到5分钟之间出现了宕机故障，这500条数据可能会丢失
RDB持久化，不是实时保存，有间隔性的保存，实时保存会降低性能
优点，性能高
缺点，很难保证数据不丢失&lt;/p&gt;
&lt;p&gt;&lt;code&gt;save 120 10&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;通过正规的方式停止服务，会做一次持久化
&lt;code&gt;systemctl stop redis&lt;/code&gt; --&amp;gt;会产生rdb文件
&lt;code&gt;poweroff --&amp;gt; systemctl stop redis&lt;/code&gt; --&amp;gt;会产生rdb文件&lt;/p&gt;
&lt;p&gt;&lt;code&gt;systemctl start redis&lt;/code&gt;--&amp;gt;读取rdb文件---&amp;gt;内存&lt;/p&gt;
&lt;p&gt;AOF文件
redis命令（增删改的命令）类似于mysql的binlog
实时去写日志，一般情况是不会丢数据库。性能低
恢复数据的时候，去重新执行AOF中的命令。恢复比较慢
默认情况下是不开启AOF
&lt;code&gt;config set appendonly yes  开启AOF&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;通过命令的方式去修改redis配置是不需要重启服务的&lt;/p&gt;
&lt;p&gt;分片高可用集群
默认最少6台机器
优点：能实现高可用集群方案，可以自主切换主从，从节点可以升级从为主。
缺点：需要的服务器比较多，造成服务器的成本增加&lt;/p&gt;
&lt;p&gt;自定义主从结构
优点：介绍成本，配置灵活，实现了读写分离，提高性能
缺点：当主服务宕机了，不能实现写数据库，无法保证高可用，从节点不能升级为主&lt;/p&gt;
&lt;p&gt;哨兵服务主从结构
优点：能实现高可用集群方案，通过哨兵监控，从节点可以升级从为主。
缺点：如果哨兵是一台，哨兵存在单节点故障，如果哨兵部署多台，增加成本，主从切换需要延迟，在延迟的时候出现数据不一致。&lt;/p&gt;
</content:encoded></item><item><title>数据库和监控平台</title><link>https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/</guid><description>目录 - 运维知识库笔记</description><pubDate>Wed, 03 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1&gt;01：mysql之基础&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111219491.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;咱公司最近业务拓展，新入职了好多员工。HR部门要管理员工信息、部门信息和工资信息，财务部门每月得核算工资，老板也想随时了解各部门的人力成本。之前用 Excel 管理，数据多了又乱又容易出错。现在打算用 MySQL 数据库来管理这些数据。但大家都是小白，得先学会 MySQL 安装、密码管理、图形化软件安装，还得会用单表查询、日期函数、聚集函数、case 函数，才能从员工表、部门表、工资表中获取想要的信息，解决工作中的难题。&lt;/p&gt;
&lt;h2&gt;二、为什么学mysql数据库&lt;/h2&gt;
&lt;p&gt;为啥要学这些东西呢？想象一下，要是不会 MySQL 安装，就没办法搭建数据库来管理公司的员工、部门和工资信息，那还不得乱成一锅粥。密码管理也很重要，要是密码泄露，公司的重要数据就可能被坏人拿走，损失可就大了。图形化软件能让操作更简单，就像玩游戏一样轻松。单表查询能让你快速找到需要的数据，日期函数可以处理和日期相关的信息，聚集函数能帮你统计数据，case 函数能根据不同条件输出不同结果。学会这些，工作效率蹭蹭往上涨，升职加薪不是梦！&lt;/p&gt;
&lt;h2&gt;三、构建mysql服务器&lt;/h2&gt;
&lt;p&gt;当前任务环节
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111120724.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3.1 安装mysql服务&lt;/h3&gt;
&lt;p&gt;1)准备1台虚拟机，要求如下：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;192.168.90.50&lt;/td&gt;
&lt;td&gt;mysql50&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;2)配置IP地址和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection modify ens160 ipv4.addresses 192.168.90.50/24 autoconnect yes
参数详解​​：
* nmcli：NetworkManager 的命令行工具，用于管理网络连接
* connection modify：修改现有网络连接的配置
* ens160：网络接口的名称（通常是以太网接口）
* ipv4.addresses 192.168.90.50/24：
    * 设置 IPv4 地址为 192.168.90.50
    * 子网掩码为 255.255.255.0（/24表示前24位是网络位）
    * autoconnect yes：设置系统启动时自动连接此网络接口
* ​​效果​​：将 ens160网络接口配置为使用静态 IP 地址 192.168.90.50，并确保系统重启后自动启用该连接。

[root@localhost ~]# nmcli connection up ens160
参数详解​​：
* connection up：激活指定的网络连接
* ens160：要激活的网络接口名称
* ​​效果​​：立即应用对 ens160接口的配置更改，使新的 IP 地址生效。相当于重启网络服务或启用网络接口。

[root@mysql50 ~]# hostnamectl set-hostname mysql50
​参数详解​​：
* hostnamectl：系统主机名管理工具
* set-hostname：设置新的主机名
* mysql50：新的主机名称
* ​​效果​​：将系统的主机名永久更改为 mysql50。主机名用于在网络中标识该系统。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3)安装mysql-server服务软件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# yum -y install mysql-server
[root@mysql50 ~]# rpm -q mysql-server
mysql-server-8.0.41-2.el9_5.x86_64

#启动服务
root@mysql50 ~]# # systemctl【西斯屯-ctl】
 start【s 达儿】 mysqld
[root@mysql50 ~]# # systemctl【西斯屯-ctl】
 enable【ing 内 步】 mysqld

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4)查看端口&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# ss -utnlp  | grep 【哥瑞普】 3306  #查看端口
tcp   LISTEN 0      70                 *:33060            *:*    users:((&quot;mysqld&quot;,pid=21912,fd=22))
tcp   LISTEN 0      128                *:3306             *:*    users:((&quot;mysqld&quot;,pid=21912,fd=25))
[root@mysql50 ~]# 
或
[root@mysql50 ~]# netstat【劣 s 塔】  -utnlp  | grep 【哥瑞普】  mysqld   #仅查看mysqld进程
tcp6       0      0 :::33060   :::*      LISTEN      21912/mysqld        
tcp6       0      0 :::3306    :::*     LISTEN      21912/mysqld        
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;选项&lt;/th&gt;
&lt;th&gt;含义&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;-t(--tcp)&lt;/td&gt;
&lt;td&gt;显示 TCP 连接&lt;/td&gt;
&lt;td&gt;过滤只显示 TCP 协议的网络连接&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-u(--udp)&lt;/td&gt;
&lt;td&gt;显示 UDP 连接&lt;/td&gt;
&lt;td&gt;过滤只显示 UDP 协议的网络连接&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-n(--numeric)&lt;/td&gt;
&lt;td&gt;数字格式显示&lt;/td&gt;
&lt;td&gt;不解析主机名和服务名，直接显示 IP 和端口号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-l(--listening)&lt;/td&gt;
&lt;td&gt;只显示监听端口&lt;/td&gt;
&lt;td&gt;只显示正在监听的套接字（服务端）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-p(--processes)&lt;/td&gt;
&lt;td&gt;显示进程信息&lt;/td&gt;
&lt;td&gt;显示使用该端口的进程信息&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;说明：&lt;/p&gt;
&lt;p&gt;MySQL 8中的3306端口是MySQL服务默认使用的端口，主要用于建立客户端与MySQL服务器之间的连接。&lt;/p&gt;
&lt;p&gt;MySQL 8中的33060端口是MySQL Shell默认使用的管理端口，主要用于执行各种数据库管理任务。远程管理MySQL服务器：使用MySQL Shell连接到MySQL服务，并在远程管理控制台上执行各种数据库管理操作，例如创建、删除、备份和恢复数据库等。&lt;/p&gt;
&lt;h3&gt;3.2 连接服务&lt;/h3&gt;
&lt;p&gt;说明： 数据库管理员本机登陆默认没有密码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version【沃申】: 8.0.41 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 &apos;help;&apos; or &apos;\h&apos; for help. Type &apos;\c&apos; to clear the current input statement.

mysql&amp;gt;
mysql&amp;gt; exit【诶西特】
Bye
[root@mysql50 ~]#

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3 mysql必备命令&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 version【沃申】() ;  //查看数据库软件版本
+------------------+
| version【沃申】() |
+------------------+
| 8.0.41           |
+------------------+
1 row in set (0.00 sec)
mysql&amp;gt; select【涩莱克特】 user() ; //查看登陆的用户和客户端地址 
+----------------+
| user()         |
+----------------+
| root@localhost | 管理员root本机登陆
+----------------+
1 row in set (0.00 sec) 
mysql&amp;gt; show【瘦】 databases;【得塔-贝斯】 //查看已有的库
+----------------------------------------------+
| Database【得塔-贝斯】                         |
+----------------------------------------------+
| information【因弗梅申】_schema【斯京(白话)磨】  |
| mysql                                        |
| performance【破佛曼斯】_schema【斯京(白话)磨】  |
| sys                                          |
+----------------------------------------------+
4 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;说明：&lt;/p&gt;
&lt;p&gt;默认4个库 不可以删除，存储的是 服务运行时加载的不同功能的程序和数据。&lt;/p&gt;
&lt;p&gt;information【因弗梅申】_schema【斯京(白话)磨】：是MySQL数据库提供的一个虚拟的数据库，存储了MySQL数据库中的相关信息，比如数据库、表、列、索引、权限、角色等信息。它并不存储实际的数据，而是提供了一些视图和存储过程，用于查询和管理数据库的元数据信息。&lt;/p&gt;
&lt;p&gt;mysql：存储了MySQL服务器的系统配置、用户、账号和权限信息等。它是MySQL数据库最基本的库，存储了MySQL服务器的核心信息。&lt;/p&gt;
&lt;p&gt;performance【破佛曼斯】_schema【斯京(白话)磨】】：存储了MySQL数据库的性能指标、事件和统计信息等数据，可以用于性能分析和优化。&lt;/p&gt;
&lt;p&gt;sys：是MySQL 8.0引入的一个新库，它基于 information【因弗梅申】_schema【斯京(白话)磨和performance【破佛曼斯】_schema【斯京(白话)磨】视图，提供了更方便、更直观的方式来查询和管理MySQL数据库的元数据和性能数据。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 database();【得塔-贝斯】  //查看当前在那个库里  null【nò】 表示没有在任何库里
+------------+
| database() |【得塔-贝斯】
+------------+
| NULL【nò】       |
+------------+
1 row in set (0.00 sec)
mysql&amp;gt; use mysql ; //切换到mysql库
mysql&amp;gt; select【涩莱克特】 database();【得塔-贝斯】  // 再次显示所在的库
+------------+
| database() |【得塔-贝斯】
+------------+
| mysql      |
+------------+
1 row in set (0.00 sec)
mysql&amp;gt; show【瘦】 tables;【忒-部s】  //显示库里已有的表
+------------------------------------------------------+
| Tables【忒-部s】_in_mysql                             |
+------------------------------------------------------+
| columns_priv                                         |
| component                                            |
| db                                                   |
| default_roles                                        |
| engine_cost                                          |
| func                                                 |
| general_log                                          |
| global_grants                                        |
| gtid_executed                                        |
| help_category                                        |
| help_keyword                                         |
| help_relation                                        |
| help_topic                                           |
| innodb_index_stats                                   |
| innodb_table【忒-部】_stats                           |
| password_history                                     |
| plugin                                               |
| procs_priv                                           |
| proxies_priv                                         |
| replication_asynchronous_connection_failover         |
| replication_asynchronous_connection_failover_managed |
| replication_group_configuration_version【沃申】       |
| replication_group_member_actions                     |
| role_edges                                           |
| server_cost                                          |
| servers                                              |
| slave_master_info                                    |
| slave_relay_log_info                                 |
| slave_worker_info                                    |
| slow_log                                             |
| tables【忒-部s】_priv                                 |
| time_zone                                            |
| time_zone_leap_second                                |
| time_zone_name                                       |
| time_zone_transition                                 |
| time_zone_transition_type                            |
| user                                                 |
+------------------------------------------------------+
37 rows in set (0.00 sec)
mysql&amp;gt; exit【诶西特】 ;  #断开连接
Bye
[root@mysql50 ~]#  
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、密码管理&lt;/h2&gt;
&lt;p&gt;当前任务环节
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111321233.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;4.1 问题&lt;/h3&gt;
&lt;p&gt;1） 在192.168.90.50主机做如下练习：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;设置root密码为moershi&lt;/li&gt;
&lt;li&gt;修改root密码为123qqq…A&lt;/li&gt;
&lt;li&gt;破解root密码为NSD123456…a&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;4.2 步骤&lt;/h3&gt;
&lt;p&gt;实现此案例需要按照如下步骤进行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;步骤一：设置root密码为moershi&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;p&gt;2行输出是警告而已不用关心&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# mysqladmin  -uroot -p  password &quot;moershi&quot;
Enter password: //敲回车
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@mysql50 ~]#
[root@mysql50 ~]# mysql //无密码连接被拒绝
ERROR 1045 (28000): Access denied for user &apos;root&apos;@&apos;localhost&apos; (using password: NO)
[root@mysql50 ~]#
[root@mysql50 ~]# mysql -uroot –pmoershi  //连接时输入密码
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 &apos;help;&apos; or &apos;\h&apos; for help. Type &apos;\c&apos; to clear the current input statement.
mysql&amp;gt; 登陆成功
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤二：修改root密码为123qqq…A&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# mysqladmin  -uroot -pmoershi password &quot;123qqq...A&quot;  //修改密码
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@mysql50 ~]#
[root@mysql50 ~]# mysql -uroot –pmoershi //旧密码无法登陆
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user &apos;root&apos;@&apos;localhost&apos; (using password: YES)
[root@mysql50 ~]#
[root@mysql50 ~]# mysql -uroot -p123qqq...A  //新密码登陆
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 18
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 &apos;help;&apos; or &apos;\h&apos; for help. Type &apos;\c&apos; to clear the current input statement.
mysql&amp;gt; 登陆成功
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤三：破解root密码为NSD123456…a&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;说明：在mysql50主机做此练习&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# mysql -uroot -pNSD123456...a  //破解前登陆失败
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user &apos;root&apos;@&apos;localhost&apos; (using password: YES)
[root@mysql50 ~]#
[root@mysql50 ~]# vim /etc/my.cnf.d/mysql-server.cnf  //修改主配置文件
[mysqld]
skip-grant-tables【忒-部s】  //手动添加此行 作用登陆时不验证密码
:wq
[root@mysql50 ~]#
[root@mysql50 ~]# # systemctl【西斯屯-ctl】   restart【 率 s 达r】 mysqld //重启服务 作用让服务以新配置运行
[root@mysql50 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# 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 &apos;help;&apos; or &apos;\h&apos; for help. Type &apos;\c&apos; to clear the current input statement.
//查看存放密码的表头名
Mysql&amp;gt; 
Mysql&amp;gt; desc  mysql.user ;
//把mysql库下user表中 用户root的密码设置为无；
Mysql&amp;gt; 
mysql&amp;gt; update mysql.user set authentication_string=&quot;&quot; where【威尔】 user=&quot;root&quot;;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1  Changed: 1  Warnings: 0
Mysql&amp;gt; 
mysql&amp;gt; exit【诶西特】; 断开连接
Bye
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]#
[root@mysql50 ~]# vim  /etc/my.cnf.d/mysql-server.cnf  编辑配置文件
[mysqld]
#skip-grant-tables【忒-部s】   //注释添加的行
:wq
[root@mysql50 ~]#
[root@mysql50 ~]# # systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld //重启服务 作用让注释生效
[root@mysql50 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[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 &apos;help;&apos; or &apos;\h&apos; for help. Type &apos;\c&apos; to clear the current input statement.
//设置root用户本机登陆密码
Mysql&amp;gt; 
mysql&amp;gt; alter user root@&quot;localhost&quot; identified by &quot;NSD123456...a&quot;;
Query OK, 0 rows affected (0.00 sec)
Mysql&amp;gt; 
mysql&amp;gt; exit【诶西特】 断开连接
Bye
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]#
[root@localhost ~]# mysql  不输密码无法登陆
ERROR 1045 (28000): Access denied for user &apos;root&apos;@&apos;localhost&apos; (using password: NO)
[root@mysql50 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# mysql -uroot -pNSD123456...a  使用破解的密码登陆
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 10
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 &apos;help;&apos; or &apos;\h&apos; for help. Type &apos;\c&apos; to clear the current input statement.
mysql&amp;gt;
mysql&amp;gt; #登陆成功
Mysql&amp;gt; 
mysql&amp;gt; show【瘦】 databases;【得塔-贝斯】 查看已有的库
+----------------------------------------------+
| Database【得塔-贝斯】                          |
+----------------------------------------------+
|  information【因弗梅申】_schema【斯京(白话)磨】 |
| mysql                                        |
| performance【破佛曼斯】_schema【斯京(白话)磨】  |
| sys                                          |
+----------------------------------------------+
4 rows in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、筛选条件&lt;/h2&gt;
&lt;p&gt;当前任务环节
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111300101.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;5.1导入数据&lt;/h3&gt;
&lt;p&gt;拷贝moershi.sql文件到mysql50主机里，然后使用moershi.sql创建练习使用的数据。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//恢复数据
[root@mysql50 ~]# mysql -uroot  -pNSD123456...a &amp;lt; /root/moershi.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
//连接服务
[root@mysql50 ~]# mysql -uroot  -pNSD123456...a
mysql&amp;gt; 
mysql&amp;gt; show【瘦】 databases;【得塔-贝斯】 //查看库
+----------------------------------------------+
| Database【得塔-贝斯】                         |
+----------------------------------------------+
|  information【因弗梅申】_schema【斯京(白话)磨】 |
| mysql                                        |
| performance【破佛曼斯】_schema【斯京(白话)磨】  |
| sys                                          |
| moershi                                      | 恢复的库
+----------------------------------------------+
5 rows in set (0.00 sec)
mysql&amp;gt; 
mysql&amp;gt; use moershi; //进入库
Reading table【忒-部】 information【因弗梅申】 for completion of table【忒-部】 and column names
You can turn off this feature to get a quicker startup【s 达 啊普】 with -A
Database【得塔-贝斯】 changed
mysql&amp;gt; 
mysql&amp;gt; show【瘦】 tables;【忒-部s】  //查看表
+------------------+
| Tables【忒-部s】_in_moershi |
+------------------+
| departments      | 部门表
| employees        | 员工表
| salary           | 工资表
| user             | 用户表
+------------------+
4 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 使用user 表做查询练习&lt;/h3&gt;
&lt;p&gt;user表里存储的是 系统用户信息( 就是 /etc/passwd 文件的内容)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; desc moershi.user;  //查看表头
+----------+-------------+------+-----+----------------+----------------+
| Field    | Type        | Null【nò】 | Key | Default | Extra          |
+----------+-------------+------+-----+----------------+----------------+
| id       | int(11)     | NO   | PRI | NULL【nò】    | auto_increment |行号
| name     | char(20)    | YES  |     | NULL【nò】    |                |用户名
| password | char(1)     | YES  |     | NULL【nò】    |                |密码占位符
| uid      | int(11)     | YES  |     | NULL【nò】    |                | uid号
| gid      | int(11)     | YES  |     | NULL【nò】    |                | gid号
| comment  | varchar(50) | YES  |     | NULL【nò】    |                | 描述信息
| homedir  | varchar(80) | YES  |     | NULL【nò】    |                | 家目录
| shell    | char(30)    | YES  |     | NULL【nò】    |                | 解释器
+----------+-------------+------+-----+----------------+----------------+
8 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.3 select【涩莱克特】命令格式演示&lt;/h3&gt;
&lt;p&gt;语法格式1 select【涩莱克特】 字段列表 FROM【弗乱】 库名.表名;&lt;/p&gt;
&lt;p&gt;语法格式2 select【涩莱克特】 字段列表 FROM【弗乱】 库名.表名 where【威尔】 筛选条件;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 name from【弗乱】  moershi.user;        //查看一个表头
+-----------------+
| name            |
+-----------------+
| root            |
| bin             |
| daemon          |
| adm             |
| lp              |
| sync            |
| shutdown        |
| halt            |
| mail            |
| operator        |
| games           |
| ftp             |
| nobody          |
| systemd-network |
| dbus            |
| polkitd         |
| sshd            |
| postfix         |
| chrony          |
| rpc             |
| rpcuser         |
| nfsnobody       |
| haproxy         |
| plj             |
| apache          |
| mysql           |
| bob             |
+-----------------+
27 rows in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 name ,uid from【弗乱】  moershi.user;    //查看多个表头
+-----------------+-------+
| name            | uid   |
+-----------------+-------+
| root            |     0 |
| bin             |     1 |
| daemon          |     2 |
| adm             |     3 |
| lp              |     4 |
| sync            |     5 |
| shutdown        |     6 |
| halt            |     7 |
| mail            |     8 |
| operator        |    11 |
| games           |    12 |
| ftp             |    14 |
| nobody          |    99 |
| systemd-network |   192 |
| dbus            |    81 |
| polkitd         |   999 |
| sshd            |    74 |
| postfix         |    89 |
| chrony          |   998 |
| rpc             |    32 |
| rpcuser         |    29 |
| nfsnobody       | 65534 |
| haproxy         |   188 |
| plj             |  1000 |
| apache          |    48 |
| mysql           |    27 |
| bob             |  NULL【nò】 |
+-----------------+-------+
27 rows in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 *  from【弗乱】  moershi.user;        //查看所有表头
+----+-----------------+----------+-------+-------+----------------------------+--------------------+----------------+
| id | name            | password | uid   | gid   | comment                    | homedir            | shell          |
+----+-----------------+----------+-------+-------+----------------------------+--------------------+----------------+
|  1 | root            | x        |     0 |     0 | root                       | /root              | /bin/bash      |
|  2 | bin             | x        |     1 |     1 | bin                        | /bin               | /sbin/nologin  |
|  3 | daemon          | x        |     2 |     2 | daemon                     | /sbin              | /sbin/nologin  |
|  4 | adm             | x        |     3 |     4 | adm                        | /var/adm           | /sbin/nologin  |
|  5 | lp              | x        |     4 |     7 | lp                         | /var/spool/lpd     | /sbin/nologin  |
|  6 | sync            | x        |     5 |     0 | sync                       | /sbin              | /bin/sync      |
|  7 | shutdown        | x        |     6 |     0 | shutdown                   | /sbin              | /sbin/shutdown |
|  8 | halt            | x        |     7 |     0 | halt                       | /sbin              | /sbin/halt     |
|  9 | mail            | x        |     8 |    12 | mail                       | /var/spool/mail    | /sbin/nologin  |
| 10 | operator        | x        |    11 |     0 | operator                   | /root              | /sbin/nologin  |
| 11 | games           | x        |    12 |   100 | games                      | /usr/games         | /sbin/nologin  |
| 12 | ftp             | x        |    14 |    50 | FTP User                   | /var/ftp           | /sbin/nologin  |
| 13 | nobody          | x        |    99 |    99 | Nobody                     | /                  | /sbin/nologin  |
| 14 | systemd-network | x        |   192 |   192 | systemd Network Management | /                  | /sbin/nologin  |
| 15 | dbus            | x        |    81 |    81 | System message bus         | /                  | /sbin/nologin  |
| 16 | polkitd         | x        |   999 |   998 | User for polkitd           | /                  | /sbin/nologin  |
| 17 | sshd            | x        |    74 |    74 | Privilege-separated SSH    | /var/empty/sshd    | /sbin/nologin  |
| 18 | postfix         | x        |    89 |    89 |                            | /var/spool/postfix | /sbin/nologin  |
| 19 | chrony          | x        |   998 |   996 |                            | /var/lib/chrony    | /sbin/nologin  |
| 20 | rpc             | x        |    32 |    32 | Rpcbind Daemon             | /var/lib/rpcbind   | /sbin/nologin  |
| 21 | rpcuser         | x        |    29 |    29 | RPC Service User           | /var/lib/nfs       | /sbin/nologin  |
| 22 | nfsnobody       | x        | 65534 | 65534 | Anonymous NFS User         | /var/lib/nfs       | /sbin/nologin  |
| 23 | haproxy         | x        |   188 |   188 | haproxy                    | /var/lib/haproxy   | /sbin/nologin  |
| 24 | plj             | x        |  1000 |  1000 |                            | /home/plj          | /bin/bash      |
| 25 | apache          | x        |    48 |    48 | Apache                     | /usr/share/httpd   | /sbin/nologin  |
| 26 | mysql           | x        |    27 |    27 | MySQL Server               | /var/lib/mysql     | /bin/false     |
| 27 | bob             | NUL【nò】L     |  NULL【nò】 |  NULL【nò】 | NULL【nò】                       | NULL【nò】               | NULL【nò】           |
+----+-----------------+----------+-------+-------+----------------------------+--------------------+----------------+
27 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;加筛选条件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 *  from【弗乱】  moershi.user where【威尔】  name = “root”;        //查找root用户信息 
+----+------+----------+------+------+---------+---------+-----------+
| id | name | password | uid  | gid  | comment | homedir | shell     |
+----+------+----------+------+------+---------+---------+-----------+
|  1 | root | x        |    0 |    0 | root    | /root   | /bin/bash |
+----+------+----------+------+------+---------+---------+-----------+
1 row in set (0.00 sec)
mysql&amp;gt; 
mysql&amp;gt; select【涩莱克特】 *  from【弗乱】  moershi.user where【威尔】  id = 2 ;        //查找第2行用户信息
+----+------+----------+------+------+---------+---------+--------------+
| id | name | password | uid  | gid  | comment | homedir | shell         |
+----+------+----------+------+------+---------+---------+--------------+
|  2 | bin   | x        |    1 |   1   | bin      | /bin   | /sbin/nologin |
+----+------+----------+------+------+---------+---------+--------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.4 练习数值比较&lt;/h3&gt;
&lt;p&gt;比较符号：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;符号&lt;/th&gt;
&lt;th&gt;意义&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;=&lt;/td&gt;
&lt;td&gt;相等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;!=&lt;/td&gt;
&lt;td&gt;不相等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;gt;&lt;/td&gt;
&lt;td&gt;大于&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;gt;=&lt;/td&gt;
&lt;td&gt;大于等于&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt;&lt;/td&gt;
&lt;td&gt;小于&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt;=&lt;/td&gt;
&lt;td&gt;小于等于&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;符号两边要是数字或数值类型的表头 符号左边与符号右边做比较&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//查看第3行的行号、用户名、uid、gid  四个表头的值
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】  id,name,uid,gid  from【弗乱】  moershi.user where【威尔】  id = 3;
+----+--------+------+------+
| id | name   | uid  | gid  |
+----+--------+------+------+
|  3 | daemon |    2 |    2 |
+----+--------+------+------+
1 row in set (0.00 sec)
//查看前2行的行号用户名、uid、gid 四个表头的值
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】  id,name,uid,gid  from【弗乱】  moershi.user where【威尔】  id &amp;lt; 3;
+----+------+------+------+
| id | name | uid  | gid  |
+----+------+------+------+
|  1 | root |    0 |    0 |
|  2 | bin  |    1 |    1 |
+----+------+------+------+
2 rows in set (0.00 sec)
//查看前3行的行号、用户名、uid、gid  四个表头的值
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】  id,name,uid,gid  from【弗乱】  moershi.user where【威尔】  id &amp;lt;= 3;
+----+--------+------+------+
| id | name   | uid  | gid  |
+----+--------+------+------+
|  1 | root   |    0 |    0 |
|  2 | bin    |    1 |    1 |
|  3 | daemon |    2 |    2 |
+----+--------+------+------+
3 rows in set (0.00 sec)
//查看前uid号大于6000的行号、用户名、uid、gid  四个表头的值
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】  id,name,uid,gid  from【弗乱】  moershi.user where【威尔】  uid &amp;gt; 6000;
+----+-----------+-------+-------+
| id | name      | uid   | gid   |
+----+-----------+-------+-------+
| 22 | nfsnobody | 65534 | 65534 |
+----+-----------+-------+-------+
1 row in set (0.00 sec)
//查看前uid号大于等于1000的行号、用户名、uid、gid  四个表头的值
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】  id,name,uid,gid  from【弗乱】  moershi.user where【威尔】  uid &amp;gt;= 1000;
+----+-----------+-------+-------+
| id | name      | uid   | gid   |
+----+-----------+-------+-------+
| 22 | nfsnobody | 65534 | 65534 |
| 24 | plj       |  1000 |  1000 |
+----+-----------+-------+-------+
2 rows in set (0.00 sec)
//查看uid号和gid号相同的行 仅显示行号、用户名、uid、gid  四个表头的值
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】  id,name,uid,gid  from【弗乱】  moershi.user where【威尔】  uid = gid;
+----+-----------------+-------+-------+
| id | name            | uid   | gid   |
+----+-----------------+-------+-------+
|  1 | root            |     0 |     0 |
|  2 | bin             |     1 |     1 |
|  3 | daemon          |     2 |     2 |
| 13 | nobody          |    99 |    99 |
| 14 | systemd-network |   192 |   192 |
| 15 | dbus            |    81 |    81 |
| 17 | sshd            |    74 |    74 |
| 18 | postfix         |    89 |    89 |
| 20 | rpc             |    32 |    32 |
| 21 | rpcuser         |    29 |    29 |
| 22 | nfsnobody       | 65534 | 65534 |
| 23 | haproxy         |   188 |   188 |
| 24 | plj             |  1000 |  1000 |
| 25 | apache          |    48 |    48 |
| 26 | mysql           |    27 |    27 |
+----+-----------------+-------+-------+
15 rows in set (0.00 sec)
//查看uid号和gid号不一样的行 仅显示行号、用户名、uid、gid  四个表头的值
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】  id,name,uid,gid  from【弗乱】  moershi.user where【威尔】  uid != gid;
+----+----------+------+------+
| id | name     | uid  | gid  |
+----+----------+------+------+
|  4 | adm      |    3 |    4 |
|  5 | lp       |    4 |    7 |
|  6 | sync     |    5 |    0 |
|  7 | shutdown |    6 |    0 |
|  8 | halt     |    7 |    0 |
|  9 | mail     |    8 |   12 |
| 10 | operator |   11 |    0 |
| 11 | games    |   12 |  100 |
| 12 | ftp      |   14 |   50 |
| 16 | polkitd  |  999 |  998 |
| 19 | chrony   |  998 |  996 |
+----+----------+------+------+
11 rows in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.5 练习范围匹配&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;in&lt;/td&gt;
&lt;td&gt;（值列表） //在…里&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;not【nuō 特】 in&lt;/td&gt;
&lt;td&gt;（值列表） //不在…里&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;between【B豚ing】&lt;/td&gt;
&lt;td&gt;数字1 and 数字2 //在…之间&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作符&lt;/th&gt;
&lt;th&gt;语法&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;th&gt;返回值说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IN&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name IN (value1, value2, ...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查列值是否在指定的值列表中&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM products WHERE category_id IN (1, 3, 5);&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回 category_id 为 1、3 或 5 的所有产品&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NOT【nuō 特】 IN&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name NOT【nuō 特】 IN (value1, value2, ...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查列值是否不在指定的值列表中&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM users WHERE country NOT【nuō 特】 IN (&apos;USA&apos;, &apos;Canada&apos;);&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回不在美国和加拿大的所有用户&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;BETWEEN【B豚ing】&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name BETWEEN【B豚ing】 value1 AND value2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查列值是否在指定的范围内（包含边界值）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM orders WHERE order_date BETWEEN【B豚ing】 &apos;2023-01-01&apos; AND &apos;2023-01-31&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回 2023 年 1 月期间的所有订单&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NOT BETWEEN【B豚ing】&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name NOT【nuō 特】 BETWEEN【B豚ing】 value1 AND value2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查列值是否不在指定的范围内&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM employees WHERE salary NOT【nuō 特】 BETWEEN【B豚ing】 30000 AND 60000;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回薪资低于 30,000 或高于 60,000 的所有员工&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;补充说明&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;IN 和 NOT【nuō 特】 IN&lt;/strong&gt; 适用于离散值的匹配，可以用于数字、字符串、日期等数据类型&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BETWEEN【B豚ing】&lt;/strong&gt; 适用于连续范围的匹配，通常用于数字和日期范围&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BETWEEN【B豚ing】&lt;/strong&gt; 操作包含边界值，即 &lt;code&gt;BETWEEN【B豚ing】 10 AND 20&lt;/code&gt; 包含 10 和 20&lt;/li&gt;
&lt;li&gt;对于日期范围，建议使用标准日期格式（如 &apos;YYYY-MM-DD&apos;）以避免歧义&lt;/li&gt;
&lt;li&gt;这些操作符可以组合使用，并与其他 WHERE 子句条件结合&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//uid号表头的值 是 (1 , 3 , 5 , 7) 中的任意一个即可
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】 name,uid  from【弗乱】  moershi.user where【威尔】  uid  in (1 , 3 , 5 , 7);  
+------+------+
| name | uid  |
+------+------+
| bin  |    1 |
| adm  |    3 |
| sync |    5 |
| halt |    7 |
+------+------+
//shell 表头的的值 不是 &quot;/bin/bash&quot;或&quot;/sbin/nologin&quot; 即可
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】 name,shell  from【弗乱】  moershi.user where【威尔】  shell  not【nuō 特】 in (&quot;/bin/bash&quot;,&quot;/sbin/nologin&quot;);
+----------+----------------+
| name     | shell          |
+----------+----------------+
| sync     | /bin/sync      |
| shutdown | /sbin/shutdown |
| halt     | /sbin/halt     |
| mysql    | /bin/false     |
+----------+----------------+
//id表头的值 在 10  到  20 之间即可 包括 10 和  20  本身
mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】 id,name,uid  from【弗乱】  moershi.user where【威尔】 id  between【B豚ing】 10 and 20 ;
+----+-----------------+------+
| id | name            | uid  |
+----+-----------------+------+
| 10 | operator        |   11 |
| 11 | games           |   12 |
| 12 | ftp             |   14 |
| 13 | nobody          |   99 |
| 14 | systemd-network |  192 |
| 15 | dbus            |   81 |
| 16 | polkitd         |  999 |
| 17 | sshd            |   74 |
| 18 | postfix         |   89 |
| 19 | chrony          |  998 |
| 20 | rpc             |   32 |
+----+-----------------+------+
11 rows in set (0.00 sec)mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.6 练习模糊匹配&lt;/h3&gt;
&lt;p&gt;where【威尔】 字段名 like【赖特】 &quot;表达式&quot;;&lt;/p&gt;
&lt;p&gt;通配符&lt;/p&gt;
&lt;p&gt;_ 表示 1个字符&lt;/p&gt;
&lt;p&gt;% 表示零个或多个字符&lt;/p&gt;
&lt;h4&gt;SQL 模糊匹配操作符参考表&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作符/通配符&lt;/th&gt;
&lt;th&gt;语法&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;th&gt;匹配结果说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LIKE【赖特】&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;WHERE column_name LIKE【赖特】 &apos;pattern&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;用于在WHERE子句中搜索列中的指定模式&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM customers WHERE name LIKE【赖特】 &apos;J%&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回所有名字以&quot;J&quot;开头的客户&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;_&lt;/strong&gt; (下划线)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&apos;_&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;匹配任意单个字符&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM products WHERE code LIKE【赖特】 &apos;A_1&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;匹配&quot;A&quot; + 任意一个字符 + &quot;1&quot;，如&quot;A01&quot;, &quot;AB1&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;%&lt;/strong&gt; (百分号)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&apos;%&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;匹配零个或多个字符&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM emails WHERE address LIKE【赖特】 &apos;%@gmail.com&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;匹配所有Gmail邮箱地址&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NOT LIKE【赖特】&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;WHERE column_name NOT LIKE【赖特】 &apos;pattern&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;查找不匹配指定模式的行&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM files WHERE name NOT LIKE【赖特】 &apos;%.tmp&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回所有不是临时文件(.tmp)的文件&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;组合使用示例&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模式&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&apos;_%&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIKE【赖特】 &apos;_%&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;匹配至少有一个字符的值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&apos;%@%&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIKE【赖特】 &apos;%@%&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;匹配包含@符号的值（常用于邮箱验证）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&apos;__-___-____&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIKE【赖特】 &apos;__-___-____&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;匹配格式为XX-XXX-XXXX的值（如电话号码）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&apos;A%Z&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIKE【赖特】 &apos;A%Z&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;匹配以&quot;A&quot;开头并以&quot;Z&quot;结尾的值&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//找名字必须是3个字符的 （没有空格挨着敲）
mysql&amp;gt; select【涩莱克特】 name from【弗乱】  moershi.user where【威尔】  name like【赖特】 &quot;___&quot;; 
+------+
| name |
+------+
| bin  |
| adm  |
| ftp  |
| rpc  |
| plj  |
| bob  |
+------+
6 rows in set (0.00 sec)
//找名字必须是4个字符的（没有空格挨着敲）
mysql&amp;gt; select【涩莱克特】 name from【弗乱】  moershi.user where【威尔】  name like【赖特】 &quot;____&quot;; 
+------+
| name |
+------+
| root |
| sync |
| halt |
| mail |
| dbus |
| sshd |
| null【nò】 |
+------+
7 rows in set (0.00 sec)
//找名字以字母a开头的（没有空格挨着敲）
mysql&amp;gt; select【涩莱克特】 name from【弗乱】  moershi.user where【威尔】  name like【赖特】 &quot;a%&quot;;  
//查找名字至少是4个字符的表达式
mysql&amp;gt; select【涩莱克特】 name from【弗乱】  moershi.user where【威尔】  name like【赖特】 &quot;%____%&quot;;（没有空格挨着敲）
mysql&amp;gt; select【涩莱克特】 name from【弗乱】  moershi.user where【威尔】 name  like【赖特】 &quot;__%__&quot;;（没有空格挨着敲）
mysql&amp;gt; select【涩莱克特】 name from【弗乱】  moershi.user where【威尔】 name  like【赖特】 &quot;____%&quot;;（没有空格挨着敲）
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.7 练习逻辑比较&lt;/h3&gt;
&lt;p&gt;多个判断条件&lt;/p&gt;
&lt;p&gt;逻辑与 and （&amp;amp;&amp;amp;） 多个判断条件必须同时成立&lt;/p&gt;
&lt;p&gt;逻辑或 or （||） 多个判断条件其中某个条件成立即可&lt;/p&gt;
&lt;p&gt;逻辑非 not【nuō 特】 （!） 取反&lt;/p&gt;
&lt;h4&gt;SQL 逻辑操作符参考表&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作符&lt;/th&gt;
&lt;th&gt;语法&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;th&gt;结果说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AND&lt;/strong&gt;  (逻辑与)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;condition1 AND condition2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;所有条件都必须为真，结果才为真&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM users WHERE age &amp;gt; 18 AND country = &apos;USA&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回年龄大于18岁且来自美国的用户&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OR&lt;/strong&gt; (逻辑或)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;condition1 OR condition2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;至少一个条件为真，结果就为真&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM products WHERE category = &apos;Electronics&apos; OR price &amp;gt; 1000;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回电子产品或价格超过1000的产品&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NOT&lt;/strong&gt; (逻辑非)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NOT condition&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;反转条件的真假值&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM orders WHERE NOT status = &apos;Cancelled&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回所有未取消的订单&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&amp;amp;&amp;amp;&lt;/strong&gt; (AND的替代符号)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;condition1 &amp;amp;&amp;amp; condition2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;某些数据库系统中AND的替代写法&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM users WHERE age &amp;gt; 18 &amp;amp;&amp;amp; country = &apos;USA&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;与AND相同，但并非所有数据库都支持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;||&lt;/strong&gt; (OR的替代符号)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;condition1 || condition2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;某些数据库系统中OR的替代写法&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM products WHERE category = &apos;Electronics&apos; || price &amp;gt; 1000;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;与OR相同，但并非所有数据库都支持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;!&lt;/strong&gt; (NOT的替代符号)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;!condition&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;某些数据库系统中NOT的替代写法&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM orders WHERE !status = &apos;Cancelled&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;与NOT相同，但并非所有数据库都支持&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;操作符优先级&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;优先级&lt;/th&gt;
&lt;th&gt;操作符&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;括号 ()&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;括号内的表达式最先计算&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;NOT&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;逻辑非&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;AND&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;逻辑与&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;OR&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;逻辑或&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//逻辑非例子，查看解释器不是/bin/bash 的
mysql&amp;gt; select【涩莱克特】 name,shell from【弗乱】 moershi.user where【威尔】  shell != &quot;/bin/bash&quot;; 
+-----------------+----------------+
| name            | shell          |
+-----------------+----------------+
| bin             | /sbin/nologin  |
| daemon          | /sbin/nologin  |
| adm             | /sbin/nologin  |
| lp              | /sbin/nologin  |
| sync            | /bin/sync      |
| shutdown        | /sbin/shutdown |
| halt            | /sbin/halt     |
| mail            | /sbin/nologin  |
| operator        | /sbin/nologin  |
| games           | /sbin/nologin  |
| ftp             | /sbin/nologin  |
| nobody          | /sbin/nologin  |
| systemd-network | /sbin/nologin  |
| dbus            | /sbin/nologin  |
| polkitd         | /sbin/nologin  |
| sshd            | /sbin/nologin  |
| postfix         | /sbin/nologin  |
| chrony          | /sbin/nologin  |
| rpc             | /sbin/nologin  |
| rpcuser         | /sbin/nologin  |
| nfsnobody       | /sbin/nologin  |
| haproxy         | /sbin/nologin  |
| apache          | /sbin/nologin  |
| mysql           | /bin/false     |
+-----------------+----------------+
24 rows in set (0.00 sec)

//not【nuō 特】 也是取反  要放在表达式的前边
mysql&amp;gt; select【涩莱克特】 name,shell from【弗乱】 moershi.user where【威尔】  not【nuō 特】  shell = &quot;/bin/bash&quot;;
+-----------------+----------------+
| name            | shell          |
+-----------------+----------------+
| bin             | /sbin/nologin  |
| daemon          | /sbin/nologin  |
| adm             | /sbin/nologin  |
| lp              | /sbin/nologin  |
| sync            | /bin/sync      |
| shutdown        | /sbin/shutdown |
| halt            | /sbin/halt     |
| mail            | /sbin/nologin  |
| operator        | /sbin/nologin  |
| games           | /sbin/nologin  |
| ftp             | /sbin/nologin  |
| nobody          | /sbin/nologin  |
| systemd-network | /sbin/nologin  |
| dbus            | /sbin/nologin  |
| polkitd         | /sbin/nologin  |
| sshd            | /sbin/nologin  |
| postfix         | /sbin/nologin  |
| chrony          | /sbin/nologin  |
| rpc             | /sbin/nologin  |
| rpcuser         | /sbin/nologin  |
| nfsnobody       | /sbin/nologin  |
| haproxy         | /sbin/nologin  |
| apache          | /sbin/nologin  |
| mysql           | /bin/false     |
+-----------------+----------------+
24 rows in set (0.00 sec)

//id值不在 10 到 20 之间 
mysql&amp;gt; select【涩莱克特】 id,name from【弗乱】 moershi.user where【威尔】 not【nuō 特】  id between【B豚ing】 10 and 20 ;  
+----+-----------+
| id | name      |
+----+-----------+
|  1 | root      |
|  2 | bin       |
|  3 | daemon    |
|  4 | adm       |
|  5 | lp        |
|  6 | sync      |
|  7 | shutdown  |
|  8 | halt      |
|  9 | mail      |
| 21 | rpcuser   |
| 22 | nfsnobody |
| 23 | haproxy   |
| 24 | plj       |
| 25 | apache    |
| 26 | mysql     |
| 27 | bob       |
+----+-----------+
16 rows in set (0.00 sec)

//逻辑与 例子
mysql&amp;gt; select【涩莱克特】 name,uid from【弗乱】 moershi.user where【威尔】 name=&quot;root&quot; and uid = 1;      
Empty set (0.00 sec)
mysql&amp;gt; select【涩莱克特】 name,uid from【弗乱】 moershi.user where【威尔】 name=&quot;root&quot; and uid = 0;
+------+------+
| name | uid  |
+------+------+
| root |    0 |
+------+------+
1 row in set (0.00 sec)

//逻辑或 例子
mysql&amp;gt; select【涩莱克特】 name , uid from【弗乱】 moershi.user where【威尔】 name = &quot;root&quot;  or  name = &quot;bin&quot;  or  uid = 1;
+------+------+
| name | uid  |
+------+------+
| root |    0 |
| bin  |    1 |
+------+------+
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;逻辑匹配什么时候需要加（）&lt;/p&gt;
&lt;p&gt;逻辑与and 优先级高于逻辑或 or&lt;/p&gt;
&lt;p&gt;如果在筛选条件里既有and 又有 or 默认先判断and 再判断or&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//没加（） 的查询结果
select【涩莱克特】 name,uid from【弗乱】 moershi.user where【威尔】 name = &quot;root&quot; or name = &quot;bin&quot;  and uid = 1 ;  
+------+------+
| name | uid  |
+------+------+
| root |    0 |
| bin  |    1 |
+------+------+
2 rows in set (0.00 sec)
//加（）的查询结果
select【涩莱克特】 name , uid from【弗乱】 moershi.user where【威尔】 (name = &quot;root&quot; or name = &quot;bin&quot;)  and uid = 1 ;  
+------+------+
| name | uid  |
+------+------+
| bin  |    1 |
+------+------+
1 row in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.8 练习字符比较/空/非空&lt;/h3&gt;
&lt;p&gt;符号两边必须是字符 或字符类型的表头&lt;/p&gt;
&lt;p&gt;= 相等比较&lt;/p&gt;
&lt;p&gt;!= 不相等比较。&lt;/p&gt;
&lt;h4&gt;SQL 字符比较与空值判断操作符参考表&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作符&lt;/th&gt;
&lt;th&gt;语法&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;th&gt;结果说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;=&lt;/strong&gt; (等于)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name = &apos;value&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;比较两个字符值是否相等&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM users WHERE name = &apos;John&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回名字为&apos;John&apos;的用户&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;!=&lt;/strong&gt; 或 &lt;strong&gt;&amp;lt;&amp;gt;&lt;/strong&gt; (不等于)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name != &apos;value&apos;&lt;/code&gt; 或 &lt;code&gt;column_name &amp;lt;&amp;gt; &apos;value&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;比较两个字符值是否不相等&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM products WHERE category != &apos;Electronics&apos;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回类别不是&apos;Electronics&apos;的产品&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IS NULL【nò】&lt;/strong&gt; (为空)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name IS NULL【nò】&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查列值是否为NULL【nò】&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM customers WHERE email IS NULL【nò】;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回没有填写邮箱的客户&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IS NOT【nuō 特】 NULL【nò】&lt;/strong&gt; (非空)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name IS NOT【nuō 特】 NULL【nò】&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查列值是否不为NULL【nò】&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM orders WHERE shipping_address IS NOT【nuō 特】 NULL【nò】;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回已填写配送地址的订单&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;字符比较注意事项&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;注意事项&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;大小写敏感&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;在某些数据库系统中，字符比较可能区分大小写&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&apos;Apple&apos; = &apos;apple&apos;&lt;/code&gt; 可能返回false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;尾部空格&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;比较时可能会忽略或考虑字符串尾部的空格&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&apos;John &apos; = &apos;John&apos;&lt;/code&gt; 可能返回true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;字符集和排序规则&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;比较结果受数据库字符集和排序规则设置影响&lt;/td&gt;
&lt;td&gt;不同字符集可能导致不同的比较结果&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;空值判断的特殊性&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NULL【nò】与任何值的比较&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NULL【nò】与任何值(包括NULL【nò】本身)比较都返回未知(UNKNOWN)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NULL【nò】 = NULL【nò】&lt;/code&gt; 返回NULL【nò】而不是true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;三值逻辑&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;SQL使用三值逻辑: true, false, unknown&lt;/td&gt;
&lt;td&gt;&lt;code&gt;WHERE column = NULL【nò】&lt;/code&gt; 不会返回任何行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;正确判断空值&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;必须使用IS NULL【nò】或IS NOT【nuō 特】 NULL【nò】判断空值&lt;/td&gt;
&lt;td&gt;&lt;code&gt;WHERE column IS NULL【nò】&lt;/code&gt; 正确判断空值&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//查看表里是否有名字叫apache的用户
mysql&amp;gt; select【涩莱克特】  name  from【弗乱】  moershi.user where【威尔】 name=&quot;apache&quot; ;
+--------+
| name   |
+--------+
| apache |
+--------+
1 row in set (0.00 sec)

//输出解释器不是/bin/bash的用户名 及使用的解释器
mysql&amp;gt; select【涩莱克特】  name,shell  from【弗乱】  moershi.user where【威尔】 shell != &quot;/bin/bash&quot;;
+-----------------+----------------+
| name            | shell          |
+-----------------+----------------+
| bin             | /sbin/nologin  |
| daemon          | /sbin/nologin  |
| adm             | /sbin/nologin  |
| lp              | /sbin/nologin  |
| sync            | /bin/sync      |
| shutdown        | /sbin/shutdown |
| halt            | /sbin/halt     |
| mail            | /sbin/nologin  |
| operator        | /sbin/nologin  |
| games           | /sbin/nologin  |
| ftp             | /sbin/nologin  |
| nobody          | /sbin/nologin  |
| systemd-network | /sbin/nologin  |
| dbus            | /sbin/nologin  |
| polkitd         | /sbin/nologin  |
| sshd            | /sbin/nologin  |
| postfix         | /sbin/nologin  |
| chrony          | /sbin/nologin  |
| rpc             | /sbin/nologin  |
| rpcuser         | /sbin/nologin  |
| nfsnobody       | /sbin/nologin  |
| haproxy         | /sbin/nologin  |
| apache          | /sbin/nologin  |
| mysql           | /bin/false     |
+-----------------+----------------+
24 rows in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;空 is null【nò】 表头下没有数据&lt;/p&gt;
&lt;p&gt;非空 is not【nuō 特】 null【nò】 表头下有数据&lt;/p&gt;
&lt;p&gt;mysql服务 使用关键字 null【nò】 或 NULL【nò】 表示表头没有数据&lt;/p&gt;
&lt;h4&gt;MySQL 空值判断操作符参考表&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作符&lt;/th&gt;
&lt;th&gt;语法&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;th&gt;结果说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IS NULL【nò】&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name IS NULL【nò】&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查列值是否为 NULL【nò】（空值）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM users WHERE email IS NULL【nò】;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回 email 字段为空的用户&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IS NOT【nuō 特】 NULL【nò】&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;column_name IS NOT【nuō 特】 NULL【nò】&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查列值是否不为 NULL【nò】（非空）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM orders WHERE amount IS NOT【nuō 特】 NULL【nò】;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回 amount 字段有值的订单&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;NULL【nò】 值的特殊性质&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NULL【nò】 与空字符串的区别&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NULL【nò】 表示没有值，而空字符串(&apos;&apos;)是一个有效的值&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NULL【nò】 != &apos;&apos;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NULL【nò】 的比较&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NULL【nò】 与任何值(包括 NULL【nò】 本身)比较都返回未知&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NULL【nò】 = NULL【nò】&lt;/code&gt; 返回 NULL【nò】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NULL【nò】 的计算&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;任何包含 NULL【nò】 的计算结果通常都是 NULL【nò】&lt;/td&gt;
&lt;td&gt;&lt;code&gt;5 + NULL【nò】&lt;/code&gt; 返回 NULL【nò】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NULL【nò】 的逻辑运算&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NULL【nò】 参与逻辑运算时通常返回未知&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NULL【nò】 AND TRUE&lt;/code&gt; 返回 NULL【nò】&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;处理 NULL【nò】 值的函数&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;语法&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IFNULL()&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IFNULL(expr1, expr2)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;如果 expr1 不为 NULL【nò】，返回 expr1，否则返回 expr2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT IFNULL(salary, 0) FROM employees;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;COALESCE()&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;COALESCE(expr1, expr2, ...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回参数列表中第一个非 NULL【nò】 的值&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT COALESCE(phone, mobile, &apos;无联系方式&apos;) FROM contacts;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NULLIF()&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NULLIF(expr1, expr2)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;如果 expr1 = expr2，返回 NULL【nò】，否则返回 expr1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT NULLIF(salary, 0) FROM employees;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;//添加新行 仅给行中的id 表头和name表头赋值
mysql&amp;gt; insert【因涩特】 into moershi.user(id,name) values(71,&quot;&quot;);    //零个字符
mysql&amp;gt; insert【因涩特】 into moershi.user(id,name) values(72,&quot;null【nò】&quot;);//普通字母
mysql&amp;gt; insert【因涩特】 into moershi.user(id,name) values(73,NULL【nò】);  //表示空
mysql&amp;gt; insert【因涩特】 into moershi.user(id,name) values(74,null【nò】);  //表示空
//查看id表头值大于等于70  的行 仅显示行中 id表头 和  name 表头的值
mysql&amp;gt; select【涩莱克特】 id,name from【弗乱】  moershi.user where【威尔】  id &amp;gt;= 71;
+----+-------------+
| id | name        |
+----+-------------+
| 71 |             |
| 72 | null【nò】 |
| 73 | NULL【nò】 |
| 74 | NULL【nò】 |
+----+-------------+

//查看name 表头没有数据的行 仅显示行中id表头 和  naeme 表头的值
mysql&amp;gt; select【涩莱克特】 id,name from【弗乱】  moershi.user where【威尔】 name is null【nò】;
+----+-------------+
| id | name        |
+----+-------------+
| 28 | NULL【nò】 |
| 29 | NULL【nò】 |
| 73 | NULL【nò】 |
| 74 | NULL【nò】 |
+----+-------------+

//查看name 表头是0个字符的行， 仅显示行中id表头 和  naeme 表头的值
mysql&amp;gt; select【涩莱克特】 id,name from【弗乱】  moershi.user where【威尔】 name=&quot;&quot;;
+----+------+
| id | name |
+----+------+
| 71 |      |
+----+------+
1 row in set (0.00 sec)

//查看name 表头值是null【nò】的行， 仅显示行中id表头 和  naeme 表头的值
mysql&amp;gt; select【涩莱克特】 id,name from【弗乱】  moershi.user where【威尔】 name=&quot;null【nò】&quot;;
+----+------+
| id | name |
+----+------+
| 72 | null【nò】 |
+----+------+
1 row in set (0.00 sec)

//查看name 表头有数据的行， 仅显示行中id表头 和  name 表头的值
mysql&amp;gt; select【涩莱克特】 id,name from【弗乱】  moershi.user where【威尔】 name is not【nuō 特】 null【nò】;
+----+-----------------+
| id | name            |
+----+-----------------+
|  1 | root            |
|  2 | bin             |
|  3 | daemon          |
|  4 | adm             |
|  5 | lp              |
....
....
| 27 | bob             |
| 71 |                 |
| 72 | null【nò】            |
+----+-----------------+
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.9 练习别名/去重/合并&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作类型&lt;/th&gt;
&lt;th&gt;关键字/函数&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;th&gt;主要用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;别名&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AS&lt;/code&gt; 或空格&lt;/td&gt;
&lt;td&gt;为列或表赋予临时名称&lt;/td&gt;
&lt;td&gt;提高可读性、简化复杂查询&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;去重&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;DISTINCT【迪斯定特】&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;去除查询结果中的重复行&lt;/td&gt;
&lt;td&gt;获取唯一值列表&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;合并&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UNION&lt;/code&gt; / &lt;code&gt;UNION ALL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;合并多个SELECT语句的结果集&lt;/td&gt;
&lt;td&gt;组合来自不同查询的数据&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;别名&lt;/h4&gt;
&lt;p&gt;基本语法&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 列别名
SELECT column_name AS alias_name FROM table_name;
SELECT column_name alias_name FROM table_name; -- 省略AS

-- 表别名
SELECT t.column_name FROM table_name AS t;
SELECT t.column_name FROM table_name t; -- 省略AS
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用场景&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;简化复杂列名或表达式&lt;/li&gt;
&lt;li&gt;提高查询结果的可读性&lt;/li&gt;
&lt;li&gt;在多表连接中简化表引用&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//定义别名使用   as  或  空格    
mysql&amp;gt; select【涩莱克特】 name,homedir  from【弗乱】 moershi.user;
+-----------------+--------------------+
| name            | homedir            |
+-----------------+--------------------+
| root            | /root              |
| bin             | /bin               |
| daemon          | /sbin              |
| adm             | /var/adm           |
| lp              | /var/spool/lpd     |
| sync            | /sbin              |
| shutdown        | /sbin              |
| halt            | /sbin              |
| mail            | /var/spool/mail    |
| operator        | /root              |
| games           | /usr/games         |
| ftp             | /var/ftp           |
| nobody          | /                  |
| systemd-network | /                  |
| dbus            | /                  |
| polkitd         | /                  |
| sshd            | /var/empty/sshd    |
| postfix         | /var/spool/postfix |
| chrony          | /var/lib/chrony    |
| rpc             | /var/lib/rpcbind   |
| rpcuser         | /var/lib/nfs       |
| nfsnobody       | /var/lib/nfs       |
| haproxy         | /var/lib/haproxy   |
| plj             | /home/plj          |
| apache          | /usr/share/httpd   |
| mysql           | /var/lib/mysql     |
| bob             | NULL               |
+-----------------+--------------------+
27 rows in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 name as 用户名,homedir  家目录 from【弗乱】 moershi.user;
+-----------------+--------------------+
| 用户名          | 家目录             |
+-----------------+--------------------+
| root            | /root              |
| bin             | /bin               |
| daemon          | /sbin              |
| adm             | /var/adm           |
| lp              | /var/spool/lpd     |
| sync            | /sbin              |
| shutdown        | /sbin              |
| halt            | /sbin              |
| mail            | /var/spool/mail    |
| operator        | /root              |
| games           | /usr/games         |
| ftp             | /var/ftp           |
| nobody          | /                  |
| systemd-network | /                  |
| dbus            | /                  |
| polkitd         | /                  |
| sshd            | /var/empty/sshd    |
| postfix         | /var/spool/postfix |
| chrony          | /var/lib/chrony    |
| rpc             | /var/lib/rpcbind   |
| rpcuser         | /var/lib/nfs       |
| nfsnobody       | /var/lib/nfs       |
| haproxy         | /var/lib/haproxy   |
| plj             | /home/plj          |
| apache          | /usr/share/httpd   |
| mysql           | /var/lib/mysql     |
| bob             | NULL               |
+-----------------+--------------------+
27 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;合并&lt;/h4&gt;
&lt;p&gt;SQL 两种“合并”操作对比表&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;&lt;code&gt;CONCAT()&lt;/code&gt; (字符串拼接)&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;&lt;code&gt;UNION&lt;/code&gt; / &lt;code&gt;UNION ALL&lt;/code&gt; (结果集合并)&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;操作对象&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;列内的数据&lt;/strong&gt;（字符串、文本）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;查询结果集&lt;/strong&gt;（行）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;操作方向&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;水平&lt;/strong&gt;合并（将多个列的值拼接到一行里）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;垂直&lt;/strong&gt;合并（将多个查询的结果上下堆叠）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;目的&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;生成新的格式化字符串&lt;/td&gt;
&lt;td&gt;组合来自不同查询的数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;语法示例&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT CONCAT(first_name, &apos; &apos;, last_name) FROM users;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT name FROM table1 UNION SELECT name FROM table2;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;结果图示&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&amp;lt;br&amp;gt;&lt;strong&gt;输入:&lt;/strong&gt; &lt;code&gt;John&lt;/code&gt; &lt;code&gt;Doe&lt;/code&gt;&amp;lt;br&amp;gt;&lt;strong&gt;输出:&lt;/strong&gt; &lt;code&gt;John Doe&lt;/code&gt;&amp;lt;br&amp;gt;&lt;/td&gt;
&lt;td&gt;&amp;lt;br&amp;gt;&lt;strong&gt;输入:&lt;/strong&gt; &amp;lt;br&amp;gt;查询1结果: &lt;code&gt;John&lt;/code&gt;&amp;lt;br&amp;gt;查询2结果: &lt;code&gt;Jane&lt;/code&gt;&amp;lt;br&amp;gt;&lt;strong&gt;输出:&lt;/strong&gt; &amp;lt;br&amp;gt;&lt;code&gt;John&lt;/code&gt;&amp;lt;br&amp;gt;&lt;code&gt;Jane&lt;/code&gt;&amp;lt;br&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h5&gt;1、 &lt;code&gt;CONCAT()&lt;/code&gt; - 字符串拼接函数（横向合并）&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;CONCAT()&lt;/code&gt; 用于将&lt;strong&gt;多个字符串字段或值连接成一个字符串&lt;/strong&gt;。它是在单条记录内进行操作。
&lt;strong&gt;基本语法：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CONCAT(string1, string2, ..., stringN)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;//拼接   concat【康(白话)凯特】()
mysql&amp;gt; select【涩莱克特】 concat【康(白话)凯特】(name,&quot;-&quot;,uid) as 用户信息 from【弗乱】 moershi.user where【威尔】 uid &amp;lt;= 5;
+--------------+
| 用户信息     |
+--------------+
| root-0       |
| bin-1        |
| daemon-2     |
| adm-3        |
| lp-4         |
| sync-5       |
+--------------+
6 rows in set (0.00 sec)
//2列拼接
mysql&amp;gt;  select【涩莱克特】 concat【康(白话)凯特】(name,&quot;-&quot;,uid)  as  用户信息  from【弗乱】 moershi.user where【威尔】 uid &amp;lt;= 5;
+--------------+
| 用户信息     |
+--------------+
| root-0       |
| bin-1        |
| daemon-2     |
| adm-3        |
| lp-4         |
| sync-5       |
+--------------+
6 rows in set (0.00 sec)

//多列拼接
mysql&amp;gt;  select【涩莱克特】 concat【康(白话)凯特】(name,&quot;-&quot;,uid ,&quot;-&quot;,gid)  as  用户信息  from【弗乱】 moershi.user where【威尔】 uid &amp;lt;= 5;
+--------------+
| 用户信息     |
+--------------+
| root-0-0     |
| bin-1-1      |
| daemon-2-2   |
| adm-3-4      |
| lp-4-7       |
| sync-5-0     |
+--------------+
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;2. &lt;code&gt;UNION&lt;/code&gt; / &lt;code&gt;UNION ALL&lt;/code&gt; - 结果集操作符（纵向合并）&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;UNION&lt;/code&gt; 用于将&lt;strong&gt;两个或多个 SELECT 语句的结果集合并&lt;/strong&gt;为一个结果集。它是在记录之间进行操作。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;基本语法：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT column1, column2 FROM table1
UNION [ALL]
SELECT column1, column2 FROM table2;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;//把moershi.user表和moershi.departments的name数据纵向合并
mysql&amp;gt; select name from moershi.user union select dept_name from moershi.departments;
+-----------------+
| name            |
+-----------------+
| root            |
| bin             |
| daemon          |
| adm             |
| lp              |
| sync            |
| shutdown        |
| halt            |
| mail            |
| operator        |
| games           |
| ftp             |
| nobody          |
| systemd-network |
| dbus            |
| polkitd         |
| sshd            |
| postfix         |
| chrony          |
| rpc             |
| rpcuser         |
| nfsnobody       |
| haproxy         |
| plj             |
| apache          |
| mysql           |
| bob             |
| 人事部          |
| 财务部          |
| 运维部          |
| 开发部          |
| 测试部          |
| 市场部          |
| 销售部          |
| 法务部          |
+-----------------+
35 rows in set (0.00 sec)
//多列纵向合并
mysql&amp;gt; select id,name from moershi.user union select dept_id,dept_name from moershi.departments;
+----+-----------------+
| id | name            |
+----+-----------------+
|  1 | root            |
|  2 | bin             |
|  3 | daemon          |
|  4 | adm             |
|  5 | lp              |
|  6 | sync            |
|  7 | shutdown        |
|  8 | halt            |
|  9 | mail            |
| 10 | operator        |
| 11 | games           |
| 12 | ftp             |
| 13 | nobody          |
| 14 | systemd-network |
| 15 | dbus            |
| 16 | polkitd         |
| 17 | sshd            |
| 18 | postfix         |
| 19 | chrony          |
| 20 | rpc             |
| 21 | rpcuser         |
| 22 | nfsnobody       |
| 23 | haproxy         |
| 24 | plj             |
| 25 | apache          |
| 26 | mysql           |
| 27 | bob             |
|  1 | 人事部          |
|  2 | 财务部          |
|  3 | 运维部          |
|  4 | 开发部          |
|  5 | 测试部          |
|  6 | 市场部          |
|  7 | 销售部          |
|  8 | 法务部          |
+----+-----------------+
35 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2. 去重&lt;/h4&gt;
&lt;p&gt;去重显示 distinct【迪斯定特】 字段名列表
基本语法&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT DISTINCT【迪斯定特】 column1, column2 FROM table_name;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用场景&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;获取某列的唯一值列表&lt;/li&gt;
&lt;li&gt;统计不重复的记录数量&lt;/li&gt;
&lt;li&gt;避免重复数据影响分析结果&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;//去重前输出
mysql&amp;gt; select【涩莱克特】 shell  from【弗乱】  moershi.user  where【威尔】 shell in (&quot;/bin/bash&quot;,&quot;/sbin/nologin&quot;) ;
+---------------+
| shell         |
+---------------+
| /bin/bash     |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /sbin/nologin |
| /bin/bash     |
| /sbin/nologin |
+---------------+
22 rows in set (0.00 sec)
//去重后查看
mysql&amp;gt; select【涩莱克特】 distinct【迪斯定特】 shell  from【弗乱】  moershi.user  where【威尔】 shell in (&quot;/bin/bash&quot;,&quot;/sbin/nologin&quot;) ;
+---------------+
| shell         |
+---------------+
| /bin/bash     |
| /sbin/nologin |
+---------------+
2 rows in set (0.01 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、作业&lt;/h2&gt;
&lt;h3&gt;1. 选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;MySQL 中，预设的拥有最高权限的超级用户的用户名为（ D ）
A. test
B. administrator
C. DBA
D. root&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;实现将 root 用户的密码修改为“123456”的语句，正确的是（ A ）
A. ALTER USER &apos;root&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;123456&apos;;
B. ALTER USER &apos;root&apos;@&apos;localhost&apos; IDENTIFIED BY 123456;
C. ALTER USER &apos;root&apos;@&apos;localhost&apos; =&apos;123456&apos;;
D. SET USER &apos;root&apos;@&apos;localhost&apos; =&apos;123456&apos;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;要启动 MySQL 服务，在 Linux 系统下可以使用的命令是（C  ）
A. service mysql start
B. systemctl start mysql
C. both A and B
D. mysql -u root -p&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;moershi.user&lt;/code&gt; 表中，查询 &lt;code&gt;id&lt;/code&gt; 大于 10 的记录，正确的 SQL 语句是（ A ）
A. select * FROM moershi.user where id &amp;gt; 10;
B. select * FROM  user where  id &amp;gt; 10;
C. select * FROM moershi.user where  id &amp;gt;= 10;
D. select * FROM user where  id &amp;gt;= 10;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;moershi.user&lt;/code&gt; 表中，查询 &lt;code&gt;uid&lt;/code&gt; 在 100 到 200 之间的记录，使用的关键字是（ A ）
A. BETWEEN
B. IN
C. LIKE
D. AND&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;moershi.user&lt;/code&gt; 表中，查询 &lt;code&gt;name&lt;/code&gt; 以“a”开头的记录，SQL 语句是（ A ）
A. select * FROM moershi.user where name LIKE &apos;a%&apos;;
B. select * FROM moershi.user where name LIKE &apos;%a&apos;;
C. select * FROM moershi.user where name LIKE &apos;%a%&apos;;
D. select * FROM moershi.user where name = &apos;a&apos;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;moershi.user&lt;/code&gt; 表中，查询 &lt;code&gt;id&lt;/code&gt; 大于 10 并且 &lt;code&gt;gid&lt;/code&gt; 小于 20 的记录，使用的逻辑运算符是（B  ）
A. OR
B. AND
C. NOT
D. XOR&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;moershi.user&lt;/code&gt; 表中，查询 &lt;code&gt;password&lt;/code&gt; 字段不为空的记录，SQL 语句是（ A ）
A. select * FROM moershi.user where password IS NOT NULL ;
B. select * FROM moershi.user where password = &apos;&apos;;
C. select * FROM moershi.user where password IS NULL ;
D. select * FROM moershi.user where password != &apos;&apos;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;moershi.user&lt;/code&gt; 表中，查询 &lt;code&gt;name&lt;/code&gt; 字段并给它起别名 &lt;code&gt;user_name&lt;/code&gt;，SQL 语句是（ A ）
A. select name AS user_name FROM moershi.user;
B. select user_name FROM moershi.user;
C. select name = user_name FROM moershi.user;
D. select user_name = name FROM moershi.user;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;moershi.user&lt;/code&gt; 表中，查询 &lt;code&gt;id&lt;/code&gt; 字段并去除重复值，使用的关键字是（ B ）
A. UNIQUE
B. DISTINCT
C. GROUP BY
D. ORDER BY&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;h4&gt;1. 简述 MySQL 密码管理的重要性以及常见的密码管理操作有哪些？&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;​重要性：​​
    安全性保障：防止未授权访问，保护敏感数据
    权限控制：确保只有授权用户才能执行数据库操作
    审计追踪：便于跟踪数据库访问和操作记录
    合规要求：满足数据安全法规和行业标准
    
​​常见的密码管理操作：​​
    设置/修改用户密码：ALTER USER &apos;username&apos;@&apos;host&apos; IDENTIFIED BY &apos;new_password&apos;;
    密码过期策略：ALTER USER &apos;username&apos;@&apos;host&apos; PASSWORD EXPIRE;
    密码复杂度要求：通过 validate_password 组件设置密码策略
    密码加密存储：MySQL 使用加密算法存储密码
    重置忘记的密码：通过安全模式启动 MySQL 重置密码
    查看用户权限：SHOW GRANTS FOR &apos;username&apos;@&apos;host&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2. 说明 MySQL 服务管理包含哪些方面，以及如何在 Linux 系统下停止和重启 MySQL 服务？&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;MySQL 服务管理包含的方面：​​
    服务启动和停止
    服务状态监控
    服务自动启动配置
    日志文件管理
    配置文件管理
    性能调优和监控

### 1. 服务启动和停止
- **启动 MySQL 服务**：
  ```bash
  systemctl start mysqld
  # 或使用 service 命令（适用于旧版系统）
  service mysqld start
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;停止 MySQL 服务&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl stop mysqld
service mysqld stop
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;重启 MySQL 服务&lt;/strong&gt;（常用于配置更改后）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl restart mysqld
service mysqld restart
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;重新加载配置&lt;/strong&gt;（不重启服务）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl reload mysqld
# 或通过 MySQL 内部命令
mysqladmin -u root -p reload
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 服务状态监控&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查服务状态&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl status mysqld
service mysqld status
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查 MySQL 进程是否运行&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ps aux | grep mysqld
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查 MySQL 端口监听&lt;/strong&gt;（默认 3306）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;netstat -tlnp | grep 3306
# 或使用 ss 命令
ss -tlnp | grep 3306
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查 MySQL 连接状态&lt;/strong&gt;（使用 MySQL 客户端）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysqladmin -u root -p status
# 或进入 MySQL 后执行
SHOW STATUS;
SHOW PROCESSLIST;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 服务自动启动配置&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;启用开机自动启动&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl enable mysqld
chkconfig mysqld on  # 适用于 SysVinit 系统
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;禁用开机自动启动&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl disable mysqld
chkconfig mysqld off  # 适用于 SysVinit 系统
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查看自动启动状态&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl is-enabled mysqld
chkconfig --list mysqld  # 适用于 SysVinit 系统
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. 日志文件管理&lt;/h3&gt;
&lt;p&gt;MySQL 有多种日志类型，如错误日志、查询日志、慢查询日志等。日志位置通常在 &lt;code&gt;/var/log/mysql/&lt;/code&gt; 或 &lt;code&gt;/var/log/&lt;/code&gt; 目录下，具体路径取决于配置文件。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查看错误日志&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tail -f /var/log/mysql/error.log
# 如果路径不同，请检查配置文件 my.cnf 中的 log_error 设置
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查看通用查询日志&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tail -f /var/log/mysql/mysql.log
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查看慢查询日志&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tail -f /var/log/mysql/slow.log
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;动态启用/禁用日志&lt;/strong&gt;（需要在 MySQL 配置文件中设置，然后重启或重新加载服务）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 在 MySQL 客户端中设置（临时生效）
SET GLOBAL general_log = &apos;ON&apos;;
SET GLOBAL slow_query_log = &apos;ON&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;日志轮转&lt;/strong&gt;（使用 logrotate）：
通常 MySQL 日志由 logrotate 管理，配置文件在 &lt;code&gt;/etc/logrotate.d/mysql&lt;/code&gt;。手动轮转：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;logrotate -f /etc/logrotate.d/mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5. 配置文件管理&lt;/h3&gt;
&lt;p&gt;MySQL 配置文件通常是 &lt;code&gt;/etc/my.cnf&lt;/code&gt; 或 &lt;code&gt;/etc/mysql/my.cnf&lt;/code&gt;，也可能包含在 &lt;code&gt;/etc/mysql/conf.d/&lt;/code&gt; 目录下。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;编辑配置文件&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo nano /etc/my.cnf
# 或使用其他编辑器
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查配置文件语法&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysqld --verbose --help | grep -A1 -B1 &quot;Default options&quot;
# 或使用
mysqld --validate-config
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;应用配置更改&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 重新加载配置（不重启服务）
systemctl reload mysqld
# 或重启服务
systemctl restart mysqld
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;6. 性能调优和监控&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;监控实时性能&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 使用 mysqladmin 查看状态
mysqladmin -u root -p extended-status
# 或进入 MySQL 后执行
SHOW GLOBAL STATUS;
SHOW ENGINE INNODB STATUS;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查变量设置&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql -u root -p -e &quot;SHOW VARIABLES;&quot;
# 或特定变量
mysql -u root -p -e &quot;SHOW VARIABLES LIKE &apos;%buffer%&apos;;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;性能分析工具&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;mysqltuner&lt;/strong&gt;：一个常用的脚本，用于分析配置和提供建议。&lt;pre&gt;&lt;code&gt;wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl
perl mysqltuner.pl --user root --pass
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pt-query-digest&lt;/strong&gt;：分析慢查询日志。&lt;pre&gt;&lt;code&gt;pt-query-digest /var/log/mysql/slow.log
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;mysqlslap&lt;/strong&gt;：负载测试工具。&lt;pre&gt;&lt;code&gt;mysqlslap -u root -p --concurrency=50 --iterations=100 --auto-generate-sql
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;优化表&lt;/strong&gt;（定期维护）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;OPTIMIZE TABLE table_name;
# 或使用 mysqlcheck
mysqlcheck -u root -p --optimize --all-databases
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;附加提示&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;确保使用具有适当权限的 MySQL 用户（如 root）执行命令。&lt;/li&gt;
&lt;li&gt;对于生产环境，建议定期备份和监控。&lt;/li&gt;
&lt;li&gt;如果使用 Docker 或其他容器化部署，命令可能有所不同。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果您有特定场景或问题，可以提供更多细节，我可以给出更具体的指导。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;   
#### 3. 请解释 SQL 中的数值比较、范围匹配、模糊匹配、逻辑比较、字符比较/空/非空、别名/去重/合并的概念，并各举一个在 `moershi.user` 表中的应用示例。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;数值比较​​：使用比较运算符（=, &amp;lt;&amp;gt;, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;=）比较数值
示例：SELECT * FROM moershi.user WHERE uid &amp;gt; 1000;
​​范围匹配​​：使用 BETWEEN 关键字匹配某个范围内的值
示例：SELECT * FROM moershi.user WHERE id BETWEEN 10 AND 20;
​​模糊匹配​​：使用 LIKE 关键字和通配符（%, _）进行模式匹配
示例：SELECT * FROM moershi.user WHERE name LIKE &apos;a%&apos;;
​​逻辑比较​​：使用逻辑运算符（AND, OR, NOT）组合多个条件
示例：SELECT * FROM moershi.user WHERE name = &apos;root&apos; AND uid = 0;
​​字符比较/空/非空​​：比较字符串值或检查字段是否为 NULL
字符比较示例：SELECT * FROM moershi.user WHERE name = &apos;root&apos;;
空/非空示例：SELECT * FROM moershi.user WHERE homedir IS NOT NULL;
​​别名/去重/合并​​：
别名：使用 AS 关键字为列或表指定临时名称
示例：SELECT name AS username, homedir AS home_directory FROM moershi.user;
去重：使用 DISTINCT 关键字去除查询结果中的重复行
示例：SELECT DISTINCT shell FROM moershi.user;
合并：使用 UNION 或 UNION ALL 合并多个查询的结果集
示例：SELECT name FROM moershi.user UNION SELECT dept_name FROM moershi.departments;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;   

### 3 操作题

#### 1.创建一个新的 MySQL 用户 `test_user`，密码为 `test_password`，并授予该用户对 `moershi.user` 表的查询权限。

```sql
mysql&amp;gt; create user if not exists &apos;test_user&apos;@&apos;%&apos; identified by &apos;test_password&apos;;
Query OK, 0 rows affected (0.21 sec)

mysql&amp;gt; GRANT SELECT ON moershi.user TO &apos;test_user&apos;@&apos;%&apos;;
Query OK, 0 rows affected (0.16 sec)

mysql&amp;gt; flush privileges;
Query OK, 0 rows affected (0.05 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2.请编写 SQL 语句，在 &lt;code&gt;moershi.user&lt;/code&gt; 表中查询 &lt;code&gt;id&lt;/code&gt; 大于 5 且 &lt;code&gt;name&lt;/code&gt; 以“r”开头的记录。&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select id,name from moershi.user where id &amp;gt; 5 and name like &quot;r%&quot;;
+----+---------+
| id | name    |
+----+---------+
| 20 | rpc     |
| 21 | rpcuser |
+----+---------+
2 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3.编写 SL 语句，将 &lt;code&gt;moershi.user&lt;/code&gt; 表中 &lt;code&gt;id&lt;/code&gt; 为 1 的记录的 &lt;code&gt;password&lt;/code&gt; 字段更新为 &lt;code&gt;new_password&lt;/code&gt;。&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select id,name,password from moershi.user where id =1; --查询原始信息
+----+------+----------+
| id | name | password |
+----+------+----------+
|  1 | root | x        |
+----+------+----------+
1 row in set (0.00 sec)

mysql&amp;gt; UPDATE moershi.user SET password = &apos;new_password&apos; WHERE id = 1; --这个错误表明 password字段的定义长度不足以存储 &apos;new_password&apos;这个值
ERROR 1406 (22001): Data too long for column &apos;password&apos; at row 1

mysql&amp;gt; DESCRIBE moershi.user; --检查表原始结构信息
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | int         | NO   | PRI | NULL    | auto_increment |
| name     | char(20)    | YES  |     | NULL    |                |
| password | char(1)     | YES  |     | NULL    |                |
| uid      | int         | YES  |     | NULL    |                |
| gid      | int         | YES  |     | NULL    |                |
| comment  | varchar(50) | YES  |     | NULL    |                |
| homedir  | varchar(80) | YES  |     | NULL    |                |
| shell    | char(30)    | YES  |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+
8 rows in set (0.01 sec)

mysql&amp;gt; ALTER TABLE moershi.user MODIFY password VARCHAR(50); --修改password结构大小
Query OK, 27 rows affected (2.64 sec)
Records: 27  Duplicates: 0  Warnings: 0

mysql&amp;gt; UPDATE moershi.user SET password = &apos;new_password&apos; WHERE id = 1; --重新修改id=1的password字段
Query OK, 1 row affected (0.11 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql&amp;gt; select id,name,password from moershi.user where id =1; --查看修改后的信息
+----+------+--------------+
| id | name | password     |
+----+------+--------------+
|  1 | root | new_password |
+----+------+--------------+
1 row in set (0.00 sec)

mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4.编写 SQL 语句，删除 &lt;code&gt;moershi.user&lt;/code&gt; 表中 &lt;code&gt;id&lt;/code&gt; 小于 3 的记录。&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; select * from moershi.user where id &amp;lt; 3;
+----+------+--------------+------+------+---------+---------+---------------+
| id | name | password     | uid  | gid  | comment | homedir | shell         |
+----+------+--------------+------+------+---------+---------+---------------+
|  1 | root | new_password |    0 |    0 | root    | /root   | /bin/bash     |
|  2 | bin  | x            |    1 |    1 | bin     | /bin    | /sbin/nologin |
+----+------+--------------+------+------+---------+---------+---------------+
2 rows in set (0.00 sec)

mysql&amp;gt; delete from moershi.user where id &amp;lt; 3;
Query OK, 2 rows affected (0.09 sec)

mysql&amp;gt; select * from moershi.user where id &amp;lt; 3;
Empty set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;5.编写 SQL 语句，将 &lt;code&gt;moershi.user&lt;/code&gt; 表按照 &lt;code&gt;id&lt;/code&gt; 字段降序排序，并取前 5 条记录。&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; 
mysql&amp;gt; select * from moershi.user order by id desc; --降序全部
+----+-----------------+----------+-------+-------+----------------------------+--------------------+----------------+
| id | name            | password | uid   | gid   | comment                    | homedir            | shell          |
+----+-----------------+----------+-------+-------+----------------------------+--------------------+----------------+
| 27 | bob             | NULL     |  NULL |  NULL | NULL                       | NULL               | NULL           |
| 26 | mysql           | x        |    27 |    27 | MySQL Server               | /var/lib/mysql     | /bin/false     |
| 25 | apache          | x        |    48 |    48 | Apache                     | /usr/share/httpd   | /sbin/nologin  |
| 24 | plj             | x        |  1000 |  1000 |                            | /home/plj          | /bin/bash      |
| 23 | haproxy         | x        |   188 |   188 | haproxy                    | /var/lib/haproxy   | /sbin/nologin  |
| 22 | nfsnobody       | x        | 65534 | 65534 | Anonymous NFS User         | /var/lib/nfs       | /sbin/nologin  |
| 21 | rpcuser         | x        |    29 |    29 | RPC Service User           | /var/lib/nfs       | /sbin/nologin  |
| 20 | rpc             | x        |    32 |    32 | Rpcbind Daemon             | /var/lib/rpcbind   | /sbin/nologin  |
| 19 | chrony          | x        |   998 |   996 |                            | /var/lib/chrony    | /sbin/nologin  |
| 18 | postfix         | x        |    89 |    89 |                            | /var/spool/postfix | /sbin/nologin  |
| 17 | sshd            | x        |    74 |    74 | Privilege-separated SSH    | /var/empty/sshd    | /sbin/nologin  |
| 16 | polkitd         | x        |   999 |   998 | User for polkitd           | /                  | /sbin/nologin  |
| 15 | dbus            | x        |    81 |    81 | System message bus         | /                  | /sbin/nologin  |
| 14 | systemd-network | x        |   192 |   192 | systemd Network Management | /                  | /sbin/nologin  |
| 13 | nobody          | x        |    99 |    99 | Nobody                     | /                  | /sbin/nologin  |
| 12 | ftp             | x        |    14 |    50 | FTP User                   | /var/ftp           | /sbin/nologin  |
| 11 | games           | x        |    12 |   100 | games                      | /usr/games         | /sbin/nologin  |
| 10 | operator        | x        |    11 |     0 | operator                   | /root              | /sbin/nologin  |
|  9 | mail            | x        |     8 |    12 | mail                       | /var/spool/mail    | /sbin/nologin  |
|  8 | halt            | x        |     7 |     0 | halt                       | /sbin              | /sbin/halt     |
|  7 | shutdown        | x        |     6 |     0 | shutdown                   | /sbin              | /sbin/shutdown |
|  6 | sync            | x        |     5 |     0 | sync                       | /sbin              | /bin/sync      |
|  5 | lp              | x        |     4 |     7 | lp                         | /var/spool/lpd     | /sbin/nologin  |
|  4 | adm             | x        |     3 |     4 | adm                        | /var/adm           | /sbin/nologin  |
|  3 | daemon          | x        |     2 |     2 | daemon                     | /sbin              | /sbin/nologin  |
+----+-----------------+----------+-------+-------+----------------------------+--------------------+----------------+
25 rows in set (0.00 sec)

mysql&amp;gt; select * from moershi.user order by id desc limit 5; --提取降序后的前5
+----+---------+----------+------+------+--------------+------------------+---------------+
| id | name    | password | uid  | gid  | comment      | homedir          | shell         |
+----+---------+----------+------+------+--------------+------------------+---------------+
| 27 | bob     | NULL     | NULL | NULL | NULL         | NULL             | NULL          |
| 26 | mysql   | x        |   27 |   27 | MySQL Server | /var/lib/mysql   | /bin/false    |
| 25 | apache  | x        |   48 |   48 | Apache       | /usr/share/httpd | /sbin/nologin |
| 24 | plj     | x        | 1000 | 1000 |              | /home/plj        | /bin/bash     |
| 23 | haproxy | x        |  188 |  188 | haproxy      | /var/lib/haproxy | /sbin/nologin |
+----+---------+----------+------+------+--------------+------------------+---------------+
5 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;02：mysql之常用函数&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[常用函数]
        direction LR
        A[字符串函数] --&amp;gt; B[日期函数] --&amp;gt; C[聚集函数] --&amp;gt; D[数学计算] --&amp;gt; E[if函数] --&amp;gt; F[case函数]
    end

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;在电商公司的运营部门，为了评估商品销售情况，需要对数据库中的销售数据进行分析。数据库使用 MySQL 存储订单信息。运营人员需要统计不同商品类别的总销售额、平均销售单价和最高销售单价。
他们使用 MySQL 的聚合函数，&lt;code&gt;SUM()&lt;/code&gt; 计算每个商品类别的总销售额，&lt;code&gt;AVG()&lt;/code&gt; 求平均销售单价，&lt;code&gt;MAX()&lt;/code&gt; 获取最高销售单价。为了筛选出近期一个月内的有效订单，使用 &lt;code&gt;DATE_SUB()&lt;/code&gt; 函数确定时间范围。通过 &lt;code&gt;GROUP BY&lt;/code&gt; 对商品类别分组，将不同类别的数据区分开。最后，利用这些统计结果，运营人员制定针对性的营销策略，以提高销售额和利润。&lt;/p&gt;
&lt;h2&gt;二、为什么学mysql的函数&lt;/h2&gt;
&lt;p&gt;学习 MySQL 函数是提升数据库操作能力和数据处理效率的关键。在日常数据处理中，我们需要对数据进行各种计算、转换和筛选，而 MySQL 函数可以帮助我们轻松完成这些任务。&lt;/p&gt;
&lt;p&gt;例如，在统计销售数据时，我们可以使用聚合函数计算总销售额、平均价格等；在处理日期数据时，日期和时间函数能让我们方便地进行日期计算和格式化。掌握 MySQL 函数还能优化查询性能，通过合理运用函数，减少不必要的数据传输和处理，提高数据库的响应速度。此外，函数的使用还能使 SQL 语句更加简洁和易读，提升我们的工作效率和代码质量。&lt;/p&gt;
&lt;h2&gt;三、字符串函数&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[常用函数]
        direction LR
        A[字符串函数] --&amp;gt; B[日期函数] --&amp;gt; C[聚集函数] --&amp;gt; D[数学计算] --&amp;gt; E[if函数] --&amp;gt; F[case函数]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class A highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.1、返回字符串长度&lt;/h3&gt;
&lt;h4&gt;&lt;code&gt;LENGTH(str) &lt;/code&gt; 函数&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;函数名称&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LENGTH【冷斯】&lt;/code&gt; (在某些数据库中也称为 &lt;code&gt;LEN&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能说明&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;返回字符串的&lt;strong&gt;长度&lt;/strong&gt;。&lt;strong&gt;注意&lt;/strong&gt;：在大多数数据库中，此函数返回的是字符串的&lt;strong&gt;字节数&lt;/strong&gt;，而非字符数，这在处理多字节字符集（如UTF-8）时至关重要。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LENGTH【冷斯】(string)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;参数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;string&lt;/code&gt;: 需要计算长度的字符串。可以是字符串字面量（如&lt;code&gt;&apos;ABC&apos;&lt;/code&gt;）、字段名或变量。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;返回值&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一个整数值，表示字符串的&lt;strong&gt;字节数&lt;/strong&gt;。如果参数为 &lt;code&gt;NULL&lt;/code&gt;，则返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;示例&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1. &lt;code&gt;SELECT【涩莱克特】 LENGTH【冷斯】(&apos;Hello&apos;);&lt;/code&gt; -&amp;gt; &lt;strong&gt;5&lt;/strong&gt; (5个英文字符，在UTF-8中每个占1字节)&amp;lt;br&amp;gt;2. &lt;code&gt;SELECT【涩莱克特】 LENGTH【冷斯】(&apos;你好&apos;);&lt;/code&gt; -&amp;gt; &lt;strong&gt;6&lt;/strong&gt; (2个中文字符，在UTF-8中每个占3字节，共6字节)&amp;lt;br&amp;gt;3. &lt;code&gt;SELECT【涩莱克特】 LENGTH(column_name) from【弗乱】 table_name;&lt;/code&gt; -&amp;gt; 返回表中该字段各值的字节长度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;注意要点&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1. 字节 vs. 字符:&lt;/strong&gt; &amp;lt;br&amp;gt; - 这是最关键的区别。如果需要获取&lt;strong&gt;字符数&lt;/strong&gt;（通常更符合直觉），应使用 &lt;code&gt;CHAR_LENGTH【查_冷斯】()&lt;/code&gt; 或 &lt;code&gt;CHARACTER_LENGTH【冷斯】()&lt;/code&gt; 函数。&amp;lt;br&amp;gt; &lt;strong&gt;2. 数据库差异:&lt;/strong&gt; &amp;lt;br&amp;gt; - &lt;strong&gt;MySQL, MariaDB:&lt;/strong&gt; &lt;code&gt;LENGTH【冷斯】()&lt;/code&gt; 返回字节数，&lt;code&gt;CHAR_LENGTH【查_冷斯】()&lt;/code&gt; 返回字符数。&amp;lt;br&amp;gt; - &lt;strong&gt;SQL Server:&lt;/strong&gt; 使用 &lt;code&gt;LEN()&lt;/code&gt; 返回字符数（但会去掉尾部空格），使用 &lt;code&gt;DATALENGTH【得塔-冷斯】()&lt;/code&gt; 返回字节数。&amp;lt;br&amp;gt; - &lt;strong&gt;Oracle:&lt;/strong&gt; 使用 &lt;code&gt;LENGTHB()&lt;/code&gt; 返回字节数，&lt;code&gt;LENGTH【冷斯】()&lt;/code&gt; 返回字符数。&amp;lt;br&amp;gt; - &lt;strong&gt;PostgreSQL:&lt;/strong&gt; &lt;code&gt;LENGTH()&lt;/code&gt; 返回字符数，使用 &lt;code&gt;OCTET_LENGTH()&lt;/code&gt; 返回字节数。&amp;lt;br&amp;gt; - &lt;strong&gt;SQLite:&lt;/strong&gt; &lt;code&gt;LENGTH()&lt;/code&gt; 返回字符数。&amp;lt;br&amp;gt; &lt;strong&gt;3. 空字符串:&lt;/strong&gt; &lt;code&gt;LENGTH(&apos;&apos;)&lt;/code&gt; 返回 &lt;strong&gt;0&lt;/strong&gt;。&amp;lt;br&amp;gt; &lt;strong&gt;4. NULL 值:&lt;/strong&gt; &lt;code&gt;LENGTH(NULL)&lt;/code&gt; 返回 &lt;strong&gt;NULL&lt;/strong&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;使用建议&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;在不确定数据库字符集或需要处理多语言文本时，&lt;strong&gt;强烈建议使用 &lt;code&gt;CHAR_LENGTH【查_冷斯】】()&lt;/code&gt; 来获取字符数&lt;/strong&gt;，以避免因字符编码不同导致的意外结果。&lt;code&gt;LENGTH【冷斯】()&lt;/code&gt; 更适用于计算存储空间等需要字节精度的场景。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;LENGTH vs. CHAR_LENGTH&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;测量单位&lt;/th&gt;
&lt;th&gt;UTF-8 示例 &lt;code&gt;LENGTH【冷斯】(&apos;你好&apos;)&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;LENGTH【冷斯】(str)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;字节&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6&lt;/strong&gt; (2字符 * 3字节/字符)&lt;/td&gt;
&lt;td&gt;计算存储占用、网络传输大小&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;CHAR_LENGTH【查_冷斯】(str)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;字符&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;计算字符串的实际字符数量、显示长度、业务逻辑&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;LENGTH(str)&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;--LENGTH【冷斯】(str)             返字符串长度，以字节为单位
mysql&amp;gt; select【涩莱克特】 name from【弗乱】 moershi.user where【威尔】 name = &quot;root&quot; ;
+------+
| name |
+------+
| root |
+------+
1 row in set (0.00 sec)
mysql&amp;gt; select【涩莱克特】 name,length【冷斯】(name) as 字节个数 from moershi.user where【威尔】 name = &quot;root&quot; ;
+------+--------------+
| name | 字节个数      |
+------+--------------+
| root |            4  |
+------+--------------+
1 row in set (0.00 sec)

--一个汉字3个字节
mysql&amp;gt; select【涩莱克特】 name,length【冷斯】(name) from【弗乱】 moershi.employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id = 3 ;
+-----------+--------------+
| name      | length【冷斯】(name) |
+-----------+--------------+
| 李玉英    |            9 |
+-----------+--------------+
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;CHAR_LENGTH(str)&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;-- CHAR_LENGTH【查_冷斯】(str)        返回字符串长度，以字符为单位
mysql&amp;gt; select【涩莱克特】 name from【弗乱】 moershi.employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id = 3 ;
+-----------+
| name      |
+-----------+
| 李玉英    |
+-----------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 name,char_length【查_冷斯】(name) from【弗乱】 moershi.employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id = 3 ;
+-----------+-----------------------------+
| name      | char_length【查_冷斯】(name) |
+-----------+-----------------------------+
| 李玉英     |                 3           |
+-----------+-----------------------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2、将字符串转换为大写&lt;/h3&gt;
&lt;h4&gt;函数概览&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;UPPER【阿普厄】(str)&lt;/code&gt; 和 &lt;code&gt;UCASE【U kèi 斯】(str)&lt;/code&gt; 函数的功能完全相同，都是将字符串 &lt;code&gt;str&lt;/code&gt; 中的所有字母字符转换为大写形式。它们互为同义词，区别仅在于函数名称，以适应不同用户的习惯。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;函数名称&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UPPER【阿普厄】(str)&lt;/code&gt;, &lt;code&gt;UCASE【U kèi 斯】(str)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能描述&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;将字符串 &lt;code&gt;str&lt;/code&gt; 中的所有字母字符转换为大写形式。非字母字符（如数字、空格、特殊符号）保持不变。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;通用语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UPPER【阿普厄】(string【斯jǘn】)&lt;/code&gt; &amp;lt;br&amp;gt; &lt;code&gt;UCASE【U kèi 斯】(string【斯jǘn】)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;参数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;string【斯jǘn】&lt;/code&gt;: 需要转换的字符串。可以是字符串字面量（如 &lt;code&gt;&apos;abc&apos;&lt;/code&gt;）、字段名或变量。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;返回值&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一个新的字符串，其中所有小写字母已被转换为大写字母。如果参数为 &lt;code&gt;NULL，则返回 &lt;/code&gt;NULL`。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;基本用法&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; SELECT【涩莱克特】 UPPER【阿普厄】(&apos;Hello World!&apos;) AS UpperText;
-- 结果: &apos;HELLO WORLD!&apos;

mysql&amp;gt; SELECT【涩莱克特】 UCASE【U kèi 斯】(&apos;sql is fun&apos;) AS UpperText;
-- 结果: &apos;SQL IS FUN&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;总结与对比&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;UPPER【阿普厄】(str)&lt;/th&gt;
&lt;th&gt;UCASE【U kèi 斯】(str)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;将字符串转换为大写&lt;/td&gt;
&lt;td&gt;将字符串转换为大写&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;标准性&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;SQL 标准&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;非标准，但广泛实现&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;通用性&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;极高&lt;/strong&gt;，所有SQL数据库都支持&lt;/td&gt;
&lt;td&gt;很高，但并非所有数据库都支持（如Oracle不支持&lt;code&gt;UCASE【U kèi 斯】&lt;/code&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;推荐度&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;⭐️⭐️⭐️⭐️⭐️ (首选)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⭐️⭐️⭐️⭐️&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;-- UPPER【阿普厄】(str)和UCASE【U kèi 斯】(str)  将字符串中的字母全部转换成大写
mysql&amp;gt; select【涩莱克特】 name from【弗乱】  moershi.user where【威尔】 uid &amp;lt;= 3 ;
+--------+
| name   |
+--------+
| root   |
| bin    |
| daemon |
| adm    |
+--------+
4 rows in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 upper【阿普厄】(name) from【弗乱】  moershi.user where【威尔】 uid &amp;lt;= 3 ;
+-------------+
| upper【阿普厄】(name) |
+-------------+
| ROOT        |
| BIN         |
| DAEMON      |
| ADM         |
+-------------+
4 rows in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 ucase【U kèi 斯】(name) from【弗乱】  moershi.user where【威尔】 uid &amp;lt;= 3 ;
+-------------+
| ucase【U kèi 斯】(name) |
+-------------+
| ROOT        |
| BIN         |
| DAEMON      |
| ADM         |
+-------------+
4 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3、将字符串转换成小写&lt;/h3&gt;
&lt;p&gt;好的，这是关于 SQL 中 &lt;code&gt;LOWER【喽厄】()&lt;/code&gt; 和 &lt;code&gt;LCASE【L kèi 斯】()&lt;/code&gt; 函数的详细说明。&lt;/p&gt;
&lt;h4&gt;函数概览&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;LOWER【喽厄】(str)&lt;/code&gt; 和 &lt;code&gt;LCASE【L kèi 斯】(str)&lt;/code&gt; 函数的功能完全相同，都是将字符串 &lt;code&gt;str&lt;/code&gt; 中的所有字母字符转换为小写形式。它们互为同义词，区别仅在于函数名称。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;函数名称&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LOWER【喽厄】(str)&lt;/code&gt;, &lt;code&gt;LCASE【L kèi 斯】(str)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能描述&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;将字符串 &lt;code&gt;str&lt;/code&gt; 中的所有字母字符转换为小写形式。非字母字符（如数字、空格、特殊符号）保持不变。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;通用语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LOWER【喽厄】(string【斯jǘn】)&lt;/code&gt; &amp;lt;br&amp;gt; &lt;code&gt;LCASE【L kèi 斯】(string【斯jǘn】)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;参数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;string【斯jǘn】&lt;/code&gt;: 需要转换的字符串。可以是字符串字面量（如 &lt;code&gt;&apos;ABC&apos;&lt;/code&gt;）、字段名或变量。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;返回值&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一个新的字符串，其中所有大写字母已被转换为小写字母。如果参数为 &lt;code&gt;NULL&lt;/code&gt;，则返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h4&gt;基本用法与示例&lt;/h4&gt;
&lt;h5&gt;1. 直接转换文本字符串&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; SELECT LOWER【喽厄】(&apos;HELLO World! 123&apos;) AS LowerText;
+------------------+
| LowerText        |
+------------------+
| hello world! 123 |
+------------------+
1 row in set (0.00 sec)

-- 结果: &apos;hello world! 123&apos;

mysql&amp;gt; SELECT LCASE【L kèi 斯】(&apos;SQL Tutorial&apos;) AS LowerText;
+--------------+
| LowerText    |
+--------------+
| sql tutorial |
+--------------+
1 row in set (0.00 sec)

-- 结果: &apos;sql tutorial&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;3. 在 WHERE 子句中实现不区分大小写的比较或搜索&lt;/h5&gt;
&lt;p&gt;这是该函数最常用和实用的场景之一。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 查找类别为 &apos;electronics&apos; 的所有产品，不区分大小写
mysql&amp;gt; SELECT * FROM products WHERE LOWER【喽厄】(category) = &apos;electronics&apos;;

-- 在模糊查询中实现不区分大小写
mysql&amp;gt; SELECT * FROM users WHERE LOWER【喽厄】(email) LIKE &apos;%@gmail.com&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;4. 与 UPPER/UCASE 结合使用进行数据标准化&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;-- 将用户输入的用户名统一格式化为小写后存储，确保唯一性
mysql&amp;gt; UPDATE【阿普dei 特】 users SET username = LOWER【喽厄】(&apos;SomeUserName&apos;) WHERE id = 100;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;总结与对比&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;LOWER【喽厄】(str)&lt;/th&gt;
&lt;th&gt;LCASE【L kèi 斯】(str)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;将字符串转换为小写&lt;/td&gt;
&lt;td&gt;将字符串转换为小写&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;标准性&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;SQL 标准&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;非标准，但广泛实现&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;通用性&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;极高&lt;/strong&gt;，所有主流SQL数据库都支持&lt;/td&gt;
&lt;td&gt;很高，但并非所有数据库都支持（如 &lt;strong&gt;Oracle 不支持 &lt;code&gt;LCASE【L kèi 斯】&lt;/code&gt;&lt;/strong&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;推荐度&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;⭐️⭐️⭐️⭐️⭐️ (首选)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⭐️⭐️⭐️⭐️&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h5&gt;核心结论与最佳实践&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;功能完全相同&lt;/strong&gt;：&lt;code&gt;LOWER【喽厄】()&lt;/code&gt; 和 &lt;code&gt;LCASE【L kèi 斯】()&lt;/code&gt; 的功能&lt;strong&gt;完全一致&lt;/strong&gt;，选择哪一个通常取决于个人习惯。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;首选 &lt;code&gt;LOWER【喽厄】()&lt;/code&gt;&lt;/strong&gt;：&lt;strong&gt;&lt;code&gt;LOWER【喽厄】()&lt;/code&gt; 是 SQL 标准中定义的函数&lt;/strong&gt;，因此具有最广泛的数据库支持（包括 Oracle）。为了代码的最大兼容性、可读性和可移植性，&lt;strong&gt;应优先使用 &lt;code&gt;LOWER【喽厄】()&lt;/code&gt;&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主要应用场景&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;数据比较&lt;/strong&gt;：在 &lt;code&gt;WHERE&lt;/code&gt; 子句中进行不区分大小写的比较。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据搜索&lt;/strong&gt;：实现不区分大小写的搜索 (&lt;code&gt;LIKE&lt;/code&gt;)。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据标准化&lt;/strong&gt;：在存储或显示前将文本统一为小写格式。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;注意 NULL&lt;/strong&gt;：如果输入参数为 &lt;code&gt;NULL&lt;/code&gt;，输出结果也为 &lt;code&gt;NULL&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;-- LOWER【喽厄】(str)和LCASE【L kèi 斯】(str)    将str中的字母全部转换成小写
mysql&amp;gt; select【涩莱克特】 lower【喽厄】(&quot;ABCD&quot;) ;
+---------------+
| lower【喽厄】(&quot;ABCD&quot;) |
+---------------+
| abcd          |
+---------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 lcase【L kèi 斯】(&quot;ABCD&quot;) ;
+---------------+
| lcase【L kèi 斯】(&quot;ABCD&quot;) |
+---------------+
| abcd          |
+---------------+
1 row in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.4、从字符串中提取&lt;strong&gt;子串&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;substr【杀斯妥】&lt;/p&gt;
&lt;h4&gt;函数概览&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;SUBSTR【杀斯妥】()&lt;/code&gt; 函数用于从字符串中提取&lt;strong&gt;子串&lt;/strong&gt;。它是 SQL 中最重要和常用的字符串函数之一。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;函数名称&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTR【杀斯妥】(string【斯jǘn】, start, length)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;别名&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTRING【杀斯jǘn】()&lt;/code&gt; (功能完全相同，&lt;code&gt;SUBSTR【杀斯妥】&lt;/code&gt; 更常见)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能描述&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;从原字符串中返回一个从指定位置开始、具有指定长度的子字符串。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;通用语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTR【杀斯妥】(string【斯jǘn】, start [, length])&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;参数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1. &lt;code&gt;string【斯jǘn】&lt;/code&gt;：必需的。要提取子串的源字符串。&amp;lt;br&amp;gt;2. &lt;code&gt;start&lt;/code&gt;：必需的。开始位置。&amp;lt;br&amp;gt; &lt;strong&gt;重要&lt;/strong&gt;：&lt;strong&gt;起始位置通常为 1，而不是 0&lt;/strong&gt;。&amp;lt;br&amp;gt;3. &lt;code&gt;length&lt;/code&gt;：可选的。要提取的字符数。如果省略，则返回从 &lt;code&gt;start&lt;/code&gt; 开始到字符串结尾的所有字符。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;返回值&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;提取出的子字符串。如果任何参数为 &lt;code&gt;NULL&lt;/code&gt;，则返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;基本用法与示例&lt;/h4&gt;
&lt;h5&gt;1. 指定起始位置和长度&lt;/h5&gt;
&lt;p&gt;这是最常用的形式。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt;  SELECT SUBSTR【杀斯妥】(&apos;SQL Tutorial&apos;, 1, 3) AS ExtractString;
+---------------+
| ExtractString |
+---------------+
| SQL           |
+---------------+
1 row in set (0.02 sec)
-- 结果: &apos;SQL&apos; (从第1个字符开始，取3个字符)

mysql&amp;gt; SELECT SUBSTR【杀斯妥】(&apos;SQL Tutorial&apos;, 5, 4) AS ExtractString;
+---------------+
| ExtractString |
+---------------+
| Tuto          |
+---------------+
1 row in set (0.00 sec)
-- 结果: &apos;Tuto&apos; (从第5个字符(&apos;T&apos;)开始，取4个字符)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;2. 省略长度参数（提取到末尾）&lt;/h5&gt;
&lt;p&gt;如果省略第三个参数，函数将返回从起始位置到字符串末尾的所有字符。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt;  SELECT SUBSTR【杀斯妥】(&apos;SQL Tutorial&apos;, 5) AS ExtractString;
+---------------+
| ExtractString |
+---------------+
| Tutorial      |
+---------------+
1 row in set (0.00 sec)
-- 结果: &apos;Tutorial&apos; (从第5个字符开始，直到结束)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;3. 使用负起始位置（从末尾开始计数）&lt;/h5&gt;
&lt;p&gt;&lt;strong&gt;这是一个非常实用的功能&lt;/strong&gt;。许多数据库（如 MySQL、PostgreSQL、SQLite）支持使用负数作为 &lt;code&gt;start&lt;/code&gt; 参数，表示从字符串&lt;strong&gt;末尾&lt;/strong&gt;开始向前计数。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 提取最后 3 个字符
mysql&amp;gt; SELECT SUBSTR【杀斯妥】(&apos;SQL Tutorial&apos;, -3) AS ExtractString;
+---------------+
| ExtractString |
+---------------+
| ial           |
+---------------+
1 row in set (0.00 sec)
-- 结果: &apos;ial&apos;

-- 从倒数第 6 个字符开始，提取 4 个字符
mysql&amp;gt; SELECT SUBSTR【杀斯妥】(&apos;SQL Tutorial&apos;, -6, 4) AS ExtractString;
+---------------+
| ExtractString |
+---------------+
| tori          |
+---------------+
1 row in set (0.00 sec)
-- 结果: &apos;ori&apos; (从倒数第6位(&apos;o&apos;)开始，取4个字符。但后面只剩3个，所以只返回&apos;ori&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;注意：SQL Server 不支持负起始位置，需配合 &lt;code&gt;LEN()&lt;/code&gt; 函数计算。&lt;/em&gt;&lt;/p&gt;
&lt;h5&gt;4. 在查询中处理表字段数据&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;-- 提取每个人的姓氏（假设从第6个字符开始）
mysql&amp;gt; SELECT full_name, SUBSTR【杀斯妥】(full_name, 6) AS last_name FROM employees【ing普洛伊s】;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;总结与对比：SUBSTR【杀斯妥】 vs. SUBSTRING【杀斯jǘn】&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;SUBSTR【杀斯妥】(...)&lt;/th&gt;
&lt;th&gt;SUBSTRING【杀斯jǘn】(...)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;从字符串中提取子串&lt;/td&gt;
&lt;td&gt;从字符串中提取子串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;普及度&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;非常普遍&lt;/strong&gt;，是许多数据库中的主要函数名&lt;/td&gt;
&lt;td&gt;也很常见，是 SQL 标准名称&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTR【杀斯妥】(str, start, length)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTRING【杀斯jǘn】(str FROM start FOR length)&lt;/code&gt; (标准语法) 或 &lt;code&gt;SUBSTRING(str, start, length)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;数据库支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;MySQL, Oracle, SQLite, PostgreSQL, MariaDB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;SQL Server, PostgreSQL, MySQL&lt;/strong&gt; (也支持&lt;code&gt;SUBSTR&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;推荐度&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⭐️⭐️⭐️⭐️⭐️ (通用性极佳)&lt;/td&gt;
&lt;td&gt;⭐️⭐️⭐️⭐️ (是标准，但需注意数据库方言)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;不同数据库的注意事项&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;数据库&lt;/th&gt;
&lt;th&gt;主要函数&lt;/th&gt;
&lt;th&gt;负起始位置&lt;/th&gt;
&lt;th&gt;备注&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MySQL, MariaDB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTR【杀斯妥】()&lt;/code&gt; 或 &lt;code&gt;SUBSTRING【杀斯jǘn】()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;两者完全同义。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Oracle&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTR【杀斯妥】()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;不支持 &lt;code&gt;SUBSTRING【杀斯jǘn】&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SQL Server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTRING【杀斯jǘn】()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;不支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;需用 &lt;code&gt;LEN(string【斯jǘn】) + 1 - n&lt;/code&gt; 来计算从末尾开始的位置。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTRING【杀斯jǘn】()&lt;/code&gt; (标准) 或 &lt;code&gt;SUBSTR【杀斯妥】()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;两者都可用。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SQLite&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUBSTR【杀斯妥】()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;核心结论与最佳实践&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;功能核心&lt;/strong&gt;：&lt;code&gt;SUBSTR【杀斯妥】(str, start, length)&lt;/code&gt; 用于精确提取字符串的特定部分。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;起始索引&lt;/strong&gt;：&lt;strong&gt;牢记起始位置通常是 1&lt;/strong&gt;，这是与许多编程语言（如 Python、Java）从 0 开始索引的最大区别。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;负索引&lt;/strong&gt;：&lt;strong&gt;负起始位置是一个非常有用的特性&lt;/strong&gt;，可以轻松地从字符串末尾开始操作，但要注意 SQL Server 不支持。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;兼容性建议&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;如果你主要在 &lt;strong&gt;MySQL、Oracle、SQLite&lt;/strong&gt; 中工作，可以放心使用 &lt;code&gt;SUBSTR【杀斯妥】()&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;如果你在 &lt;strong&gt;SQL Server&lt;/strong&gt; 中工作，则必须使用 &lt;code&gt;SUBSTRING【杀斯jǘn】()&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;为了编写跨数据库兼容的 SQL，了解这些差异至关重要。在不确定时，查看数据库的官方文档是最好的方法。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;常见用途&lt;/strong&gt;：提取区号、获取文件扩展名、隐藏部分敏感信息（如 &lt;code&gt;SUBSTR【杀斯妥】(phone_number, -4)&lt;/code&gt; 显示手机尾号）、解析固定格式的代码等。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;--SUBSTR【杀斯妥】(s, start,end)     从s的start位置开始取出到end长度的子串
mysql&amp;gt; select【涩莱克特】 name from【弗乱】  moershi.employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id &amp;lt;= 3 ;
+-----------+
| name      |
+-----------+
| 梁伟      |
| 郭岩      |
| 李玉英    |
+-----------+
3 rows in set (0.00 sec)
--不是输出员工的姓 只输出名字（只输出第2、3个字符）
mysql&amp;gt; select【涩莱克特】 substr(name,2,3) from【弗乱】  moershi.employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id &amp;lt;= 3 ;
+------------------+
| substr(name,2,3) |
+------------------+
| 伟               |
| 岩               |
| 玉英             |
+------------------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.5、在一个字符串中查找另一个子字符串&lt;/h3&gt;
&lt;h4&gt;函数概览&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;INSTR()&lt;/code&gt; 函数用于在一个字符串中查找另一个子字符串，并返回其&lt;strong&gt;首次出现的位置&lt;/strong&gt;。如果未找到，则返回 0。它是一个非常重要的字符串查找函数。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;函数名称&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;INSTR(string【斯jǘn】, substring【杀斯jǘn】)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;别名&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LOCATE()&lt;/code&gt; (在MySQL中), &lt;code&gt;CHARINDEX()&lt;/code&gt; (在SQL Server中)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能描述&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;返回子字符串 &lt;code&gt;substring【杀斯jǘn】&lt;/code&gt; 在字符串 &lt;code&gt;string【斯jǘn】&lt;/code&gt; 中&lt;strong&gt;第一次出现&lt;/strong&gt;的起始位置。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;通用语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;INSTR(string【斯jǘn】, substring【杀斯jǘn】)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;扩展语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;某些数据库（如Oracle、MySQL）支持可选参数来指定起始搜索位置和出现次数：&lt;code&gt;INSTR(string【斯jǘn】, substring【杀斯jǘn】 [, start [, occurrence]])&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;参数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1. &lt;code&gt;string【斯jǘn】&lt;/code&gt;：必需的。被搜索的源字符串。&amp;lt;br&amp;gt;2. &lt;code&gt;substring【杀斯jǘn】&lt;/code&gt;：必需的。要查找的子字符串。&amp;lt;br&amp;gt;3. &lt;code&gt;start&lt;/code&gt;：可选的。开始搜索的位置，默认为 1。&amp;lt;br&amp;gt;4. &lt;code&gt;occurrence&lt;/code&gt;：可选的。指定要查找第几次出现的位置，默认为 1。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;返回值&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一个整数值，表示子串首次出现的起始位置。&amp;lt;br&amp;gt;&lt;strong&gt;位置从 1 开始计数&lt;/strong&gt;。&amp;lt;br&amp;gt;如果未找到子串，则返回 &lt;strong&gt;0&lt;/strong&gt;。&amp;lt;br&amp;gt;如果任何参数为 &lt;code&gt;NULL&lt;/code&gt;，则返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;基本用法与示例&lt;/h4&gt;
&lt;p&gt;为了演示，我们使用字符串 &lt;code&gt;&apos;Hello World! Welcome to the World of SQL.&apos;&lt;/code&gt; 作为示例源字符串。&lt;/p&gt;
&lt;h5&gt;1. 基本查找：查找子串首次出现的位置&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; SELECT INSTR(&apos;Hello World!&apos;, &apos;World&apos;) AS Position;
+----------+
| Position |
+----------+
|        7 |
+----------+
1 row in set (0.00 sec)

-- 结果: 7 (因为 &apos;W&apos; 是源字符串的第7个字符)
-- 分解: H e l l o [空格] W o r l d !
-- 位置: 1 2 3 4 5  6    7 8 9 10 11 12
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;2. 查找不存在的子串&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; SELECT INSTR(&apos;Hello World!&apos;, &apos;SQL&apos;) AS Position;
+----------+
| Position |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)
-- 结果: 0 (因为 &apos;SQL&apos; 没有出现)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;3. 在查询中处理表字段数据&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;-- 找到所有产品代码中连字符 &apos;-&apos; 的位置
mysql&amp;gt; SELECT product_code, INSTR(product_code, &apos;-&apos;) AS hyphen_position FROM products;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;4. 与其他函数组合使用（常与 SUBSTR 搭配）&lt;/h5&gt;
&lt;p&gt;一个非常强大的组合是先用 &lt;code&gt;INSTR&lt;/code&gt; 定位，再用 &lt;code&gt;SUBSTR&lt;/code&gt; 截取。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 提取产品代码中连字符之后的部分（型号）
mysql&amp;gt; SELECT product_code,SUBSTR(product_code, INSTR(product_code, &apos;-&apos;) + 1) AS model_number FROM products;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;结果：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;product_code&lt;/th&gt;
&lt;th&gt;model_number&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LAPTOP-001&lt;/td&gt;
&lt;td&gt;001&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MOUSE-002&lt;/td&gt;
&lt;td&gt;002&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KEYBOARD-003&lt;/td&gt;
&lt;td&gt;003&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;逻辑：先找到 &lt;code&gt;-&lt;/code&gt; 的位置 (N)，然后从 N+1 的位置开始截取到末尾。&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;总结与对比：INSTR vs. 其他类似函数&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;INSTR(string【斯jǘn】, substring【杀斯jǘn】)&lt;/th&gt;
&lt;th&gt;LOCATE (MySQL)&lt;/th&gt;
&lt;th&gt;CHARINDEX (SQL Server)&lt;/th&gt;
&lt;th&gt;POSITION (标准SQL)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;INSTR(str, substr)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LOCATE(substr, str [, start])&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CHARINDEX(substr, str [, start])&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;POSITION(substr IN str)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;参数顺序&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;(字符串, 子串)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;(子串, 字符串)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;(子串, 字符串)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;(子串 IN 字符串)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;起始位置&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;可选第三参数 &lt;code&gt;start&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;可选第三参数 &lt;code&gt;start&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;可选第三参数 &lt;code&gt;start&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;不支持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;出现次数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;可选第四参数 &lt;code&gt;occurrence&lt;/code&gt; (Oracle/MySQL)&lt;/td&gt;
&lt;td&gt;不支持&lt;/td&gt;
&lt;td&gt;不支持&lt;/td&gt;
&lt;td&gt;不支持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;返回值&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;位置 (从1开始) / 0&lt;/td&gt;
&lt;td&gt;位置 (从1开始) / 0&lt;/td&gt;
&lt;td&gt;位置 (从1开始) / 0&lt;/td&gt;
&lt;td&gt;位置 (从1开始) / 0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;不同数据库的注意事项与语法&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;数据库&lt;/th&gt;
&lt;th&gt;主要函数&lt;/th&gt;
&lt;th&gt;语法示例&lt;/th&gt;
&lt;th&gt;备注&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Oracle&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;INSTR&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;INSTR(&apos;abc&apos;, &apos;b&apos;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;支持扩展参数 (&lt;code&gt;start&lt;/code&gt;, &lt;code&gt;occurrence&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MySQL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;INSTR&lt;/code&gt; 或 &lt;code&gt;LOCATE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;INSTR(&apos;abc&apos;, &apos;b&apos;)&lt;/code&gt; 或 &lt;code&gt;LOCATE(&apos;b&apos;, &apos;abc&apos;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;INSTR&lt;/code&gt; 支持扩展参数，&lt;code&gt;LOCATE&lt;/code&gt; 支持 &lt;code&gt;start&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SQL Server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;CHARINDEX&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CHARINDEX(&apos;b&apos;, &apos;abc&apos;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;不支持 &lt;code&gt;occurrence&lt;/code&gt; 参数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;STRPOS&lt;/code&gt;&lt;/strong&gt; 或 &lt;code&gt;POSITION&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;STRPOS(&apos;abc&apos;, &apos;b&apos;)&lt;/code&gt; 或 &lt;code&gt;POSITION(&apos;b&apos; IN &apos;abc&apos;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;POSITION&lt;/code&gt; 是标准SQL语法&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SQLite&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;INSTR&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;INSTR(&apos;abc&apos;, &apos;b&apos;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;只支持两个基本参数&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;核心结论与最佳实践&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;功能核心&lt;/strong&gt;：&lt;code&gt;INSTR&lt;/code&gt; 用于&lt;strong&gt;定位&lt;/strong&gt;，而不是提取。它返回的是数字位置。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;黄金搭档&lt;/strong&gt;：&lt;code&gt;INSTR&lt;/code&gt; 常与 &lt;code&gt;SUBSTR&lt;/code&gt; 组合使用，实现“先定位，后截取”的强大功能。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;参数顺序陷阱&lt;/strong&gt;：&lt;strong&gt;不同数据库的参数顺序可能不同&lt;/strong&gt;（特别是 &lt;code&gt;INSTR&lt;/code&gt; 和 &lt;code&gt;CHARINDEX/LOCATE&lt;/code&gt;）。这是最大的混淆点，使用时务必注意。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;兼容性建议&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;如果你主要在 &lt;strong&gt;Oracle、SQLite&lt;/strong&gt; 中工作，使用 &lt;code&gt;INSTR&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;如果你在 &lt;strong&gt;MySQL&lt;/strong&gt; 中工作，&lt;code&gt;INSTR&lt;/code&gt; 和 &lt;code&gt;LOCATE&lt;/code&gt; 都可以，但注意参数顺序。&lt;/li&gt;
&lt;li&gt;如果你在 &lt;strong&gt;SQL Server&lt;/strong&gt; 中工作，必须使用 &lt;code&gt;CHARINDEX&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;为了编写符合SQL标准的代码，可以使用 &lt;code&gt;POSITION(substr IN str)&lt;/code&gt;，但功能可能最基础。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;常见用途&lt;/strong&gt;：查找特定字符或关键字的位置、解析结构化字符串（如URL、代码）、验证字符串中是否包含某部分内容（结果&amp;gt;0即表示包含）。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;-- INSTR(str,str1)        返回str1参数，在str参数内的位置
mysql&amp;gt;  select【涩莱克特】 name from【弗乱】  moershi.user where【威尔】 uid &amp;lt;= 3 ;
+--------+
| name   |
+--------+
| root   |
| bin    |
| daemon |
| adm    |
+--------+
4 rows in set (0.00 sec)

--查找名字里有a及出现的位置
mysql&amp;gt; select【涩莱克特】 name,instr(name,&quot;a&quot;) from【弗乱】  moershi.user where【威尔】 uid &amp;lt;= 3 ;
+--------+-----------------+
| name   | instr(name,&quot;a&quot;) |
+--------+-----------------+
| root   |               0 |
| bin    |               0 |
| daemon |               2 |
| adm    |               1 |
+--------+-----------------+
4 rows in set (0.00 sec)

-- 查找名字里有英字及出现的位置
mysql&amp;gt; select【涩莱克特】 name , instr(name,&quot;英&quot;) from【弗乱】  moershi.employees【ing普洛伊s】;
+-----------+-------------------+
| name      | instr(name,&quot;英&quot;)  |
+-----------+-------------------+
| 梁伟      |                 0 |
| 郭岩      |                 0 |
| 李玉英    |                 3 |
| 张健      |                 0 |
| 郑静      |                 0 |
| 牛建军    |                 0 |
| 刘斌      |                 0 |
| 汪云      |                 0 |
| 张建平    |                 0 |
| 郭娟      |                 0 |
| 郭兰英    |                 3 |
| 王英      |                 2 |
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.6、移除字符串开头和/或结尾处的指定字符&lt;/h3&gt;
&lt;h4&gt;函数概览&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;TRIM【垂姆】()&lt;/code&gt; 函数用于&lt;strong&gt;移除字符串开头和/或结尾处&lt;/strong&gt;的&lt;strong&gt;指定字符&lt;/strong&gt;（默认为空格）。它是数据清洗和标准化中最重要、最常用的函数之一。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;函数名称&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TRIM【垂姆】(...)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能描述&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;从字符串的&lt;strong&gt;两端&lt;/strong&gt;（开头和结尾）移除指定的前缀和后缀字符（默认为空格）。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;标准语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TRIM【垂姆】([removal_spec] [remove_char] FROM string【斯jǘn】)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;简化语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TRIM【垂姆】(string【斯jǘn】)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;参数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1. &lt;code&gt;string【斯jǘn】&lt;/code&gt;：必需的。要处理的源字符串。&amp;lt;br&amp;gt;2. &lt;code&gt;removal_spec&lt;/code&gt;：可选的。指定移除位置：&amp;lt;br&amp;gt;   - &lt;code&gt;LEADING&lt;/code&gt;：只移除开头的字符。&amp;lt;br&amp;gt;   - &lt;code&gt;TRAILING&lt;/code&gt;：只移除结尾的字符。&amp;lt;br&amp;gt;   - &lt;code&gt;BOTH&lt;/code&gt;：移除开头和结尾的字符（默认行为）。&amp;lt;br&amp;gt;3. &lt;code&gt;remove_char&lt;/code&gt;：可选的。指定要移除的字符，默认为空格 &lt;code&gt;&apos; &apos;&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;返回值&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一个新的字符串，已移除指定位置上的指定字符。如果参数为 &lt;code&gt;NULL&lt;/code&gt;，则返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;基本用法与示例&lt;/h4&gt;
&lt;h5&gt;基本语法​说明&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM] str)

&amp;gt; BOTH​​：移除字符串​​开头和结尾​​的字符（默认选项）。
&amp;gt; ​​LEADING​​：仅移除字符串​​开头​​的字符。
&amp;gt; ​​TRAILING​​：仅移除字符串​​结尾​​的字符。
&amp;gt; ​​remstr​​：要移除的字符（或字符串）。如果省略，​​默认移除空格​​。
&amp;gt; ​​str​​：要处理的原始字符串。
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;1. 基本用法：移除首尾空格（最常见用途）&lt;/h5&gt;
&lt;p&gt;这是最常用的情况，因此几乎所有数据库都支持最简形式。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; SELECT TRIM【垂姆】(&apos;   Hello World   &apos;) AS TrimmedString;
+---------------+
| TrimmedString |
+---------------+
| Hello World   |
+---------------+
1 row in set (0.00 sec)
-- 结果: &apos;Hello World&apos; (首尾空格被移除，中间空格保留)

-- 等效于标准写法的默认行为
mysql&amp;gt; SELECT TRIM【垂姆】(BOTH &apos; &apos; FROM &apos;   Hello World   &apos;) AS TrimmedString;
+---------------+
| TrimmedString |
+---------------+
| Hello World   |
+---------------+
1 row in set (0.00 sec)
-- 结果: &apos;Hello World&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;2. 指定移除位置 (LEADING / TRAILING / BOTH)&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;-- 只移除开头的空格 (LTRIM 的功能)
mysql&amp;gt; SELECT TRIM【垂姆】(LEADING FROM &apos;   Hello World   &apos;) AS LeadingTrimmed;
+----------------+
| LeadingTrimmed |
+----------------+
| Hello World    |
+----------------+
1 row in set (0.00 sec)
-- 结果: &apos;Hello World   &apos;

-- 只移除结尾的空格 (RTRIM 的功能)
mysql&amp;gt; SELECT TRIM【垂姆】(TRAILING FROM &apos;   Hello World   &apos;) AS TrailingTrimmed;
+-----------------+
| TrailingTrimmed |
+-----------------+
|    Hello World  |
+-----------------+
1 row in set (0.00 sec)
-- 结果: &apos;   Hello World&apos;

-- 明确指定移除两端 (BOTH 是默认值，可省略)
mysql&amp;gt; SELECT TRIM【垂姆】(BOTH FROM &apos;   Hello World   &apos;) AS BothTrimmed;
+-------------+
| BothTrimmed |
+-------------+
| Hello World |
+-------------+
1 row in set (0.00 sec)
-- 结果: &apos;Hello World&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;3. 移除指定字符（不仅仅是空格）&lt;/h5&gt;
&lt;p&gt;这是一个非常强大的功能，可以移除任何指定的字符。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 移除首尾的 &apos;x&apos;
mysql&amp;gt; SELECT TRIM【垂姆】(&apos;x&apos; FROM &apos;xxHello Worldxx&apos;) AS TrimmedString;
+---------------+
| TrimmedString |
+---------------+
| Hello World   |
+---------------+
1 row in set (0.00 sec)
-- 结果: &apos;Hello World&apos;

-- 移除首尾的连字符 &apos;-&apos;
mysql&amp;gt; SELECT TRIM【垂姆】(&apos;-&apos; FROM &apos;--SQL-&apos;) AS TrimmedString;
+---------------+
| TrimmedString |
+---------------+
| SQL           |
+---------------+
1 row in set (0.00 sec)
-- 结果: &apos;SQL&apos;

-- 组合使用：只移除开头的 &apos;0&apos;
mysql&amp;gt; SELECT TRIM【垂姆】(LEADING &apos;0&apos; FROM &apos;0001234500&apos;) AS TrimmedString;
+---------------+
| TrimmedString |
+---------------+
| 1234500       |
+---------------+
1 row in set (0.00 sec)
-- 结果: &apos;1234500&apos; (开头的0被移除，结尾的0保留)

-- 组合使用：只移除结尾的逗号 &apos;,&apos;
mysql&amp;gt; SELECT TRIM【垂姆】(TRAILING &apos;,&apos; FROM &apos;value1,value2,value3,,,&apos;) AS TrimmedString;
+----------------------+
| TrimmedString        |
+----------------------+
| value1,value2,value3 |
+----------------------+
1 row in set (0.00 sec)
-- 结果: &apos;value1,value2,value3&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;4. 在查询中处理表字段数据（数据清洗）&lt;/h5&gt;
&lt;p&gt;假设有一个 &lt;code&gt;users&lt;/code&gt; 表，由于数据导入问题，&lt;code&gt;name&lt;/code&gt; 字段可能包含多余空格：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;id&lt;/th&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&apos;  John Doe  &apos;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&apos;Alice  &apos;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;-- 清理并显示姓名
mysql&amp;gt; SELECT id, name, TRIM【垂姆】(name) AS cleaned_name FROM users;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;结果：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;id&lt;/th&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;cleaned_name&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&apos;  John Doe  &apos;&lt;/td&gt;
&lt;td&gt;&apos;John Doe&apos;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&apos;Alice  &apos;&lt;/td&gt;
&lt;td&gt;&apos;Alice&apos;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;-- 在 WHERE 子句中使用，确保比较的准确性
mysql&amp;gt; SELECT * FROM products WHERE TRIM【垂姆】(product_code) = &apos;ABC123&apos;;
-- 即使数据库中存的是 &apos; ABC123 &apos; 也能匹配
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;总结与对比：TRIM【垂姆】 vs. LTRIM/RTRIM&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;&lt;code&gt;TRIM【垂姆】()&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;LTRIM()&lt;/code&gt; / &lt;code&gt;RTRIM()&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;功能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;可灵活移除&lt;strong&gt;首&lt;/strong&gt;、&lt;strong&gt;尾&lt;/strong&gt;或&lt;strong&gt;两端&lt;/strong&gt;的指定字符&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LTRIM()&lt;/code&gt; 只移除&lt;strong&gt;开头&lt;/strong&gt;的空格/字符&amp;lt;br&amp;gt;&lt;code&gt;RTRIM()&lt;/code&gt; 只移除&lt;strong&gt;结尾&lt;/strong&gt;的空格/字符&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;灵活性&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;高&lt;/strong&gt;。通过参数配置功能&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;低&lt;/strong&gt;。功能单一，每个函数只做一件事&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;符合标准&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;是 ANSI SQL 标准&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;不是标准，但被广泛实现&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;移除指定字符&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;支持&lt;/strong&gt;。可移除任意指定字符&lt;/td&gt;
&lt;td&gt;在多数数据库中&lt;strong&gt;仅支持空格&lt;/strong&gt;，或语法有所不同&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;推荐度&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;⭐️⭐️⭐️⭐️⭐️ (首选)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⭐️⭐️⭐️ (用于简单场景或兼容旧代码)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h5&gt;&lt;code&gt;TRIM【垂姆】()&lt;/code&gt; 与 &lt;code&gt;LTRIM()&lt;/code&gt;/&lt;code&gt;RTRIM()&lt;/code&gt; 的等效操作&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;-- 移除开头空格：
mysql&amp;gt; TRIM【垂姆】(LEADING FROM &apos;  abc  &apos;) -- 结果: &apos;abc  &apos;
mysql&amp;gt; LTRIM(&apos;  abc  &apos;)             -- 结果: &apos;abc  &apos;

-- 移除结尾空格：
mysql&amp;gt; TRIM【垂姆】(TRAILING FROM &apos;  abc  &apos;) -- 结果: &apos;  abc&apos;
mysql&amp;gt; RTRIM(&apos;  abc  &apos;)              -- 结果: &apos;  abc&apos;

-- 移除两端空格：
mysql&amp;gt; TRIM【垂姆】(&apos;  abc  &apos;)               -- 结果: &apos;abc&apos;
-- 等效组合：
mysql&amp;gt; LTRIM(RTRIM(&apos;  abc  &apos;))       -- 结果: &apos;abc&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;不同数据库的注意事项&lt;/h5&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;数据库&lt;/th&gt;
&lt;th&gt;&lt;code&gt;TRIM【垂姆】()&lt;/code&gt; 支持程度&lt;/th&gt;
&lt;th&gt;备注&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MySQL, MariaDB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;完全支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;支持标准语法和简化语法&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;完全支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;支持标准语法和简化语法&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SQL Server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;支持 (2017及以上版本)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2017版本之前需使用 &lt;code&gt;LTRIM(RTRIM())&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Oracle&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;完全支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;支持标准语法和简化语法&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SQLite&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;支持简化语法 &lt;code&gt;TRIM【垂姆】(string【斯jǘn】)&lt;/code&gt;，但从3.38版本开始支持标准语法&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;核心结论与最佳实践&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;功能核心&lt;/strong&gt;：&lt;code&gt;TRIM【垂姆】()&lt;/code&gt; 用于&lt;strong&gt;清理字符串边界&lt;/strong&gt;的无关字符，最常用于移除空格。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;现代首选&lt;/strong&gt;：&lt;strong&gt;对于新的项目，应优先使用功能更强大、更符合标准的 &lt;code&gt;TRIM【垂姆】()&lt;/code&gt; 函数&lt;/strong&gt;，而不是 &lt;code&gt;LTRIM()&lt;/code&gt; 和 &lt;code&gt;RTRIM()&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据清洗&lt;/strong&gt;：在数据导入、数据验证和查询比较前，使用 &lt;code&gt;TRIM【垂姆】()&lt;/code&gt; 清理用户输入或外部数据至关重要，可以避免因首尾空格导致的匹配失败。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;灵活运用&lt;/strong&gt;：记住它可以移除&lt;strong&gt;任何指定字符&lt;/strong&gt;（如 &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, &lt;code&gt;,&lt;/code&gt;），而不仅仅是空格，这在处理固定格式的代码、数字字符串时非常有用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;兼容性&lt;/strong&gt;：虽然是最新标准，但已在主流数据库的最新版本中得到良好支持。对于旧版SQL Server等环境，需回退到 &lt;code&gt;LTRIM(RTRIM())&lt;/code&gt; 组合。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;--TRIM【垂姆】(s)            返回字符串s删除了两边空格之后的字符串
mysql&amp;gt; select【涩莱克特】 trim【垂姆】(&quot;  ABC  &quot;);
+-----------------+
| trim【垂姆】(&quot;  ABC  &quot;) |
+-----------------+
| ABC             |
+-----------------+
1 row in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、日期函数&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[常用函数]
        direction LR
        A[字符串函数] --&amp;gt; B[日期函数] --&amp;gt; C[聚集函数] --&amp;gt; D[数学计算] --&amp;gt; E[if函数] --&amp;gt; F[case函数]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class B highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;获取系统或指定日期与时间&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;curtime【科泰姆】()&lt;/td&gt;
&lt;td&gt;获取时间&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;curdate【科dei 特】()&lt;/td&gt;
&lt;td&gt;获取日期&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;now【闹】()&lt;/td&gt;
&lt;td&gt;获取日期和时间&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;year【耶尔】()&lt;/td&gt;
&lt;td&gt;获取年&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;month【mèn斯】()&lt;/td&gt;
&lt;td&gt;获取月&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;day【dèi】()&lt;/td&gt;
&lt;td&gt;获取日&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;week【wèi kē】()&lt;/td&gt;
&lt;td&gt;获取一年中的第几周&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;date【dei 特】()&lt;/td&gt;
&lt;td&gt;获取日期&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;weekday【wèi kē dèi】()&lt;/td&gt;
&lt;td&gt;获取一周中的周几&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;time【泰姆】()&lt;/td&gt;
&lt;td&gt;获取时间&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;hour【ào é】()&lt;/td&gt;
&lt;td&gt;获取小时&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;minute【密 ní 特】 ()&lt;/td&gt;
&lt;td&gt;获取分钟&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;second【塞耿特】()&lt;/td&gt;
&lt;td&gt;获取秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;quarter【扩特】()&lt;/td&gt;
&lt;td&gt;获取一年中第几季度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;monthname【mòn斯-内姆】()&lt;/td&gt;
&lt;td&gt;获取月份名称&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dayname【dei 内姆】()&lt;/td&gt;
&lt;td&gt;获取日期对应的星期名&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dayofyear【dèi诶 符 耶尔】()&lt;/td&gt;
&lt;td&gt;获取一年中第几天&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dayofmonth【dèi诶 符 mèn斯】()&lt;/td&gt;
&lt;td&gt;获取一月中第几天&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; select【涩莱克特】 curtime【科泰姆】(); //获取系统时间
+-----------+
| curtime【科泰姆】() |
+-----------+
| 17:42:20  |
+-----------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 curdate【科dei 特】();//获取系统日期
+------------+
| curdate【科dei 特】()  |
+------------+
| 2023-05-24 |
+------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 now【闹】() ;//获取系统日期+时间
+---------------------+
| now【闹】()               |
+---------------------+
| 2023-05-24 17:42:29 |
+---------------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 year【耶尔】(now【闹】()) ; //获取系统当前年
+-------------+
| year【耶尔】(now【闹】()) |
+-------------+
|        2023 |
+-------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 month【mèn斯】(now【闹】()) ; //获取系统当前月
+--------------+
| month【mèn斯】(now【闹】()) |
+--------------+
|            5 |
+--------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 day【dèi】(now【闹】()) ; //获取系统当前日
+------------+
| day【dèi】(now【闹】()) |
+------------+
|         24 |
+------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 hour【ào é】(now【闹】()) ; //获取系统当前小时
+-------------+
| hour【ào é】(now【闹】()) |
+-------------+
|          17 |
+-------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 minute【密 ní 特】 (now【闹】()) ; //获取系统当分钟
+---------------+
| minute【密 ní 特】 (now【闹】()) |
+---------------+
|            46 |
+---------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 second【塞耿特】(now【闹】()) ; //获取系统当前秒
+---------------+
| second【塞耿特】(now【闹】()) |
+---------------+
|            34 |
+---------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 time【泰姆】(now【闹】()) ;//获取当前系统时间
+-------------+
| time【泰姆】(now【闹】()) |
+-------------+
| 17:47:36    |
+-------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 date【dei 特】(now【闹】()) ; //获取当前系统日期
+-------------+
| date【dei 特】(now【闹】()) |
+-------------+
| 2023-05-24  |
+-------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 curdate【科dei 特】();//获取当前系统日志
+------------+
| curdate【科dei 特】()  |
+------------+
| 2023-05-24 |
+------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 dayofmonth【dèi诶 符 mèn斯】(curdate【科dei 特】());//获取一个月的第几天
+-----------------------+
| dayofmonth【dèi诶 符 mèn斯】(curdate【科dei 特】()) |
+-----------------------+
|                    24 |
+-----------------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 dayofyear【dèi诶 符 耶尔】(curdate【科dei 特】());//获取一年中的第几天
+----------------------+
| dayofyear【dèi诶 符 耶尔】(curdate【科dei 特】()) |
+----------------------+
|                  144 |
+----------------------+
1 row in set (0.00 sec)

mysql&amp;gt;
mysql&amp;gt; select【涩莱克特】 monthname【mòn斯-内姆】(curdate【科dei 特】());//获取月份名
+----------------------+
| monthname【mòn斯-内姆】(curdate【科dei 特】()) |
+----------------------+
| May                  |
+----------------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 dayname【dei 内姆】(curdate【科dei 特】());//获取星期名
+--------------------+
| dayname【dei 内姆】(curdate【科dei 特】()) |
+--------------------+
| Wednesday          |
+--------------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 quarter【扩特】(curdate【科dei 特】());//获取一年中的第几季度
+--------------------+
| quarter【扩特】(curdate【科dei 特】()) |
+--------------------+
|                  2 |
+--------------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 week【wèi kē】(now【闹】());//一年中的第几周
+-------------+
| week【wèi kē】(now【闹】()) |
+-------------+
|          21 |
+-------------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 weekday【wèi kē dèi】(now【闹】())；//一周中的周几 
+----------------+
| weekday【wèi kē dèi】(now【闹】()) |
+----------------+
|              2 |
+----------------+
1 row in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、聚集函数&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[常用函数]
        direction LR
        A[字符串函数] --&amp;gt; B[日期函数] --&amp;gt; C[聚集函数] --&amp;gt; D[数学计算] --&amp;gt; E[if函数] --&amp;gt; F[case函数]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class C highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;对数值类型表头下的数据做统计&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;p&gt;输出3号员工2018每个月的基本工资&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; select【涩莱克特】 basic【贝斯克】 from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】 employee【ing普洛伊】_id=3 and year【耶尔】(date【dei 特】)=2018;
+-------+
| basic【贝斯克】 |
+-------+
|  9261 |
|  9261 |
|  9261 |
|  9261 |
|  9261 |
|  9261 |
|  9261 |
|  9261 |
|  9261 |
|  9261 |
|  9261 |
|  9724 |
+-------+
12 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;sum(表头名) 求和&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 sum(basic【贝斯克】) from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】 employee【ing普洛伊】_id=3 and year【耶尔】(date【dei 特】)=2018;
+------------+
| sum(basic【贝斯克】) |
+------------+
|     111595 |
+------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;avg(表头名) 计算平均值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 avg(basic【贝斯克】) from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】 employee【ing普洛伊】_id=3 and year【耶尔】(date【dei 特】)=2018;
+------------+
| avg(basic【贝斯克】) |
+------------+
|  9299.5833 |
+------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;min(表头名) 获取最小值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 min(basic【贝斯克】) from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】 employee【ing普洛伊】_id=3 and year【耶尔】(date【dei 特】)=2018;
+------------+
| min(basic【贝斯克】) |
+------------+
|       9261 |
+------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;max(表头名) 获取最大值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 max(basic【贝斯克】) from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】 employee【ing普洛伊】_id=3 and year【耶尔】(date【dei 特】)=2018;
+------------+
| max(basic【贝斯克】) |
+------------+
|       9724 |
+------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;count【kàn特】(表头名) 统计表头值个数&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//输出3号员工2018年奖金小于3000的奖金
mysql&amp;gt; select【涩莱克特】 bonus【波诺斯】 from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】 employee【ing普洛伊】_id=3 and year【耶尔】(date【dei 特】)=2018 and bonus【波诺斯】&amp;lt;3000; 
+-------+
| bonus【波诺斯】 |
+-------+
|  1000 |
|  1000 |
|  1000 |
+-------+
3 rows in set (0.00 sec)
//统计3号员工2018年奖金小于3000的次数
mysql&amp;gt; select【涩莱克特】 count【kàn特】(bonus【波诺斯】) from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】 employee【ing普洛伊】_id=3 and year【耶尔】(date【dei 特】)=2018 and bonus【波诺斯】&amp;lt;3000;  
+--------------+
| count【kàn特】(bonus【波诺斯】) |
+--------------+
|            3 |
+--------------+
1 row in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、数学计算&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[常用函数]
        direction LR
        A[字符串函数] --&amp;gt; B[日期函数] --&amp;gt; C[聚集函数] --&amp;gt; D[数学计算] --&amp;gt; E[if函数] --&amp;gt; F[case函数]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class D highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;对行中的列做计算&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;符号&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;th&gt;例子&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;+&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;加法&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uid + gid&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;减法&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uid - gid&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;乘法&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uid * gid&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;除法&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uid / gid&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;%&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;取余数（求模）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uid % gid&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;提高优先级&lt;/td&gt;
&lt;td&gt;&lt;code&gt;(uid + gid) / 2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;p&gt;输出8号员工2019年1月10 工资总和&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 employee【ing普洛伊】_id,date【dei 特】,basic【贝斯克】 +  bonus【波诺斯】  as 总工资 from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】employee【ing普洛伊】_id = 8 and date【dei 特】=20190110;
+-------------------------+------------+-----------------+
| employee【ing普洛伊】_id | date【dei 特】       |     总工资       |
+-------------------------+------------+-----------------+
|           8             | 2019-01-10 |          24093  |
+-------------------------+------------+-----------------+
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出8号员工的名字和年龄&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 name, 当前年份 - year【耶尔】(birth_date【dei 特】) as 年龄 from【弗乱】 moershi.employees【ing普洛伊s】  where【威尔】employee【ing普洛伊】_id = 8 ;

-- mysql&amp;gt; select name, year【耶尔】(now【闹】()) - year【耶尔】(birth_date【dei 特】) as 年龄 from moershi.employees where employee_id=8;
-- year【耶尔】(now【闹】())  获取当前年份
+--------+--------+
| name   | 年龄   |
+--------+--------+
| 汪云   |     29 |
+--------+--------+
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看8号员工2019年1月10 基本工资翻3倍的 值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 employee【ing普洛伊】_id , basic【贝斯克】 , basic【贝斯克】 * 3  as 工资翻三倍  from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】 employee【ing普洛伊】_id=8  and date【dei 特】=20190110;

-- mysql&amp;gt; select employee_id,basic,basic * 3 as 工资翻三倍 from moershi.salary where employee_id=8 and date=20190110;
+-------------+-------+-----------------+
| employee【ing普洛伊】_id | basic【贝斯克】 | 工资翻三倍      |
+-------------+-------+-----------------+
|           8 | 23093 |           69279 |
+-------------+-------+-----------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看8号员工2019年1月10的平均工资&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 employee【ing普洛伊】_id ,  (basic【贝斯克】+bonus【波诺斯】)/2 as 平均工资  from【弗乱】 moershi.salary【撒拉瑞】 where【威尔】  employee【ing普洛伊】_id=8  and date【dei 特】=20190110 ;

--mysql&amp;gt; select employee_id,(basic + bonus)/2 as 平均工资 from moershi.salary where employee_id=8 and date=20190110;
+-------------+--------------+
| employee【ing普洛伊】_id | 平均工资     |
+-------------+--------------+
|           8 |   12046.5000 |
+-------------+--------------+
1 row in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出员工编号1-10之间偶数员工编号及对应的员工名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 employee【ing普洛伊】_id , name  from【弗乱】  moershi.employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id  between【B豚ing】 1 and 10  and  employee【ing普洛伊】_id % 2  =  0   ;

-- mysql&amp;gt; select employee_id,name from moershi.employees where employee_id between 1 and 10 and employee_id % 2 = 0;
+-------------+-----------+
| employee【ing普洛伊】_id | name      |
+-------------+-----------+
|           2 | 郭岩      |
|           4 | 张健      |
|           6 | 牛建军    |
|           8 | 汪云      |
|          10 | 郭娟      |
+-------------+-----------+
5 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;七、if函数&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[常用函数]
        direction LR
        A[字符串函数] --&amp;gt; B[日期函数] --&amp;gt; C[聚集函数] --&amp;gt; D[数学计算] --&amp;gt; E[if函数] --&amp;gt; F[case函数]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class E highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;if(条件,v1,v2) 如果条件是TRUE则返回v1，否则返回v2&lt;/p&gt;
&lt;p&gt;ifnull(v1,v2) 如果v1不为NULL，则返回v1，否则返回v2&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;IF 函数&lt;/th&gt;
&lt;th&gt;IFNULL 函数&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;主要用途&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;通用的条件判断，根据条件真假返回不同值&lt;/td&gt;
&lt;td&gt;专门处理 &lt;code&gt;NULL&lt;/code&gt; 值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;参数数量&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;三个：&lt;code&gt;IF(条件, 值_if_true, 值_if_false)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;两个：&lt;code&gt;IFNULL(表达式, 替换值)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;核心逻辑&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;条件为真（非0且非NULL）返回第二个参数，否则返回第三个参数&lt;/td&gt;
&lt;td&gt;表达式不为&lt;code&gt;NULL&lt;/code&gt;时返回其自身，否则返回替换值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;适用场景&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;两种可能性的选择，如分类、状态转换&lt;/td&gt;
&lt;td&gt;字段可能为&lt;code&gt;NULL&lt;/code&gt;时提供默认值，防止计算错误&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;💡 认识 &lt;code&gt;IF&lt;/code&gt; 函数&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;IF&lt;/code&gt; 函数就像一个简单的“如果...那么...否则...”判断器。它的基本语法是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IF(condition, value_if_true, value_if_false)
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;condition&lt;/strong&gt;：要判断的条件表达式。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;value_if_true&lt;/strong&gt;：当条件为真（TRUE，即非0且非NULL）时返回的值。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;value_if_false&lt;/strong&gt;：当条件为假（FALSE 或 NULL）时返回的值。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;使用示例&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 根据年龄判断是否成年
SELECT name, IF(age &amp;gt;= 18, &apos;成年&apos;, &apos;未成年&apos;) AS age_group FROM users;

-- 在商品查询中显示折扣信息
SELECT product_name, price, IF(price &amp;gt; 100, &apos;高价商品&apos;, &apos;普通商品&apos;) AS price_category FROM products;

-- 注意：直接判断浮点数时，MySQL会尝试将其转为整数，这可能不是你想要的结果
SELECT IF(0.1, 1, 0); -- 返回 0，因为0.1被转为整数0后判断为假
SELECT IF(0.1 &amp;lt;&amp;gt; 0, 1, 0); -- 返回 1，这是正确的比较方式
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;演示if（） 语句的执行过程&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】  if(1 = 2 , &quot;a&quot;,&quot;b&quot;);
+---------------------+
| if(1 = 2 , &quot;a&quot;,&quot;b&quot;) |
+---------------------+
| b                   |
+---------------------+
1 row in set (0.00 sec)
mysql&amp;gt; select【涩莱克特】  if( 1 = 1 , &quot;a&quot;,&quot;b&quot;);
+---------------------+
| if(1 = 1 , &quot;a&quot;,&quot;b&quot;) |
+---------------------+
| a                   |
+---------------------+
1 row in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;🔄 掌握 &lt;code&gt;IFNULL&lt;/code&gt; 函数&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;IFNULL&lt;/code&gt; 函数专为处理可能为 &lt;code&gt;NULL&lt;/code&gt; 的值而设计，提供回退方案。它的语法更简洁：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IFNULL(expression, replacement_value)
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;expression&lt;/strong&gt;：要检查的表达式或字段。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;replacement_value&lt;/strong&gt;：如果 &lt;code&gt;expression&lt;/code&gt; 为 &lt;code&gt;NULL&lt;/code&gt;，则返回此值。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;使用示例&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 为用户表中邮箱为空的记录提供默认显示
SELECT username, IFNULL(email, &apos;未提供邮箱&apos;) AS user_email FROM users;

-- 在计算中避免NULL值导致整体结果为NULL
SELECT product, price, discount, price * IFNULL(discount, 1) AS final_price FROM sales;

-- IFNULL返回值的数据类型取决于上下文
SELECT IFNULL(1, &apos;test&apos;); -- 在临时表中，test列的类型可能是CHAR(4)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;演示ifnull（） 语句的执行过程&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; mysql&amp;gt; select【涩莱克特】  ifnull(&quot;abc&quot;,&quot;xxx&quot;);
+---------------------+
| ifnull(&quot;abc&quot;,&quot;xxx&quot;) |
+---------------------+
| abc                 |
+---------------------+
1 row in set (0.00 sec)
mysql&amp;gt; select【涩莱克特】  ifnull(null,&quot;xxx&quot;);
+--------------------+
| ifnull(null,&quot;xxx&quot;) |
+--------------------+
| xxx                |
+--------------------+
1 row in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查询例子&lt;/p&gt;
&lt;p&gt;根据uid 号 输出用户类型&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 name,uid,if(uid &amp;lt; 1000 , &quot;系统用户&quot;,&quot;创建用户&quot;) as 用户类型  from【弗乱】 moershi.user;
+-----------------+-------+--------------+
| name            | uid   | 用户类型     |
+-----------------+-------+--------------+
| root            |     0 | 系统用户     |
| bin             |     1 | 系统用户     |
| daemon          |     2 | 系统用户     |
| adm             |     3 | 系统用户     |
| lp              |     4 | 系统用户     |
| sync            |     5 | 系统用户     |
| shutdown        |     6 | 系统用户     |
| halt            |     7 | 系统用户     |
| mail            |     8 | 系统用户     |
| operator        |    11 | 系统用户     |
| games           |    12 | 系统用户     |
| ftp             |    14 | 系统用户     |
| nobody          |    99 | 系统用户     |
| systemd-network |   192 | 系统用户     |
| dbus            |    81 | 系统用户     |
| polkitd         |   999 | 系统用户     |
| sshd            |    74 | 系统用户     |
| postfix         |    89 | 系统用户     |
| chrony          |   998 | 系统用户     |
| rpc             |    32 | 系统用户     |
| rpcuser         |    29 | 系统用户     |
| nfsnobody       | 65534 | 创建用户     |
| haproxy         |   188 | 系统用户     |
| plj             |  1000 | 创建用户     |
| apache          |    48 | 系统用户     |
| mysql           |    27 | 系统用户     |
| bob             |  NULL | 创建用户     |
+-----------------+-------+--------------+
27 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;根据shell 输出用户类型&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt;  select【涩莱克特】 name , shell  , if(shell = &quot;/bin/bash&quot; , &quot;交互用户&quot;,&quot;非交户用户&quot;) as 用户类型 from【弗乱】 moershi.user;
+-----------------+----------------+-----------------+
| name            | shell          | 用户类型        |
+-----------------+----------------+-----------------+
| root            | /bin/bash      | 交互用户        |
| bin             | /sbin/nologin  | 非交户用户      |
| daemon          | /sbin/nologin  | 非交户用户      |
| adm             | /sbin/nologin  | 非交户用户      |
| lp              | /sbin/nologin  | 非交户用户      |
| sync            | /bin/sync      | 非交户用户      |
| shutdown        | /sbin/shutdown | 非交户用户      |
| halt            | /sbin/halt     | 非交户用户      |
| mail            | /sbin/nologin  | 非交户用户      |
| operator        | /sbin/nologin  | 非交户用户      |
| games           | /sbin/nologin  | 非交户用户      |
| ftp             | /sbin/nologin  | 非交户用户      |
| nobody          | /sbin/nologin  | 非交户用户      |
| systemd-network | /sbin/nologin  | 非交户用户      |
| dbus            | /sbin/nologin  | 非交户用户      |
| polkitd         | /sbin/nologin  | 非交户用户      |
| sshd            | /sbin/nologin  | 非交户用户      |
| postfix         | /sbin/nologin  | 非交户用户      |
| chrony          | /sbin/nologin  | 非交户用户      |
| rpc             | /sbin/nologin  | 非交户用户      |
| rpcuser         | /sbin/nologin  | 非交户用户      |
| nfsnobody       | /sbin/nologin  | 非交户用户      |
| haproxy         | /sbin/nologin  | 非交户用户      |
| plj             | /bin/bash      | 交互用户        |
| apache          | /sbin/nologin  | 非交户用户      |
| mysql           | /bin/false     | 非交户用户      |
| bob             | NULL           | 非交户用户      |
+-----------------+----------------+-----------------+
27 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;插入没有家目录的用户&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; insert【因涩特】   into   moershi.user (name, homedir) values【挖柳斯】 (&quot;jerrya&quot;,null);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看时加判断&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt;  select【涩莱克特】 name  姓名, ifnull(homedir,&quot;NO  home&quot;)as 家目录  from【弗乱】  moershi.user;
+-----------------+--------------------+
| 姓名            | 家目录             |
+-----------------+--------------------+
| root            | /root              |
| bin             | /bin               |
| daemon          | /sbin              |
| adm             | /var/adm           |
| lp              | /var/spool/lpd     |
| sync            | /sbin              |
| shutdown        | /sbin              |
| halt            | /sbin              |
| mail            | /var/spool/mail    |
| operator        | /root              |
| games           | /usr/games         |
| ftp             | /var/ftp           |
| nobody          | /                  |
| systemd-network | /                  |
| dbus            | /                  |
| polkitd         | /                  |
| sshd            | /var/empty/sshd    |
| postfix         | /var/spool/postfix |
| chrony          | /var/lib/chrony    |
| rpc             | /var/lib/rpcbind   |
| rpcuser         | /var/lib/nfs       |
| nfsnobody       | /var/lib/nfs       |
| haproxy         | /var/lib/haproxy   |
| plj             | /home/plj          |
| apache          | /usr/share/httpd   |
| mysql           | /var/lib/mysql     |
| bob             | NO  home           |
| jerrya          | NO  home           |
+-----------------+--------------------+
28 rows in set (0.00 sec)
Mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;八、case【kèi 斯】函数&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[常用函数]
        direction LR
        A[字符串函数] --&amp;gt; B[日期函数] --&amp;gt; C[聚集函数] --&amp;gt; D[数学计算] --&amp;gt; E[if函数] --&amp;gt; F[case函数]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class F highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;命令格式&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CASE 表头名              
WHEN【问】 值1 then【diān~】 输出结果 
WHEN【问】 值2 then【diān~】 输出结果  
WHEN【问】 值3 then【diān~】 输出结果 
ELSE 输出结果  
END
或
CASE              
WHEN【问】  判断条件1 then【diān~】 输出结果 
WHEN【问】  判断条件2 then【diān~】 输出结果  
WHEN【问】  判断条件3 then【diān~】 输出结果 
ELSE  输出结果  
END
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;步骤&lt;/th&gt;
&lt;th&gt;简单 CASE：精确匹配器 (&lt;code&gt;CASE 表头名 WHEN【问】 ...&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;搜索 CASE：条件扫描仪 (&lt;code&gt;CASE WHEN ...&lt;/code&gt;)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;取出当前行中 &lt;code&gt;表头名&lt;/code&gt; 字段的值。&lt;/td&gt;
&lt;td&gt;评估 &lt;strong&gt;第一个&lt;/strong&gt; &lt;code&gt;WHEN【问】&lt;/code&gt; 后的&lt;strong&gt;判断条件1&lt;/strong&gt; (如 &lt;code&gt;salary &amp;gt; 5000&lt;/code&gt;) 是真还是假。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;将这个值&lt;strong&gt;按顺序&lt;/strong&gt;与 &lt;code&gt;WHEN【问】&lt;/code&gt; 后的值（值1、值2...）进行&lt;strong&gt;相等比较&lt;/strong&gt;。&lt;/td&gt;
&lt;td&gt;如果 &lt;strong&gt;判断条件1&lt;/strong&gt; 为 &lt;strong&gt;TRUE&lt;/strong&gt;，则立刻返回 &lt;strong&gt;结果1&lt;/strong&gt;，&lt;strong&gt;过程结束&lt;/strong&gt;，后续条件被忽略。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一旦遇到一个&lt;strong&gt;相等的值&lt;/strong&gt;（如 &lt;code&gt;值2&lt;/code&gt;），则立刻返回其对应的 &lt;code&gt;then【diān~】&lt;/code&gt; &lt;strong&gt;结果2&lt;/strong&gt;，&lt;strong&gt;过程结束&lt;/strong&gt;。&lt;/td&gt;
&lt;td&gt;如果为 &lt;strong&gt;FALSE&lt;/strong&gt;，则继续评估&lt;strong&gt;下一个&lt;/strong&gt;条件 (&lt;strong&gt;判断条件2&lt;/strong&gt;)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;如果所有 &lt;code&gt;WHEN【问】&lt;/code&gt; 值都不匹配，则最终返回 &lt;code&gt;ELSE&lt;/code&gt; 部分的输出结果。&lt;/td&gt;
&lt;td&gt;后续条件依此类推，直到找到一个为 TRUE 的条件。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;如果没有 &lt;code&gt;ELSE&lt;/code&gt; 部分且无匹配项，则返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/td&gt;
&lt;td&gt;如果所有条件都为 FALSE，则返回 &lt;code&gt;ELSE&lt;/code&gt; 部分的结果；若无 &lt;code&gt;ELSE&lt;/code&gt; 则返回 &lt;code&gt;NULL&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;如果表头名等于某个值，则返回对应位置then【diān~】后面的值并结束判断，&lt;/p&gt;
&lt;p&gt;如果与所有值都不相等，则返回else后面的结果并结束判断&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;p&gt;查看部门表(departments)所有行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】  * from【弗乱】 moershi.departments;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|       1 | 人事部    |
|       2 | 财务部    |
|       3 | 运维部    |
|       4 | 开发部    |
|       5 | 测试部    |
|       6 | 市场部    |
|       7 | 销售部    |
|       8 | 法务部    |
+---------+-----------+
8 rows in set (0.03 sec)

//输出部门类型
select dept_id, dept_name,
case dept_name
when【问】 &apos;运维部&apos; then【diān~】 &apos;技术部门&apos;
when【问】 &apos;开发部&apos; then【diān~】 &apos;技术部门&apos;
when【问】 &apos;测试部&apos; then【diān~】 &apos;技术部门&apos;
else &apos;非技术部门&apos;
end as  部门类型   from【弗乱】  moershi.departments;
+---------+-----------+-----------------+
| dept_id | dept_name | 部门类型        |
+---------+-----------+-----------------+
|       1 | 人事部    | 非技术部门      |
|       2 | 财务部    | 非技术部门      |
|       3 | 运维部    | 技术部门        |
|       4 | 开发部    | 技术部门        |
|       5 | 测试部    | 技术部门        |
|       6 | 市场部    | 非技术部门      |
|       7 | 销售部    | 非技术部门      |
|       8 | 法务部    | 非技术部门      |
+---------+-----------+-----------------+
8 rows in set (0.00 sec)

或
mysql&amp;gt; select【涩莱克特】 dept_id,dept_name,
    -&amp;gt; case
    -&amp;gt; when【问】 dept_name=&quot;运维部&quot;  then【diān~】 &quot;技术部&quot;
    -&amp;gt; when【问】 dept_name=&quot;开发部&quot;  then【diān~】 &quot;技术部&quot;
    -&amp;gt; when【问】 dept_name=&quot;测试部&quot;  then【diān~】 &quot;技术部&quot;
    -&amp;gt; else &quot;非技术部&quot;
    -&amp;gt; end as 部门类型  from【弗乱】  moershi.departments;
+---------+-----------+--------------+
| dept_id | dept_name | 部门类型     |
+---------+-----------+--------------+
|       1 | 人事部    | 非技术部     |
|       2 | 财务部    | 非技术部     |
|       3 | 运维部    | 技术部       |
|       4 | 开发部    | 技术部       |
|       5 | 测试部    | 技术部       |
|       6 | 市场部    | 非技术部     |
|       7 | 销售部    | 非技术部     |
|       8 | 法务部    | 非技术部     |
+---------+-----------+--------------+
8 rows in set (0.00 sec)
或
mysql&amp;gt; select【涩莱克特】 dept_id,dept_name,
    -&amp;gt; case
    -&amp;gt; when【问】 dept_name in (&quot;运维部&quot;,&quot;开发部&quot;,&quot;测试部&quot;) then【diān~】 &quot;技术部&quot;
    -&amp;gt; else &quot;非技术部&quot;
    -&amp;gt; end as 部门类型  from【弗乱】  moershi.departments;
+---------+-----------+--------------+
| dept_id | dept_name | 部门类型     |
+---------+-----------+--------------+
|       1 | 人事部    | 非技术部     |
|       2 | 财务部    | 非技术部     |
|       3 | 运维部    | 技术部       |
|       4 | 开发部    | 技术部       |
|       5 | 测试部    | 技术部       |
|       6 | 市场部    | 非技术部     |
|       7 | 销售部    | 非技术部     |
|       8 | 法务部    | 非技术部     |
+---------+-----------+--------------+
8 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;九、作业&lt;/h2&gt;
&lt;h3&gt;1.选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;要从 &lt;code&gt;employees&lt;/code&gt; 表的 &lt;code&gt;email&lt;/code&gt; 列中提取出 &lt;code&gt;@&lt;/code&gt; 后面的域名部分，应使用以下哪个函数？ B
A. &lt;code&gt;SUBSTRING&lt;/code&gt;
B. &lt;code&gt;SUBSTRING_INDEX&lt;/code&gt;
C. &lt;code&gt;LEFT&lt;/code&gt;
D. &lt;code&gt;RIGHT&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;**要从 `employees` 表的 `email` 列中提取出 `@` 后面的域名部分，应使用以下哪个函数？**
    *   **答案：B **
    *   **讲解**：`SUBSTRING_INDEX` 函数是完成这个任务最简洁高效的选择。它的语法是 `SUBSTRING_INDEX(str, delimiter, count)`。当 `count` 为负数时，表示从字符串右边开始查找分隔符，并返回分隔符**之后**的所有内容。因此，使用 `SUBSTRING_INDEX(email, &apos;@&apos;, -1)` 可以直接提取出域名部分，例如从 `&quot;alice@example.com&quot;` 中提取出 `&quot;example.com&quot;`。其他函数如 `SUBSTRING` 需要结合 `LOCATE` 先找到 `@` 的位置，更为繁琐。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;已知 &lt;code&gt;employees&lt;/code&gt; 表的 &lt;code&gt;hire_date&lt;/code&gt; 列是日期类型，要计算每个员工入职到当前日期的天数，应使用的函数是？
A. &lt;code&gt;TIMESTAMPDIFF(DAY【dèi】, hire_date, CURDATE【科dei 特】())&lt;/code&gt;
B. &lt;code&gt;TIMESTAMPDIFF(MONTH【mèn斯】, hire_date, CURDATE【科dei 特】())&lt;/code&gt;
C. &lt;code&gt;TIMESTAMPDIFF(YEAR【耶尔】, hire_date, CURDATE【科dei 特】())&lt;/code&gt;
D. &lt;code&gt;DATEDIFF(CURDATE【科dei 特】(), hire_date)&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt; **已知 `employees` 表的 `hire_date` 列是日期类型，要计算每个员工入职到当前日期的天数，应使用的函数是？**
    *   **答案：D**
    *   **讲解**：计算两个日期的天数差，最直接和常用的函数是 `DATEDIFF(end_date, start_date)`。它返回两个日期之间相差的天数。因此，`DATEDIFF(CURDATE【科dei 特】(), hire_date)` 可以准确计算出从入职日到今天的天数。选项A的 `TIMESTAMPDIFF` 函数也能实现，但它通常用于计算年、月等更大单位的差值，对于计算天数，`DATEDIFF` 是更常规和简洁的选择。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;在统计每个部门的员工数量时，应使用的聚集函数是？ C
A. &lt;code&gt;SUM&lt;/code&gt;
B. &lt;code&gt;AVG&lt;/code&gt;
C. &lt;code&gt;COUNT&lt;/code&gt;
D. &lt;code&gt;MAX&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;**在统计每个部门的员工数量时，应使用的聚集函数是？**
    *   **答案：C **
    *   **讲解**：`COUNT` 是SQL中专门用于**统计行数**的聚合函数。在配合 `GROUP BY department` 使用时，`COUNT(*)` 会返回每个分组（即每个部门）中包含的数据行数，也就是员工数量。`SUM` 用于对数值列求和，`AVG` 用于求平均值，`MAX` 用于找最大值，都不适用于计数场景。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;在 &lt;code&gt;salary&lt;/code&gt; 表中，要计算每个员工的总薪资（基本工资 &lt;code&gt;basic&lt;/code&gt; 加上奖金 &lt;code&gt;bonus&lt;/code&gt;），以下表达式正确的是？ B
A. &lt;code&gt;basic + bonus&lt;/code&gt;
B. &lt;code&gt;SUM(basic, bonus)&lt;/code&gt;
C. &lt;code&gt;AVG(basic + bonus)&lt;/code&gt;
D. &lt;code&gt;MAX(basic, bonus)&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;**在 `salary` 表中，要计算每个员工的总薪资（基本工资 `basic` 加上奖金 `bonus`），以下表达式正确的是？**
    *   **答案：A**
    *   **讲解**：这里的关键是区分**行内计算**与**多行聚合**。计算单个员工的“基本工资+奖金”属于行内计算，只需要使用基本的算术运算符 `+` 即可，即 `basic + bonus`。而 `SUM` 是一个聚合函数，它的作用是对**一组行**的某个字段值进行求和，例如计算整个部门的工资总和，不能用于对同一行内的不同列进行计算。`SUM(basic, bonus)` 的写法在MySQL中本身就是错误的，因为 `SUM` 函数只能接受一个参数。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;在 &lt;code&gt;employees&lt;/code&gt; 表中，若要根据员工的入职日期判断，如果入职日期在 2025 年 1 月 1 日之后，标记为 “新员工”，否则标记为 “老员工”，可以使用以下哪个函数实现？ A
A. &lt;code&gt;IF(hire_date &amp;gt; &apos;2025-01-01&apos;, &apos;新员工&apos;, &apos;老员工&apos;)&lt;/code&gt;
B. &lt;code&gt;CASE WHEN hire_date &amp;gt; &apos;2025-01-01&apos; THEN &apos;新员工&apos; ELSE &apos;老员工&apos; END&lt;/code&gt;
C. 以上两种都可以
D. 以上两种都不可以&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;**在 `employees` 表中，若要根据员工的入职日期判断，如果入职日期在 2025 年 1 月 1 日之后，标记为 “新员工”，否则标记为 “老员工”，可以使用以下哪个函数实现？**
    *   **答案：C**
    *   **讲解**：MySQL 提供了两种实现条件逻辑的主要方式。`IF` 函数适合处理简单的“如果...就...否则...”的双分支判断，语法简洁，本题中的 `IF(hire_date &amp;gt; &apos;2025-01-01&apos;, &apos;新员工&apos;, &apos;老员工&apos;)` 完全正确。而 `CASE` 表达式则更强大，尤其适合多分支的复杂条件判断，其搜索形式 `CASE WHEN ... THEN ... ELSE ... END` 同样可以完美实现本题需求。因此，两种方法都是可行的。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2.简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;请简述字符串函数 &lt;code&gt;CONCAT&lt;/code&gt; 和 &lt;code&gt;CONCAT_WS&lt;/code&gt; 的区别。
答：
CONCAT：是将多个字符串简单拼接在一起，且任一参数为NULL则返回NULL。
CONCAT_WS：是 CONCAT的基础上增加了分隔符功能，是带分隔符地拼接多个字符，​​自动忽略参数中的NULL值​​（分隔符本身不能为NULL）&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;    在MySQL中，`CONCAT` 和 `CONCAT_WS` 都是用于连接字符串的函数，但它们在处理分隔符和空值（`NULL`）时的行为是关键区别所在。下面这个表格能帮你快速把握它们的核心区别。

    | 特性 | `CONCAT` | `CONCAT_WS` |
    | :--- | :--- | :--- |
    | **核心功能** | 将多个字符串**简单连接**在一起 | **带分隔符**地连接多个字符串 |
    | **分隔符** | 无内置分隔符概念，需手动在每个参数间添加 | **第一个参数即为分隔符**，一次性指定 |
    | **处理`NULL`值** | **任一参数为`NULL`，则整个结果返回`NULL`** | **忽略要连接的参数中的`NULL`值**（分隔符本身不能为`NULL`） |
    | **适用场景** | 简单的、无间隔的字符串拼接 | 需要用特定字符（如逗号、短横线）连接字段，且字段可能包含`NULL`值 |

    ### 💡 深入了解 `CONCAT` 函数

    `CONCAT` 函数的功能非常直接：按顺序将传入的所有参数连接成一个字符串。其语法为 `CONCAT(str1, str2, ...)`。

    *   **注意事项**：它最大的特点（也常被视为一个“坑”）是，**只要待连接的参数中有一个是 `NULL`，整个函数的返回结果就是 `NULL`**。这在处理可能包含空值的数据库字段时需要格外小心。
    *   **示例**：
        ```sql
        SELECT CONCAT(&apos;Hello&apos;, &apos; &apos;, &apos;World&apos;); -- 返回 &apos;Hello World&apos;
        SELECT CONCAT(&apos;Hello&apos;, NULL, &apos;World&apos;); -- 返回 NULL
        SELECT CONCAT(&apos;2025&apos;, &apos;10&apos;, &apos;22&apos;); -- 返回 &apos;20251022&apos; (如需日期格式，需手动加分隔符)
        ```

    ### 🔄 掌握 `CONCAT_WS` 函数

    `CONCAT_WS` 是 &quot;CONCAT With Separator&quot; 的缩写，它在 `CONCAT` 的基础上增加了分隔符功能。其语法为 `CONCAT_WS(separator, str1, str2, ...)`，**第一个参数就是分隔符**。

    *   **核心优势**：除了能自动添加分隔符，它最实用的特性是**会忽略除分隔符之外的其他参数中的 `NULL` 值**。这意味着即使 `str2` 是 `NULL`，最终结果也会是 `str1` + 分隔符 + `str3`，而不会返回 `NULL`。
    *   **重要例外**：虽然会忽略参数中的 `NULL`，但如果**分隔符（第一个参数）本身是 `NULL`**，那么结果仍会返回 `NULL`。
    *   **示例**：
        ```sql
        SELECT CONCAT_WS(&apos;, &apos;, &apos;Apple&apos;, &apos;Banana&apos;, &apos;Orange&apos;); -- 返回 &apos;Apple, Banana, Orange&apos;
        SELECT CONCAT_WS(&apos;-&apos;, &apos;2025&apos;, &apos;10&apos;, &apos;22&apos;); -- 返回 &apos;2025-10-22&apos; (轻松格式化日期)
        SELECT CONCAT_WS(&apos; &apos;, &apos;Hello&apos;, NULL, &apos;World&apos;); -- 返回 &apos;Hello World&apos; (忽略NULL)
        ```

    ### 🛠️ 用场景选择函数

    根据上面的区别，你可以在不同场景下选择合适的函数：

    *   **使用 `CONCAT` 当**：你需要进行简单的、无间隔的字符串拼接，并且能**确保所有参数都不为 `NULL`**，或者你**希望当存在 `NULL` 时结果直接变为 `NULL`**。

    *   **使用 `CONCAT_WS` 当**：你希望用统一的**分隔符（如逗号、空格、短横线）来连接多个字符串**，特别是当这些字段**可能包含 `NULL` 值**，而你又不希望最终的拼接结果因某个空值而中断或失效时。这在拼接地址、全名或生成特定格式的编码时非常有用。

    ### 💎 简单总结

    记住一个简单的法则：需要加分隔符或者担心字段有`NULL`值影响拼接结果时，优先选择 **`CONCAT_WS`**；否则，进行最简单的无缝拼接且不担心`NULL`值时，可以使用 **`CONCAT`**。

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;聚集函数 &lt;code&gt;SUM&lt;/code&gt; 和 &lt;code&gt;AVG&lt;/code&gt; 在使用上有什么不同？
答：
&lt;code&gt;SUM&lt;/code&gt;是计算指定列中所有​​非NULL数值的总和​​。
&lt;code&gt;AVG&lt;/code&gt;是计算指定列中所有​​非NULL数值的算术平均值&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;IF&lt;/code&gt; 函数和 &lt;code&gt;CASE&lt;/code&gt; 函数在条件判断方面有什么特点和适用场景？
答：
&lt;code&gt;IF&lt;/code&gt; 函数：就像一个简单的“如果...那么...否则...”判断器，适用于简单场景，类似考试成绩if(cj &amp;gt;60,&quot;合格&quot;,&quot;不合格&quot;)
&lt;code&gt;CASE&lt;/code&gt; 函数：是一个​​多分支条件判断的精确匹配器，可以进行精细的​​多分支条件判断，像成绩分级case when  cj &amp;gt;=90 then &quot;优秀&quot; when cj &amp;gt;=80 and &amp;lt;=89 then &quot;良好&quot;.......&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;    这三个问题确实是SQL学习中的关键知识点。下面我用一个表格快速梳理它们的核心区别，然后我们再详细看看。


    | 函数对比 | 核心功能与关键区别 | 典型应用场景 |
    | :---- | :---- | :---- |
    | **CONCAT vs CONCAT_WS** | **CONCAT**：简单连接字符串，**任一参数为NULL则返回NULL**。&amp;lt;br&amp;gt;**CONCAT_WS**：带分隔符连接，**自动忽略参数中的NULL值**（分隔符本身不能为NULL）。 | **CONCAT**：无间隔拼接，如合并姓和名`CONCAT(last_name, first_name)`。&amp;lt;br&amp;gt;**CONCAT_WS**：需统一分隔符的拼接，如格式化日期`CONCAT_WS(&apos;-&apos;, year【耶尔】, month【mèn斯】, day【dèi】)`，或拼接可能为NULL的字段。 |
    | **SUM vs AVG** | **SUM**：计算指定列中所有**非NULL数值的总和**。&amp;lt;br&amp;gt;**AVG**：计算指定列中所有**非NULL数值的算术平均值**（其计算方式为`SUM(列) / COUNT(列)`）。 | **SUM**：回答“总量”问题，如总销售额、总成本。&amp;lt;br&amp;gt;**AVG**：回答“平均水平”问题，如平均分、平均工资。 |
    | **IF vs CASE** | **IF函数**：MySQL特有，适用于简单的**二元判断**（类似三元运算符`条件 ? 结果1 : 结果2`）。&amp;lt;br&amp;gt;**CASE表达式**：SQL标准语法，适用于**多分支条件判断**，功能更强大，可读性更好。 | **IF函数**：简单的“是/否”判断，如`IF(score &amp;gt;= 60, &apos;及格&apos;, &apos;不及格&apos;)`。&amp;lt;br&amp;gt;**CASE表达式**：复杂的多条件分支，如成绩分级、会员等级划分。 |

    ### 💡 字符串连接：CONCAT 与 CONCAT_WS

    -   **CONCAT 的注意事项**：由于其“遇NULL则NULL”的特性，在拼接可能包含空值的字段时存在风险。为确保结果，通常需要先用`COALESCE`或`IFNULL`函数将`NULL`值转换为空字符串等默认值，例如 `CONCAT(COALESCE(field1, &apos;&apos;), field2)`。
    -   **CONCAT_WS 的优势**：它在处理如地址等多部分信息时特别有用，因为这些信息中的某些部分很可能为`NULL`。使用`CONCAT_WS`可以避免繁琐的空值检查，直接生成整洁的拼接结果（例如 `CONCAT_WS(&apos; &apos;, address, city, country)`），即使其中部分字段为`NULL`，结果字符串也不会中断。

    ### 📊 数据汇总：SUM 与 AVG

    -   **共同点**：`SUM`和`AVG`都是聚合函数，它们在计算时都会**自动忽略**列中的`NULL`值。这意味着计算分母是非`NULL`值的个数，而非总行数。
    -   **重要细节**：
        -   `AVG`函数的结果类型可能比输入列的类型精度更高。例如，对整数列（`INT`）求平均值，可能会返回浮点数（如`DECIMAL`）结果。
        -   它们常与`GROUP BY`子句结合使用，以实现分组统计，例如计算每个部门的平均工资。
        -   可以使用`DISTINCT`关键字对唯一值进行计算，如 `AVG(DISTINCT score)` 只计算不同成绩的平均值。

    ### 🔀 条件判断：IF 与 CASE

    -   **CASE 表达式的两种形式**：
        1.  **简单 CASE 表达式**：用于等值比较，语法为 `CASE column WHEN value1 THEN result1 ... END`。例如，根据部门编号显示名称：`CASE department WHEN &apos;IT&apos; THEN &apos;技术部&apos; ... END`。
        2.  **搜索型 CASE 表达式**：功能更强，允许进行范围判断和多条件组合，语法为 `CASE WHEN condition1 THEN result1 ... END`。例如，成绩分级：`CASE WHEN score &amp;gt;= 90 THEN &apos;优秀&apos; ... END`。
    -   **选择策略**：
        -   当你的逻辑是简单的“如果...就...否则...”（二选一）时，使用 **`IF` 函数**，代码更简洁。
        -   当条件超过两种，或判断条件复杂（涉及范围、多条件组合）时，务必使用 **`CASE` 表达式**，其结构更清晰，可读性更强。
        -   `CASE`表达式是SQL标准，兼容性更好，而`IF`函数通常是MySQL扩展。此外，`CASE`表达式不仅可用于`SELECT`列表，还能用在`ORDER BY`、`WHERE`、`UPDATE`等子句中，实现非常灵活的条件逻辑。

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;使用字符串函数，将 &lt;code&gt;employees&lt;/code&gt; 表中所有员工的姓名转换为小写，并在每个姓名后面添加 “_emp” 后缀。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select concat(lower(name),&apos;_emp&apos;) as 姓名 from moershi.employees;
+---------------+
| 姓名          |
+---------------+
| 梁伟_emp      |
| 郭岩_emp      |
| 李玉英_emp    |
| 张健_emp      |
| 郑静_emp      |
| 牛建军_emp    |
...........
| 刘倩_emp      |
| 杨金凤_emp    |
+---------------+
133 rows in set (0.00 sec)

mysql&amp;gt; 

    ```sql
    SELECT CONCAT(LOWER(name), &apos;_emp&apos;) AS formatted_name
    FROM employees;
    ```

    或者，你也可以使用 `LCASE()` 函数（它与 `LOWER()` 功能完全相同）：

    ```sql
    SELECT CONCAT(LCASE(name), &apos;_emp&apos;) AS formatted_name
    FROM employees;
    ```

    ### 关键点说明

    -   **`LOWER()` / `LCASE()` 函数**：这两个函数用于将字符串中的所有字母字符转换为小写。例如，如果员工姓名是 &quot;John DOE&quot;，转换后将变为 &quot;john doe&quot;。
    -   **`CONCAT()` 函数**：此函数用于将多个字符串连接在一起。在这里，我们将转换后的小写姓名和固定后缀 &quot;_emp&quot; 拼接起来。
    -   **注意 `NULL` 值**：需要特别注意的是，如果 `name` 字段的值为 `NULL`，那么 `CONCAT()` 函数的结果也将是 `NULL`。如果您的数据中存在这种情况并且不希望返回 `NULL`，可以使用 `COALESCE()` 或 `IFNULL()` 函数为其设置一个默认值。例如：
        ```sql
        SELECT CONCAT(LOWER(COALESCE(name, &apos;unknown&apos;)), &apos;_emp&apos;) AS formatted_name
        FROM employees;
        ```

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;使用日期函数，从 &lt;code&gt;employees&lt;/code&gt; 表中找出在本月出生的员工信息。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; select name,birth_date birth_date from moershi.employees where month【mèn斯】(birth_date) = month【mèn斯】(now【闹】());
+-----------+------------+
| name      | birth_date |
+-----------+------------+
| 王英      | 1997-10-11 |
| 许辉      | 1992-10-21 |
| 罗岩      | 1986-10-17 |
| 赵成      | 1985-10-11 |
| 刘桂兰    | 1982-10-11 |
| 李莹      | 1995-10-26 |
| 李柳      | 1972-10-14 |
| 王小红    | 1989-10-04 |
| 贾荣      | 1984-10-19 |
| 张梅      | 1981-10-21 |
+-----------+------------+
10 rows in set (0.00 sec)

mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;使用数学计算，在 &lt;code&gt;salary&lt;/code&gt; 表中计算每个员工奖金占总薪资（基本工资 &lt;code&gt;basic&lt;/code&gt; 加上奖金 &lt;code&gt;bonus&lt;/code&gt;）的比例，并保留两位小数。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; select employee_id,basic,bonus,round(bonus / (basic + bonus) ,2) as 占总薪资比例 from moershi.salary where id&amp;lt;=50; #加个where 减少数据量方便截图
+-------------+-------+-------+--------------------+
| employee_id | basic | bonus | 占总薪资比例       |
+-------------+-------+-------+--------------------+
|           2 | 17000 | 10000 |               0.37 |
|           3 |  8000 |  2000 |               0.20 |
|           4 | 14000 |  9000 |               0.39 |
|           6 | 14000 | 10000 |               0.42 |
|           7 | 19000 | 10000 |               0.34 |
|          11 | 14000 |  7000 |               0.33 |
|          13 | 15000 |  1000 |               0.06 |
|          14 | 10000 | 11000 |               0.52 |
|          17 | 16000 |  7000 |               0.30 |
|          18 |  6000 | 10000 |               0.63 |
|          21 | 15000 |  6000 |               0.29 |
|          22 | 12000 |  8000 |               0.40 |
|          25 | 19000 |  2000 |               0.10 |
|          26 |  7000 | 11000 |               0.61 |
|          27 | 20000 |  5000 |               0.20 |
|          28 | 14000 |  5000 |               0.26 |
|          29 | 19000 |  1000 |               0.05 |
|          30 |  6000 |  1000 |               0.14 |
|          32 | 15000 |  8000 |               0.35 |
|          34 | 19000 |  6000 |               0.24 |
|          37 | 20000 |  6000 |               0.23 |
|          38 | 19000 | 11000 |               0.37 |
|          39 | 12000 | 10000 |               0.45 |
|          40 | 17000 |  2000 |               0.11 |
|          41 |  8000 |  7000 |               0.47 |
|          43 | 11000 |  9000 |               0.45 |
|          44 | 11000 |  8000 |               0.42 |
|          45 | 12000 |  1000 |               0.08 |
|          46 | 13000 | 10000 |               0.43 |
|          47 | 11000 | 11000 |               0.50 |
|          48 | 21000 | 10000 |               0.32 |
|          49 | 13000 |  7000 |               0.35 |
|          50 |  9000 |  4000 |               0.31 |
+-------------+-------+-------+--------------------+
33 rows in set (0.00 sec)

mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;使用 &lt;code&gt;CASE&lt;/code&gt; 函数，结合 &lt;code&gt;employees&lt;/code&gt; 表和 &lt;code&gt;departments&lt;/code&gt; 表，根据部门名称将员工分为 “技术部员工”、“销售部员工” 和 “其他部门员工” 三类。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; select
    -&amp;gt;     e.employee_id,
    -&amp;gt;     e.name as 姓名,
    -&amp;gt;     d.dept_name as 部门,
    -&amp;gt;     case 
    -&amp;gt;         when d.dept_name = &apos;运维部&apos; then &apos;技术部员工&apos;
    -&amp;gt;         when d.dept_name = &apos;开发部&apos; then &apos;技术部员工&apos;
    -&amp;gt;         when d.dept_name = &apos;测试部&apos; then &apos;技术部员工&apos;
    -&amp;gt;         when d.dept_name = &apos;市场部&apos; then &apos;销售部员工&apos;
    -&amp;gt;         when d.dept_name = &apos;销售部&apos; then &apos;销售部员工&apos;
    -&amp;gt;         else &apos;其他部门员工&apos;
    -&amp;gt;     end as 部门类型
    -&amp;gt; from moershi.employees e
    -&amp;gt; join moershi.departments d on e.dept_id = d.dept_id;
+-------------+-----------+-----------+--------------------+
| employee_id | 姓名      | 部门      | 部门类型           |
+-------------+-----------+-----------+--------------------+
|           1 | 梁伟      | 人事部    | 其他部门员工       |
|           2 | 郭岩      | 人事部    | 其他部门员工       |
|           3 | 李玉英    | 人事部    | 其他部门员工       |
|           4 | 张健      | 人事部    | 其他部门员工       |
|           5 | 郑静      | 人事部    | 其他部门员工       |
|           6 | 牛建军    | 人事部    | 其他部门员工       |
|           7 | 刘斌      | 人事部    | 其他部门员工       |
.......
|         128 | 许华      | 销售部    | 销售部员工         |
|         129 | 汤华      | 销售部    | 销售部员工         |
|         130 | 王玉兰    | 销售部    | 销售部员工         |
|         131 | 王荣      | 法务部    | 其他部门员工       |
|         132 | 刘倩      | 法务部    | 其他部门员工       |
|         133 | 杨金凤    | 法务部    | 其他部门员工       |
+-------------+-----------+-----------+--------------------+
133 rows in set (0.00 sec)

mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;

    您提出的这几个问题非常典型，涵盖了数据库查询中几个核心函数的用法。下面我将为您逐一提供详细的解答和示例。

    | 问题序号        | 核心方法                          | 示例 SQL 语句框架                                     |
    | :------------- | :------------------------------- | :-------------------------------------------------- |
    | 1. 姓名转换     | 使用 `LOWER()` 和 `CONCAT()` 函数 | `SELECT CONCAT(LOWER(name), &apos;_emp&apos;) ...`            |
    | 2. 查询本月生日 | 使用 `MONTH【mèn斯】()` 函数比较月份        | `SELECT ... WHERE MONTH【mèn斯】(birth_date) = MONTH【mèn斯】(NOW【闹】())` |
    | 3. 计算奖金占比 | 使用 `ROUND()` 函数控制小数位      | `SELECT ROUND(bonus/(basic+bonus), 2) ...`          |
    | 4. 员工部门分类 | 使用 `CASE` 条件表达式             | `CASE WHEN d.name = &apos;技术部&apos; THEN ... END`           |

    ### 💡 字符串函数：姓名格式化

    这个问题的目标是修改姓名显示格式，主要用到两个字符串函数：
    -   `LOWER()`：将字符串中的所有字母转换为小写。
    -   `CONCAT()`：将两个或多个字符串连接起来。

    相应的SQL语句和说明如下：
    ```sql
    SELECT 
        employee_id,
        CONCAT(LOWER(name), &apos;_emp&apos;) AS formatted_name
    FROM employees;
    ```
    **关键点说明**：这个操作创建了一个名为 `formatted_name` 的新列，其中每个员工的名字先被转换为小写，然后与后缀 `_emp` 连接。例如，`&quot;Alice&quot;` 会变成 `&quot;alice_emp&quot;`。

    ### 📅 日期函数：查询本月生日员工

    要找出在本月出生的员工，核心在于使用 `MONTH【mèn斯】()` 函数来提取日期字段中的月份部分，并与当前月份进行比较。

    相应的SQL语句和说明如下：
    ```sql
    SELECT 
        employee_id, 
        name, 
        birth_date
    FROM employees
    WHERE MONTH【mèn斯】(birth_date) = MONTH【mèn斯】(NOW【闹】());
    ```
    **关键点说明**：`NOW【闹】()` 函数返回当前的日期和时间。`MONTH【mèn斯】(NOW【闹】())` 提取出当前的月份数字（例如10月返回10）。`WHERE` 条件会筛选出 `birth_date` 字段中月份与当前月份相同的所有记录。

    ### ➗ 数学计算：计算奖金占比

    这个问题需要执行除法运算，并使用 `ROUND` 函数对结果进行格式化。

    相应的SQL语句和说明如下：
    ```sql
    SELECT 
        employee_id,
        basic,
        bonus,
        ROUND(bonus / (basic + bonus), 2) AS bonus_ratio
    FROM salary;
    ```
    **关键点说明**：
    -   计算逻辑：使用 `奖金 / (基本工资 + 奖金)` 来得到奖金占总薪资的比例。
    -   精度控制：`ROUND(数值, 2)` 函数将计算结果四舍五入到小数点后两位，这是处理金融或比率数据时的常见做法。
    -   注意 `NULL` 值：如果 `basic` 或 `bonus` 可能为 `NULL`，直接计算会导致结果为 `NULL`。为确保计算安全，可以使用 `IFNULL(basic, 0)` 等函数为 `NULL` 值设置默认值。

    ### 🔀 条件判断：对员工进行部门分类

    `CASE` 表达式非常适合这种多条件的值映射场景，它允许你根据不同的条件返回不同的结果。这里假设员工表（`employees`）中有一个部门ID字段（`dept_id`）与部门表（`departments`）关联，部门表中有部门名字段（`name`）。

    相应的SQL语句和说明如下：
    ```sql

    select
        e.employee_id,
        e.name as 姓名,
        d.dept_name as 部门,
        case 
            when d.dept_name = &apos;运维部&apos; then &apos;技术部员工&apos;
            when d.dept_name = &apos;开发部&apos; then &apos;技术部员工&apos;
            when d.dept_name = &apos;测试部&apos; then &apos;技术部员工&apos;
            when d.dept_name = &apos;市场部&apos; then &apos;销售部员工&apos;
            when d.dept_name = &apos;销售部&apos; then &apos;销售部员工&apos;
            else &apos;其他部门员工&apos;
        end as 部门类型
    from moershi.employees e
    join moershi.departments d on e.dept_id = d.dept_id;

    ```
    **关键点说明**：
    -   使用搜索型 `CASE` 表达式：`CASE WHEN condition THEN result ... END`。
    -   执行顺序是自上而下评估每个 `WHEN` 条件，一旦某个条件为真，就返回对应的 `THEN` 结果，并跳过后续条件。
    -   如果所有 `WHEN` 条件都不满足，则返回 `ELSE` 子句的结果。指定 `ELSE` 是一个好习惯，可以确保所有情况都有明确的输出。


&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;03：mysql之单表增删改查&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[单表增删改查]
        direction LR
        A[分组查询] --&amp;gt; B[对查询结果进行排序] --&amp;gt; C[分组后条件过滤] --&amp;gt; D[新增数据] --&amp;gt; E[修改数据] --&amp;gt; F[删除数据]
    end
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;在电商运营工作中，单表的增删改查操作十分常见。运营人员为了丰富商品种类，会向商品信息表中新增商品记录，包括商品名称、价格、库存等信息，以满足市场需求。若某商品价格调整，运营人员会及时修改商品信息表中该商品的价格字段，保证数据准确性。当一款商品下架时，他们会从表中删除该商品的记录，避免无效数据干扰。同时，在分析销售数据时，运营人员会根据不同条件从表中查询特定商品的信息，比如筛选出销量高的商品，为后续的营销策略提供数据支持。&lt;/p&gt;
&lt;h2&gt;二、为什么学增删改查&lt;/h2&gt;
&lt;p&gt;学习 MySQL 单表的增删改查至关重要。在数据管理领域，这是最基础且核心的技能。在日常工作里，我们常常要与各种数据打交道，增删改查操作能让我们灵活处理数据。比如，电商平台需新增商品信息、删除滞销商品数据、修改商品价格、查询特定商品库存。掌握这些操作，能高效维护数据，确保数据实时性与准确性。同时，它们是学习更复杂数据库操作的基石，如多表连接、存储过程等。对于从事数据分析、软件开发等行业的人而言，熟练运用增删改查是必备技能，能提升工作效率与质量。&lt;/p&gt;
&lt;h2&gt;三、分组查询&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[单表增删改查]
        direction LR
        A[分组查询] --&amp;gt; B[对查询结果进行排序] --&amp;gt; C[分组后条件过滤] --&amp;gt; D[新增数据] --&amp;gt; E[修改数据] --&amp;gt; F[删除数据]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class A highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;分组函数 group【格鲁普】 by&lt;/h3&gt;
&lt;p&gt;GROUP【格鲁普】 BY是 SQL 中非常重要的一个子句，它的主要作用是对查询结果进行分组统计&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;示例或关键点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;核心功能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;根据指定列将数据分成若干组，然后对每个组应用聚合函数进行统计。&lt;/td&gt;
&lt;td&gt;计算每个部门的平均工资、每个产品的总销售额等。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;基本语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT【涩莱克特】 列A, 聚合函数(列B) FROM【弗乱】 表名 GROUP【格鲁普】 BY 列A;&lt;/code&gt;。&lt;/td&gt;
&lt;td&gt;列A是分组依据。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;常用聚合函数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;COUNT【kàn特】()&lt;/code&gt;（计数）, &lt;code&gt;SUM【桑à姆】()&lt;/code&gt;（求和）, &lt;code&gt;AVG()&lt;/code&gt;（平均值）, &lt;code&gt;MAX【mà 斯】()&lt;/code&gt;（最大值）, &lt;code&gt;MIN【敏ì】()&lt;/code&gt;（最小值）。&lt;/td&gt;
&lt;td&gt;对每个分组进行计算。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;与HAVING子句&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;WHERE【威尔】&lt;/code&gt; 在分组&lt;strong&gt;前&lt;/strong&gt;过滤行，&lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; 在分组&lt;strong&gt;后&lt;/strong&gt;过滤组。&lt;/td&gt;
&lt;td&gt;&lt;code&gt;HAVING【嗨夫营】 AVG(salary【晒了瑞】) &amp;gt; 5000&lt;/code&gt;（筛选出平均工资大于5000的组）。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;多列分组&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; 后面可接多个列，按这些列的组合进行分组。&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GROUP【格鲁普】 BY department【迪帕踢门特】, job_title&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;重要注意事项&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT【涩莱克特】&lt;/code&gt; 后面非聚合的列，必须出现在 &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; 子句中。&lt;/td&gt;
&lt;td&gt;这是最容易出错的地方。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;💡 理解分组的过程&lt;/h4&gt;
&lt;p&gt;你可以把 &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; 想象成一个高效的数据整理师。它的工作流程通常是：首先，根据 &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; 后面指定的列，将表中所有数据行分成不同的“小组”，每个小组内的这些列的值完全相同。然后，数据库会对每一个这样的小组分别计算聚合函数（如求和、计数等）。最后，查询结果将为每个小组返回一行摘要信息，其中包含分组列的值和聚合函数计算的结果。&lt;/p&gt;
&lt;p&gt;例如，有一个员工表，使用 &lt;code&gt;SELECT【涩莱克特】 department【迪帕踢门特】, AVG(salary【晒了瑞】) FROM【弗乱】 employees【ing普洛伊s】 GROUP【格鲁普】 BY department【迪帕踢门特】;&lt;/code&gt; 可以计算出每个部门的平均工资。在这里，数据库会先按部门进行分组，然后对每个部门小组计算平均工资。&lt;/p&gt;
&lt;h4&gt;🛠️ 基本用法与示例&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;单列分组&lt;/strong&gt;
这是最常见的情况，即根据一个字段进行分组。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 统计每个城市的用户数量
SELECT【涩莱克特】 city, COUNT【kàn特】(*) AS user_count【kàn特】
FROM【弗乱】 users
GROUP【格鲁普】 BY city;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;多列分组&lt;/strong&gt;
当需要根据多个字段的组合进行更精细的分组时，可以使用多列分组。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 统计每个部门下每个职位的员工数量
SELECT【涩莱克特】 department【迪帕踢门特】, job_title, COUNT【kàn特】(*) AS employee【ing普洛伊】_count【kàn特】
FROM【弗乱】 employees【ing普洛伊s】
GROUP【格鲁普】 BY department【迪帕踢门特】, job_title;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个查询会返回所有唯一的“部门-职位”组合及其对应的员工数量。&lt;/p&gt;
&lt;h4&gt;⚠️ 关键规则与常见错误&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SELECT【涩莱克特】列表的非聚合列规则&lt;/strong&gt;
这是使用 &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; 时最需要牢记的规则：出现在 &lt;code&gt;SELECT【涩莱克特】&lt;/code&gt; 列表中的列，&lt;strong&gt;要么必须包含在 &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; 子句中，要么必须被包含在聚合函数里&lt;/strong&gt;。这是因为，对于每个分组来说，分组列的值是唯一的（比如“技术部”），但其他列可能有多条不同的记录（比如“技术部”里有很多不同的员工名）。数据库无法确定应该返回哪一条非分组列的值，因此强制要求通过聚合函数（如&lt;code&gt;MAX【mà 斯】&lt;/code&gt;, &lt;code&gt;AVG&lt;/code&gt;）将其汇总成一个值，或者将其本身作为分组依据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;WHERE【威尔】 与 HAVING【嗨夫营】 的区别&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;WHERE【威尔】&lt;/code&gt;&lt;/strong&gt;：在 &lt;strong&gt;分组之前&lt;/strong&gt; 过滤数据行。它不能包含聚合函数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;HAVING【嗨夫营】&lt;/code&gt;&lt;/strong&gt;：在 &lt;strong&gt;分组之后&lt;/strong&gt; 过滤分组结果。它通常与聚合函数一起使用，用来筛选满足特定条件的组。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;-- 正确示例：先过滤出2023年以后的订单，再按客户分组，最后筛选出总金额大于1000的客户
SELECT【涩莱克特】 customer_id, SUM【桑à姆】(amount) AS total【偷ò头ō】_amount
FROM【弗乱】 orders【欧朵s】
WHERE【威尔】 order【欧朵】_date &amp;gt;= &apos;2023-01-01&apos;  -- 分组前过滤行
GROUP【格鲁普】 BY customer_id
HAVING【嗨夫营】 SUM【桑à姆】(amount) &amp;gt; 1000;        -- 分组后过滤组
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;🔍 高级用法与技巧&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;使用表达式或函数分组&lt;/strong&gt;：可以根据表达式的结果进行分组，这在处理时间序列数据时特别有用。例如，可以按年份和月份分组统计订单。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;使用ROLLUP生成小计和总计&lt;/strong&gt;：&lt;code&gt;WITH ROLLUP&lt;/code&gt; 选项可以在分组结果的基础上，生成层次性的小计和总计行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;处理NULL【nò】值&lt;/strong&gt;：需要注意的是，如果分组列中包含 &lt;code&gt;NULL【nò】&lt;/code&gt; 值，所有 &lt;code&gt;NULL【nò】&lt;/code&gt; 值会被归为同一组。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;命令操作如下所示：&lt;/h4&gt;
&lt;h5&gt;输出符合条件的shell 和 name&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 shell,name  from【弗乱】 moershi.user where【威尔】shell in (&quot;/bin/bash&quot;,&quot;/sbin/nologin【诺劳京(白话)】&quot;);
+---------------+-----------------+
| shell         | name            |
+---------------+-----------------+
| /bin/bash     | root            |
| /sbin/nologin | bin             |
| /sbin/nologin | daemon          |
| /sbin/nologin | adm             |
.................
| /sbin/nologin | rpc             |
| /sbin/nologin | rpcuser         |
| /sbin/nologin | nfsnobody       |
| /sbin/nologin | haproxy         |
| /bin/bash     | plj             |
| /sbin/nologin | apache          |
+---------------+-----------------+
22 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;统计每种解释器用户的个数 （按照shell表头值分组统计name表头值个数）&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 shell as 解释器 , count【kàn特】(name) as 总人数  from【弗乱】 moershi.user where【威尔】shell in (&quot;/bin/bash&quot;,&quot;/sbin/nologin【诺劳京(白话)】&quot;) group【格鲁普】 by shell;
+---------------+-----------+
| 解释器        | 总人数    |
+---------------+-----------+
| /bin/bash     |         2 |
| /sbin/nologin |        20 |
+---------------+-----------+
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;子句/部分&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SELECT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;指定要查询的列。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;shell AS 解释器&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;查询 &lt;code&gt;shell&lt;/code&gt; 字段，并将其&lt;strong&gt;别名&lt;/strong&gt;设置为“解释器”。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;COUNT(name) AS 总人数&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;使用 &lt;strong&gt;&lt;code&gt;COUNT&lt;/code&gt;&lt;/strong&gt; 聚合函数统计每个分组中 &lt;code&gt;name&lt;/code&gt; 的数目，别名是“总人数”。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FROM moershi.user&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;指定查询的表为 &lt;code&gt;moershi&lt;/code&gt; 数据库下的 &lt;code&gt;user&lt;/code&gt; 表。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;WHERE shell IN (...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;过滤&lt;/strong&gt;条件，只统计使用&lt;code&gt;/bin/bash&lt;/code&gt;或&lt;code&gt;/sbin/nologin&lt;/code&gt;的用户。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GROUP BY shell&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;根据 &lt;code&gt;shell&lt;/code&gt; 字段的值进行&lt;strong&gt;分组&lt;/strong&gt;，将使用相同Shell的用户归为一组进行统计。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h5&gt;统计每个部门的总人数 (按照部门表头分组统计name表头值的个数)&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 dept_id , count【kàn特】(name)  from【弗乱】moershi.employees【ing普洛伊s】 group【格鲁普】 by  dept_id ;
+---------+-------------+
| dept_id | count【kàn特】(name) |
+---------+-------------+
|       1 |           8 |
|       2 |           5 |
|       3 |           6 |
|       4 |          55 |
|       5 |          12 |
|       6 |           9 |
|       7 |          35 |
|       8 |           3 |
+---------+-------------+
8 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、对查询结果进行排序&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[单表增删改查]
        direction LR
        A[分组查询] --&amp;gt; B[对查询结果&amp;lt;/n&amp;gt;进行排序] --&amp;gt; C[分组后条件过滤] --&amp;gt; D[新增数据] --&amp;gt; E[修改数据] --&amp;gt; F[删除数据]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class B highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;排序函数 order【欧朵】 by&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;示例或关键点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;核心功能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;根据指定的列对查询结果集进行排序。&lt;/td&gt;
&lt;td&gt;让数据展示更清晰，便于分析和查看。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;基本语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;`SELECT【涩莱克特】 ... FROM【弗乱】 ... ORDER【欧朵】 BY column【科勒姆】_name [ASC【阿斯克】&lt;/td&gt;
&lt;td&gt;desc];`&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;排序方式&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ASC【阿斯克】&lt;/code&gt;：升序（默认，可省略）。 &lt;code&gt;desc&lt;/code&gt;：降序。&lt;/td&gt;
&lt;td&gt;若不指定，默认为 &lt;code&gt;ASC【阿斯克】&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;多列排序&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;按多个字段排序，优先级从左到右。&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ORDER【欧朵】 BY column1【科勒姆】 desc, column2【科勒姆】 ASC【阿斯克】;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;排序键类型&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;字段名、字段在SELECT【涩莱克特】中的序号（从1开始）、字段别名。&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ORDER【欧朵】 BY 1&lt;/code&gt;（按第一列排序）。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;与聚合函数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;可使用聚合函数结果排序。&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ORDER【欧朵】 BY COUNT【kàn特】(*) desc;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NULL【nò】值处理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NULL【nò】值可能集中出现在开头或末尾，具体取决于数据库系统。&lt;/td&gt;
&lt;td&gt;需特别注意其默认位置。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;💡 理解排序规则与语法&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;ORDER【欧朵】 BY&lt;/code&gt; 子句的核心作用是将查询结果按照特定顺序排列。其基本语法遵循以下结构：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT【涩莱克特】 column1【科勒姆】, column2【科勒姆】, ...
FROM【弗乱】 table【忒-部】_name
ORDER【欧朵】 BY column1【科勒姆】 [ASC【阿斯克】|desc], column2【科勒姆】 [ASC【阿斯克】|desc], ...;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里，&lt;code&gt;ASC【阿斯克】&lt;/code&gt; 表示升序（Ascending），&lt;code&gt;desc&lt;/code&gt; 表示降序（Descending）。如果省略排序方式，数据库将默认按照升序（&lt;code&gt;ASC【阿斯克】&lt;/code&gt;）排列结果 。&lt;/p&gt;
&lt;h4&gt;🛠️ 掌握多种排序方式&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;单列排序&lt;/strong&gt;
这是最基础的排序方式，即根据单个字段的值进行排序。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 按产品名称升序排列（ASC【阿斯克】可省略）
SELECT【涩莱克特】 prod_name FROM【弗乱】 products ORDER【欧朵】 BY prod_name ASC【阿斯克】;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;多列排序与优先级&lt;/strong&gt;
当需要根据多个条件排序时，可以在 &lt;code&gt;ORDER【欧朵】 BY&lt;/code&gt; 后列出多个列，它们具有明确的优先级：&lt;strong&gt;写在前面的字段优先级最高&lt;/strong&gt;。数据库会先按第一个字段排序，当第一个字段的值相同时，再按第二个字段排序，以此类推 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 先按价格降序，价格相同的再按产品名称升序排列
SELECT【涩莱克特】 prod_id, prod_price, prod_name
FROM【弗乱】 products
ORDER【欧朵】 BY prod_price desc, prod_name ASC【阿斯克】;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;按列位置和别名排序&lt;/strong&gt;
除了直接使用列名，还可以使用列在 &lt;code&gt;SELECT【涩莱克特】&lt;/code&gt; 子句中的&lt;strong&gt;位置序号&lt;/strong&gt;（从1开始）或定义的&lt;strong&gt;别名&lt;/strong&gt;进行排序 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 按位置排序：按SELECT【涩莱克特】中的第二列(prod_price)降序，第三列(prod_name)升序
SELECT【涩莱克特】 prod_id, prod_price, prod_name
FROM【弗乱】 products
ORDER【欧朵】 BY 2 desc, 3;

-- 按别名排序
SELECT【涩莱克特】 prod_id, prod_price AS price, prod_name
FROM【弗乱】 products
ORDER【欧朵】 BY price desc;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;⚠️ 注意关键细节与技巧&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;子句顺序&lt;/strong&gt;：在 SQL 语句中，&lt;code&gt;ORDER【欧朵】 BY&lt;/code&gt; 子句必须位于所有其他子句之后，即正确的书写顺序是：&lt;code&gt;SELECT【涩莱克特】&lt;/code&gt; -&amp;gt; &lt;code&gt;FROM【弗乱】&lt;/code&gt; -&amp;gt; &lt;code&gt;WHERE【威尔】&lt;/code&gt; -&amp;gt; &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; -&amp;gt; &lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; -&amp;gt; &lt;code&gt;ORDER【欧朵】 BY&lt;/code&gt; 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NULL【nò】 值的排序&lt;/strong&gt;：对于包含 NULL【nò】 值的列进行排序时，NULL【nò】 会被集中排列，但具体出现在结果集的开头还是末尾，不同的数据库管理系统可能有不同的默认行为 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;与聚合函数结合使用&lt;/strong&gt;：&lt;code&gt;ORDER【欧朵】 BY&lt;/code&gt; 可以根据聚合函数的结果进行排序，这在数据统计和分析时非常有用 。&lt;pre&gt;&lt;code&gt;-- 统计每个产品类型的数量，并按数量降序排列
SELECT【涩莱克特】 product_type, COUNT【kàn特】(*)
FROM【弗乱】 Product
GROUP【格鲁普】 BY product_type
ORDER【欧朵】 BY COUNT【kàn特】(*) desc;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能考虑&lt;/strong&gt;：对经常需要排序的列建立索引，可以显著提高排序查询的速度 。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;💎 简单总结&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;ORDER【欧朵】 BY&lt;/code&gt; 是控制查询结果展示顺序的关键。记住：&lt;strong&gt;&lt;code&gt;ORDER【欧朵】 BY&lt;/code&gt; 默认升序，多列排序时左侧列优先级最高，并且它总是 &lt;code&gt;SELECT【涩莱克特】&lt;/code&gt; 语句的最后一个子句。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;desc :  降序&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;asc【阿斯克】：升序&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;命令操作如下所示：&lt;/h4&gt;
&lt;h5&gt;查看满足条件记录的name和uid 字段的值&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 name , uid from【弗乱】 moershi.user where【威尔】uid is not【nuō 特】 null【nò】 and uid between【B豚ing】 100  and 1000 ;
+-----------------+------+
| name            | uid  |
+-----------------+------+
| systemd-network |  192 |
| polkitd         |  999 |
| chrony          |  998 |
| haproxy         |  188 |
| plj             | 1000 |
+-----------------+------+
5 rows in set【赛特】 (0.00 sec)  
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;按照uid升序排序&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 name , uid from【弗乱】 moershi.user where【威尔】uid is not【nuō 特】 null【nò】 and uid between【B豚ing】 100  and 1000  order【欧朵】 by uid asc【阿斯克】;
+-----------------+------+
| name            | uid  |
+-----------------+------+
| haproxy         |  188 |
| systemd-network |  192 |
| chrony          |  998 |
| polkitd         |  999 |
| plj             | 1000 |
+-----------------+------+
5 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;按照uid降序排序&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 name , uid from【弗乱】 moershi.user where【威尔】uid is not【nuō 特】 null【nò】 and uid between【B豚ing】 100  and 1000  order【欧朵】 by uid desc;
+-----------------+------+
| name            | uid  |
+-----------------+------+
| plj             | 1000 |
| polkitd         |  999 |
| chrony          |  998 |
| systemd-network |  192 |
| haproxy         |  188 |
+-----------------+------+
5 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;查看2015年1月10号员工编号小于10的工资总额&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 employee【ing普洛伊】_id , date , basic【贝斯克】 , bonus【波诺斯】 ,  basic【贝斯克】+bonus【波诺斯】 as total【偷ò头ō】  from【弗乱】 moershi.salary【晒了瑞】 where【威尔】date=20150110 and employee【ing普洛伊】_id &amp;lt;= 10;
+-------------+------------+-----------------+----------------+-----------------+
| employee_id | date       | basic【贝斯克】 | bonus【波诺斯】 | total【偷ò头ō】 |
+-------------+------------+-----------------+----------------+-----------------+
|           2 | 2015-01-10 | 17000           | 10000          | 27000           |
|           3 | 2015-01-10 |  8000           |  2000          | 10000           |
|           4 | 2015-01-10 | 14000           |  9000          | 23000           |
|           6 | 2015-01-10 | 14000           | 10000          | 24000           |
|           7 | 2015-01-10 | 19000           | 10000          | 29000           |
+-------------+------------+-----------------+----------------+-----------------+
5 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;以工资总额升序排 ，总额相同按照员工编号升序排&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 employee【ing普洛伊】_id , basic【贝斯克】+bonus【波诺斯】 as total【偷ò头ō】  from【弗乱】 moershi.salary【晒了瑞】 where【威尔】date=20150110 and employee【ing普洛伊】_id &amp;lt;= 10 order【欧朵】 by total【偷ò头ō】 asc【阿斯克】 ,employee【ing普洛伊】_id asc【阿斯克】;
+-------------+-------+
| employee_id | total【偷ò头ō】 |
+-------------+-------+
|           3 | 10000 |
|           4 | 23000 |
|           6 | 24000 |
|           2 | 27000 |
|           7 | 29000 |
+-------------+-------+
5 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、分组后条件过滤&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[单表增删改查]
        direction LR
        A[分组查询] --&amp;gt; B[对查询结果&amp;lt;/n&amp;gt;进行排序] --&amp;gt; C[分组后条件过滤] --&amp;gt; D[新增数据] --&amp;gt; E[修改数据] --&amp;gt; F[删除数据]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class C highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;对分组后的组进行筛选: having【嗨夫营】&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;HAVING【嗨夫营】 子句&lt;/th&gt;
&lt;th&gt;WHERE【威尔】 子句&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;核心功能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;对 &lt;strong&gt;分组后的组&lt;/strong&gt; 进行筛选&lt;/td&gt;
&lt;td&gt;对 &lt;strong&gt;分组前的原始数据行&lt;/strong&gt; 进行筛选&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;作用对象&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;由 GROUP【格鲁普】 BY 产生的分组或聚合函数的结果&lt;/td&gt;
&lt;td&gt;来自表的单行记录&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;聚合函数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;可以且经常&lt;/strong&gt; 使用（如 &lt;code&gt;HAVING【嗨夫营】 SUM【桑à姆】(amount) &amp;gt; 100&lt;/code&gt;）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;不可以&lt;/strong&gt; 直接使用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;执行顺序&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;在 &lt;strong&gt;GROUP【格鲁普】 BY&lt;/strong&gt; 之后&lt;/td&gt;
&lt;td&gt;在 &lt;strong&gt;GROUP【格鲁普】 BY&lt;/strong&gt; 之前&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;典型应用&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;筛选满足条件的组，例如&quot;总销售额大于1万的部门&quot;&lt;/td&gt;
&lt;td&gt;筛选满足条件的行，例如&quot;年龄大于30岁的员工&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;💡 理解 HAVING【嗨夫营】 的工作原理&lt;/h4&gt;
&lt;p&gt;你可以将 SQL 查询的执行顺序理解为：&lt;strong&gt;FROM【弗乱】 → WHERE【威尔】 → GROUP【格鲁普】 BY → HAVING【嗨夫营】 → SELECT【涩莱克特】 → ORDER【欧朵】 BY&lt;/strong&gt; 。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;FROM【弗乱】&lt;/strong&gt;：首先从表中获取数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WHERE【威尔】&lt;/strong&gt;：接着，&lt;code&gt;WHERE【威尔】&lt;/code&gt; 子句会像一道筛子，根据你设定的条件（比如 &lt;code&gt;amount &amp;gt; 100&lt;/code&gt;）对原始数据行进行过滤，只保留符合条件的行。这一步会在分组之前有效减少需要处理的数据量 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GROUP【格鲁普】 BY&lt;/strong&gt;：然后，数据库会按照指定的列对 &lt;code&gt;WHERE【威尔】&lt;/code&gt; 过滤后的结果进行分组，将具有相同值的行归到同一组中。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HAVING【嗨夫营】&lt;/strong&gt;：最后，&lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; 子句登场，它基于聚合函数的结果（例如组的平均工资、总销售额等）对这些分组进行筛选，只保留满足条件的分组 。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;🛠️ HAVING【嗨夫营】 的典型用法场景&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;1. 基础用法：筛选聚合结果&lt;/strong&gt;
这是 HAVING【嗨夫营】 最经典的场景，用于找出符合某项统计条件的组。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 找出总消费金额超过1000元的客户
SELECT【涩莱克特】 customer_id, SUM【桑à姆】(amount) AS total【偷ò头ō】_spending
FROM【弗乱】 orders
GROUP【格鲁普】 BY customer_id
HAVING【嗨夫营】 SUM【桑à姆】(amount) &amp;gt; 1000; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;2. 结合 WHERE【威尔】 使用：提高查询效率&lt;/strong&gt;
你可以同时使用 &lt;code&gt;WHERE【威尔】&lt;/code&gt; 和 &lt;code&gt;HAVING【嗨夫营】&lt;/code&gt;，让 &lt;code&gt;WHERE【威尔】&lt;/code&gt; 先过滤掉不需要的原始数据，减少分组计算的压力，再由 &lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; 完成最终筛选 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 找出在2024年下单次数超过5次的客户
SELECT【涩莱克特】 customer_id, COUNT【kàn特】(order_id) AS order_count【kàn特】
FROM【弗乱】 orders
WHERE【威尔】 YEAR(order_date) = 2024  -- 先筛选出2024年的订单，提高效率
GROUP【格鲁普】 BY customer_id
HAVING【嗨夫营】 COUNT【kàn特】(order_id) &amp;gt; 5;     -- 再筛选出订单数超过5的客户 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;3. 多条件组合&lt;/strong&gt;
在 &lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; 子句中，你可以使用 &lt;code&gt;AND&lt;/code&gt;、&lt;code&gt;OR&lt;/code&gt; 来连接多个聚合条件 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 找出总消费超过2000元且平均订单金额大于500元的客户
SELECT【涩莱克特】 customer_id, SUM【桑à姆】(amount) AS total【偷ò头ō】, AVG(amount) AS avg_amount
FROM【弗乱】 orders
GROUP【格鲁普】 BY customer_id
HAVING【嗨夫营】 SUM【桑à姆】(amount) &amp;gt; 2000 AND AVG(amount) &amp;gt; 500; 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;⚠️ 常见误区与注意事项&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;不要在 HAVING【嗨夫营】 中过滤非聚合的原始字段&lt;/strong&gt;：如果过滤条件不涉及聚合计算，只是针对某一行的原始字段，那么应该把它放在 &lt;code&gt;WHERE【威尔】&lt;/code&gt; 子句，而不是 &lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; 中。放在 &lt;code&gt;WHERE【威尔】&lt;/code&gt; 子句效率更高，因为它能在分组前就减少数据量 。当然，如果该字段是分组字段，则可以在 HAVING【嗨夫营】 中使用 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HAVING【嗨夫营】 通常依赖于 GROUP【格鲁普】 BY&lt;/strong&gt;：&lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; 子句通常与 &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; 一起出现。除非你的查询是对整个表进行聚合（例如 &lt;code&gt;SELECT【涩莱克特】 COUNT【kàn特】(*) FROM【弗乱】 table【忒-部】 HAVING【嗨夫营】 COUNT【kàn特】(*) &amp;gt; 10&lt;/code&gt;），否则缺少 &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; 会导致语法错误 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;别名使用&lt;/strong&gt;：在某些数据库系统中，&lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; 子句可以直接使用在 &lt;code&gt;SELECT【涩莱克特】&lt;/code&gt; 中为聚合函数定义的别名，例如 &lt;code&gt;HAVING【嗨夫营】 total【偷ò头ō】_spending &amp;gt; 1000&lt;/code&gt;，这可以使查询更简洁 。但为了更好的兼容性，直接在 HAVING【嗨夫营】 中写完整的聚合表达式是更稳妥的做法。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;💎 简单总结&lt;/h4&gt;
&lt;p&gt;记住一个核心原则：当你需要对 &lt;strong&gt;分组后的统计结果&lt;/strong&gt; 设置条件时，就是 &lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; 子句大显身手的时候。它与 &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt; 是形影不离的好搭档，一个负责分组，一个负责对分组后的结果进行筛选 。&lt;/p&gt;
&lt;h4&gt;命令操作如下所示：&lt;/h4&gt;
&lt;h5&gt;查找部门总人数少于10人的部门名称及人数&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;//第一步，查看所有员工的部门名称
select【涩莱克特】  dept_id ,  name    from【弗乱】  moershi.employees【ing普洛伊s】;
//第二步，按部门编号分组 统计人名个数
mysql&amp;gt; select【涩莱克特】  dept_id ,  count【kàn特】(name) as numbers【nèn波s】   from【弗乱】  moershi.employees【ing普洛伊s】 group【格鲁普】 by  dept_id;
+---------+-------------------+
| dept_id | numbers【nèn波s】 |
+---------+-------------------+
|       1 |       8           |
|       2 |       5           |
|       3 |       6           |
|       4 |      55           |
|       5 |      12           |
|       6 |       9           |
|       7 |      35           |
|       8 |       3           |
+---------+-------------------+
8 rows in set【赛特】 (0.00 sec) 
//第三步，查找部门人数少于10人的部门名称及人数
mysql&amp;gt; select【涩莱克特】  dept_id ,  count【kàn特】(name) as numbers【nèn波s】 from【弗乱】  moershi.employees【ing普洛伊s】 group【格鲁普】 by  dept_id having【嗨夫营】 numbers【nèn波s】 &amp;lt; 10;
+---------+-------------------+
| dept_id | numbers【nèn波s】 |
+---------+-------------------+
|       1 |       8           |
|       2 |       5           |
|       3 |       6           |
|       6 |       9           |
|       8 |       3           |
+---------+-------------------+
5 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;六、分页查询 limit【类梅特】&lt;/h3&gt;
&lt;p&gt;在 MySQL 中，LIMIT【类梅特】是用于实现分页查询的关键字，它能够精确控制查询结果返回的记录条数和起始位置
。下面这个表格能帮你快速抓住它的核心用法。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;语法格式A&lt;/th&gt;
&lt;th&gt;语法格式B (MySQL 8.0+ 推荐)&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;基本语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIMIT【类梅特】 offset【哦夫赛特】, row_count&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIMIT【类梅特】 row_count OFFSET【哦夫赛特】 offset【哦夫赛特】&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从第 &lt;code&gt;offset【哦夫赛特】&lt;/code&gt; 条记录开始，返回 &lt;code&gt;row_count&lt;/code&gt; 条记录。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;偏移量(offset【哦夫赛特】)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;从 &lt;strong&gt;0&lt;/strong&gt; 开始计数&lt;/td&gt;
&lt;td&gt;从 &lt;strong&gt;0&lt;/strong&gt; 开始计数&lt;/td&gt;
&lt;td&gt;例如，&lt;code&gt;offset【哦夫赛特】&lt;/code&gt; 为 0 表示从第一条记录开始。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;简化查询&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIMIT【类梅特】 row_count&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;等同于 &lt;code&gt;LIMIT【类梅特】 0, row_count&lt;/code&gt;，返回前 &lt;code&gt;row_count&lt;/code&gt; 条。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;分页公式&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIMIT【类梅特】 (pageNum - 1) * pageSize, pageSize&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIMIT【类梅特】 pageSize OFFSET【哦夫赛特】 (pageNum - 1) * pageSize&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pageNum&lt;/code&gt;: 当前页码(从1开始); &lt;code&gt;pageSize&lt;/code&gt;: 每页条数。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;💡 如何使用 LIMIT【类梅特】 进行分页&lt;/h4&gt;
&lt;p&gt;掌握 &lt;code&gt;LIMIT【类梅特】&lt;/code&gt; 的最佳方式就是动手实践。假设我们有一张 &lt;code&gt;users&lt;/code&gt; 表，需要实现每页显示10条记录的分页查询。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查询第1页数据&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 使用语法A
SELECT【涩莱克特】 * FROM【弗乱】 users ORDER BY id LIMIT【类梅特】 0, 10;
-- 使用语法B (推荐，语义更清晰)
SELECT【涩莱克特】 * FROM【弗乱】 users ORDER BY id LIMIT【类梅特】 10 OFFSET【哦夫赛特】 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这两条语句是等价的，都返回最前面的10条记录。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查询第2页数据&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 偏移量 offset【哦夫赛特】 = (2 - 1) * 10 = 10
SELECT【涩莱克特】 * FROM【弗乱】 users ORDER BY id LIMIT【类梅特】 10, 10;
-- 或
SELECT【涩莱克特】 * FROM【弗乱】 users ORDER BY id LIMIT【类梅特】 10 OFFSET【哦夫赛特】 10;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里从第11条记录开始（偏移10条），再取10条记录。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;⚠️ 重要提示&lt;/strong&gt;：&lt;strong&gt;分页查询必须与 &lt;code&gt;ORDER BY&lt;/code&gt; 子句配合使用&lt;/strong&gt;，以确保每次查询结果的顺序一致。否则，数据库返回的记录顺序可能是随机的，导致分页混乱。&lt;/p&gt;
&lt;h4&gt;🚀 如何优化大偏移量下的分页性能&lt;/h4&gt;
&lt;p&gt;当需要查询的页码非常靠后时（例如 &lt;code&gt;LIMIT【类梅特】 100000, 10&lt;/code&gt;），直接使用 &lt;code&gt;LIMIT【类梅特】&lt;/code&gt; 会产生性能问题，因为数据库需要先扫描并丢弃掉偏移量指定的前大量记录，效率很低。&lt;/p&gt;
&lt;p&gt;一个高效的优化策略是&lt;strong&gt;使用基于主键（或唯一索引）的范围查询来替代大的偏移量&lt;/strong&gt;。这种方法的原理是记录上一页最后一条记录的唯一ID，然后以此为起点获取下一页。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 假设已知上一页最后一条记录的id是10000
-- 传统的低效写法：SELECT【涩莱克特】 * FROM【弗乱】 table【忒-部】 ORDER BY id LIMIT【类梅特】 10000, 10;
-- 优化后的高效写法：
SELECT【涩莱克特】 * FROM【弗乱】 table【忒-部】 WHERE【威尔】 id &amp;gt; 10000 ORDER BY id LIMIT【类梅特】 10;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这种方法通过索引直接定位到起始位置，跳过了大量数据的扫描，使得查询速度与页码基本无关。它非常适合实现“上一页/下一页”这种连续翻页的场景。&lt;/p&gt;
&lt;h4&gt;💎 简单总结&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;LIMIT【类梅特】&lt;/code&gt; 是实现MySQL分页的核心。记住：&lt;strong&gt;务必搭配 &lt;code&gt;ORDER BY&lt;/code&gt; 保证顺序&lt;/strong&gt;，在需要跳转到很靠后的页面时，&lt;strong&gt;尽量使用基于唯一ID的范围查询来优化性能&lt;/strong&gt;。&lt;/p&gt;
&lt;h4&gt;命令操作如下所示：&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;关键字：limit【类梅特】 数字1,数字2&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;数字1：起始行&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;数字2：每页显示总行数&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;limit【类梅特】   1   ;  显示查询结果的第1行
limit【类梅特】   3   ;  显示查询结果的前3行
limit【类梅特】   10  ;  显示查询结果的前10行
limit【类梅特】   0,1 ;      从查询结果的第1行开始显示，共显示1行
limit【类梅特】   3,5 ;      从查询结果的第4行开始显示，共显示5行
limit【类梅特】  10,10;      从查询结果的第11行开始显示，共显示10行
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;查看有解释器的用户信息&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】  * from【弗乱】moershi.user where【威尔】shell is not【nuō 特】 null【nò】 ;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;只显示查询结果的第1行&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 *  from【弗乱】moershi.user where【威尔】shell is not【nuō 特】 null【nò】  limit【类梅特】 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;只显示查询结果的前3行&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 *  from【弗乱】moershi.user  where【威尔】shell is not【nuō 特】 null【nò】  limit【类梅特】  3;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;仅仅显示查询结果的第1行 到 第3 （0 表示查询结果的第1行）&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】  *  from【弗乱】user   where【威尔】shell is not【nuō 特】 null【nò】  limit【类梅特】 0,3;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;从查询结果的第4行开始显示，共显示3行&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 name,uid , gid  , shell  from【弗乱】user  where【威尔】shell is not【nuō 特】 null【nò】  limit【类梅特】 3,3;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;查看uid 号最大的用户名和UID&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】   name , uid from【弗乱】  moershi.user order【欧朵】  by   uid  desc  limit【类梅特】    1  ;
+-----------+-------+
| name      | uid   |
+-----------+-------+
| nfsnobody | 65534 |
+-----------+-------+
1 row in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、新增数据&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[单表增删改查]
        direction LR
        A[分组查询] --&amp;gt; B[对查询结果&amp;lt;/n&amp;gt;进行排序] --&amp;gt; C[分组后条件过滤] --&amp;gt; D[新增数据] --&amp;gt; E[修改数据] --&amp;gt; F[删除数据]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class D highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;p&gt;查看表头&lt;/p&gt;
&lt;h3&gt;desc&lt;/h3&gt;
&lt;p&gt;在SQL中，&lt;code&gt;desc&lt;/code&gt; 是一个常用的关键字，但它根据使用场景的不同，主要有两种截然不同的含义和用法。为了帮助你快速区分，我先用一个表格来总结它的核心用途。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;用途分类&lt;/th&gt;
&lt;th&gt;语法/上下文&lt;/th&gt;
&lt;th&gt;核心功能&lt;/th&gt;
&lt;th&gt;简要说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;查看表结构&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;desc table【忒-部】_name;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;显示数据表的详细结构信息（列名、类型、约束等）。&lt;/td&gt;
&lt;td&gt;主要用于数据库管理和调试，是一个&lt;strong&gt;命令&lt;/strong&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;指定查询排序&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ORDER BY column【科勒姆】_name desc;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;在查询结果中，将指定列按&lt;strong&gt;降序&lt;/strong&gt;（从大到小）排列。&lt;/td&gt;
&lt;td&gt;必须与 &lt;code&gt;ORDER BY&lt;/code&gt; 子句搭配使用，是一个&lt;strong&gt;关键字&lt;/strong&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;📊 作为表结构查看命令&lt;/h4&gt;
&lt;p&gt;这是 &lt;code&gt;desc&lt;/code&gt; 命令最直接的用途，相当于数据表的“说明书”。执行后，它会返回一个包含以下字段的表格，帮助你全面了解表的设计 ：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;输出列&lt;/th&gt;
&lt;th&gt;含义说明&lt;/th&gt;
&lt;th&gt;备注/示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Field&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;表中每一列（字段）的名称。&lt;/td&gt;
&lt;td&gt;例如 &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Type&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;该列字段的数据类型。&lt;/td&gt;
&lt;td&gt;例如 &lt;code&gt;int(11)&lt;/code&gt;, &lt;code&gt;varchar(255)&lt;/code&gt;, &lt;code&gt;date&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Null【nò】&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;该列是否允许存储空值（NULL【nò】）。&lt;/td&gt;
&lt;td&gt;&lt;code&gt;YES&lt;/code&gt; 表示允许，&lt;code&gt;NO&lt;/code&gt; 表示不允许。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Key&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;表示该列是否定义了键（索引）。&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PRI&lt;/code&gt;（主键），&lt;code&gt;UNI&lt;/code&gt;（唯一索引），&lt;code&gt;MUL&lt;/code&gt;（可重复的非唯一索引前导列或唯一索引的组成部分但可含空值），或为空（无索引）。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Default&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;该列的默认值。如果未显式赋值且未指定默认值，多数情况下显示 &lt;code&gt;NULL【nò】&lt;/code&gt;。&lt;/td&gt;
&lt;td&gt;例如，可设置为 &lt;code&gt;CURRENT_TIMESTAMP&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Extra&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;额外信息，如 &lt;code&gt;auto_increment&lt;/code&gt;（自动递增）。&lt;/td&gt;
&lt;td&gt;常见于主键ID列。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;如何使用：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 查看名为 &apos;employees【ing普洛伊s】&apos; 的表结构
desc employees【ing普洛伊s】;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;💡 如何避免混淆？&lt;/h4&gt;
&lt;p&gt;记住一个简单的规则：&lt;strong&gt;看它的位置&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果 &lt;code&gt;desc&lt;/code&gt; 后面直接跟着&lt;strong&gt;表名&lt;/strong&gt;（如 &lt;code&gt;desc employees【ing普洛伊s】;&lt;/code&gt;），它就是&lt;strong&gt;查看表结构&lt;/strong&gt;的命令。&lt;/li&gt;
&lt;li&gt;如果 &lt;code&gt;desc&lt;/code&gt; 前面有 &lt;strong&gt;&lt;code&gt;ORDER BY&lt;/code&gt;&lt;/strong&gt; 关键字（如 &lt;code&gt;ORDER BY salary【晒了瑞】 desc;&lt;/code&gt;），它就是&lt;strong&gt;指定降序排序&lt;/strong&gt;的关键字。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;命令操作如下所示：&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; desc moershi.user;
+---------------------+-------------+------------+-----+---------------------+----------------+
| Field               | Type        | Null【nò】 | Key| Default【迪-佛特】   | Extra          |
+---------------------+-------------+------------+-----+---------------------+----------------+
| id                  | int         | NO         | PRI | NULL【nò】         | auto_increment |
| name                | char(20)    | YES        |     | NULL【nò】         |                |
| password            | char(1)     | YES        |     | NULL【nò】         |                |
| uid                 | int         | YES        |     | NULL【nò】         |                |
| gid                 | int         | YES        |     | NULL【nò】         |                |
| comment【坑门特】    | varchar(50) | YES        |     | NULL【nò】         |                |
| homedir【home-跌儿】 | varchar(80) | YES        |     | NULL【nò】         |                |
| shell               | char(30)    | YES        |     | NULL【nò】         |                |
+---------------------+-------------+------------+-----+---------------------+----------------+
8 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;插入1条记录给所有表头赋值&lt;/h3&gt;
&lt;p&gt;（给所有表头赋值表头可以省略不写）id表头的值不能重复，主键的知识在后边课程里讲&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.user values【挖柳斯】(40,&quot;jingyaya&quot;,&quot;x&quot;,1001,1001,&quot;teacher&quot;,&quot;/home/jingyaya&quot;,&quot;/bin/bash&quot;);
Query OK, 1 row affected (0.05 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;查看表记录&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】  * from【弗乱】 moershi.user where【威尔】name=&quot;jingyaya&quot;;
+----+----------+----------+------+------+------------------+------------------------+-----------+
| id | name     | password | uid  | gid  | comment【坑门特】 | homedir【home-跌儿】   | shell     |
+----+----------+----------+------+------+------------------+------------------------+-----------+
| 40 | jingyaya | x        | 1001 | 1001 | teacher          | /home/jingyaya         | /bin/bash |
+----+----------+----------+------+------+------------------+------------------------+-----------+
1 row in set【赛特】 (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;插入多行记录给所有列赋值&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt; insert【因涩特】 into【因兔】 moershi.user values【挖柳斯】
(41,&quot;jingyaya2&quot;,&quot;x&quot;,1002,1002,&quot;teacher&quot;,&quot;/home/jingyaya2&quot;,&quot;/bin/bash&quot;),
(42,&quot;jingyaya3&quot;,&quot;x&quot;,1003,1003,&quot;teacher&quot;,&quot;/home/jingyaya3&quot;,&quot;/bin/bash&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;插入1行给指定列赋值，必须写列名，没赋值的列 没有数据 后通过设置的默认值赋值&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.user(name,uid,shell)values【挖柳斯】(&quot;benben&quot;,1002,&quot;/sbin/nologin&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;插入多行给指定列赋值，必须写列名，没赋值的列 没有数据 后通过设置的默认值赋值&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.user(name,uid,shell)values【挖柳斯】(&quot;benben2&quot;,1002,&quot;/sbin/nologin&quot;),(&quot;benben3&quot;,1003,&quot;/sbin/nologin&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;查看记录&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】  * from【弗乱】moershi.user where【威尔】name like  &quot;benben%&quot;;
+----+---------+----------+------+------+-------------------+---------------------+------------------------------+
| id | name    | password | uid  | gid  | comment【坑门特】 | homedir【home-跌儿】 | shell                        |
+----+---------+----------+------+------+-------------------+---------------------+------------------------------+
| 41 | benben  | NULL     | 1002 | NULL | NULL              | NULL                | /sbin/nologin【诺劳京(白话)】 |
| 42 | benben2 | NULL     | 1002 | NULL | NULL              | NULL                | /sbin/nologin【诺劳京(白话)】 |
| 43 | benben3 | NULL     | 1003 | NULL | NULL              | NULL                | /sbin/nologin【诺劳京(白话)】 |
+----+---------+----------+------+------+-------------------+---------------------+------------------------------+
3 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;使用select【涩莱克特】查询结果赋值(查询表头个数和 插入记录命令表头个数要一致)&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 user from【弗乱】 mysql.user;
+------------------+
| user             |
+------------------+
| mysql.infoschema |
| mysql.session    |
| mysql.sys        |
| root             |
+------------------+
4 rows in set【赛特】 (0.00 sec)
mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.user(name) (select【涩莱克特】 user from【弗乱】 mysql.user);
Query OK, 4 rows affected (0.09 sec)
Records: 4  Duplicates: 0  Warnings: 0
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;查看插入后的数据&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】  * from【弗乱】 moershi.user where【威尔】name like &quot;mysql%&quot; or name=&quot;root&quot;;
+----+------------------+----------+------+------+-----------------------+------------------------+------------+
| id | name             | password | uid  | gid  | comment【坑门特】      | homedir【home-跌儿】   | shell      |
+----+------------------+----------+------+------+-----------------------+------------------------+------------+
|  1 | root             | x        |    0 |    0 | root                  | /root                  | /bin/bash  |
| 26 | mysql            | x        |   27 |   27 | MySQL Server          | /var/lib/mysql         | /bin/false |
| 44 | mysql.infoschema | NULL     | NULL | NULL | NULL                  | NULL                   | NULL       |
| 45 | mysql.session    | NULL     | NULL | NULL | NULL                  | NULL                   | NULL       |
| 46 | mysql.sys        | NULL     | NULL | NULL | NULL                  | NULL                   | NULL       |
| 47 | root             | NULL     | NULL | NULL | NULL                  | NULL                   | NULL       |
+----+------------------+----------+------+------+-----------------------+------------------------+------------+
6 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;使用set【赛特】命令赋值&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.user set【赛特】 name=&quot;yaya&quot; , uid=99 , gid=99 ;
Query OK, 1 row affected (0.06 sec)
mysql&amp;gt; select【涩莱克特】 * from【弗乱】 moershi.user where【威尔】name=&quot;yaya&quot;;
+----+------+----------+------+------+------------------+----------------------+-------+
| id | name | password | uid  | gid  | comment【坑门特】 | homedir【home-跌儿】 | shell |
+----+------+----------+------+------+------------------+----------------------+-------+
| 28 | yaya | NULL     |   99 |   99 | NULL             | NULL                 | NULL  |
+----+------+----------+------+------+------------------+----------------------+-------+
1 row in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;七、修改数据&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[单表增删改查]
        direction LR
        A[分组查询] --&amp;gt; B[对查询结果&amp;lt;/n&amp;gt;进行排序] --&amp;gt; C[分组后条件过滤] --&amp;gt; D[新增数据] --&amp;gt; E[修改数据] --&amp;gt; F[删除数据]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class E highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;命令操作如下所示：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;//修改前查看
mysql&amp;gt; select【涩莱克特】  name , comment【坑门特】 from【弗乱】moershi.user where【威尔】id &amp;lt;= 10 ;
+----------+--------------------+
| name     | comment【坑门特】  |
+----------+--------------------+
| root     | root               |
| bin      | bin                |
| daemon   | daemon             |
| adm      | adm                |
| lp       | lp                 |
| sync     | sync               |
| shutdown | shutdown           |
| halt     | halt               |
| mail     | mail               |
| operator | operator           |
+----------+--------------------+
10 rows in set【赛特】 (0.00 sec)
//修改符合条件
mysql&amp;gt; update【阿普 dei 特】 moershi.user set【赛特】 comment【坑门特】=NULL【nò】 where【威尔】id &amp;lt;= 10 ;
Query OK, 10 rows affected (0.09 sec)
Rows matched: 10  Changed: 10  Warnings: 0
//修改后查看
mysql&amp;gt; select【涩莱克特】  name , comment【坑门特】 from【弗乱】moershi.user where【威尔】id &amp;lt;= 10 ;
+----------+------------------+
| name     | comment【坑门特】 |
+----------+------------------+
| root     | NULL             |
| bin      | NULL             |
| daemon   | NULL             |
| adm      | NULL             |
| lp       | NULL             |
| sync     | NULL             |
| shutdown | NULL             |
| halt     | NULL             |
| mail     | NULL             |
| operator | NULL             |
+----------+------------------+
10 rows in set【赛特】 (0.00 sec) 
[root@localhost ~]#
//修改前查看
mysql&amp;gt; select【涩莱克特】 name , homedir  from【弗乱】moershi.user;
+------------------+--------------------+
| name             | homedir【home-跌儿】|
+------------------+--------------------+
| root             | /root              |
| bin              | /bin               |
| daemon           | /sbin              |
| adm              | /var/adm           |
| lp               | /var/spool/lpd     |
| sync             | /sbin              |
| shutdown         | /sbin              |
| halt             | /sbin              |
| mail             | /var/spool/mail    |
| operator         | /root              |
| games            | /usr/games         |
| ftp              | /var/ftp           |
| nobody           | /                  |
| systemd-network  | /                  |
| dbus             | /                  |
| polkitd          | /                  |
| sshd             | /var/empty/sshd    |
| postfix          | /var/spool/postfix |
| chrony           | /var/lib/chrony    |
| rpc              | /var/lib/rpcbind   |
| rpcuser          | /var/lib/nfs       |
| nfsnobody        | /var/lib/nfs       |
| haproxy          | /var/lib/haproxy   |
| plj              | /home/plj          |
| apache           | /usr/share/httpd   |
| mysql            | /var/lib/mysql     |
| bob              | NULL               |
| jerrya           | NULL               |
| jingyaya         | /home/jingyaya     |
| benben           | NULL               |
| benben2          | NULL               |
| benben3          | NULL               |
| mysql.infoschema | NULL               |
| mysql.session    | NULL               |
| mysql.sys        | NULL               |
| root             | NULL               |
+------------------+--------------------+
36 rows in set【赛特】 (0.00 sec)
//不加条件批量修改
mysql&amp;gt; update【阿普 dei 特】  moershi.user set【赛特】 homedir=&quot;/student&quot; ;
Query OK, 36 rows affected (0.09 sec)
Rows matched: 36  Changed: 36  Warnings: 0
//修改后查看
mysql&amp;gt; select【涩莱克特】 name , homedir  from【弗乱】moershi.user;
+------------------+---------------------+
| name             | homedir【home-跌儿】|
+------------------+---------------------+
| root             | /student            |
| bin              | /student            |
| daemon           | /student            |
| adm              | /student            |
| lp               | /student            |
| sync             | /student            |
| shutdown         | /student            |
| halt             | /student            |
| mail             | /student            |
| operator         | /student            |
| games            | /student            |
| ftp              | /student            |
| nobody           | /student            |
| systemd-network  | /student            |
| dbus             | /student            |
| polkitd          | /student            |
| sshd             | /student            |
| postfix          | /student            |
| chrony           | /student            |
| rpc              | /student            |
| rpcuser          | /student            |
| nfsnobody        | /student            |
| haproxy          | /student            |
| plj              | /student            |
| apache           | /student            |
| mysql            | /student            |
| bob              | /student            |
| jerrya           | /student            |
| jingyaya         | /student            |
| benben           | /student            |
| benben2          | /student            |
| benben3          | /student            |
| mysql.infoschema | /student            |
| mysql.session    | /student            |
| mysql.sys        | /student            |
| root             | /student            |
+------------------+---------------------+
36 rows in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;八、删除数据&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[单表增删改查]
        direction LR
        A[分组查询] --&amp;gt; B[对查询结果&amp;lt;/n&amp;gt;进行排序] --&amp;gt; C[分组后条件过滤] --&amp;gt; D[新增数据] --&amp;gt; E[修改数据] --&amp;gt; F[删除数据]
    end

    classDef highlight stroke:#f00,stroke-width:2px;
    class F highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//删除前查看
mysql&amp;gt; select【涩莱克特】  * from【弗乱】moershi.user where【威尔】id &amp;lt;= 10 ;
+----+----------+----------+------+------+------------------+---------------------+----------------+
| id | name     | password | uid  | gid  | comment【坑门特】 | homedir【home-跌儿】| shell          |
+----+----------+----------+------+------+------------------+---------------------+----------------+
|  1 | root     | x        |    0 |    0 | NULL             | /student            | /bin/bash      |
|  2 | bin      | x        |    1 |    1 | NULL             | /student            | /sbin/nologin  |
|  3 | daemon   | x        |    2 |    2 | NULL             | /student            | /sbin/nologin  |
|  4 | adm      | x        |    3 |    4 | NULL             | /student            | /sbin/nologin  |
|  5 | lp       | x        |    4 |    7 | NULL             | /student            | /sbin/nologin  |
|  6 | sync     | x        |    5 |    0 | NULL             | /student            | /bin/sync      |
|  7 | shutdown | x        |    6 |    0 | NULL             | /student            | /sbin/shutdown |
|  8 | halt     | x        |    7 |    0 | NULL             | /student            | /sbin/halt     |
|  9 | mail     | x        |    8 |   12 | NULL             | /student            | /sbin/nologin  |
| 10 | operator | x        |   11 |    0 | NULL             | /student            | /sbin/nologin  |
+----+----------+----------+------+------+------------------+---------------------+----------------+
10 rows in set【赛特】 (0.00 sec)
//仅删除与条件匹配的行
mysql&amp;gt; delete【迪利特】 from【弗乱】moershi.user where【威尔】id &amp;lt;= 10 ;
Query OK, 10 rows affected (0.06 sec)
//查不到符合条件的记录了
mysql&amp;gt; select【涩莱克特】  * from【弗乱】moershi.user where【威尔】id &amp;lt;= 10 ;
Empty set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;九、作业&lt;/h2&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;employees【ing普洛伊s】&lt;/code&gt; 表中，要将查询结果按照 &lt;code&gt;hire_date&lt;/code&gt; 降序排列，应使用以下哪个关键字？B
A. &lt;code&gt;ASC【阿斯克】&lt;/code&gt;
B. &lt;code&gt;desc&lt;/code&gt;
C. &lt;code&gt;GROUP【格鲁普】 BY&lt;/code&gt;
D. &lt;code&gt;HAVING【嗨夫营】&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;若要在 &lt;code&gt;departments【迪帕踢门特s】&lt;/code&gt; 表中新增一条记录，&lt;code&gt;dept_name&lt;/code&gt; 为 &apos;市场部&apos;，以下 SQL 语句正确的是？ A
A. &lt;code&gt;INSERT【因涩特】 INTO【因兔】 departments【迪帕踢门特s】 (dept_name) VALUES【挖柳斯】 (&apos;市场部&apos;);&lt;/code&gt;
B. &lt;code&gt;UPDATE【阿普 dei 特】 departments【迪帕踢门特s】 SET【赛特】 dept_name = &apos;市场部&apos;;&lt;/code&gt;
C. &lt;code&gt;DELETE【迪利特】 from【弗乱】departments【迪帕踢门特s】 where【威尔】dept_name = &apos;市场部&apos;;&lt;/code&gt;
D. &lt;code&gt;SELECT * from【弗乱】departments【迪帕踢门特s】 where【威尔】dept_name = &apos;市场部&apos;;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;salary【晒了瑞】&lt;/code&gt; 表中，要统计每个员工的总薪资（&lt;code&gt;basic【贝斯克】&lt;/code&gt; 与 &lt;code&gt;bonus【波诺斯】&lt;/code&gt; 之和），并按照总薪资降序排列，以下 SQL 语句正确的是？A
A. &lt;code&gt;SELECT employee【ing普洛伊】_id, SUM(basic【贝斯克】 + bonus【波诺斯】) AS total【偷ò头ō】_salary【晒了瑞】 from【弗乱】salary【晒了瑞】 GROUP【格鲁普】 BY employee【ing普洛伊】_id ORDER【欧朵】 BY total【偷ò头ō】_salary【晒了瑞】 desc;&lt;/code&gt;
B. &lt;code&gt;SELECT employee【ing普洛伊】_id, AVG(basic【贝斯克】 + bonus【波诺斯】) AS total【偷ò头ō】_salary【晒了瑞】 from【弗乱】salary【晒了瑞】 GROUP【格鲁普】 BY employee【ing普洛伊】_id ORDER【欧朵】 BY total【偷ò头ō】_salary【晒了瑞】 desc;&lt;/code&gt;
C. &lt;code&gt;SELECT employee【ing普洛伊】_id, SUM(basic【贝斯克】 + bonus【波诺斯】) AS total【偷ò头ō】_salary【晒了瑞】 from【弗乱】salary【晒了瑞】 ORDER【欧朵】 BY total【偷ò头ō】_salary【晒了瑞】 desc;&lt;/code&gt;
D. &lt;code&gt;SELECT employee【ing普洛伊】_id, AVG(basic【贝斯克】 + bonus【波诺斯】) AS total【偷ò头ō】_salary【晒了瑞】 from【弗乱】salary【晒了瑞】 ORDER【欧朵】 BY total【偷ò头ō】_salary【晒了瑞】 desc;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在分组查询中，&lt;code&gt;HAVING【嗨夫营】&lt;/code&gt; 子句的作用是？B
A. 对分组前的数据进行过滤
B. 对分组后的数据进行过滤
C. 对查询结果进行排序
D. 对数据进行分组&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;要删除 &lt;code&gt;employees【ing普洛伊s】&lt;/code&gt; 表中 &lt;code&gt;employee【ing普洛伊】_id&lt;/code&gt; 为 10 的记录，以下 SQL 语句正确的是？B
A. &lt;code&gt;UPDATE【阿普 dei 特】 employees SET【赛特】 employee_id = NULL【nò】 where【威尔】employee_id = 10;&lt;/code&gt;
B. &lt;code&gt;DELETE【迪利特】 from【弗乱】employees where【威尔】employee_id = 10;&lt;/code&gt;
C. &lt;code&gt;SELECT * from【弗乱】employees where【威尔】employee_id = 10;&lt;/code&gt;
D. &lt;code&gt;INSERT【因涩特】 INTO【因兔】 employees (employee_id) VALUES【挖柳斯】 (10);&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;简述 &lt;code&gt;WHERE&lt;/code&gt; 子句和 &lt;code&gt;HAVING&lt;/code&gt; 子句的区别。
答： &lt;code&gt;WHERE&lt;/code&gt;是对分组前的原始数据行进行筛选
&lt;code&gt;HAVING&lt;/code&gt;是对分组后的组进行筛选&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;UPDATE&lt;/code&gt; 语句中，&lt;code&gt;SET&lt;/code&gt; 关键字的作用是什么？
答：&lt;code&gt;SET&lt;/code&gt; 关键字的作用是指定要修改的内容&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;新增数据时，&lt;code&gt;INSERT INTO&lt;/code&gt; 语句有哪几种常见的使用方式？
答：1、向表中插入一条完整记录。
2、向表中插入部分字段的值（未指定的字段将采用默认值或自动生成的值，如自增主键）。
3、一次性插入多条记录（批量插入）。
4、结合 SELECT语句，将查询结果插入到另一个表中。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3 操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;在 &lt;code&gt;employees&lt;/code&gt; 表中新增一条记录，&lt;code&gt;name&lt;/code&gt; 为 &apos;李四&apos;，&lt;code&gt;hire_date&lt;/code&gt; 为 &apos;2025-06-01&apos;，&lt;code&gt;birth_date&lt;/code&gt; 为 &apos;1990-05-10&apos;，&lt;code&gt;email&lt;/code&gt; 为 &apos;lisi@example.com&apos;，&lt;code&gt;phone_number&lt;/code&gt; 为 &apos;13800138000&apos;，&lt;code&gt;dept_id&lt;/code&gt; 为 2。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; insert into moershi.employees values(134,&quot;李四&quot;,&quot;2025-06-01&quot;,&quot;1990-05-10&quot;,&quot;lisi@example.com&quot;,13800138000,2);
Query OK, 1 row affected (0.19 sec)

mysql&amp;gt; select * from moershi.employees where employee_id=134;
+-------------+--------+------------+------------+------------------+--------------+---------+
| employee_id | name   | hire_date  | birth_date | email            | phone_number | dept_id |
+-------------+--------+------------+------------+------------------+--------------+---------+
|         134 | 李四   | 2025-06-01 | 1990-05-10 | lisi@example.com | 13800138000  |       2 |
+-------------+--------+------------+------------+------------------+--------------+---------+
1 row in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;将 &lt;code&gt;departments&lt;/code&gt; 表中 &lt;code&gt;dept_id&lt;/code&gt; 为 3 的 &lt;code&gt;dept_name&lt;/code&gt; 修改为 &apos;研发部&apos;。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; select * from moershi.departments where dept_id=3;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|       3 | 运维部    |
+---------+-----------+
1 row in set (0.00 sec)

mysql&amp;gt; update moershi.departments set dept_name=&quot;研发部&quot; where dept_id=3;
Query OK, 1 row affected (0.13 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql&amp;gt; select * from moershi.departments where dept_id=3;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|       3 | 研发部    |
+---------+-----------+
1 row in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;统计 &lt;code&gt;salary&lt;/code&gt; 表中每个员工的平均基本工资（&lt;code&gt;basic&lt;/code&gt; 列），只显示平均基本工资大于 5000 的员工信息，并按照平均基本工资降序排列。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; select employee_id,avg(basic) as 平均工资  from moershi.salary group by employee_id having avg(basic) &amp;gt; 5000 order by 平均工资 desc;
+-------------+--------------+
| employee_id | 平均工资     |
+-------------+--------------+
|         103 |   27023.3333 |
|          19 |   26520.0000 |
|         104 |   24251.1429 |
|         117 |   23905.0000 |
|           8 |   23741.5600 |
|          86 |   22766.9444 |
|         112 |   22766.9444 |
|          10 |   22314.9286 |
|          16 |   22314.9286 |
|         102 |   21911.2462 |
|         119 |   21628.2083 |
|         118 |   21628.2083 |
|           7 |   21628.2083 |
|         106 |   21628.2083 |
|         105 |   20490.1528 |
|         122 |   20490.1528 |
|          91 |   20311.2979 |
|          76 |   19351.5972 |
|          88 |   19351.5972 |
|           2 |   19351.5972 |
|          95 |   18213.9028 |
|          98 |   18213.9028 |
|         123 |   18213.9028 |
|          92 |   18213.9028 |
|          17 |   18213.9028 |
|         107 |   18015.6818 |
|          80 |   17644.5789 |
|           1 |   17279.1000 |
|           5 |   17125.8000 |
|         110 |   17074.6528 |
|         108 |   17074.6528 |
|          13 |   17074.6528 |
|         131 |   16653.7692 |
|         125 |   16525.1887 |
|         127 |   16427.4107 |
|          81 |   15991.9286 |
|           4 |   15936.5972 |
|           6 |   15936.5972 |
|          11 |   15936.5972 |
|          12 |   15506.8125 |
|          85 |   14798.0417 |
|          79 |   14798.0417 |
|          99 |   14798.0417 |
|          75 |   13760.0417 |
|         129 |   13659.9861 |
|          94 |   13659.9861 |
|          96 |   13659.9861 |
|         124 |   13659.9861 |
|         100 |   13659.9861 |
|           9 |   12931.4545 |
|         115 |   12521.2500 |
|          14 |   11383.2083 |
|         120 |   11044.4242 |
|          15 |   11044.4242 |
|         128 |   10337.5000 |
|          78 |   10244.4722 |
|         126 |   10244.4722 |
|          84 |   10244.4722 |
|         113 |   10244.4722 |
|         132 |   10244.4722 |
|          83 |    9106.9444 |
|         121 |    9106.9444 |
|         116 |    9106.9444 |
|           3 |    9106.9444 |
|         130 |    9106.9444 |
|          82 |    7967.6944 |
|          93 |    7967.6944 |
|         109 |    7967.6944 |
|          77 |    7967.6944 |
|          87 |    7281.6410 |
|          89 |    6829.6389 |
|         101 |    6829.6389 |
|          18 |    6829.6389 |
|          97 |    6829.6389 |
|         114 |    5690.9028 |
|         111 |    5690.9028 |
|          90 |    5690.9028 |
|         133 |    5690.9028 |
+-------------+--------------+
78 rows in set (0.01 sec)

mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;要统计 `salary` 表中每个员工的平均基本工资，并筛选出平均工资大于5000且按降序排列，可以使用以下SQL语句。其核心在于使用 `GROUP BY` 对员工分组，使用 `HAVING` 对分组后的聚合结果进行过滤。

### 🔍 查询语句及说明

完整的SQL查询语句如下：

SELECT employee_id, AVG(basic) AS avg_basic_salary
FROM salary
GROUP BY employee_id
HAVING AVG(basic) &amp;gt; 5000
ORDER BY avg_basic_salary DESC;


下面这个表格详细解释了每个子句的作用：

| SQL 子句 | 作用说明 | 备注 |
| :--- | :--- | :--- |
| `SELECT employee_id, AVG(basic) AS avg_basic_salary` | 选择员工编号和计算出的平均基本工资，并为平均工资列设置别名 `avg_basic_salary`。 | `AVG()` 是聚合函数，用于计算平均值。 |
| `FROM salary` | 指定查询的数据来源是 `salary` 表。 | - |
| `GROUP BY employee_id` | 根据 `employee_id` 进行分组。这是使用聚合函数（如`AVG`）的前提，它将数据按每个员工归类。 | 确保 `SELECT` 中非聚合列在 `GROUP BY` 中出现。 |
| `HAVING AVG(basic) &amp;gt; 5000` | 对分组（即每个员工）后的结果进行筛选，只保留平均基本工资大于5000的记录。**`HAVING` 专门用于过滤聚合函数的结果**。 | 这与在分组前过滤行的 `WHERE` 子句有本质区别。 |
| `ORDER BY avg_basic_salary DESC` | 将最终结果按照平均基本工资（别名）从高到低进行排序。 | `DESC` 表示降序，`ASC` 表示升序。 |

### 💡 关键点与技巧

- **`HAVING` 与 `WHERE` 的区别**：这是编写此类查询的关键。`WHERE` 子句在 **分组之前** 过滤原始数据行，并且其条件中不能直接使用聚合函数（如 `AVG(), COUNT()`）。`HAVING` 子句在 **分组之后** 过滤分组结果，条件通常包含聚合函数。如果你的过滤条件不涉及聚合计算（例如 `employee_id &amp;gt; 100`），则应使用 `WHERE`，这能先减少数据量，提升查询效率。

- **使用列别名**：在 `ORDER BY` 子句中，我们可以直接使用在 `SELECT` 中定义的列别名（`avg_basic_salary`），这使得语句更简洁易读。但请注意，在某些数据库系统中，`HAVING` 子句可能不支持直接使用别名，此时需要重复聚合函数（如 `HAVING AVG(basic) &amp;gt; 5000`），如示例中所示。

### 📚 扩展思考

你可以通过修改聚合函数和条件来满足不同的统计需求。例如：
- 统计每个员工的**总工资**（假设还有其他工资项）：`SELECT employee_id, SUM(basic + bonus) AS total_salary FROM salary GROUP BY employee_id HAVING SUM(basic + bonus) &amp;gt; 10000 ORDER BY total_salary DESC;`
- 先通过 `WHERE` 子句排除某些记录后再进行分组统计，例如，只统计某个月份之后的数据。
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;删除 &lt;code&gt;employees&lt;/code&gt; 表中 &lt;code&gt;dept_id&lt;/code&gt; 为 4 的所有记录。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; --查询删除前数据
mysql&amp;gt; select * from moershi.employees where dept_id=4;
+-------------+-----------+------------+------------+---------------------------+--------------+---------+
| employee_id | name      | hire_date  | birth_date | email                     | phone_number | dept_id |
+-------------+-----------+------------+------------+---------------------------+--------------+---------+
|          20 | 蒋红      | 2017-12-29 | 1978-01-24 | jianghong@tedu.cn         | 15852915398  |       4 |
|          21 | 曹宁      | 2004-06-07 | 1988-01-05 | caoning@tedu.cn           | 14513022304  |       4 |
|          22 | 吕刚      | 2014-01-18 | 1980-06-24 | lvgang@tedu.cn            | 18136987619  |       4 |
|          23 | 王莉      | 2021-02-04 | 1972-12-19 | wangli@moershi.com        | 15376329290  |       4 |
|          24 | 邓秀芳    | 2020-09-08 | 1980-12-12 | dengxiufang@moershi.com   | 15884927117  |       4 |
|          25 | 邵佳      | 2011-08-15 | 1978-11-28 | shaojia@tedu.cn           | 13296016750  |       4 |
|          26 | 党丽      | 2014-03-14 | 1978-12-30 | dangli@moershi.com        | 13166234580  |       4 |
|          27 | 梁勇      | 2007-01-19 | 1997-11-12 | liangyong@tedu.cn         | 15307868657  |       4 |
|          28 | 郑秀珍    | 2011-04-28 | 1972-09-01 | zhengxiuzhen@moershi.com  | 14543186401  |       4 |
|          29 | 胡秀云    | 2003-11-03 | 2000-05-14 | huxiuyun@tedu.cn          | 18212266720  |       4 |
|          30 | 邢淑兰    | 2011-07-02 | 1989-06-17 | xingshulan@moershi.com    | 13032270370  |       4 |
|          31 | 刘海燕    | 2018-01-06 | 1982-08-21 | liuhaiyan@moershi.com     | 15064354651  |       4 |
|          32 | 冯建国    | 2014-05-28 | 1980-01-26 | fengjianguo@tedu.cn       | 13344957322  |       4 |
|          33 | 曹杰      | 2017-01-04 | 1975-07-03 | caojie@moershi.com        | 13244741822  |       4 |
|          34 | 苗桂花    | 2001-10-06 | 1974-01-26 | miaoguihua@tedu.cn        | 18124884107  |       4 |
|          35 | 袁建平    | 2020-09-17 | 1990-07-25 | yuanjianping@moershi.com  | 13580624147  |       4 |
|          36 | 黄淑兰    | 2019-08-29 | 1988-02-08 | huangshulan@tedu.cn       | 14568738205  |       4 |
|          37 | 朱淑兰    | 2002-04-26 | 1977-12-10 | zhushulan@tedu.cn         | 13635439422  |       4 |
|          38 | 曹凯      | 2006-07-23 | 1995-11-07 | caokai@moershi.com        | 15172694474  |       4 |
|          39 | 张倩      | 2009-10-27 | 2000-04-27 | zhangqian@tedu.cn         | 15053279648  |       4 |
|          40 | 王淑珍    | 2013-09-21 | 1995-05-06 | wangshuzhen@tedu.cn       | 18583012709  |       4 |
|          41 | 陈玉      | 2011-08-20 | 1985-06-14 | chenyu@tedu.cn            | 13632957562  |       4 |
|          42 | 陈玉英    | 2020-10-03 | 1996-05-19 | chenyuying@tedu.cn        | 15100520600  |       4 |
|          43 | 王波      | 2008-06-14 | 1979-05-26 | wangbo@tedu.cn            | 15236208918  |       4 |
|          44 | 黄文      | 2010-06-05 | 1983-01-30 | huangwen@tedu.cn          | 13688719481  |       4 |
|          45 | 陈刚      | 2010-10-26 | 1978-05-10 | chengang@tedu.cn          | 13679861175  |       4 |
|          46 | 罗建华    | 2004-06-20 | 1989-02-23 | luojianhua@tedu.cn        | 13176305978  |       4 |
|          47 | 黄建平    | 2009-04-09 | 1995-07-15 | huangjianping@moershi.com | 18517722322  |       4 |
|          48 | 范秀英    | 2001-03-13 | 1996-06-01 | fanxiuying@moershi.com    | 18252125689  |       4 |
|          49 | 李平      | 2003-10-28 | 1998-07-24 | liping@tedu.cn            | 18526198243  |       4 |
|          50 | 臧龙      | 2011-10-06 | 1976-05-11 | zanglong@moershi.com      | 13474064425  |       4 |
|          51 | 吴静      | 2017-09-26 | 1983-08-04 | wujing@tedu.cn            | 14762137325  |       4 |
|          52 | 张冬梅    | 2010-10-26 | 1982-05-09 | zhangdongmei@tedu.cn      | 13690746261  |       4 |
|          53 | 邢成      | 2018-05-07 | 1991-07-13 | xingcheng@moershi.com     | 13983238261  |       4 |
|          54 | 孙丹      | 2012-01-28 | 1997-02-22 | sundan@moershi.com        | 13684254376  |       4 |
|          55 | 梁静      | 2013-03-21 | 1995-05-20 | liangjing@moershi.com     | 18077866993  |       4 |
|          56 | 陈洁      | 2006-08-17 | 1977-04-23 | chenjie@tedu.cn           | 14737309895  |       4 |
|          57 | 许辉      | 2014-09-16 | 1992-10-21 | xuhui@moershi.com         | 13143391754  |       4 |
|          58 | 张伟      | 2007-06-22 | 1999-04-30 | zhangwei@moershi.com      | 18172302428  |       4 |
|          59 | 钟倩      | 2011-02-23 | 1983-06-28 | zhongqian@moershi.com     | 18611282765  |       4 |
|          60 | 贺磊      | 2001-06-19 | 1993-02-07 | helei@tedu.cn             | 15897839325  |       4 |
|          61 | 沈秀梅    | 2003-04-27 | 1992-08-13 | shenxiumei@tedu.cn        | 18044302910  |       4 |
|          62 | 林刚      | 2007-09-19 | 1990-09-23 | lingang@tedu.cn           | 13355063263  |       4 |
|          63 | 王玉华    | 2016-10-09 | 1973-09-14 | wangyuhua@tedu.cn         | 18010485419  |       4 |
|          64 | 徐金凤    | 2015-09-09 | 1972-01-31 | xujinfeng@tedu.cn         | 15124816733  |       4 |
|          65 | 张淑英    | 2010-11-08 | 1996-09-12 | zhangshuying@moershi.com  | 18846908114  |       4 |
|          66 | 罗岩      | 2001-06-13 | 1986-10-17 | luoyan@tedu.cn            | 14544559539  |       4 |
|          67 | 潘玲      | 2017-08-31 | 1993-02-18 | panling@tedu.cn           | 13311560534  |       4 |
|          68 | 柴冬梅    | 2003-11-24 | 1976-01-01 | chaidongmei@moershi.com   | 14506733843  |       4 |
|          69 | 谢莹      | 2017-12-06 | 1996-04-01 | xieying@tedu.cn           | 15137904023  |       4 |
|          70 | 傅雪      | 2001-04-23 | 1976-09-06 | fuxue@moershi.com         | 15210059051  |       4 |
|          71 | 龙旭      | 2019-05-15 | 1974-11-02 | longxu@moershi.com        | 15155879580  |       4 |
|          72 | 赵杰      | 2004-05-08 | 1984-04-06 | zhaojie@tedu.cn           | 13466360255  |       4 |
|          73 | 王璐      | 2003-09-22 | 2000-02-01 | wanglu@moershi.com        | 13056592974  |       4 |
|          74 | 赵成      | 2012-11-30 | 1985-10-11 | zhaocheng@tedu.cn         | 18545824587  |       4 |
+-------------+-----------+------------+------------+---------------------------+--------------+---------+
55 rows in set (0.00 sec)


mysql&amp;gt; --外键约束,先删除salary表对应数据
mysql&amp;gt; delete from moershi.salary where employee_id in (select employee_id from moershi.employees where dept_id=4);
Query OK, 3308 rows affected (0.36 sec)

mysql&amp;gt; --删除employees表dept_id=4的数据
mysql&amp;gt; delete from moershi.employees where dept_id=4;
Query OK, 55 rows affected (0.22 sec)

mysql&amp;gt; --查询删除后结果
mysql&amp;gt; select * from moershi.employees where dept_id=4;
Empty set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;您在删除 `dept_id=4` 的部门记录时遇到了外键约束错误，这表明有其他表（比如 `salary` 表）的数据通过外键关联着这个部门的员工记录。下面为您梳理解决方案。

### 🔍 理解错误原因
错误信息 `Cannot delete or update a parent row: a foreign key constraint fails` 表明，由于外键约束的存在，您无法直接删除 `employees` 表中 `dept_id=4` 的记录。这通常是数据库为了维护数据一致性而设定的保护机制，防止出现“孤悬数据”（例如，工资记录对应的员工信息不存在了）。

核心问题在于，`salary` 表通过 `employee_id` 字段关联了 `employees` 表。当您尝试删除 `employees` 表中的某条员工记录时，如果 `salary` 表中还存在与之对应的工资记录，数据库就会阻止这个删除操作。

### ✅ 解决方案选择
您可以根据具体情况选择下表列出的方法来解决这个问题：

| 解决方案 | 核心操作 | 适用场景 |
| :--- | :--- | :--- |
| **先删关联数据** | 先手动删除 `salary` 表中相关的员工工资记录，再删除 `employees` 表中的员工记录。 | 希望精确控制删除范围，或数据库未设置级联删除时。 |
| **临时禁用约束** | 暂时关闭外键约束检查，执行删除操作后重新开启。 | 需要快速处理数据，且确认删除不会破坏业务逻辑；**需谨慎使用**。 |
| **设置级联删除** | 修改外键约束，设置 `ON DELETE CASCADE`。 | 希望一劳永逸，后续删除员工能自动同步删除其工资记录。 |

### ⚠️ 重要操作步骤与提醒
无论选择哪种方法，**在进行任何删除或结构修改操作前，强烈建议备份数据**。

- **方案一：先删除关联数据**
  这种方法思路直接，即先清除子表（`salary`）中的相关记录，再删除父表（`employees`）中的记录。
  ```sql
  -- 1. 首先删除 salary 表中所有属于 dept_id=4 部门的员工的工资记录
  DELETE FROM moershi.salary 
  WHERE employee_id IN (SELECT employee_id FROM moershi.employees WHERE dept_id = 4);

  -- 2. 然后再删除 employees 表中 dept_id=4 的员工记录
  DELETE FROM moershi.employees WHERE dept_id = 4;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;方案二：临时禁用外键约束&lt;/strong&gt;
此方法通过 &lt;code&gt;SET FOREIGN_KEY_CHECKS = 0;&lt;/code&gt; 临时关闭外键约束检查，操作完成后务必记得重新开启。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 临时禁用外键约束检查
SET FOREIGN_KEY_CHECKS = 0;

-- 执行删除操作
DELETE FROM moershi.employees WHERE dept_id = 4;

-- 立即重新启用外键约束检查
SET FOREIGN_KEY_CHECKS = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：这种方法会暂时破坏数据库的引用完整性，如果操作不当，可能导致数据不一致，请务必确保在可控范围内使用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;方案三：设置级联删除（长远之计）&lt;/strong&gt;
级联删除是一种“一劳永逸”的解决方案。设置后，当您删除 &lt;code&gt;employees&lt;/code&gt; 表中的某位员工时，数据库会自动删除 &lt;code&gt;salary&lt;/code&gt; 表中与之相关的所有工资记录。
首先，你需要删除原有的外键约束，然后重新添加一个带有级联删除选项的新约束。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 1. 先删除现有的外键约束（需要知道约束名称，错误信息中提示是 `emp_id_fk`）
ALTER TABLE moershi.salary DROP FOREIGN KEY emp_id_fk;

-- 2. 重新添加外键约束，并设置级联删除
ALTER TABLE moershi.salary 
ADD CONSTRAINT emp_id_fk 
FOREIGN KEY (employee_id) REFERENCES employees(employee_id) 
ON DELETE CASCADE;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;设置完成后，您再次执行 &lt;code&gt;DELETE FROM moershi.employees WHERE dept_id=4;&lt;/code&gt;，数据库就会自动处理关联的工资记录了。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;💡 决策建议与总结&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;若&lt;strong&gt;当前操作是临时的、一次性的&lt;/strong&gt;，建议使用&lt;strong&gt;方案一（先删关联数据）&lt;/strong&gt;，它最清晰、可控。&lt;/li&gt;
&lt;li&gt;若&lt;strong&gt;经常需要进行此类关联删除&lt;/strong&gt;，建议使用&lt;strong&gt;方案三（设置级联删除）&lt;/strong&gt;，一劳永逸，但务必理解其自动删除的后果。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;方案二（临时禁用约束）&lt;/strong&gt; 风险较高，通常用于数据迁移或清理等特定场景，&lt;strong&gt;日常操作请谨慎选择&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;请根据您的具体需求选择最合适的方法。如果对约束名称或具体操作步骤仍有疑问，可以随时追问。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;从 &lt;code&gt;employees&lt;/code&gt; 表中查询出所有在 2025 年入职的员工信息，并按照 &lt;code&gt;hire_date&lt;/code&gt; 升序排列。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; 
mysql&amp;gt; select * from moershi.employees where year(hire_date) = 2025 order by hire_date asc;
+-------------+--------+------------+------------+------------------+--------------+---------+
| employee_id | name   | hire_date  | birth_date | email            | phone_number | dept_id |
+-------------+--------+------------+------------+------------------+--------------+---------+
|         134 | 李四   | 2025-06-01 | 1990-05-10 | lisi@example.com | 13800138000  |       2 |
+-------------+--------+------------+------------+------------------+--------------+---------+
1 row in set (0.00 sec)

mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;要从 `employees` 表中查询出所有在 2025 年入职的员工信息并按入职日期升序排列，可以使用以下 SQL 语句：

    ```sql
    SELECT *
    FROM employees
    WHERE YEAR(hire_date) = 2025
    ORDER BY hire_date ASC;
    ```

下面是这个查询语句中各部分作用的详细说明：

| SQL 部分 | 作用说明 | 备注 |
| :--- | :--- | :--- |
| `SELECT *` | 选择所有列 | 返回员工表的所有字段信息。 |
| `FROM employees` | 指定数据来源 | 从名为 `employees` 的表中查询数据。 |
| `WHERE YEAR(hire_date) = 2025` | 筛选条件 | **`YEAR()` 函数用于从日期中提取年份**，这里限定只查询入职年份为 2025 年的记录。 |
| `ORDER BY hire_date ASC` | 排序结果 | 按照 `hire_date`（入职日期）字段进行升序排列。`ASC` 表示升序，可以省略，因为它是默认的排序方式。 |

### 💡 其他可行的日期筛选方法

除了使用 `YEAR()` 函数，你也可以考虑以下方法来实现相同的筛选目标，它们在特定场景下可能更有用：

- **使用 `BETWEEN` 指定日期范围**
  你可以明确指定入职日期的起止范围来筛选2025年的记录：
    ```sql
    SELECT *
    FROM employees
    WHERE hire_date BETWEEN &apos;2025-01-01&apos; AND &apos;2025-12-31&apos;
    ORDER BY hire_date;
    ```

- **使用 `DATE_FORMAT()` 函数**
  `DATE_FORMAT()` 函数功能强大，可以按各种格式输出日期。用它来提取年份部分进行匹配也是一种方法：
    ```sql
    SELECT *
    FROM employees
    WHERE DATE_FORMAT(hire_date, &apos;%Y&apos;) = &apos;2025&apos;
    ORDER BY hire_date;
    ```

&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h1&gt;04：mysql之综合查询&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[综合查询]
        direction LR
        A[内连接查询] --&amp;gt; B[外连接查询] --&amp;gt; C[合并查询结果] --&amp;gt; D[嵌套查询]
    end
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;在一家中型企业的人力资源管理工作里，会频繁运用 MySQL 综合查询。企业有员工表，包含员工编号、姓名、入职时间等；部门表记录着部门编号、部门名称等；薪资表存有员工编号、薪资数额、发放日期等。&lt;/p&gt;
&lt;p&gt;每到季度末，人力部门需要统计各部门员工的平均薪资。这时就会综合查询这三张表。通过员工编号关联员工表和薪资表，再通过部门编号关联员工表和部门表。筛选出本季度发放的薪资数据，按部门分组计算平均薪资。如此，就能清晰了解各部门的人力成本，为后续的预算规划、薪资调整等提供数据支撑。&lt;/p&gt;
&lt;h2&gt;二、为什么要学综合查询&lt;/h2&gt;
&lt;p&gt;在日常工作里，学会 MySQL 综合查询是非常必要的。以员工表、部门表和薪资表为例，单看一张表，能获取的信息有限。员工表只有员工基本信息，部门表只有部门情况，薪资表只有薪资数据。&lt;/p&gt;
&lt;p&gt;但当你掌握综合查询，就能将三张表关联起来。比如想知道每个部门的平均薪资，就可以通过员工表关联部门表和薪资表，快速得出结果。还能查询出不同部门入职时间早且薪资高的员工。综合查询让你从多个角度挖掘数据价值，为企业的决策提供准确依据，极大提升工作效率和质量，所以很有学习的必要。&lt;/p&gt;
&lt;h2&gt;三、内连接查询&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[综合查询]
        direction LR
        A[内连接查询] --&amp;gt; B[外连接查询] --&amp;gt; C[合并查询结果] --&amp;gt; D[嵌套查询]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class A highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;MySQL 内连接查询是一种常用的表连接方式，用于从多个表中提取相关联的数据。它分为隐式和显式内连接查询，区别在于是否包含 &lt;code&gt;inner【ing呐】 join【载(白话)】&lt;/code&gt; 关键字 。只有主表和从表中的数据都满足连接条件时才能被查询出来，不满足则会被忽略 。&lt;/p&gt;
&lt;p&gt;例如有员工表和部门表，若要查询每个员工所在部门的信息，可通过员工表中的部门 ID 与部门表中的 ID 匹配连接，获取员工姓名和部门名称等信息。内连接能确保数据准确，适用于查询具有明确关联关系的表 。&lt;/p&gt;
&lt;p&gt;使用moershi库下的3张表做今天的查询练习。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;departments【迪帕踢门特s】：部门表，存储部门信息&lt;/li&gt;
&lt;li&gt;employees【ing普洛伊s】： 员工表，存储员工信息&lt;/li&gt;
&lt;li&gt;salary【撒拉瑞】: 工资表，存储工资信息&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;三张表的关系如果图
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111330633.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;INNER【ing呐】 JOIN【载(白话)】 关键字详解&lt;/h3&gt;
&lt;p&gt;INNER【ing呐】 JOIN【载(白话)】是SQL中最基础且最重要的连接操作，它通过精确的匹配条件将相关的数据行连接在一起，是构建复杂查询和数据分析的基石。掌握INNER【ing呐】 JOIN【载(白话)】的正确用法对于进行有效的数据处理至关重要。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;属性&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;关键字&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;INNER【ing呐】 JOIN【载(白话)】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;中文名称&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;内连接&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;返回两个表中满足连接条件的匹配行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT【涩莱克特】 列名 FROM【弗乱】 表1 INNER【ing呐】 JOIN【载(白话)】 表2 ON【昂】 连接条件&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;返回值&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;只返回两个表中连接条件为TRUE的行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;等价写法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;可以省略INNER【ing呐】，直接写JOIN【载(白话)】&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;语法结构&lt;/h4&gt;
&lt;p&gt;基本语法结构&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT【涩莱克特】 列名列表 FROM【弗乱】 表1 INNER【ing呐】 JOIN【载(白话)】 表2 ON【昂】 表1.列名 = 表2.列名;

表1 INNER【ing呐】 JOIN【载(白话)】 表2: 是表连接 的核心部分，用于将 1 表和 2 表的数据关联起来。
作用
指定主表和从表：
1 是主表（左表）。
2 是从表（右表）。

定义连接类型：
INNER JOIN 表示内连接，只返回两个表中匹配的记录。
如果 1 表中的某条记录在 2 表中没有匹配的记录（即 employee_id 不匹配），则该记录不会出现在结果中。

配合连接条件：
通常与 ON 子句一起使用（例如 ON employees.employee_id = salary.employee_id ），以指定如何匹配两个表的记录。

ON【昂】 表1.列名 = 表2.列名: 是 连接条件，用于指定 1 表和 2 表之间的关联关系
作用
定义表之间的关联：
    它告诉数据库如何将 employees 表中的记录与 salary 表中的记录匹配起来。
    只有当 employees.employee_id 和 salary.employee_id 的值相等时，两条记录才会被关联起来。

确保数据一致性：
    通过这个条件，查询只会返回那些在 employees 表和 salary 表中都有对应 employee_id 的记录（如果是 INNER JOIN ）。
    如果是 LEFT JOIN ，则会返回 employees 表中的所有记录，即使 salary 表中没有匹配的记录（此时 salary 表的字段会显示为 NULL【nò】 ）。

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;完整语法格式&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT【涩莱克特】 [表别名1].列名, [表别名2].列名, ...
FROM【弗乱】 表1 [AS] 表别名1
INNER【ing呐】 JOIN【载(白话)】 表2 [AS] 表别名2 ON【昂】 表别名1.连接列 = 表别名2.连接列
[WHERE【威尔】 筛选条件]
[ORDER【欧朵】 BY 排序字段];
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;示例&lt;/h5&gt;
&lt;p&gt;1：基本INNER【ing呐】 JOIN【载(白话)】查询&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 查询员工及其部门信息
SELECT【涩莱克特】 e.employee【ing普洛伊】_id, e.name, d.dept_name, e.hire_date
FROM【弗乱】 employees【ing普洛伊s】 e
INNER【ing呐】 JOIN【载(白话)】 departments【迪帕踢门特s】 d ON【昂】 e.dept_id = d.dept_id;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;查询结果：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;employee【ing普洛伊】_id&lt;/th&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;dept_name&lt;/th&gt;
&lt;th&gt;hire_date&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;张三&lt;/td&gt;
&lt;td&gt;技术部&lt;/td&gt;
&lt;td&gt;2023-01-15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;李四&lt;/td&gt;
&lt;td&gt;销售部&lt;/td&gt;
&lt;td&gt;2023-03-20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;王五&lt;/td&gt;
&lt;td&gt;技术部&lt;/td&gt;
&lt;td&gt;2023-02-10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;赵六&lt;/td&gt;
&lt;td&gt;人事部&lt;/td&gt;
&lt;td&gt;2023-04-05&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;2：带WHERE【威尔】条件的INNER【ing呐】 JOIN【载(白话)】&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 只查询技术部的员工
SELECT【涩莱克特】 e.name, d.dept_name, e.hire_date
FROM【弗乱】 employees【ing普洛伊s】 e
INNER【ing呐】 JOIN【载(白话)】 departments【迪帕踢门特s】 d ON【昂】 e.dept_id = d.dept_id
WHERE【威尔】 d.dept_name = &apos;技术部&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;查询结果：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;dept_name&lt;/th&gt;
&lt;th&gt;hire_date&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;张三&lt;/td&gt;
&lt;td&gt;技术部&lt;/td&gt;
&lt;td&gt;2023-01-15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;王五&lt;/td&gt;
&lt;td&gt;技术部&lt;/td&gt;
&lt;td&gt;2023-02-10&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;3：多表INNER【ing呐】 JOIN【载(白话)】连接&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 假设有salary【撒拉瑞】表，三表连接
SELECT【涩莱克特】 e.name, d.dept_name, s.basic【贝斯克】_salary【撒拉瑞】
FROM【弗乱】 employees【ing普洛伊s】 e
INNER【ing呐】 JOIN【载(白话)】 departments【迪帕踢门特s】 d ON【昂】 e.dept_id = d.dept_id
INNER【ing呐】 JOIN【载(白话)】 salary【撒拉瑞】 s ON【昂】 e.employee【ing普洛伊】_id = s.employee【ing普洛伊】_id;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;使用场景分析&lt;/h5&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;场景&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;主从表关联&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;查询主表记录的详细信息&lt;/td&gt;
&lt;td&gt;员工表关联部门表查部门信息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;多维度分析&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;结合多个维度的数据进行统计&lt;/td&gt;
&lt;td&gt;销售数据关联产品表、客户表&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;数据验证&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;检查两个表的数据一致性&lt;/td&gt;
&lt;td&gt;验证订单表和库存表的数据匹配&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;报表生成&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;生成包含多个表数据的综合报表&lt;/td&gt;
&lt;td&gt;员工考勤关联工资计算&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h5&gt;与其他JOIN【载(白话)】类型的对比&lt;/h5&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;INNER【ing呐】 JOIN&lt;/th&gt;
&lt;th&gt;LEFT【列夫特】 JOIN【载(白话)】&lt;/th&gt;
&lt;th&gt;RIGHT【来特】 JOIN【载(白话)】&lt;/th&gt;
&lt;th&gt;FULL【fò】 JOIN【载(白话)】&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;返回结果&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;只返回匹配行&lt;/td&gt;
&lt;td&gt;左表所有行+匹配行&lt;/td&gt;
&lt;td&gt;右表所有行+匹配行&lt;/td&gt;
&lt;td&gt;左右表所有行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NULL【nò】处理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;排除不匹配行&lt;/td&gt;
&lt;td&gt;右表不匹配显示NULL【nò】&lt;/td&gt;
&lt;td&gt;左表不匹配显示NULL【nò】&lt;/td&gt;
&lt;td&gt;不匹配都显示NULL【nò】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;使用频率&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;⭐⭐&lt;/td&gt;
&lt;td&gt;⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;性能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;通常最优&lt;/td&gt;
&lt;td&gt;中等&lt;/td&gt;
&lt;td&gt;中等&lt;/td&gt;
&lt;td&gt;较差&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;最佳实践指南&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;使用表别名提高可读性&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;-- 推荐写法
SELECT【涩莱克特】 emp.name, dept.dept_name
FROM【弗乱】 employees【ing普洛伊s】 emp
INNER【ing呐】 JOIN【载(白话)】 departments【迪帕踢门特s】 dept ON【昂】 emp.dept_id = dept.dept_id;

-- 不推荐写法
SELECT【涩莱克特】 employees【ing普洛伊s】.name, departments【迪帕踢门特s】.dept_name
FROM【弗乱】 employees【ing普洛伊s】
INNER【ing呐】 JOIN【载(白话)】 departments【迪帕踢门特s】 ON【昂】 employees【ing普洛伊s】.dept_id = departments【迪帕踢门特s】.dept_id;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;明确指定列所属表&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;-- 避免列名歧义
SELECT【涩莱克特】 e.employee【ing普洛伊】_id, e.name, d.dept_name
FROM【弗乱】 employees【ing普洛伊s】 e
INNER【ing呐】 JOIN【载(白话)】 departments【迪帕踢门特s】 d ON【昂】 e.dept_id = d.dept_id;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;合理使用索引优化性能&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;-- 确保连接列有索引
CREATE INDEX idx_employees【ing普洛伊s】_dept_id ON【昂】 employees【ing普洛伊s】(dept_id);
CREATE INDEX idx_departments【迪帕踢门特s】_dept_id ON【昂】 departments【迪帕踢门特s】(dept_id);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.1 等值连接查询&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;查询每个员工所在的部门名&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;Use  moershi;
select【涩莱克特】 name, dept_name  
from【弗乱】 employees【ing普洛伊s】 inner【ing呐】 join【载(白话)】 departments【迪帕踢门特s】  on【昂】 employees【ing普洛伊s】.dept_id=departments【迪帕踢门特s】.dept_id;

-- mysql&amp;gt; select name,dept_name 
--     -&amp;gt; from employees inner join departments on employees.dept_id=departments.dept_id;
-- 
-- | name      | dept_name |
-- |-----------|-----------|
-- | 梁伟      | 人事部    |
-- | 郭岩      | 人事部    |
-- | 李玉英    | 人事部    |
-- | 张健      | 人事部    |
-- | 郑静      | 人事部    |
-- | 牛建军    | 人事部    |
-- | 刘斌      | 人事部    |
-- | 汪云      | 人事部    |
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）查询员工编号8 的 员工所在部门的部门名称&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】  name, dept_name  from【弗乱】 employees【ing普洛伊s】  inner【ing呐】 join【载(白话)】 departments【迪帕踢门特s】 
on【昂】 employees【ing普洛伊s】.dept_id=departments【迪帕踢门特s】.dept_id  where【威尔】  employees【ing普洛伊s】.employee【ing普洛伊】_id=8;

-- mysql&amp;gt; select name,dept_name from employees inner join departments on employees.dept_id=departments.dept_id where employees.employee_id=8;
-- +--------+-----------+
-- | name   | dept_name |
-- +--------+-----------+
-- | 汪云   | 人事部    |
-- +--------+-----------+
-- 1 row in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;别名规则&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;字段名&lt;/th&gt;
&lt;th&gt;是否必须加别名 &lt;code&gt;e.&lt;/code&gt; 或 &lt;code&gt;d.&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;原因说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;dept_id&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;必须&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;因为 &lt;code&gt;employees&lt;/code&gt; 和 &lt;code&gt;departments&lt;/code&gt; 两个表&lt;strong&gt;都有&lt;/strong&gt;名为 &lt;code&gt;dept_id&lt;/code&gt; 的字段，MySQL 无法自动判断您想用的是哪一个。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;name&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;不需要&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;因为只有 &lt;code&gt;employees&lt;/code&gt; 表中有 &lt;code&gt;name&lt;/code&gt; 字段，&lt;code&gt;departments&lt;/code&gt; 表中没有这个字段，MySQL 可以&lt;strong&gt;唯一确定&lt;/strong&gt;它来自哪里。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;如果&lt;strong&gt;字段名&lt;/strong&gt;在多个表中同时存在，必须带上别名才可以识别你要查询的&lt;strong&gt;字段名&lt;/strong&gt;是那个表的&lt;strong&gt;字段名&lt;/strong&gt;
如果&lt;strong&gt;字段名&lt;/strong&gt;只在其中一个表存在，这就具有唯一性，sql可以明确识别&lt;strong&gt;字段名&lt;/strong&gt;在那个表，就不需要带上别名&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;3）查询每个员工所有信息及所在的部门名称&lt;/p&gt;
&lt;p&gt;给表名定义别名 ，定义别名后必须使用别名表示表名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】 e.* , d.dept_name
from【弗乱】 employees【ing普洛伊s】 as e inner【ing呐】 join【载(白话)】 departments【迪帕踢门特s】 as d on【昂】 e.dept_id=d.dept_id;

-- mysql&amp;gt; select e.*,d.dept_name from employees as e inner join departments as d on e.dept_id=d.dept_id limit 5;#结果太多，加上&quot;limit 5&quot; 只输出前5行
-- +-------------+-----------+------------+------------+-----------------------+--------------+---------+-----------+
-- | employee_id | name      | hire_date  | birth_date | email                 | phone_number | dept_id | dept_name |
-- +-------------+-----------+------------+------------+-----------------------+--------------+---------+-----------+
-- |           1 | 梁伟      | 2018-06-21 | 1971-08-19 | liangwei@tedu.cn      | 13591491431  |       1 | 人事部    |
-- |           2 | 郭岩      | 2010-03-21 | 1974-05-13 | guoyan@tedu.cn        | 13845285867  |       1 | 人事部    |
-- |           3 | 李玉英    | 2012-01-19 | 1974-01-25 | liyuying@tedu.cn      | 15628557234  |       1 | 人事部    |
-- |           4 | 张健      | 2008-09-17 | 1972-06-07 | zhangjian@moershi.com | 13835990213  |       1 | 人事部    |
-- |           5 | 郑静      | 2018-02-03 | 1997-02-14 | zhengjing@tedu.cn     | 14508936730  |       1 | 人事部    |
-- +-------------+-----------+------------+------------+-----------------------+--------------+---------+-----------+
-- 5 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4）查询每个员工姓名、部门编号、部门名称&lt;/p&gt;
&lt;p&gt;两个表有同名表头，表头名前必须加表名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】 e.dept_id , name , dept_name  from【弗乱】   employees【ing普洛伊s】 as e  inner【ing呐】 join【载(白话)】 departments【迪帕踢门特s】 as d on【昂】  e.dept_id=d.dept_id;

-- mysql&amp;gt; select e.dept_id,name,dept_name from employees as e inner join departments as d on e.dept_id=d.dept_id limit 5;#结果太多，加上&quot;limit 5&quot; 只输出前5行
-- +---------+-----------+-----------+
-- | dept_id | name      | dept_name |
-- +---------+-----------+-----------+
-- |       1 | 梁伟      | 人事部    |
-- |       1 | 郭岩      | 人事部    |
-- |       1 | 李玉英    | 人事部    |
-- |       1 | 张健      | 人事部    |
-- |       1 | 郑静      | 人事部    |
-- +---------+-----------+-----------+
-- 5 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 对连接后的查询结果，筛选、分组、排序、过滤&lt;/h3&gt;
&lt;p&gt;1）查询11号员工的名字及2018年每个月总工资&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】   e.employee【ing普洛伊】_id,  name, date, basic【贝斯克】+bonus【波诺斯】 as total【偷ò头ō】 
from【弗乱】 employees【ing普洛伊s】 as e   inner【ing呐】 join【载(白话)】 salary【撒拉瑞】 as s 
on【昂】 e.employee【ing普洛伊】_id=s.employee【ing普洛伊】_id
where【威尔】 year【耶尔】(date)=2018 and e.employee【ing普洛伊】_id=11;
-- mysql&amp;gt; 
-- mysql&amp;gt; select e.employee_id,name,date,basic+bonus as total
--     -&amp;gt; from employees as e inner join salary as s on e.employee_id=s.employee_id
--     -&amp;gt; where year(date)=2018 and e.employee_id=11;
-- +-------------+-----------+------------+-------+
-- | employee_id | name      | date       | total |
-- +-------------+-----------+------------+-------+
-- |          11 | 郭兰英    | 2018-01-10 | 18206 |
-- |          11 | 郭兰英    | 2018-02-10 | 19206 |
-- |          11 | 郭兰英    | 2018-03-10 | 18206 |
-- |          11 | 郭兰英    | 2018-04-10 | 19206 |
-- |          11 | 郭兰英    | 2018-05-10 | 18206 |
-- |          11 | 郭兰英    | 2018-06-10 | 19206 |
-- |          11 | 郭兰英    | 2018-07-10 | 27206 |
-- |          11 | 郭兰英    | 2018-08-10 | 27206 |
-- |          11 | 郭兰英    | 2018-09-10 | 19206 |
-- |          11 | 郭兰英    | 2018-10-10 | 21206 |
-- |          11 | 郭兰英    | 2018-11-10 | 22206 |
-- |          11 | 郭兰英    | 2018-12-10 | 25016 |
-- +-------------+-----------+------------+-------+
-- 12 rows in set (0.00 sec)
-- mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2） 查询每个员工2018年的总工资&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    #没分组前
select【涩莱克特】 employees【ing普洛伊s】.employee【ing普洛伊】_id,date,basic【贝斯克】,bonus【波诺斯】  from【弗乱】 employees【ing普洛伊s】 inner【ing呐】 join【载(白话)】 salary【撒拉瑞】
on【昂】 employees【ing普洛伊s】.employee【ing普洛伊】_id=salary【撒拉瑞】【撒拉瑞】.employee【ing普洛伊】_id  where【威尔】  year【耶尔】(date)=2018;
-- mysql&amp;gt; select employees.employee_id,date,basic,bonus 
--     -&amp;gt; from employees inner join salary
--     -&amp;gt; on employees.employee_id=salary.employee_id
--     -&amp;gt; where year(date)=2018;
-- +-------------+------------+-------+-------+
-- | employee_id | date       | basic | bonus |
-- +-------------+------------+-------+-------+
-- |           1 | 2018-07-10 | 16206 | 11000 |
-- |           1 | 2018-08-10 | 16206 |  8000 |
-- |           1 | 2018-09-10 | 16206 |  8000 |
-- |           1 | 2018-10-10 | 16206 | 11000 |
-- |           1 | 2018-11-10 | 16206 |  8000 |
-- ...............
-- mysql&amp;gt;   
    # 分组后
select【涩莱克特】 employees【ing普洛伊s】.employee【ing普洛伊】_id, sum【桑à姆】(basic【贝斯克】+bonus【波诺斯】) from【弗乱】 employees【ing普洛伊s】 inner【ing呐】 join【载(白话)】 salary【撒拉瑞】
on【昂】 employees【ing普洛伊s】.employee【ing普洛伊】_id=salary【撒拉瑞】.employee【ing普洛伊】_id  
where【威尔】 year【耶尔】(date)=2018    group【格鲁普】 by employees【ing普洛伊s】.employee【ing普洛伊】_id;

-- mysql&amp;gt; 
-- mysql&amp;gt; select employees.employee_id,sum(basic+bonus)
--     -&amp;gt; from employees inner join salary
--     -&amp;gt; on employees.employee_id=salary.employee_id
--     -&amp;gt; where year(date)=2018      --过滤只输出2018年的数据
--     -&amp;gt; group by employees.employee_id;     --查询结果以employees.employee_id分组
-- +-------------+------------------+
-- | employee_id | sum(basic+bonus) |
-- +-------------+------------------+
-- |           1 |           151046 |
-- |           2 |           328131 |
-- |           3 |           177595 |
-- |           4 |           262282 |
-- |           5 |           248076 |
-- |           6 |           257282 |
-- |           7 |           314027 |
-- ...............
-- mysql&amp;gt;   
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3）查询每个员工2018年的总工资，按总工资升序排列&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】 employees【ing普洛伊s】.employee【ing普洛伊】_id, sum【桑à姆】(basic【贝斯克】+bonus【波诺斯】) as total【偷ò头ō】  
 from【弗乱】 employees【ing普洛伊s】 inner【ing呐】 join【载(白话)】 salary【撒拉瑞】 on【昂】 employees【ing普洛伊s】.employee【ing普洛伊】_id=salary【撒拉瑞】.employee【ing普洛伊】_id 
 where【威尔】 year【耶尔】(salary【撒拉瑞】.date)=2018 group【格鲁普】 by employee【ing普洛伊】_id order【欧朵】 by total【偷ò头ō】 asc【阿斯克】;

-- mysql&amp;gt; 
-- mysql&amp;gt; select employees.employee_id,sum(basic+bonus) as total  
--     -&amp;gt; from employees inner join salary on employees.employee_id=salary.employee_id
--     -&amp;gt; where year(salary.date)=2018     --过滤只输出2018年的数据
--     -&amp;gt; group by employee_id     --查询结果以employee_id分组
--     -&amp;gt; order by total asc;    --查询结果以升序排序
-- +-------------+--------+
-- | employee_id | total  |
-- +-------------+--------+
-- |           8 |  25093 |
-- |          10 | 116389 |
-- |          16 | 119389 |
-- |          51 | 123733 |
-- |          18 | 126687 |
-- .........
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4）查询2018年总工资大于30万的员工，按2018年总工资降序排列&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】 employees【ing普洛伊s】.employee【ing普洛伊】_id, sum【桑à姆】(basic【贝斯克】+bonus【波诺斯】) as total【偷ò头ō】  
from【弗乱】 employees【ing普洛伊s】 inner【ing呐】 join【载(白话)】 salary【撒拉瑞】 on【昂】 employees【ing普洛伊s】.employee【ing普洛伊】_id=salary【撒拉瑞】.employee【ing普洛伊】_id   
where【威尔】 year【耶尔】(salary【撒拉瑞】.date)=2018 
group【格鲁普】 by employees【ing普洛伊s】.employee【ing普洛伊】_id 
having【嗨夫营】 total【偷ò头ō】 &amp;gt; 300000
order【欧朵】 by  total【偷ò头ō】 desc;
-- mysql&amp;gt; 
-- mysql&amp;gt; select employees.employee_id,sum(basic+bonus) as total
--     -&amp;gt; from employees inner join salary on employees.employee_id=salary.employee_id
--     -&amp;gt; where year(salary.date)=2018 
--     -&amp;gt; group by employees.employee_id
--     -&amp;gt; having total &amp;gt; 300000
--     -&amp;gt; order by total desc;
-- +-------------+--------+
-- | employee_id | total  |
-- +-------------+--------+
-- |         117 | 374923 |
-- |          31 | 374923 |
-- |          37 | 362981 |
-- |          68 | 360923 |
-- |          48 | 359923 |
-- ......
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、外连接查询&lt;/h2&gt;
&lt;p&gt;当前任何环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[综合查询]
        direction LR
        A[内连接查询] --&amp;gt; B[外连接查询] --&amp;gt; C[合并查询结果] --&amp;gt; D[嵌套查询]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class B highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;MySQL 外连接查询是一种在多个表间获取数据的重要方式，它主要分为左外连接、右外连接和全外连接。&lt;/p&gt;
&lt;h3&gt;外连接类型对比&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;连接类型&lt;/th&gt;
&lt;th&gt;关键字&lt;/th&gt;
&lt;th&gt;返回结果&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;左外连接&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LEFT【列夫特】 JOIN【载(白话)】&lt;/code&gt; 或 &lt;code&gt;LEFT【列夫特】 OUTER【奥特尔】 JOIN【载(白话)】&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;左表所有记录 + 右表匹配记录&lt;/td&gt;
&lt;td&gt;主表记录必须全部保留，关联表信息可选&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;右外连接&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;RIGHT【来特】 JOIN【载(白话)】&lt;/code&gt; 或 &lt;code&gt;RIGHT【来特】 OUTER【奥特尔】 JOIN【载(白话)】&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;右表所有记录 + 左表匹配记录&lt;/td&gt;
&lt;td&gt;从表记录必须全部保留，主表信息可选&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;全外连接&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FULL【fò】 JOIN【载(白话)】&lt;/code&gt; 或 &lt;code&gt;FULL【fò】 OUTER【奥特尔】 JOIN【载(白话)】&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;左右表所有记录&lt;/td&gt;
&lt;td&gt;需要两个表的完整数据合并&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;外连接是SQL查询中非常重要的功能，特别适用于：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需要保留主表所有记录的查询&lt;/li&gt;
&lt;li&gt;数据完整性检查（查找缺失的关联数据）&lt;/li&gt;
&lt;li&gt;生成完整的报表和统计分析&lt;/li&gt;
&lt;li&gt;处理可能存在NULL【nò】关联关系的业务场景&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;左外连接会返回左表中的所有记录，以及右表中匹配的记录，若右表无匹配项，对应字段会显示为 NULL【nò】。右外连接则相反，返回右表所有记录与左表匹配记录。全外连接会返回左右表的所有记录，无匹配项的字段同样显示为 NULL【nò】。&lt;/p&gt;
&lt;p&gt;例如员工表和部门表，用左外连接查询时，即便有员工未分配部门，该员工信息也会显示出来。外连接能满足在关联表查询时，不遗漏某表记录的需求。&lt;/p&gt;
&lt;h3&gt;4.1 左连接查询&lt;/h3&gt;
&lt;p&gt;向departments【迪帕踢门特s】表里添加3个部门:小卖部 行政部 公关部&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; insert【因涩特】 into【因兔】 departments【迪帕踢门特s】(dept_name) values【挖柳斯】(&quot;小卖部&quot;),(&quot;行政部&quot;),(&quot;公关部&quot;);
Query OK, 3 rows affected (0.06 sec)
Records: 3  Duplicates: 0  Warnings: 0

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查询部门信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】  * from【弗乱】 moershi.departments【迪帕踢门特s】;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|       1 | 人事部    |
|       2 | 财务部    |
|       3 | 运维部    |
|       4 | 开发部    |
|       5 | 测试部    |
|       6 | 市场部    |
|       7 | 销售部    |
|       8 | 法务部    |
|       9 | 小卖部    |
|      10 | 行政部    |
|      11 | 公关部    |
+---------+-----------+
11 rows in set (0.00 sec)
mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;左连接查询例子：输出没有员工的部门名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 d.dept_name,e.name from【弗乱】 departments【迪帕踢门特s】 as d  left【列夫特】  join【载(白话)】 employees【ing普洛伊s】 as e on【昂】 d.dept_id=e.dept_id;
...
...
| 法务部    | 王荣      |
| 法务部    | 刘倩      |
| 法务部    | 杨金凤    |
| 小卖部    | NULL      |
| 行政部    | NULL      |
| 公关部    | NULL      |
+-----------+-----------+
136 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;连接后 输出与筛选条件匹配的行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】 d.dept_name,e.name from【弗乱】 departments【迪帕踢门特s】 as d  left【列夫特】  join【载(白话)】 employees【ing普洛伊s】 as e on【昂】 d.dept_id=e.dept_id where【威尔】 e.name is null【nò】;
+-----------+------+
| dept_name | name |
+-----------+------+
| 小卖部    | NULL |
| 行政部    | NULL |
| 公关部    | NULL |
+-----------+------+
3 rows in set (0.01 sec)
mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;仅显示departments【迪帕踢门特s】表中dept_name表头&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】 d.dept_name from【弗乱】 departments【迪帕踢门特s】 as d  left【列夫特】  join【载(白话)】 employees【ing普洛伊s】 as e on【昂】 d.dept_id=e.dept_id where【威尔】 e.name is null【nò】;
+-----------+
| dept_name |
+-----------+
| 小卖部     |
| 行政部     | 
| 公关部     | 
+-----------+
3 rows in set (0.01 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 右连接查询&lt;/h3&gt;
&lt;p&gt;向employees【ing普洛伊s】表中添加3个员工 只给name表头赋值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;insert【因涩特】  into【因兔】  employees【ing普洛伊s】(name) values【挖柳斯】(&quot;bob&quot;),(&quot;tom&quot;),(&quot;lily&quot;);
Query OK, 3 rows affected (0.05 sec)
Records: 3  Duplicates: 0  Warnings: 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;右连接查询例子：显示没有部门的员工名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//右连接查询
select【涩莱克特】 e.name ,d.dept_name from【弗乱】 departments【迪帕踢门特s】 as d  right【来特】  join【载(白话)】 employees【ing普洛伊s】 as e on【昂】 d.dept_id=e.dept_id;
//加筛选条件
select【涩莱克特】 e.name ,d.dept_name from【弗乱】 departments【迪帕踢门特s】 as d  right【来特】  join【载(白话)】 employees【ing普洛伊s】 as e on【昂】 d.dept_id=e.dept_id where【威尔】 d.dept_name is null【nò】 ;
+------+-----------+
| name | dept_name |
+------+-----------+
| bob  | NULL      |
| tom  | NULL      |
| lily | NULL      |
+------+-----------+
3 rows in set (0.00 sec)
mysql&amp;gt; 
//仅显示员工名
select【涩莱克特】 e.name from【弗乱】 departments【迪帕踢门特s】 as d  right【来特】  join【载(白话)】 employees【ing普洛伊s】 as e on【昂】 d.dept_id=e.dept_id where【威尔】 d.dept_name is null【nò】 ;
+------+
| name |
+------+
| bob  | 
| tom  |
| lily |
+------+
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、合并查询结果&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[综合查询]
        direction LR
        A[内连接查询] --&amp;gt; B[外连接查询] --&amp;gt; C[合并查询结果] --&amp;gt; D[嵌套查询]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class C highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在 MySQL 综合查询里，合并查询是一种实用的操作。它主要用于将多个查询结果合并成一个结果集，使用的关键字是 &lt;code&gt;UNION【U凝】&lt;/code&gt; 和 &lt;code&gt;UNION【U凝】 ALL【ò】&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;UNION【U凝】&lt;/code&gt; 会去除合并结果里的重复记录，只保留一条。比如，你分别从员工表查询出薪资大于 8000 的员工，和从另一筛选条件查出的员工，用 &lt;code&gt;UNION【U凝】&lt;/code&gt; 合并后，相同员工就只显示一次。而 &lt;code&gt;UNION【U凝】 ALL【ò】&lt;/code&gt; 不会去重，会把所有查询结果直接合并。当你需要查看所有相关数据，不在意重复时，就用 &lt;code&gt;UNION【U凝】 ALL【ò】&lt;/code&gt;。合并查询让你能灵活整合不同查询的数据。&lt;/p&gt;
&lt;h3&gt;基本概念对比&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;UNION【U凝】&lt;/th&gt;
&lt;th&gt;UNION【U凝】 ALL【ò】&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;去重处理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;自动去除重复行&lt;/td&gt;
&lt;td&gt;保留所有行，包括重复行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;性能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;较慢（需要排序和去重）&lt;/td&gt;
&lt;td&gt;较快（直接合并）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;结果排序&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;默认按第一列升序排列&lt;/td&gt;
&lt;td&gt;不保证顺序&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;语法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT【涩莱克特】 ... UNION【U凝】 SELECT【涩莱克特】 ...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT【涩莱克特】 ... UNION【U凝】 ALL【ò】 SELECT【涩莱克特】 ...&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;使用场景&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;需要唯一结果时&lt;/td&gt;
&lt;td&gt;需要完整数据或已知无重复时&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;----------&lt;/td&gt;
&lt;td&gt;---------------&lt;/td&gt;
&lt;td&gt;-------------------&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;去重能力&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ 自动去重&lt;/td&gt;
&lt;td&gt;❌ 保留重复&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;执行性能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⭐⭐ 较慢&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐ 较快&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;内存消耗&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;较高&lt;/td&gt;
&lt;td&gt;较低&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;结果顺序&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;默认排序&lt;/td&gt;
&lt;td&gt;不保证顺序&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;使用频率&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⭐⭐⭐ 常用&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐⭐ 更常用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;适用场景&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;需要唯一结果&lt;/td&gt;
&lt;td&gt;完整数据或性能优先&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;关键要点总结&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;UNION【U凝】 ALL【ò】 通常比 UNION【U凝】 性能更好&lt;/strong&gt;，因为它不需要去重操作&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;只有需要去除重复记录时才使用 UNION【U凝】&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;确保所有SELECT【涩莱克特】语句的列数、数据类型和顺序一致&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UNION【U凝】 ALL【ò】 保留所有记录，包括重复项&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在合并大量数据时，UNION【U凝】 ALL【ò】 是更优选择&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;基本语法格式&lt;/h3&gt;
&lt;p&gt;UNION【U凝】 语法&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT【涩莱克特】 列名1, 列名2, ...
FROM【弗乱】 表1
WHERE【威尔】 条件
UNION【U凝】
SELECT【涩莱克特】 列名1, 列名2, ...
FROM【弗乱】 表2
WHERE【威尔】 条件;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;UNION 【U凝】ALL【ò】 语法&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT【涩莱克特】 列名1, 列名2, ...
FROM【弗乱】 表1
WHERE【威尔】 条件
UNION【U凝】 ALL【ò】
SELECT【涩莱克特】 列名1, 列名2, ...
FROM【弗乱】 表2
WHERE【威尔】 条件;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;性能对比分析&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作步骤&lt;/th&gt;
&lt;th&gt;UNION【U凝】&lt;/th&gt;
&lt;th&gt;UNION【U凝】 ALL【ò】&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;数据读取&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;读取所有数据&lt;/td&gt;
&lt;td&gt;读取所有数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;排序处理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;对结果进行排序&lt;/td&gt;
&lt;td&gt;不需要排序&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;去重操作&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;比较并去除重复行&lt;/td&gt;
&lt;td&gt;保留所有行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;内存使用&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;较高&lt;/td&gt;
&lt;td&gt;较低&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;执行时间&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;较长&lt;/td&gt;
&lt;td&gt;较短&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;实际示例演示&lt;/h3&gt;
&lt;p&gt;输出2018年基本工资的最大值和最小值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; ( select【涩莱克特】 basic【贝斯克】  from【弗乱】 salary【撒拉瑞】 where【威尔】 year【耶尔】(date)=2018 order【欧朵】 by  basic【贝斯克】  desc limit 1) union【U凝】 (select【涩莱克特】 basic【贝斯克】  from【弗乱】 salary【撒拉瑞】 where【威尔】 year【耶尔】(date)=2018 order【欧朵】 by  basic【贝斯克】 asc【阿斯克】 limit【肋梅特】 1 );
-- mysql&amp;gt; (select basic from salary where year(date)=2018 order by basic desc limit 1)
--     -&amp;gt; union
--     -&amp;gt; (select basic from salary where year(date)=2018 order by basic asc limit 1);
-- +----------------+
-- | basic【贝斯克】 |
-- +----------------+
-- | 25524          |
-- |  5787          |
-- +----------------+
-- 2 rows in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出2018年1月10号 基本工资的最大值和最小值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; (select【涩莱克特】 date , max【mà 斯】(basic【贝斯克】) as 工资 from【弗乱】 salary【撒拉瑞】 where【威尔】 date=20180110) union【U凝】(select【涩莱克特】 date,min【敏ì】(basic【贝斯克】) from【弗乱】 salary【撒拉瑞】 where【威尔】 date=20180110);

-- mysql&amp;gt; (select date,max(basic) as 工资 from salary where date=20180110)
--     -&amp;gt; union
--     -&amp;gt; (select date,min(basic) from salary where date=20180110);
-- +------------+--------+
-- | date       | 工资   |
-- +------------+--------+
-- | 2018-01-10 |  24309 |
-- | 2018-01-10 |   5787 |
-- +------------+--------+
-- 2 rows in set (0.01 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;union【U凝】 去掉查询结果中重复的行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; (select【涩莱克特】 employee【ing普洛伊】_id , name , birth【波尔斯】_date from【弗乱】 employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id &amp;lt;= 5) union【U凝】 (select【涩莱克特】 employee【ing普洛伊】_id , name , birth【波尔斯】_date from【弗乱】 employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id &amp;lt;= 6);
-- mysql&amp;gt; (select employee_id,name,birth_date from employees where employee_id &amp;lt;=5)
--     -&amp;gt; union
--     -&amp;gt; (select employee_id,name,birth_date from employees where employee_id &amp;lt;=6);
+-------------------------+-----------+------------+
| employee【ing普洛伊】_id | name      | birth_date |
+-------------------------+-----------+------------+
|           1            | 梁伟      | 1971-08-19 |
|           2            | 郭岩      | 1974-05-13 |
|           3            | 李玉英    | 1974-01-25 |
|           4            | 张健      | 1972-06-07 |
|           5            | 郑静      | 1997-02-14 |
|           6            | 牛建军    | 1985-03-19 |
+------------------------+-----------+------------+
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第二个查询只输出了与条件匹配的最后1行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; (select【涩莱克特】 employee【ing普洛伊】_id , name , birth【波尔斯】_date from【弗乱】 employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id &amp;lt;= 5) union【U凝】  (select【涩莱克特】 employee【ing普洛伊】_id , name , birth【波尔斯】_date from【弗乱】 employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id &amp;lt;= 6);
-- mysql&amp;gt; (select employee_id,name,birth_date from employees where employee_id &amp;lt;=5)
--     -&amp;gt; union
--     -&amp;gt; (select employee_id,name,birth_date from employees where employee_id &amp;lt;=6);
+------------------------+-----------+-------------+
| employee【ing普洛伊】_id | name      | birth【波尔斯】_date |
+------------------------+-----------+-------------+
|           1             | 梁伟      | 1971-08-19 |
|           2             | 郭岩      | 1974-05-13 |
|           3             | 李玉英    | 1974-01-25 |
|           4             | 张健      | 1972-06-07 |
|           5             | 郑静      | 1997-02-14 |
|           6             | 牛建军    | 1985-03-19 |
+------------------------+-----------+-------------+
6 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;union【U凝】 all 不去重显示查询结果&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; (select【涩莱克特】 employee【ing普洛伊】_id , name , birth【波尔斯】_date from【弗乱】 employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id &amp;lt;= 5) union【U凝】 all【ò】  (select【涩莱克特】 employee【ing普洛伊】_id , name , birth【波尔斯】_date from【弗乱】 employees【ing普洛伊s】 where【威尔】 employee【ing普洛伊】_id &amp;lt;= 6);
-- mysql&amp;gt; (select employee_id,name,birth_date from employees where employee_id &amp;lt;=5)
--     -&amp;gt; union all
--     -&amp;gt; (select employee_id,name,birth_date from employees where employee_id &amp;lt;=6);
+-------------+-----------+------------+
| employee_id | name      | birth_date |
+-------------+-----------+------------+
|           1 | 梁伟      | 1971-08-19 |
|           2 | 郭岩      | 1974-05-13 |
|           3 | 李玉英    | 1974-01-25 |
|           4 | 张健      | 1972-06-07 |
|           5 | 郑静      | 1997-02-14 |
|           1 | 梁伟      | 1971-08-19 |
|           2 | 郭岩      | 1974-05-13 |
|           3 | 李玉英    | 1974-01-25 |
|           4 | 张健      | 1972-06-07 |
|           5 | 郑静      | 1997-02-14 |
|           6 | 牛建军    | 1985-03-19 |
+-------------+-----------+------------+
11 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、嵌套查询&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[综合查询]
        direction LR
        A[内连接查询] --&amp;gt; B[外连接查询] --&amp;gt; C[合并查询结果] --&amp;gt; D[嵌套查询]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class D highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;嵌套查询：是指在一个完整的查询语句之中，包含若干个不同功能的小查询；从而一起完成复杂查询的一种编写形式。包含的查询放在（）里 ， 包含的查询出现的位置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SELECT【涩莱克特】之后&lt;/li&gt;
&lt;li&gt;FROM【弗乱】之后&lt;/li&gt;
&lt;li&gt;WHERE【威尔】&lt;/li&gt;
&lt;li&gt;HAVING【嗨夫营】之后&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;嵌套查询的作用&lt;/h3&gt;
&lt;h4&gt;1. &lt;strong&gt;数据筛选与过滤&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;在主查询中使用子查询的结果作为筛选条件&lt;/li&gt;
&lt;li&gt;实现复杂的多条件数据过滤&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;2. &lt;strong&gt;数据比较与计算&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;将子查询结果与主查询数据进行对比&lt;/li&gt;
&lt;li&gt;计算相对值、百分比等复杂指标&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;3. &lt;strong&gt;数据存在性检查&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;检查某条记录是否存在于另一个表中&lt;/li&gt;
&lt;li&gt;验证数据的完整性&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;4. &lt;strong&gt;数据聚合与统计&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;在子查询中进行分组统计&lt;/li&gt;
&lt;li&gt;将统计结果用于主查询的条件判断&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;嵌套查询的优势&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;逻辑清晰&lt;/strong&gt;：将复杂问题分解为多个简单步骤&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;灵活性高&lt;/strong&gt;：可以处理各种复杂的数据关系&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可读性强&lt;/strong&gt;：SQL语句结构清晰，易于理解&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;功能强大&lt;/strong&gt;：支持多层嵌套，解决复杂业务逻辑&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;注意事项&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;性能考虑&lt;/strong&gt;：多层嵌套可能影响查询性能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可维护性&lt;/strong&gt;：过度嵌套会使SQL难以维护&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;替代方案&lt;/strong&gt;：考虑使用JOIN或CTE（公共表表达式）作为替代方案&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;6.1 where【威尔】之后嵌套查询&lt;/h3&gt;
&lt;p&gt;1）查询运维部所有员工信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#先把 运维部的id 找到
mysql&amp;gt; select【涩莱克特】 dept_id from【弗乱】 departments【迪帕踢门特s】 where【威尔】 dept_name=&quot;运维部&quot;;
-- mysql&amp;gt; select dept_id from departments where dept_name=&quot;运维部&quot;;
+---------+
| dept_id |
+---------+
|       3 |
+---------+
1 row in set (0.00 sec)
#员工表里没有部门名称 但有部门编号 （和部门表的编号是一致的）
mysql&amp;gt; select【涩莱克特】  *  from【弗乱】  employees【ing普洛伊s】 where【威尔】  dept_id = (select【涩莱克特】 dept_id from【弗乱】 departments【迪帕踢门特s】 where【威尔】 dept_name=&quot;运维部&quot;);
-- mysql&amp;gt; select * from employees where dept_id=(select dept_id from departments where dept_name=&quot;运维部&quot;);
+-------------+-----------+------------+---------------------+--------------------+--------------+---------+
| employee_id | name      | hire_date  | birth【波尔斯】_date | email              | phone_number | dept_id |
+-------------+-----------+------------+---------------------+--------------------+--------------+---------+
|          14 | 廖娜      | 2012-05-20 | 1982-06-22          | liaona@moershi.com  | 15827928192  |       3 |
|          15 | 窦红梅    | 2018-03-16 | 1971-09-09          | douhongmei@qcjy.cn | 15004739483  |       3 |
|          16 | 聂想      | 2018-09-09 | 1999-06-05          | niexiang@qcjy.cn   | 15501892446  |       3 |
|          17 | 陈阳      | 2004-09-16 | 1991-04-10          | chenyang@qcjy.cn   | 15565662056  |       3 |
|          18 | 戴璐      | 2001-11-30 | 1975-05-16          | dailu@qcjy.cn      | 13465236095  |       3 |
|          19 | 陈斌      | 2019-07-04 | 2000-01-22          | chenbin@moershi.com | 13621656037  |       3 |
+-------------+-----------+------------+---------------------+--------------------+--------------+---------+
6 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）查询人事部2018年12月所有员工工资&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//查看人事部的部门id
mysql&amp;gt; select【涩莱克特】 dept_id from【弗乱】 departments【迪帕踢门特s】 where【威尔】 dept_name=&apos;人事部&apos;;
-- mysql&amp;gt; select dept_id from departments where dept_name=&apos;人事部&apos;;
+---------+
| dept_id |
+---------+
|       1 |
+---------+
1 row in set (0.00 sec)
//查找employees【ing普洛伊s】表里 人事部的员工id 
select【涩莱克特】 employee【ing普洛伊】_id from【弗乱】 employees【ing普洛伊s】  where【威尔】 dept_id=(select【涩莱克特】 dept_id from【弗乱】 departments【迪帕踢门特s】 where【威尔】 dept_name=&apos;人事部&apos;);
-- mysql&amp;gt; select employee_id from employees where dept_id=(select dept_id from departments where dept_name=&apos;人事部&apos;);
+-------------+
| employee_id |
+-------------+
|           1 |
|           2 |
|           3 |
|           4 |
|           5 |
|           6 |
|           7 |
|           8 |
+-------------+
8 rows in set (0.00 sec)
//查询人事部2018年12月所有员工工资 
select【涩莱克特】   *   from【弗乱】 salary【撒拉瑞】 where【威尔】 year【耶尔】(date)=2018 and month【mèn斯】(date)=12 
and employee【ing普洛伊】_id in (select【涩莱克特】 employee【ing普洛伊】_id from【弗乱】 employees【ing普洛伊s】 
where【威尔】 dept_id=(select【涩莱克特】 dept_id from【弗乱】 departments【迪帕踢门特s】 where【威尔】 dept_name=&apos;人事部&apos;) );
-- mysql&amp;gt; select * from salary where year(date)=2018 and month(date)=12 
--     -&amp;gt; and employee_id in (select employee_id from employees 
--     -&amp;gt; where dept_id=(select dept_id from departments where dept_name=&apos;人事部&apos;));
+------+------------+-------------+----------------+----------------+
| id   | date       | employee_id | basic【贝斯克】 | bonus【波诺斯】 |
+------+------------+-------------+----------------+----------------+
| 6252 | 2018-12-10 |           1 | 17016          |  7000          |
| 6253 | 2018-12-10 |           2 | 20662          |  9000          |
| 6254 | 2018-12-10 |           3 |  9724          |  8000          |
| 6255 | 2018-12-10 |           4 | 17016          |  2000          |
| 6256 | 2018-12-10 |           5 | 17016          |  3000          |
| 6257 | 2018-12-10 |           6 | 17016          |  1000          |
| 6258 | 2018-12-10 |           7 | 23093          |  4000          |
| 6259 | 2018-12-10 |           8 | 23093          |  2000          |
+------+------------+-------------+----------------+----------------+
8 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3）查询人事部和财务部员工信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//查看人事部和财务部的 部门id
select【涩莱克特】 dept_id from【弗乱】 departments【迪帕踢门特s】  where【威尔】 dept_name in (&apos;人事部&apos;, &apos;财务部&apos;);
-- mysql&amp;gt; select dept_id from departments where dept_name in (&apos;人事部&apos;,&apos;财务部&apos;);
+---------+
| dept_id |
+---------+
|       1 |
|       2 |
+---------+
2 rows in set (0.00 sec)

//查询人事部和财务部员工信息
select【涩莱克特】 dept_id , name  from【弗乱】 employees【ing普洛伊s】 
where【威尔】 dept_id in ( 
select【涩莱克特】 dept_id from【弗乱】 departments【迪帕踢门特s】  where【威尔】 dept_name in (&apos;人事部&apos;, &apos;财务部&apos;) 
);
-- mysql&amp;gt; select dept_id,name from employees
--     -&amp;gt; where dept_id in (
--     -&amp;gt; select dept_id from departments where dept_name in (&apos;人事部&apos;,&apos;财务部&apos;));
+---------+-----------+
| dept_id | name      |
+---------+-----------+
|       1 | 梁伟      |
|       1 | 郭岩      |    
|       1 | 李玉英    |
|       1 | 张健      |
|       1 | 郑静      |
|       1 | 牛建军    |
|       1 | 刘斌      |
|       1 | 汪云      |
|       2 | 张建平    |
|       2 | 郭娟      |
|       2 | 郭兰英    |
|       2 | 王英      |
|       2 | 王楠      |
+---------+-----------+
13 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4）查询2018年12月所有比100号员工基本工资高的工资信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//把100号员工的基本工资查出来
select【涩莱克特】 basic【贝斯克】 from【弗乱】 salary【撒拉瑞】  where【威尔】 year【耶尔】(date)=2018 and 
month【mèn斯】(date)=12 and employee【ing普洛伊】_id=100; 
-- mysql&amp;gt; select basic from salary where year(date)=2018 and 
--     -&amp;gt; month(date)=12 and employee_id=100; 
+----------------+
| basic【贝斯克】 |
+----------------+
| 14585          |
+----------------+
1 row in set (0.00 sec) 

//查看比100号员工工资高的工资信息
select【涩莱克特】  *  from【弗乱】 salary【撒拉瑞】 
where【威尔】 year【耶尔】(date)=2018 and month【mèn斯】(date)=12 and 
basic【贝斯克】&amp;gt;(select【涩莱克特】 basic【贝斯克】 from【弗乱】 salary【撒拉瑞】 where【威尔】 year【耶尔】(date)=2018 and 
month【mèn斯】(date)=12 and employee【ing普洛伊】_id=100);
-- mysql&amp;gt; select * from salary
--     -&amp;gt; where year(date)=2018 and month(date)=12 and
--     -&amp;gt; basic &amp;gt; (select basic from salary where year(date)=2018 and        
--     -&amp;gt; month(date)=12 and employee_id=100);
+------+------------+-------------+----------------+----------------+
| id   | date       | employee_id | basic【贝斯克】 | bonus【波诺斯】 |
+------+------------+-------------+----------------+----------------+
| 6252 | 2018-12-10 |           1 | 17016          |  7000          |
| 6253 | 2018-12-10 |           2 | 20662          |  9000          |
| 6255 | 2018-12-10 |           4 | 17016          |  2000          |
| 6256 | 2018-12-10 |           5 | 17016          |  3000          |
| 6257 | 2018-12-10 |           6 | 17016          |  1000          |
| 6258 | 2018-12-10 |           7 | 23093          |  4000          |
| 6259 | 2018-12-10 |           8 | 23093          |  2000          |
| 6261 | 2018-12-10 |          10 | 21878          |  8000          |
| 6262 | 2018-12-10 |          11 | 17016          |  8000          |
| 6263 | 2018-12-10 |          12 | 15800          |  4000          |
| 6264 | 2018-12-10 |          13 | 18231          |  3000          |
| 6267 | 2018-12-10 |          16 | 21878          |  8000          |
| 6268 | 2018-12-10 |          17 | 19448          |  7000          |
| 6271 | 2018-12-10 |          20 | 19448          |  3000          |
| 6272 | 2018-12-10 |          21 | 18231          | 11000          |
| 6276 | 2018-12-10 |          25 | 23093          |  3000          |
| 6278 | 2018-12-10 |          27 | 24309          |  5000          |
| 6279 | 2018-12-10 |          28 | 17016          |  9000          |
| 6280 | 2018-12-10 |          29 | 23093          |  1000          |
| 6282 | 2018-12-10 |          31 | 25524          |  9000          |
| 6283 | 2018-12-10 |          32 | 18231          | 11000          |
| 6284 | 2018-12-10 |          33 | 23093          |  6000          |
| 6285 | 2018-12-10 |          34 | 23093          |  1000          |
| 6288 | 2018-12-10 |          37 | 24309          |  4000          |
| 6289 | 2018-12-10 |          38 | 23093          |  3000          |
| 6291 | 2018-12-10 |          40 | 20662          |  2000          |
| 6297 | 2018-12-10 |          46 | 15800          |  7000          |
| 6299 | 2018-12-10 |          48 | 25524          |  1000          |
| 6300 | 2018-12-10 |          49 | 15800          |  9000          |
| 6303 | 2018-12-10 |          52 | 19448          |  9000          |
| 6304 | 2018-12-10 |          53 | 25524          |  8000          |
| 6305 | 2018-12-10 |          54 | 21878          |  9000          |
| 6307 | 2018-12-10 |          56 | 23093          |  3000          |
| 6308 | 2018-12-10 |          57 | 23093          |  3000          |
| 6312 | 2018-12-10 |          61 | 24309          |  3000          |
| 6313 | 2018-12-10 |          62 | 15800          |  4000          |
| 6314 | 2018-12-10 |          63 | 15800          |  8000          |
| 6317 | 2018-12-10 |          66 | 19448          |  7000          |
| 6319 | 2018-12-10 |          68 | 25524          |  9000          |
| 6324 | 2018-12-10 |          73 | 17016          | 10000          |
| 6327 | 2018-12-10 |          76 | 20662          | 11000          |
| 6330 | 2018-12-10 |          79 | 15800          |  4000          |
| 6332 | 2018-12-10 |          81 | 17016          |  3000          |
| 6336 | 2018-12-10 |          85 | 15800          |  1000          |
| 6337 | 2018-12-10 |          86 | 24309          |  4000          |
| 6339 | 2018-12-10 |          88 | 20662          |  2000          |
| 6342 | 2018-12-10 |          91 | 20662          | 11000          |
| 6343 | 2018-12-10 |          92 | 19448          |  2000          |
| 6346 | 2018-12-10 |          95 | 19448          |  8000          |
| 6349 | 2018-12-10 |          98 | 19448          |  9000          |
| 6350 | 2018-12-10 |          99 | 15800          |  5000          |
| 6353 | 2018-12-10 |         102 | 23093          |  3000          |
| 6356 | 2018-12-10 |         105 | 21878          |  8000          |
| 6357 | 2018-12-10 |         106 | 23093          |  5000          |
| 6358 | 2018-12-10 |         107 | 18231          |  7000          |
| 6359 | 2018-12-10 |         108 | 18231          |  2000          |
| 6361 | 2018-12-10 |         110 | 18231          |  2000          |
| 6363 | 2018-12-10 |         112 | 24309          |  9000          |
| 6368 | 2018-12-10 |         117 | 25524          | 11000          |
| 6369 | 2018-12-10 |         118 | 23093          |  3000          |
| 6370 | 2018-12-10 |         119 | 23093          | 10000          |
| 6373 | 2018-12-10 |         122 | 21878          |  2000          |
| 6374 | 2018-12-10 |         123 | 19448          | 10000          |
| 6376 | 2018-12-10 |         125 | 17016          |  5000          |
| 6378 | 2018-12-10 |         127 | 17016          |  6000          |
+------+------------+-------------+----------------+----------------+
65 rows in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.2 having【嗨夫营】之后嵌套查询&lt;/h3&gt;
&lt;p&gt;查询部门员工总人数比开发部总人数少 的 部门名称和人数&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//统计开发部员工总人数
select【涩莱克特】 count【kàn特】(name) from【弗乱】 employees【ing普洛伊s】 where【威尔】 dept_id = (select【涩莱克特】 
  dept_id from【弗乱】 departments【迪帕踢门特s】 where【威尔】 dept_name=&quot;开发部&quot;);
-- mysql&amp;gt; select count(name) from employees where dept_id=
--     -&amp;gt; (select dept_id from departments where dept_name=&quot;开发部&quot;);
+---------------------+
| count【kàn特】(name) |
+---------------------+
|          55         |
+---------------------+
1 row in set (0.00 sec)



//统计每个部门总人数 
select【涩莱克特】   dept_id , count【kàn特】(name) from【弗乱】 employees【ing普洛伊s】 group【格鲁普】 by   dept_id;
-- mysql&amp;gt; select dept_id,count(name) from employees group by dept_id;
+---------+---------------------+
| dept_id | count【kàn特】(name) |
+---------+---------------------+
|       1 |           8         |
|       2 |           5         |
|       3 |           6         |
|       4 |          55         |
|       5 |          12         |
|       6 |           9         |
|       7 |          35         |
|       8 |           3         |
+---------+---------------------+
8 rows in set (0.00 sec)


//输出总人数比开发部总人数少的部门名及总人数 
select【涩莱克特】  dept_id ,  count【kàn特】(name) as total【偷ò头ō】    from【弗乱】 employees【ing普洛伊s】 group【格鲁普】 by dept_id 
having【嗨夫营】  total【偷ò头ō】 &amp;lt; (
select【涩莱克特】 count【kàn特】(name) from【弗乱】 employees【ing普洛伊s】  where【威尔】 dept_id=(
select【涩莱克特】 dept_id from【弗乱】 departments【迪帕踢门特s】 where【威尔】 dept_name=&apos;开发部&apos;)
);
-- mysql&amp;gt; select dept_id,count(name) as total from employees group by dept_id 
--     -&amp;gt; having total &amp;lt; (select count(name) from employees where dept_id= (select 
--     -&amp;gt; dept_id from departments where dept_name=&apos;开发部&apos;));
+---------+----------------+
| dept_id | total【偷ò头ō】 |
+---------+----------------+
|       1 |     8          |
|       2 |     5          |
|       3 |     6          |
|       5 |    12          |
|       6 |     9          |
|       7 |    35          |
|       8 |     3          |
+---------+----------------+
7 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.3 from【弗乱】之后嵌套查询&lt;/h3&gt;
&lt;p&gt;查询3号部门 、部门名称 及其部门内 员工的编号、名字 和 email&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】 dept_id, dept_name, employee【ing普洛伊】_id, name, email  from【弗乱】 (
select【涩莱克特】  d.dept_name, e.*  from【弗乱】 departments【迪帕踢门特s】 as d  inner【ing呐】 join【载(白话)】 employees【ing普洛伊s】 as e 
on【昂】 d.dept_id=e.dept_id ) as tmp_table【忒-部】  where【威尔】 dept_id=3;
-- mysql&amp;gt; select dept_id,dept_name,employee_id,name,email from
--     -&amp;gt; (select d.dept_name,e.* from departments as d inner join employees as e
--     -&amp;gt; on d.dept_id=e.dept_id) as tmp_toble where dept_id=3;
+---------+-----------+-------------+-----------+--------------------+
| dept_id | dept_name | employee_id | name      | email              |
+---------+-----------+-------------+-----------+--------------------+
|       3 | 运维部    |          14 | 廖娜      | liaona@moershi.com  |
|       3 | 运维部    |          15 | 窦红梅    | douhongmei@qcjy.cn |
|       3 | 运维部    |          16 | 聂想      | niexiang@qcjy.cn   |
|       3 | 运维部    |          17 | 陈阳      | chenyang@qcjy.cn   |
|       3 | 运维部    |          18 | 戴璐      | dailu@qcjy.cn      |
|       3 | 运维部    |          19 | 陈斌      | chenbin@moershi.com |
+---------+-----------+-------------+-----------+--------------------+
6 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.4 select【涩莱克特】之后嵌套查询&lt;/h3&gt;
&lt;p&gt;查询每个部门的人数： dept_id dept_name 部门人数&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//显示部门表中的所有列表
select【涩莱克特】 d.*  from【弗乱】 departments【迪帕踢门特s】 as d;
-- mysql&amp;gt; select d.* from departments as d;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|       1 | 人事部    |
|       2 | 财务部    |
|       3 | 运维部    |
|       4 | 开发部    |
|       5 | 测试部    |
|       6 | 市场部    |
|       7 | 销售部    |
|       8 | 法务部    |
+---------+-----------+
8 rows in set (0.00 sec)

//查询每个部门的人数
select【涩莱克特】  d.* , ( select【涩莱克特】 count【kàn特】(name) from【弗乱】 employees【ing普洛伊s】 as e  where【威尔】 d.dept_id=e.dept_id) as 部门人数  from【弗乱】 departments【迪帕踢门特s】 as d;
-- mysql&amp;gt; select d.*,(select count(name) from employees as e where d.dept_id=e.dept_id) as 部门人数 
--     -&amp;gt; from departments as d;
+---------+-----------+--------------+
| dept_id | dept_name | 部门人数     |
+---------+-----------+--------------+
|       1 | 人事部    |            8 |
|       2 | 财务部    |            5 |
|       3 | 运维部    |            6 |
|       4 | 开发部    |           55 |
|       5 | 测试部    |           12 |
|       6 | 市场部    |            9 |
|       7 | 销售部    |           35 |
|       8 | 法务部    |            3 |
+---------+-----------+--------------+
8 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;七、作业&lt;/h2&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;在内连接查询中，使用以下哪种关键字进行连接操作？C
A. LEFT JOIN
B. RIGHT JOIN
C. INNER JOIN
D. FULL JOIN&lt;/li&gt;
&lt;li&gt;外连接查询中，左外连接会返回以下哪些数据？A
A. 左表的所有记录和右表匹配的记录
B. 右表的所有记录和左表匹配的记录
C. 左右表的所有记录
D. 只返回左右表匹配的记录&lt;/li&gt;
&lt;li&gt;合并查询中，&lt;code&gt;UNION ALL&lt;/code&gt; 和 &lt;code&gt;UNION&lt;/code&gt; 的区别是？ B
A. &lt;code&gt;UNION ALL&lt;/code&gt; 会去除重复记录，&lt;code&gt;UNION&lt;/code&gt; 不会
B. &lt;code&gt;UNION&lt;/code&gt; 会去除重复记录，&lt;code&gt;UNION ALL&lt;/code&gt; 不会
C. 两者都去除重复记录
D. 两者都不去除重复记录&lt;/li&gt;
&lt;li&gt;嵌套查询是指？B
A. 在一个查询语句中嵌套多个表
B. 在一个查询语句中嵌套另一个查询语句
C. 同时进行多个查询操作
D. 以上都不对&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;简述内连接查询和外连接查询的区别。
答：
内连接是：只保留匹配的记录（交集）
外链接是：保留至少一个表的所有记录，不匹配的用NULL填充
应用场景区别：内连接用于需要精确匹配的场景，外连接用于需要保留所有记录的统计分析&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;什么时候使用 &lt;code&gt;UNION&lt;/code&gt;，什么时候使用 &lt;code&gt;UNION ALL&lt;/code&gt;？
答：
需要唯一结果的时候可以使用&lt;code&gt;UNION&lt;/code&gt;
当需要完整数据或性能优先  时候使用 &lt;code&gt;UNION ALL&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;请解释嵌套查询的作用和适用场景。
答：
嵌套查询的作用
1. 数据筛选与过滤
2. 数据比较与计算
3. 数据存在性检查
4.  数据聚合与统计&lt;/p&gt;
&lt;p&gt;特别适合需要多步骤数据处理和分析的业务场景。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3 操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;使用内连接查询，查询出每个员工所在部门的名称和员工姓名。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt;
mysql&amp;gt; select e.name,d.dept_name from employees as e inner join departments as d         
    -&amp;gt; on e.dept_id=d.dept_id;
+-----------+-----------+
| name      | dept_name |
+-----------+-----------+
| 梁伟      | 人事部    |
| 郭岩      | 人事部    |
| 李玉英    | 人事部    |
| 张健      | 人事部    |
.........

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;使用左外连接查询，查询出所有员工的信息以及他们所在部门的名称（如果员工没有部门，部门名称显示为 NULL）。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt;
mysql&amp;gt; select e.*,d.dept_name from employees as e left join departments as d on e.dept_id=d.dept_id;
+-------------+-----------+------------+------------+---------------------------+--------------+---------+-----------+
| employee_id | name      | hire_date  | birth_date | email                     | phone_number | dept_id | dept_name |
+-------------+-----------+------------+------------+---------------------------+--------------+---------+-----------+
|           1 | 梁伟      | 2018-06-21 | 1971-08-19 | liangwei@tedu.cn          | 13591491431  |       1 | 人事部    |
|           2 | 郭岩      | 2010-03-21 | 1974-05-13 | guoyan@tedu.cn            | 13845285867  |       1 | 人事部    |
|           3 | 李玉英    | 2012-01-19 | 1974-01-25 | liyuying@tedu.cn          | 15628557234  |       1 | 人事部    |
|           4 | 张健      | 2008-09-17 | 1972-06-07 | zhangjian@moershi.com     | 13835990213  |       1 | 人事部    |
|           5 | 郑静      | 2018-02-03 | 1997-02-14 | zhengjing@tedu.cn         | 14508936730  |       1 | 人事部    |
|           6 | 牛建军    | 2005-11-18 | 1985-03-19 | niujianjun@moershi.com    | 14750937118  |       1 | 人事部    |
......

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;使用合并查询，将薪资表中基本薪资大于 5000 和奖金大于 2000 的记录合并。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; (select name,basic from salary as s inner join employees as e on e.employee_id=s.employee_id where basic &amp;gt; 5000)
    -&amp;gt; union
    -&amp;gt; (select name,bonus from salary as s inner join employees as e on e.employee_id=s.employee_id where bonus &amp;gt;2000);
+-----------+-------+
| name      | basic |
+-----------+-------+
| 郭岩      | 17000 |
| 李玉英    |  8000 |
| 张健      | 14000 |
| 牛建军    | 14000 |
| 刘斌      | 19000 |
| 郭兰英    | 14000 |
| 王楠      | 15000 |
| 廖娜      | 10000 |
| 陈阳      | 16000 |
.....

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;使用嵌套查询，查询出部门名称为 “开发部” 的所有员工的信息。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt;
mysql&amp;gt; select * from employees where dept_id=
    -&amp;gt; (select dept_id from departments where dept_name=&apos;开发部&apos;);
+-------------+-----------+------------+------------+---------------------------+--------------+---------+
| employee_id | name      | hire_date  | birth_date | email                     | phone_number | dept_id |
+-------------+-----------+------------+------------+---------------------------+--------------+---------+
|          20 | 蒋红      | 2017-12-29 | 1978-01-24 | jianghong@tedu.cn         | 15852915398  |       4 |
|          21 | 曹宁      | 2004-06-07 | 1988-01-05 | caoning@tedu.cn           | 14513022304  |       4 |
|          22 | 吕刚      | 2014-01-18 | 1980-06-24 | lvgang@tedu.cn            | 18136987619  |       4 |
|          23 | 王莉      | 2021-02-04 | 1972-12-19 | wangli@moershi.com        | 15376329290  |       4 |
|          24 | 邓秀芳    | 2020-09-08 | 1980-12-12 | dengxiufang@moershi.com   | 15884927117  |       4 |
|          25 | 邵佳      | 2011-08-15 | 1978-11-28 | shaojia@tedu.cn           | 13296016750  |       4 |
|          26 | 党丽      | 2014-03-14 | 1978-12-30 | dangli@moershi.com        | 13166234580  |       4 |
|          27 | 梁勇      | 2007-01-19 | 1997-11-12 | liangyong@tedu.cn         | 15307868657  |       4 |
|          28 | 郑秀珍    | 2011-04-28 | 1972-09-01 | zhengxiuzhen@moershi.com  | 14543186401  |       4 |
|          29 | 胡秀云    | 2003-11-03 | 2000-05-14 | huxiuyun@tedu.cn          | 18212266720  |       4 |
|          30 | 邢淑兰    | 2011-07-02 | 1989-06-17 | xingshulan@moershi.com    | 13032270370  |       4 |
|          31 | 刘海燕    | 2018-01-06 | 1982-08-21 | liuhaiyan@moershi.com     | 15064354651  |       4 |
|          32 | 冯建国    | 2014-05-28 | 1980-01-26 | fengjianguo@tedu.cn       | 13344957322  |       4 |
.........

&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;05：mysql之表结构管理&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[表结构管理]
        direction LR
        A[表管理] --&amp;gt; B[表格字段数据类型] --&amp;gt; C[表头基本约束]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class E highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;小李在一家小型互联网公司担任数据库管理员。最近公司业务拓展，员工数量大幅增加，原本的数据库表结构逐渐难以满足需求。&lt;/p&gt;
&lt;p&gt;在员工表中，原先的“职位”字段过于笼统，无法精准区分不同岗位。部门表也没有记录各部门的成立时间，不利于做部门发展分析。薪资表中奖金计算方式单一，不能适应新的绩效制度。&lt;/p&gt;
&lt;p&gt;小李意识到要对表结构进行优化。他先和各部门沟通，了解实际业务需求，再设计新的表结构，在员工表细化“职位”，部门表添加“成立时间”，薪资表调整奖金规则。最后在测试环境验证新结构，确保准确稳定后应用到正式环境。&lt;/p&gt;
&lt;h2&gt;二、为啥要学表结构管理&lt;/h2&gt;
&lt;p&gt;学习 MySQL 表结构管理非常有必要。想象下你在一家公司工作，公司有员工表、部门表和薪资表。如果表结构管理不好，问题就会接踵而至。&lt;/p&gt;
&lt;p&gt;要是员工表没有合理设置字段，可能会导致员工信息记录不全，影响人事管理。部门表结构混乱，就很难清晰掌握各部门的情况。薪资表如果设计不佳，计算薪资时容易出错，引发员工不满。&lt;/p&gt;
&lt;p&gt;学会表结构管理，能让这些表合理存储数据，查询和修改数据更高效，避免数据冗余和错误。可以准确统计各部门员工数量、快速算出员工薪资，让公司运营更顺畅，所以学好它对处理数据很有帮助。&lt;/p&gt;
&lt;h2&gt;三、表管理&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[表结构管理]
        direction LR
        A[表管理] --&amp;gt; B[表格字段数据类型] --&amp;gt; C[表头基本约束]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class A highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.1 建库练习&lt;/h3&gt;
&lt;p&gt;库名命名规则：&lt;/p&gt;
&lt;p&gt;仅可以使用数字、字母、下划线、不能纯数字&lt;/p&gt;
&lt;p&gt;区分字母大小写，&lt;/p&gt;
&lt;p&gt;具有唯一性&lt;/p&gt;
&lt;p&gt;不可使用MySQL命令或特殊字符&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//库名区分字母大小写
mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】 gamedb ;
-- mysql&amp;gt; create database gamedb;
Query OK, 1 row affected (0.14 sec)

mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】 GAMEDB ;
-- mysql&amp;gt; create database GAMEDB;
Query OK, 1 row affected (0.08 sec)

mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】 GAMEDB ;  
-- mysql&amp;gt; create database GAMEDB;
ERROR 1007 (HY000): Can&apos;t create【克瑞特】 database【得塔-贝斯】 &apos;GAMEDB&apos;; database【得塔-贝斯】 exists【伊贼谁斯】&apos; //重名报错

//加if not【nuō 特】 exists【伊贼谁斯】 命令避免重名报错
mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】  if not【nuō 特】 exists【伊贼谁斯】  gamedb ; 
-- mysql&amp;gt; create database if not exists gamedb; 
Query OK, 1 row affected, 1 warning (0.03 sec) //正常

mysql&amp;gt; show【瘦】  databases【得塔-贝斯】; //查看创建的库
-- mysql&amp;gt; show databases;
+--------------------+
| Database           |
+--------------------+
| GAMEDB             |
| gamedb             |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| moershi             |
+--------------------+
7 rows in set (0.00 sec)

mysql&amp;gt; drop【卓-普】 database【得塔-贝斯】 gamedb;  //删除库
-- mysql&amp;gt; drop database gamedb;
Query OK, 0 rows affected (0.11 sec)

mysql&amp;gt; drop【卓-普】 database【得塔-贝斯】 gamedb; // 删除没有的库报错
-- mysql&amp;gt; drop database gamedb;
ERROR 1008 (HY000): Can’t drop【卓-普】 database【得塔-贝斯】 ‘gamedb’; database【得塔-贝斯】 doesn’t exist

//加if exists【伊贼谁斯】 删除没有的库，也不报错
mysql&amp;gt; drop【卓-普】 database【得塔-贝斯】 if exists【伊贼谁斯】 gamedb;
-- mysql&amp;gt; drop database if exists gamedb; 
Query OK, 0 rows affected, 1 warning (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 建表练习&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】  studb【斯丢db】; //建库
-- mysql&amp;gt; create database studb; 
Query OK, 1 row affected (0.11 sec)

mysql&amp;gt; create【克瑞特】 table【忒-部】 studb【斯丢db】.stu(  //建表
    -&amp;gt; name char【查尔】(10), 
    -&amp;gt; class【克拉斯】 char【查尔】(9), 
    -&amp;gt; gender【间德尔】 char【查尔】(4), 
    -&amp;gt; age int【因特】 
    -&amp;gt; );
-- mysql&amp;gt; create table studb.stu( 
--     -&amp;gt; name char(10),
--     -&amp;gt; class char(9),
--     -&amp;gt; gender char(4),
--     -&amp;gt; age int);    
Query OK, 0 rows affected (1.17 sec)

mysql&amp;gt; desc studb【斯丢db】.stu;  //查看表头
-- mysql&amp;gt; desc studb.stu;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| name   | char(10) | YES  |     | NULL    |       |
| class  | char(9)  | YES  |     | NULL    |       |
| gender | char(4)  | YES  |     | NULL    |       |
| age    | int      | YES  |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
4 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3 修改表练习&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;h4&gt;修改表名&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; show【瘦】 tables【忒-部s】; //查看表
-- mysql&amp;gt; show tables;
+-----------------+
| Tables_in_studb |
+-----------------+
| stu             |
+-----------------+
1 row in set (0.00 sec)

mysql&amp;gt; alter【奥-特】 table【忒-部】 studb【斯丢db】.stu rename【瑞-内姆】 studb【斯丢db】.stuinfo【斯丢因否】; //修改表名  rename【瑞-内姆】
-- mysql&amp;gt; alter table studb.stu rename studb.stuinfo;
Query OK, 0 rows affected (0.28 sec)

mysql&amp;gt; use studb【斯丢db】; //进入库
-- mysql&amp;gt; use studb;
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&amp;gt; show【瘦】 tables【忒-部s】; //查看表
-- mysql&amp;gt; show tables;
+-----------------+
| Tables_in_studb |
+-----------------+
| stuinfo         |
+-----------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;删除表头&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; desc studb【斯丢db】.stu;  //查看表头
-- mysql&amp;gt; desc studb.stu;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| name   | char(10) | YES  |     | NULL    |       |
| class  | char(9)  | YES  |     | NULL    |       |
| gender | char(4)  | YES  |     | NULL    |       |
| age    | int      | YES  |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
4 rows in set (0.00 sec)

mysql&amp;gt;  alter【奥-特】 table【忒-部】 studb【斯丢db】.stuinfo【斯丢因否】 drop【卓-普】 age ; //删除age表头 drop【卓-普】
-- mysql&amp;gt; alter table studb.stuinfo drop age;
Query OK, 0 rows affected (0.52 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql&amp;gt;  desc stuinfo【斯丢因否】; //查看表头
-- mysql&amp;gt; desc stuinfo;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| name   | char(10) | YES  |     | NULL    |       |
| class  | char(9)  | YES  |     | NULL    |       |
| gender | char(4)  | YES  |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;添加表头&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//添加表头，默认添加在末尾add
mysql&amp;gt; alter【奥-特】 table【忒-部】 studb【斯丢db】.stuinfo【斯丢因否】 add  mail【miào e】  char【查尔】(30) ; 
-- mysql&amp;gt; alter table studb.stuinfo add mail char(30);
Query OK, 0 rows affected (0.24 sec)
Records: 0  Duplicates: 0  Warnings: 0

//查看表头
mysql&amp;gt; desc studb【斯丢db】.stuinfo【斯丢因否】;
-- mysql&amp;gt; desc studb.stuinfo;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| name   | char(10) | YES  |     | NULL    |       |
| class  | char(9)  | YES  |     | NULL    |       |
| gender | char(4)  | YES  |     | NULL    |       |
| mail   | char(30) | YES  |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
4 rows in set (0.00 sec)

//first【佛斯特】 把表头添加首位  
//after【啊夫特】 添加在指定表头名的下方
mysql&amp;gt; alter【奥-特】 table【忒-部】  studb【斯丢db】.stuinfo【斯丢因否】 add number【能波】  char【查尔】(9) first【佛斯特】 , add  school【斯故】 char【查尔】(10) after【啊夫特】 name;
-- mysql&amp;gt; alter table studb.stuinfo add number char(9) first,add school char(10) after name;
Query OK, 0 rows affected (0.48 sec)
Records: 0  Duplicates: 0  Warnings: 0

//查看表结构
mysql&amp;gt; desc studb【斯丢db】.stuinfo【斯丢因否】;  //查看表头
-- mysql&amp;gt; desc studb.stuinfo;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| number | char(9)  | YES  |     | NULL    |       |
| name   | char(10) | YES  |     | NULL    |       |
| school | char(10) | YES  |     | NULL    |       |
| class  | char(9)  | YES  |     | NULL    |       |
| gender | char(4)  | YES  |     | NULL    |       |
| mail   | char(30) | YES  |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
6 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;修改表头数据类型&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//修改表头数据类型modify【莫迪fái】
mysql&amp;gt; alter【奥-特】 table【忒-部】  studb【斯丢db】.stuinfo【斯丢因否】  modify【莫迪fái】  mail【miào e】 varchar【瓦儿-查儿】(50);
-- mysql&amp;gt; alter table studb.stuinfo modify mail varchar(50);
Query OK, 0 rows affected (1.17 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql&amp;gt; desc studb【斯丢db】.stuinfo【斯丢因否】;
-- mysql&amp;gt; desc studb.stuinfo;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| number | char(9)     | YES  |     | NULL    |       |
| name   | char(10)    | YES  |     | NULL    |       |
| school | char(10)    | YES  |     | NULL    |       |
| class  | char(9)     | YES  |     | NULL    |       |
| gender | char(4)     | YES  |     | NULL    |       |
| mail   | varchar(50) | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
6 rows in set (0.01 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;修改表头名&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//修改表头名class【克拉斯】
mysql&amp;gt; alter【奥-特】 table【忒-部】 studb【斯丢db】.stuinfo【斯丢因否】 change【趁(chèn)吉】  class【克拉斯】  班级  char【查尔】(9) ;
-- mysql&amp;gt; alter table studb.stuinfo change class 班级 char(9);
Query OK, 0 rows affected (0.12 sec)
Records: 0  Duplicates: 0  Warnings: 0

//查看表头
mysql&amp;gt; desc studb【斯丢db】.stuinfo【斯丢因否】;
-- mysql&amp;gt; desc studb.stuinfo;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| number | char(9)     | YES  |     | NULL    |       |
| name   | char(10)    | YES  |     | NULL    |       |
| school | char(10)    | YES  |     | NULL    |       |
| 班级   | char(9)     | YES  |     | NULL    |       |
| gender | char(4)     | YES  |     | NULL    |       |
| mail   | varchar(50) | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;删除多个表头&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//一起删除多个表头
mysql&amp;gt; alter【奥-特】 table【忒-部】  studb【斯丢db】.stuinfo【斯丢因否】  drop【卓-普】 school【斯故】 , drop【卓-普】 班级 ,drop【卓-普】 mail【miào e】 ;
-- mysql&amp;gt; alter table studb.stuinfo drop school,drop 班级,drop mail;
Query OK, 0 rows affected (0.73 sec)
Records: 0  Duplicates: 0  Warnings: 0

//查看表头
mysql&amp;gt; desc studb【斯丢db】.stuinfo【斯丢因否】;
-- mysql&amp;gt; desc studb.stuinfo;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| number | char(9)  | YES  |     | NULL    |       |
| name   | char(10) | YES  |     | NULL    |       |
| gender | char(4)  | YES  |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;修改表头的位置&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; 
//使用modify【莫迪fái】  修改表头的位置  
mysql&amp;gt; alter【奥-特】 table【忒-部】 studb【斯丢db】.stuinfo【斯丢因否】 modify【莫迪fái】 gender【间德尔】 char【查尔】(4) after【啊夫特】 number【能波】;
-- mysql&amp;gt; alter table studb.stuinfo modify gender char(4) after number;
Query OK, 0 rows affected (0.77 sec)
Records: 0  Duplicates: 0  Warnings: 0

//查看表头
mysql&amp;gt; desc studb【斯丢db】.stuinfo【斯丢因否】;
-- mysql&amp;gt; desc studb.stuinfo;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| number | char(9)  | YES  |     | NULL    |       |
| gender | char(4)  | YES  |     | NULL    |       |
| name   | char(10) | YES  |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

//再修改回原来位置
mysql&amp;gt;  alter【奥-特】 table【忒-部】 studb【斯丢db】.stuinfo【斯丢因否】 modify【莫迪fái】 gender【间德尔】 char【查尔】(4) after【啊夫特】 name;
-- mysql&amp;gt; alter table studb.stuinfo modify gender char(4) after name;
Query OK, 0 rows affected (0.50 sec)
Records: 0  Duplicates: 0  Warnings: 0

//查看表头
mysql&amp;gt; desc studb【斯丢db】.stuinfo【斯丢因否】;
-- mysql&amp;gt; desc studb.stuinfo;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| number | char(9)  | YES  |     | NULL    |       |
| name   | char(10) | YES  |     | NULL    |       |
| gender | char(4)  | YES  |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
3 rows in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.4 复制表&lt;/h3&gt;
&lt;p&gt;拷贝已有的表 和系统命令 cp 的功能一样&lt;/p&gt;
&lt;h4&gt;复制表&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;-- create table 表名  select * from 表名
//复制moershi库salary【晒了瑞】表到 studb【斯丢db】库 表名不变
mysql&amp;gt; create【克瑞特】 table【忒-部】 studb【斯丢db】.salary【晒了瑞】  select【涩莱克特】  * from【弗乱】 moershi.salary【晒了瑞】;
-- mysql&amp;gt; create table studb.salary select * from moershi.salary;
Query OK, 8055 rows affected (2.66 sec)
Records: 8055  Duplicates: 0  Warnings: 0 

//查看表头，源表的key【kì】 不会被复制
mysql&amp;gt; desc studb【斯丢db】.salary【晒了瑞】;
-- mysql&amp;gt; desc studb.salary;
+-------------+------+------+-----+---------+-------+
| Field       | Type | Null | Key | Default | Extra |
+-------------+------+------+-----+---------+-------+
| id          | int  | NO   |     | 0       |       |
| date        | date | YES  |     | NULL    |       |
| employee_id | int  | YES  |     | NULL    |       |
| basic       | int  | YES  |     | NULL    |       |
| bonus       | int  | YES  |     | NULL    |       |
+-------------+------+------+-----+---------+-------+
5 rows in set (0.00 sec)

//查看表行数
mysql&amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】 studb【斯丢db】.salary【晒了瑞】;
-- mysql&amp;gt; select count(*) from studb.salary;
+----------+
| count(*) |
+----------+
|     8055 |
+----------+
1 row in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;复制表头&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//仅仅复制表头like【赖特
mysql&amp;gt; create【克瑞特】 table【忒-部】 studb【斯丢db】.salary2【晒了瑞2】  like【赖特】 moershi.salary【晒了瑞】;
-- mysql&amp;gt; create table studb.salary2 like moershi.salary;
Query OK, 0 rows affected (0.95 sec)

//查看表头
mysql&amp;gt; desc studb【斯丢db】.salary2【晒了瑞2】;
-- mysql&amp;gt; desc studb.salary2;
+-------------+------+------+-----+---------+----------------+
| Field       | Type | Null | Key | Default | Extra          |
+-------------+------+------+-----+---------+----------------+
| id          | int  | NO   | PRI | NULL    | auto_increment |
| date        | date | YES  |     | NULL    |                |
| employee_id | int  | YES  | MUL | NULL    |                |
| basic       | int  | YES  |     | NULL    |                |
| bonus       | int  | YES  |     | NULL    |                |
+-------------+------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

//查看表行数
mysql&amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】 studb【斯丢db】.salary2【晒了瑞2】;
-- mysql&amp;gt; select count(*) from studb.salary2;
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、表的字段数据类型&lt;/h2&gt;
&lt;p&gt;数值类型：INT存储整数，DECIMAL存储精确小数
字符类型：CHAR适合固定长度，VARCHAR适合可变长度
日期时间：DATE存储日期，TIME存储时间
枚举类型：ENUM存储预定义值列表&lt;/p&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[表结构管理]
        direction LR
        A[表管理] --&amp;gt; B[表格字段数据类型] --&amp;gt; C[表头基本约束]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class B highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;常用数据类型：数值类型、字符类型、日期时间类型、枚举类型,每种类型都有对应的命令表示、有具体的存储范围。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;比如存储： 身高、体重、工资、奖金，适合使用数值类型。&lt;/li&gt;
&lt;li&gt;比如存储： 姓名、家庭地址、收货地址，适合使用字符类型。char&lt;/li&gt;
&lt;li&gt;比如存储： 生日、出生年份、入职时间、下班时间、注册时间，适合使用日期时间。date(日期) time(时间) datetime(时间日期) yeaer(年份)&lt;/li&gt;
&lt;li&gt;比如存储： 爱好、性别、社保医院，适合使用枚举类型。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.1 练习字符类型的使用&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//建表
mysql&amp;gt; create【克瑞特】  table【忒-部】   studb【斯丢db】.t2(name   char【查尔】(3) , address【额拽斯】   varchar【瓦儿-查儿】(5) );
-- mysql&amp;gt; create table studb.t2(name char(3),adderss varchar(5));
Query OK, 0 rows affected (0.30 sec)

//查看表头
mysql&amp;gt;  desc studb【斯丢db】.t2;
-- mysql&amp;gt; desc studb.t2;
+---------+------------+------+-----+---------+-------+
| Field   | Type       | Null | Key | Default | Extra |
+---------+------------+------+-----+---------+-------+
| name    | char(3)    | YES  |     | NULL    |       |
| address | varchar(5) | YES  |     | NULL    |       |
+---------+------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

//插入记录
mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t2 values【挖柳斯】 (&quot;a&quot;,&quot;a&quot;); //正常
-- mysql&amp;gt; insert into studb.t2 values(&quot;a&quot;,&quot;a&quot;);
Query OK, 1 row affected (0.05 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t2 values【挖柳斯】 (&quot;ab&quot;,&quot;ab&quot;); //正常
-- mysql&amp;gt; insert into studb.t2 values (&quot;ab&quot;,&quot;ab&quot;);   
Query OK, 1 row affected (0.08 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t2 values【挖柳斯】 (&quot;abc&quot;,&quot;abc&quot;);//正常
-- mysql&amp;gt; insert into studb.t2 values (&quot;abc&quot;,&quot;abc&quot;);
Query OK, 1 row affected (0.04 sec)

mysql&amp;gt;  insert【因涩特】 into【因兔】 studb【斯丢db】.t2 values【挖柳斯】 (&quot;abcd&quot;,&quot;abcd&quot;); //超出字符个数报错
-- mysql&amp;gt; insert into studb.t2 values (&quot;abcd&quot;,&quot;abcd&quot;);
ERROR 1406 (22001): Data too long for column &apos;name&apos; at row 1

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mysql8 建表默认支持中文字符集&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//查看字符集
mysql&amp;gt; show【瘦】 create【克瑞特】 table【忒-部】 studb【斯丢db】.t2 \G
-- mysql&amp;gt; show create table studb.t2 \G
*************************** 1. row ***************************
       Table: t2
Create Table: CREATE TABLE `t2` (
  `name` char【查尔】(3) DEFAULT NULL【nào】,
  `address【额拽斯】` varchar【瓦儿-查儿】(5) DEFAULT NULL【nào】
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

说明 ：
ENGINE=InnoDB  定义存储引擎（存储引擎课程里讲） 
DEFAULT   CHARSET=定义表使用的字符集 

//插入记录
mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t2 values【挖柳斯】 (&quot;张翠山&quot;,&quot;武当山&quot;);
-- mysql&amp;gt; insert into studb.t2 values(&quot;张翠山&quot;,&quot;武当山&quot;);
Query OK, 1 row affected (0.07 sec)

//查看表记录
mysql&amp;gt; SELECT【涩莱克特】  * FROM【弗乱】 studb【斯丢db】.t2;
-- mysql&amp;gt; select * from studb.t2;
+-----------+-----------+
| name      | address   |
+-----------+-----------+
| a         | a         |
| ab        | ab        |
| abc       | abc       |
| 张翠山    | 武当山     |
+-----------+-----------+
4 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 练习数值类型的使用&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//建表
mysql&amp;gt; create【克瑞特】 table【忒-部】  studb【斯丢db】.t1(name  char【查尔】(10) , level【列沃】  tinyint【泰尼因特】 unsigned【安赛因德】 ,  money【孟妮】  double【答步】  );
-- mysql&amp;gt; create table studb.t1(name char(10),level  tinyint unsigned ,  money  double  );
Query OK, 0 rows affected (0.72 sec)

//查看表头
mysql&amp;gt; desc studb【斯丢db】.t1;
-- mysql&amp;gt; desc studb.t1;
+-------+------------------+------+-----+---------+-------+
| Field | Type             | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| name  | char(10)         | YES  |     | NULL    |       |
| level | tinyint unsigned | YES  |     | NULL    |       |
| money | double           | YES  |     | NULL    |       |
+-------+------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

//插入数据
mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t1 values【挖柳斯】(&quot;法师&quot;,80,88);
-- mysql&amp;gt; insert into studb.t1 values(&quot;法师&quot;,80,88);
Query OK, 1 row affected (0.04 sec)

//超出范围报错 tinyint unsigned 最大255  可以是小数，四舍五入取整
mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t1 values【挖柳斯】(&quot;战士&quot;,301,1.292);
-- mysql&amp;gt; insert into studb.t1 values(&quot;战士&quot;,301,1.292);
ERROR 1264 (22003): Out of range value for column &apos;level【列沃】&apos; at row 1 -- 失败是因为值301超出了TINYINT UNSIGNED的数据范围（0-255）

mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t1 values【挖柳斯】(&quot;猎人&quot;,255,1.292);
-- mysql&amp;gt; insert into studb.t1 values(&quot;猎人&quot;,255,1.292);
Query OK, 1 row affected (0.06 sec)

//整数类型 不存储小数位
mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t1  values【挖柳斯】 (&quot;英雄&quot;,1.292,6.78);
-- mysql&amp;gt; insert into studb.t1 values(&quot;英雄&quot;,1.292,6.78);
Query OK, 1 row affected (0.07 sec) 

//查看表记录  
mysql&amp;gt; select【涩莱克特】 *  from【弗乱】 studb【斯丢db】.t1 ;
-- mysql&amp;gt; select * from studb.t1;
+--------+-------+-------+
| name   | level | money |
+--------+-------+-------+
| 法师   |    80 |    88 |
| 猎人   |   255 | 1.292 |
| 英雄   |     1 |  6.78 |
+--------+-------+-------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.3 枚举类型&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;//建表
mysql&amp;gt; create【克瑞特】  table【忒-部】 studb【斯丢db】.t8(
    -&amp;gt; 姓名 char【查尔】(10),
    -&amp;gt; 性别  enum【伊牛姆】(&quot;男&quot;,&quot;女&quot;,&quot;保密&quot;), 
    -&amp;gt; 爱好 set【赛特】(&quot;帅哥&quot;,&quot;金钱&quot;,&quot;吃&quot;,&quot;睡&quot;) 
    -&amp;gt; );
-- mysql&amp;gt; create table studb.t8(
--     -&amp;gt; 姓名 char(10),
--     -&amp;gt; 性别 enum(&quot;男&quot;,&quot;女&quot;,&quot;保密&quot;),
--     -&amp;gt; 爱好 set(&quot;帅哥&quot;,&quot;金钱&quot;,&quot;吃&quot;,&quot;睡&quot;));
Query OK, 0 rows affected (0.29 sec)

//查看表头
mysql&amp;gt; desc studb【斯丢db】.t8 ;
-- mysql&amp;gt; desc studb.t8;
+--------+------------------------------------+------+-----+---------+-------+
| Field  | Type                               | Null | Key | Default | Extra |
+--------+------------------------------------+------+-----+---------+-------+
| 姓名   | char(10)                           | YES  |     | NULL    |       |
| 性别   | enum(&apos;男&apos;,&apos;女&apos;,&apos;保密&apos;)             | YES  |     | NULL    |       |
| 爱好   | set(&apos;帅哥&apos;,&apos;金钱&apos;,&apos;吃&apos;,&apos;睡&apos;)       | YES  |     | NULL    |       |
+--------+------------------------------------+------+-----+---------+-------+
3 rows in set (0.01 sec)

//插入记录超出范围报错
mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t8 values【挖柳斯】 (&quot;小包总&quot;,&quot;男人&quot;,&quot;帅哥,睡,金钱&quot;);
-- mysql&amp;gt; insert into studb.t8 values (&quot;小包总&quot;,&quot;男人&quot;,&quot;帅哥,睡,金钱&quot;);
ERROR 1265 (01000): Data truncated for column &apos;性别&apos; at row 1 -- 值&quot;男人&quot;不在ENUM类型的预定义值列表中（只有&apos;男&apos;,&apos;女&apos;,&apos;保密&apos;）

mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t8 values【挖柳斯】 (&quot;小包总&quot;,&quot;男&quot;,&quot;美女,睡,金钱&quot;);
-- mysql&amp;gt; insert into studb.t8 values (&quot;小包总&quot;,&quot;男&quot;,&quot;美女,睡,金钱&quot;);
ERROR 1265 (01000): Data truncated for column &apos;爱好&apos; at row 1 --&quot;爱好&quot;字段只包含&apos;帅哥&apos;,&apos;金钱&apos;,&apos;吃&apos;,&apos;睡&apos;四个值，不包含&quot;美女&quot;这个值


//在范围内插入成功
mysql&amp;gt; insert【因涩特】 into【因兔】 studb【斯丢db】.t8 values【挖柳斯】 (&quot;丫丫&quot;,&quot;女&quot;,&quot;帅哥,吃&quot;);
-- mysql&amp;gt; insert into studb.t8 values(&quot;丫丫&quot;,&quot;女&quot;,&quot;帅哥,吃&quot;);
Query OK, 1 row affected (0.09 sec)

mysql&amp;gt; select【涩莱克特】  * from【弗乱】 studb【斯丢db】.t8;
-- mysql&amp;gt; select * from studb.t8;
+--------+--------+------------+
| 姓名   | 性别   | 爱好       |
+--------+--------+------------+
| 丫丫   | 女     | 帅哥,吃    |
+--------+--------+------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.4 练习日期时间类型的使用&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//建表
mysql&amp;gt; create【克瑞特】 table【忒-部】 studb【斯丢db】.t6( 
    -&amp;gt; 姓名  char【查尔】(10), 
    -&amp;gt; 生日  date , 
    -&amp;gt; 出生年份 year【耶尔】, 
    -&amp;gt; 家庭聚会  datetime , 
    -&amp;gt; 聚会地点  varchar【瓦儿-查儿】(15), 
    -&amp;gt; 上班时间 time
    -&amp;gt; );
-- mysql&amp;gt; create table studb.t6(
--     -&amp;gt; 姓名 char(10),
--     -&amp;gt; 生日 date,
--     -&amp;gt; 出生年份 year,
--     -&amp;gt; 家庭聚会 datetime,
--     -&amp;gt; 聚会地点 varchar(15),
--     -&amp;gt; 上班时间 time);
Query OK, 0 rows affected (0.25 sec)

//查看表头
mysql&amp;gt; desc studb【斯丢db】.t6 ;
-- mysql&amp;gt; desc studb.t6;
+--------------+-------------+------+-----+---------+-------+
| Field        | Type        | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| 姓名         | char(10)    | YES  |     | NULL    |       |
| 生日         | date        | YES  |     | NULL    |       |
| 出生年份     | year        | YES  |     | NULL    |       |
| 家庭聚会     | datetime    | YES  |     | NULL    |       |
| 聚会地点     | varchar(15) | YES  |     | NULL    |       |
| 上班时间     | time        | YES  |     | NULL    |       |
+--------------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

//插入表头
mysql&amp;gt; insert【因涩特】 into【因兔】  studb【斯丢db】.t6 
    -&amp;gt; values【挖柳斯】 (&quot;翠花&quot;,20211120,1990,20220101183000,&quot;天坛校区&quot;,090000);
-- mysql&amp;gt; insert into studb.t6
--     -&amp;gt; values (&quot;翠花&quot;,20211120,1990,20220101183000,&quot;天坛校区&quot;,090000);
Query OK, 1 row affected (0.05 sec)

//查看表记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 studb【斯丢db】.t6;
-- mysql&amp;gt; select * from studb.t6;
+--------+------------+--------------+---------------------+--------------+--------------+
| 姓名   | 生日       | 出生年份     | 家庭聚会            | 聚会地点     | 上班时间     |
+--------+------------+--------------+---------------------+--------------+--------------+
| 翠花   | 2021-11-20 |         1990 | 2022-01-01 18:30:00 | 天坛校区     | 09:00:00     |
+--------+------------+--------------+---------------------+--------------+--------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、表头基本约束&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[表结构管理]
        direction LR
        A[表管理] --&amp;gt; B[表格字段数据类型] --&amp;gt; C[表头基本约束]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class C highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;约束是一种限制，设置在表头上，用来控制表头的赋值，包括以下几种：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;NOT【nuō 特】 NULL【nò】 ：非空，用于保证该字段的值不能为空。&lt;/li&gt;
&lt;li&gt;DEFAULT【迪-佛特】：默认值，用于保证该字段有默认值。&lt;/li&gt;
&lt;li&gt;UNIQUE【U尼克】：唯一索引，用于保证该字段的值具有唯一性，可以为空。&lt;/li&gt;
&lt;li&gt;primary【普赖莫瑞】 KEY【kì】：主键，用于保证该字段的值具有唯一性并且非空。&lt;/li&gt;
&lt;li&gt;FOREIGN【佛润】 KEY【kì】：外键，用于限制两个表的关系，用于保证该字段的值必须来自于主表的关联列的值，在从表添加外键约束，用于引用主表中某些的值。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;5.1 表头不允许赋空值&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;//建表时给表头设置默认和不允许赋null【nào】值    
mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】 if not【nuō 特】 exists【伊贼谁斯】 db1;
-- mysql&amp;gt; create database if not exists db1;
Query OK, 1 row affected (0.07 sec)

//建表
mysql&amp;gt; create【克瑞特】 table【忒-部】 db1.t31(
    -&amp;gt; name char【查尔】(10) not【nuō 特】 null【nào】 , 
    -&amp;gt; class【克拉斯】 char【查尔】(7) default【迪-佛特】 &quot;nsd&quot;,
    -&amp;gt; likes【赖特s】 set【赛特】(&quot;money【孟妮】&quot;,&quot;game&quot;,&quot;film&quot;,&quot;music&quot;) not【nuō 特】 null【nào】  default【迪-佛特】 &quot;film,music&quot; );
-- mysql&amp;gt; create table db1.t31(
--     -&amp;gt; name char(10) not null,
--     -&amp;gt; class char(7) default &quot;nsd&quot;,
--     -&amp;gt; likes set(&quot;money&quot;,&quot;game&quot;,&quot;film&quot;,&quot;music&quot;) not null default &quot;film,music&quot; );
Query OK, 0 rows affected (0.43 sec)

//查看表头
mysql&amp;gt; desc db1.t31;
-- mysql&amp;gt; desc db1.t31;
+-------+------------------------------------+------+-----+------------+-------+
| Field | Type                               | Null | Key | Default    | Extra |
+-------+------------------------------------+------+-----+------------+-------+
| name  | char(10)                           | NO   |     | NULL       |       |
| class | char(7)                            | YES  |     | nsd        |       |
| likes | set(&apos;money&apos;,&apos;game&apos;,&apos;film&apos;,&apos;music&apos;) | NO   |     | film,music |       |
+-------+------------------------------------+------+-----+------------+-------+
3 rows in set (0.01 sec)

//验证默认值和不允许为null
mysql&amp;gt; insert【因涩特】 into【因兔】  db1.t31 values【挖柳斯】 (null, null , null); 
-- mysql&amp;gt; insert into db1.t31 values(null, null , null); 
ERROR 1048 (23000): Column &apos;name&apos; cannot be null  //表头name赋null值 报错

//表头likes【赖特s】赋null值 报错
mysql&amp;gt; insert【因涩特】 into【因兔】  db1.t31 values【挖柳斯】 (&quot;bob&quot;, null , null);
-- mysql&amp;gt; insert into db1.t31 values(&quot;bob&quot;, null , null);
ERROR 1048 (23000): Column &apos;likes&apos; cannot be null   

//符合约束不报错
mysql&amp;gt; insert【因涩特】 into【因兔】  db1.t31 values【挖柳斯】 (&quot;bob&quot;,null,&quot;money【孟妮】,game,film&quot;); 
-- mysql&amp;gt; insert into db1.t31 values(&quot;bob&quot;,null,&quot;money,game,film&quot;); 
Query OK, 1 row affected (0.06 sec)

//不赋值的表头使用默认值赋值
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t31(name) values【挖柳斯】(&quot;jim&quot;);  
-- mysql&amp;gt; insert into db1.t31(name) values(&quot;jim&quot;);
-- Query OK, 1 row affected (0.01 sec)

//根据需要自定义表头的值
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t31 values【挖柳斯】 (&quot;lucy&quot;,&quot;nsd2108&quot;,&quot;game,film&quot;); 
-- mysql&amp;gt; insert into db1.t31 values(&quot;lucy&quot;,&quot;nsd2108&quot;,&quot;game,film&quot;);
-- Query OK, 1 row affected (0.14 sec)

//查看表记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.t31;
-- mysql&amp;gt; select * from db1.t31;
+------+---------+-----------------+
| name | class   | likes           |
+------+---------+-----------------+
| bob  | NULL    | money,game,film |
| jim  | nsd     | film,music      |
| lucy | nsd2108 | game,film       |
+------+---------+-----------------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 表头加唯一索引练习&lt;/h3&gt;
&lt;p&gt;唯一索引 （unique【U尼克】）&lt;/p&gt;
&lt;p&gt;约束的方式：表头值唯一 , 但可以赋null 值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//建表
create【克瑞特】      table【忒-部】  db1.t32 (姓名  char【查尔】(10)  ,  护照   char【查尔】(18)  unique【U尼克】  );
-- mysql&amp;gt; create table db1.t32 (姓名 char(10) , 护照 char(18) unique);

//查看表头 唯一索引标志UNI
mysql&amp;gt; desc db1.t32 ;
-- mysql&amp;gt; desc db1.t32;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| 姓名   | char(10) | YES  |     | NULL    |       |
| 护照   | char(18) | YES  | UNI | NULL    |       |
+--------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec) 

//赋null值 可以
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t32 values【挖柳斯】(&quot;bob&quot;,null);
-- mysql&amp;gt; insert into db1.t32 values(&quot;bob&quot;,null);
Query OK, 1 row affected (0.07 sec)

//表头值重复不可以
mysql&amp;gt;  insert【因涩特】 into【因兔】 db1.t32 values【挖柳斯】(&quot;tom&quot;,&quot;666888&quot;);
-- mysql&amp;gt; insert into db1.t32 values(&quot;tom&quot;,&quot;666888&quot;);
Query OK, 1 row affected (0.08 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t32 values【挖柳斯】(&quot;jim&quot;,&quot;666888&quot;);
-- mysql&amp;gt; insert into db1.t32 values(&quot;jim&quot;,&quot;666888&quot;);
ERROR 1062 (23000): Duplicate entry &apos;666888&apos; for key【kì】 &apos;t32.护照&apos;

//不重复 可以
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t32 values【挖柳斯】(&quot;jim&quot;,&quot;766888&quot;); 
-- mysql&amp;gt; insert into db1.t32 values(&quot;jim&quot;,&quot;766888&quot;);
Query OK, 1 row affected (0.05 sec) 

//查看表记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 DB1.t32;
-- mysql&amp;gt; select * from db1.t32;
+------+--------+
| 姓名  | 护照  |
+------+--------+
| bob  | NULL   |
| tom  | 666888 |
| jim  | 766888 |
+------+--------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;/h3&gt;
&lt;p&gt;2 bob nsd2107 bj&lt;/p&gt;
&lt;p&gt;3 bob nsd2107 bj&lt;/p&gt;
&lt;p&gt;4 bob nsd2107 bj&lt;/p&gt;
&lt;p&gt;1）建表&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】     table【忒-部】   db1.t38 (
    -&amp;gt; 行号   int【因特】   primary【普赖莫瑞】 key【kì】  auto_increment【奥特欧_因克瑞门特】   , 
    -&amp;gt; 姓名   char【查尔】(10) , 
    -&amp;gt; 班级   char【查尔】(7) , 
    -&amp;gt; 住址   char【查尔】(10)
    -&amp;gt; );
-- mysql&amp;gt; create table db1.t38(
--     -&amp;gt; 行号 int primary key auto_increment,
--     -&amp;gt; 姓名 char(10),
--     -&amp;gt; 班级 char(7),
--     -&amp;gt; 住址 char(10));
Query OK, 0 rows affected (0.76 sec)

//查看表头
mysql&amp;gt; desc db1.t38 ;
-- mysql&amp;gt; desc db1.t38;
+--------+----------+------+-----+---------+----------------+
| Field  | Type     | Null | Key | Default | Extra          |
+--------+----------+------+-----+---------+----------------+
| 行号   | int      | NO   | PRI | NULL    | auto_increment |
| 姓名   | char(10) | YES  |     | NULL    |                |
| 班级   | char(7)  | YES  |     | NULL    |                |
| 住址   | char(10) | YES  |     | NULL    |                |
+--------+----------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

//插入表记录 不给自增长表头赋值
mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;bob&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;bob&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
Query OK, 1 row affected (0.05 sec)

mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;bob&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;bob&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
Query OK, 1 row affected (0.04 sec)

mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;tom&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;tom&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
Query OK, 1 row affected (0.05 sec)

//查看表记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.t38;
-- mysql&amp;gt; select * from db1.t38;
+--------+--------+---------+--------+
| 行号   | 姓名   | 班级    | 住址   |
+--------+--------+---------+--------+
|      1 | bob    | nsd2107 | bj     |
|      2 | bob    | nsd2107 | bj     |
|      3 | tom    | nsd2107 | bj     |
+--------+--------+---------+--------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、作业&lt;/h2&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;在 MySQL 中创建表时，用于定义字段为字符类型且长度为 20 的是以下哪种写法？A
A. CHAR(20)
B. TEXT(20)
C. INT(20)
D. FLOAT(20)&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;讲解：CHAR是固定长度的字符类型，TEXT是可变长度文本类型不能指定长度，INT是整数类型，FLOAT是浮点数类型。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;若要修改表名为 &lt;code&gt;students&lt;/code&gt; 的表，将其中 &lt;code&gt;age&lt;/code&gt; 字段的数据类型从 &lt;code&gt;INT&lt;/code&gt; 改为 &lt;code&gt;SMALLINT&lt;/code&gt;，应使用以下哪条语句？ B
A. UPDATE TABLE students CHANGE age age SMALLINT;
B. ALTER TABLE students MODIFY age SMALLINT;
C. MODIFY TABLE students ALTER age SMALLINT;
D. CHANGE TABLE students UPDATE age SMALLINT;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;讲解：使用ALTER TABLE + MODIFY来修改字段数据类型，CHANGE用于修改字段名。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;以下哪种方法可以复制表 &lt;code&gt;orders&lt;/code&gt; 的结构和数据到新表 &lt;code&gt;orders_copy&lt;/code&gt; ？A
A. CREATE TABLE orders_copy AS SELECT * FROM orders;
B. COPY TABLE orders TO orders_copy;
C. INSERT INTO orders_copy SELECT * FROM orders;
D. CLONE TABLE orders orders_copy;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;讲解：这是最常用的复制表方法，会同时复制表结构和数据。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;以下适合存储邮件地址的字段类型是？C
A. DATE
B. DECIMAL
C. VARCHAR
D. TINYINT&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;讲解：邮件地址是可变长度字符串，VARCHAR最适合。DATE是日期，DECIMAL是小数，TINYINT是整数。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;要在创建表 &lt;code&gt;products&lt;/code&gt; 时，确保 &lt;code&gt;product_name&lt;/code&gt; 字段的值不为空，应使用以下哪种约束？ B
A. UNIQUE
B. NOT NULL
C. CHECK
D. DEFAULT&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;讲解：NOT NULL约束确保字段必须有值，不能为空。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;简述在 MySQL 中创建表时，如何选择合适的字段类型，请举例说明。
答：
存储： 身高、体重、工资、奖金，适合使用数值类型。如：tinyint unsigned、long、int
存储： 姓名、家庭地址、收货地址，适合使用字符类型。如：char、varchar
存储： 生日、出生年份、入职时间、下班时间、注册时间，适合使用日期时间。date、time、datetime、year
存储： 爱好、性别、社保医院，适合使用枚举类型。如：enum、set&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;说明使用 &lt;code&gt;ALTER TABLE&lt;/code&gt; 语句修改表结构时，修改字段名和修改字段数据类型的操作有什么不同。
答：
1. 修改字段数据类型：
语法：alter table 数据库.表 modify 字段名 新数据类型;
2. 修改字段名：
语法：alter table 数据库.表 change 旧字段名 新字段名 数据类型;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;复制表有哪几种常见方式，它们各自的优缺点是什么？
答：
1. 复制表结构（不复制数据）
语法：CREATE TABLE 新表名 LIKE 旧表名;
优点：快速，只复制结构
缺点：不包含数据
2. 复制表结构和数据：
语法：CREATE TABLE 新表名 AS SELECT * FROM 旧表名;
优点：同时复制结构和数据
缺点：不复制索引和约束&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;解释表的基本约束 &lt;code&gt;NOT NULL&lt;/code&gt; 和 &lt;code&gt;DEFAULT&lt;/code&gt; 的作用，并举例说明如何在创建表时使用。
答：
NOT NULL：
作用：
不允许字段为空、字段必须有值
举例：
create table 数据库.表 (字段名 数据类型 not null);
DEFAULT：
作用：
设置字段的默认值、当不赋值时使用
举例：
create table 数据库.表 (字段名 数据类型 default 默认值);&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3 操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;创建一个名为 &lt;code&gt;books&lt;/code&gt; 的表，包含字段 &lt;code&gt;book_title&lt;/code&gt;（字符串类型，长度不超过 100）、&lt;code&gt;publish_year&lt;/code&gt;（年份类型）、&lt;code&gt;price&lt;/code&gt;（小数类型，保留两位小数）。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create table if not exists studb.books (
    -&amp;gt; id int auto_increment primary key,
    -&amp;gt; book_title varchar(100),
    -&amp;gt; publish_year year,
    -&amp;gt; price decimal(10,2)
    -&amp;gt; );
Query OK, 0 rows affected (0.94 sec)

mysql&amp;gt; desc studb.books;
+--------------+---------------+------+-----+---------+----------------+
| Field        | Type          | Null | Key | Default | Extra          |
+--------------+---------------+------+-----+---------+----------------+
| id           | int           | NO   | PRI | NULL    | auto_increment |
| book_title   | varchar(100)  | YES  |     | NULL    |                |
| publish_year | year          | YES  |     | NULL    |                |
| price        | decimal(10,2) | YES  |     | NULL    |                |
+--------------+---------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;在 &lt;code&gt;books&lt;/code&gt; 表中添加一个新字段 &lt;code&gt;author&lt;/code&gt;，类型为字符串，长度不超过 50。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; 
mysql&amp;gt; alter table studb.books add author varchar(50);
Query OK, 0 rows affected (2.88 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql&amp;gt; desc studb.books;
+--------------+---------------+------+-----+---------+----------------+
| Field        | Type          | Null | Key | Default | Extra          |
+--------------+---------------+------+-----+---------+----------------+
| id           | int           | NO   | PRI | NULL    | auto_increment |
| book_title   | varchar(100)  | YES  |     | NULL    |                |
| publish_year | year          | YES  |     | NULL    |                |
| price        | decimal(10,2) | YES  |     | NULL    |                |
| author       | varchar(50)   | YES  |     | NULL    |                |
+--------------+---------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;复制 &lt;code&gt;books&lt;/code&gt; 表的结构和数据到一个新表 &lt;code&gt;books_archive&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; create table studb.books_archive select * from studb.books;
Query OK, 0 rows affected (1.29 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql&amp;gt; show tables;
+-----------------+
| Tables_in_studb |
+-----------------+
| books           |
| books_archive   |
| salary          |
| salary2         |
| stuinfo         |
| t1              |
| t2              |
| t6              |
| t8              |
+-----------------+
9 rows in set (0.00 sec)

mysql&amp;gt; desc books_archive;
+--------------+---------------+------+-----+---------+-------+
| Field        | Type          | Null | Key | Default | Extra |
+--------------+---------------+------+-----+---------+-------+
| id           | int           | NO   |     | 0       |       |
| book_title   | varchar(100)  | YES  |     | NULL    |       |
| publish_year | year          | YES  |     | NULL    |       |
| price        | decimal(10,2) | YES  |     | NULL    |       |
| author       | varchar(50)   | YES  |     | NULL    |       |
+--------------+---------------+------+-----+---------+-------+
5 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;修改 &lt;code&gt;books&lt;/code&gt; 表中 &lt;code&gt;price&lt;/code&gt; 字段的默认值为 0。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; alter table books modify price decimal(10,2) default 0;
Query OK, 0 rows affected (0.23 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql&amp;gt; desc books;
+--------------+---------------+------+-----+---------+----------------+
| Field        | Type          | Null | Key | Default | Extra          |
+--------------+---------------+------+-----+---------+----------------+
| id           | int           | NO   | PRI | NULL    | auto_increment |
| book_title   | varchar(100)  | YES  |     | NULL    |                |
| publish_year | year          | YES  |     | NULL    |                |
| price        | decimal(10,2) | YES  |     | 0.00    |                |
| author       | varchar(50)   | YES  |     | NULL    |                |
+--------------+---------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;将 &lt;code&gt;books&lt;/code&gt; 表中的 &lt;code&gt;book_title&lt;/code&gt; 字段设置为不允许为空。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; alter table books modify book_title varchar(100) not null;
Query OK, 0 rows affected (2.19 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql&amp;gt; desc books;
+--------------+---------------+------+-----+---------+----------------+
| Field        | Type          | Null | Key | Default | Extra          |
+--------------+---------------+------+-----+---------+----------------+
| id           | int           | NO   | PRI | NULL    | auto_increment |
| book_title   | varchar(100)  | NO   |     | NULL    |                |
| publish_year | year          | YES  |     | NULL    |                |
| price        | decimal(10,2) | YES  |     | 0.00    |                |
| author       | varchar(50)   | YES  |     | NULL    |                |
+--------------+---------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;06：mysql之主键外键索引&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[主键外键索引]
        direction LR
        A[主键] --&amp;gt; B[外键] --&amp;gt; C[MySQL索引]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class E highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;小型电商公司&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;林悦是一家小型电商公司的数据库管理员。随着业务发展，订单量逐渐增多，数据库查询变得缓慢。林悦发现订单表缺乏主键约束，数据存在重复，在查询某一订单时效率极低。同时，订单表和商品表之间没有设置外键关联，导致数据一致性难以保证。她为订单表添加主键，建立订单表与商品表的外键关系，并在经常用于查询的字段上创建索引，大大提高了数据查询和写入的效率，保障了数据的准确性。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;大型互联网企业&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;张成就职于大型互联网企业，负责管理用户相关数据库。该企业用户数量庞大，每天产生海量数据。在用户表中，使用自增主键确保数据的唯一标识。为了关联用户表和用户行为表，设置了外键约束，保证数据的参照完整性。随着业务复杂度增加，查询需求多样化，他依据不同业务需求，在用户表的常用查询字段如“注册时间”“用户等级”上创建索引，显著提升了系统响应速度。&lt;/p&gt;
&lt;h2&gt;二、作用、为什么要学呢&lt;/h2&gt;
&lt;p&gt;学习 MySQL 的主键、外键和索引十分必要。&lt;/p&gt;
&lt;p&gt;从数据完整性看
主键能唯一标识表中每行数据，防止数据重复，确保数据准确。
外键可建立表间关联，保证数据参照完整性，避免出现孤立或错误关联的数据。&lt;/p&gt;
&lt;p&gt;从查询性能上
索引能加快数据查询速度。在海量数据中，如果没有索引，查询会全表扫描，效率极低。
合理创建索引后，数据库能快速定位到所需数据。&lt;/p&gt;
&lt;p&gt;在实际应用里
如电商系统、金融系统等，都离不开这些技术保障数据质量与系统性能。
掌握它们能让你更高效地管理和操作数据库，为项目稳定运行提供有力支持。&lt;/p&gt;
&lt;h2&gt;三、主键&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[主键外键索引]
        direction LR
        A[主键] --&amp;gt; B[外键] --&amp;gt; C[MySQL索引]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class A highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;主键使用规则：&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;表头值不允许重复，不允许赋NULL【nò】值&lt;/li&gt;
&lt;li&gt;一个表中只能有一个primary【普赖莫瑞】 key【kì】 表头&lt;/li&gt;
&lt;li&gt;多个表头做主键，称为复合主键，必须一起创建和删除&lt;/li&gt;
&lt;li&gt;主键标志PRI&lt;/li&gt;
&lt;li&gt;主键通常与auto_increment【奥特欧_因克瑞门特】连用&lt;/li&gt;
&lt;li&gt;通常把表中唯一标识记录的表头设置为主键[行号表]&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3.1 主键的创建、查看、删除、添加、验证主键&lt;/h3&gt;
&lt;h4&gt;创建表时创建主键&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//语法格式1
create【克瑞特】  table【忒-部】  库.表（ 表头名 数据类型  primary【普赖莫瑞】 key【kì】  , 表头名  数据类型 , ..... ）;

//建表
mysql&amp;gt;  create【克瑞特】 table【忒-部】 db1.t35(
    -&amp;gt; name char【查尔】(10) , 
    -&amp;gt; hz_id  char【查尔】(10) primary【普赖莫瑞】 key【kì】  , 
    -&amp;gt; class【克拉斯】 char【查尔】(10) 
    -&amp;gt; );
-- mysql&amp;gt; create table db1.t35(
--     -&amp;gt; name char(10),
--     -&amp;gt; hz_id char(10) primary key,
--     -&amp;gt; class char(10));
Query OK, 0 rows affected (0.49 sec)

//查看表头
mysql&amp;gt; desc db1.t35;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| name  | char(10) | YES  |     | NULL    |       |
| hz_id | char(10) | NO   | PRI | NULL    |       |
| class | char(10) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

//语法格式2
create【克瑞特】  table【忒-部】  库.表（ 字段名 类型 , 字段名 类型 , primary【普赖莫瑞】 key【kì】（字段名） ）;

//建表
mysql&amp;gt; create【克瑞特】 table【忒-部】 db1.t36(
    -&amp;gt; name char【查尔】(10) , 
    -&amp;gt; hz_id  char【查尔】(10) , 
    -&amp;gt; class【克拉斯】 char【查尔】(10),
    -&amp;gt; primary【普赖莫瑞】 key【kì】(hz_id)  
    -&amp;gt; );
-- mysql&amp;gt; create table db1.t36(
--     -&amp;gt; name char(10),
--     -&amp;gt; hz_id char(10),
--     -&amp;gt; class char(10),
--     -&amp;gt; primary key(hz_id));
Query OK, 0 rows affected (0.39 sec)

//查看表头
mysql&amp;gt; desc db1.t36;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| name  | char(10) | YES  |     | NULL    |       |
| hz_id | char(10) | NO   | PRI | NULL    |       |
| class | char(10) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;删除主键&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//删除主键命令格式
mysql&amp;gt; alter【奥-特】  table【忒-部】   库.表   drop【卓-普】 primary【普赖莫瑞】 key【kì】 ;

//例子
mysql&amp;gt;  alter【奥-特】  table【忒-部】 db1.t36  drop【卓-普】 primary【普赖莫瑞】 key【kì】 ;
-- mysql&amp;gt; alter table db1.t36 drop primary key;
Query OK, 0 rows affected (1.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

//查看表头
mysql&amp;gt; desc  db1.t36;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| name  | char(10) | YES  |     | NULL    |       |
| hz_id | char(10) | NO   |     | NULL    |       |
| class | char(10) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql&amp;gt; 

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;添加主键&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//添加主键命令格式
mysql&amp;gt; alter【奥-特】  table【忒-部】  库.表  add  primary【普赖莫瑞】 key【kì】(表头名);

//例子
mysql&amp;gt; alter【奥-特】  table【忒-部】  db1.t36  add  primary【普赖莫瑞】 key【kì】(hz_id);
-- mysql&amp;gt; alter table db1.t36 add primary key(hz_id);
mysql&amp;gt; desc db1.t36;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| name  | char(10) | YES  |     | NULL    |       |
| hz_id | char(10) | NO   | PRI | NULL    |       |
| class | char(10) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;验证主键约束&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//使用t35表 验证主键约束
//查看主键表头
mysql&amp;gt; desc db1.t35;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| name  | char(10) | YES  |     | NULL    |       |
| hz_id | char(10) | NO   | PRI | NULL    |       |
| class | char(10) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

-- 插入第1条记录 正常
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t35  values【挖柳斯】 (&quot;bob&quot;,&quot;888&quot;,&quot;nsd2107&quot;);
-- mysql&amp;gt; insert into db1.t35 values(&quot;bob&quot;,&quot;888&quot;,&quot;nsd2107&quot;);
Query OK, 1 row affected (0.05 sec)

-- 主键表头值不允许为null【nò】，否则插入失败
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t35  values【挖柳斯】 (&quot;john&quot;,null【nò】,&quot;nsd2107&quot;); 
-- mysql&amp;gt; insert into db1.t35 values(&quot;john&quot;,null,&quot;nsd2107&quot;);
ERROR 1048 (23000): Column &apos;hz_id&apos; cannot be null【nò】
mysql&amp;gt; 

-- 主键表头值不允许重复，否则插入失败
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t35  values【挖柳斯】 (&quot;john&quot;,&quot;888&quot;,&quot;nsd2107&quot;); 
-- mysql&amp;gt; insert into db1.t35 values(&quot;john&quot;,&quot;888&quot;,&quot;nsd2107&quot;);
ERROR 1062 (23000): Duplicate entry &apos;888&apos; for key【kì】 &apos;primary【普赖莫瑞】&apos;

-- 主键表头值不重复也不是null【nò】可以
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t35  values【挖柳斯】 (&quot;john&quot;,&quot;988&quot;,&quot;nsd2107&quot;); 
-- mysql&amp;gt; insert into db1.t35 values(&quot;john&quot;,&quot;988&quot;,&quot;nsd2107&quot;);
Query OK, 1 row affected (0.07 sec)

-- 查看表记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.t35 ;
-- mysql&amp;gt; select * from db1.t35;
+------+-------+---------+
| name | hz_id | class   |
+------+-------+---------+
| bob  | 888   | nsd2107 |
| john | 988   | nsd2107 |
+------+-------+---------+
2 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 复合主键的使用&lt;/h3&gt;
&lt;h4&gt;创建表时创建复合主键&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;-- 创建复合主键 表头依次是客户端ip 、服务端口号、访问状态
mysql&amp;gt; create【克瑞特】  table【忒-部】  db1.t39(
cip   varchar【瓦儿-查儿】(15) , 
port【破特】  smallint【斯莫尔因特】,  
status【s 塔丢】  enum【ing纽某】(&quot;deny【迪奈】&quot;,&quot;allow【饿劳】&quot;) , 
primary【普赖莫瑞】 key【kì】(cip,port【破特】)
);
-- mysql&amp;gt; create table db1.t39(
--     -&amp;gt; cip varchar(15),
--     -&amp;gt; port smallint,
--     -&amp;gt; status enum(&quot;deny&quot;,&quot;allow&quot;),
--     -&amp;gt; primary key(cip,port));

-- 插入记录验证
insert【因涩特】 into【因兔】  db1.t39  values【挖柳斯】 (&quot;1.1.1.1&quot;,22,&quot;deny【迪奈】&quot;);
-- mysql&amp;gt; insert into db1.t39 values(&quot;1.1.1.1&quot;,22,&quot;deny&quot;);
-- Query OK, 1 row affected (0.09 sec)

insert【因涩特】 into【因兔】  db1.t39  values【挖柳斯】 (&quot;1.1.1.1&quot;,22,&quot;deny【迪奈】&quot;); --两个复合主键相同报错
-- mysql&amp;gt; insert into db1.t39 values(&quot;1.1.1.1&quot;,22,&quot;deny&quot;);
-- ERROR 1062 (23000): Duplicate entry &apos;1.1.1.1-22&apos; for key &apos;t39.PRIMARY&apos;

insert【因涩特】 into【因兔】  db1.t39  values【挖柳斯】 (&quot;1.1.1.1&quot;,80,&quot;deny【迪奈】&quot;); -- 单个复合主键相同可以插入
-- mysql&amp;gt; insert into db1.t39 values(&quot;1.1.1.1&quot;,80,&quot;deny&quot;);
-- Query OK, 1 row affected (0.10 sec)

insert【因涩特】 into【因兔】  db1.t39  values【挖柳斯】 (&quot;2.1.1.1&quot;,80,&quot;allow【饿劳】&quot;); -- 单个复合主键相同可以插入
-- mysql&amp;gt; insert into db1.t39 values(&quot;2.1.1.1&quot;,80,&quot;allow&quot;);
-- Query OK, 1 row affected (0.10 sec)

-- 查看记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.t39;
-- mysql&amp;gt; select * from db1.t39;
+---------+------+--------+
| cip     | port | status |
+---------+------+--------+
| 1.1.1.1 |   22 | deny   |
| 1.1.1.1 |   80 | deny   |
| 2.1.1.1 |   80 | allow  |
+---------+------+--------+
3 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;删除复合主键&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//删除复合主键
mysql&amp;gt; alter【奥-特】 table【忒-部】  db1.t39 drop【卓-普】 primary【普赖莫瑞】 key【kì】;
-- mysql&amp;gt; alter table db1.t39 drop primary key;
Query OK, 3 rows affected (1.10 sec)
Records: 3  Duplicates: 0  Warnings: 0

//查看表头
mysql&amp;gt;  desc  db1.t39;
-- mysql&amp;gt; desc db1.t39; 
+--------+----------------------+------+-----+---------+-------+
| Field  | Type                 | Null | Key | Default | Extra |
+--------+----------------------+------+-----+---------+-------+
| cip    | varchar(15)          | NO   |     | NULL    |       |
| port   | smallint             | NO   |     | NULL    |       |
| status | enum(&apos;deny&apos;,&apos;allow&apos;) | YES  |     | NULL    |       |
+--------+----------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

//没有复合主键约束后 ，插入记录不受限制了
mysql&amp;gt;  insert【因涩特】 into【因兔】 db1.t39 values【挖柳斯】(&quot;2.1.1.1&quot;,80,&quot;allow【饿劳】&quot;);
-- mysql&amp;gt; insert into db1.t39 values(&quot;2.1.1.1&quot;,80,&quot;allow&quot;); 
Query OK, 1 row affected (0.06 sec)
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.t39 values【挖柳斯】(&quot;2.1.1.1&quot;,80,&quot;deny【迪奈】&quot;);
--mysql&amp;gt; insert into db1.t39 values(&quot;2.1.1.1&quot;,80,&quot;deny&quot;);  
Query OK, 1 row affected (0.08 sec)

//查看表记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】  db1.t39;
-- mysql&amp;gt; select * from db1.t39;
+---------+------+--------+
| cip     | port | status |
+---------+------+--------+
| 1.1.1.1 |   22 | deny   |
| 1.1.1.1 |   80 | deny   |
| 2.1.1.1 |   80 | allow  |
| 2.1.1.1 |   80 | allow  |
| 2.1.1.1 |   80 | deny   |
+---------+------+--------+
5 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;添加复合主键&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//添加复合主键时 字段下的数据与主键约束冲突 不允许添加
mysql&amp;gt; alter【奥-特】 table【忒-部】  db1.t39 add primary【普赖莫瑞】 key【kì】(cip,port【破特】);
-- mysql&amp;gt; alter table db1.t39 add primary key(cip,port); 
ERROR 1062 (23000): Duplicate entry &apos;2.1.1.1-80&apos; for key【kì】 &apos;t39.primary【普赖莫瑞】&apos;

//删除重复的数据
mysql&amp;gt; delete【迪  利 特】 from【弗乱】 db1.t39 where【威尔】 cip=&quot;2.1.1.1&quot;;
-- mysql&amp;gt; delete from db1.t39 where cip=&quot;2.1.1.1&quot;; 
Query OK, 3 rows affected (0.05 sec)

mysql&amp;gt; select【涩莱克特】  * from【弗乱】  db1.t39;
-- mysql&amp;gt; select * from db1.t39;
+---------+------+--------+
| cip     | port | status |
+---------+------+--------+
| 1.1.1.1 |   22 | deny   |
| 1.1.1.1 |   80 | deny   |
+---------+------+--------+
2 rows in set (0.00 sec)

//添加复合主键
mysql&amp;gt; alter【奥-特】 table【忒-部】  db1.t39 add primary【普赖莫瑞】 key【kì】(cip,port【破特】);
-- mysql&amp;gt; alter table db1.t39 add primary key(cip,port);
Query OK, 0 rows affected (0.67 sec)
Records: 0  Duplicates: 0  Warnings: 0

//查看表头
mysql&amp;gt;  desc  db1.t39;
-- mysql&amp;gt; desc db1.t39;
+--------+----------------------+------+-----+---------+-------+
| Field  | Type                 | Null | Key | Default | Extra |
+--------+----------------------+------+-----+---------+-------+
| cip    | varchar(15)          | NO   | PRI | NULL    |       |
| port   | smallint             | NO   | PRI | NULL    |       |
| status | enum(&apos;deny&apos;,&apos;allow&apos;) | YES  |     | NULL    |       |
+--------+----------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3  auto_increment【奥特欧_因克瑞门特】的使用&lt;/h3&gt;
&lt;p&gt;表头设置了auto_increment【奥特欧_因克瑞门特】属性后，&lt;/p&gt;
&lt;p&gt;插入记录时，如果不给表头赋值表头通过自加1的计算结果赋值&lt;/p&gt;
&lt;p&gt;要想让表头有自增长 表头必须有主键设置才可以&lt;/p&gt;
&lt;p&gt;查看表结构时 在 Extra【埃斯处了】 （额外设置） 位置显示&lt;/p&gt;
&lt;p&gt;建表时 创建有auto_increment【奥特欧_因克瑞门特】 属性的表头。实现的效果如下：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;行号&lt;/th&gt;
&lt;th&gt;姓名&lt;/th&gt;
&lt;th&gt;班级&lt;/th&gt;
&lt;th&gt;住址&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;bob&lt;/td&gt;
&lt;td&gt;nsd2107&lt;/td&gt;
&lt;td&gt;bj&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;bob&lt;/td&gt;
&lt;td&gt;nsd2107&lt;/td&gt;
&lt;td&gt;bj&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;bob&lt;/td&gt;
&lt;td&gt;nsd2107&lt;/td&gt;
&lt;td&gt;bj&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;bob&lt;/td&gt;
&lt;td&gt;nsd2107&lt;/td&gt;
&lt;td&gt;bj&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;1）建表&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】     table【忒-部】   db1.t38 (
    -&amp;gt; 行号   int【因特】   primary【普赖莫瑞】 key【kì】  auto_increment【奥特欧_因克瑞门特】, 
    -&amp;gt; 姓名   char【查尔】(10) , 
    -&amp;gt; 班级   char【查尔】(7) , 
    -&amp;gt; 住址   char【查尔】(10)
    -&amp;gt; );
-- mysql&amp;gt; create table db1.t38(
--     -&amp;gt; 行号 int primary key auto_increment,
--     -&amp;gt; 姓名 char(10),
--     -&amp;gt; 班级 char(7),
--     -&amp;gt; 住址 char(10));
Query OK, 0 rows affected (0.76 sec)

//查看表头
mysql&amp;gt; desc db1.t38 ;
-- mysql&amp;gt; desc db1.t38;
+--------+----------+------+-----+---------+----------------+
| Field  | Type     | Null | Key | Default | Extra          |
+--------+----------+------+-----+---------+----------------+
| 行号   | int      | NO   | PRI | NULL    | auto_increment |
| 姓名   | char(10) | YES  |     | NULL    |                |
| 班级   | char(7)  | YES  |     | NULL    |                |
| 住址   | char(10) | YES  |     | NULL    |                |
+--------+----------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

//插入表记录 不给自增长表头赋值
mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址)  values【挖柳斯】(&quot;bob&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;bob&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
Query OK, 1 row affected (0.05 sec)

mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;bob&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;bob&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
Query OK, 1 row affected (0.04 sec)

mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;tom&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;tom&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
Query OK, 1 row affected (0.05 sec)

//查看表记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.t38;
-- mysql&amp;gt; select * from db1.t38;
+--------+--------+---------+--------+
| 行号   | 姓名   | 班级    | 住址   |
+--------+--------+---------+--------+
|      1 | bob    | nsd2107 | bj     |
|      2 | bob    | nsd2107 | bj     |
|      3 | tom    | nsd2107 | bj     |
+--------+--------+---------+--------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;自增长使用注意事项&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//给自增长字段的赋值
mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(行号,姓名,班级,住址) values【挖柳斯】(5,&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);  
-- mysql&amp;gt; insert into db1.t38(行号,姓名,班级,住址) values(5,&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);  
Query OK, 1 row affected (0.26 sec)

//不赋值后 用最后1条件记录表头的值+1结果赋值
mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);  
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);  
Query OK, 1 row affected (0.03 sec)

//查看记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.t38 ;
-- mysql&amp;gt; select * from db1.t38;
+--------+--------+---------+--------+
| 行号   | 姓名   | 班级    | 住址   |
+--------+--------+---------+--------+
|      1 | bob    | nsd2107 | bj     |
|      2 | bob    | nsd2107 | bj     |
|      3 | tom    | nsd2107 | bj     |
|      5 | lucy   | nsd2107 | bj     |
|      6 | lucy   | nsd2107 | bj     |
+--------+--------+---------+--------+
5 rows in set (0.00 sec)

//删除所有行
mysql&amp;gt; delete【迪  利 特】  from【弗乱】  db1.t38 ； 
-- mysql&amp;gt; delete from db1.t38; 

//再添加行 继续行号 而不是从 1 开始 
mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);

mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);

mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);

//查看记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.t38;
-- mysql&amp;gt; select * from db1.t38;
+--------+--------+---------+--------+
| 行号   | 姓名   | 班级    | 住址   |
+--------+--------+---------+--------+
|      8 | lucy   | nsd2107 | bj     |
|      9 | lucy   | nsd2107 | bj     |
|     10 | lucy   | nsd2107 | bj     |
+--------+--------+---------+--------+
3 rows in set (0.01 sec)


-- truncate【创kí特】删除行，会同时重置auto_increment值为1开始
//truncate【创kí特】删除行 再添加行 从1开始 
mysql&amp;gt; truncate【创kí特】 table【忒-部】  db1.t38;  
-- mysql&amp;gt; truncate table db1.t38;
Query OK, 0 rows affected (2.66 sec)

//插入记录
mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
Query OK, 1 row affected (0.04 sec)

mysql&amp;gt; insert【因涩特】  into【因兔】  db1.t38(姓名,班级,住址) values【挖柳斯】(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;);
-- mysql&amp;gt; insert into db1.t38(姓名,班级,住址) values(&quot;lucy&quot;,&quot;nsd2107&quot;,&quot;bj&quot;); 
Query OK, 1 row affected (0.30 sec)

//查看记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.t38;
-- mysql&amp;gt; select * from db1.t38;
+--------+--------+---------+--------+
| 行号   | 姓名   | 班级    | 住址   |
+--------+--------+---------+--------+
|      1 | lucy   | nsd2107 | bj     |
|      2 | lucy   | nsd2107 | bj     |
+--------+--------+---------+--------+
2 rows in set (0.01 sec)
mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、外键&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[主键外键索引]
        direction LR
        A[主键] --&amp;gt; B[外键] --&amp;gt; C[MySQL索引]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class B highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;外键使用规则：&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;表存储引擎必须是innodb【伊诺 DB】&lt;/li&gt;
&lt;li&gt;表头数据类型要一致&lt;/li&gt;
&lt;li&gt;被参照表头必须要是索引类型的一种(primary【普赖莫瑞】 key【kì】)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;作用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;插入记录时，表头值在另一个表的表头值范围内选择。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.1 外键的创建、查看、删除、添加&lt;/h3&gt;
&lt;h4&gt;创建外键命令&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;create【克瑞特】 table【忒-部】   库.表(
表头列表 , 
foreign【佛润】 key【kì】(表头名)        #指定外键
references【略粉谁斯】 库.表(表头名)   #指定参考的表头名
on【昂】 update【阿普 dei 特】  cascade【卡斯kèi】         #同步更新
on【昂】  delete【迪  利 特】  cascade【卡斯kèi】        #同步删除
)engine【恩-京】=innodb【伊诺 DB】;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需求： 仅给公司里已经入职的员工发工资&lt;/p&gt;
&lt;p&gt;首先创建存储员工信息的员工表&lt;/p&gt;
&lt;p&gt;表名 yg&lt;/p&gt;
&lt;p&gt;员工编号 yg_id&lt;/p&gt;
&lt;p&gt;姓名 name&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#创建员工表
create【克瑞特】 table【忒-部】  db1.yg (
yg_id   int【因特】  primary【普赖莫瑞】 key【kì】  auto_increment【奥特欧_因克瑞门特】, 
name  char【查尔】(16) 
) engine【恩-京】=innodb【伊诺 DB】;
-- mysql&amp;gt; create table db1.yg (
--     -&amp;gt; yg_id int primary key auto_increment,
--     -&amp;gt; name char(16)
--     -&amp;gt; )engine=innodb;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建工资表&lt;/p&gt;
&lt;p&gt;表名 gz&lt;/p&gt;
&lt;p&gt;员工编号 gz_id&lt;/p&gt;
&lt;p&gt;工资 pay&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#创建工资表 指定外键表头
-- 语句一
mysql&amp;gt; create【克瑞特】 table【忒-部】 db1.gz(
  gz_id int【因特】 primary【普赖莫瑞】 key【kì】 auto_increment【奥特欧_因克瑞门特】,  -- 指定主键
  pay  float【弗洛特】,
foreign【佛润】 key【kì】(gz_id)  references【略粉谁斯】 db1.yg(yg_id)  -- 指定外键值为主键，即yg表的yg_id值为gz表的gz_id
on【昂】 update【阿普 dei 特】 cascade【卡斯kèi】                       -- 同步更新
on【昂】 delete【迪  利 特】 cascade【卡斯kèi】                         -- 同步删除
)engine【恩-京】=innodb【伊诺 DB】 ;                                   -- 指定存储引擎
-- mysql&amp;gt; create table db1.gz(
--     -&amp;gt; gz_id int primary key auto_increment,  
--     -&amp;gt; pay float,
--     -&amp;gt; foreign key(gz_id) references db1.yg(yg_id)
--     -&amp;gt; on update cascade
--     -&amp;gt; on delete cascade
--     -&amp;gt; )engine=innodb;


-- 语句二（推荐）
mysql&amp;gt; create【克瑞特】 table【忒-部】 db1.gz (
    -&amp;gt; gz_id int【因特】 primary【普赖莫瑞】 key【kì】 auto_increment【奥特欧_因克瑞门特】,  -- 指定主键
    -&amp;gt; pay float【弗洛特】, 
    -&amp;gt; yg_id int【因特】, 
    -&amp;gt; foreign【佛润】 key【kì】(yg_id) references【略粉谁斯】 db1.yg(yg_id)  -- 指定外键
    -&amp;gt; on【昂】 update【阿普 dei 特】 cascade【卡斯kèi】  -- 同步更新
    -&amp;gt; on【昂】 delete【迪  利 特】 cascade【卡斯kèi】-- 同步删除
    -&amp;gt; )engine【恩-京】=innodb【伊诺 DB】;  -- 指定存储引擎
-- mysql&amp;gt; create table db1.gz(
--     -&amp;gt; gz_id int primary key auto_increment,  
--     -&amp;gt; pay float,
--     -&amp;gt; yg_id int,
--     -&amp;gt; foreign key(yg_id) references db1.yg(yg_id)
--     -&amp;gt; on update cascade
--     -&amp;gt; on delete cascade
--     -&amp;gt; )engine=innodb;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;查看外键&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//查看工资表外键
mysql&amp;gt; show【瘦】 create【克瑞特】  table【忒-部】 db1.gz \G
-- mysql&amp;gt; show create table db1.gz \G
*************************** 1. row ***************************
       Table: gz
Create Table: CREATE TABLE `gz` (
  `gz_id` int NOT NULL AUTO_INCREMENT,
  `pay` float DEFAULT NULL,
  `yg_id` int DEFAULT NULL,
  PRIMARY KEY (`gz_id`),
  KEY `yg_id` (`yg_id`),
  CONSTRAINT `gz_ibfk_1` FOREIGN KEY (`yg_id`) REFERENCES `yg` (`yg_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.022 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;删除外键&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//删除外键
mysql&amp;gt; alter【奥-特】 table【忒-部】 db1.gz drop【卓-普】 FOREIGN【佛润】 KEY【kì】  gz_ibfk_1;
-- mysql&amp;gt; alter table db1.gz drop foreign key gz_ibfk_1;

-- 手动命名：在创建外键时，使用 CONSTRAINT关键字后面跟一个自定义的名称，例如 CONSTRAINT fk_student_class。这样做的好处是名称有意义，便于记忆和管理 
--             CREATE TABLE db1.gz(
--                 gz_id INT PRIMARY KEY AUTO_INCREMENT,  
--                 pay FLOAT,
--                 yg_id INT,
--                 CONSTRAINT fk_gz_yg_id                     -- 这里添加了显式的外键约束名
--                 FOREIGN KEY(yg_id) REFERENCES db1.yg(yg_id)
--                 ON UPDATE CASCADE
--                 ON DELETE CASCADE
--             ) ENGINE=InnoDB;

-- 自动生成：创建外键时没有指定名称（即省略了 CONSTRAINT [symbol]部分），MySQL 会自动生成一个约束名。自动生成的名称通常遵循 表名_ibfk_序号的规则 
-- 在MySQL中，当创建一个外键时，无论是手动命名还是系统自动生成，数据库都会为这个约束关系分配一个唯一的名称。这个名称就是外键约束的标识符。
-- 在MySQL中，外键约束的标识符是以表名和外键列名作为前缀，后跟一个下划线和一个数字作为后缀。

-- 在上面的示例中，外键约束的标识符是 gz_ibfk_1。
--  gz：这是您当前表（从表）的名字。
--  ibfk：这是 InnoDB 存储引擎为外键（InnoDB Foreign Key）生成的标识符，表示这是一个外键约束。
--  1：这是一个数字，表示这是该表中第一个外键约束,如果表中有多个外键，序号会依次递增（如 gz_ibfk_2, gz_ibfk_3）。

-- 可以使用 SHOW CREATE TABLE 语句来查看外键约束的标识符。


//查看不到外键
mysql&amp;gt; show【瘦】 create【克瑞特】  table【忒-部】 db1.gz \G
-- mysql&amp;gt; show create table db1.gz \G
*************************** 1. row ***************************
       Table: gz
Create Table: CREATE TABLE `gz` (
  `gz_id` int NOT NULL AUTO_INCREMENT,
  `pay` float DEFAULT NULL,
  `yg_id` int DEFAULT NULL,
  PRIMARY KEY (`gz_id`),
  KEY `yg_id` (`yg_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;添加外键&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//添加外键
mysql&amp;gt; alter【奥-特】 table【忒-部】 db1.gz 
add  foreign【佛润】 key【kì】(yg_id)  references【略粉谁斯】 db1.yg(yg_id)  
on【昂】 update【阿普 dei 特】 cascade【卡斯kèi】  on【昂】 delete【迪  利 特】 cascade【卡斯kèi】 ;
-- mysql&amp;gt; alter table db1.gz
--     -&amp;gt; add foreign key(yg_id) references db1.yg(yg_id) 
--     -&amp;gt; on update cascade on delete cascade;


//查看外键
mysql&amp;gt; show【瘦】 create【克瑞特】  table【忒-部】 db1.gz \G
-- mysql&amp;gt; show create table db1.gz \G
*************************** 1. row ***************************
       Table: gz
Create Table: CREATE TABLE `gz` (
  `gz_id` int NOT NULL AUTO_INCREMENT,
  `pay` float DEFAULT NULL,
  `yg_id` int DEFAULT NULL,
  PRIMARY KEY (`gz_id`),
  KEY `yg_id` (`yg_id`),
  CONSTRAINT `gz_ibfk_1` FOREIGN KEY (`yg_id`) REFERENCES `yg` (`yg_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 验证外键功能&lt;/h3&gt;
&lt;h4&gt;1)、外键字段的值必须在参考表字段值范围内&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;-- 员工表插入记录
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.yg (name) values【挖柳斯】 (&quot;jerry&quot;),(&quot;tom&quot;);
-- mysql&amp;gt; insert into db1.yg(name) values(&quot;jerry&quot;),(&quot;tom&quot;);
-- Query OK, 2 rows affected (0.15 sec)
-- Records: 2  Duplicates: 0  Warnings: 0

mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.yg;
-- mysql&amp;gt; select *from db1.yg;
-- +-------+-------+
-- | yg_id | name  |
-- +-------+-------+
-- |     1 | jerry |
-- |     2 | tom   |
-- +-------+-------+
-- 2 rows in set (0.00 sec)

-- 工资表插入记录
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.gz values【挖柳斯】(1,50000);
-- mysql&amp;gt; insert into db1.gz values(1,50000,1);
-- Query OK, 1 row affected (0.15 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 db1.gz values【挖柳斯】(2,60000);
-- mysql&amp;gt; insert into db1.gz values(2,50000,2);
-- Query OK, 1 row affected (0.16 sec)

mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.gz;
-- mysql&amp;gt; select * from db1.gz;
+-------+-------+-------+
| gz_id | pay   | yg_id |
+-------+-------+-------+
|     1 | 50000 |     1 |
|     2 | 50000 |     2 |
+-------+-------+-------+
2 rows in set (0.00 sec)

-- 没有的3号员工 工资表插入记录报错(因为yg表中没有3号员工数据，需要先插入3号员工数据)
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.gz values【挖柳斯】(3,50000);  
-- mysql&amp;gt; insert into db1.gz values(3,50000,3);
ERROR 1452 (23000): Cannot add or update【阿普 dei 特】 a child row: a foreign key【kì】 constraint fails (`db1`.`gz`, CONSTRAINT `gz_ibfk_1` FOREIGN KEY【kì】 (`gz_id`) REFERENCES【略粉谁斯】 `yg` (`yg_id`) ON【昂】 DELETE【迪  利 特】 CASCADE【卡斯kèi】 ON【昂】 UPDATE【阿普 dei 特】 CASCADE【卡斯kèi】)


-- 员工表 插入编号3的员工
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.yg (name) values【挖柳斯】 (&quot;Lucy&quot;); 
-- mysql&amp;gt; insert into db1.yg(name) values(&quot;Lucy&quot;);
-- Query OK, 1 row affected (0.14 sec)

mysql&amp;gt; select【涩莱克特】  * from【弗乱】  db1.yg;  
-- mysql&amp;gt; select * from yg;
-- +-------+-------+
-- | yg_id | name  |
-- +-------+-------+
-- |     1 | jerry |
-- |     2 | tom   |
-- |     3 | Lucy  |
-- +-------+-------+
-- 3 rows in set (0.00 sec)


-- 可以给3号员工 发工资了 
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.gz values【挖柳斯】(3,40000,3);
-- mysql&amp;gt; insert into db1.gz values(3,40000,3); 
-- Query OK, 1 row affected (0.12 sec) 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2)、验证同步更新&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;-- 查看员工表记录
mysql&amp;gt; select【涩莱克特】 * from【弗乱】 db1.yg;
-- mysql&amp;gt; select * from db1.yg;
+-------+-------+
| yg_id | name  |
+-------+-------+
|     1 | jerry |
|     2 | tom   |
|     3 | lucy  |
+-------+-------+
3 rows in set (0.00 sec)

-- 把yg表里编号是3的改成9 
mysql&amp;gt; update【阿普 dei 特】 db1.yg set yg_id=9 where【威尔】 yg_id=3;  
-- mysql&amp;gt; update db1.yg set yg_id=9 where yg_id=3;
-- Query OK, 1 row affected (0.17 sec)
-- Rows matched: 1  Changed: 1  Warnings: 0

mysql&amp;gt; select【涩莱克特】 * from【弗乱】 db1.yg;
-- mysql&amp;gt; select * from db1.yg;
+-------+-------+
| yg_id | name  |
+-------+-------+
|     1 | jerry |
|     2 | tom   |
|     9 | Lucy  |
+-------+-------+
3 rows in set (0.00 sec)

-- 工资表里编号是3的自动变成 9 
mysql&amp;gt; select【涩莱克特】 * from【弗乱】 db1.gz;
-- mysql&amp;gt; select * from db1.gz;
+-------+-------+-------+
| gz_id | pay   | yg_id |
+-------+-------+-------+
|     1 | 50000 |     1 |
|     2 | 50000 |     2 |
|     3 | 40000 |     9 |
+-------+-------+-------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3)、验证同步删除&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;-- 删除前查看员工表记录
mysql&amp;gt; select【涩莱克特】 * from【弗乱】 db1.yg;  
-- mysql&amp;gt; select * from db1.yg;
+-------+-------+
| yg_id | name  |
+-------+-------+
|     1 | jerry |
|     2 | tom   |
|     9 | Lucy  |
+-------+-------+
3 rows in set (0.00 sec)

-- 删除编号2的员工
mysql&amp;gt; delete【迪  利 特】 from【弗乱】 db1.yg where【威尔】 yg_id=2; 
-- mysql&amp;gt; delete from db1.yg where yg_id=2;
-- Query OK, 1 row affected (0.19 sec)


-- 删除后查看
mysql&amp;gt; select【涩莱克特】 * from【弗乱】 db1.yg; 
-- mysql&amp;gt; select * from db1.yg;
+-------+-------+
| yg_id | name  |
+-------+-------+
|     1 | jerry |
|     9 | Lucy  |
+-------+-------+
2 rows in set (0.00 sec)


-- 查看工资表也没有编号2的工资了
mysql&amp;gt; select【涩莱克特】 * from【弗乱】 db1.gz; 
-- mysql&amp;gt; select * from db1.gz;
+-------+-------+-------+
| gz_id | pay   | yg_id |
+-------+-------+-------+
|     1 | 50000 |     1 |
|     3 | 40000 |     9 |
+-------+-------+-------+
2 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4)、外键使用注意事项&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;-- 被参考的表不能删除
mysql&amp;gt; drop【卓-普】 table【忒-部】 db1.yg;
-- mysql&amp;gt; drop table db1.yg;  --因为db1.yg的yg_id表被db1.gz表的yg_id参考引用为外键，所以不能删除，只能先解除外键或者先删除gz表
ERROR 1217 (23000): Cannot delete【迪  利 特】 or update【阿普 dei 特】 a parent row: a foreign key【kì】 constraint fails
mysql&amp;gt; 



-- 给gz表的gz_id表头 加主键标签
-- 保证每个员工只能发1遍工资  且有员工编号的员工才能发工资
-- 如果重复发工资和没有编号的发了工资 删除记录后 再添加主键 
mysql&amp;gt; delete【迪  利 特】 form db1.gz;
-- mysql&amp;gt; delete from db1.gz;
-- Query OK, 2 rows affected (0.15 sec)

-- 删除主键
-- 先查看表头
mysql&amp;gt; desc db1.gz;
+-------+-------+------+-----+---------+----------------+
| Field | Type  | Null | Key | Default | Extra          |
+-------+-------+------+-----+---------+----------------+
| gz_id | int   | NO   | PRI | NULL    | auto_increment |
| pay   | float | YES  |     | NULL    |                |
| yg_id | int   | YES  | MUL | NULL    |                |
+-------+-------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

-- 删除auto_increment（一个列是auto_increment自增长，该列就必须定义为主键，所有要删除该主键必须先删除auto_increment属性）
mysql&amp;gt; alter table db1.gz modify gz_id int;
Query OK, 0 rows affected (2.83 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 再次查看表头属性（现在自增长属性已删除，可以开始删除主键了）
mysql&amp;gt; desc db1.gz;
+-------+-------+------+-----+---------+-------+
| Field | Type  | Null | Key | Default | Extra |
+-------+-------+------+-----+---------+-------+
| gz_id | int   | NO   | PRI | NULL    |       |
| pay   | float | YES  |     | NULL    |       |
| yg_id | int   | YES  | MUL | NULL    |       |
+-------+-------+------+-----+---------+-------+
3 rows in set (0.00 sec)

-- 删除主键
mysql&amp;gt; alter table db1.gz drop primary key;
Query OK, 0 rows affected (2.82 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 查看表头属性(已删除，没有PRI标识)
mysql&amp;gt; desc db1.gz;
+-------+-------+------+-----+---------+-------+
| Field | Type  | Null | Key | Default | Extra |
+-------+-------+------+-----+---------+-------+
| gz_id | int   | NO   |     | NULL    |       |
| pay   | float | YES  |     | NULL    |       |
| yg_id | int   | YES  | MUL | NULL    |       |
+-------+-------+------+-----+---------+-------+
3 rows in set (0.00 sec)

--添加主键
mysql&amp;gt; alter【奥-特】 table【忒-部】 db1.gz add primary【普赖莫瑞】 key【kì】(gz_id);
-- mysql&amp;gt; alter table db1.gz add primary key(gz_id);
Query OK, 0 rows affected (2.21 sec)
Records: 0  Duplicates: 0  Warnings: 0 

-- 查看表头属性
mysql&amp;gt; desc db1.gz;
+-------+-------+------+-----+---------+-------+
| Field | Type  | Null | Key | Default | Extra |
+-------+-------+------+-----+---------+-------+
| gz_id | int   | NO   | PRI | NULL    |       |
| pay   | float | YES  |     | NULL    |       |
| yg_id | int   | YES  | MUL | NULL    |       |
+-------+-------+------+-----+---------+-------+
3 rows in set (0.00 sec)

-- 添加auto_increment自增长属性
mysql&amp;gt; alter table db1.gz modify gz_id int auto_increment;
Query OK, 0 rows affected (2.75 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 查看表头属性
mysql&amp;gt; desc db1.gz;
+-------+-------+------+-----+---------+----------------+
| Field | Type  | Null | Key | Default | Extra          |
+-------+-------+------+-----+---------+----------------+
| gz_id | int   | NO   | PRI | NULL    | auto_increment |
| pay   | float | YES  |     | NULL    |                |
| yg_id | int   | YES  | MUL | NULL    |                |
+-------+-------+------+-----+---------+----------------+
3 rows in set (0.00 sec)




-- 保证每个员工只能发1遍工资  且有员工编号的员工才能发工资
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.gz values【挖柳斯】 (1,53000);  报错
-- mysql&amp;gt; insert into db1.gz values(1,53000);
-- ERROR 1136 (21S01): Column count doesn&apos;t match value count at row 1


mysql&amp;gt; insert into db1.gz values(1,53000,9);
Query OK, 1 row affected (0.19 sec)

mysql&amp;gt; select * from gz;
+-------+-------+-------+
| gz_id | pay   | yg_id |
+-------+-------+-------+
|     1 | 53000 |     9 |
+-------+-------+-------+
Query OK, 1 row affected (0.10 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 db1.gz values【挖柳斯】 (NULL【nò】,53000,2); 报错
-- mysql&amp;gt; insert into db1.gz values(NULL,53000,2);        -- 主键值不能为空
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`db1`.`gz`, CONSTRAINT `gz_ibfk_1` FOREIGN KEY (`yg_id`) REFERENCES `yg` (`yg_id`) ON DELETE CASCADE ON UPDATE CASCADE)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、MySQL索引&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[主键外键索引]
        direction LR
        A[主键] --&amp;gt; B[外键] --&amp;gt; C[MySQL索引]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class C highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;使用规则：&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;一个表中可以有多个index【因戴克斯】&lt;/li&gt;
&lt;li&gt;任何数据类型的表头都可以设置索引&lt;/li&gt;
&lt;li&gt;表头值可以重复，也可以赋NULL【nò】值&lt;/li&gt;
&lt;li&gt;通常在where【威尔】条件中的表头上设置Index【因戴克斯】&lt;/li&gt;
&lt;li&gt;index【因戴克斯】索引标志MUL&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;主键和唯一索引和普通索引的区别&lt;/h3&gt;
&lt;p&gt;主键和唯一索引是数据库设计中两个核心但易混淆的概念。下面这个表格能帮你快速把握它们的核心区别。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性维度&lt;/th&gt;
&lt;th&gt;主键 (&lt;code&gt;PRIMARY KEY&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;外键 (&lt;code&gt;FOREIGN KEY&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;唯一索引 (&lt;code&gt;UNIQUE INDEX&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;普通索引 (&lt;code&gt;INDEX&lt;/code&gt;)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;本质&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;约束，用于唯一标识每条记录&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;引用约束&lt;/strong&gt;，用于建立和加强表间的数据关联&lt;/td&gt;
&lt;td&gt;索引，附带唯一性保证&lt;/td&gt;
&lt;td&gt;最基本的索引类型，没有唯一性约束&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;数量限制&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一个表&lt;strong&gt;只能有一个&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一个表&lt;strong&gt;可以有多个&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一个表&lt;strong&gt;可以有多个&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一个表&lt;strong&gt;可以有多个&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;空值处理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;不允许&lt;/strong&gt;为 &lt;code&gt;NULL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;允许&lt;/strong&gt;为 &lt;code&gt;NULL&lt;/code&gt;，表示该记录无关联记录&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;允许&lt;/strong&gt;为 &lt;code&gt;NULL&lt;/code&gt;，且可包含多个 &lt;code&gt;NULL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;允许&lt;/strong&gt;出现重复值和空值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;核心功能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;唯一标识&lt;/strong&gt;表中的每一行记录，保证实体完整性&lt;/td&gt;
&lt;td&gt;维护&lt;strong&gt;引用完整性&lt;/strong&gt;，确保值必须在另一表的主键中存在&lt;/td&gt;
&lt;td&gt;确保&lt;strong&gt;索引列的数据唯一&lt;/strong&gt;，防止重复&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;加速查询&lt;/strong&gt;，提高查询效率，不做任何约束&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;外键引用&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;可以被&lt;/strong&gt;其他表的外键引用&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;定义表间关系&lt;/strong&gt;（如一对多），外键是另一表主键的引用&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;不可以&lt;/strong&gt;直接作为外键引用目标&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;不可以&lt;/strong&gt;直接作为外键引用目标&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;核心语句&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ALTER TABLE 表名 ADD PRIMARY KEY (字段);&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ALTER TABLE 从表 ADD FOREIGN KEY (外键字段) REFERENCES 主表(主键字段);&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ALTER TABLE 表名 ADD UNIQUE [索引名] (字段);&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ALTER TABLE 表名 ADD INDEX [索引名] (字段);&lt;/code&gt; 或 &lt;code&gt;CREATE INDEX 索引名 ON 表名 (字段);&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;核心内涵与进阶理解&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主键：数据存储的基石&lt;/strong&gt;
“主键还充当聚簇索引”非常关键。在InnoDB存储引擎中，表数据本身就是按主键顺序组织存储的。这使得主键查询极快，但同时也意味着如果主键值是随机的（如UUID），可能导致频繁的页分裂，影响插入性能并产生碎片。因此，使用与业务无关的&lt;strong&gt;自增主键&lt;/strong&gt;往往是性能最佳实践。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;外键：表间关系的纽带与数据一致性的守护者&lt;/strong&gt;
外键的本质是一个&lt;strong&gt;约束&lt;/strong&gt;，它通过强制要求子表（从表）中的外键字段值必须存在于主表（被引用表）的主键中，来维护&lt;strong&gt;参照完整性&lt;/strong&gt;。这有效防止了“孤立数据”的产生，例如，确保了不会有一条订单记录指向一个不存在的客户ID。外键关系通常用于实现“一对多”的关联，例如，一个客户（主表）可以拥有多个订单（子表）。
在实现上，定义外键时通常可以指定&lt;strong&gt;级联操作&lt;/strong&gt;（如 &lt;code&gt;ON DELETE CASCADE&lt;/code&gt; 或 &lt;code&gt;ON UPDATE SET NULL&lt;/code&gt;），这允许在主表数据变更时自动处理子表中的关联数据，但使用时需谨慎，以免导致非预期的数据修改。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;唯一索引：业务规则的守护者&lt;/strong&gt;
它的强大之处在于将业务唯一性要求（如“手机号不可重复”）固化在数据库层，从根源上防止了脏数据的产生。与主键不同，一个表可以有多个唯一索引，为多个业务字段提供唯一性保障。它也可以是&lt;strong&gt;复合索引&lt;/strong&gt;（多列组合），确保几个字段的组合值唯一，例如防止同一用户对同一商品重复评论 &lt;code&gt;(user_id, product_id)&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;普通索引：纯粹的查询加速器&lt;/strong&gt;
它唯一的目标就是“快”。其核心价值在于&lt;strong&gt;大幅减少磁盘I/O&lt;/strong&gt;，通过索引数据结构（如B+Tree）快速定位数据，避免全表扫描。创建普通索引时，应考虑字段的“&lt;strong&gt;区分度&lt;/strong&gt;”（选择性），即不重复值的比例。区分度越高，索引筛选效率越好。像“性别”这种区分度很低的字段创建索引意义不大。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;创建唯一索引&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;-- 语法一
mysql&amp;gt; alter table db1.customers add unique index email_index(email);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 语法二
mysql&amp;gt; alter table db1.customers add unique (email); 
Query OK, 0 rows affected (4.387 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 建表时创建
 CREATE TABLE 库.表 (
  id INT, 
  表头名 VARCHAR(255), 
  ..., 
  UNIQUE INDEX 索引名 (表头名)
  );
-- 或 
 CREATE TABLE 库.表 (
  id INT, 
  表头名 VARCHAR(255) 
  UNIQUE, ...);

-- 为已存在表添加
  ALTER TABLE 库.表 ADD UNIQUE INDEX 索引名 (表头名);
-- 或 
  ALTER TABLE 库.表 ADD UNIQUE (表头名);
--或 
  CREATE UNIQUE INDEX 索引名 ON 库.表 (表头名);

-- 删除唯一索引
  DROP INDEX 索引名 ON 库.表;
-- 或
  ALTER TABLE 库.表 DROP INDEX 索引名;

-- 修改唯一索引
-- MySQL 不直接支持修改索引。通常需要先删除旧索引，再添加新索引。
-- 例如，先 
  DROP INDEX 旧索引名 ON 库.表;
--   再 
  CREATE UNIQUE INDEX 新索引名 ON 库.表 (表头名);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.1 索引的创建、查看、删除、添加&lt;/h3&gt;
&lt;h4&gt;1)建表时创建索引命令格式&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;CREATE【克瑞特】 TABLE【忒-部】  库.表(
字段列表 ,
INDEX【因戴克斯】(字段名) ,
INDEX【因戴克斯】(字段名) 
);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Create【克瑞特】 database  home;
Use home;
CREATE【克瑞特】 TABLE【忒-部】 tea4(
id char【查尔】(6),
name varchar【瓦儿-查儿】(6),
age int(3),
gender enum【ing纽某】(&apos;boy&apos;,&apos;girl&apos;) DEFAULT【迪-佛特】 &apos;boy&apos;,
INDEX【因戴克斯】(id),INDEX【因戴克斯】(name)
);
-- mysql&amp;gt; create database home;
-- Query OK, 1 row affected (0.17 sec)

-- mysql&amp;gt; use home;
-- Database changed
-- mysql&amp;gt; create table tea4(
--     -&amp;gt; id char(6),
--     -&amp;gt; name varchar(6),
--     -&amp;gt; age int(3),
--     -&amp;gt; gender enum(&apos;boy&apos;,&apos;girl&apos;) default &apos;boy&apos;,
--     -&amp;gt; index(id),index(name));-- 创建名为 `id`和`name` 的普通索引
-- Query OK, 0 rows affected, 1 warning (1.70 sec)

-- mysql&amp;gt; desc tea4;
-- +--------+--------------------+------+-----+---------+-------+
-- | Field  | Type               | Null | Key | Default | Extra |
-- +--------+--------------------+------+-----+---------+-------+
-- | id     | char(6)            | YES  | MUL | NULL    |       |
-- | name   | varchar(6)         | YES  | MUL | NULL    |       |
-- | age    | int                | YES  |     | NULL    |       |
-- | gender | enum(&apos;boy&apos;,&apos;girl&apos;) | YES  |     | boy     |       |
-- +--------+--------------------+------+-----+---------+-------+
-- 4 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2）查看索引&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;des  库.表；
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; desc home.tea4;
+--------+--------------------+------+-----+---------+-------+
| Field  | Type               | Null | Key | Default | Extra |
+--------+--------------------+------+-----+---------+-------+
| id     | char(6)            | YES   | MUL | NULL    |       |
| name   | varchar(6)         | YES  | MUL | NULL    |       |
| age    | int(3)              | YES |     | NULL    |       |
| gender | enum(&apos;boy&apos;,&apos;girl&apos;) | YES  |     | boy     |       |
+--------+--------------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

mysql&amp;gt; system ls /var/lib/mysql/home/tea4.ibd  保存排队信息的文件
/var/lib/mysql/home/tea4.ibd
mysql&amp;gt;


&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3）查看索引详细信息&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;show【瘦】 index【因戴克斯】   from【弗乱】   库.表； 
-- mysql&amp;gt; show index from home.tea4;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| tea4  |          1 | id       |            1 | id          | A         |           0 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tea4  |          1 | name     |            1 | name        | A         |           0 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
2 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;show【瘦】  index【因戴克斯】   from【弗乱】  home.tea4 \G
-- mysql&amp;gt; show index from home.tea4 \G
*************************** 1. row ***************************
        Table: tea4         -- 表名
   Non_unique: 1
     Key_name: id           -- 索引名   （默认索引名和表头名相同，删除索引时，使用的索引名）
 Seq_in_index: 1
  Column_name: id           -- 表头名
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE        -- 索引类型
      Comment: 
Index_comment: 
*************************** 2. row ***************************
        Table: tea4         -- 表名
   Non_unique: 1
     Key_name: name         -- 索引名
 Seq_in_index: 1
  Column_name: name         -- 表头名
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE        -- 排队算法
      Comment: 
Index_comment: 
2 rows in set (0.00 sec)
mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4）删除索引&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;命令格式   DROP【卓-普】  INDEX【因戴克斯】   索引名   ON【昂】  库.表；
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; drop【卓-普】 index【因戴克斯】 id on【昂】 home.tea4 ;
-- mysql&amp;gt; drop index id on home.tea4;
-- Query OK, 0 rows affected (0.48 sec)
-- Records: 0  Duplicates: 0  Warnings: 0

mysql&amp;gt; desc  home.tea4;
-- mysql&amp;gt; desc home.tea4;
+--------+--------------------+------+-----+---------+-------+
| Field  | Type               | Null | Key | Default | Extra |
+--------+--------------------+------+-----+---------+-------+
| id     | char(6)            | YES   |     | NULL    |       |
| name   | varchar(6)         | YES  | MUL | NULL    |       |
| age    | int(3)             | YES |     | NULL    |       |
| gender | enum(&apos;boy&apos;,&apos;girl&apos;) | YES  |     | boy     |       |
+--------+--------------------+------+-----+---------+-------+
4 rows in set (0.14 sec)

mysql&amp;gt; show【瘦】  index【因戴克斯】   from【弗乱】  home.tea4 \G
-- mysql&amp;gt; show index from home.tea4 \G
*************************** 1. row ***************************
        Table: tea4
   Non_unique: 1
     Key_name: name
 Seq_in_index: 1
  Column_name: name
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
1 row in set (0.00 sec)
mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;5）已有表添加索引命令&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;CREATE【克瑞特】  INDEX【因戴克斯】  索引名  ON【昂】  库.表(字段名)；
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】  index【因戴克斯】 nianling on【昂】 home.tea4(age);
-- mysql&amp;gt; create index nianling on home.tea4(age);    -- 给age创建一个索引，索引命令为&quot;nianling&quot;
-- Query OK, 0 rows affected (0.50 sec)
-- Records: 0  Duplicates: 0  Warnings: 0

mysql&amp;gt; desc home.tea4;
+--------+--------------------+------+-----+---------+-------+
| Field  | Type               | Null | Key | Default | Extra |
+--------+--------------------+------+-----+---------+-------+
| id     | char(6)            | YES   |     | NULL    |       |
| name   | varchar(6)         | YES  | MUL | NULL    |       |
| age    | int(3)             | YES | MUL | NULL    |       |
| gender | enum(&apos;boy&apos;,&apos;girl&apos;) | YES  |     | boy     |       |
+--------+--------------------+------+-----+---------+-------+
4 rows in set (0.00 sec)



mysql&amp;gt; show【瘦】 create【克瑞特】 table【忒-部】 home.tea4 \G
-- mysql&amp;gt; show create table home.tea4 \G
*************************** 1. row ***************************
       Table: tea4
Create Table: CREATE TABLE `tea4` (
  `id` char(6) DEFAULT NULL,
  `name` varchar(6) DEFAULT NULL,
  `age` int DEFAULT NULL,
  `gender` enum(&apos;boy&apos;,&apos;girl&apos;) DEFAULT &apos;boy&apos;,
  KEY `name` (`name`),
  KEY `nianling` (`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

mysql&amp;gt; show【瘦】 index【因戴克斯】 from【弗乱】 home.tea4;
mysql&amp;gt; show index from home.tea4;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| tea4  |          1 | name     |            1 | name        | A         |           0 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tea4  |          1 | nianling |            1 | age         | A         |           0 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
2 rows in set (0.07 sec)

mysql&amp;gt; show【瘦】  index【因戴克斯】   from【弗乱】  home.tea4 \G
-- mysql&amp;gt; show index from home.tea4 \G
*************************** 1. row ***************************
        Table: tea4
   Non_unique: 1
     Key_name: name
 Seq_in_index: 1
  Column_name: name
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
*************************** 2. row ***************************
        Table: tea4
   Non_unique: 1
     Key_name: nianling       -- 设置的索引名
 Seq_in_index: 1
  Column_name: age            -- 表头名
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
2 rows in set (0.00 sec)
mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;6）验证索引&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; explain【e 斯 波 类】 select【涩莱克特】  * from【弗乱】 moershi.user where【威尔】 name=&quot;sshd&quot; \G
-- mysql&amp;gt; explain select * from moershi.user where name=&quot;sshd&quot; \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: user         -- 表名
   partitions: NULL
         type: ref
possible_keys: name
          key: name         -- 使用的索引名
      key_len: 21
          ref: const
         rows: 1            -- 查找的总行数
     filtered: 100.00
        Extra: NULL         -- 额外说明
1 row in set, 1 warning (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、作业&lt;/h2&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;以下关于主键的描述，正确的是（ C ）
A. 一个表可以有多个主键
B. 主键的值可以为 NULL
C. 主键用于唯一标识表中的每一行记录
D. 主键只能由一个字段组成&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;主键的核心作用是
  唯一标识表中的每一行记录
  一个表只能有一个主键（不论是单字段还是多字段联合主键），
  且主键值不可重复、不可为NULL
  主键可以由多个字段组成（联合主键）
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;外键的作用是（ B ）
A. 保证表中数据的唯一性
B. 建立表与表之间的关联
C. 提高数据的查询速度
D. 对数据进行加密&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;外键的主要作用是
  建立并维护表与表之间的关联关系
  从而保证数据的参照完整性，防止产生“孤立数据”。
  保证数据唯一性是主键或唯一约束的作用
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;以下哪种情况适合创建索引（ C ）
A. 经常进行更新操作的字段
B. 数据量很小的表
C. 经常作为查询条件的字段
D. 很少使用的字段&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;为频繁作为查询条件（WHERE子句） 的字段创建索引，可以显著提高查询速度。
而经常更新的字段、数据量小的表或很少使用的字段创建索引，可能无法带来性能提升，反而增加维护开销
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;在 MySQL 中，创建主键的关键字是（ B ）
A. PRIMARY
B. PRIMARY KEY
C. UNIQUE
D. FOREIGN KEY&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;在MySQL中，定义主键的语法关键字是 PRIMARY KEY
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;若要删除表中的外键约束，应使用的关键字是（ A ）
A. DROP FOREIGN KEY
B. DELETE FOREIGN KEY
C. REMOVE FOREIGN KEY
D. ALTER FOREIGN KEY&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;删除外键约束需要使用 ALTER TABLE 库.表 DROP FOREIGN KEY(表头名);语句，后接具体的外键约束名
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;简述主键和唯一索引的区别。
答：
主键：
是一种约束，用于唯一标识每条记录，可以作为外键的引用。一个表只能有一个主键（但可以是复合主键），主键值不可重复、不可为NULL。&lt;/p&gt;
&lt;p&gt;唯一索引：
是一种索引，附带唯一性保证，用于确保索引列的数据唯一。一个表可以有多个唯一索引，也可以作为外键的引用（只要它满足唯一性）。唯一索引允许NULL值，并且可以包含多个NULL（但具体取决于数据库系统，如MySQL中唯一索引允许多个NULL）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;说明外键约束在数据库设计中的重要性。
答：
外键约束通过强制要求子表（从表）中的外键字段值必须存在于主表（被引用表）的主键中，来维护&lt;strong&gt;参照完整性&lt;/strong&gt;，这有效防止了&quot;孤立数据&quot;的产生。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;索引在什么情况下会失效？如何避免索引失效？
答：
索引在以下情况下会失效：
索引在以下情况下会失效（针对WHERE条件）：
查询条件中使用了函数或表达式，如 WHERE YEAR(date_column) = 2020。
查询条件中使用了通配符（以%开头），如 WHERE name LIKE &apos;%John%&apos;。
查询条件中使用了不等于操作符（如 !=或 &amp;lt;&amp;gt;），但如果是覆盖索引可能有效。
数据类型隐式转换（如字符串列与数字比较）。
OR条件连接多个索引列（如果未优化）。&lt;/p&gt;
&lt;p&gt;为了避免索引失效，可以采取以下措施：
避免在查询条件中使用函数或表达式，尽量使用索引列原始值。
尽量使用等值查询，避免通配符开头；如果必须用LIKE，尝试用前缀匹配（如 LIKE &apos;John%&apos;）。
确保ORDER BY或GROUP BY的列上有索引，以利用索引排序。
使用覆盖索引（索引包含所有查询字段）来优化不等于查询。
避免数据类型转换，确保比较时类型一致。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3 操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;创建一个名为 &lt;code&gt;customers&lt;/code&gt; 的表，包含 &lt;code&gt;customer_id&lt;/code&gt;（作为主键）、&lt;code&gt;customer_name&lt;/code&gt;、&lt;code&gt;email&lt;/code&gt; 字段。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create table db1.customers (
    -&amp;gt; customer_id int primary key auto_increment,
    -&amp;gt; customer_name char(10),
    -&amp;gt; email varchar(255)
    -&amp;gt; )engine=innodb;
Query OK, 0 rows affected (1.44 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;创建一个 &lt;code&gt;orders&lt;/code&gt; 表，包含 &lt;code&gt;order_id&lt;/code&gt;、&lt;code&gt;customer_id&lt;/code&gt;（作为外键关联 &lt;code&gt;customers&lt;/code&gt; 表的 &lt;code&gt;customer_id&lt;/code&gt;）、&lt;code&gt;order_date&lt;/code&gt; 字段。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create table db1.orders (
    -&amp;gt; order_id int primary key auto_increment,
    -&amp;gt; customer_id int,
    -&amp;gt; order_date datetime,
    -&amp;gt; foreign key (customer_id) references customers(customer_id)
    -&amp;gt; )engine=innodb;
Query OK, 0 rows affected (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;在 &lt;code&gt;customers&lt;/code&gt; 表的 &lt;code&gt;email&lt;/code&gt; 字段上创建一个唯一索引。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; 
mysql&amp;gt; alter table db1.customers add unique (email); 
Query OK, 0 rows affected (4.387 sec)
Records: 0  Duplicates: 0  Warnings: 0
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;修改 &lt;code&gt;orders&lt;/code&gt; 表，添加一个新的外键约束，关联 &lt;code&gt;products&lt;/code&gt; 表（假设 &lt;code&gt;products&lt;/code&gt; 表已存在，有 &lt;code&gt;product_id&lt;/code&gt; 字段）。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;-- 添加product_id字段
mysql&amp;gt; alter table db1.orders add product_id int;
Query OK, 0 rows affected (5.441 sec)
Records: 0  Duplicates: 0  Warnings: 0
-- 创建product表
mysql&amp;gt; create table db1.products(
    -&amp;gt; product_id int primary key auto_increment
    -&amp;gt; )engine=innodb;
Query OK, 0 rows affected (0.689 sec)
-- 添加外键约束
mysql&amp;gt; alter table db1.orders
    -&amp;gt; add foreign key(product_id) references db1.products(product_id)
    -&amp;gt; on update cascade;
Query OK, 0 rows affected (2.100 sec)
Records: 0  Duplicates: 0  Warnings: 0
-- 查看orders表
mysql&amp;gt; show create table db1.orders \G
*************************** 1. row ***************************
       Table: orders
Create Table: CREATE TABLE `orders` (
  `order_id` int NOT NULL AUTO_INCREMENT,
  `customer_id` int DEFAULT NULL,
  `order_date` datetime DEFAULT NULL,
  `product_id` int DEFAULT NULL,
  PRIMARY KEY (`order_id`),
  KEY `customer_id` (`customer_id`),
  KEY `product_id` (`product_id`),
  CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`customer_id`),
  CONSTRAINT `orders_ibfk_2` FOREIGN KEY (`product_id`) REFERENCES `products` (`product_id`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.065 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;删除 &lt;code&gt;customers&lt;/code&gt; 表上的索引。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;-- 查看`customers` 表索引
mysql&amp;gt; show index from db1.customers;
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table     | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| customers |          0 | PRIMARY  |            1 | customer_id | A         |           0 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| customers |          0 | email    |            1 | email       | A         |           0 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
2 rows in set (1.751 sec)
-- 删除email唯一索引
mysql&amp;gt; alter table db1.customers drop index email;
Query OK, 0 rows affected (2.905 sec)
Records: 0  Duplicates: 0  Warnings: 0
-- 查看`customers` 表索引
mysql&amp;gt; show index from db1.customers;
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table     | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| customers |          0 | PRIMARY  |            1 | customer_id | A         |           0 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
1 row in set (0.256 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;删除 &lt;code&gt;orders&lt;/code&gt; 表上的索引。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 查看外键属性
mysql&amp;gt; show create table db1.orders \G    
*************************** 1. row ***************************
       Table: orders
Create Table: CREATE TABLE `orders` (
  `order_id` int NOT NULL AUTO_INCREMENT,
  `customer_id` int DEFAULT NULL,
  `order_date` datetime DEFAULT NULL,
  `product_id` int DEFAULT NULL,
  PRIMARY KEY (`order_id`),
  KEY `customer_id` (`customer_id`),
  KEY `product_id` (`product_id`),
  CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`customer_id`),
  CONSTRAINT `orders_ibfk_2` FOREIGN KEY (`product_id`) REFERENCES `products` (`product_id`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (1.279 sec)

-- 删除外键orders_ibfk_1
mysql&amp;gt; alter table db1.orders drop foreign key orders_ibfk_1;
Query OK, 0 rows affected (1.222 sec)
Records: 0  Duplicates: 0  Warnings: 0
-- 删除外键orders_ibfk_2
mysql&amp;gt; alter table db1.orders drop foreign key orders_ibfk_2; 
Query OK, 0 rows affected (0.342 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 查看索引名
mysql&amp;gt; show index from db1.orders;
+--------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table  | Non_unique | Key_name    | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+--------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| orders |          0 | PRIMARY     |            1 | order_id    | A         |           0 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| orders |          1 | product_id  |            1 | product_id  | A         |           0 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| orders |          1 | customer_id |            1 | customer_id | A         |           0 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
+--------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
3 rows in set (1.037 sec)

-- 删除索引 product_id
mysql&amp;gt; drop index product_id on db1.orders;
Query OK, 0 rows affected (1.191 sec)
Records: 0  Duplicates: 0  Warnings: 0
-- 删除索引 customer_id
mysql&amp;gt; drop index customer_id on db1.orders; 
Query OK, 0 rows affected (0.326 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 查看索引属性
mysql&amp;gt; show index from db1.orders;           
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table  | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| orders |          0 | PRIMARY  |            1 | order_id    | A         |           0 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
1 row in set (0.392 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;07 mysql之数据导入导出与用户管理&lt;/h1&gt;
&lt;p&gt;今天工作任务路线图&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[数据导入导出与用户管理]
        direction LR
        A[数据导入导出] --&amp;gt; B[用户管理]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class E highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;小李是一家电商公司的数据库管理员。最近公司要对业务系统进行升级，需要将旧数据库中的商品信息、订单记录等数据迁移到新数据库，这就需要他运用数据导出与导入功能。小李使用 &lt;code&gt;SELECT【涩莱克特】 ... INTO【因兔】 OUTFILE【奥特-伐尔】&lt;/code&gt; 语句把旧数据库的数据导出到文件，再用 &lt;code&gt;LOAD【漏德】 DATA INFILE【因-伐尔】&lt;/code&gt; 语句将数据导入新数据库，保证数据完整迁移。&lt;/p&gt;
&lt;p&gt;同时，公司业务拓展后新成立了营销和客服部门，需要为这些新员工创建数据库账户。小李使用 &lt;code&gt;CREATE【克瑞特】 USER&lt;/code&gt; 语句创建用户，用 &lt;code&gt;grant【古亮普】&lt;/code&gt; 语句根据岗位需求赋予不同权限，确保数据的安全性和员工操作的规范性。&lt;/p&gt;
&lt;h2&gt;二、为什么学呢&lt;/h2&gt;
&lt;p&gt;学习 MySQL 数据导入导出与用户管理具有很强的现实意义。在数据迁移场景中，当公司更换数据库系统或升级服务器时，掌握数据导入导出技能，能确保数据完整、准确地从旧环境过渡到新环境，避免业务中断。比如电商平台促销活动前后，要灵活调整数据存储。&lt;/p&gt;
&lt;p&gt;在数据共享方面，可与合作伙伴安全、高效地交换数据。而用户管理是数据库安全的关键，合理设置用户权限，能防止未经授权的访问和数据泄露，保护公司核心数据。掌握这些技能，可提升数据库管理能力，为企业的稳定运行保驾护航，也增强个人在职场上的竞争力。&lt;/p&gt;
&lt;h2&gt;三、数据导入导出&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[数据导入导出与用户管理]
        direction LR
        A[数据导入导出] --&amp;gt; B[用户管理]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class A highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;secure【瑟Q儿】_file【伐尔】_priv【破略夫】&lt;/code&gt; 是 MySQL 中的一个系统变量，主要用于控制数据导入和导出操作的安全性。下面为你详细介绍：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;它限定了 MySQL 服务器在执行数据导入（&lt;code&gt;LOAD【漏德】 DATA INFILE【因-伐尔】&lt;/code&gt;）和导出（&lt;code&gt;SELECT【涩莱克特】 ... INTO【因兔】 OUTFILE【奥特-伐尔】&lt;/code&gt;）操作时，可以访问的文件路径。通过设置该变量，可以防止 MySQL 服务器随意访问系统上的文件，从而增强系统的安全性，避免潜在的文件访问风险。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;查看与修改&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;查看&lt;/strong&gt;：可以使用 &lt;code&gt;SHOW【瘦】 VARIABLES【wèi 利 bóu 斯】 LIKE【赖特】 &apos;secure【瑟Q儿】_file【伐尔】_priv【破略夫】&apos;;&lt;/code&gt; 语句查看当前 &lt;code&gt;secure【瑟Q儿】_file【伐尔】_priv【破略夫】&lt;/code&gt; 的值。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;修改&lt;/strong&gt;：要修改该变量的值，需要编辑 MySQL 的配置文件，在其中添加或修改 &lt;code&gt;secure【瑟Q儿】_file【伐尔】_priv【破略夫】&lt;/code&gt; 参数，然后重启 MySQL 服务器使修改生效。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3.1 修改文件存储路径&lt;/h3&gt;
&lt;p&gt;修改检索目录为/myload【my漏德】。&lt;/p&gt;
&lt;p&gt;检查目录存放导入导出数据时存放数据的文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# mysql -uroot -pNSD123456...a
mysql&amp;gt; show【瘦】 variables【wèi 利 bóu 斯】 like【赖特】 &quot;%file【伐尔】%&quot;;    -- 查看与文件相关的配置项
-- mysql&amp;gt; show variables like &quot;%file%&quot;; 
+---------------------------------------+---------------------------------+
| Variable_name                         | Value                           |
+---------------------------------------+---------------------------------+
| character_set_filesystem              | binary                          |
| core_file                             | OFF                             |
| ft_stopword_file                      | (built-in)                      |
| general_log_file                      | /var/lib/mysql/mysql50.log      |
| init_file                             |                                 |
| innodb_buffer_pool_filename           | ib_buffer_pool                  |
| innodb_buffer_pool_in_core_file       | ON                              |
| innodb_data_file_path                 | ibdata1:12M:autoextend          |
| innodb_disable_sort_file_cache        | OFF                             |
| innodb_doublewrite_files              | 2                               |
| innodb_file_per_table                 | ON                              |
| innodb_log_file_size                  | 50331648                        |
| innodb_log_files_in_group             | 2                               |
| innodb_open_files                     | 4000                            |
| innodb_temp_data_file_path            | ibtmp1:12M:autoextend           |
| keep_files_on_create                  | OFF                             |
| large_files_support                   | ON                              |
| local_infile                          | OFF                             |
| lower_case_file_system                | OFF                             |
| myisam_max_sort_file_size             | 9223372036853727232             |
| open_files_limit                      | 10000                           |
| performance_schema_max_file_classes   | 80                              |
| performance_schema_max_file_handles   | 32768                           |
| performance_schema_max_file_instances | -1                              |
| pid_file                              | /run/mysqld/mysqld.pid          |
| relay_log_info_file                   | relay-log.info                  |
| secure_file_priv                      | /var/lib/mysql-files/           |
| slow_query_log_file                   | /var/lib/mysql/mysql50-slow.log |
+---------------------------------------+---------------------------------+
28 rows in set (0.00 sec)

-- 查看默认检索目录
mysql&amp;gt; show【瘦】 variables【wèi 利 bóu 斯】 like【赖特】 &quot;secure【瑟Q儿】_file【伐尔】_priv【破略夫】&quot;;
-- mysql&amp;gt; show variables like &quot;secure_file_priv&quot;; 
+------------------+-----------------------+
| Variable_name    | Value                 |
+------------------+-----------------------+
| secure_file_priv | /var/lib/mysql-files/ |
+------------------+-----------------------+
1 row in set (0.00 sec)
mysql&amp;gt; exit【诶西特】

-- 安装MySQL服务软件时自动创建
[root@mysql50 ~]# ls -ld /var/lib/mysql-files【伐尔】/
-- [root@mha ~]# ls -ld /var/lib/mysql-files/
drwxr-x--- 2 mysql mysql 6 Sep 22  2021 /var/lib/mysql-files【伐尔】/


-- 修改主配置文件
[root@mysql50 ~]# vim /etc/my.cnf.d/mysql-server.cnf
[mysqld]
secure【瑟Q儿】_file【伐尔】_priv【破略夫】=/myload【my漏德】  -- 添加此行
:wq

-- 创建目录并修改所有者为mysql用户 ,并保证mysql用户对父目录有rx
[root@mysql50 ~]# mkdir /myload【my漏德】
-- [root@mha ~]# mkdir /myload
[root@mysql50 ~]# chown【吃-昂】 mysql /myload【my漏德】
-- [root@mha ~]# chown mysql /myload

-- 关闭selinux
[root@mysql50 ~]# setenforce【赛特-因佛尔斯】 0
-- [root@mha ~]# setenforce 0
setenforce: SELinux is disabled

-- 重启服务
[root@mysql50 ~]# systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld
-- [root@mha ~]# systemctl restart mysqld

-- 管理员员登陆查看目录
[root@mysql50 ~]# mysql -uroot -pNSD123456...a
mysql&amp;gt; show【瘦】 variables【wèi 利 bóu 斯】 like【赖特】 &quot;secure【瑟Q儿】_file【伐尔】_priv【破略夫】&quot;;
-- mysql&amp;gt; show variables like &quot;secure_file_priv&quot;;
+------------------+----------+
| Variable_name    | Value    |
+------------------+----------+
| secure_file_priv | /myload/ |
+------------------+----------+
1 row in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 导入数据&lt;/h3&gt;
&lt;p&gt;将/etc/passwd文件导入db1库的user3表里。&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# mysql -uroot -pNSD123456...a
mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】 db1;
-- mysql&amp;gt; create database db1;
-- Query OK, 1 row affected (0.01 sec)

-- 建表（ 根据导入的文件内容 创建表头）
mysql&amp;gt; create【克瑞特】 table【忒-部】 db1.user3(
   name varchar【瓦儿-查儿】(30),
   password【帕斯沃德】 char【查尔】(1),
   uid int【因特】 , 
   gid int【因特】 , 
   comment【坑门特】 varchar【瓦儿-查儿】(200),
   homedir【home-跌儿】 varchar【瓦儿-查儿】(50),
   shell varchar【瓦儿-查儿】(30));
Query OK, 0 rows affected (0.41 sec)
-- mysql&amp;gt; create table db1.user3(
--    name varchar(30),
--    password char(1),
--    uid int,
--    gid int,
--    comment varchar(200),
--    homedir varchar(50),
--    shell varchar(30));
-- Query OK, 0 rows affected (0.06 sec)

-- 查看表头
mysql&amp;gt; desc db1.user3;
-- mysql&amp;gt; desc db1.user3;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| name     | varchar(30)  | YES  |     | NULL    |       |
| password | char(1)      | YES  |     | NULL    |       |
| uid      | int          | YES  |     | NULL    |       |
| gid      | int          | YES  |     | NULL    |       |
| comment  | varchar(200) | YES  |     | NULL    |       |
| homedir  | varchar(50)  | YES  |     | NULL    |       |
| shell    | varchar(30)  | YES  |     | NULL    |       |
+----------+--------------+------+-----+---------+-------+
7 rows in set (0.01 sec)

-- 没有数据
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.user3;
-- mysql&amp;gt; select * from db1.user3;
Empty set (0.01 sec)

-- 拷贝文件到检索目录 system【西斯屯】 在MySQL 里执行系统命令
mysql&amp;gt; system【西斯屯】 cp /etc/passwd  /myload【my漏德】/
-- mysql&amp;gt; system cp /etc/passwd /myload
-- mysql&amp;gt; 

-- mysql&amp;gt; system cp /etc/passwd /myload   
-- cp: cannot stat &apos;/etc/passwd&apos;: No such file or directory -- 提示该报错是因为一、没有权限，需要修改权限，二、没有文件，需要拷贝文件，三、当前登录的mysql账号没有权限，需要修改权限
-- 一、修改权限 
-- mysql&amp;gt; system【西斯屯】 chmod【吃-默德】 777 /myload【my漏德】/
-- mysql&amp;gt; system chmod 777 /myload
-- 三、修改mysql用户权限
-- mysql&amp;gt; grant【格拉特】 all【阿尔】 on /myload【my漏德】/* to【托 敏 内提】 mysql@&apos;%&apos;【托 敏 内提】;
-- mysql&amp;gt; grant all on /myload/* to mysql@&apos;%&apos;;
-- 或者切换有权限用户
-- mysql&amp;gt; system whoami --查看当前登录用户
-- sf\ta206682

mysql&amp;gt; system【西斯屯】 ls /myload【my漏德】/  -- 查看文件
-- mysql&amp;gt; system ls /myload
passwd
mysql&amp;gt;

-- 导入数据
mysql&amp;gt; load【漏德】 data  infile【因-伐尔】 &quot;/myload【my漏德】/passwd&quot; into【因兔】 table【忒-部】 db1.user3 fields【菲尔兹】 terminated【托 敏 内提】 by【拜】 &quot;:&quot; lines【赖嗯 s】 terminated【托 敏 内提】 by【拜】 &quot;\n&quot; ;
-- mysql&amp;gt; load data infile &quot;/myload/passwd&quot; into table db1.user3 fields terminated by &quot;:&quot; lines terminated by &quot;\n&quot;;
Query OK, 23 rows affected (0.06 sec)
Records: 23  Deleted: 0  Skipped: 0  Warnings: 0

-- 查看表记录
mysql&amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】  db1.user3;
-- mysql&amp;gt; select count(*) from db1.user3;
+----------+
| count(*) |
+----------+
|       23 |
+----------+
1 row in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.user3;
-- mysql&amp;gt; select * from db1.user3;
+------------------+----------+-------+-------+-----------------------------+-----------------+----------------+
| name             | password | uid   | gid   | comment                     | homedir         | shell          |
+------------------+----------+-------+-------+-----------------------------+-----------------+----------------+
| root             | x        |     0 |     0 | root                        | /root           | /bin/bash      |
| bin              | x        |     1 |     1 | bin                         | /bin            | /sbin/nologin  |
| daemon           | x        |     2 |     2 | daemon                      | /sbin           | /sbin/nologin  |
| adm              | x        |     3 |     4 | adm                         | /var/adm        | /sbin/nologin  |
| lp               | x        |     4 |     7 | lp                          | /var/spool/lpd  | /sbin/nologin  |
| sync             | x        |     5 |     0 | sync                        | /sbin           | /bin/sync      |
| shutdown         | x        |     6 |     0 | shutdown                    | /sbin           | /sbin/shutdown |
| halt             | x        |     7 |     0 | halt                        | /sbin           | /sbin/halt     |
| mail             | x        |     8 |    12 | mail                        | /var/spool/mail | /sbin/nologin  |
| operator         | x        |    11 |     0 | operator                    | /root           | /sbin/nologin  |
| games            | x        |    12 |   100 | games                       | /usr/games      | /sbin/nologin  |
| ftp              | x        |    14 |    50 | FTP User                    | /var/ftp        | /sbin/nologin  |
| nobody           | x        | 65534 | 65534 | Kernel Overflow User        | /               | /sbin/nologin  |
| dbus             | x        |    81 |    81 | System message bus          | /               | /sbin/nologin  |
| systemd-coredump | x        |   999 |   997 | systemd Core Dumper         | /               | /sbin/nologin  |
| systemd-resolve  | x        |   193 |   193 | systemd Resolver            | /               | /sbin/nologin  |
| polkitd          | x        |   998 |   995 | User for polkitd            | /               | /sbin/nologin  |
| unbound          | x        |   997 |   994 | Unbound DNS resolver        | /etc/unbound    | /sbin/nologin  |
| tss              | x        |    59 |    59 | Account used for TPM access | /dev/null       | /sbin/nologin  |
| chrony           | x        |   996 |   993 |                             | /var/lib/chrony | /sbin/nologin  |
| sshd             | x        |    74 |    74 | Privilege-separated SSH     | /var/empty/sshd | /sbin/nologin  |
| tcpdump          | x        |    72 |    72 |                             | /               | /sbin/nologin  |
| mysql            | x        |    27 |    27 | MySQL Server                | /var/lib/mysql  | /sbin/nologin  |
+------------------+----------+-------+-------+-----------------------------+-----------------+----------------+
23 rows in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3 导出数据&lt;/h3&gt;
&lt;p&gt;将db1库user3表所有记录导出, 存到/myload【my漏德】/user.txt文件里。&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】  * from【弗乱】 db1.user3 into【因兔】 outfile【奥特-伐尔】 &quot;/myload【my漏德】/user.txt&quot; ;
-- mysql&amp;gt; select * from db1.user3 into outfile &quot;/myload/user.txt&quot;;
Query OK, 23 rows affected (0.00 sec)

mysql&amp;gt; system【西斯屯】 ls /myload【my漏德】/
-- mysql&amp;gt; system ls /myload/
passwd  user.txt

mysql&amp;gt; system【西斯屯】 wc -l  /myload【my漏德】/user.txt
-- mysql&amp;gt; system wc -l /myload/user.txt
23 /myload/user.txt

mysql&amp;gt;
mysql&amp;gt; system【西斯屯】 vim /myload【my漏德】/user.txt
-- mysql&amp;gt; system vim /myload/user.txt
root    x       0       0       root    /root   /bin/bash
bin     x       1       1       bin     /bin    /sbin/nologin
daemon  x       2       2       daemon  /sbin   /sbin/nologin
adm     x       3       4       adm     /var/adm        /sbin/nologin
lp      x       4       7       lp      /var/spool/lpd  /sbin/nologin
sync    x       5       0       sync    /sbin   /bin/sync
shutdown        x       6       0       shutdown        /sbin   /sbin/shutdown
halt    x       7       0       halt    /sbin   /sbin/halt
mail    x       8       12      mail    /var/spool/mail /sbin/nologin
operator        x       11      0       operator        /root   /sbin/nologin
games   x       12      100     games   /usr/games      /sbin/nologin
ftp     x       14      50      FTP User        /var/ftp        /sbin/nologin
nobody  x       65534   65534   Kernel Overflow User    /       /sbin/nologin
dbus    x       81      81      System message bus      /       /sbin/nologin
systemd-coredump        x       999     997     systemd Core Dumper     /       /sbin/nologin
systemd-resolve x       193     193     systemd Resolver        /       /sbin/nologin
polkitd x       998     995     User for polkitd        /       /sbin/nologin
unbound x       997     994     Unbound DNS resolver    /etc/unbound    /sbin/nologin
tss     x       59      59      Account used for TPM access     /dev/null       /sbin/nologin
chrony  x       996     993             /var/lib/chrony /sbin/nologin
sshd    x       74      74      Privilege-separated SSH /var/empty/sshd /sbin/nologin
tcpdump x       72      72              /       /sbin/nologin
mysql   x       27      27      MySQL Server    /var/lib/mysql  /sbin/nologin
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、用户管理&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[数据导入导出与用户管理]
        direction LR
        A[数据导入导出] --&amp;gt; B[用户管理]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class B highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.1 问题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;允许所有主机使用root连接数据库服务，对所有库和所有表有完全权限、密码为123qqq…A&lt;/li&gt;
&lt;li&gt;允许192.168.90.0/24网段主机使用jam连接数据库服务，仅对gamedb库有完全权限、密码为moershi&lt;/li&gt;
&lt;li&gt;允许在本机使用jamadmin用户连接数据库服务器，仅对moershi库有查询、插入、更新、删除记录的权限，密码为NSD123456…a&lt;/li&gt;
&lt;li&gt;允许192.168.90.51主机使用yaya用户连接数据库服务，仅对moershi库有查询权限，密码为moershi1&lt;/li&gt;
&lt;li&gt;给yaya用户追加，插入记录的权限&lt;/li&gt;
&lt;li&gt;撤销jam用户删库、删表、删记录的权限&lt;/li&gt;
&lt;li&gt;删除jamadmin用户&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;4.2 方案&lt;/h3&gt;
&lt;p&gt;授权是在数据库服务器里添加用户并设置权限及密码；重复执行grant【古亮普】命令时如果库名和用户名不变时，是追加权限。授权步骤如下：&lt;/p&gt;
&lt;p&gt;授权信息保存在mysql库的如下表里：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;user表 保存已有的授权用户及用户对所有库的权限&lt;/li&gt;
&lt;li&gt;db表 保存已有授权用户对某一个库的访问权限&lt;/li&gt;
&lt;li&gt;tables【忒-部s】_priv【破略夫】表 记录已有授权用户对某一张表的访问权限&lt;/li&gt;
&lt;li&gt;columns【科勒姆 s】_priv【破略夫】表 记录已有授权用户对某一个表头的访问权限&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在192.168.90.50 数据库服务器练习用户授权&lt;/p&gt;
&lt;p&gt;在192.168.90.51 数据库服务器测试&lt;/p&gt;
&lt;p&gt;通过模板机克隆一台机器，修改主机名和IP地址&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.51/24 autoconnect【奥特欧 坑聂特】 yes
#[root@mha ~]# nmcli connection modify ens160 ipv4.addresses 192.168.90.51/24 autoconnect yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
#[root@mha ~]# nmcli connection up ens160
[root@mysql51 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql51
#[root@mha ~]# hostnamectl set-hostname mysql51
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装mysql-server服务软件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# yum -y install【因-斯多】 mysql-server【涩·沃】
#[root@mysql51 ~]# yum -y install mysql-server

#启动服务
[root@mysql51 ~]# systemctl【西斯屯-ctl】 start【s 达儿】 mysqld
#[root@mysql51 ~]# systemctl start mysqld

#设置开机自启
[root@mysql51 ~]# systemctl【西斯屯-ctl】 enable【ing 内 步】 mysqld
#[root@mysql51 ~]# systemctl enable mysqld
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.3 步骤&lt;/h3&gt;
&lt;p&gt;实现此案例需要按照如下步骤进行。&lt;/p&gt;
&lt;h4&gt;步骤一：在192.168.90.50 数据库服务器做如下授权练习&lt;/h4&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 数据库管理员登陆
[root@mysql51 ~]# mysql -uroot -pNSD123456...a
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;1）允许所有主机使用root连接数据库服务，对所有库和所有表有完全权限、密码为123qqq…A&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】 user root@&quot;%&quot; identified【爱-丹-提伐】 by【拜】 &quot;123qqq...A&quot;;    -- 创建用户
-- mysql&amp;gt; create user root@&quot;%&quot; identified by &quot;123qqq...A&quot;;
Query OK, 0 rows affected (0.08 sec)

mysql&amp;gt; grant【古亮普】 all【ò】 on【昂】 *.* to root@&quot;%&quot; ;    -- 授予权限
-- mysql&amp;gt; grant all on *.* to root@&quot;%&quot;;
Query OK, 0 rows affected (0.13 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在 MySQL 中，使用 &lt;code&gt;GRANT&lt;/code&gt; 语句来分配权限。其核心语法结构如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;GRANT 权限列表 ON 数据库对象 TO &apos;用户名&apos;@&apos;主机名&apos; [IDENTIFIED BY &apos;密码&apos;];
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;权限类别&lt;/th&gt;
&lt;th&gt;具体权限&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;数据定义 (DDL)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CREATE&lt;/code&gt;, &lt;code&gt;ALTER&lt;/code&gt;, &lt;code&gt;INDEX&lt;/code&gt;, &lt;code&gt;REFERENCES&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;允许创建、修改、删除表；创建和删除索引；创建外键 。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;数据操作 (DML)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT&lt;/code&gt;, &lt;code&gt;INSERT&lt;/code&gt;, &lt;code&gt;UPDATE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;允许对数据进行查询、插入和更新 。&lt;strong&gt;注意&lt;/strong&gt;：输出中不包含 &lt;code&gt;DELETE&lt;/code&gt; 权限，因此该用户不能删除数据行。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;存储程序与高级对象&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CREATE ROUTINE&lt;/code&gt;, &lt;code&gt;ALTER ROUTINE&lt;/code&gt;, &lt;code&gt;EXECUTE&lt;/code&gt;, &lt;code&gt;EVENT&lt;/code&gt;, &lt;code&gt;TRIGGER&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;允许创建、修改和执行存储过程和函数；创建和管理事件（定时任务）；创建和管理触发器 。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;视图管理&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CREATE VIEW&lt;/code&gt;, &lt;code&gt;SHOW VIEW&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;允许创建和查看视图的定义 。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;其他操作&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CREATE TEMPORARY TABLES&lt;/code&gt;, &lt;code&gt;LOCK TABLES&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;允许在操作时创建临时表，并显式锁定表 。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;基本连接&lt;/td&gt;
&lt;td&gt;&lt;code&gt;USAGE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;仅表示该用户账户存在，并允许其连接数据库。默认情况下，此权限不授予任何数据库操作权限 。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;权限列表&lt;/strong&gt;：指定要授予的具体操作权限。对于记录的增删改查，主要涉及以下四种：
-   &lt;code&gt;SELECT&lt;/code&gt;：允许查询（检索）数据。
-   &lt;code&gt;INSERT&lt;/code&gt;：允许插入（添加）新记录。
-   &lt;code&gt;UPDATE&lt;/code&gt;：允许更新（修改）现有记录。
-   &lt;code&gt;DELETE&lt;/code&gt;：允许删除记录。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;数据库对象&lt;/strong&gt;：定义权限的作用范围，使用 &lt;code&gt;数据库名.表名&lt;/code&gt; 的格式指定。
-   &lt;code&gt;mydb.mytable&lt;/code&gt;：授权针对 &lt;code&gt;mydb&lt;/code&gt; 数据库下的 &lt;code&gt;mytable&lt;/code&gt; 表。
-   &lt;code&gt;mydb.*&lt;/code&gt;：授权针对 &lt;code&gt;mydb&lt;/code&gt; 数据库下的所有表（这是最常用的场景）。
-   &lt;code&gt;*.*&lt;/code&gt;：授权针对服务器上所有数据库的所有表（通常仅限管理员用户）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;用户与主机&lt;/strong&gt;：指定被授权的用户及其允许连接的主机，格式为 &lt;code&gt;&apos;用户名&apos;@&apos;主机名&apos;&lt;/code&gt;。
-   &lt;code&gt;&apos;user1&apos;@&apos;localhost&apos;&lt;/code&gt;：仅允许用户 &lt;code&gt;user1&lt;/code&gt; 从数据库服务器本机连接。
-   &lt;code&gt;&apos;user1&apos;@&apos;%&apos;&lt;/code&gt;：允许用户 &lt;code&gt;user1&lt;/code&gt; 从任何远程主机连接。&lt;code&gt;%&lt;/code&gt; 在这里是一个通配符。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;密码设置（可选）&lt;/strong&gt;：在 &lt;code&gt;GRANT&lt;/code&gt; 语句中直接指定或修改用户的密码。更推荐的做法是先使用 &lt;code&gt;CREATE USER&lt;/code&gt; 语句明确创建用户。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;授予特定数据库的所有表权限&lt;/strong&gt;
假设想让用户 &lt;code&gt;report_user&lt;/code&gt; 可以从任何主机连接，并拥有对数据库 &lt;code&gt;samp_db&lt;/code&gt; 中所有表进行增删改查的权限，可以使用以下命令：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;  ```sql
  GRANT SELECT, INSERT, UPDATE, DELETE ON samp_db.* TO &apos;report_user&apos;@&apos;%&apos;;
  ```
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;创建用户并授权（完整步骤）&lt;/strong&gt;
这是一个更清晰、安全的做法，将创建用户和授权分步进行：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;  ```sql
  -- 1. 创建用户
  CREATE USER &apos;dev_user&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;secure_password&apos;;
  -- 2. 授予特定权限（例如，对test_db数据库的所有表）
  GRANT SELECT, INSERT, UPDATE, DELETE ON test_db.* TO &apos;dev_user&apos;@&apos;localhost&apos;;
  -- 3. 使权限设置立即生效
  FLUSH PRIVILEGES;
  ```
  执行 `FLUSH PRIVILEGES;` 命令是为了让服务器重新加载权限表，确保新的权限设置立即生效。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;查看用户权限&lt;/strong&gt;
授权完成后，可以验证权限是否已正确分配：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;  ```sql
  SHOW GRANTS FOR &apos;dev_user&apos;@&apos;localhost&apos;;
  ```
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;撤销权限&lt;/strong&gt;
如果需要收回某些权限，可以使用 &lt;code&gt;REVOKE【瑞 - 沃克】&lt;/code&gt; 语句。例如，撤销 &lt;code&gt;dev_user&lt;/code&gt; 对 &lt;code&gt;test_db&lt;/code&gt; 的删除权限：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;  ```sql
  REVOKE【瑞 - 沃克】 DELETE ON test_db.* FROM &apos;dev_user&apos;@&apos;localhost&apos;;
  FLUSH PRIVILEGES;
  ```
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;2）允许192.168.90.0/24网段主机使用jam连接数据库服务，仅对gamedb库有完全权限、密码为moershi&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】 user jam@&quot;192.168.90.0/24&quot; identified【爱-丹-提伐】 by【拜】 &quot;moershi&quot;;    -- 创建用户
-- mysql&amp;gt; create user jam@&quot;192.168.88.0/24&quot; identified by &quot;moershi&quot;;
Query OK, 0 rows affected (0.06 sec)

mysql&amp;gt; grant【古亮普】 all【ò】 on【昂】  gamedb.*  to jam@&quot;192.168.90.0/24&quot;;    -- 授予权限
-- mysql&amp;gt; grant all on gamedb.* to jam@&quot;192.168.88.0/24&quot;;
Query OK, 0 rows affected (0.05 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;3）允许在本机使用jamadmin用户连接数据库服务器，仅对moershi库有查询、插入、更新、删除记录的权限，密码为NSD123456…a&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】 user jamadmin@&quot;localhost&quot; identified【爱-丹-提伐】 by【拜】 &quot;NSD123456...a&quot;;    -- 创建用户
-- mysql&amp;gt; create user jamadmin@&quot;localhost&quot; identified by &quot;NSD123456...a&quot;;
Query OK, 0 rows affected (0.05 sec)

mysql&amp;gt; grant【古亮普】  select【涩莱克特】 , insert【因涩特】 , update【阿普 dei 特】,delete【迪  利 特】 on【昂】 moershi.* to jamadmin@&quot;localhost&quot;;   -- 授予权限
-- mysql&amp;gt; grant select,insert,update,delete on moershi.* to jamadmin@&quot;localhost&quot;;
Query OK, 0 rows affected (0.06 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;4）允许192.168.90.51主机使用yaya用户连接数据库服务，仅对moershi库有查询权限，密码为moershi1&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】 user yaya@&quot;192.168.90.51&quot;  identified【爱-丹-提伐】 by【拜】 &quot;moershi1&quot; ;    -- 创建用户
-- mysql&amp;gt; create user yaya@&quot;192.168.88.40&quot; identified by &quot;moershi&quot;;
Query OK, 0 rows affected (0.10 sec)

mysql&amp;gt; grant【古亮普】 select【涩莱克特】 on【昂】 moershi.* to yaya@&quot;192.168.90.51&quot;;    -- 授予权限
-- mysql&amp;gt; grant select on moershi.* to yaya@&quot;192.168.88.40&quot;;
Query OK, 0 rows affected (0.07 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;5）给yaya用户追加，插入记录的权限&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; grant【古亮普】 insert【因涩特】 on【昂】 moershi.* to yaya@&quot;192.168.90.51&quot;;
-- mysql&amp;gt; grant insert on moershi.* to yaya@&quot;192.168.88.40&quot;;
Query OK, 0 rows affected (0.05 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;6）查看添加的用户&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;-- 添加的用户保存在 mysql库的user表里
mysql&amp;gt; select【涩莱克特】  host,user from【弗乱】  mysql.user; 
-- mysql&amp;gt; select user,host from mysql.user;
+-----------------+------------------+
| host            | user             |
+-----------------+------------------+
| %               | root             |
| 192.168.90.0/24 | jam              |
| 192.168.90.51   | yaya             |
| localhost       | mysql.infoschema |
| localhost       | mysql.session    |
| localhost       | mysql.sys        |
| localhost       | jamadmin         |
| localhost       | root             |
+-----------------+------------------+
8 rows in set (0.00 sec)

-- 查看已有用户的访问权限
mysql&amp;gt; show【瘦】 grants【哥亮特s】 for【fò】 yaya@&quot;192.168.90.51&quot;; 
-- mysql&amp;gt; show grants for yaya@&quot;192.168.88.40&quot;;
-- +---------------------------------------------------------------+
-- | Grants for yaya@192.168.88.40                                 |
-- +---------------------------------------------------------------+
-- | GRANT USAGE ON *.* TO &apos;yaya&apos;@&apos;192.168.88.40&apos;                  |
-- | GRANT SELECT, INSERT ON `moershi`.* TO &apos;yaya&apos;@&apos;192.168.88.40&apos; |
-- +---------------------------------------------------------------+
-- 2 rows in set (0.00 sec)

-- 用户对某一个库的访问权限保存在mysql库的db表里
mysql&amp;gt; select【涩莱克特】  * from【弗乱】  mysql.db where【威尔】 db=&quot;moershi&quot;  and user=&quot;yaya&quot; \G
-- mysql&amp;gt; select * from mysql.db where db=&quot;moershi&quot; and user=&quot;yaya&quot; \G
*************************** 1. row ***************************
                 Host: 192.168.88.40
                   Db: moershi
                 User: yaya
          Select_priv: Y
          Insert_priv: Y
          Update_priv: N
          Delete_priv: N
          Create_priv: N
            Drop_priv: N
           Grant_priv: N
      References_priv: N
           Index_priv: N
           Alter_priv: N
Create_tmp_table_priv: N
     Lock_tables_priv: N
     Create_view_priv: N
       Show_view_priv: N
  Create_routine_priv: N
   Alter_routine_priv: N
         Execute_priv: N
           Event_priv: N
         Trigger_priv: N
1 row in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;7）撤销jam用户删库、删表、删记录的权限&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;-- 先查看jam用户的权限
-- mysql&amp;gt; show grants for jam@&quot;192.168.88.0/24&quot;;
-- +---------------------------------------------------------------+
-- | Grants for jam@192.168.88.0/24                                |
-- +---------------------------------------------------------------+
-- | GRANT USAGE ON *.* TO &apos;jam&apos;@&apos;192.168.88.0/24&apos;                 |
-- | GRANT ALL PRIVILEGES ON `gamedb`.* TO &apos;jam&apos;@&apos;192.168.88.0/24&apos; |
-- +---------------------------------------------------------------+
-- 2 rows in set (0.01 sec)
-- 撤销权限
mysql&amp;gt; revoke【瑞 - 沃克】 delete【迪  利 特】,drop【卓-普】 on【昂】 gamedb.* from【弗乱】 jam@&quot;192.168.90.0/24&quot; ;
-- mysql&amp;gt; revoke delete,drop on gamedb.* from jam@&quot;192.168.88.0/24&quot;;

-- 查看撤销后jam用户的权限
-- mysql&amp;gt; show grants for jam@&quot;192.168.88.0/24&quot;;
-- +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- | Grants for jam@192.168.88.0/24                                                                                                                                                                                                |
-- +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- | GRANT USAGE ON *.* TO &apos;jam&apos;@&apos;192.168.88.0/24&apos;                                                                                                                                                                                 |
-- | GRANT SELECT, INSERT, UPDATE, CREATE, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON `gamedb`.* TO &apos;jam&apos;@&apos;192.168.88.0/24&apos; |
-- +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-- 2 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;8）修改yaya用户的登陆密码为123456&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; set【赛特】 password【帕斯沃德】 for【fò】 yaya@&quot;192.168.90.51&quot;=&quot;123456&quot; ;
-- mysql&amp;gt; set password for yaya@&quot;192.168.88.40&quot;=&quot;123456&quot;;
Query OK, 0 rows affected (0.05 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;9）删除jamadmin用户&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; drop【卓-普】 user jamadmin@&quot;localhost&quot; ;
-- mysql&amp;gt; drop user jamadmin@&quot;localhost&quot;;
Query OK, 0 rows affected (0.04 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;步骤二：在192.168.90.51测试授权&lt;/h4&gt;
&lt;p&gt;命令格式 mysql -h数据库服务器ip地址 –u用户名 -p密码&lt;/p&gt;
&lt;h5&gt;1）在mysql51连接mysql50 （使用50 添加的yaya 用户）&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# mysql -h192.168.90.50 -uyaya -p123456
#[root@mysql51 ~]# mysql -h 192.168.88.10 -uyaya -p123456
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; show【瘦】 grants【哥亮特】; //查看权限
-- mysql&amp;gt; show grants;
-- +---------------------------------------------------------------+
-- | Grants for yaya@192.168.88.40                                 |
-- +---------------------------------------------------------------+
-- | GRANT USAGE ON *.* TO &apos;yaya&apos;@&apos;192.168.88.40&apos;                  |
-- | GRANT SELECT, INSERT ON `moershi`.* TO &apos;yaya&apos;@&apos;192.168.88.40&apos; |
-- +---------------------------------------------------------------+
-- 2 rows in set (0.00 sec)

mysql&amp;gt; select【涩莱克特】 user();   -- 查看登陆信息
-- mysql&amp;gt; select user();
-- +--------------------+
-- | user()             |
-- +--------------------+
-- | yaya@192.168.88.40 |
-- +--------------------+
-- 1 row in set (0.00 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】  moershi.user(name,uid) values【挖柳斯】(&quot;jim&quot;,11);    -- 插入数据权限内可以执行
-- mysql&amp;gt; insert into moershi.user(name,uid) values(&quot;jim&quot;,11);
Query OK, 1 row affected (0.06 sec)

mysql&amp;gt; delete【迪  利 特】 from【弗乱】  moershi.salary【晒了瑞】 ;    -- 删表超出权限 报错
-- mysql&amp;gt; delete from moershi.salary;
-- ERROR 1142 (42000): DELETE command denied to user &apos;yaya&apos;@&apos;192.168.88.40&apos; for table &apos;salary&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、作业&lt;/h2&gt;
&lt;h3&gt;选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;在 MySQL 里，若要创建一个新用户 &apos;test_user&apos; 并指定其可从任意主机登录，使用的命令是（ A ）
A. CREATE USER &apos;test_user&apos;@&apos;%&apos; IDENTIFIED BY &apos;password&apos;;
B. CREATE USER &apos;test_user&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;password&apos;;
C. CREATE USER &apos;test_user&apos; IDENTIFIED BY &apos;password&apos;;
D. ADD USER &apos;test_user&apos;@&apos;%&apos; IDENTIFIED BY &apos;password&apos;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;下列哪种情况最适合使用 &lt;code&gt;LOAD DATA INFILE&lt;/code&gt; 进行数据导入？（ C ）
A. 导入从网页爬取的不规则数据
B. 把 Excel 文件中的数据导入 MySQL
C. 从 MySQL 导出的数据文件重新导入数据库
D. 导入图片数据到 MySQL&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;LOAD DATA INFILE最适合处理格式规整的文本文件
MySQL 导出的数据文件（如使用 SELECT ... INTO OUTFILE导出的）格式规整，最适合用此命令重新导入
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;想要撤销用户 &apos;user1&apos; 对 &apos;db1&apos; 数据库下 &apos;table1&apos; 表的所有权限，正确的 SQL 语句是（ A ）
A. REVOKE ALL PRIVILEGES ON db1.table1 FROM &apos;user1&apos;@&apos;%&apos;;
B. REMOVE ALL PRIVILEGES ON db1.table1 FROM &apos;user1&apos;@&apos;%&apos;;
C. DELETE ALL PRIVILEGES ON db1.table1 FROM &apos;user1&apos;@&apos;%&apos;;
D. CANCEL ALL PRIVILEGES ON db1.table1 FROM &apos;user1&apos;@&apos;%&apos;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;若要查看当前 MySQL 服务器上所有用户，应执行的命令是（ B ）
A. SHOW USERS;
B. SELECT * FROM mysql.user;
C. SHOW ALL USERS;
D. LIST USERS;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;执行数据导出时，若使用 &lt;code&gt;SELECT ... INTO OUTFILE&lt;/code&gt; 语句，对导出文件所在目录的要求是（ C ）
A. 必须是 MySQL 安装目录
B. 必须是系统临时目录
C. 该目录必须是 MySQL 进程有写入权限的目录
D. 该目录必须是用户主目录&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;阐述 MySQL 中用户管理的重要性以及主要的管理内容。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在 MySQL 中，实施有效的用户管理是保障数据库安全的核心环节。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;重要性：如果所有操作都使用拥有最高权限的 &lt;code&gt;root&lt;/code&gt; 账户，会带来极大的安全隐患。一旦此账户泄露，攻击者可能完全控制数据库。通过用户管理，可以实现权限分离（不同用户只能访问其职责范围内的数据）、安全控制（防止误操作或恶意操作）和审计追踪（记录谁在何时做了什么）。&lt;/li&gt;
&lt;li&gt;主要管理内容：用户管理主要涉及用户账户的创建、修改、删除以及权限的授予与回收。具体操作包括使用 &lt;code&gt;CREATE USER&lt;/code&gt; 创建用户（需指定用户名、允许登录的主机及密码），使用 &lt;code&gt;DROP USER&lt;/code&gt; 删除用户（必须同时指定用户名和主机名），以及使用 &lt;code&gt;ALTER USER&lt;/code&gt; 或 &lt;code&gt;SET PASSWORD&lt;/code&gt; 修改用户密码。所有用户信息都存储在 &lt;code&gt;mysql&lt;/code&gt; 系统数据库的 &lt;code&gt;user&lt;/code&gt; 表中。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;说明 &lt;code&gt;LOAD DATA INFILE&lt;/code&gt; 和 &lt;code&gt;SELECT ... INTO OUTFILE&lt;/code&gt; 在数据导入导出方面的区别与联系。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;LOAD DATA INFILE&lt;/code&gt; 和 &lt;code&gt;SELECT ... INTO OUTFILE&lt;/code&gt; 是 MySQL 中用于高效数据导入和导出的两个互补命令。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;功能区别：&lt;code&gt;SELECT ... INTO OUTFILE&lt;/code&gt; 主要用于将数据库查询结果导出到服务器主机上的指定格式文件中。而 &lt;code&gt;LOAD DATA INFILE&lt;/code&gt; 则是其逆操作，用于将格式化的数据文件从服务器主机快速导入到数据库表中，执行效率通常远高于逐条 &lt;code&gt;INSERT&lt;/code&gt; 语句。使用 &lt;code&gt;LOCAL&lt;/code&gt; 关键字时，&lt;code&gt;LOAD DATA LOCAL INFILE&lt;/code&gt; 可以从客户端主机读取文件。&lt;/li&gt;
&lt;li&gt;语法联系：这两个命令在指定数据格式时使用相似的子句，可以定义字段和行的处理方式，例如 &lt;code&gt;FIELDS TERMINATED BY&lt;/code&gt;（字段分隔符）、&lt;code&gt;LINES TERMINATED BY&lt;/code&gt;（行终止符）等。这意味着可以方便地使用 &lt;code&gt;SELECT ... INTO OUTFILE&lt;/code&gt; 导出数据后，再用 &lt;code&gt;LOAD DATA INFILE&lt;/code&gt; 按相同格式将其导入。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;当在数据导入过程中遇到数据格式不匹配的问题，你会采取哪些解决办法？&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在使用 &lt;code&gt;LOAD DATA INFILE&lt;/code&gt; 导入数据时，如果遇到数据格式不匹配（如字段不对应、分隔符错误等），可以通过以下方式解决：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;明确指定格式选项：在 &lt;code&gt;LOAD DATA INFILE&lt;/code&gt; 语句中，通过 &lt;code&gt;FIELDS TERMINATED BY&lt;/code&gt;、&lt;code&gt;ENCLOSED BY&lt;/code&gt;、&lt;code&gt;ESCAPED BY&lt;/code&gt; 以及 &lt;code&gt;LINES TERMINATED BY&lt;/code&gt; 等子句，确保指定的格式与源文件的实际格式完全匹配。&lt;/li&gt;
&lt;li&gt;忽略文件标题行：如果数据文件包含标题行，可以使用 &lt;code&gt;IGNORE number LINES&lt;/code&gt; 子句跳过文件开头指定行数的内容。&lt;/li&gt;
&lt;li&gt;指定列映射：如果文件中的列顺序与数据库表中的列顺序不一致，可以在 &lt;code&gt;LOAD DATA INFILE&lt;/code&gt; 语句末尾的 &lt;code&gt;(col_name1, col_name2, ...)&lt;/code&gt; 部分明确指定列的顺序映射。&lt;/li&gt;
&lt;li&gt;字符集处理：如果文件编码与数据库字符集不匹配，可能产生乱码。可以使用 &lt;code&gt;CHARACTER SET&lt;/code&gt; 子句指定输入文件的正确字符集。&lt;/li&gt;
&lt;li&gt;数据转换：&lt;code&gt;LOAD DATA INFILE&lt;/code&gt; 支持在导入时通过 &lt;code&gt;SET&lt;/code&gt; 子句对数据进行简单转换或计算，例如 &lt;code&gt;SET id=id+5&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;描述如何对 MySQL 用户权限进行精细管理，以保障数据库安全。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;为保障数据库安全，对用户权限进行精细化管理至关重要，核心原则是最小权限原则，即只授予用户完成其工作所必需的最小权限。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;权限层级：MySQL 的权限可以在不同层级进行设置，包括全局层级（所有数据库，如 &lt;code&gt;*.*&lt;/code&gt;）、数据库层级（指定数据库的所有对象，如 &lt;code&gt;mydb.*&lt;/code&gt;）、表层级（特定表）、列层级（表的特定列）甚至存储过程层级。例如，可以只授予某个用户对员工表的 &lt;code&gt;姓名&lt;/code&gt; 和 &lt;code&gt;部门&lt;/code&gt; 列有 &lt;code&gt;SELECT&lt;/code&gt; 权限，而无权查看 &lt;code&gt;薪资&lt;/code&gt; 列。&lt;/li&gt;
&lt;li&gt;使用角色：可以创建角色，将一组常用的权限授予角色，然后再将角色授予用户，这极大地简化了权限管理。&lt;/li&gt;
&lt;li&gt;授权与回收：使用 &lt;code&gt;GRANT&lt;/code&gt; 语句授予权限，使用 &lt;code&gt;REVOKE&lt;/code&gt; 语句回收权限。授权后通常需要执行 &lt;code&gt;FLUSH PRIVILEGES;&lt;/code&gt; 命令使新权限立即生效（在某些情况下 MySQL 会自动刷新）。&lt;/li&gt;
&lt;li&gt;网络限制：创建用户时，应通过 &lt;code&gt;&apos;用户名&apos;@&apos;主机名&apos;&lt;/code&gt; 的格式限制用户只能从特定的 IP 地址或网段登录数据库，例如 &lt;code&gt;&apos;app_user&apos;@&apos;192.168.1.%&apos;&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;定期审计：定期检查用户权限，及时回收不必要的权限。可以使用 &lt;code&gt;SHOW GRANTS FOR &apos;username&apos;@&apos;hostname&apos;;&lt;/code&gt; 命令查看特定用户的权限。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;简述在数据导出时，设置不同字段和行分隔符的作用及方法。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在数据导出时，通过 &lt;code&gt;SELECT ... INTO OUTFILE&lt;/code&gt; 语句设置字段和行分隔符，主要是为了控制导出文件的格式，使其易于被其他程序（如 Excel、其他数据库系统或自定义脚本）正确解析和读取。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;作用：
&lt;ul&gt;
&lt;li&gt;字段分隔符：定义了文件中每个字段（列）之间的分隔符号，默认为制表符 &lt;code&gt;\t&lt;/code&gt;。常用符号有逗号 (&lt;code&gt;,&lt;/code&gt;) 用于生成 CSV 文件。&lt;/li&gt;
&lt;li&gt;行分隔符：定义了文件中每条记录（行）之间的分隔符号，默认为换行符 &lt;code&gt;\n&lt;/code&gt;。在不同操作系统中可能有所不同，例如在 Windows 系统中可能需要设置为 &lt;code&gt;\r\n&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;设置方法：在 &lt;code&gt;SELECT ... INTO OUTFILE&lt;/code&gt; 语句中使用 &lt;code&gt;FIELDS&lt;/code&gt; 和 &lt;code&gt;LINES&lt;/code&gt; 子句进行定义。&lt;pre&gt;&lt;code&gt;SELECT * FROM your_table
INTO OUTFILE &apos;/path/to/export/file.csv&apos;
FIELDS TERMINATED BY &apos;,&apos; OPTIONALLY ENCLOSED BY &apos;&quot;&apos; -- 字段由逗号分隔，并用双引号包围
LINES TERMINATED BY &apos;\n&apos;; -- 行以换行符结束
&lt;/code&gt;&lt;/pre&gt;
通过合理设置这些分隔符和包围字符，可以确保导出的数据格式规整，避免因数据本身包含分隔符而导致解析错误。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;创建一个名为 &apos;new_db&apos; 的数据库，接着创建用户 &apos;admin_user&apos; 并赋予其对 &apos;new_db&apos; 数据库的所有权限，然后创建用户 &apos;guest_user&apos; 仅赋予对 &apos;new_db&apos; 中 &apos;table1&apos; 表的查询权限。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;实战案例：MySQL 用户权限管理&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这是一个完整的MySQL用户权限管理实战示例，展示如何创建数据库、用户，并分配不同级别的权限。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 数据库创建
mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】 new_db【牛-滴比】;
-- mysql&amp;gt; create database new_db;
Query OK, 1 row affected (6.379 sec)

-- admin_user 用户创建
mysql&amp;gt; create【克瑞特】 user【右瑟】 admin_user【admin-右瑟】@&quot;%&quot; identified【爱-丹-提伐】 by【拜】 &quot;admin_user&quot;; 
-- mysql&amp;gt; create user admin_user@&quot;%&quot; identified by &quot;admin_user&quot;;
Query OK, 0 rows affected (7.111 sec)

-- admin_user 用户赋予权限
mysql&amp;gt; grant【古亮普】 all【ò】 on【昂】 new_db【牛-滴比】.* to admin_user【admin-右瑟】@&quot;%&quot;; 
-- mysql&amp;gt; grant all on new_db.* to admin_user@&quot;%&quot;;
Query OK, 0 rows affected (0.680 sec)

-- guest_user 用户创建
mysql&amp;gt; create【克瑞特】 user【右瑟】 guest_user【盖斯特-右瑟】@&quot;%&quot; identified【爱-丹-提伐】 by【拜】 &quot;guest_user【盖斯特-右瑟】&quot;;
-- mysql&amp;gt; create user guest_user@&quot;%&quot; identified by &quot;guest_user&quot;;
Query OK, 0 rows affected (0.224 sec)

-- 创建new_db.table1
mysql&amp;gt; create【克瑞特】 table【忒-部】 new_db【牛-滴比】.table1【忒-部-万】(id int【因特】); 
-- mysql&amp;gt; create table new_db.table1(id int);
Query OK, 0 rows affected (2.602 sec)

-- guest_user 用户赋予权限
mysql&amp;gt; grant【古亮普】 select【涩莱克特】 on【昂】 new_db【牛-滴比】.table1【忒-部-万】 to guest_user【盖斯特-右瑟】@&quot;%&quot;;
-- mysql&amp;gt; grant select on new_db.table1 to guest_user@&quot;%&quot;;
Query OK, 0 rows affected (0.295 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;权限验证&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;检查创建的用户和权限：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 查看用户列表
mysql&amp;gt; select【涩莱克特】 user【右瑟】, host【厚斯特】 from【弗乱】 mysql.user【右瑟】 where【威尔】 user【右瑟】 like【赖特】 &apos;%admin%&apos; or user【右瑟】 like【赖特】 &apos;%guest%&apos;;
-- mysql&amp;gt; select user, host from mysql.user where user like &apos;%admin%&apos; or user like &apos;%guest%&apos;;
+-------------+------+
| user        | host |
+-------------+------+
| admin_user  | %    |
| guest_user  | %    |
+-------------+------+
2 rows in set (0.00 sec)

-- 查看 admin_user 权限
mysql&amp;gt; show【瘦】 grants【古亮普 s】 for【fó】 admin_user【admin-右瑟】@&quot;%&quot;;
-- mysql&amp;gt; show grants for admin_user@&quot;%&quot;;
+-------------------------------------------------------------+
| Grants for admin_user@%                                     |
+-------------------------------------------------------------+
| GRANT USAGE ON *.* TO &apos;admin_user&apos;@&apos;%&apos;                      |
| GRANT ALL PRIVILEGES ON `new_db`.* TO &apos;admin_user&apos;@&apos;%&apos;      |
+-------------------------------------------------------------+

-- 查看 guest_user 权限
mysql&amp;gt; show【瘦】 grants【古亮普 s】 for【fó】 guest_user【盖斯特-右瑟】@&quot;%&quot;;
-- mysql&amp;gt; show grants for guest_user@&quot;%&quot;;
+-------------------------------------------------------------+
| Grants for guest_user@%                                     |
+-------------------------------------------------------------+
| GRANT USAGE ON *.* TO &apos;guest_user&apos;@&apos;%&apos;                      |
| GRANT SELECT ON `new_db`.`table1` TO &apos;guest_user&apos;@&apos;%&apos;      |
+-------------------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;功能说明&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;admin_user&lt;/strong&gt;：拥有对 &lt;code&gt;new_db&lt;/code&gt; 数据库的&lt;strong&gt;完全权限&lt;/strong&gt;（包括创建表、插入、更新、删除等所有操作）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;guest_user&lt;/strong&gt;：仅拥有对 &lt;code&gt;new_db.table1&lt;/code&gt; 表的&lt;strong&gt;查询权限&lt;/strong&gt;（只能查看数据，不能修改）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;权限级别&lt;/strong&gt;：展示了从数据库级别到表级别的权限控制&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全实践&lt;/strong&gt;：体现了最小权限原则，只为用户分配完成工作所需的最小权限&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;mysql&amp;gt; -- guest_user 用户创建
mysql&amp;gt; create user guest_user@&quot;%&quot; identified by &quot;guest_user&quot;;
Query OK, 0 rows affected (0.224 sec)&lt;/p&gt;
&lt;p&gt;mysql&amp;gt; -- 创建new_db.table1
mysql&amp;gt; create table new_db.table1(id int);
Query OK, 0 rows affected (2.602 sec)&lt;/p&gt;
&lt;p&gt;mysql&amp;gt; -- guest_user 用户赋予查询权限
mysql&amp;gt; grant select on new_db.table1 to guest_user@&quot;%&quot;;
Query OK, 0 rows affected (0.295 sec)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
2. 从 &apos;employees&apos; 表中导出员工的每一列信息到一个 TXT 文件，要求使用逗号作为字段分隔符，换行符作为行分隔符。之后将这个 TXT 文件中的数据导入到新创建的 &apos;employees_backup&apos; 表。
```sql
mysql&amp;gt;-- 导出moershi.employees
mysql&amp;gt; select * from moershi.employees into outfile &quot;/myload/employees.txt&quot; fields terminated by &quot;,&quot; lines terminated by &quot;\n&quot;; 
Query OK, 136 rows affected (0.200 sec)

mysql&amp;gt;-- 创建new_db.employees_backup
mysql&amp;gt; create table new_db.employees_backup like moershi.employees;
Query OK, 0 rows affected (3.269 sec)

mysql&amp;gt; -- 导入
mysql&amp;gt; load data infile &quot;/myload/employees.txt&quot; into table new_db.employees_backup fields terminated by &quot;,&quot; lines terminated by &quot;\n&quot;; 
Query OK, 136 rows affected (1.059 sec)
Records: 136  Deleted: 0  Skipped: 0  Warnings: 0

mysql&amp;gt; select count(*) from new_db.employees_backup; 
+----------+
| count(*) |
+----------+
|      136 |
+----------+
1 row in set (0.351 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;对用户 &apos;editor_user&apos; 的权限进行调整，撤销其对 &apos;news&apos; 数据库下 &apos;articles&apos; 表的删除权限，同时增加更新权限。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; --创建数据库
mysql&amp;gt; create database news;
Query OK, 1 row affected (0.664 sec)

mysql&amp;gt;-- 创建表
mysql&amp;gt; create table news.articles(id int,name varchar(9));
Query OK, 0 rows affected (2.513 sec)

mysql&amp;gt;-- 创建用户
mysql&amp;gt; create user editor_user@&quot;%&quot; identified by &quot;editor_user&quot;; 
Query OK, 0 rows affected (1.115 sec)

mysql&amp;gt;-- 赋予权限
mysql&amp;gt; grant all on news.articles to editor_user@&quot;%&quot;; 
Query OK, 0 rows affected (0.571 sec)

mysql&amp;gt;-- 撤销权限
mysql&amp;gt; revoke delete on news.articles from editor_user@&quot;%&quot;;  
Query OK, 0 rows affected (0.438 sec)

mysql&amp;gt;-- 增加权限
mysql&amp;gt; grant update on news.articles to editor_user@&quot;%&quot;;   
Query OK, 0 rows affected (0.469 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;先创建一个新用户 &apos;temp_user&apos;，仅赋予其对 &apos;test_db&apos; 数据库下 &apos;logs&apos; 表的插入权限，在完成数据插入任务后，删除该用户。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; --创建数据库
mysql&amp;gt; create database test_db;
Query OK, 1 row affected (0.648 sec)

mysql&amp;gt; -- 创建表
mysql&amp;gt; create table test_db.logs(
    -&amp;gt; id int,
    -&amp;gt; logs varchar(200));
Query OK, 0 rows affected (1.589 sec)

mysql&amp;gt; 创建用户
mysql&amp;gt; create user temp_user@&quot;%&quot; identified by &quot;temp_user&quot;;
Query OK, 0 rows affected (0.760 sec)

mysql&amp;gt; --赋予权限
mysql&amp;gt; grant insert on  test_db.logs to temp_user@&quot;%&quot;;
Query OK, 0 rows affected (0.676 sec)

mysql&amp;gt; --插入数据
mysql&amp;gt; insert into test_db.logs values(1,&quot;程序卡死&quot;); 
Query OK, 1 row affected (0.291 sec)

mysql&amp;gt; --删除用户
mysql&amp;gt; drop user temp_user@&quot;%&quot;;
Query OK, 0 rows affected (0.693 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;08：mysql之备份与恢复&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[mysql之备份与恢复]
        direction LR
        A[mysqldump&amp;lt;br/&amp;gt;备份与恢复] --&amp;gt; B[增量备份&amp;lt;br/&amp;gt;与恢复] --&amp;gt; C[差分备份&amp;lt;br/&amp;gt;与恢复]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class E highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;在一家电商公司的运营过程中，数据库管理员小张日常负责 MySQL 数据库的维护。某天，开发团队要对数据库进行大规模的架构升级，为防止升级过程中出现数据丢失或损坏，小张决定对 MySQL 数据库进行备份。他使用 mysqldump【mysql-当普】 工具，将数据库中的数据和结构导出到一个 SQL 文件中，并把文件存储在多个安全的存储位置。然而，升级过程中出现了意外，数据库中的部分数据丢失。小张迅速行动，利用之前备份的 SQL 文件，使用 mysql 命令将数据恢复到升级前的状态，确保了公司业务的正常运行。&lt;/p&gt;
&lt;h2&gt;二、为什么学&lt;/h2&gt;
&lt;p&gt;学习 MySQL 备份与恢复意义重大。在实际工作里，数据是企业的核心资产，一旦数据库因系统故障、人为误操作、硬件损坏、黑客攻击等原因出现数据丢失或损坏，将给企业带来巨大损失。掌握 MySQL 备份与恢复技术，能在数据丢失时及时恢复，保障业务连续性。同时，在对数据库进行升级、迁移或维护时，提前备份可防止数据意外丢失。此外，学习此技术也是数据库管理员、运维工程师等相关岗位的基本要求，有助于提升个人职业技能，增强在职场上的竞争力。&lt;/p&gt;
&lt;h2&gt;三、mysqldump【mysql-当普】备份与恢复&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[mysql之备份与恢复]
        direction LR
        A[mysqldump&amp;lt;br/&amp;gt;备份与恢复] --&amp;gt; B[增量备份&amp;lt;br/&amp;gt;与恢复] --&amp;gt; C[差分备份&amp;lt;br/&amp;gt;与恢复]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class A highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;热备份，备份和恢复数据库服务必须是运行的&lt;/p&gt;
&lt;h3&gt;3.1 备份数据&lt;/h3&gt;
&lt;p&gt;mysqldump【mysql-当普】 主要是把数据导出成一个sql脚本
可以针对某一个表或多个表
也可以针对某一个或多个库&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参数&lt;/th&gt;
&lt;th&gt;命令示例&lt;/th&gt;
&lt;th&gt;备份范围&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;无参数&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mysqldump 库名 表名&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;单个数据库的&lt;strong&gt;表的内容&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;日常单个数据&lt;strong&gt;表&lt;/strong&gt;备份&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;无参数&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mysqldump 库名 表名 表名...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;数据库的多个&lt;strong&gt;表的内容&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;日常多个数据&lt;strong&gt;表&lt;/strong&gt;备份&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;无参数&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mysqldump 库名&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;单个数据库的&lt;strong&gt;内容&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;日常单个数据库备份&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mysqldump -B 库名&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;单个数据库的&lt;strong&gt;完整结构+内容&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;数据库迁移&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mysqldump -B 库名 库名...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;多个数据库的&lt;strong&gt;完整结构+内容&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;数据库迁移&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-A&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mysqldump -A&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;所有数据库&lt;/strong&gt;的完整结构+内容&lt;/td&gt;
&lt;td&gt;全服务器备份、灾难恢复&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;#备份1张表 
[root@mysql50 ~]# mysqldump【mysql-当普】 -uroot -pNSD123456...a  moershi salary【晒了瑞】 &amp;gt; /bakdir/moershi_salary【晒了瑞】.sql
#[root@mha ~]# mysqldump -uroot -p123 moershi salary &amp;gt; /root/moershi_salary.sql
#mysqldump【mysql-当普】: [Warning] Using a password on the command line interface can be insecure.

#备份多张表
[root@mysql50 ~]# mysqldump【mysql-当普】 -uroot -pNSD123456...a  moershi employees【ing普洛伊s】 departments【迪帕踢门特】 &amp;gt; /bakdir/moershi_employees【ing普洛伊s】_deparments.sql
#[root@mha ~]# mysqldump -uroot -p123 moershi employees departments &amp;gt; /root/moershi_employees_deparments.sql
#mysqldump【mysql-当普】: [Warning] Using a password on the command line interface can be insecure.

#备份1个库 
[root@mysql50 ~]# mysqldump【mysql-当普】 -uroot -pNSD123456...a  -B moershi &amp;gt; /bakdir/moershi.sql 
#[root@mha ~]# mysqldump -uroot -p123 -B moershi &amp;gt; /root/moershi.sql
#mysqldump【mysql-当普】: [Warning] Using a password on the command line interface can be insecure.

#备份多个库
[root@mysql50 ~]# mysqldump【mysql-当普】 -uroot -pNSD123456...a  -B studb db1 &amp;gt; /bakdir/studb_db1.sql 
#[root@mha ~]# mysqldump -uroot -p123 -B studb db1 &amp;gt; /root/studb_db1.sql
#mysqldump【mysql-当普】: [Warning] Using a password on the command line interface can be insecure.

#备份所有库 
[root@mysql50 ~]# mysqldump【mysql-当普】 -uroot -pNSD123456...a  -A  &amp;gt; /bakdir/allbak.sql 
#[root@mha ~]# mysqldump -uroot -p123 -A &amp;gt; /root/allbak.sql
#mysqldump【mysql-当普】: [Warning] Using a password on the command line interface can be insecure.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 恢复数据&lt;/h3&gt;
&lt;p&gt;分析：&lt;/p&gt;
&lt;p&gt;特点：
mysqldump【mysql-当普】 备份和恢复数据时会锁表，锁表期间无法对表做写访问
mysqldump【mysql-当普】适合备份数据量比较小的数据或在数据库服务器访问量少的时候备份。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# mysql -uroot -pNSD123456...a
-- [root@mha ~]# mysql -uroot -p123
-- 删除库
mysql&amp;gt; drop【卓-普】  database【得塔-贝斯】 moershi; 
-- mysql&amp;gt; drop database moershi;
-- Query OK, 6 rows affected (0.57 sec)
mysql&amp;gt; exit【诶西特】
Bye

-- 恢复数据
[root@mysql50 ~]# mysql -uroot -pNSD123456...a &amp;lt; /bakdir/moershi.sql
-- [root@mha ~]# mysql -uroot -p123 &amp;lt; /root/moershi.sql 
-- mysql: [Warning] Using a password on the command line interface can be insecure.

-- 登陆
[root@mysql50 ~]# mysql -uroot -pNSD123456...a 
-- [root@mha ~]# mysql -uroot -p123

-- 进库
mysql&amp;gt; use moershi; 
-- mysql&amp;gt; use moershi;

-- 看表
mysql&amp;gt; show【瘦】 tables【忒-部s】; 
-- mysql&amp;gt; show tables;
+------------------+
| Tables_in_moershi |
+------------------+
| departments      |
| employees        |
| salary           |
| stu4             |
| user             |
| wage_grade       |
+------------------+
6 rows in set (0.00 sec)

-- 删除表记录
mysql&amp;gt; delete【迪利特】 from【弗乱】 salary【晒了瑞】; 
Query OK, 8055 rows affected (0.11 sec)
mysql&amp;gt; exit【诶西特】
Bye

-- 使用备份文件恢复数据
[root@mysql50 ~]# mysql -uroot -pNSD123456...a  moershi &amp;lt; /bakdir/moershi_salary【晒了瑞】.sql 
-- mysql: [Warning] Using a password on the command line interface can be insecure.

-- 登陆服务
[root@mysql50 ~]# mysql -uroot -pNSD123456...a 
-- [root@mha ~]# mysql -uroot -p123

-- 查看行数
mysql&amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】 moershi.salary【晒了瑞】; 
-- mysql&amp;gt; select count(*) from moershi.salary;
+----------+
| count(*) |
+----------+
|     8055 |
+----------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、增量备份与恢复&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[mysql之备份与恢复]
        direction LR
        A[mysqldump&amp;lt;br/&amp;gt;备份与恢复] --&amp;gt; B[增量备份&amp;lt;br/&amp;gt;与恢复] --&amp;gt; C[差分备份&amp;lt;br/&amp;gt;与恢复]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class B highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.1 准备2台数据库服务器&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;mysql50&lt;/td&gt;
&lt;td&gt;192.168.90.50&lt;/td&gt;
&lt;td&gt;用于备份数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mysql51&lt;/td&gt;
&lt;td&gt;192.168.90.51&lt;/td&gt;
&lt;td&gt;用于恢复数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;mysql51机器的IP配置和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.51/24 autoconnect【奥特欧 坑聂特】 yes
#[root@mha ~]# nmcli connection modify eth0 ipv4.addresses 192.168.88.40/24 autoconnect yes

[root@localhost ~]# nmcli connection【肯耐申】 up【啊普】 ens160
#[root@mha ~]# nmcli connection up eth1

[root@mysql51 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql51
#[root@mha ~]# hostnamectl set-hostname mha
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;增量备份和差异备份优缺点&lt;/h3&gt;
&lt;p&gt;增量备份&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;定义：增量备份只备份自上一次备份（无论是完全备份、增量备份还是差异备份）以来发生变化的数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;工作原理：首先需要一个完整的备份（基础备份），然后每次增量备份都只备份相对于上一次备份后变化的数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;优点：备份速度快，占用空间小，因为每次只备份变化的数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;缺点：恢复数据时，需要先恢复完整备份，然后按照时间顺序依次恢复所有的增量备份，直到指定的时间点。恢复过程复杂且耗时，如果中间任何一个备份损坏，可能导致整个恢复链失效。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;适用场景：数据量大，备份窗口短，但对恢复时间要求不高的场景。&lt;/p&gt;
&lt;p&gt;当前的备份是基于上一次备份做增量的备份
一般第一次备份要完全备份
第一次：全量--&amp;gt;增加了a
第二次:  备份a---&amp;gt;增加了b
第三次:  备份b---&amp;gt;增加了c
第四次:  备份c---&amp;gt;增加了d&lt;/p&gt;
&lt;p&gt;增量备份做数据恢复
全量&amp;lt;---备份a
全量&amp;lt;---备份b
全量&amp;lt;---备份c
最终 全量(abc)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;差异备份&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;定义：差异备份备份自上一次完整备份以来所有发生变化的数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;工作原理：首先需要一个完整备份，然后每次差异备份都会备份自上次完整备份以来所有变化的数据。因此，第二次差异备份会包含第一次差异备份的内容，第三次会包含第一次和第二次的内容，以此类推。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;优点：恢复时只需要完整备份和最近一次的差异备份，恢复过程相对简单。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;缺点：随着时间推移，差异备份的大小会越来越大，因为每次都要备份自完整备份以来的所有变化。备份时间可能会逐渐增加。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;适用场景：数据量变化不大，且希望恢复过程相对简单的场景。&lt;/p&gt;
&lt;p&gt;当前的备份是基于第一次备份做增量的备份
一般第一次备份要完全备份
第一次：全量--&amp;gt;增加了a
第二次:  备份a---&amp;gt;增加了b
第三次:  备份ab---&amp;gt;增加了c
第四次:  备份abc---&amp;gt;增加了d
全量&amp;lt;--备份abc
最终 全量(abc)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对比总结：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;备份内容：增量备份只备份上一次备份后的变化，而差异备份备份自上次完整备份后的所有变化。&lt;/li&gt;
&lt;li&gt;备份空间和速度：增量备份占用空间小，速度快；差异备份随着时间推移，占用空间和备份时间都会增加。&lt;/li&gt;
&lt;li&gt;恢复过程：增量恢复需要完整备份和所有增量备份，步骤多，易出错；差异恢复只需要完整备份和最近一次差异备份，相对简单。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;PERCONA【帕扣娜】 xtrabackup【xtra-拜克阿普】是一款强大的在线热备份工具，备份过程中不锁库表，适合生产环境。支持完全备份与恢复、增量备份与恢复、差异备份与恢复。&lt;/p&gt;
&lt;p&gt;在192.168.90.50主机完成备份与恢复的练习 。&lt;/p&gt;
&lt;h3&gt;4.2 数据增量备份&lt;/h3&gt;
&lt;p&gt;安装软件（在mysql50 、MySQL51 两台主机都要安装）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#一、使用YUM下载方式，下载RPM包：
[root@mysql50 ~]# yum -y install【因-斯多】 https://repo.percona.com/yum/percona-release-latest.noarch.rpm
#[root@mha ~]# yum -y install https://repo.percona.com/yum/percona-release-latest.noarch.rpm

#二、启用percona【帕扣娜】库：
[root@mysql50 ~]# percona【帕扣娜】-release【率利斯】 enable【ing 内 步】-only【欧利】 tools【兔斯】 release【率利斯】
#[root@mha ~]# percona-release enable-only tools release

#三、依赖包下载
[root@mysql50 ~]#  yum -y install【因-斯多】 lz4 zstd
#[root@mha ~]# yum -y install lz4 zstd

#四、安装percona【帕扣娜】-xtrabackup【xtra-拜克阿普】
[root@mysql50 ~]#  yum -y install【因-斯多】 percona【帕扣娜】-xtrabackup【xtra-拜克阿普】-80
#[root@mha ~]# yum -y install percona-xtrabackup-80
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;增量备份（在mysql50主机 完成增量备份练习）&lt;/p&gt;
&lt;p&gt;--host：备份的主机IP&lt;/p&gt;
&lt;p&gt;--user:  数据库的用户&lt;/p&gt;
&lt;p&gt;--password【帕斯沃德】: 数据库的密码&lt;/p&gt;
&lt;p&gt;--backup【拜克阿普】:启动备份过程，是最基本的备份启动选项&lt;/p&gt;
&lt;p&gt;--target【塔géi特】-dir【迪尔】: 指定备份文件的存储目录&lt;/p&gt;
&lt;p&gt;--datadir【得塔-迪尔】: 数据库文件目录&lt;/p&gt;
&lt;p&gt;--incremental【因葵孟透】-basedir【贝斯迪尔】：指定增量备份的基础目录，即上一次备份的目录&lt;/p&gt;
&lt;p&gt;周一完全备份（备份所有数据）&lt;/p&gt;
&lt;p&gt;对数据做增量备份前，必须先有一次备份，也就是首次备份，通常是备份所有数据；比如每周周一完全备份，周二到周日增量备份。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#全量备份
[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】 --datadir【得塔-迪尔】=/var/lib/mysql
#[root@mha ~]# xtrabackup --host=127.0.0.1 --user=root --password=123 --backup --target-dir=/fullbak --datadir=/var/lib/mysql
……
230530 18:18:48 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24822878) to (24822898) was copied.
230530 18:18:50 completed OK!

#插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250610&quot;,18,25000,8000);
#mysql&amp;gt; insert into moershi.salary(date,employee_id,basic,bonus) values(&quot;20250610&quot;,18,25000,8000);
#Query OK, 1 row affected (0.05 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周二增量备份（备份周一备份后新产生的数据）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/new2 --incremental【因葵孟透】-basedir【贝斯迪尔】=/fullbak【fò-拜克】  --datadir【得塔-迪尔】=/var/lib/mysql
#[root@mha ~]# xtrabackup --host=127.0.0.1 --user=root --password=123 --backup --target-dir=/new2 --incremental-basedir=/fullbak --datadir=/var/lib/mysql
……
……
230530 18:33:52 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24827173) to (24827183) was copied.
230530 18:33:53 completed OK!

#插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250710&quot;,18,25000,8000);
#mysql&amp;gt; insert into moershi.salary(date,employee_id,basic,bonus) values(&quot;20250710&quot;,18,25000,8000);
#Query OK, 1 row affected (0.11 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周三增量备份（备份周二备份后新产生的数据）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/new3 --incremental【因葵孟透】-basedir【贝斯迪尔】=/new2  --datadir【得塔-迪尔】=/var/lib/mysql
#[root@mha ~]# xtrabackup --host=127.0.0.1 --user=root --password=123 --backup --target-dir=/new3 --incremental-basedir=/fullbak --datadir=/var/lib/mysql
……
……
230530 18:46:17 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24832526) to (24832536) was copied.
230530 18:46:18 completed OK!

#插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250710&quot;,18,25000,8000);
#mysql&amp;gt; insert into moershi.salary(date,employee_id,basic,bonus) values(&quot;20250710&quot;,18,25000,8000);
#Query OK, 1 row affected (0.08 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周四增量备份（备份周三备份后新产生的数据）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/new4 --incremental【因葵孟透】-basedir【贝斯迪尔】=/new3  --datadir【得塔-迪尔】=/var/lib/mysql
#[root@mha ~]# xtrabackup --host=127.0.0.1 --user=root --password=123 --backup --target-dir=/new4 --incremental-basedir=/fullbak --datadir=/var/lib/mysql
……
……
230530 18:53:41 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24837561) to (24837571) was copied.
230530 18:53:42 completed OK!

#插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250710&quot;,18,25000,8000);
#mysql&amp;gt; insert into moershi.salary(date,employee_id,basic,bonus) values(&quot;20250710&quot;,18,25000,8000);
#Query OK, 1 row affected (0.05 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周五增量备份（备份周四备份后新产生的数据）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/new5 --incremental【因葵孟透】-basedir【贝斯迪尔】=/new4  --datadir【得塔-迪尔】=/var/lib/mysql
#[root@mha ~]# xtrabackup --host=127.0.0.1 --user=root --password=123 --backup --target-dir=/new5 --incremental-basedir=/fullbak --datadir=/var/lib/mysql
……
……
230530 18:58:50 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24841645) to (24841655) was copied.
230530 18:58:51 completed OK!

#插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250710&quot;,18,25000,8000);
#mysql&amp;gt; insert into moershi.salary(date,employee_id,basic,bonus) values(&quot;20250710&quot;,18,25000,8000);
#Query OK, 1 row affected (0.04 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周六增量备份（备份周五备份后新产生的数据）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/new6 --incremental【因葵孟透】-basedir【贝斯迪尔】=/new5  --datadir【得塔-迪尔】=/var/lib/mysql
#[root@mha ~]# xtrabackup --host=127.0.0.1 --user=root --password=123 --backup --target-dir=/new6 --incremental-basedir=/fullbak --datadir=/var/lib/mysql
……
……
230530 19:00:55 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24848404) to (24848414) was copied.
230530 19:00:56 completed OK!

#插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250710&quot;,18,25000,8000);
#mysql&amp;gt; insert into moershi.salary(date,employee_id,basic,bonus) values(&quot;20250710&quot;,18,25000,8000);
#Query OK, 1 row affected (0.06 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周日增量备份（备份周六备份后新产生的数据）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/new7 --incremental【因葵孟透】-basedir【贝斯迪尔】=/new6  --datadir【得塔-迪尔】=/var/lib/mysql
#[root@mha ~]# xtrabackup --host=127.0.0.1 --user=root --password=123 --backup --target-dir=/new7 --incremental-basedir=/fullbak --datadir=/var/lib/mysql
……
……
230530 19:00:55 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24848404) to (24848414) was copied.
230530 19:00:56 completed OK!
[root@mysql50 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.3 数据增量恢复&lt;/h3&gt;
&lt;p&gt;增量恢复数据步骤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;准备恢复数据&lt;/li&gt;
&lt;li&gt;合并数据&lt;/li&gt;
&lt;li&gt;清空数据库目录&lt;/li&gt;
&lt;li&gt;拷贝数据&lt;/li&gt;
&lt;li&gt;修改数据库目录所有者/组用户为mysql&lt;/li&gt;
&lt;li&gt;重启数据库服务&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;具体操作如下：&lt;/p&gt;
&lt;p&gt;MySQL51 拷贝 MySQL50 的备份文件到 本机的根目录下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# scp –r  root@192.168.90.50:/fullbak【fò-拜克】  /
[root@mysql51 ~]# scp –r  root@192.168.90.50:/new2  /
[root@mysql51 ~]# scp –r  root@192.168.90.50:/new3  /
[root@mysql51 ~]# scp –r  root@192.168.90.50:/new4  /
[root@mysql51 ~]# scp –r  root@192.168.90.50:/new5  /
[root@mysql51 ~]# scp –r  root@192.168.90.50:/new6  /
[root@mysql51 ~]# scp –r  root@192.168.90.50:/new7  /
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在MySQL51主机使用备份文件恢复数据&lt;/p&gt;
&lt;p&gt;--prepare【普瑞-撇尔】：对备份数据进行预处理，回滚未提交的事务并同步已提交的事务至数据文件，使数据文件处于一致性状态，以便用于恢复&lt;/p&gt;
&lt;p&gt;--apply-log-only【欧利】：在准备备份时使用，表示只应用重做日志（redo log），不回滚未提交的事务，常用于增量备份准备&lt;/p&gt;
&lt;p&gt;--target【塔géi特】-dir【迪尔】：指定备份文件的存储目录&lt;/p&gt;
&lt;p&gt;--incremental【因葵孟透】-dir【迪尔】：指定增量备份的存储目录&lt;/p&gt;
&lt;p&gt;1)、准备恢复数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --apply-log-only【欧利】 --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】
……
……
Log background threads are being closed...
Shutdown completed; log sequence number 24822898
Number of pools: 1
250630 14:32:14 completed OK!
[root@mysql51 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）、合并数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//将周二的增量数据拷贝到周一备份目录里，合并后周一的目录里存放的是周一 + 周二 的数据
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --apply-log-only【欧利】 --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】 --incremental【因葵孟透】-dir【迪尔】=/new2
……
……
250630 14:40:05 [00] Copying /new2/binlog.index to ./binlog.index
250630 14:40:05 [00]        ...done
250630 14:40:05 completed OK!
[root@mysql51 ~]#
//将周三的增量数据拷贝到周一备份目录里，合并后周一的目录里存放的是周一 + 周二 + 周三 的数据
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --apply-log-only【欧利】 --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】 --incremental【因葵孟透】-dir【迪尔】=/new3
……
……
250630 15:00:37 [00] Copying /new3/binlog.index to ./binlog.index
250630 15:00:37 [00]        ...done
250630 15:00:37 completed OK!
[root@mysql51 ~]#
//将周四的增量数据拷贝到周一备份目录里，合并后周一的目录里存放的是周一 + 周二 + 周三 +周四的数据
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --apply-log-only【欧利】 --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】 --incremental【因葵孟透】-dir【迪尔】=/new4
……
……
250630 15:00:37 [00] Copying /new4/binlog.index to ./binlog.index
250630 15:00:37 [00]        ...done
250630 15:00:37 completed OK!
[root@mysql51 ~]#
//将周五的增量数据拷贝到周一备份目录里，合并后周一的目录里存放的是周一 + 周二 + 周三 +周四+周五的数据
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --apply-log-only【欧利】 --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】 --incremental【因葵孟透】-dir【迪尔】=/new5
……
……
250630 15:00:37 [00] Copying /new5/binlog.index to ./binlog.index
250630 15:00:37 [00]        ...done
250630 15:00:37 completed OK!
[root@mysql51 ~]#
//将周六的增量数据拷贝到周一备份目录里，合并后周一的目录里存放的是周一 + 周二 + 周三 +周四+周五+周六的数据
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --apply-log-only【欧利】 --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】 --incremental【因葵孟透】-dir【迪尔】=/new6
……
……
250630 15:00:37 [00] Copying /new6/binlog.index to ./binlog.index
250630 15:00:37 [00]        ...done
250630 15:00:37 completed OK!
[root@mysql51 ~]#
//将周日的增量数据拷贝到周一备份目录里，合并后周一的目录里存放的是周一 + 周二 + 周三 +周四+周五+周六+周日的数据
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --apply-log-only【欧利】 --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】 --incremental【因葵孟透】-dir【迪尔】=/new7
……
……
250630 15:00:37 [00] Copying /new7/binlog.index to ./binlog.index
250630 15:00:37 [00]        ...done
250630 15:00:37 completed OK!
[root@mysql51 ~]#

[root@mysql51 ~]# rm -rf /var/lib/mysql/*
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --copy-back --target【塔géi特】-dir【迪尔】=/fullbak【fò-拜克】
[root@mysql51 ~]# chown -R mysql:mysql /var/lib/mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;6）重启数据库服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# systemctl  restart  mysqld
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;7）连接服务查看数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# mysql -uroot -pNSD123456...a
mysql&amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】 moershi.salary【晒了瑞】 where date=20250710;
+----------+
| count(*) |
+----------+
|       75 |
+----------+
1 row in set (0.01 sec)
mysql&amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】 moershi.salary【晒了瑞】 where not  date=20250710;
+----------+
| count(*) |
+----------+
|     8067 |
+----------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、差异备份与恢复&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    subgraph BottomRow[mysql之备份与恢复]
        direction LR
        A[mysqldump&amp;lt;br/&amp;gt;备份与恢复] --&amp;gt; B[增量备份&amp;lt;br/&amp;gt;与恢复] --&amp;gt; C[差分备份&amp;lt;br/&amp;gt;与恢复]
    end
    classDef highlight stroke:#f00,stroke-width:2px;
    class C highlight;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;差异备份：备份完全备份后，新产生的数据。&lt;/p&gt;
&lt;p&gt;PERCONA【帕扣娜】 xtrabackup【xtra-拜克阿普】是一款强大的在线热备份工具，备份过程中不锁库表，适合生产环境。支持差异备份与恢复。&lt;/p&gt;
&lt;p&gt;在192.168.90.50主机完成差异备份&lt;/p&gt;
&lt;h3&gt;5.1 差异备份&lt;/h3&gt;
&lt;p&gt;差异备份&lt;/p&gt;
&lt;p&gt;对数据做差异备份前，必须先有一次备份，也就是首次备份，通常是备份所有数据；比如每周周一完全备份，周二到周日差异备份。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//周一完全备份
[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/allbak --datadir【得塔-迪尔】=/var/lib/mysql
……
……
260630 17:10:02 [00] Writing /allbak/xtrabackup【xtra-拜克阿普】_info
260630 17:10:02 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24881353) to (24881373) was copied.
260630 17:10:03 completed OK!
[root@mysql50 ~]# 
//插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 tarena.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250810&quot;,18,25000,8000);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周二差异备份，备份周一备份后新产生的数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/dir2 --incremental【因葵孟透】-basedir【贝斯迪尔】=/allbak --datadir【得塔-迪尔】=/var/lib/mysql
……
……
260630 17:23:56 [00] Writing /dir2/xtrabackup【xtra-拜克阿普】_info
260630 17:23:56 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24886741) to (24886751) was copied.
260630 17:23:58 completed OK!
[root@mysql50 ~]# 
//插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 tarena.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250810&quot;,18,25000,8000);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周三差异备份，备份周一备份后新产生的数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/dir3 --incremental【因葵孟透】-basedir【贝斯迪尔】=/allbak  --datadir【得塔-迪尔】=/var/lib/mysql
……
……
260630 17:27:10 [00] Writing /dir3/xtrabackup【xtra-拜克阿普】_info
260630 17:27:10 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24892043) to (24892063) was copied.
260630 17:27:11 completed OK!
[root@mysql50 ~]# 
//插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 tarena.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250810&quot;,18,25000,8000);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周四差异备份，备份周一备份后新产生的数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/dir4 --incremental【因葵孟透】-basedir【贝斯迪尔】=/allbak  --datadir【得塔-迪尔】=/var/lib/mysql
……
……
230531 17:31:00 [00] Writing /dir4/xtrabackup【xtra-拜克阿普】_info
230531 17:31:00 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24900560) to (24900580) was copied.
230531 17:31:01 completed OK!
[root@mysql50 ~]# 
//插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 tarena.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250810&quot;,18,25000,8000);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周五差异备份，备份周一备份后新产生的数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/dir5 --incremental【因葵孟透】-basedir【贝斯迪尔】=/allbak  --datadir【得塔-迪尔】=/var/lib/mysql
……
……
230531 17:32:38 [00] Writing /dir5/xtrabackup【xtra-拜克阿普】_info
230531 17:32:38 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24906902) to (24906912) was copied.
230531 17:32:39 completed OK!
[root@mysql50 ~]# 
//插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 tarena.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250810&quot;,18,25000,8000);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周六差异备份，备份周一备份后新产生的数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/dir6 --incremental【因葵孟透】-basedir【贝斯迪尔】=/allbak  --datadir【得塔-迪尔】=/var/lib/mysql
……
……
230531 17:41:01 [00] Writing /dir6/xtrabackup【xtra-拜克阿普】_info
230531 17:41:01 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24914729) to (24914739) was copied.
230531 17:41:02 completed OK!

[root@mysql50 ~]#
-- 插入新数据 （可以插入多行）
mysql&amp;gt; insert【因涩特】 into【因兔】 tarena.salary【晒了瑞】(date,employee_id,basic【贝斯克】,bonus【波诺斯】) values【挖柳斯】(&quot;20250810&quot;,18,25000,8000);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;周日差异，备份备份周一备份后新产生的数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# xtrabackup【xtra-拜克阿普】 --host=127.0.0.1 --user=root --password【帕斯沃德】=NSD123456...a --backup【拜克阿普】 --target【塔géi特】-dir【迪尔】=/dir7 --incremental【因葵孟透】-basedir【贝斯迪尔】=/allbak  --datadir【得塔-迪尔】=/var/lib/mysql
……
……
230531 17:43:16 [00] Writing /dir7/xtrabackup【xtra-拜克阿普】_info
230531 17:43:16 [00]        ...done
xtrabackup【xtra-拜克阿普】: Transaction log of lsn (24920772) to (24920782) was copied.
230531 17:43:17 completed OK!
[root@mysql50 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 差异恢复&lt;/h3&gt;
&lt;p&gt;差异恢复数据步骤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;准备恢复数据&lt;/li&gt;
&lt;li&gt;合并数据&lt;/li&gt;
&lt;li&gt;清空数据库目录&lt;/li&gt;
&lt;li&gt;拷贝数据&lt;/li&gt;
&lt;li&gt;修改数据库目录所有者/组用户为mysql&lt;/li&gt;
&lt;li&gt;重启数据库服务&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;具体操作如下：&lt;/p&gt;
&lt;p&gt;MySQL51 拷贝 MySQL50 的备份文件到 本机的根目录下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# scp –r  root@192.168.90.50:/allbak  /
[root@mysql51 ~]# scp –r  root@192.168.90.50:/dir7  /
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在MySQL51主机使用备份文件恢复数据&lt;/p&gt;
&lt;p&gt;1)、准备恢复数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --apply-log-only【欧利】 --target【塔géi特】-dir【迪尔】=/allbak
……
……
Log background threads are being closed...
Shutdown completed; log sequence number 24881373
Number of pools: 1
230531 17:59:06 completed OK!
[root@mysql51 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）、合并数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//将周日的差异备份与周一的完全备份合并，因为周日的差异备份包扩周二+周日的所有数据
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --apply-log-only【欧利】 --target【塔géi特】-dir【迪尔】=/allbak --incremental【因葵孟透】-dir【迪尔】=/dir7
……
……
230531 18:05:08 [00] Copying /dir7/binlog.000029 to ./binlog.000029
230531 18:05:08 [00]        ...done
230531 18:05:08 [00] Copying /dir7/binlog.index to ./binlog.index
230531 18:05:08 [00]        ...done
230531 18:05:08 completed OK!

[root@mysql51 ~]#
[root@mysql51 ~]# rm -rf /var/lib/mysql/*
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --prepare【普瑞-撇尔】 --target【塔géi特】-dir【迪尔】=/allbak
[root@mysql51 ~]# xtrabackup【xtra-拜克阿普】 --copy-back --target【塔géi特】-dir【迪尔】=/allbak
[root@mysql51 ~]# chown -R mysql:mysql /var/lib/mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3）重启数据库服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# systemctl  restart  mysqld
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4）连接服务查看数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql51 ~]# mysql -uroot -pNSD123456...a
mysql&amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】 tarena.salary【晒了瑞】 where date=20250810;
+----------+
| count(*) |
+----------+
|       75 |
+----------+
1 row in set (0.01 sec)

mysql&amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】 tarena.salary【晒了瑞】 where not  date=20250810;
+----------+
| count(*) |
+----------+
|     8067 |
+----------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;全量备份&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;	### 全量备份步骤
	以下是使用 `xtrabackup` 进行全量备份的命令：
	[root@mha ~]# xtrabackup --backup --target-dir=/path/to/backup
	
	#- `--backup`：表示执行备份操作。
	#- `--target-dir`：指定备份文件的存储目录。
	备份完成后，需要对备份进行准备，以确保备份数据处于一致状态：
	
	[root@mha ~]# xtrabackup --prepare --target-dir=/path/to/backup
	
	#- `--prepare`：对备份数据进行准备，应用事务日志。
	
	### 恢复步骤
	#### 1. 停止 MySQL 服务
	在恢复备份之前，需要停止正在运行的 MySQL 服务，以避免数据冲突。
	[root@mha ~]# sudo systemctl stop mysql
	
	#### 2. 清空 MySQL 数据目录
	为了确保恢复的数据是完整的，需要清空 MySQL 数据目录中的现有数据。
	[root@mha ~]# sudo rm -rf /var/lib/mysql/*
	
	#### 3. 恢复备份数据
	将备份数据复制到 MySQL 数据目录。
	[root@mha ~]# sudo xtrabackup --copy-back --target-dir=/path/to/backup
	
	#- `--copy-back`：将备份数据复制回 MySQL 数据目录。
	
	#### 4. 修改文件权限
	恢复数据后，需要确保 MySQL 数据目录及其文件的权限正确。
	[root@mha ~]# sudo chown -R mysql:mysql /var/lib/mysql
	
	#### 5. 启动 MySQL 服务
	完成上述步骤后，可以启动 MySQL 服务。
	[root@mha ~]# sudo systemctl start mysql
	
	#### 6. 验证恢复结果
	可以登录 MySQL 并检查数据库和表是否已成功恢复。
	[root@mha ~]# mysql -u root -p
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;增量备份恢复&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;	#准备恢复数据。使用 `--apply-log-only`只应用重做日志，不回滚为后续增量备份应用做准备。因为在增量备份中，基础备份必须保持事务状态，以便后续的增量备份能够正确应用。如果提前回滚了未提交事务，那么增量备份应用时可能会丢失一些事务信息。
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak
	#合并增量数据，需要把所有的增量备份数据全部合并，不然会造成数据缺失
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak --incremental-dir=/new1
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak --incremental-dir=/new2
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak --incremental-dir=/new3
	# 停止 MySQL 服务。在恢复备份之前，需要停止正在运行的 MySQL 服务，以避免数据冲突。
	[root@mha ~]# sudo systemctl stop mysql
	# 清空 MySQL 数据目录。为了确保恢复的数据是完整的，需要清空 MySQL 数据目录中的现有数据。
	[root@mha ~]# sudo rm -rf /var/lib/mysql/*
	# 最终准备预处理备份数据。应用重做日志（redo log）到数据文件，将数据文件前滚到备份结束时的状态，使备份数据处于一致状态，可以用于恢复。
	[root@mha ~]# sudo xtrabackup --prepare --target-dir=/fullbak
	# 恢复备份数据。将备份数据复制到 MySQL 数据目录。
	[root@mha ~]# sudo xtrabackup --copy-back --target-dir=/fullbak
	# 修改文件权限。恢复数据后，需要确保 MySQL 数据目录及其文件的权限正确。
	[root@mha ~]# sudo chown -R mysql:mysql /var/lib/mysql
	# 启动 MySQL 服务。完成上述步骤后，可以启动 MySQL 服务。
	[root@mha ~]# sudo systemctl start mysql
	# 验证恢复结果。可以登录 MySQL 并检查数据库和表是否已成功恢复。
	[root@mha ~]# mysql -u root -p
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;差异备份恢复&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;	# 差异备份恢复步骤：
	
	# 1. 准备基础全量备份（使用 --apply-log-only 保持事务状态）
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak
	# 原因：基础备份必须保持事务状态，以便后续的差异备份能够正确应用。
	#       如果提前回滚了未提交事务，差异备份应用时可能会丢失事务信息。
	
	# 2. 应用最后一次差异备份（直接完整准备，不使用 --apply-log-only）
	[root@mha ~]# sudo xtrabackup --prepare --target-dir=/fullbak --incremental-dir=/diff_backup
	# 原因：差异备份基于同一个全量备份，这是最后一个备份步骤，需要完成事务回滚，使数据达到一致状态。
	#       不需要使用 --apply-log-only，因为后面没有更多的备份要应用。
	
	# 3. 停止 MySQL 服务
	[root@mha ~]# sudo systemctl stop mysql
	# 原因：在恢复备份之前，需要停止正在运行的 MySQL 服务，以避免数据冲突。
	
	# 4. 备份并清空 MySQL 数据目录
	[root@mha ~]# sudo mv /var/lib/mysql /var/lib/mysql_backup_$(date +%Y%m%d)
	[root@mha ~]# sudo mkdir /var/lib/mysql
	# 原因：为了确保恢复的数据是完整的，需要清空 MySQL 数据目录中的现有数据。
	
	# 5. 恢复备份数据到 MySQL 数据目录
	[root@mha ~]# sudo xtrabackup --copy-back --target-dir=/fullbak
	# 原因：将已准备好的备份数据复制到 MySQL 数据目录。
	
	# 6. 修改文件权限
	[root@mha ~]# sudo chown -R mysql:mysql /var/lib/mysql
	# 原因：恢复数据后，需要确保 MySQL 数据目录及其文件的权限正确。
	
	# 7. 启动 MySQL 服务
	[root@mha ~]# sudo systemctl start mysql
	# 原因：完成上述步骤后，可以启动 MySQL 服务。
	
	# 8. 验证恢复结果
	[root@mha ~]# mysql -u root -p -e &quot;SHOW DATABASES;&quot;
	# 原因：验证数据库和表是否已成功恢复。
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;备份完整性验证&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;	# 1. 准备备份
	# 在验证之前，需要对备份进行准备操作，以应用事务日志，使备份数据处于一致状态。此步骤适用于全量备份和差异备份。
	
	[root@mha ~]# xtrabackup --prepare --target-dir=/path/to/backup
	# - `--prepare`：该参数用于对备份数据进行准备操作。
	# - `--target-dir`：指定备份文件所在的目录。
	
	#  2. 检查备份元数据文件
	# 备份完成后，XtraBackup 会生成一个名为 `xtrabackup_info` 的元数据文件，该文件包含了备份的相关信息，如备份类型、开始时间、结束时间等。你可以查看这个文件来初步验证备份的基本信息是否正确。
	
	[root@mha ~]# cat /path/to/backup/xtrabackup_info
	# 查看输出内容，确认备份类型为差异备份（`incremental`），并且各项时间信息和其他元数据是否合理。
	
	# 3. 检查备份文件的完整性
	# 可以使用 `xtrabackup --stats` 命令来检查备份文件中的数据页和事务日志的完整性。
	
	[root@mha ~]# xtrabackup --stats --target-dir=/path/to/backup
	
	# - `--stats`：该参数用于显示备份文件的统计信息。
	# - `--target-dir`：指定备份文件所在的目录。
	# 如果备份文件完整，命令执行后会输出详细的统计信息，包括数据页的数量、事务日志的大小等。如果备份文件存在损坏，该命令可能会报错。
	
	# 4. 模拟恢复操作
	# 模拟恢复操作是验证备份完整性的最可靠方法。虽然不会真正覆盖现有的 MySQL 数据目录，但可以检查备份数据是否能够正确恢复。
	
	# 停止 MySQL 服务（如果正在运行）
	[root@mha ~]# sudo systemctl stop mysql
	
	# 创建一个临时目录用于模拟恢复
	[root@mha ~]# mkdir /tmp/restore-test
	
	# 执行模拟恢复操作
	[root@mha ~]# xtrabackup --copy-back --target-dir=/path/to/backup --datadir=/tmp/restore-test
	# - `--copy-back`：将备份数据复制到指定的数据目录。
	# - `--target-dir`：指定备份文件所在的目录。
	# - `--datadir`：指定模拟恢复的数据目录。
	# 如果模拟恢复过程中没有报错，说明备份文件可以正常恢复，完整性得到验证。恢复完成后，你可以查看临时目录中的文件是否与预期一致。
	
	# 5. 清理临时目录
	# 模拟恢复验证完成后，清理临时目录。
	[root@mha ~]# rm -rf /tmp/restore-test
	
	# 6. 启动 MySQL 服务
	# 如果之前停止了 MySQL 服务，现在可以启动它。
	[root@mha ~]# sudo systemctl start mysql
	
	# 通过以上步骤，你可以全面验证 Percona XtraBackup 差异备份文件的完整性，确保在需要恢复数据时能够顺利进行。 
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;备份方案案例&lt;/h2&gt;
&lt;p&gt;以下是一个完整的 MySQL 备份与恢复方案，包含使用 &lt;code&gt;mysqldump&lt;/code&gt; 进行定期全量备份、&lt;code&gt;Percona XtraBackup&lt;/code&gt; 进行日常增量和差异备份，以及在数据丢失时的恢复方法。&lt;/p&gt;
&lt;h3&gt;1. 环境准备&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;安装 &lt;code&gt;mysqldump&lt;/code&gt;&lt;/strong&gt;：&lt;code&gt;mysqldump&lt;/code&gt; 是 MySQL 自带的备份工具，通常在安装 MySQL 时会一并安装。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安装 &lt;code&gt;Percona XtraBackup&lt;/code&gt;&lt;/strong&gt;：根据你的操作系统，按照 Percona 官方文档进行安装。例如，在 Ubuntu 上可以使用以下命令：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb
sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb
sudo apt-get update
sudo apt-get install percona-xtrabackup-80
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 备份方案&lt;/h3&gt;
&lt;h4&gt;2.1 使用 &lt;code&gt;mysqldump&lt;/code&gt; 进行定期全量备份&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;mysqldump&lt;/code&gt; 适合进行全量备份，特别是对于较小的数据库。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;脚本示例（&lt;code&gt;full_backup.sh&lt;/code&gt;）&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash

# 数据库连接信息
DB_USER=&quot;your_username&quot;
DB_PASSWORD=&quot;your_password&quot;
DB_NAME=&quot;your_database_name&quot;
BACKUP_DIR=&quot;/path/to/backup&quot;

# 创建备份目录
mkdir -p $BACKUP_DIR

# 生成备份文件名
BACKUP_FILE=&quot;$BACKUP_DIR/$(date +%Y%m%d)_full_backup.sql&quot;

# 执行全量备份
mysqldump -u$DB_USER -p$DB_PASSWORD $DB_NAME &amp;gt; $BACKUP_FILE

# 检查备份是否成功
if [ $? -eq 0 ]; then
    echo &quot;Full backup completed successfully.&quot;
else
    echo &quot;Full backup failed.&quot;
fi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;定时任务&lt;/strong&gt;：使用 &lt;code&gt;crontab&lt;/code&gt; 每周执行一次全量备份。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 2 * * 0 /path/to/full_backup.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2.2 使用 &lt;code&gt;Percona XtraBackup&lt;/code&gt; 进行日常增量和差异备份&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;全量备份脚本（&lt;code&gt;full_xtrabackup.sh&lt;/code&gt;）&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash

# 数据库连接信息
DB_USER=&quot;your_username&quot;
DB_PASSWORD=&quot;your_password&quot;
BACKUP_DIR=&quot;/path/to/backup/xtrabackup&quot;

# 创建备份目录
mkdir -p $BACKUP_DIR

# 生成备份文件名
FULL_BACKUP_DIR=&quot;$BACKUP_DIR/$(date +%Y%m%d)_full&quot;
mkdir -p $FULL_BACKUP_DIR

# 执行全量备份
xtrabackup --user=$DB_USER --password=$DB_PASSWORD --backup --target-dir=$FULL_BACKUP_DIR

# 检查备份是否成功
if [ $? -eq 0 ]; then
    echo &quot;Full XtraBackup completed successfully.&quot;
else
    echo &quot;Full XtraBackup failed.&quot;
fi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;增量备份脚本（&lt;code&gt;incremental_backup.sh&lt;/code&gt;）&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash

# 数据库连接信息
DB_USER=&quot;your_username&quot;
DB_PASSWORD=&quot;your_password&quot;
BACKUP_DIR=&quot;/path/to/backup/xtrabackup&quot;

# 获取最新的全量备份目录
LAST_FULL_BACKUP=$(ls -d $BACKUP_DIR/*_full | tail -n 1)

# 生成增量备份目录
INCREMENTAL_BACKUP_DIR=&quot;$BACKUP_DIR/$(date +%Y%m%d)_incremental&quot;
mkdir -p $INCREMENTAL_BACKUP_DIR

# 执行增量备份
xtrabackup --user=$DB_USER --password=$DB_PASSWORD --backup --target-dir=$INCREMENTAL_BACKUP_DIR --incremental-basedir=$LAST_FULL_BACKUP

# 检查备份是否成功
if [ $? -eq 0 ]; then
    echo &quot;Incremental backup completed successfully.&quot;
else
    echo &quot;Incremental backup failed.&quot;
fi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;定时任务&lt;/strong&gt;：每周执行一次全量备份，每天执行一次增量备份。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 2 * * 0 /path/to/full_xtrabackup.sh
0 3 * * 1-6 /path/to/incremental_backup.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 恢复方案&lt;/h3&gt;
&lt;h4&gt;3.1 使用 &lt;code&gt;mysqldump&lt;/code&gt; 恢复数据&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql -u your_username -p your_password your_database_name &amp;lt; /path/to/backup/20240101_full_backup.sql
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3.2 使用 &lt;code&gt;Percona XtraBackup&lt;/code&gt; 恢复数据&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;步骤 1：准备全量备份&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;xtrabackup --prepare --target-dir=/path/to/backup/xtrabackup/20240101_full
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤 2：应用增量备份&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;xtrabackup --prepare --target-dir=/path/to/backup/xtrabackup/20240101_full --incremental-dir=/path/to/backup/xtrabackup/20240102_incremental
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤 3：停止 MySQL 服务&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl stop mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤 4：恢复备份数据&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo rm -rf /var/lib/mysql/*
sudo xtrabackup --copy-back --target-dir=/path/to/backup/xtrabackup/20240101_full
sudo chown -R mysql:mysql /var/lib/mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤 5：启动 MySQL 服务&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl start mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、作业&lt;/h2&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;以下哪种备份方式能在备份时不锁表，从而不影响 MySQL 数据库的正常读写操作？ B
A. mysqldump 全量备份
B. PERCONA Xtrabackup 全量备份
C. mysqldump 增量备份
D. 以上都不能&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用 PERCONA Xtrabackup 进行增量备份时，基于的基础备份是？A
A. 上一次的全量备份
B. 上一次的增量备份
C. 上一次的差异备份
D. 任意一次备份&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;当使用 mysqldump 备份数据库时，若要备份所有数据库，应使用以下哪个参数？ A
A. --all-databases
B. --database-all
C. --full-databases
D. --every-database&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PERCONA Xtrabackup 的差异备份恢复时，依赖于？A
A. 最新的全量备份和后续的差异备份
B. 最新的增量备份和后续的差异备份
C. 最早的全量备份和所有后续备份
D. 任意一次全量备份和差异备份&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;若要使用 PERCONA Xtrabackup 进行增量备份，需要记录上一次备份的什么信息？ C
A. 备份文件大小
B. 备份文件位置
C. 备份的 LSN（日志序列号）
D. 备份的时间戳&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;简述 mysqldump、PERCONA Xtrabackup 增量备份和差异备份的优缺点。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;	答：
	 mysqldump：
		 优点：灵活，可以针对单表或多表和单数据库或多数据进行备份还原
		 缺点：备份和恢复数据时会锁表，锁表期间无法对表做写访问。只适合备份数据量比较小的数据或在数据库服务器访问量少的时候备份。
		 
	 PERCONA Xtrabackup 增量备份：
		 优点：备份速度快，占用空间小，因为每次只备份变化的数据。
		 缺点：恢复数据时，需要先恢复完整备份，然后按照时间顺序依次恢复所有的增量备份，直到指定的时间点。恢复过程复杂且耗时，如果中间任何一个备份损坏，可能导致整个恢复链失效。
		 
	 PERCONA Xtrabackup 差异备份：
		 优点：恢复时只需要完整备份和最近一次的差异备份，恢复过程相对简单。
		 缺点：随着时间推移，差异备份的大小会越来越大，因为每次都要备份自完整备份以来的所有变化。备份时间可能会逐渐增加。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;阐述在什么业务场景下适合使用 PERCONA Xtrabackup 的增量备份，什么场景适合使用差异备份。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;	答：
	增量备份：
		 数据量大，备份窗口短，但对恢复时间要求不高的场景。
			
	差异备份：
		数据量变化不大，且希望恢复过程相对简单的场景。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;说明在进行 MySQL 数据库恢复时，全量备份、增量备份和差异备份的恢复顺序及原因。
答：
全量备份恢复步骤：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;	# 停止 MySQL 服务。在恢复备份之前，需要停止正在运行的 MySQL 服务，以避免数据冲突。
	[root@mha ~]# sudo systemctl stop mysql
	# 清空 MySQL 数据目录。为了确保恢复的数据是完整的，需要清空 MySQL 数据目录中的现有数据。
	[root@mha ~]# sudo rm -rf /var/lib/mysql/*
	# 预处理备份数据。应用重做日志（redo log）到数据文件，将数据文件前滚到备份结束时的状态，使备份数据处于一致状态，可以用于恢复。
	[root@mha ~]# sudo xtrabackup --prepare --target-dir=/path/to/backup
	# 恢复备份数据。将备份数据复制到 MySQL 数据目录。
	[root@mha ~]# sudo xtrabackup --copy-back --target-dir=/path/to/backup
	# 修改文件权限。恢复数据后，需要确保 MySQL 数据目录及其文件的权限正确。
	[root@mha ~]# sudo chown -R mysql:mysql /var/lib/mysql
	# 启动 MySQL 服务。完成上述步骤后，可以启动 MySQL 服务。
	[root@mha ~]# sudo systemctl start mysql
	# 验证恢复结果。可以登录 MySQL 并检查数据库和表是否已成功恢复。
	[root@mha ~]# mysql -u root -p
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;增量备份恢复步骤：
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;	#准备恢复数据。使用 `--apply-log-only`只应用重做日志，不回滚为后续增量备份应用做准备。因为在增量备份中，基础备份必须保持事务状态，以便后续的增量备份能够正确应用。如果提前回滚了未提交事务，那么增量备份应用时可能会丢失一些事务信息。
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak
	#合并增量数据，需要把所有的增量备份数据全部合并，不然会造成数据缺失
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak --incremental-dir=/new1
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak --incremental-dir=/new2
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak --incremental-dir=/new3
	# 停止 MySQL 服务。在恢复备份之前，需要停止正在运行的 MySQL 服务，以避免数据冲突。
	[root@mha ~]# sudo systemctl stop mysql
	# 清空 MySQL 数据目录。为了确保恢复的数据是完整的，需要清空 MySQL 数据目录中的现有数据。
	[root@mha ~]# sudo rm -rf /var/lib/mysql/*
	# 最终准备预处理备份数据。应用重做日志（redo log）到数据文件，将数据文件前滚到备份结束时的状态，使备份数据处于一致状态，可以用于恢复。
	[root@mha ~]# sudo xtrabackup --prepare --target-dir=/fullbak
	# 恢复备份数据。将备份数据复制到 MySQL 数据目录。
	[root@mha ~]# sudo xtrabackup --copy-back --target-dir=/fullbak
	# 修改文件权限。恢复数据后，需要确保 MySQL 数据目录及其文件的权限正确。
	[root@mha ~]# sudo chown -R mysql:mysql /var/lib/mysql
	# 启动 MySQL 服务。完成上述步骤后，可以启动 MySQL 服务。
	[root@mha ~]# sudo systemctl start mysql
	# 验证恢复结果。可以登录 MySQL 并检查数据库和表是否已成功恢复。
	[root@mha ~]# mysql -u root -p
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;差异备份恢复步骤：
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;	#准备恢复数据。使用 `--apply-log-only`只应用重做日志，不回滚为后续增量备份应用做准备。因为在增量备份中，基础备份必须保持事务状态，以便后续的增量备份能够正确应用。如果提前回滚了未提交事务，那么增量备份应用时可能会丢失一些事务信息。
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/fullbak
	#合并差异数据，只需要把全量数据和最后一次的差异数据合并，但暂不完成最终一致性
	[root@mha ~]# sudo xtrabackup --prepare --target-dir=/fullbak --incremental-dir=/dir7
	# 停止 MySQL 服务。在恢复备份之前，需要停止正在运行的 MySQL 服务，以避免数据冲突。
	[root@mha ~]# sudo systemctl stop mysql
	# 清空 MySQL 数据目录。为了确保恢复的数据是完整的，需要清空 MySQL 数据目录中的现有数据。
	[root@mha ~]# sudo rm -rf /var/lib/mysql/*
	# 最终准备预处理备份数据。应用重做日志（redo log）到数据文件，将数据文件前滚到备份结束时的状态，使备份数据处于一致状态，可以用于恢复。
	[root@mha ~]# sudo xtrabackup --prepare --target-dir=/fullbak
	# 恢复备份数据。将备份数据复制到 MySQL 数据目录。
	[root@mha ~]# sudo xtrabackup --copy-back --target-dir=/fullbak
	# 修改文件权限。恢复数据后，需要确保 MySQL 数据目录及其文件的权限正确。
	[root@mha ~]# sudo chown -R mysql:mysql /var/lib/mysql
	# 启动 MySQL 服务。完成上述步骤后，可以启动 MySQL 服务。
	[root@mha ~]# sudo systemctl start mysql
	# 验证恢复结果。可以登录 MySQL 并检查数据库和表是否已成功恢复。
	[root@mha ~]# mysql -u root -p
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;比较 mysqldump 和 PERCONA Xtrabackup 在备份和恢复过程中对数据库性能的影响。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;答：
	mysqldump：
		在备份和恢复数据时会通过锁表保证一致性，影响写操作，锁表期间无法对表做写访问
	PERCONA Xtrabackup：
		利用InnoDB的MVCC机制，实现热备份，几乎不影响业务
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3 操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;请写出使用 mysqldump 对指定一个数据库进行全量备份，并将备份文件存储到“/backup/sales_full_backup.sql”的完整命令。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;	[root@mha ~]# mysqldump -uroot -p123 -B moershi &amp;gt; /backup/sales_full_backup.sql
	mysqldump: [Warning] Using a password on the command line interface can be insecure.
	[root@mha ~]# ls /backup
	sales_full_backup.sql
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;假设已经有一个 PERCONA Xtrabackup 的全量备份，之后数据库有了新的数据更新，写出进行一次增量备份的操作步骤和相应命令。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;	[root@mha ~]# xtrabackup --host=127.0.0.1 --user=root --password=123 --backup --target-dir=/增量备份保存路径 --incremenntal-basedir=/全量备份保存路径 --datadir=/mysql数据路径
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;若数据库因磁盘故障丢失部分数据，现有一个全量备份和若干个 PERCONA Xtrabackup 的差异备份文件，请详细描述恢复数据库的操作过程和命令。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;	1.准备恢复数据,预处理只应用重做日志，不回滚为后续备份应用做准备。
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/全量备份数据
	
	2.合并差异数据，只需要把一个全量备份数据和最后一次的差异备份数据合并，但暂不完成最终一致性
	[root@mha ~]# sudo xtrabackup --prepare --target-dir=/全量备份数据 --incremental-dir=/差异备份数据
	
	3.停止 MySQL 服务。在恢复备份之前，需要停止正在运行的 MySQL 服务，以避免数据冲突。
	[root@mha ~]# sudo systemctl stop mysql
	
	4.清空 MySQL 数据目录。为了确保恢复的数据是完整的，需要清空 MySQL 数据目录中的现有数据。
	[root@mha ~]# sudo rm -rf /var/lib/mysql/*
	
	5.最终准备预处理备份数据。应用重做日志（redo log）到数据文件，将数据文件前滚到备份结束时的状态，使备份数据处于一致状态，可以用于恢复。
	[root@mha ~]# sudo xtrabackup --prepare --target-dir=/全量备份数据
	
	6.恢复备份数据。将备份数据复制到 MySQL 数据目录。
	[root@mha ~]# sudo xtrabackup --copy-back --target-dir=/全量备份数据
	
	7.修改文件权限。恢复数据后，需要确保 MySQL 数据目录及其文件的权限正确。
	[root@mha ~]# sudo chown -R mysql:mysql /var/lib/mysql
	
	8.启动 MySQL 服务。完成上述步骤后，可以启动 MySQL 服务。
	[root@mha ~]# sudo systemctl start mysql
	
	9.验证恢复结果。可以登录 MySQL 并检查数据库和表是否已成功恢复。
	[root@mha ~]# mysql -u root -p
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;使用 PERCONA Xtrabackup 进行差异备份时，如何验证备份文件的完整性？写出具体步骤和命令。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;	1. 准备备份
	在验证之前，需要对备份进行准备操作，以应用事务日志，使备份数据处于一致状态。

	[root@mha ~]# xtrabackup --prepare --target-dir=/path/to/backup

	
	2. 检查备份元数据文件
	备份完成后，XtraBackup 会生成一个名为 `xtrabackup_info` 的元数据文件，该文件包含了备份的相关信息，如备份类型、开始时间、结束时间等。可以查看这个文件来初步验证备份的基本信息是否正确。

	[root@mha ~]# cat /path/to/backup/xtrabackup_info

	查看输出内容，确认备份类型为差异备份（`incremental`），并且各项时间信息和其他元数据是否合理。
	
	3. 检查备份文件的完整性
	可以使用 `xtrabackup --stats` 命令来检查备份文件中的数据页和事务日志的完整性。

	[root@mha ~]# xtrabackup --stats --target-dir=/path/to/backup

	如果备份文件完整，命令执行后会输出详细的统计信息，包括数据页的数量、事务日志的大小等。如果备份文件存在损坏，该命令可能会报错。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;请设计一个完整的 MySQL 备份与恢复方案，包括使用 mysqldump 进行定期全量备份、PERCONA Xtrabackup 进行日常增量和差异备份，并描述在数据丢失时如何利用这些备份进行恢复。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;一。备份方案
1 使用 `crontab` 和 `mysqldump` 进行定期全量备份
0 2 * * 0 /bin/mysqldump -uroot -p123 -A &amp;gt; /backup/sql/all_$(date +%Y-%m-%d_%H-%M-%S).sql 

2 使用 `Percona XtraBackup` 进行日常增量和差异备份

全量备份脚本
#!/bin/bash

# 数据库连接信息
DB_USER=&quot;root&quot;
DB_PASSWORD=&quot;123&quot;
BACKUP_DIR=&quot;/fullbak&quot;

# 创建备份目录
mkdir -p $BACKUP_DIR

# 生成备份文件名
FULL_BACKUP_DIR=&quot;$BACKUP_DIR/$(date +%Y%m%d)_full&quot;
mkdir -p $FULL_BACKUP_DIR

# 执行全量备份
xtrabackup --host=127.0.0.1  --user=$DB_USER --password=$DB_PASSWORD --backup --target-dir=$FULL_BACKUP_DIR --datadir=/var/lib/mysql

# 检查备份是否成功
if [ $? -eq 0 ]; then
    echo &quot;Full XtraBackup completed successfully.&quot;
else
    echo &quot;Full XtraBackup failed.&quot;
fi


增量备份脚本
#!/bin/bash

# 数据库连接信息
DB_USER=&quot;root&quot;
DB_PASSWORD=&quot;123&quot;
BACKUP_DIR=&quot;/fullbak&quot;

# 获取最新的全量备份目录
LAST_FULL_BACKUP=$(ls -d $BACKUP_DIR/*_full | tail -n 1)

# 生成增量备份目录
INCREMENTAL_BACKUP_DIR=&quot;$BACKUP_DIR/$(date +%Y%m%d)_incremental&quot;
mkdir -p $INCREMENTAL_BACKUP_DIR

# 执行增量备份
xtrabackup --host=127.0.0.1 --user=$DB_USER --password=$DB_PASSWORD --backup --target-dir=$INCREMENTAL_BACKUP_DIR --incremental-basedir=$LAST_FULL_BACKUP --datadir=/var/lib/mysql

# 检查备份是否成功
if [ $? -eq 0 ]; then
    echo &quot;Incremental backup completed successfully.&quot;
else
    echo &quot;Incremental backup failed.&quot;
fi


定时任务：每周执行一次全量备份，每天执行一次增量备份。
0 2 * * 0 /全量备份脚本
0 3 * * 1-6 /增量备份脚本


二. 恢复方案

1 使用 `mysqldump` 恢复数据
	mysql -uroot -p123 -A &amp;lt; /backup/sql/all_指定恢复时间版本.sql 

2 使用 `Percona XtraBackup` 恢复数据

	#准备恢复数据。
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/全量备份路径
	#合并增量数据
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/全量备份路径 --incremental-dir=/增量备份路径1
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/全量备份路径 --incremental-dir=/增量备份路径2
	[root@mha ~]# sudo xtrabackup --prepare --apply-log-only --target-dir=/全量备份路径 --incremental-dir=/增量备份路径3
	# 停止 MySQL 服务。
	[root@mha ~]# sudo systemctl stop mysql
	# 清空 MySQL 数据目录。
	[root@mha ~]# sudo rm -rf /var/lib/mysql/*
	# 最终准备预处理备份数据。
	[root@mha ~]# sudo xtrabackup --prepare --target-dir=/全量备份路径
	# 恢复备份数据。
	[root@mha ~]# sudo xtrabackup --copy-back --target-dir=/全量备份路径
	# 修改文件权限。
	[root@mha ~]# sudo chown -R mysql:mysql /var/lib/mysql
	# 启动 MySQL 服务。
	[root@mha ~]# sudo systemctl start mysql
	# 验证恢复结果。
	[root@mha ~]# mysql -u root -p
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;作业的详细检查&lt;/h2&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;第 1 题&lt;/strong&gt;：答案正确。&lt;code&gt;PERCONA Xtrabackup&lt;/code&gt; 全量备份利用 InnoDB 的 MVCC 机制实现热备份，备份时不锁表，不影响数据库正常读写操作；而 &lt;code&gt;mysqldump&lt;/code&gt; 备份时会锁表。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 2 题&lt;/strong&gt;：答案正确。&lt;code&gt;PERCONA Xtrabackup&lt;/code&gt; 进行增量备份时，基于上一次的全量备份。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 3 题&lt;/strong&gt;：答案正确。&lt;code&gt;--all - databases&lt;/code&gt; 是 &lt;code&gt;mysqldump&lt;/code&gt; 用于备份所有数据库的参数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 4 题&lt;/strong&gt;：答案正确。&lt;code&gt;PERCONA Xtrabackup&lt;/code&gt; 的差异备份恢复时，依赖于最新的全量备份和后续的差异备份。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 5 题&lt;/strong&gt;：答案错误。若要使用 &lt;code&gt;PERCONA Xtrabackup&lt;/code&gt; 进行增量备份，需要记录上一次备份的 LSN（日志序列号），而不是备份文件位置。所以正确答案选 C。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;第 1 题&lt;/strong&gt;：回答准确，清晰阐述了 &lt;code&gt;mysqldump&lt;/code&gt;、&lt;code&gt;PERCONA Xtrabackup&lt;/code&gt; 增量备份和差异备份的优缺点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 2 题&lt;/strong&gt;：回答合理，增量备份适合数据量大、备份窗口短且对恢复时间要求不高的场景；差异备份适合数据量变化不大且希望恢复过程相对简单的场景。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 3 题&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;回答内容整体正确，但存在一个小问题，在增量备份和差异备份准备恢复数据的注释中，提到“因为在增量备份中，基础备份必须保持事务状态，以便后续的增量备份能够正确应用”，这里应该是为了后续的增量或差异备份能够正确应用，表述不够严谨。&lt;/li&gt;
&lt;li&gt;另外，在代码中路径使用 &lt;code&gt;/fullbak&lt;/code&gt;、&lt;code&gt;/new1&lt;/code&gt; 等应该是示例，实际操作需要替换为真实路径。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 4 题&lt;/strong&gt;：回答正确，准确比较了 &lt;code&gt;mysqldump&lt;/code&gt; 和 &lt;code&gt;PERCONA Xtrabackup&lt;/code&gt; 在备份和恢复过程中对数据库性能的影响。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3 操作题&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;第 1 题&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;命令基本正确，但需要注意的是，使用 &lt;code&gt;-p&lt;/code&gt; 后面直接跟密码会有安全风险，实际操作中建议不直接写密码，而是在提示时输入。同时，&lt;code&gt;-B&lt;/code&gt; 选项用于指定数据库，这里 &lt;code&gt;moershi&lt;/code&gt; 应该是你要备份的数据库名，如果需要备份 &lt;code&gt;sales&lt;/code&gt; 数据库，应该将 &lt;code&gt;moershi&lt;/code&gt; 替换为 &lt;code&gt;sales&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 2 题&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;命令存在拼写错误，&lt;code&gt;--incremenntal - basefir&lt;/code&gt; 应该为 &lt;code&gt;--incremental - basedir&lt;/code&gt;。正确的命令为：&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;[root@mha ~]# xtrabackup --host=127.0.0.1 --user=root --password=123 --backup --target-dir=/增量备份保存路径 --incremental-basedir=/全量备份保存路径 --datadir=/mysql数据路径
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;- 同样，路径需要替换为实际路径。
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;第 3 题&lt;/strong&gt;：回答正确，详细描述了使用全量备份和差异备份恢复数据库的操作过程和命令。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 4 题&lt;/strong&gt;：回答正确，给出了验证 &lt;code&gt;PERCONA Xtrabackup&lt;/code&gt; 差异备份文件完整性的具体步骤和命令。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 5 题&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;备份方案：
&lt;ul&gt;
&lt;li&gt;使用 &lt;code&gt;crontab&lt;/code&gt; 和 &lt;code&gt;mysqldump&lt;/code&gt; 进行定期全量备份的命令基本正确，但密码使用方式存在安全风险，建议使用更安全的方式存储密码。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Percona XtraBackup&lt;/code&gt; 进行全量、增量备份脚本和定时任务设置思路正确，但路径需要替换为实际路径。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;恢复方案：
&lt;ul&gt;
&lt;li&gt;使用 &lt;code&gt;mysqldump&lt;/code&gt; 恢复数据的命令中，&lt;code&gt;$(date +%Y - %m - %d_%H - %M - %S)&lt;/code&gt; 会获取当前时间，应该指定具体的备份文件时间，而不是当前时间。&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;Percona XtraBackup&lt;/code&gt; 恢复数据的步骤正确，但路径需要替换为实际路径。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;总体来说，作业完成情况较好，但存在一些小错误和需要注意的安全问题，希望你能及时修改完善。&lt;/p&gt;
&lt;h1&gt;09：mysql之主从复制&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250616165058217.webp&quot; alt=&quot;image-20250616165058217&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;在一家电商公司，其业务涵盖商品展示、订单处理、用户管理等，数据库中存储着海量的商品信息、用户数据和交易记录。随着业务的快速发展，数据库的读写压力与日俱增。为了缓解数据库压力，提高系统的可用性和数据安全性，公司决定采用 MySQL 主从复制架构。&lt;/p&gt;
&lt;p&gt;主数据库负责处理所有的写操作，如商品信息更新、订单创建等。从数据库则实时同步主数据库的数据，负责处理大量的读操作，如商品查询、用户信息展示等。通过这种方式，有效地分担了数据库的负载，提高了系统的响应速度。同时，当主数据库出现故障时，可以快速将业务切换到从数据库，保障业务的连续性。&lt;/p&gt;
&lt;h2&gt;二、为什么学&lt;/h2&gt;
&lt;p&gt;学习 MySQL 主从复制有诸多重要意义。在企业应用层面，随着业务增长，数据库面临读写压力大的问题，主从复制可将读操作分发到从库，减轻主库负担，提升系统性能和响应速度，保障业务流畅运行。在数据安全与备份方面，从库是主库数据的实时副本，当主库出现故障，可快速切换到从库继续服务，降低数据丢失风险，保证业务连续性。此外，掌握主从复制也是提升个人技术能力的关键一步，如今数据库技术广泛应用，精通此技术能增强职场竞争力，为从事数据库管理、开发等工作奠定坚实基础。&lt;/p&gt;
&lt;h2&gt;三、binlog【宾-劳格】日志&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250616165129789.webp&quot; alt=&quot;image-20250616165129789&quot; /&gt;&lt;/p&gt;
&lt;p&gt;binlog【宾-劳格】日志介绍：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;也称做 二进制日志&lt;/li&gt;
&lt;li&gt;MySQL服务日志文件的一种&lt;/li&gt;
&lt;li&gt;保存除查询之外的所有SQL命令m&lt;/li&gt;
&lt;li&gt;可用于数据的备份和恢复&lt;/li&gt;
&lt;li&gt;配置mysql主从同步的必要条件&lt;/li&gt;
&lt;li&gt;准备新的数据库服务器如表-1，做binlog【宾-劳格】&lt;/li&gt;
&lt;/ol&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;mysql52&lt;/td&gt;
&lt;td&gt;192.168.90.52&lt;/td&gt;
&lt;td&gt;练习binlog【宾-劳格】日志&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;mysql52的IP配置和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.52/24 autoconnect【奥特欧 坑聂特】 yes
#[root@slave2 ~]# nmcli connection modify ens160 ipv4.addresses 192.168.90.52/24 autoconnect yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
#[root@slave2 ~]# nmcli connection up ens160
[root@mysql52 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql52
#[root@slave2 ~]# hostnamectl set-hostname mysql52
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.1 查看正在使用的binlog【宾-劳格】日志文件&lt;/h3&gt;
&lt;p&gt;在新创建的数据库服务器做如下操作:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 安装软件 
[root@mysql52 ~]# yum -y install【因-斯多】 mysql-server  
# [root@slave2 ~]# yum -y install mysql-server 

# 启动服务
[root@mysql52 ~]# systemctl【西斯屯-ctl】   start【s 达儿】 mysqld  
# [root@slave2 ~]# systemctl status mysqld

# 连接服务
[root@mysql52 ~]# mysql  
# [root@mysql52 ~]# mysql

# 查看日志文件
mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】; 
# mysql&amp;gt; show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| binlog.000001 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

# 执行查询命令 
mysql&amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】  mysql.user;
# mysql&amp;gt; select count(*) from mysql.user;
+-------------------+
| count【kàn特】(*) |
+-------------------+
|        4          |
+-------------------+
1 row in set (0.00 sec)

# 执行查询命令 日志偏移量不变
mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】; 
# mysql&amp;gt; show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| binlog.000001 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

# 执行建库、建表命令
mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】  db1;
# mysql&amp;gt; create database db1;
Query OK, 1 row affected (0.07 sec)

mysql&amp;gt; create【克瑞特】 table【忒-部】 db1.user(name char【查尔】(10));
# mysql&amp;gt; create table db1.user(name char(10));
Query OK, 0 rows affected (0.52 sec)

# 执行写命令 日志偏移量改变
mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】; 
# mysql&amp;gt; show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| binlog.000001 |      535 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

# 插入记录
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.user values【挖柳斯】(&quot;jim&quot;); 
# mysql&amp;gt; insert into db1.user values(&quot;jim&quot;);
Query OK, 1 row affected (0.10 sec)

# 执行写命令 日志偏移量改变
mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】; 
# mysql&amp;gt; show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| binlog.000001 |      809 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 自定义日志目录和日志名&lt;/h3&gt;
&lt;p&gt;日志文件默认保存在/var/lib/mysql目录下，默认日志名binlog【宾-劳格】&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql52 ~]# vim /etc/my.cnf.d/mysql-server.cnf 
[mysqld]
log-bin=/mylog/mysql52   #定义日志目录和日志文件名(手动添加)
:wq

[root@mysql52 ~]# mkdir【摸克跌儿】 /mylog  创建目录
[root@mysql52 ~]# chown【吃-昂】  mysql  /mylog   修改目录所有者mysql用户
[root@mysql52 ~]# setenforce【赛特-因佛尔斯】  0   关闭selinux
[root@mysql52 ~]# systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld   重启服务
[root@mysql52 ~]# ls /mylog/  查看日志目录
mysql52.000001  mysql52.index
[root@mysql52 ~]# mysql  登陆服务

Mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】 ； 查看日志信息
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql52.000001 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3 手动创建新的日志文件&lt;/h3&gt;
&lt;p&gt;默认日志文件容量大于1G时会自动创建新的日志文件，在日志文件没写满时，执行的所有写命令都会保存到当前使用的日志文件里。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#刷新前查看
mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql52.000001 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql&amp;gt; flush【福 辣 徐】 logs【劳格斯】; #刷新日志
Query OK, 0 rows affected (0.22 sec)

mysql&amp;gt; flush【福 辣 徐】 logs【劳格斯】; #刷新日志
Query OK, 0 rows affected (0.16 sec)

mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】; #刷新一次创建一个新日志
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql52.000003 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

#只要服务重启就会创建新日志
[root@mysql52 ~]# systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld 
[root@mysql52 ~]# mysql  连接服务

Mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】; 查看日志
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql52.000004 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
[root@mysql52 ~]#

#完全备份后创建新的日志文件，创建的日志个数和备份库的个数一致
[root@mysql52 ~]# mysqldump【mysql-当普】  --flush【福 辣 徐】-logs【劳格斯】  mysql user &amp;gt; user.sql

[root@mysql52 ~]# mysql -e &apos;show【瘦】  master【马斯特】 status【 斯dèi 特斯】&apos;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql52.000005 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
[root@mysql52 ~]# mysqldump【mysql-当普】  --flush【福 辣 徐】-logs【劳格斯】  -B mysql db1 &amp;gt; db_2.sql

[root@mysql52 ~]# mysql -e &apos;show【瘦】  master【马斯特】 status【 斯dèi 特斯】&apos;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql52.000007 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
[root@mysql52 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.4 日志相关命令的使用&lt;/h3&gt;
&lt;p&gt;MySQL服务提供了管理日志的专属命令，具体练习如下:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#查看已有的日志文件
mysql&amp;gt;  show【瘦】 binary【拜讷瑞】  logs【劳格斯】;
日志文件名        日志大小(字节)  加密（no/yes）
+----------------+-----------+-----------+
| Log_name       | File_size | Encrypted |
+----------------+-----------+-----------+
| mysql52.000001 |       201 | No        |
| mysql52.000002 |       201 | No        |
| mysql52.000003 |       179 | No        |
| mysql52.000004 |       201 | No        |
| mysql52.000005 |       201 | No        |
| mysql52.000006 |       201 | No        |
| mysql52.000007 |       156 | No        |
+----------------+-----------+-----------+
7 rows in set (0.00 sec)

#查看正在使用的日志
mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql52.000007 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

#插入记录
mysql&amp;gt; insert【因涩特】 into【因兔】 db1.user values【挖柳斯】(&quot;yaya&quot;);
Query OK, 1 row affected (0.04 sec)

#查看日志文件内容
mysql&amp;gt;  show【瘦】 binlog【宾-劳格】 events【伊文茨】 in  &quot;mysql52.000007&quot;;
Log_name：   日志文件名。
Pos：         命令在日志文件中的起始位置。
Event_type： 事件类型，例如 Query、Table_map、Write_rows 等。
Server_id：  服务器 ID。
End_log_pos：命令在文件中的结束位置，以字节为单位。
Info：执行命令信息。
+----------------+-----+----------------+-----------+-------------+--------------------------------------+
| Log_name       | Pos | Event_type     | Server_id | End_log_pos | Info                                 |
+----------------+-----+----------------+-----------+-------------+--------------------------------------+
| mysql52.000007 |   4 | Format_desc    |         1 |         125 | Server ver: 8.0.26, Binlog ver: 4    |
| mysql52.000007 | 125 | Previous_gtids |         1 |         156 |                                      |
| mysql52.000007 | 156 | Anonymous_Gtid |         1 |         235 | SET @@SESSION.GTID_NEXT= &apos;ANONYMOUS&apos; |
| mysql52.000007 | 235 | Query          |         1 |         306 | BEGIN                                |
| mysql52.000007 | 306 | Table_map      |         1 |         359 | table_id: 108 (db1.user)             |
| mysql52.000007 | 359 | Write_rows     |         1 |         400 | table_id: 108 flags: STMT_END_F      |
| mysql52.000007 | 400 | Xid            |         1 |         431 | COMMIT /* xid=649 */                 |
+----------------+-----+----------------+-----------+-------------+--------------------------------------+
7 rows in set (0.00 sec)

#删除日志文件名之前的所有日志文件
mysql&amp;gt; purge【pò取】  master【马斯特】 logs【劳格斯】  to  &quot;mysql52.000004&quot;;
Query OK, 0 rows affected (0.10 sec)

#查看已有的日志文件
mysql&amp;gt;  show【瘦】 binary【拜讷瑞】 logs【劳格斯】;
+----------------+-----------+-----------+
| Log_name       | File_size | Encrypted |
+----------------+-----------+-----------+
| mysql52.000004 |       201 | No        |
| mysql52.000005 |       201 | No        |
| mysql52.000006 |       201 | No        |
| mysql52.000007 |       431 | No        |
+----------------+-----------+-----------+
4 rows in set (0.00 sec)

#删除所有日志文件，并重新创建日志文件
mysql&amp;gt; reset【瑞 赛特】 master【马斯特】;
Query OK, 0 rows affected (0.14 sec)

#查看已有的日志文件 ，仅有第1个文件了
mysql&amp;gt;  show【瘦】 binary【拜讷瑞】 logs【劳格斯】;
+----------------+-----------+-----------+
| Log_name       | File_size | Encrypted |
+----------------+-----------+-----------+
| mysql52.000001 |       156 | No        |
+----------------+-----------+-----------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.5 使用日志恢复数据&lt;/h3&gt;
&lt;p&gt;把查看到的文件内容管道给连接mysql服务的命令执行&lt;/p&gt;
&lt;p&gt;恢复数据命令：&lt;/p&gt;
&lt;p&gt;mysqlbinlog【宾-劳格】 /目录/文件名 | mysql –uroot -p密码&lt;/p&gt;
&lt;p&gt;1）在mysql52主机执行如下操：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#重置日志
mysql&amp;gt; reset【瑞 赛特】 master【马斯特】;
Query OK, 0 rows affected (0.09 sec)

#查看日志
mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql52.000001 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

#建库、
mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】 gamedb;
Query OK, 1 row affected (0.07 sec)

#建表
mysql&amp;gt; create【克瑞特】 table【忒-部】 gamedb.t1(name char【查尔】(10),class【克拉斯】 char【查尔】(3));
Query OK, 0 rows affected (0.55 sec)

#插入记录
mysql&amp;gt; insert【因涩特】 into【因兔】 gamedb.t1 values【挖柳斯】 (&quot;yaya&quot;,&quot;nsd&quot;);
Query OK, 1 row affected (0.08 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 gamedb.t1 values【挖柳斯】 (&quot;yaya&quot;,&quot;nsd&quot;);
Query OK, 1 row affected (0.04 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 gamedb.t1 values【挖柳斯】 (&quot;yaya&quot;,&quot;nsd&quot;);
Query OK, 1 row affected (0.08 sec)

#查看表记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 gamedb.t1;
+------+----------------+
| name | class【克拉斯】 |
+------+----------------+
| yaya | nsd            |
| yaya | nsd            |
| yaya | nsd            |
+------+----------------+
3 rows in set (0.00 sec)
mysql&amp;gt; exit【诶西特】
#把日志文件拷贝给恢复数据的服务器,比如 mysql50
[root@mysql52 ~]# scp  /mylog/mysql52.000001 root@192.168.90.50:/root/
The authenticity of host &apos;192.168.90.50 (192.168.90.50)&apos; can&apos;t be established.
ECDSA key fingerprint is SHA256:t7J3okFd0o+9zTmFCIetvDl6mxGCmc43VoD6C65zico.
Are you sure you want to continue connecting (yes/no/[fingerprint])? Yes 同意
Warning: Permanently added &apos;192.168.90.50&apos; (ECDSA) to the list of known hosts.
root@192.168.90.50&apos;s password:  mysql50的密码
mysql52.000001                                                              100% 1410     1.6MB/s   00:00    
[root@mysql52 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）在MySQL50 使用日志恢复数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#查看日志
[root@mysql50 ~]# ls /root/mysql52.000001 
/root/mysql52.000001

#执行日志恢复数据
[root@mysql50 ~]# mysqlbinlog【mtsql宾-劳格】 /root/mysql52.000001 | mysql -uroot -pNSD123456...a
mysql: [Warning] Using a password on【昂】 the command line interface can be insecure.

#连接服务查看数据
[root@mysql50 ~]# mysql -uroot -pNSD123456...a -e &apos;selectt【涩莱克特】 * from【弗乱】 gamedb.t1&apos;
mysql: [Warning] Using a password on【昂】 the command line interface can be insecure.
 +------+----------------+
| name | class【克拉斯】  |
 +------+----------------+
| yaya | nsd             |
| yaya | nsd             |
| yaya | nsd             |
 +------+----------------+
[root@mysql50 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、MySQL一主一从&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250616165155177.webp&quot; alt=&quot;image-20250616165155177&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;4.1 mysql主从复制原理&lt;/h3&gt;
&lt;p&gt;MySQL主从复制基于二进制日志（binlog【宾-劳格】）实现。主要分为三步：
首先，主库上执行更新操作时，会将变更记录到二进制日志日志里。
其次，从库的I/O线程会连接主库，请求主库发送二进制日志日志。主库的二进制日志转储线程将日志内容发送给从库I/O线程，I/O线程把接收的日志写入从库的中继日志(Relay Log)。
最后，从库的SQL线程读取中继日志中的事件，并在从库上重放，实现主从数据一致。&lt;/p&gt;
&lt;p&gt;mysql主从复制原理&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;主库将数据变更（DDL和DML）记录到二进制日志（binlog）中。&lt;/li&gt;
&lt;li&gt;从库的I/O线程向主库的log dump线程请求binlog。&lt;/li&gt;
&lt;li&gt;主库的log dump线程将binlog事件发送给从库的I/O线程。&lt;/li&gt;
&lt;li&gt;从库的I/O线程将接收到的事件写入中继日志（relay log）。&lt;/li&gt;
&lt;li&gt;从库的SQL线程读取并解析relay log中的事件，在从库上执行这些事件，从而使从库与主库的数据保持同步。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250616160307840.webp&quot; alt=&quot;image-20250616160307840&quot; /&gt;&lt;/p&gt;
&lt;p&gt;准备两台服务器&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;mysql53&lt;/td&gt;
&lt;td&gt;192.168.90.53&lt;/td&gt;
&lt;td&gt;master【马斯特】数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mysql54&lt;/td&gt;
&lt;td&gt;192.168.90.54&lt;/td&gt;
&lt;td&gt;slave【斯累夫】数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;mysql53的IP配置和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.53/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mysql53 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql53
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mysql54的IP配置和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.54/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mysql54 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql54
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 配置为主数据库服务器&lt;/h3&gt;
&lt;p&gt;数据库服务器192.168.90.53配置为主数据库服务器&lt;/p&gt;
&lt;p&gt;1）启用binlog【宾-劳格】日志&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql53 ~]# yum -y  install【因-斯多】 mysql-server  mysql
[root@mysql53 ~]# systemctl【西斯屯-ctl】  start【s 达儿】 mysqld
[root@mysql53 ~]# vim /etc/my.cnf.d/mysql-server.cnf
[mysqld]
server-id=53
log-bin=mysql53
:wq
[root@mysql53 ~]# systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）用户授权&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql53 ~]# mysql

mysql&amp;gt; create【克瑞特】 user repluser@&quot;%&quot; identified【爱-丹-提伐】 WITH【威付】 mysql_native_password by &quot;123qqq...A&quot;;
Query OK, 0 rows affected (0.11 sec)

mysql&amp;gt; grant【古亮普】 replication【瑞普利K申】 slave【斯累夫】 on【昂】 *.*  to repluser@&quot;%&quot;;
Query OK, 0 rows affected (0.09 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3）查看日志信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt;  show【瘦】  master【马斯特】 status【 斯dèi 特斯】;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql53.000001 |      667 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.3 配置为从数据库服务&lt;/h3&gt;
&lt;p&gt;数据库服务器192.168.90.54配置为从数据库服务&lt;/p&gt;
&lt;p&gt;1)指定server-id 并重启数据库服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql54 ~]# yum -y  install【因-斯多】 mysql-server  mysql
[root@mysql54 ~]# systemctl【西斯屯-ctl】  start【s 达儿】 mysqld
[root@mysql54 ~]# vim /etc/my.cnf.d/mysql-server.cnf
[mysqld]
server-id=54
:wq
[root@mysql54 ~]# systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2)登陆服务指定主服务器信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql54 ~]# mysql
mysql&amp;gt; change【趁(chèn)吉】  master【马斯特】 to  master【马斯特】_host=&quot;192.168.90.53&quot; , master【马斯特】_user=&quot;repluser&quot; , master【马斯特】_password=&quot;123qqq...A&quot; ,master【马斯特】_log_file=&quot;mysql53.000001&quot; , master【马斯特】_log_pos=667;
Query OK, 0 rows affected, 8 warnings (0.34 sec)

mysql&amp;gt;  start【s 达儿】 slave【斯累夫】 ; #启动slave【斯累夫】进程
Query OK, 0 rows affected, 1 warning (0.04 sec)

mysql&amp;gt;  show【瘦】 slave【斯累夫】 status【 斯dèi 特斯】 \G  #查看状态信息
*************************** 1. row ***************************
               Slave【斯累夫】_IO_State: Waiting for source to send event
                  master【马斯特】_Host: 192.168.90.53
                  master【马斯特】_User: repluser
                  master【马斯特】_Port: 3306
                Connect_Retry: 60
              master【马斯特】_Log_File: mysql53.000001
          Read_master【马斯特】_Log_Pos: 667
               Relay_Log_File: mysql54-relay-bin.000002
                Relay_Log_Pos: 322
        Relay_master【马斯特】_Log_File: mysql53.000001
             Slave【斯累夫】_IO_Running: Yes   #IO线程
            Slave【斯累夫】_SQL_Running: Yes   #SQL线程
              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: 667
              Relay_Log_Space: 533
              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: 53
                  master【马斯特】_UUID: 38c02165-005e-11ee-bd2d-525400007271
             master【马斯特】_Info_File: mysql.slave【斯累夫】_master【马斯特】_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave【斯累夫】_SQL_Running_State: Replica 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: 
       master【马斯特】_public_key_path: 
        Get_master【马斯特】_public_key: 0
            Network_Namespace: 
1 row in set, 1 warning (0.00 sec)
mysql&amp;gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.4 客户端192.168.90.50测试配置&lt;/h3&gt;
&lt;p&gt;1）在主服务器添加用户，给客户端连接使用&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql53 ~]# mysql
mysql&amp;gt; create【克瑞特】 user jam@&quot;%&quot; identified【爱-丹-提伐】 by &quot;123456&quot;;
Query OK, 0 rows affected (0.14 sec)

mysql&amp;gt; grant【古亮普】 all【ò】 on【昂】 gamedb.* to jam@&quot;%&quot; ;
Query OK, 0 rows affected (0.12 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）客户端连接主服务器存储数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# mysql -h192.168.90.53 -ujam -p123456
mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】 gamedb;
Query OK, 1 row affected (0.24 sec)

mysql&amp;gt; create【克瑞特】 table【忒-部】 gamedb.user(name char【查尔】(10) , class【克拉斯】 char【查尔】(3));
Query OK, 0 rows affected (1.71 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 gamedb.user values【挖柳斯】 (&quot;yaya&quot;,&quot;nsd&quot;);
Query OK, 1 row affected (0.14 sec)

mysql&amp;gt; select【涩莱克特】  * from【弗乱】 gamedb.user;
+------+-------+
| name | class【克拉斯】 |
+------+-------+
| yaya | nsd   |
+------+-------+
1 row in set (0.01 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3）客户端连接从服务器查看数据&lt;/p&gt;
&lt;p&gt;-e 命令行下执行数据库命令&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql50 ~]# mysql -h192.168.90.54 -ujam -p123456 –e ‘select【涩莱克特】  * from【弗乱】 gamedb.user’
+------+-------+
| name | class【克拉斯】 |
+------+-------+
| yaya | nsd   |
+------+-------+
[root@mysql54 ~]# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、配置一主多从结构&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250616165031927.webp&quot; alt=&quot;image-20250616165031927&quot; /&gt;&lt;/p&gt;
&lt;p&gt;准备新的服务器&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;mysql55&lt;/td&gt;
&lt;td&gt;192.168.90.55&lt;/td&gt;
&lt;td&gt;从数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;mysql55的IP配置和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.55/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mysql55 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql55
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250616163452783.webp&quot; alt=&quot;image-20250616163452783&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;5.1 配置192.168.90.55从服务器&lt;/h3&gt;
&lt;p&gt;1)指定MySQL55主机的server-id 并重启数据库服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@mysql55 ~]# yum -y  install【因-斯多】 mysql-server
[root@mysql55 ~]# systemctl【西斯屯-ctl】  start【s 达儿】 mysqld
[root@mysql55 ~]# vim /etc/my.cnf.d/mysql-server.cnf
[mysqld]
server-id=55
:wq
[root@mysql55 ~]# systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）确保与主服务器数据一致。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#在mysql53执行备份命令前查看日志名和偏移量 ，mysql55 在当前查看到的位置同步数据
[root@mysql53 ~]# mysql -e &apos;show【瘦】  master【马斯特】 status【 斯dèi 特斯】&apos;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql53.000002 |      156 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
[root@mysql53 ~]#

#在主服务器存做完全备份
[root@mysql53 ~]# mysqldump【mysql-当普】  -B gamedb &amp;gt; /root/gamedb.sql 

#主服务器把备份文件拷贝给从服务器mysql55
[root@mysql53 ~]# scp  /root/gamedb.sql  root@192.168.90.55:/root/
[root@mysql55 ~]# mysql &amp;lt; /root/gamedb.sql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3）在MySQL55主机指定主服务器信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql55 ~]# mysql 

mysql&amp;gt; change【趁(chèn)吉】  master【马斯特】 to  master【马斯特】_host=&quot;192.168.90.53&quot; , master【马斯特】_user=&quot;repluser&quot; , master【马斯特】_password=&quot;123qqq...A&quot; , master【马斯特】_log_file=&quot;mysql53.000002&quot; , master【马斯特】_log_pos=156;
Query OK, 0 rows affected, 8 warnings (0.44 sec)

注意:日志名和偏移量 要写 在mysql53主机执行完全备份之前查看到的日志名和偏移量

mysql&amp;gt;  start【s 达儿】 slave【斯累夫】; #启动slave【斯累夫】进程
Query OK, 0 rows affected, 1 warning (0.02 sec)

#查看状态信息
mysql&amp;gt;  show【瘦】 slave【斯累夫】 status【 斯dèi 特斯】 \G
*************************** 1. row ***************************
               Slave【斯累夫】_IO_State: Waiting for source to send event
                  master【马斯特】_Host: 192.168.90.53
                  master【马斯特】_User: repluser
                  master【马斯特】_Port: 3306
                Connect_Retry: 60
              master【马斯特】_Log_File: mysql53.000002
          Read_master【马斯特】_Log_Pos: 156
               Relay_Log_File: mysql55-relay-bin.000002
                Relay_Log_Pos: 322
        Relay_master【马斯特】_Log_File: mysql53.000002
             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: 156
              Relay_Log_Space: 533
              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: 53
                  master【马斯特】_UUID: 38c02165-005e-11ee-bd2d-525400007271
             master【马斯特】_Info_File: mysql.slave【斯累夫】_master【马斯特】_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave【斯累夫】_SQL_Running_State: Replica 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: 
       master【马斯特】_public_key_path: 
        Get_master【马斯特】_public_key: 0
            Network_Namespace: 
1 row in set, 1 warning (0.00 sec)

#添加客户端访问时使用的用户
mysql&amp;gt; create【克瑞特】 user jam@&quot;%&quot; identified【爱-丹-提伐】 by &quot;123456&quot;;
Query OK, 0 rows affected (0.08 sec)

mysql&amp;gt; grant【古亮普】 all【ò】 on【昂】 gamedb.* to jam@&quot;%&quot; ;
Query OK, 0 rows affected (0.04 sec)
Mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 客户端测试配置&lt;/h3&gt;
&lt;p&gt;1）在mysql50 连接主服务器mysql53 存储数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#连接主服务器存储数据
[root@mysql50 ~]# mysql -h192.168.90.53 -ujam -p123456

mysql&amp;gt; insert【因涩特】 into【因兔】  gamedb.user values【挖柳斯】(&quot;tt&quot;,&quot;aid&quot;);
Query OK, 1 row affected (0.14 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】  gamedb.user values【挖柳斯】(&quot;mm&quot;,&quot;uid&quot;);
Query OK, 1 row affected (0.13 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）在client50 分别连接2个从服务器查看数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#连接从服务器54查看数据
[root@mysql50 ~]# mysql -h192.168.90.54 -ujam -p123456 -e &apos;select【涩莱克特】 * from【弗乱】 gamedb.user&apos;
mysql: [Warning] Using a password on【昂】 the command line interface can be insecure.
+------+-------+
| name | class【克拉斯】 |
+------+-------+
| yaya | nsd   |
| tt   | aid   |
| mm   | uid   |
+------+-------+

#连接从服务器55查看数据
[root@mysql50 ~]# mysql -h192.168.90.55 -ujam -p123456 -e &apos;select【涩莱克特】 * from【弗乱】 gamedb.user&apos;
mysql: [Warning] Using a password on【昂】 the command line interface can be insecure.
+------+-------+
| name | class【克拉斯】 |
+------+-------+
| yaya | nsd   |
| tt   | aid   |
| mm   | uid   |
+------+-------+
[root@mysql50 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image002.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;#我 : 按照上面的方法设置主从同步，之后新加的数据会同步从库，那要是在设置主从之前的数据呢？也会同步吗？&lt;/p&gt;
&lt;p&gt;#Doubao :
在设置 MySQL 主从同步时，设置同步之前主库已存在的数据是否会同步到从库，取决于具体的配置和操作步骤，下面为你详细分析不同情况：&lt;/p&gt;
&lt;h2&gt;设置主从同步之前的数据不会自动同步&lt;/h2&gt;
&lt;p&gt;如果只是简单地配置主从同步的连接信息（如设置从库的 &lt;code&gt;CHANGE MASTER TO&lt;/code&gt; 语句），而没有做额外的数据初始化操作，那么设置主从同步之前主库上已存在的数据不会自动同步到从库。这是因为主从同步是基于二进制日志（binlog）来记录和同步主库上的更改操作，在配置主从同步时，从库会从指定的二进制日志文件和位置开始读取并应用主库的更改，而设置之前的历史数据并没有被包含在这个起始点之后的二进制日志中。&lt;/p&gt;
&lt;h3&gt;可以通过特定操作实现同步&lt;/h3&gt;
&lt;p&gt;为了让设置主从同步之前主库上的数据也能同步到从库，可以采取以下常见方法：&lt;/p&gt;
&lt;h4&gt;1. 使用 &lt;code&gt;mysqldump&lt;/code&gt; 备份和恢复&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;步骤&lt;/strong&gt;：
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;在主库上锁定表并进行备份&lt;/strong&gt;：为了保证数据的一致性，在备份过程中需要锁定主库上的表，防止数据被修改。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;# 登录主库，锁定所有表
mysql -u root -p -e &quot;FLUSH TABLES WITH READ LOCK;&quot;
# 记录当前二进制日志文件和位置
mysql -u root -p -e &quot;SHOW MASTER STATUS;&quot;
# 使用 mysqldump 备份主库数据
mysqldump -u root -p --all-databases &amp;gt; master_backup.sql
# 解锁主库上的表
mysql -u root -p -e &quot;UNLOCK TABLES;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;2. **将备份文件传输到从库**：可以使用 `scp` 等工具将备份文件从主库复制到从库。
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;scp master_backup.sql user@slave_ip:/path/to/destination
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;3. **在从库上恢复备份数据**：登录从库，执行备份文件中的 SQL 语句。
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mysql -u root -p &amp;lt; master_backup.sql
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;4. **配置从库连接主库**：使用之前记录的二进制日志文件和位置，配置从库连接主库。
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CHANGE MASTER TO
    MASTER_HOST=&apos;master_ip&apos;,
    MASTER_USER=&apos;replication_user&apos;,
    MASTER_PASSWORD=&apos;replication_password&apos;,
    MASTER_LOG_FILE=&apos;binlog_file_name&apos;,
    MASTER_LOG_POS=binlog_position;
START SLAVE;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2. 使用 &lt;code&gt;rsync&lt;/code&gt; 复制数据文件（适用于 InnoDB 存储引擎）&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;步骤&lt;/strong&gt;：
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;停止主库和从库的 MySQL 服务&lt;/strong&gt;：为了避免数据冲突，需要先停止主库和从库的 MySQL 服务。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;systemctl stop mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;2. **使用 `rsync` 复制主库的数据文件到从库**：确保主库和从库的数据目录结构一致。
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;rsync -avz /var/lib/mysql/ user@slave_ip:/var/lib/mysql/
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;3. **启动从库的 MySQL 服务**：启动从库的 MySQL 服务，并配置从库连接主库。
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;systemctl start mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CHANGE MASTER TO
    MASTER_HOST=&apos;master_ip&apos;,
    MASTER_USER=&apos;replication_user&apos;,
    MASTER_PASSWORD=&apos;replication_password&apos;,
    MASTER_LOG_FILE=&apos;binlog_file_name&apos;,
    MASTER_LOG_POS=binlog_position;
START SLAVE;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过以上方法，可以将设置主从同步之前主库上的数据同步到从库，实现主从库数据的一致性。&lt;/p&gt;
&lt;h2&gt;异步复制、半同步复制、完全同步复制&lt;/h2&gt;
&lt;p&gt;#我 : MySQL 主从复制采用异步复制是什么？有同步复制吗？区别和优缺点是什么？&lt;/p&gt;
&lt;p&gt;#Doubao :&lt;/p&gt;
&lt;h3&gt;MySQL 主从复制中的异步复制&lt;/h3&gt;
&lt;h4&gt;概念&lt;/h4&gt;
&lt;p&gt;在 MySQL 主从复制的异步复制模式下，主库在执行完客户端提交的事务后，会立即将结果返回给客户端，而不会等待从库接收并处理该事务的二进制日志（binlog）。主库会将事务的变更记录到二进制日志中，然后异步地将这些日志发送给从库，从库会在自己的线程中独立地接收和应用这些日志。&lt;/p&gt;
&lt;h4&gt;示例代码配置&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;-- 在主库上创建用于复制的用户
CREATE USER &apos;repl_user&apos;@&apos;%&apos; IDENTIFIED BY &apos;password&apos;;
GRANT REPLICATION SLAVE ON *.* TO &apos;repl_user&apos;@&apos;%&apos;;
FLUSH PRIVILEGES;

-- 查看主库的二进制日志信息
SHOW MASTER STATUS;

-- 在从库上配置主从复制
CHANGE MASTER TO
    MASTER_HOST=&apos;master_ip&apos;,
    MASTER_USER=&apos;repl_user&apos;,
    MASTER_PASSWORD=&apos;password&apos;,
    MASTER_LOG_FILE=&apos;master_binlog_file_name&apos;,
    MASTER_LOG_POS=master_binlog_position;

START SLAVE;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;MySQL 中的同步复制&lt;/h3&gt;
&lt;h4&gt;概念&lt;/h4&gt;
&lt;p&gt;严格意义上，MySQL 原生的复制模式默认是异步复制，但 MySQL 也提供了半同步复制（Semi-synchronous Replication），可以看作是一种介于异步和完全同步之间的模式。在半同步复制中，主库在提交事务后，会等待至少一个从库确认已经接收到该事务的二进制日志后，才会向客户端返回操作成功的信息。&lt;/p&gt;
&lt;h4&gt;示例代码配置&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;-- 在主库和从库上都要安装半同步复制插件
INSTALL PLUGIN rpl_semi_sync_master SONAME &apos;semisync_master.so&apos;;
INSTALL PLUGIN rpl_semi_sync_slave SONAME &apos;semisync_slave.so&apos;;

-- 在主库上启用半同步复制
SET GLOBAL rpl_semi_sync_master_enabled = 1;
SET GLOBAL rpl_semi_sync_master_timeout = 10000;  -- 设置超时时间

-- 在从库上启用半同步复制
SET GLOBAL rpl_semi_sync_slave_enabled = 1;

-- 重启从库的复制线程
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;区别&lt;/h3&gt;
&lt;h4&gt;数据一致性&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;异步复制&lt;/strong&gt;：主库和从库之间存在一定的数据延迟，因为主库不会等待从库接收和应用事务。在主库发生故障时，从库可能没有完全同步主库的最新数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;半同步复制&lt;/strong&gt;：在一定程度上保证了数据的一致性，因为主库会等待至少一个从库确认接收事务。但如果所有从库都出现问题，主库会在超时后自动切换回异步复制模式。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;性能影响&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;异步复制&lt;/strong&gt;：对主库的性能影响较小，因为主库不需要等待从库的响应，可以立即返回结果给客户端。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;半同步复制&lt;/strong&gt;：会对主库的性能产生一定的影响，因为主库需要等待从库的确认信息，增加了事务的提交时间。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;优缺点&lt;/h3&gt;
&lt;h4&gt;异步复制&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;优点&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;性能高，主库可以快速响应客户端请求，不会因为从库的性能问题而受到影响。&lt;/li&gt;
&lt;li&gt;配置简单，是 MySQL 默认的复制模式，不需要额外的插件和复杂的配置。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺点&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;数据一致性较差，在主库故障时可能会导致数据丢失。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;半同步复制&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;优点&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;提高了数据的一致性，减少了主库故障时数据丢失的风险。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺点&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;性能相对较低，因为主库需要等待从库的确认信息。&lt;/li&gt;
&lt;li&gt;配置相对复杂，需要安装和启用半同步复制插件。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;完全同步复制&lt;/h3&gt;
&lt;p&gt;除了半同步复制，还有一些第三方解决方案可以实现完全同步复制，即主库必须等待所有从库都成功应用事务后才会提交。但这种方式会对性能产生极大的影响，实际应用中较少使用。&lt;/p&gt;
&lt;h2&gt;binlog 的三种格式&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;格式&lt;/th&gt;
&lt;th&gt;记录内容&lt;/th&gt;
&lt;th&gt;优点&lt;/th&gt;
&lt;th&gt;缺点&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;**STATEMENT (SBR)**​&lt;/td&gt;
&lt;td&gt;记录造成数据变更的&lt;strong&gt;SQL语句本身&lt;/strong&gt;​&lt;/td&gt;
&lt;td&gt;日志量小，节省磁盘和网络I/O；易于查看和审计&lt;/td&gt;
&lt;td&gt;可能引起主从不一致（如使用&lt;code&gt;NOW()&lt;/code&gt;, &lt;code&gt;UUID()&lt;/code&gt;等非确定性函数时）&lt;/td&gt;
&lt;td&gt;数据结构简单、SQL模式固定、更新量大但涉及行少的场景&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;**ROW (RBR)**​&lt;/td&gt;
&lt;td&gt;记录每一行数据&lt;strong&gt;如何被修改&lt;/strong&gt;（如修改前/后的镜像）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;数据安全性和一致性最高&lt;/strong&gt;，可可靠地复制任何变更&lt;/td&gt;
&lt;td&gt;日志量可能非常大（特别是批量更新或表结构变更时）&lt;/td&gt;
&lt;td&gt;对数据一致性要求极高的场景（如金融业务），或使用了可能引起不一致的函数/存储过程时&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;**MIXED (MBR)**​&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;智能混合&lt;/strong&gt;使用STATEMENT和ROW模式&lt;/td&gt;
&lt;td&gt;在安全性和性能间取得平衡；多数情况下日志量小，特定情况下自动转为ROW模式以保证安全&lt;/td&gt;
&lt;td&gt;仍存在极小概率在混合模式下出现不一致&lt;/td&gt;
&lt;td&gt;希望兼顾性能和数据安全性的通用业务场景，&lt;strong&gt;MySQL 5.7.7及以上版本默认采用此格式&lt;/strong&gt;​&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;#我 : . 列举 MySQL 主从复制中 binlog 的三种格式，并说明各自特点。&lt;/p&gt;
&lt;p&gt;#Doubao :
在 MySQL 主从复制中，binlog（二进制日志）有三种格式，分别是 &lt;code&gt;STATEMENT&lt;/code&gt;（语句级）、&lt;code&gt;ROW&lt;/code&gt;（行级）和 &lt;code&gt;MIXED&lt;/code&gt;（混合级），以下是它们各自的特点：&lt;/p&gt;
&lt;h3&gt;1. STATEMENT（语句级）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特点&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;日志记录方式&lt;/strong&gt;：记录的是主库上执行的 SQL 语句。也就是说，主库在执行一条 SQL 语句后，会将该语句本身记录到 binlog 中，从库在复制时，会重新执行这些 SQL 语句来达到与主库数据一致的目的。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;优点&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;日志量小&lt;/strong&gt;：由于只记录 SQL 语句，相比于记录每行数据变化的 ROW 格式，日志量通常要小很多，这可以减少磁盘 I/O 和网络传输的压力，同时也能节省存储空间。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可读性高&lt;/strong&gt;：SQL 语句本身是人类可读的，因此查看和分析 binlog 内容相对容易，便于进行故障排查和审计。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺点&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;部分语句复制可能存在问题&lt;/strong&gt;：一些依赖于主库当前环境的 SQL 语句，如 &lt;code&gt;NOW()&lt;/code&gt;、&lt;code&gt;UUID()&lt;/code&gt; 等函数，在主从库上执行时可能会产生不同的结果，因为主从库的系统时间、随机数种子等可能不同。此外，一些存储过程、触发器等也可能因为主从库环境差异而导致复制不一致。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;并发复制性能受限&lt;/strong&gt;：在高并发场景下，由于从库需要重新执行 SQL 语句，可能会受到锁和并发控制的影响，导致复制性能下降。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. ROW（行级）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特点&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;日志记录方式&lt;/strong&gt;：记录的是每行数据的变化情况，即哪些行被插入、更新或删除，以及具体的变更内容。而不是像 STATEMENT 格式那样记录 SQL 语句。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;优点&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;复制一致性高&lt;/strong&gt;：由于记录的是实际的数据变更，不依赖于 SQL 语句的执行环境，因此可以保证主从库数据的高度一致性，避免了 STATEMENT 格式中因环境差异导致的复制问题。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;并发复制性能好&lt;/strong&gt;：从库可以并行地应用这些行级变更，而不需要像执行 SQL 语句那样考虑锁和并发控制，因此在高并发场景下，复制性能通常比 STATEMENT 格式要好。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺点&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;日志量大&lt;/strong&gt;：需要记录每行数据的变化，对于大规模的数据更新操作，日志量会非常大，这会增加磁盘 I/O 和网络传输的负担，同时也需要更多的存储空间。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可读性差&lt;/strong&gt;：由于记录的是数据行的变化，而不是 SQL 语句，因此 binlog 的内容难以直接阅读和理解，不利于故障排查和审计。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. MIXED（混合级）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特点&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;日志记录方式&lt;/strong&gt;：结合了 STATEMENT 和 ROW 两种格式的优点。MySQL 会根据具体的 SQL 语句和执行情况，自动选择使用 STATEMENT 格式还是 ROW 格式来记录 binlog。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;优点&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;灵活性高&lt;/strong&gt;：对于大多数普通的 SQL 语句，会使用 STATEMENT 格式记录，以减少日志量；而对于那些可能导致复制不一致的 SQL 语句，如包含不确定函数的语句，则会使用 ROW 格式记录，以保证复制的一致性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能和一致性的平衡&lt;/strong&gt;：在保证复制一致性的同时，尽可能地减少日志量，提高复制性能和效率。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺点&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;难以预测日志格式&lt;/strong&gt;：由于是自动选择日志格式，在某些情况下可能会让人难以预测具体使用的是哪种格式，增加了故障排查和管理的难度。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以通过以下命令来查看和设置 binlog 的格式：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 查看当前 binlog 格式
SHOW VARIABLES LIKE &apos;binlog_format&apos;;

-- 设置 binlog 格式为 STATEMENT
SET GLOBAL binlog_format = &apos;STATEMENT&apos;;
-- 设置 binlog 格式为 ROW
SET GLOBAL binlog_format = &apos;ROW&apos;;
-- 设置 binlog 格式为 MIXED
SET GLOBAL binlog_format = &apos;MIXED&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需要注意的是，设置全局变量后，新的设置只会对新建立的会话生效，对于已经存在的会话，需要重新连接才能应用新的设置。&lt;/p&gt;
&lt;h2&gt;主库宕机如何保证业务&lt;/h2&gt;
&lt;p&gt;#我 : 主从复制中，若主库宕机，应如何进行故障切换以保证业务继续运行？&lt;/p&gt;
&lt;p&gt;#Doubao :
在 MySQL 主从复制架构中，当主库宕机时，为了保证业务能够继续运行，需要进行故障切换。以下是详细的故障切换步骤和方法：&lt;/p&gt;
&lt;h3&gt;1. 确认主库宕机&lt;/h3&gt;
&lt;p&gt;首先要通过监控系统、日志或者手动检查等方式，确认主库确实已经无法正常工作。例如，可以尝试连接主库，查看是否能够正常响应查询请求；查看主库的系统日志和 MySQL 日志，确认是否有异常信息。&lt;/p&gt;
&lt;h3&gt;2. 选择新的主库&lt;/h3&gt;
&lt;p&gt;从多个从库中选择一个合适的从库作为新的主库，通常会考虑以下因素：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;数据同步情况&lt;/strong&gt;：选择与原主库数据最接近同步的从库，以减少数据丢失。可以通过查看从库的 &lt;code&gt;SHOW SLAVE STATUS&lt;/code&gt; 命令输出，比较 &lt;code&gt;Seconds_Behind_Master&lt;/code&gt; 的值，选择该值最小的从库。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;硬件资源&lt;/strong&gt;：选择硬件配置较好、性能较高的从库，以确保新主库能够稳定运行。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 停止从库复制&lt;/h3&gt;
&lt;p&gt;在将选定的从库提升为新主库之前，需要先停止该从库的复制进程，避免后续出现数据冲突。在选定的从库上执行以下命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;STOP SLAVE;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. 提升从库为新主库&lt;/h3&gt;
&lt;p&gt;将选定的从库设置为独立的主库，需要重置二进制日志和中继日志。在选定的从库上执行以下命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;RESET MASTER;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5. 配置其他从库指向新主库&lt;/h3&gt;
&lt;p&gt;将其他从库配置为连接到新的主库，继续进行复制。在每个从库上执行以下命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 停止当前的复制进程
STOP SLAVE;
-- 配置新主库的连接信息
CHANGE MASTER TO
    MASTER_HOST=&apos;新主库的 IP 地址&apos;,
    MASTER_USER=&apos;复制用户&apos;,
    MASTER_PASSWORD=&apos;复制用户密码&apos;,
    MASTER_LOG_FILE=&apos;新主库当前的二进制日志文件名&apos;,
    MASTER_LOG_POS=新主库当前的二进制日志位置;
-- 启动复制进程
START SLAVE;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以通过 &lt;code&gt;SHOW SLAVE STATUS&lt;/code&gt; 命令检查复制是否正常工作，确保 &lt;code&gt;Slave_IO_Running&lt;/code&gt; 和 &lt;code&gt;Slave_SQL_Running&lt;/code&gt; 都为 &lt;code&gt;Yes&lt;/code&gt;。&lt;/p&gt;
&lt;h3&gt;6. 更新应用程序配置&lt;/h3&gt;
&lt;p&gt;将应用程序连接的数据库地址从原主库更新为新主库的地址，确保应用程序能够正常连接到新的主库。这可能需要修改应用程序的配置文件，并重新启动应用程序。&lt;/p&gt;
&lt;h3&gt;7. 恢复原主库&lt;/h3&gt;
&lt;p&gt;在故障切换完成后，可以对原主库进行故障排查和修复。修复完成后，将原主库配置为新主库的从库，继续进行复制。在原主库上执行以下命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 停止当前的复制进程
STOP SLAVE;
-- 重置二进制日志和中继日志
RESET SLAVE ALL;
-- 配置新主库的连接信息
CHANGE MASTER TO
    MASTER_HOST=&apos;新主库的 IP 地址&apos;,
    MASTER_USER=&apos;复制用户&apos;,
    MASTER_PASSWORD=&apos;复制用户密码&apos;,
    MASTER_LOG_FILE=&apos;新主库当前的二进制日志文件名&apos;,
    MASTER_LOG_POS=新主库当前的二进制日志位置;
-- 启动复制进程
START SLAVE;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;自动化故障切换&lt;/h3&gt;
&lt;p&gt;为了提高故障切换的效率和准确性，可以使用一些自动化工具来实现故障切换，例如 MHA（Master High Availability）、PXC（Percona XtraDB Cluster）等。这些工具可以自动检测主库的故障，并在主库宕机时自动进行故障切换，减少人工干预的时间和错误。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@master /]# cat  /usr/local/mysql/my.cnf 
[mysqld]
basedir=/usr/local/mysql                    # MySQL安装目录
datadir=/usr/local/mysql/data               # 数据文件存储目录
socket=/tmp/mysql.sock                      # 本地连接使用的socket文件
port=3306                                   # 服务监听端口
log_error=/usr/local/mysql/data/master.err  # 指定错误日志文件的路径。错误日志记录了MySQL启动、运行和停止过程中的错误信息。
log_bin=/usr/local/mysql/data/binlog        # 指定二进制日志（binlog）文件的基本路径和名称。二进制日志记录了所有更改数据的SQL语句（或数据变更），用于主从复制和数据恢复。
server_id=10                                # 设置服务器的唯一标识符，在主从复制拓扑中，每个服务器必须有一个唯一的server_id。
character_set_server=utf8mb4                # 设置服务器默认的字符集为utf8mb4，它支持更广泛的Unicode字符（如emoji表情）
gtid_mode=on                                # 启用全局事务标识符（GTID）模式。GTID为每个事务分配一个全局唯一的标识符，简化了主从复制的管理
log_slave_updates=1                         # 允许从库将其从主库接收到的更新记录到自己的二进制日志中。这通常用于链式复制（例如，A-&amp;gt;B-&amp;gt;C）或备份从库
enforce_gtid_consistency                    # 强制GTID一致性，确保只有能够安全记录GTID的事务才会被执行。这有助于保证复制的可靠性。
# 复制核心参数
log_bin=/usr/local/mysql/data/binlog
relay_log=/usr/local/mysql/data/relaylog
server_id=20
#字符集
character_set_server=utf8mb4
# 可靠性参数
relay_log_recovery = ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
#设置从库只读
read_only=1

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;#我 : 检查下面作业是否有问题&lt;/p&gt;
&lt;h2&gt;六、作业&lt;/h2&gt;
&lt;h3&gt;选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;在 MySQL 主从复制中，主服务器记录数据变更的二进制日志文件是（ A ）。
A. binlog
B. relay-bin
C. binlog.index
D. relay-bin.log&lt;/li&gt;
&lt;li&gt;若要开启 MySQL 主从复制，主从服务器的以下哪个参数必须不同（ A ）。
A. server-id
B. log-bin
C. sync-binlog
D. relay-log&lt;/li&gt;
&lt;li&gt;MySQL 主从复制中，从服务器将接收到的主服务器 binlog 日志写入的文件是（ B ）。
A. binlog
B. relay log
C. binlog.index
D. relay-bin.log&lt;/li&gt;
&lt;li&gt;主从复制中，主库执行写操作后，以下哪个线程负责把 binlog 的内容发送到从库（ A ）。
A. binlog dump thread
B. I/O 线程
C. SQL 线程
D. log dump 线程&lt;/li&gt;
&lt;li&gt;MySQL 主从复制采用异步复制时，可能出现的问题是（ A ）。
A. 数据丢失
B. 性能严重下降
C. 无法实现复制
D. 主从服务器无法连接&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;简述 MySQL 主从复制的基本原理。
答：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;主库将数据变更（DDL和DML）记录到二进制日志（binlog）中。&lt;/li&gt;
&lt;li&gt;从库的I/O线程向主库的binlog dump线程请求binlog。&lt;/li&gt;
&lt;li&gt;主库的binlog dump线程将binlog事件发送给从库的I/O线程。&lt;/li&gt;
&lt;li&gt;从库的I/O线程将接收到的事件写入中继日志（relay log）。&lt;/li&gt;
&lt;li&gt;从库的SQL线程读取并解析relay log中的事件，在从库上执行这些事件，从而使从库与主库的数据保持同步。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;列举 MySQL 主从复制中 binlog 的三种格式，并说明各自特点。
答：
binlog的三种格式，&lt;code&gt;STATEMENT&lt;/code&gt;（语句级）、&lt;code&gt;ROW&lt;/code&gt;（行级）和 &lt;code&gt;MIXED&lt;/code&gt;（混合级）
&lt;code&gt;STATEMENT&lt;/code&gt;（语句级）：日志量小、可读性高
&lt;code&gt;ROW&lt;/code&gt;（行级）：复制一致性高、并发复制性能好
&lt;code&gt;MIXED&lt;/code&gt;（混合级）：灵活性高、性能和一致性的平衡&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;主从复制中，若主库宕机，应如何进行故障切换以保证业务继续运行？
答：
1、确认主库宕机之后，第一时间选择一个从库作为新主库以承接服务
2、停止新主库上的从库配置改为主库，同事配置其它从库指向新主库
3、更新业务服务的数据库配置指向新主库&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;请详细描述搭建一主一从 MySQL 主从复制环境的步骤，包括主从服务器的配置、用户创建、同步启动等。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;# 清理mariadb
[root@master ~]# rpm -qa | grep mariadb | xargs rpm -e --nodeps
# 基本环境安装
[root@master ~]# yum install -y libaio-devel numactl wget
# 下载安装官方源
[root@master ~]# wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
[root@master ~]# rpm -ivh mysql80-community-release-el7-3.noarch.rpm
# 下载并导入 MySQL 官方 GPG 密钥 
[root@master ~]# rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023
[root@master ~]# yum repolist enabled | grep mysql
mysql-connectors-community/x86_64       MySQL Connectors Community           293
mysql-tools-community/x86_64            MySQL Tools Community                118
mysql80-community/x86_64                MySQL 8.0 Community Server           598
[root@master ~]# 

# 主从安装mysql服务
[root@master ~]# yum install -y mysql-community-server 
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
Resolving Dependencies
--&amp;gt; Running transaction check
---&amp;gt; Package mysql-community-server.x86_64 0:8.0.44-1.el7 will be installed
--&amp;gt; Processing Dependency: mysql-community-common(x86-64) = 8.0.44-1.el7 for package: mysql-community-server-8.0.44-1.el7.x86_64
--&amp;gt; Processing Dependency: mysql-community-icu-data-files = 8.0.44-1.el7 for package: mysql-community-server-8.0.44-1.el7.x86_64
--&amp;gt; Processing Dependency: mysql-community-client(x86-64) &amp;gt;= 8.0.11 for package: mysql-community-server-8.0.44-1.el7.x86_64

# 配置主库，指定server_id和开启binlog日记
[root@master ~]# grep -vE &quot;#&quot; /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

server_id=10
log_bin=/var/lib/mysql/binlog


#启动和添加开机启动mysql服务
[root@master /]# systemctl enable mysqld
[root@master /]# systemctl status mysqld



[root@master /]# mysql -uroot -p
........
# 第一次登陆需先修改默认密码
mysql&amp;gt; alter user &apos;root&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;mysql123!&apos;;
Query OK, 0 rows affected (0.01 sec)

# 创建用户同步的repluser账号密码repluser
mysql&amp;gt; create user repluser@&quot;%&quot; identified WITH mysql_native_password by &quot;repluser&quot;;
Query OK, 0 rows affected (0.09 sec)
# 给repluser用户赋权
mysql&amp;gt; grant replication slave on *.*  to repluser@&quot;%&quot;;
Query OK, 0 rows affected (0.05 sec)
# 查询binlog名称和偏移量
mysql&amp;gt; show  master status;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000002 |     1307 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)





# 从库安装mysql服务
# 清理mariadb
[root@slave1 ~]# rpm -qa | grep mariadb | xargs rpm -e --nodeps
# 基本环境安装
[root@slave1 ~]# yum install -y libaio-devel numactl wget
# 下载安装官方源
[root@slave1 ~]# wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
[root@slave1 ~]# rpm -ivh mysql80-community-release-el7-3.noarch.rpm
# 下载并导入 MySQL 官方 GPG 密钥 
[root@slave1 ~]# rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023
[root@slave1 ~]# yum repolist enabled | grep mysql
mysql-connectors-community/x86_64       MySQL Connectors Community           293
mysql-tools-community/x86_64            MySQL Tools Community                118
mysql80-community/x86_64                MySQL 8.0 Community Server           598
[root@slave1 ~]# 

# 主从安装mysql服务
[root@slave1 ~]# yum install -y mysql-community-server 
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
Resolving Dependencies
--&amp;gt; Running transaction check
---&amp;gt; Package mysql-community-server.x86_64 0:8.0.44-1.el7 will be installed
--&amp;gt; Processing Dependency: mysql-community-common(x86-64) = 8.0.44-1.el7 for package: mysql-community-server-8.0.44-1.el7.x86_64
--&amp;gt; Processing Dependency: mysql-community-icu-data-files = 8.0.44-1.el7 for package: mysql-community-server-8.0.44-1.el7.x86_64
--&amp;gt; Processing Dependency: mysql-community-client(x86-64) &amp;gt;= 8.0.11 for package: mysql-community-server-8.0.44-1.el7.x86_64



# 配置从库，指定server_id和开启binlog日记
[root@slave1 ~]# vim /etc/my.cnf
[root@slave1 ~]# grep -vE &quot;#&quot; /etc/my.cnf

[mysqld]

datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

server_id=20
log_bin=/var/lib/mysql/binlog
relay_log=/var/lib/mysql/relaylog

[root@slave1 ~]# systemctl enable mysqld
[root@slave1 ~]# systemctl start mysqld

# 从库配置
# 修改默认密码
mysql&amp;gt; alter user &apos;root&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;Mysql123!&apos;;
Query OK, 0 rows affected (0.01 sec)

# 配置 MySQL 主从复制
mysql&amp;gt; change  master to  master_host=&quot;192.168.99.10&quot; , master_user=&quot;repluser&quot; , master_password=&quot;repluser&quot; ,master_log_file=&quot;binlog.000002&quot; , master_log_pos=1307;
Query OK, 0 rows affected, 8 warnings (0.06 sec)

# 启动slave进程
mysql&amp;gt; start slave ;
Query OK, 0 rows affected, 1 warning (0.32 sec)

# 同步查看状态信息
mysql&amp;gt; show slave status \G  
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: 192.168.99.10
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000002
          Read_Master_Log_Pos: 1307
               Relay_Log_File: relaylog.000002
                Relay_Log_Pos: 323
        Relay_Master_Log_File: binlog.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 


# 测试

# 在主服务器创建text数据库
mysql&amp;gt; create database text;
Query OK, 1 row affected (0.06 sec)

# 从库查看是否同步
mysql&amp;gt; show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| text               |
+--------------------+
5 rows in set (0.06 sec)


&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;假设已有一主多从的 MySQL 主从复制环境，现在需要新增一个从服务器，写出具体操作步骤。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;# 查看主库当前binlog和偏移量
mysql&amp;gt; show  master status;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000002 |     1492 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.04 sec)


# 从库安装mysql服务
# 清理mariadb
[root@slave1 ~]# rpm -qa | grep mariadb | xargs rpm -e --nodeps
# 基本环境安装
[root@slave1 ~]# yum install -y libaio-devel numactl wget
# 下载安装官方源
[root@slave1 ~]# wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
[root@slave1 ~]# rpm -ivh mysql80-community-release-el7-3.noarch.rpm
# 下载并导入 MySQL 官方 GPG 密钥 
[root@slave1 ~]# rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023
[root@slave1 ~]# yum repolist enabled | grep mysql
mysql-connectors-community/x86_64       MySQL Connectors Community           293
mysql-tools-community/x86_64            MySQL Tools Community                118
mysql80-community/x86_64                MySQL 8.0 Community Server           598
[root@slave1 ~]# 

# 主从安装mysql服务
[root@slave1 ~]# yum install -y mysql-community-server 
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
Resolving Dependencies
--&amp;gt; Running transaction check
---&amp;gt; Package mysql-community-server.x86_64 0:8.0.44-1.el7 will be installed
--&amp;gt; Processing Dependency: mysql-community-common(x86-64) = 8.0.44-1.el7 for package: mysql-community-server-8.0.44-1.el7.x86_64
--&amp;gt; Processing Dependency: mysql-community-icu-data-files = 8.0.44-1.el7 for package: mysql-community-server-8.0.44-1.el7.x86_64
--&amp;gt; Processing Dependency: mysql-community-client(x86-64) &amp;gt;= 8.0.11 for package: mysql-community-server-8.0.44-1.el7.x86_64



# 配置从库，指定server_id和开启binlog日记
[root@slave1 ~]# vim /etc/my.cnf
[root@slave1 ~]# grep -vE &quot;#&quot; /etc/my.cnf

[mysqld]

datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

server_id=30
log_bin=/var/lib/mysql/binlog
relay_log=/var/lib/mysql/relaylog

[root@slave1 ~]# systemctl enable mysqld
[root@slave1 ~]# systemctl start mysqld

# 从库配置
# 修改默认密码
mysql&amp;gt; alter user &apos;root&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;Mysql123!&apos;;
Query OK, 0 rows affected (0.01 sec)

# 配置 MySQL 主从复制
mysql&amp;gt; change  master to  master_host=&quot;192.168.99.10&quot; , master_user=&quot;repluser&quot; , master_password=&quot;repluser&quot; ,master_log_file=&quot;binlog.000002&quot; , master_log_pos=1492;
Query OK, 0 rows affected, 8 warnings (0.04 sec)

# 启动slave进程
mysql&amp;gt; start slave;
Query OK, 0 rows affected, 1 warning (0.63 sec)

# 同步查看状态信息
mysql&amp;gt; show slave status \G  
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: 192.168.99.10
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000002
          Read_Master_Log_Pos: 1492
               Relay_Log_File: relaylog.000002
                Relay_Log_Pos: 323
        Relay_Master_Log_File: binlog.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

# 测试

# 在主服务器创建text数据库
mysql&amp;gt; create database text2;
Query OK, 1 row affected (0.09 sec)

# 从库1 查看是否同步
mysql&amp;gt; show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| text               |
| text2              |
+--------------------+
6 rows in set (0.12 sec)

# 新增从库2 查看是否同步
mysql&amp;gt; show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| text2              |
+--------------------+
5 rows in set (0.02 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;#Doubao : 以下是对这份作业的详细检查分析：&lt;/p&gt;
&lt;h3&gt;选择题&lt;/h3&gt;
&lt;p&gt;所有选择题答案均正确，对 MySQL 主从复制的基本概念掌握较好。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;第 1 题&lt;/strong&gt;：主服务器记录数据变更的二进制日志文件是 &lt;code&gt;binlog&lt;/code&gt;，选项 A 正确。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 2 题&lt;/strong&gt;：在 MySQL 主从复制中，主从服务器的 &lt;code&gt;server-id&lt;/code&gt; 必须不同，用于唯一标识每个服务器，选项 A 正确。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 3 题&lt;/strong&gt;：从服务器将接收到的主服务器 &lt;code&gt;binlog&lt;/code&gt; 日志写入 &lt;code&gt;relay log&lt;/code&gt;，选项 B 正确。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 4 题&lt;/strong&gt;：主库执行写操作后，&lt;code&gt;binlog dump thread&lt;/code&gt; 负责把 &lt;code&gt;binlog&lt;/code&gt; 的内容发送到从库，选项 A 正确。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 5 题&lt;/strong&gt;：MySQL 主从复制采用异步复制时，主库不等待从库确认，可能出现数据丢失的问题，选项 A 正确。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;简答题&lt;/h3&gt;
&lt;h4&gt;1. 简述 MySQL 主从复制的基本原理&lt;/h4&gt;
&lt;p&gt;答案准确完整，清晰地阐述了 MySQL 主从复制的基本流程，包括主库记录 &lt;code&gt;binlog&lt;/code&gt;、从库请求和接收 &lt;code&gt;binlog&lt;/code&gt;、写入中继日志以及执行事件等步骤。&lt;/p&gt;
&lt;h4&gt;2. 列举 MySQL 主从复制中 binlog 的三种格式，并说明各自特点&lt;/h4&gt;
&lt;p&gt;答案基本正确，但不够详细。对于每种格式的优缺点可以进一步展开说明，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;STATEMENT&lt;/code&gt;（语句级）&lt;/strong&gt;：日志量小、可读性高，但部分依赖主库环境的 SQL 语句（如含 &lt;code&gt;NOW()&lt;/code&gt;、&lt;code&gt;UUID()&lt;/code&gt; 等函数）可能导致主从复制不一致，在高并发场景下并发复制性能受限。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;ROW&lt;/code&gt;（行级）&lt;/strong&gt;：复制一致性高、并发复制性能好，但日志量大，可读性差，对于大规模数据更新操作会增加磁盘 I/O 和网络传输负担。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;MIXED&lt;/code&gt;（混合级）&lt;/strong&gt;：灵活性高、性能和一致性的平衡，会根据具体 SQL 语句自动选择 &lt;code&gt;STATEMENT&lt;/code&gt; 或 &lt;code&gt;ROW&lt;/code&gt; 格式，但难以预测具体使用的日志格式，增加了故障排查和管理难度。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;3. 主从复制中，若主库宕机，应如何进行故障切换以保证业务继续运行&lt;/h4&gt;
&lt;p&gt;答案步骤不够详细，可能会导致实际操作时出现问题。可以补充以下内容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;确认主库宕机&lt;/strong&gt;：通过监控系统、日志或者手动检查等方式，确认主库确实无法正常工作。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;选择新的主库&lt;/strong&gt;：考虑数据同步情况（查看 &lt;code&gt;Seconds_Behind_Master&lt;/code&gt;）和硬件资源，选择合适的从库作为新主库。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;停止从库复制&lt;/strong&gt;：在选定的从库上执行 &lt;code&gt;STOP SLAVE&lt;/code&gt; 命令。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;提升从库为新主库&lt;/strong&gt;：执行 &lt;code&gt;RESET MASTER&lt;/code&gt; 命令。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配置其他从库指向新主库&lt;/strong&gt;：在每个从库上执行 &lt;code&gt;CHANGE MASTER TO&lt;/code&gt; 命令，更新主库连接信息，然后执行 &lt;code&gt;START SLAVE&lt;/code&gt; 命令。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;更新应用程序配置&lt;/strong&gt;：将应用程序连接的数据库地址从原主库更新为新主库的地址。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;恢复原主库&lt;/strong&gt;：对原主库进行故障排查和修复，修复完成后将其配置为新主库的从库。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;操作题&lt;/h3&gt;
&lt;h4&gt;1. 请详细描述搭建一主一从 MySQL 主从复制环境的步骤，包括主从服务器的配置、用户创建、同步启动等&lt;/h4&gt;
&lt;p&gt;整体步骤基本正确，但存在一些小问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;数据库名拼写错误&lt;/strong&gt;：在测试部分创建数据库时，写成了 &lt;code&gt;text&lt;/code&gt;，推测可能是想写 &lt;code&gt;test&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺少权限刷新&lt;/strong&gt;：在主库创建用户并赋权后，应执行 &lt;code&gt;FLUSH PRIVILEGES&lt;/code&gt; 命令使权限生效。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;日志记录&lt;/strong&gt;：在安装和配置过程中，应检查命令执行结果，确保没有报错，并且可以记录关键步骤的日志，方便后续排查问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;2. 假设已有一主多从的 MySQL 主从复制环境，现在需要新增一个从服务器，写出具体操作步骤&lt;/h4&gt;
&lt;p&gt;整体步骤基本正确，同样存在以下问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;数据库名拼写错误&lt;/strong&gt;：同第一题，测试部分创建数据库写成 &lt;code&gt;text2&lt;/code&gt;，可能是 &lt;code&gt;test2&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺少权限刷新&lt;/strong&gt;：在主库创建用户并赋权后，应执行 &lt;code&gt;FLUSH PRIVILEGES&lt;/code&gt; 命令使权限生效。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;日志记录&lt;/strong&gt;：在安装和配置过程中，应检查命令执行结果，确保没有报错，并且可以记录关键步骤的日志，方便后续排查问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;综上所述，作业对 MySQL 主从复制的基本概念和操作有较好的理解，但在一些细节和完整性方面还有提升空间。&lt;/p&gt;
&lt;h1&gt;10：mysql之读写分离&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250616174238077.webp&quot; alt=&quot;image-20250616174238077&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;MySQL读写分离在多种工作场景中优势明显。在高并发读场景里，如电商平台商品浏览、社交媒体内容加载，大量读请求可由从库处理，减轻主库压力，提升系统响应速度 。对于数据实时性要求低的报表生成、数据分析场景，允许主从短暂延迟，能充分发挥读写分离的优势 。在容灾与备份方面，从库可作为主库实时备份，主库故障时能快速切换，保障业务持续运行 。另外，全球分布式架构中，将读操作路由到离用户近的从库，可减少网络延迟。&lt;/p&gt;
&lt;h2&gt;二、为什么学&lt;/h2&gt;
&lt;p&gt;学习 MySQL 读写分离很有必要。在高并发场景下，数据库面临大量读写请求，读写分离可将读操作分配到从库，有效减轻主库压力，提升系统整体性能与响应速度。对于有海量数据处理需求的企业，能提升业务处理效率。它还能增强系统的可扩展性，可通过增加从库数量来应对不断增长的读请求。在数据备份与恢复方面，从库可充当主库的实时副本，一旦主库出现故障，能快速恢复数据，保障业务连续性。掌握这一技术，有助于提升数据库管理和运维能力。&lt;/p&gt;
&lt;h2&gt;三、准备环境&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250616174302014.webp&quot; alt=&quot;image-20250616174302014&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3.1 准备新的虚拟机&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;mysql56&lt;/td&gt;
&lt;td&gt;192.168.90.56&lt;/td&gt;
&lt;td&gt;master【马斯特】数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mysql57&lt;/td&gt;
&lt;td&gt;192.168.90.57&lt;/td&gt;
&lt;td&gt;slave【斯累夫】数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mycat58&lt;/td&gt;
&lt;td&gt;192.168.90.58&lt;/td&gt;
&lt;td&gt;读写分离服务&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;mysql56配置IP地址和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.56/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mysql56 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql56
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mysql57配置IP地址和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.57/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mysql57 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql57
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mycat58配置IP地址和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.58/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mycat ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mycat58
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 读写分离原理&lt;/h3&gt;
&lt;p&gt;Mycat【麦-凯特】 读写分离原理基于对 MySQL 主从复制的利用。
Mycat【麦-凯特】 作为中间件，介于应用程序和 MySQL 数据库之间。
当应用程序发起 SQL 请求时，Mycat【麦-凯特】 会根据 SQL 语句类型进行判断。对于读操作，如 SELECT【涩莱克特】 语句，Mycat【麦-凯特】 将请求路由到从库处理，从库可有多台，能实现负载均衡，以此减轻主库读压力。而对于写操作，如 INSERT【因涩特】、UPDATE【阿普 dei 特】、DELETE【迪  利 特】 语句，Mycat【麦-凯特】 会将请求转发到主库，确保数据写入的一致性。
主库数据更新后，通过 MySQL 主从复制机制同步到从库，保证数据的实时性和准确性。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250616170530176.webp&quot; alt=&quot;image-20250616170530176&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;四、搭建一主一从结构&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250616174211732.webp&quot; alt=&quot;image-20250616174211732&quot; /&gt;&lt;/p&gt;
&lt;p&gt;因为数据的查询和存储分别访问不同的数据库服务器，所以要通过主从同步来保证负责读访问的服务与负责写访问的服务器数据一致。&lt;/p&gt;
&lt;h3&gt;4.1 配置主数据库服务器&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql56 ~]# yum -y  install【因-斯多】  mysql-server mysql
[root@mysql56 ~]#  systemctl【西斯屯-ctl】  start【s 达儿】 mysqld

# 启用binlog日志
[root@mysql56 ~]# vim /etc/my.cnf.d/mysql-server.cnf
# [root@mysql56 ~]# vim /etc/my.cnf
[mysqld]
server-id=56
log-bin=mysql56
:wq

[root@mysql56 ~]#  systemctl【西斯屯-ctl】 restart【 率 s 达r】 mysqld
# [root@mysql56 ~]# systemctl restart mysqld

# 用户授权
[root@mysql56 ~]# mysql
# [root@mysql56 ~]# mysql -uroot -p123

mysql&amp;gt; create【克瑞特】 user repluser@&quot;%&quot;  identified【爱-丹-提伐】 with【威付】 mysql_native_password by【拜】  &quot;123qqq...A&quot;;
# mysql&amp;gt; create user repluser@&apos;%&apos; identified with mysql_native_password by &apos;repluser&apos;;
# Query OK, 0 rows affected (0.26 sec)

mysql&amp;gt;  grant【古亮普】 replication【瑞普利K申】 slave【斯累夫】 on  *.* to  repluser@&quot;%&quot; ;
# mysql&amp;gt; grant replication slave on *.* to repluser@&apos;%&apos;;
# Query OK, 0 rows affected (0.15 sec)

# 查看日志信息
mysql&amp;gt; show【瘦】 master【马斯特】 status【 斯dèi 特斯】;
# mysql&amp;gt; show master status;
# +----------------+----------+--------------+------------------+-------------------+
# | File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
# +----------------+----------+--------------+------------------+-------------------+
# | mysql56.000001 |      668 |              |                  |                   |
# +----------------+----------+--------------+------------------+-------------------+
# 1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 配置从数据库服务器&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 指定server-id 并重启数据库服务
[root@mysql57 ~]# yum -y install【因-斯多】 mysql-server mysql
[root@mysql57 ~]# systemctl【西斯屯-ctl】 start【s 达儿】 mysqld
[root@mysql57 ~]# vim /etc/my.cnf.d/mysql-server.cnf
# [root@mysql57 ~]# vim /etc/my.cnf
[mysqld]
server-id=57
:wq

[root@mysql57 ~]#  systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld
# [root@mysql57 ~]# systemctl restart mysqld

# 管理员登陆，指定主服务器信息
[root@mysql57 ~]# mysql
# [root@mysql57 ~]# mysql -uroot -p123

mysql&amp;gt; change【趁(chèn)吉】 master【马斯特】 to master【马斯特】_host=&quot;192.168.90.56&quot;, master【马斯特】_user=&quot;repluser&quot;, master【马斯特】_password=&quot;123qqq...A&quot;, master【马斯特】_log_file=&quot;mysql56.000001&quot;,master【马斯特】_log_pos=667;
# mysql&amp;gt; change master to master_host=&apos;192.168.88.10&apos;,master_user=&apos;repluser&apos;,master_password=&apos;repluser&apos;,master_log_file=&quot;mysql56.000001&quot;,master_log_pos=668;
# Query OK, 0 rows affected, 8 warnings (9.74 sec)

# 启动slave【斯累夫】进程
mysql&amp;gt;  start【s 达儿】 slave【斯累夫】;
# mysql&amp;gt; start slave;
# Query OK, 0 rows affected, 1 warning (0.95 sec)

# 查看状态信息
mysql&amp;gt; show【瘦】 slave【斯累夫】 status【 斯dèi 特斯】 \G
# mysql&amp;gt; show slave status \G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: 192.168.90.56
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql56.000001
          Read_Master_Log_Pos: 667
               Relay_Log_File: mysql57-relay-bin.000002
                Relay_Log_Pos: 322
        Relay_Master_Log_File: mysql56.000001
             Slave_IO_Running: Yes   //IO线程
            Slave_SQL_Running: Yes   //SQL线程
              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: 667
              Relay_Log_Space: 533
              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: 56
                  Master_UUID: e0ab8dc4-0109-11ee-87e7-525400ad7ed3
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates【阿普 dei 特s】
           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: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set, 1 warning (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、配置mycat【麦-凯特】服务器&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250616174346754.webp&quot; alt=&quot;image-20250616174346754&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;5.1 拷贝软件到mycat【麦-凯特】58主机&lt;/h3&gt;
&lt;p&gt;mycat2-1.21-release-jar-with-dependencies.jar&lt;/p&gt;
&lt;p&gt;mycat2**-&lt;strong&gt;install&lt;/strong&gt;-**template-1.21.zip&lt;/p&gt;
&lt;h3&gt;5.2 安装mycat【麦-凯特】软件&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 安装jdk
[root@mycat58 upload]# yum -y install【因-斯多】 java-1.8.0-openjdk.x86_64
# [root@mycat58 ~]# yum -y install java-1.8.0-openjdk.x86_64
# 安装解压命令
[root@mycat58 upload]# which【维曲】 unzip || yum -y  install【因-斯多】 unzip
# [root@mycat58 ~]# which unzip || yum -y install unzip
# 安装mycat
[root@mycat58 upload]# unzip mycat2-install-template-1.21.zip
# [root@mycat58 ~]# unzip mycat2-install-template-1.21.zip 
[root@mycat58 upload]# mv mycat【麦-凯特】 /usr/local/
# [root@mycat58 ~]# mv mycat /usr/local/
# 安装依赖
[root@mycat58 upload]# cp mycat2-1.21-release-jar-with-dependencies.jar  /usr/local/mycat/lib/
# [root@mycat58 ~]# cp mycat2-1.21-release-jar-with-dependencies.jar /usr/local/mycat/lib/
# 修改权限
[root@mycat58 upload]# chmod -R 777 /usr/local/mycat/ 
# [root@mycat58 ~]# chmod -R 777 /usr/local/mycat/ 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.3 配置mycat【麦-凯特】密码&lt;/h3&gt;
&lt;p&gt;定义客户端连接mycat【麦-凯特】服务使用用户及密码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# vim  /usr/local/mycat/conf/users/root.user.json
{
        &quot;dialect&quot;:&quot;mysql&quot;,
        &quot;ip&quot;:null,
        &quot;password&quot;:&quot;654321&quot;, 密码
        &quot;transactionType&quot;:&quot;proxy&quot;,
        &quot;username&quot;:&quot;mycat&quot; 用户名
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mycat【麦-凯特】连接本机数据库配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# vim /usr/local/mycat/conf/datasources/prototypeDs.datasource.json
{
        &quot;dbType&quot;:&quot;mysql&quot;,
        &quot;idleTimeout&quot;:60000,
        &quot;initSqls&quot;:[],
        &quot;initSqlsGetConnection&quot;:true,
        &quot;instanceType&quot;:&quot;READ_WRITE&quot;,
        &quot;maxCon&quot;:1000,
        &quot;maxConnectTimeout&quot;:3000,
        &quot;maxRetryCount&quot;:5,
        &quot;minCon&quot;:1,
        &quot;name&quot;:&quot;prototypeDs&quot;,
        &quot;password&quot;:&quot;123456&quot;, 密码
        &quot;type&quot;:&quot;JDBC&quot;,
        &quot;url&quot;:&quot;jdbc:mysql://localhost:3306/mysql?useUnicode=true&amp;amp;serverTimezone=Asia/Shanghai&amp;amp;characterEncoding=UTF-8&quot;, 连接本机的数据库服务
        &quot;user&quot;:&quot;jam&quot;, 用户名
        &quot;weight&quot;:0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.4 mycat58主机mysql安装&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#  安装软件
[root@mycat58 ~]# yum -y  install【因-斯多】  mysql-server  mysql
# 启动服务
[root@mycat58 ~]#  systemctl【西斯屯-ctl】  start【s 达儿】 mysqld
#  连接服务
[root@mycat58 ~]# mysql 
# [root@mycat58 ~]# mysql -uroot -p123

#  创建jam用户
mysql&amp;gt; create【克瑞特】 user jam@&quot;%&quot;  identified【爱-丹-提伐】 by【拜】 &quot;123456&quot;;
# mysql&amp;gt; create user jam@&apos;%&apos; identified by &apos;123456&apos;;
# Query OK, 0 rows affected (0.52 sec)

#  授予权限
mysql&amp;gt;  grant【古亮普】 all on *.* to jam@&quot;%&quot; ;
# mysql&amp;gt; grant all on *.* to jam@&apos;%&apos;;
# Query OK, 0 rows affected (1.14 sec)

# 断开连接
mysql&amp;gt;  exit【诶西特】
# mysql&amp;gt; exit
Bye
[root@mycat58 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.5 mycat【麦-凯特】服务启动和连接&lt;/h3&gt;
&lt;p&gt;启动mycat【麦-凯特】服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# /usr/local/mycat/bin/mycat help
# [root@mycat58 ~]# /usr/local/mycat/bin/mycat help
Usage: /usr/local/mycat/bin/mycat { console |  start【s 达儿】 | stop | restart【 率 s 达r】 | status【 斯dèi 特斯】 | dump }

[root@mycat58 ~]# /usr/local/mycat/bin/mycat start
# [root@mycat58 ~]# /usr/local/mycat/bin/mycat start
# Starting mycat2...

# 半分钟左右 能看到端口
[root@mycat58 ~]# netstat  -utnlp  | grep 8066
# [root@mycat58 ~]# netstat -tunlp | grep 8066
# tcp6       0      0 :::8066                 :::*                    LISTEN      30687/java          
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;连接mycat【麦-凯特】服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321
# [root@mycat58 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321

mysql&amp;gt; show【瘦】 databases;
# mysql&amp;gt; show databases;
+--------------------+
| `Database`         |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.11 sec)
Mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、配置读写分离&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250616174409311.webp&quot; alt=&quot;image-20250616174409311&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;6.1 添加数据源&lt;/h3&gt;
&lt;p&gt;添加数据源：连接mycat【麦-凯特】服务后做如下操作&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 连接mycat【麦-凯特】服务
[root@mycat58 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321
# [root@mycat58 ~]# mysql -h 127.0.0.1 -P8066 -umycat -p654321

# 添加mysql56数据库服务器
MySQL&amp;gt; /*+ mycat:createdatasource{
&quot;name&quot;:&quot;whost56&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.90.56:3306&quot;,&quot;user&quot;:&quot;jama&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;whost56&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.10:3306&quot;,&quot;user&quot;:&quot;jama&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# Query OK, 0 rows affected (0.86 sec)

# 添加mysql57数据库服务器
Mysql&amp;gt;/*+ mycat:createdatasource{
&quot;name&quot;:&quot;rhost57&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.90.57:3306&quot;,&quot;user&quot;:&quot;jama&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;rhost57&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.20:3306&quot;,&quot;user&quot;:&quot;jama&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# Query OK, 0 rows affected (0.06 sec)

# 查看数据源
mysql&amp;gt; /*+mycat:showDataSources{}*/ \G
# mysql&amp;gt; /*+mycat:showDataSources{}*/ \G
*************************** 1. row ***************************
                   NAME: whost56
               USERNAME: jama
               PASSWORD: 123456
                MAX_CON: 1000
                MIN_CON: 1
              EXIST_CON: 0
                USE_CON: 0
        MAX_RETRY_COUNT: 5
    MAX_CONNECT_TIMEOUT: 30000
                DB_TYPE: mysql
                    URL: jdbc:mysql://192.168.90.56:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
                 WEIGHT: 0
               INIT_SQL: 
INIT_SQL_GET_CONNECTION: true
          INSTANCE_TYPE: READ_WRITE
           IDLE_TIMEOUT: 60000
                 DRIVER: {
        CreateTime:&quot;2023-06-02 17:01:14&quot;,
        ActiveCount:0,
        PoolingCount:0,
        CreateCount:0,
        DestroyCount:0,
        CloseCount:0,
        ConnectCount:0,
        Connections:[
        ]
}
                   TYPE: JDBC
               IS_MYSQL: true
*************************** 2. row ***************************
                   NAME: rhost57
               USERNAME: jama
               PASSWORD: 123456
                MAX_CON: 1000
                MIN_CON: 1
              EXIST_CON: 0
                USE_CON: 0
        MAX_RETRY_COUNT: 5
    MAX_CONNECT_TIMEOUT: 30000
                DB_TYPE: mysql
                    URL: jdbc:mysql://192.168.90.57:3306?useUnicode=true&amp;amp;serverTimezone=Asia/Shanghai&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
                 WEIGHT: 0
               INIT_SQL: 
INIT_SQL_GET_CONNECTION: true
          INSTANCE_TYPE: READ_WRITE
           IDLE_TIMEOUT: 60000
                 DRIVER: {
        CreateTime:&quot;2023-06-02 17:01:14&quot;,
        ActiveCount:0,
        PoolingCount:0,
        CreateCount:0,
        DestroyCount:0,
        CloseCount:0,
        ConnectCount:0,
        Connections:[
        ]
}
                   TYPE: JDBC
               IS_MYSQL: true
*************************** 3. row ***************************
                   NAME: prototypeDs
               USERNAME: jam
               PASSWORD: 123456
                MAX_CON: 1000
                MIN_CON: 1
              EXIST_CON: 0
                USE_CON: 0
        MAX_RETRY_COUNT: 5
    MAX_CONNECT_TIMEOUT: 3000
                DB_TYPE: mysql
                    URL: jdbc:mysql://localhost:3306/mysql?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
                 WEIGHT: 0
               INIT_SQL: 
INIT_SQL_GET_CONNECTION: true
          INSTANCE_TYPE: READ_WRITE
           IDLE_TIMEOUT: 60000
                 DRIVER: {
        CreateTime:&quot;2023-06-02 17:01:14&quot;,
        ActiveCount:0,
        PoolingCount:0,
        CreateCount:0,
        DestroyCount:0,
        CloseCount:0,
        ConnectCount:0,
        Connections:[
        ]
}
                   TYPE: JDBC
               IS_MYSQL: true
3 rows in set (0.00 sec)
mysql&amp;gt;

# 添加的数据源以文件的形式保存在安装目录下
[root@mycat58 conf]# ls /usr/local/mycat/conf/datasources/
# [root@mycat58 ~]# ls /usr/local/mycat/conf/datasources/
# prototypeDs.datasource.json  rhost57.datasource.json  whost56.datasource.json

[root@mycat58 conf]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.2 配置数据库服务器添加jama用户&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 在master【马斯特】服务器添加
[root@mysql56 ~]# mysql 

mysql&amp;gt; create【克瑞特】 user jama@&quot;%&quot;  identified【爱-丹-提伐】 by【拜】 &quot;123456&quot;;
# mysql&amp;gt; create user jama@&quot;%&quot;  identified by &quot;123456&quot;;
# Query OK, 0 rows affected (0.24 sec)

mysql&amp;gt;  grant【古亮普】 all on *.* to  jama@&quot;%&quot;;
# mysql&amp;gt; grant  all on *.* to  jama@&quot;%&quot;;
# Query OK, 0 rows affected (0.19 sec)

mysql&amp;gt; exit【诶西特】
[root@mysql56 ~]#

# 在slave【斯累夫】服务器查看是否同步成功
[root@mysql57 ~]# mysql -e &apos;select【涩莱克特】 user , host from【弗乱】 mysql.user where user=&quot;jama&quot;&apos;
+------+------+
| user | host |
+------+------+
| jama | %    |
+------+------+
[root@mysql57 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.3 创建集群&lt;/h3&gt;
&lt;p&gt;创建集群,连接mycat【麦-凯特】服务后做如下配置:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321

# 创建集群
mysql&amp;gt;/*!mycat:createcluster{
&quot;name&quot;:&quot;rwcluster&quot;,
&quot;masters&quot;:[&quot;whost56&quot;],
&quot;replicas&quot;:[&quot;rhost57&quot;]
}*/ ;


# 查看集群信息
mysql&amp;gt; /*+ mycat:showClusters{}*/ \G
*************************** 1. row ***************************
             NAME: rwcluster
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 2000
             TYPE: BALANCE_ALL
         WRITE_DS: whost56
          READ_DS: whost56,rhost57
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
*************************** 2. row ***************************
             NAME: prototype
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 200
             TYPE: BALANCE_ALL
         WRITE_DS: prototypeDs
          READ_DS: prototypeDs
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
2 rows in set (0.00 sec)
mysql&amp;gt;

# 创建的集群以文件的形式保存在目录下
[root@mycat58 conf]# ls /usr/local/mycat/conf/clusters/
prototype.cluster.json  rwcluster.cluster.json
[root@mycat58 conf]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.4 指定主机角色&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 修改master【马斯特】角色主机仅负责写访问
[root@mycat58 ~]# vim /usr/local/mycat/conf/datasources/whost56.datasource.json
{
        &quot;dbType&quot;:&quot;mysql&quot;,
        &quot;idleTimeout&quot;:60000,
        &quot;initSqls&quot;:[],
        &quot;initSqlsGetConnection&quot;:true,
        &quot;instanceType&quot;:&quot;WRITE&quot;, 仅负责写访问
        &quot;logAbandoned&quot;:true,
        &quot;maxCon&quot;:1000,
        &quot;maxConnectTimeout&quot;:30000,
        &quot;maxRetryCount&quot;:5,
        &quot;minCon&quot;:1,
        &quot;name&quot;:&quot;whost56&quot;,
        &quot;password&quot;:&quot;123456&quot;,
        &quot;queryTimeout&quot;:0,
        &quot;removeAbandoned&quot;:false,
        &quot;removeAbandonedTimeoutSecond&quot;:180,
        &quot;type&quot;:&quot;JDBC&quot;,
        &quot;url&quot;:&quot;jdbc:mysql://192.168.90.56:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&quot;,
        &quot;user&quot;:&quot;jama&quot;,
        &quot;weight&quot;:0
}
:wq

# 修改slave【斯累夫】角色主机仅负责读访问
[root@mycat58 ~]# vim /usr/local/mycat/conf/datasources/rhost57.datasource.json
{
        &quot;dbType&quot;:&quot;mysql&quot;,
        &quot;idleTimeout&quot;:60000,
        &quot;initSqls&quot;:[],
        &quot;initSqlsGetConnection&quot;:true,
        &quot;instanceType&quot;:&quot;READ&quot;,仅负责读访问
        &quot;logAbandoned&quot;:true,
        &quot;maxCon&quot;:1000,
        &quot;maxConnectTimeout&quot;:30000,
        &quot;maxRetryCount&quot;:5,
        &quot;minCon&quot;:1,
        &quot;name&quot;:&quot;rhost57&quot;,
        &quot;password&quot;:&quot;123456&quot;,
        &quot;queryTimeout&quot;:0,
        &quot;removeAbandoned&quot;:false,
        &quot;removeAbandonedTimeoutSecond&quot;:180,
        &quot;type&quot;:&quot;JDBC&quot;,
        &quot;url&quot;:&quot;jdbc:mysql://192.168.90.57:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&quot;,
        &quot;user&quot;:&quot;jama&quot;,
        &quot;weight&quot;:0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.5 修改读策略&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;readBalanceType&lt;/code&gt;参数值&lt;/th&gt;
&lt;th&gt;负载均衡策略说明&lt;/th&gt;
&lt;th&gt;行为描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;BALANCE_ALL_READ&lt;/strong&gt;​&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;在所有从库（Replicas）间均衡&lt;/strong&gt;​&lt;/td&gt;
&lt;td&gt;所有的 &lt;code&gt;SELECT&lt;/code&gt;查询请求会在 &lt;code&gt;replicas&lt;/code&gt;列表配置的所有从库上进行负载均衡。写节点（&lt;code&gt;masters&lt;/code&gt;）不参与读流量的分担。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;BALANCE_ALL&lt;/strong&gt;​ (如果支持)&lt;/td&gt;
&lt;td&gt;在所有节点（主和从）间均衡&lt;/td&gt;
&lt;td&gt;读请求会随机地在所有数据库节点（包括写节点 &lt;code&gt;masters&lt;/code&gt;和读节点 &lt;code&gt;replicas&lt;/code&gt;）上进行分发。这种模式允许主库也承担一部分读压力。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;BALANCE_MASTER&lt;/strong&gt;​ (如果支持)&lt;/td&gt;
&lt;td&gt;仅从主库读取&lt;/td&gt;
&lt;td&gt;所有读请求都会发往配置的写节点（&lt;code&gt;masters&lt;/code&gt;）。这通常用于需要强一致性读的场景，或者尚未配置从库的情况。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# vim /usr/local/mycat/conf/clusters/rwcluster.cluster.json 
{
        &quot;clusterType&quot;:&quot;MASTER_SLAVE&quot;,
        &quot;heartbeat&quot;:{
                &quot;heartbeatTimeout&quot;:1000,
                &quot;maxRetryCount&quot;:3,
                &quot;minSwitchTimeInterval&quot;:300,
                &quot;showLog&quot;:false,
                &quot;slaveThreshold&quot;:0.0
        },
        &quot;masters&quot;:[
                &quot;whost56&quot;
        ],
        &quot;maxCon&quot;:2000,
        &quot;name&quot;:&quot;rwcluster&quot;,
        &quot;readBalanceType&quot;:&quot;BALANCE_ALL_READ&quot;,# _READ将查询语句分发到从数据库节点
        &quot;replicas&quot;:[
                &quot;rhost57&quot;
        ],
        &quot;switchType&quot;:&quot;SWITCH&quot;
}
:wq

# 重启mycat【麦-凯特】服务
[root@mycat58 ~]# /usr/local/mycat/bin/mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...

[root@mycat58 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;七、测试读写分离&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250616174434099.webp&quot; alt=&quot;image-20250616174434099&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;7.1 指定testdb库存储数据使用的集群&lt;/h3&gt;
&lt;p&gt;具体操作如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat58 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321 

mysql&amp;gt; create【克瑞特】 database testdb;
# mysql&amp;gt; create database testdb;
# Query OK, 0 rows affected (0.54 sec)

mysql&amp;gt;  exit【诶西特】


# 指定testdb库存储数据使用的集群
[root@mycat58 ~]# vim /usr/local/mycat/conf/schemas/testdb.schema.json
{
        &quot;customTables&quot;:{},
        &quot;globalTables&quot;:{},
        &quot;normalProcedures&quot;:{},
        &quot;normalTables&quot;:{},
        &quot;schemaName&quot;:&quot;testdb&quot;,
        &quot;targetName&quot;:&quot;rwcluster&quot;, 添加此行,之前创建的集群名rwcluster
        &quot;shardingTables&quot;:{},
        &quot;views&quot;:{}
}
:wq

[root@mycat58 ~]# /usr/local/mycat/bin/mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...

[root@mycat58 ~]#

# 连接mycat【麦-凯特】服务建表插入记录
[root@client50 ~]# mysql -h192.168.90.58 -P8066 -umycat -p654321

mysql&amp;gt; create【克瑞特】 table【忒-部】 testdb.user (name varchar【瓦儿-查儿】(10) , password varchar【瓦儿-查儿】(10));
# mysql&amp;gt; create table testdb.user (name varchar(10), password varchar(10));
# Query OK, 0 rows affected (3.65 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】  testdb.user values【挖柳斯】(&quot;yaya&quot;,&quot;123456&quot;);
# mysql&amp;gt; insert into testdb.user values(&quot;yaya&quot;,&quot;123456&quot;);
# Query OK, 1 row affected (0.28 sec)

mysql&amp;gt; select【涩莱克特】 * from【弗乱】 testdb.user;
# mysql&amp;gt; select * from testdb.user;
# +------+----------+
# | name | password |
# +------+----------+
# | yaya | 123456   |
# +------+----------+
# 1 row in set (0.01 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.2 测试读写分离&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 在从服务器本机插入记录，数据仅在从服务器有，主服务器没有
[root@mysql57 ~]# mysql -e &apos;insert【因涩特】 into【因兔】 testdb.user values【挖柳斯】 (&quot;yayaA&quot;,&quot;654321&quot;)&apos;
# [root@mysql57 ~]# mysql -uroot -p123 -e &apos;insert into testdb.user values(&quot;yayaA&quot;,&quot;654321&quot;)&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.

[root@mysql57 ~]# mysql -e &apos;select【涩莱克特】 * from【弗乱】 testdb.user&apos;
# [root@mysql57 ~]# mysql -uroot -p123 -e &apos;select * from testdb.user&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +-------+----------+
# | name  | password |
# +-------+----------+
# | yaya  | 123456   |
# | yayaA | 654321   |
# +-------+----------+


# 主服务器数据不变，日志偏移量不不变
[root@mysql56 ~]# mysql -e &apos;select【涩莱克特】 * from【弗乱】 testdb.user&apos;
# [root@mysql56 ~]# mysql -uroot -p123 -e &apos;select * from testdb.user&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +------+----------+
# | name | password |
# +------+----------+
# | yaya | 123456   |
# +------+----------+

[root@mysql56 ~]# mysql -e &apos;show【瘦】 master【马斯特】 status【 斯dèi 特斯】&apos;
# [root@mysql56 ~]# mysql -uroot -p123 -e &apos;show master status&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +----------------+----------+--------------+------------------+-------------------+
# | File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
# +----------------+----------+--------------+------------------+-------------------+
# | mysql56.000002 |     1910 |              |                  |                   |
# +----------------+----------+--------------+------------------+-------------------+

# 客户端连接mycat【麦-凯特】服务读/写数据
[root@client50 ~]# mysql -h192.168.90.58 -P8066 -umycat -p654321
# [root@mycat58 ~]# mysql -h 127.0.0.1 -P8066 -umycat -p654321

#  查看到的是2条记录的行
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 testdb.user;
# mysql&amp;gt; select * from testdb.user;
# +-------+----------+
# | name  | password |
# +-------+----------+
# | yaya  | 123456   |
# | yayaA | 654321   |
# +-------+----------+
# 2 rows in set (1.34 sec)

#   插入记录
mysql&amp;gt; insert【因涩特】 into【因兔】 testdb.user values【挖柳斯】(&quot;yayaB&quot;,&quot;123456&quot;);
# mysql&amp;gt; insert into testdb.user values(&quot;yayaB&quot;,&quot;123456&quot;);
# Query OK, 1 row affected (0.14 sec)

mysql&amp;gt; select【涩莱克特】  * from【弗乱】 testdb.user;
# mysql&amp;gt; select * from testdb.user;
# +-------+----------+
# | name  | password |
# +-------+----------+
# | yaya  | 123456   |
# | yayaB | 123456   |
# +-------+----------+
# 2 rows in set (0.00 sec)

# 在主服务器查看数据和日志偏移量
[root@mysql56 ~]# mysql -e &apos;select【涩莱克特】 * from【弗乱】 testdb.user&apos;
# [root@mysql56 ~]# mysql -uroot -p123 -e &apos;select * from testdb.user&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +-------+----------+
# | name  | password |
# +-------+----------+
# | yaya  | 123456   |
# | yayaB | 123456   |
# +-------+----------+

[root@mysql56 ~]# mysql -e &apos;show【瘦】 master【马斯特】 status【 斯dèi 特斯】&apos;
# [root@mysql56 ~]# mysql -uroot -p123 -e &apos;show master status&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +----------------+----------+--------------+------------------+-------------------+
# | File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
# +----------------+----------+--------------+------------------+-------------------+
# | mysql56.000002 |     2203 |              |                  |                   |
# +----------------+----------+--------------+------------------+-------------------+

# 客户端连接mycat【麦-凯特】服务查看到的是3条记录
[root@client50 ~]# mysql -h192.168.90.58 -P8066 -umycat -p654321 -e &apos;select【涩莱克特】  * from【弗乱】 testdb.user&apos;
# [root@mycat58 mycat]# mysql -h192.168.88.30 -P8066 -umycat -p654321 -e &apos;select * from testdb.user&apos;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +-------+----------+
# | name  | password |
# +-------+----------+
# | yaya  | 123456   |
# | yayaA | 654321   |
# +-------+----------+
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;MyCat 核心配置文件功能总结&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;配置文件&lt;/th&gt;
&lt;th&gt;核心功能&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;server.xml&lt;/td&gt;
&lt;td&gt;系统级配置（账户、密码、逻辑库、序列、连接参数）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;schema.xml&lt;/td&gt;
&lt;td&gt;逻辑库-物理库映射、表配置、分片规则关联、数据节点/主机配置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rule.xml&lt;/td&gt;
&lt;td&gt;分片规则定义与参数配置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dataHost.xml（可选）&lt;/td&gt;
&lt;td&gt;独立配置数据主机（部分版本将 DataHost 配置拆分到该文件，默认在 schema.xml 中）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;MySQL 读写分离的原理与优势&lt;/h2&gt;
&lt;h3&gt;一、核心原理&lt;/h3&gt;
&lt;p&gt;MySQL 读写分离基于 &lt;strong&gt;主从复制&lt;/strong&gt; 机制，通过中间件（如 MyCat、ProxySQL、MaxScale）实现请求分流，核心逻辑如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;架构基础&lt;/strong&gt;：部署1台主库（Master）和1+台从库（Slave），主库负责写操作，从库仅负责读操作；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据同步&lt;/strong&gt;：主库执行写操作（INSERT/UPDATE/DELETE）后，通过二进制日志（binlog）将数据变更同步到所有从库，保障主从数据一致性；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;请求路由&lt;/strong&gt;：应用程序的SQL请求统一发送至中间件，中间件根据SQL类型分流：
&lt;ul&gt;
&lt;li&gt;写请求（含事务类读请求）直接路由到主库，确保数据写入的原子性和一致性；&lt;/li&gt;
&lt;li&gt;读请求（SELECT）分发到任意从库，支持多从库负载均衡；&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;故障兼容&lt;/strong&gt;：中间件实时监测主从节点状态，自动剔除故障从库，主库故障时可配合主从切换机制保障业务连续性。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;二、核心优势&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;提升并发承载能力&lt;/strong&gt;：读操作（占业务请求80%以上）分流至多从库，主库专注处理写操作，避免读写冲突排队，系统整体并发量显著提升；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;减轻主库负载压力&lt;/strong&gt;：主库无需承担大量读请求的CPU、IO资源消耗，降低主库因负载过高导致的卡顿、超时风险；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高可用与容错&lt;/strong&gt;：从库故障仅影响部分读业务，主库故障可快速切换读请求至从库，避免单点故障导致系统瘫痪；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;优化响应速度&lt;/strong&gt;：从库可就近部署（异地多活），降低网络延迟；且从库可关闭写日志、优化索引，专项提升读性能；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;灵活横向扩展&lt;/strong&gt;：读压力增长时，无需升级主库硬件，仅需新增从库节点接入集群，扩展成本低、效率高；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;简化维护与数据安全&lt;/strong&gt;：从库可作为灾备节点，主库数据丢失时可从从库恢复；报表统计、数据备份等非核心操作可在从库执行，不影响主库业务。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Mycat 在 MySQL 读写分离中的核心作用&lt;/h2&gt;
&lt;p&gt;Mycat 作为开源分布式数据库中间件，是 MySQL 读写分离架构的 &lt;strong&gt;核心枢纽&lt;/strong&gt;，其核心价值是屏蔽底层主从集群复杂度，实现请求智能分流、数据一致性保障和高可用调度，让应用无需感知主从架构即可享受读写分离带来的性能提升。具体作用如下：&lt;/p&gt;
&lt;h3&gt;一、请求路由：读写操作智能分流（核心功能）&lt;/h3&gt;
&lt;p&gt;Mycat 是应用与 MySQL 集群之间的“流量分发器”，实现读写请求的精准拆分：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;SQL 类型识别&lt;/strong&gt;：自动解析应用发送的 SQL 语句，区分读操作（SELECT、SHOW 等）和写操作（INSERT、UPDATE、DELETE、DDL 等）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;路由规则执行&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;写请求（含事务类读请求，如 &lt;code&gt;SELECT ... FOR UPDATE&lt;/code&gt;）强制路由到 &lt;strong&gt;主库&lt;/strong&gt;，确保数据写入的原子性和一致性，避免写操作分散导致的数据冲突；&lt;/li&gt;
&lt;li&gt;读请求默认路由到 &lt;strong&gt;从库&lt;/strong&gt;，并支持多从库负载均衡（如轮询、加权轮询、一致性哈希等算法），将读压力均匀分摊到多个从库，减轻主库负担；&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;灵活路由扩展&lt;/strong&gt;：支持自定义路由规则（如指定某类查询走特定从库、分库分表场景下的联合路由），适配复杂业务需求。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;二、数据一致性保障：解决主从同步延迟问题&lt;/h3&gt;
&lt;p&gt;MySQL 主从复制存在天然的同步延迟（毫秒级到秒级），可能导致“主库写入数据后，从库未及时同步，读请求获取旧数据”的问题。Mycat 提供多种机制保障数据一致性：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;强制走主库策略&lt;/strong&gt;：支持通过 SQL 注解（如 &lt;code&gt;/*MASTER*/ SELECT * FROM table&lt;/code&gt;）或配置规则，让关键读请求（如刚写入后需立即查询的场景）强制路由到主库，避免延迟导致的数据不一致；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;延迟判断机制&lt;/strong&gt;：可配置从库同步延迟阈值（如 1 秒），Mycat 实时监测主从延迟，若从库延迟超过阈值，自动将读请求切换到其他低延迟从库或主库，确保读取数据的时效性；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;事务一致性控制&lt;/strong&gt;：事务内的所有操作（无论读写）均路由到主库，避免事务跨主从执行导致的隔离级别失效或数据不一致。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;三、负载均衡：提升集群并发处理能力&lt;/h3&gt;
&lt;p&gt;针对多从库架构，Mycat 提供成熟的负载均衡策略，最大化利用从库资源：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;读负载均衡&lt;/strong&gt;：将海量读请求均匀分发到多个从库，避免单台从库过载，提升整体读并发能力（如 3 台从库可承载 3 倍于单从库的读请求）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;权重配置支持&lt;/strong&gt;：可根据从库硬件性能（CPU、内存、IO）配置权重（如高性能从库权重设为 3，普通从库设为 1），让资源更优的从库承担更多请求；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;动态负载调整&lt;/strong&gt;：支持在线新增/下线从库节点，Mycat 自动感知节点变化并调整负载分发策略，无需重启应用或中间件。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;四、高可用调度：避免单点故障，保障业务连续性&lt;/h3&gt;
&lt;p&gt;Mycat 实时监测主从节点状态，提供故障自动切换和容错能力，提升集群可用性：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;节点健康检查&lt;/strong&gt;：通过心跳检测（如定期执行 &lt;code&gt;SELECT 1&lt;/code&gt;）监测主从库是否存活，若发现节点故障（如从库宕机、主库离线），自动将其从集群中剔除，避免请求路由到故障节点导致的业务报错；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主从切换支持&lt;/strong&gt;：配合 MGR（MySQL Group Replication）或第三方高可用工具（如 Keepalived），主库故障时，Mycat 可自动识别新主库并切换路由规则，写请求无缝迁移到新主库，读请求继续由正常从库处理，实现业务“无感知”恢复；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;故障恢复自动接入&lt;/strong&gt;：当故障节点修复后，Mycat 可自动检测并将其重新纳入集群，恢复负载均衡，无需人工干预。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;五、透明接入：降低应用改造成本&lt;/h3&gt;
&lt;p&gt;Mycat 对应用完全透明，无需修改应用代码即可实现读写分离：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;协议兼容&lt;/strong&gt;：完全兼容 MySQL 协议，应用可像连接普通 MySQL 数据库一样连接 Mycat（仅需修改数据库连接地址为 Mycat 服务地址，端口为 Mycat 监听端口），无需调整 SQL 语法或数据库驱动；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;逻辑库抽象&lt;/strong&gt;：Mycat 将底层多个主从库抽象为一个“逻辑库”，应用仅需面向逻辑库开发，无需关心底层主从节点的数量、地址和部署架构，降低架构复杂度和运维成本。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;六、辅助功能：强化读写分离架构的稳定性与可维护性&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;权限集中管理&lt;/strong&gt;：在 Mycat 层面统一配置应用访问权限（如某应用仅允许读从库、某账户仅允许写主库），无需在每个 MySQL 节点单独配置，简化权限管理；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SQL 拦截与过滤&lt;/strong&gt;：支持拦截非法 SQL（如高风险 DDL、慢查询）或不符合规则的请求（如写请求路由到从库），避免恶意操作或误操作破坏集群稳定性；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;监控与审计&lt;/strong&gt;：提供完善的日志（如路由日志、错误日志、访问日志）和监控指标（如请求量、路由命中率、节点状态），方便运维人员排查问题、优化性能；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分库分表兼容&lt;/strong&gt;：Mycat 不仅支持读写分离，还可与分库分表功能结合，实现“读写分离+分库分表”的复杂架构，满足海量数据存储和高并发访问的场景（如电商订单库）。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;Mycat 在 MySQL 读写分离架构中的核心作用是 &lt;strong&gt;“承上启下”&lt;/strong&gt;：向上屏蔽底层主从集群的复杂性，让应用无需改造即可享受读写分离的性能红利；向下通过智能路由、负载均衡、高可用调度和一致性保障，最大化发挥主从集群的资源价值，解决“主库负载高、读并发不足、单点故障”等核心问题，是中小型企业实现 MySQL 高可用、高并发架构的优选中间件。&lt;/p&gt;
&lt;h3&gt;Mycat 在 MySQL 读写分离中的核心作用（简洁版）&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;读写请求智能分流&lt;/strong&gt;&lt;br /&gt;
自动解析 SQL 类型，写操作（INSERT/UPDATE/DELETE）路由到主库保证数据一致，读操作（SELECT）分发到从库，避免主库读压力过载。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;保障数据一致与读负载均衡&lt;/strong&gt;&lt;br /&gt;
通过“关键读请求强制走主库”解决主从同步延迟问题；支持多从库按权重分摊读请求，最大化利用从库资源，提升读并发能力。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;透明接入与高可用兜底&lt;/strong&gt;&lt;br /&gt;
应用无需改代码，仅需将连接地址指向 Mycat（兼容 MySQL 协议）；实时监测主从节点状态，故障节点自动剔除，主库故障时配合切换保障业务不中断。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Mycat 读写分离 schema.xml 核心配置项及作用（简洁版）&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;1. **&amp;lt;schema&amp;gt; 标签**  
   - 核心属性：`name`（逻辑库名称）、`checkSQLschema`（是否校验SQL库名）  
   - 作用：定义应用访问的**逻辑库**，关联底层数据节点，屏蔽物理库集群复杂度。

2. **&amp;lt;table&amp;gt; 标签**  
   - 核心属性：`name`（逻辑表名）、`dataNode`（关联的数据节点）、`primaryKey`（主键）、`autoIncrement`（是否自增）  
   - 作用：映射逻辑表与物理表，指定表所属数据节点，配置主键和自增规则（读写分离场景中主要用于关联数据节点）。

3. **&amp;lt;dataNode&amp;gt; 标签**  
   - 核心属性：`name`（数据节点名称）、`dataHost`（关联的数据主机）、`database`（物理库名称）  
   - 作用：关联**数据主机**与**物理库**，是逻辑表到物理库的中间映射。

4. **&amp;lt;dataHost&amp;gt; 标签**（读写分离核心配置）  
   - 核心属性：`name`（数据主机名称）、`balance`（读负载均衡策略）、`writeType`（写路由规则）、`switchType`（主从切换策略）  
   - 作用：配置主从库集群信息，控制读负载分发、写请求路由、主从故障切换。

5. **&amp;lt;writeHost&amp;gt; 标签**  
   - 核心属性：`host`（主机标识）、`url`（主库地址:端口）、`user`（数据库用户名）、`password`（密码）  
   - 作用：定义**主库**连接信息，接收所有写请求（INSERT/UPDATE/DELETE）。

6. **&amp;lt;readHost&amp;gt; 标签**  
   - 核心属性：`host`（主机标识）、`url`（从库地址:端口）、`user`（数据库用户名）、`password`（密码）  
   - 作用：定义**从库**连接信息，接收读请求（SELECT），配合 `balance` 实现负载均衡。

7. **关键属性补充**  
   - `balance=&quot;1&quot;`：开启读负载均衡（主从库均参与读）；  
   - `writeType=&quot;0&quot;`：写请求路由到第一个 &amp;lt;writeHost&amp;gt;（主库）；  
   - `switchType=&quot;1&quot;`：主库故障时自动切换到备用主库/从库。
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Mycat balance 属性（负载均衡策略）取值含义与适用场景&lt;/h2&gt;
&lt;p&gt;balance 是 Mycat &lt;code&gt;schema.xml&lt;/code&gt; 中 &lt;code&gt;&amp;lt;dataHost&amp;gt;&lt;/code&gt; 标签的核心属性，专门控制 &lt;strong&gt;读请求的负载均衡规则&lt;/strong&gt;，取值仅支持 &lt;code&gt;0、1、2、3&lt;/code&gt; 四种，不同取值对应不同的集群架构和业务需求，具体如下：&lt;/p&gt;
&lt;h3&gt;1. balance=&quot;0&quot;：关闭读负载均衡&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;含义&lt;/strong&gt;：不开启读负载分发，所有读请求（SELECT）均路由到当前活跃的 &lt;code&gt;writeHost&lt;/code&gt;（主库），从库（&lt;code&gt;readHost&lt;/code&gt;）不参与读请求处理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;从库未部署（仅单主库架构）；&lt;/li&gt;
&lt;li&gt;主从同步延迟极高（如跨地域主从，延迟秒级以上），读从库会导致数据不一致；&lt;/li&gt;
&lt;li&gt;业务需要 &lt;strong&gt;强一致性读&lt;/strong&gt;（如刚写入数据后立即查询、核心交易查询），必须读主库。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. balance=&quot;1&quot;：主从库混合读负载（推荐默认）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;含义&lt;/strong&gt;：开启读负载均衡，读请求分发到所有 &lt;code&gt;readHost&lt;/code&gt;（从库）和 &lt;strong&gt;备用 &lt;code&gt;writeHost&lt;/code&gt;（备用主库）&lt;/strong&gt;；当前活跃的主库（默认 &lt;code&gt;writeHost&lt;/code&gt;）不参与读请求，仅负责写操作。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;典型主从架构（1主多从 + 1备用主库），需最大化利用从库和备用主库资源；&lt;/li&gt;
&lt;li&gt;读请求占比高（如电商商品查询、新闻列表、用户信息查询），需分摊主库读压力；&lt;/li&gt;
&lt;li&gt;大多数中小型业务的默认选择，兼顾性能和数据一致性（配合主从同步延迟阈值使用）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. balance=&quot;2&quot;：全节点读负载（不分主从）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;含义&lt;/strong&gt;：不区分主库（&lt;code&gt;writeHost&lt;/code&gt;）和从库（&lt;code&gt;readHost&lt;/code&gt;），所有可用的 &lt;code&gt;writeHost&lt;/code&gt;（主库、备用主库）和 &lt;code&gt;readHost&lt;/code&gt;（从库）均参与读负载，读请求随机分发到所有节点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;主库硬件配置充足（CPU/内存/IO 资源未饱和），允许承担部分读请求；&lt;/li&gt;
&lt;li&gt;备用主库长期闲置，需利用其资源分担读压力；&lt;/li&gt;
&lt;li&gt;读压力较大但未达到需要部署多从库的规模，适合中小型集群（如 1主1从 + 1备用主库）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. balance=&quot;3&quot;：仅从库读负载&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;含义&lt;/strong&gt;：读请求仅分发到&lt;code&gt;readHost&lt;/code&gt;（从库），主库（&lt;code&gt;writeHost&lt;/code&gt;）和备用主库&lt;strong&gt;完全不参与&lt;/strong&gt;读负载&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;主库写压力极大（如高频插入/更新），需完全隔离读请求（主库仅负责写）；&lt;/li&gt;
&lt;li&gt;对读数据时效性有要求（需避免主从延迟导致的旧数据），如金融交易查询、订单状态查询；&lt;/li&gt;
&lt;li&gt;多从库架构（1主多从），且从库性能均衡，适合中大型业务的读密集场景。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;balance=&quot;3&quot;&lt;/code&gt;是&lt;strong&gt;最常用的读写分离策略&lt;/strong&gt;，特别适合读多写少的业务场景，它能有效降低主库压力，提升系统整体性能。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;核心总结（快速选型）&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;balance&lt;/code&gt; 值&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;读请求负载策略&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;核心工作机制&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;最适用场景&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;不开启读写分离&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;所有读、写操作均发送至当前可用的主库 (&lt;code&gt;writeHost&lt;/code&gt;)。&lt;/td&gt;
&lt;td&gt;单点数据库、要求强一致性读、从库延迟不可接受。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;主从库混合读负载&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;读请求在所有从库 (&lt;code&gt;readHost&lt;/code&gt;) 及&lt;strong&gt;备用主库&lt;/strong&gt; (&lt;code&gt;standby writeHost&lt;/code&gt;) 间负载均衡，&lt;strong&gt;当前主库不参与读&lt;/strong&gt;。&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;双主双从&lt;/strong&gt;等高可用架构，最大化利用从库和备用主库资源。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;全节点随机读负载&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;所有读请求随机分发到配置内&lt;strong&gt;所有&lt;/strong&gt;数据库节点（包括主库和从库）。&lt;/td&gt;
&lt;td&gt;读压力大，且主库性能充足，允许主库分担读请求。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;仅从库读负载&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;读请求&lt;strong&gt;只&lt;/strong&gt;分发到当前主库对应的从库 (&lt;code&gt;readHost&lt;/code&gt;) 上，&lt;strong&gt;主库完全不负担任何读压力&lt;/strong&gt;。&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;一主多从&lt;/strong&gt;架构，且希望&lt;strong&gt;严格分离读写&lt;/strong&gt;、保障主库写性能的场景。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;八、作业&lt;/h2&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;h4&gt;1&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在 Mycat 读写分离配置中，schema.xml 文件里 datahost 标签的 balance 属性值为 3 时，表示（ D ）。
A. 不开启读写分离机制，所有读操作都可发送到当前可用的 writeHost 上
B. 全部的 readHost 与备用的 writeHost 都参与 select 语句的负载均衡
C. 所有的读写操作都随机在 writeHost，readHost 上分发
D. 所有的读请求随机分发到 writeHost 对应的 readHost 上执行，writeHost 不负担读压力&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;2&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Mycat 的默认数据端口和管理端口分别是（ A ）。
A. 8066 和 9066
B. 9066 和 8066
C. 3306 和 8066
D. 8066 和 3306&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;3&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在 Mycat 配置中，server.xml 文件主要用于（ A ）。
A. 配置 Mycat 所需要的服务器信息，如序列生成方式、逻辑数据库、访问账户和密码等
B. 配置逻辑数据库的映射、表、分片规则、数据结点及真实的数据库信息
C. 定义分片规则
D. 配置负载均衡策略&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;4&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在 Mycat 读写分离配置前，需要确保（ A ）。
A. MySQL 主从复制已完成并正常运行
B. MySQL 版本为 8.0
C. Mycat 安装在 Windows 系统上
D. 所有数据库服务器的 server-id 相同&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;h4&gt;1&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;简述 MySQL 读写分离的原理和优势。
答：
核心原理
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;架构基础&lt;/strong&gt;：部署1台主库（Master）和1+台从库（Slave），主库负责写操作，从库仅负责读操作；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据同步&lt;/strong&gt;：主库执行写操作（INSERT/UPDATE/DELETE）后，通过二进制日志（binlog）将数据变更同步到所有从库，保障主从数据一致性；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;请求路由&lt;/strong&gt;：应用程序的SQL请求统一发送至中间件，中间件根据SQL类型分流：
&lt;ul&gt;
&lt;li&gt;写请求（含事务类读请求）直接路由到主库，确保数据写入的原子性和一致性；&lt;/li&gt;
&lt;li&gt;读请求（SELECT）分发到任意从库，支持多从库负载均衡；&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;故障兼容&lt;/strong&gt;：中间件实时监测主从节点状态，自动剔除故障从库，主库故障时可配合主从切换机制保障业务连续性。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;核心优势
1. &lt;strong&gt;提升并发承载能力&lt;/strong&gt;：读操作（占业务请求80%以上）分流至多从库，主库专注处理写操作，避免读写冲突排队，系统整体并发量显著提升；
2. &lt;strong&gt;减轻主库负载压力&lt;/strong&gt;：主库无需承担大量读请求的CPU、IO资源消耗，降低主库因负载过高导致的卡顿、超时风险；
3. &lt;strong&gt;高可用与容错&lt;/strong&gt;：从库故障仅影响部分读业务，主库故障可快速切换读请求至从库，避免单点故障导致系统瘫痪；
4. &lt;strong&gt;优化响应速度&lt;/strong&gt;：从库可就近部署（异地多活），降低网络延迟；且从库可关闭写日志、优化索引，专项提升读性能；
5. &lt;strong&gt;灵活横向扩展&lt;/strong&gt;：读压力增长时，无需升级主库硬件，仅需新增从库节点接入集群，扩展成本低、效率高；
6. &lt;strong&gt;简化维护与数据安全&lt;/strong&gt;：从库可作为灾备节点，主库数据丢失时可从从库恢复；报表统计、数据备份等非核心操作可在从库执行，不影响主库业务。&lt;/p&gt;
&lt;h4&gt;2&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;说明 Mycat 在 MySQL 读写分离中的作用。
答：
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;读写请求智能分流&lt;/strong&gt;&lt;br /&gt;
自动解析 SQL 类型，写操作（INSERT/UPDATE/DELETE）路由到主库保证数据一致，读操作（SELECT）分发到从库，避免主库读压力过载。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保障数据一致与读负载均衡&lt;/strong&gt;&lt;br /&gt;
通过“关键读请求强制走主库”解决主从同步延迟问题；支持多从库按权重分摊读请求，最大化利用从库资源，提升读并发能力。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;透明接入与高可用兜底&lt;/strong&gt;&lt;br /&gt;
应用无需改代码，仅需将连接地址指向 Mycat（兼容 MySQL 协议）；实时监测主从节点状态，故障节点自动剔除，主库故障时配合切换保障业务不中断。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;3&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;列举 Mycat 读写分离配置中 schema.xml 文件的主要配置项及其作用。
答：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;schema&amp;gt; 标签&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;核心属性：&lt;code&gt;name&lt;/code&gt;（逻辑库名称）、&lt;code&gt;checkSQLschema&lt;/code&gt;（是否校验SQL库名）&lt;/li&gt;
&lt;li&gt;作用：定义应用访问的&lt;strong&gt;逻辑库&lt;/strong&gt;，关联底层数据节点，屏蔽物理库集群复杂度。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;table&amp;gt; 标签&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;核心属性：&lt;code&gt;name&lt;/code&gt;（逻辑表名）、&lt;code&gt;dataNode&lt;/code&gt;（关联的数据节点）、&lt;code&gt;primaryKey&lt;/code&gt;（主键）、&lt;code&gt;autoIncrement&lt;/code&gt;（是否自增）&lt;/li&gt;
&lt;li&gt;作用：映射逻辑表与物理表，指定表所属数据节点，配置主键和自增规则（读写分离场景中主要用于关联数据节点）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;dataNode&amp;gt; 标签&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;核心属性：&lt;code&gt;name&lt;/code&gt;（数据节点名称）、&lt;code&gt;dataHost&lt;/code&gt;（关联的数据主机）、&lt;code&gt;database&lt;/code&gt;（物理库名称）&lt;/li&gt;
&lt;li&gt;作用：关联&lt;strong&gt;数据主机&lt;/strong&gt;与&lt;strong&gt;物理库&lt;/strong&gt;，是逻辑表到物理库的中间映射。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;dataHost&amp;gt; 标签&lt;/strong&gt;（读写分离核心配置）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;核心属性：&lt;code&gt;name&lt;/code&gt;（数据主机名称）、&lt;code&gt;balance&lt;/code&gt;（读负载均衡策略）、&lt;code&gt;writeType&lt;/code&gt;（写路由规则）、&lt;code&gt;switchType&lt;/code&gt;（主从切换策略）&lt;/li&gt;
&lt;li&gt;作用：配置主从库集群信息，控制读负载分发、写请求路由、主从故障切换。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;writeHost&amp;gt; 标签&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;核心属性：&lt;code&gt;host&lt;/code&gt;（主机标识）、&lt;code&gt;url&lt;/code&gt;（主库地址:端口）、&lt;code&gt;user&lt;/code&gt;（数据库用户名）、&lt;code&gt;password&lt;/code&gt;（密码）&lt;/li&gt;
&lt;li&gt;作用：定义&lt;strong&gt;主库&lt;/strong&gt;连接信息，接收所有写请求（INSERT/UPDATE/DELETE）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;readHost&amp;gt; 标签&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;核心属性：&lt;code&gt;host&lt;/code&gt;（主机标识）、&lt;code&gt;url&lt;/code&gt;（从库地址:端口）、&lt;code&gt;user&lt;/code&gt;（数据库用户名）、&lt;code&gt;password&lt;/code&gt;（密码）&lt;/li&gt;
&lt;li&gt;作用：定义&lt;strong&gt;从库&lt;/strong&gt;连接信息，接收读请求（SELECT），配合 &lt;code&gt;balance&lt;/code&gt; 实现负载均衡。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;关键属性补充&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;balance=&quot;1&quot;&lt;/code&gt;：开启读负载均衡（主从库均参与读）；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;writeType=&quot;0&quot;&lt;/code&gt;：写请求路由到第一个 &amp;lt;writeHost&amp;gt;（主库）；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;switchType=&quot;1&quot;&lt;/code&gt;：主库故障时自动切换到备用主库/从库。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;4&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;阐述 Mycat 读写分离中负载均衡策略 balance 属性不同取值的含义和适用场景。
答：
balance 取值 “0”，核心含义为“读请求仅走主库，从库不参与”，适用场景为单主库、强一致性读、主从延迟极高
balance 取值 “1”，核心含义为“读请求走从库+备用主库，主库只读不写”，适用场景为1主多从+备用主库、常规读写分离
balance 取值 “2”，核心含义为“所有主从节点均分担读请求”，适用场景为主库资源充足、读压力适中
balance 取值 “3”，核心含义为“读请求&lt;strong&gt;只&lt;/strong&gt;分发到当前主库对应的从库 (&lt;code&gt;readHost&lt;/code&gt;) 上，&lt;strong&gt;主库完全不负担任何读压力&lt;/strong&gt;。”，适用场景为&lt;strong&gt;一主多从&lt;/strong&gt;架构，且希望&lt;strong&gt;严格分离读写&lt;/strong&gt;、保障主库写性能的场景&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3 操作题&lt;/h3&gt;
&lt;h4&gt;1&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;请详细描述在 Linux 环境下使用 Mycat 实现 MySQL 一主一从读写分离的完整操作步骤，包括 MySQL 主从复制配置、Mycat 安装与配置、测试验证等。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;// **MySQL 主从复制配置**

# 配置主库，指定server_id和开启binlog日记
[root@master ~]# grep -vE &quot;#&quot; /etc/my.cnf
[mysqld]
server-id=56
log-bin=mysql56

# 重启服务
[root@master /]# systemctl restart mysqld

# 创建用户同步的repluser账号密码repluser
mysql&amp;gt; create user repluser@&quot;%&quot; identified WITH mysql_native_password by &quot;repluser&quot;;
Query OK, 0 rows affected (0.09 sec)
# 给repluser用户赋权
mysql&amp;gt; grant replication slave on *.*  to repluser@&quot;%&quot;;
Query OK, 0 rows affected (0.05 sec)
# 查询binlog名称和偏移量
mysql&amp;gt; show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql56.000002 |      157 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)



// **从库安装mysql服务**

# 配置从库，指定server_id和开启binlog日记
[root@slave1 ~]# vim /etc/my.cnf
[root@slave1 ~]# grep -vE &quot;#&quot; /etc/my.cnf
[mysqld]
server-id=57
log_bin=/var/lib/mysql/binlog
relay_log=/var/lib/mysql/relaylog

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

# 从库配置
# 修改默认密码
[root@slave1 ~]# mysql -uroot -p123
# 配置 MySQL 主从复制
mysql&amp;gt; change  master to  master_host=&quot;192.168.88.10&quot; , master_user=&quot;repluser&quot; , master_password=&quot;repluser&quot; ,master_log_file=&quot;mysql56.000002&quot; , master_log_pos=157;
Query OK, 0 rows affected, 8 warnings (0.06 sec)

# 启动slave进程
mysql&amp;gt; start slave;
Query OK, 0 rows affected, 1 warning (0.32 sec)

# 同步查看状态信息
mysql&amp;gt; show slave status \G
......
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
......


# 配置mycat服务jama用户
# 在master 服务器添加
mysql&amp;gt; create user jama@&quot;%&quot;  identified by &quot;123456&quot;;
Query OK, 0 rows affected (0.24 sec)

mysql&amp;gt; grant  all on *.* to  jama@&quot;%&quot;;
Query OK, 0 rows affected (0.19 sec)

# 在slave 服务器查看是否同步成功
[root@slave1 ~]# mysql -e &apos;select user , host from mysql.user where user=&quot;jama&quot;&apos;
+------+------+
| user | host |
+------+------+
| jama | %    |
+------+------+
[root@slave1 ~]#





// **Mycat 安装与配置、测试验证**

# 安装mycat 软件和环境
# 安装jdk64和unzip
[root@mycat ~]# yum -y install java-1.8.0-openjdk.x86_64 unzip
# 安装mycat
[root@mycat ~]# unzip mycat2-install-template-1.21.zip 
[root@mycat ~]# mv mycat /usr/local/
# 安装依赖
[root@mycat ~]# cp mycat2-1.21-release-jar-with-dependencies.jar /usr/local/mycat/lib/
[root@mycat ~]# chmod -R 777 /usr/local/mycat/ 

# 配置mycat 密码
# 定义客户端连接mycat 服务使用用户及密码：
[root@mycat ~]# vim  /usr/local/mycat/conf/users/root.user.json
{
        &quot;dialect&quot;:&quot;mysql&quot;,
        &quot;ip&quot;:null,
        &quot;password&quot;:&quot;654321&quot;, # 密码
        &quot;transactionType&quot;:&quot;proxy&quot;,
        &quot;username&quot;:&quot;mycat&quot; # 用户名
}

# mycat【麦-凯特】连接本机数据库配置
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/prototypeDs.datasource.json
{
        &quot;dbType&quot;:&quot;mysql&quot;,
        &quot;idleTimeout&quot;:60000,
        &quot;initSqls&quot;:[],
        &quot;initSqlsGetConnection&quot;:true,
        &quot;instanceType&quot;:&quot;READ_WRITE&quot;,
        &quot;maxCon&quot;:1000,
        &quot;maxConnectTimeout&quot;:3000,
        &quot;maxRetryCount&quot;:5,
        &quot;minCon&quot;:1,
        &quot;name&quot;:&quot;prototypeDs&quot;,
        &quot;password&quot;:&quot;123456&quot;, # 密码
        &quot;type&quot;:&quot;JDBC&quot;,
        &quot;url&quot;:&quot;jdbc:mysql://localhost:3306/mysql?useUnicode=true&amp;amp;serverTimezone=Asia/Shanghai&amp;amp;characterEncoding=UTF-8&quot;, # 连接本机的数据库服务
        &quot;user&quot;:&quot;jam&quot;, # 用户名
        &quot;weight&quot;:0
}



# mycat58主机mysql配置
[root@mycat ~]# mysql -uroot -p123
#  创建jam用户
mysql&amp;gt; create user jam@&apos;%&apos; identified by &apos;123456&apos;;
Query OK, 0 rows affected (0.52 sec)
#  授予权限
mysql&amp;gt; grant all on *.* to jam@&apos;%&apos;;
Query OK, 0 rows affected (1.14 sec)

# 断开连接
mysql&amp;gt; exit


# 启动mycat 服务
[root@mycat ~]# /usr/local/mycat/bin/mycat start
Starting mycat2...

# 半分钟左右 能看到端口     
[root@mycat ~]# netstat -tunlp | grep -E &quot;8066|9066&quot;
tcp6       0      0 :::8066                 :::*                    LISTEN      18159/java          
tcp6       0      0 127.0.0.1:9066          :::*                    LISTEN      18159/java       


# 连接mycat 服务
[root@mycat ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321

mysql&amp;gt; show databases;
+--------------------+
| `Database`         |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.11 sec)


# 配置读写分离
# 添加数据源
# 连接mycat 服务
[root@mycat ~]# mysql -h 127.0.0.1 -P8066 -umycat -p654321

# 添加mysql56数据库服务器
mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;whost56&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.10:3306&quot;,&quot;user&quot;:&quot;jama&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
Query OK, 0 rows affected (0.86 sec)

# 添加mysql57数据库服务器
mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;rhost57&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.20:3306&quot;,&quot;user&quot;:&quot;jama&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
Query OK, 0 rows affected (0.06 sec)

# 查看数据源
mysql&amp;gt; /*+mycat:showDataSources{}*/ \G
*************************** 1. row ***************************
                   NAME: whost56
               USERNAME: jama
               PASSWORD: 123456
......
                DB_TYPE: mysql
                    URL: jdbc:mysql://192.168.88.10:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
......
*************************** 2. row ***************************
                   NAME: prototypeDs
               USERNAME: jam
               PASSWORD: 123456
......
                DB_TYPE: mysql
                    URL: jdbc:mysql://localhost:3306/mysql?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
......
*************************** 3. row ***************************
                   NAME: rhost57
               USERNAME: jama
               PASSWORD: 123456
......
                DB_TYPE: mysql
                    URL: jdbc:mysql://192.168.88.20:3306?useUnicode=true&amp;amp;serverTimezone=Asia/Shanghai&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
......
3 rows in set (0.01 sec)

# 创建集群
[root@mycat ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321

# 创建集群
mysql&amp;gt;/*!mycat:createcluster{
&quot;name&quot;:&quot;rwcluster&quot;,
&quot;masters&quot;:[&quot;whost56&quot;],
&quot;replicas&quot;:[&quot;rhost57&quot;]
}*/ ;


# 查看集群信息
mysql&amp;gt; /*+ mycat:showClusters{}*/ \G
*************************** 1. row ***************************
             NAME: rwcluster
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 2000
             TYPE: BALANCE_ALL
         WRITE_DS: whost56
          READ_DS: whost56,rhost57
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
*************************** 2. row ***************************
             NAME: prototype
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 200
             TYPE: BALANCE_ALL
         WRITE_DS: prototypeDs
          READ_DS: prototypeDs
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
2 rows in set (0.01 sec)


# 指定主机角色
# 修改master 角色主机仅负责写访问
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/whost56.datasource.json
{
        &quot;dbType&quot;:&quot;mysql&quot;,
        &quot;idleTimeout&quot;:60000,
        &quot;initSqls&quot;:[],
        &quot;initSqlsGetConnection&quot;:true,
        &quot;instanceType&quot;:&quot;WRITE&quot;, 仅负责写访问
        &quot;logAbandoned&quot;:true,
        &quot;maxCon&quot;:1000,
        &quot;maxConnectTimeout&quot;:30000,
        &quot;maxRetryCount&quot;:5,
        &quot;minCon&quot;:1,
        &quot;name&quot;:&quot;whost56&quot;,
        &quot;password&quot;:&quot;123456&quot;,
        &quot;queryTimeout&quot;:0,
        &quot;removeAbandoned&quot;:false,
        &quot;removeAbandonedTimeoutSecond&quot;:180,
        &quot;type&quot;:&quot;JDBC&quot;,
        &quot;url&quot;:&quot;jdbc:mysql://192.168.90.56:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&quot;,
        &quot;user&quot;:&quot;jama&quot;,
        &quot;weight&quot;:0
}
:wq

# 修改slave 角色主机仅负责读访问
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/rhost57.datasource.json
{
        &quot;dbType&quot;:&quot;mysql&quot;,
        &quot;idleTimeout&quot;:60000,
        &quot;initSqls&quot;:[],
        &quot;initSqlsGetConnection&quot;:true,
        &quot;instanceType&quot;:&quot;READ&quot;,仅负责读访问
        &quot;logAbandoned&quot;:true,
        &quot;maxCon&quot;:1000,
        &quot;maxConnectTimeout&quot;:30000,
        &quot;maxRetryCount&quot;:5,
        &quot;minCon&quot;:1,
        &quot;name&quot;:&quot;rhost57&quot;,
        &quot;password&quot;:&quot;123456&quot;,
        &quot;queryTimeout&quot;:0,
        &quot;removeAbandoned&quot;:false,
        &quot;removeAbandonedTimeoutSecond&quot;:180,
        &quot;type&quot;:&quot;JDBC&quot;,
        &quot;url&quot;:&quot;jdbc:mysql://192.168.90.57:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&quot;,
        &quot;user&quot;:&quot;jama&quot;,
        &quot;weight&quot;:0
}


# 修改读策略
[root@mycat ~]# vim /usr/local/mycat/conf/clusters/rwcluster.cluster.json 
{
        &quot;clusterType&quot;:&quot;MASTER_SLAVE&quot;,
        &quot;heartbeat&quot;:{
                &quot;heartbeatTimeout&quot;:1000,
                &quot;maxRetryCount&quot;:3,
                &quot;minSwitchTimeInterval&quot;:300,
                &quot;showLog&quot;:false,
                &quot;slaveThreshold&quot;:0.0
        },
        &quot;masters&quot;:[
                &quot;whost56&quot;
        ],
        &quot;maxCon&quot;:2000,
        &quot;name&quot;:&quot;rwcluster&quot;,
        &quot;readBalanceType&quot;:&quot;BALANCE_ALL_READ&quot;,# _READ将查询语句分发到从数据库节点
        &quot;replicas&quot;:[
                &quot;rhost57&quot;
        ],
        &quot;switchType&quot;:&quot;SWITCH&quot;
}
:wq

# 重启mycat 服务
[root@mycat ~]# /usr/local/mycat/bin/mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...

[root@mycat ~]#







// **测试读写分离测试读写分离**
# 指定testdb库存储数据使用的集群
[root@mycat ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321 
mysql&amp;gt; create database testdb;
Query OK, 0 rows affected (0.54 sec)

mysql&amp;gt; exit
Bye
# 指定testdb库存储数据使用的集群
[root@mycat ~]# vim /usr/local/mycat/conf/schemas/testdb.schema.json
{
        &quot;customTables&quot;:{},
        &quot;globalTables&quot;:{},
        &quot;normalProcedures&quot;:{},
        &quot;normalTables&quot;:{},
        &quot;schemaName&quot;:&quot;testdb&quot;,
        &quot;targetName&quot;:&quot;rwcluster&quot;, 添加此行,之前创建的集群名rwcluster
        &quot;shardingTables&quot;:{},
        &quot;views&quot;:{}
}
:wq

[root@mycat ~]# /usr/local/mycat/bin/mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...


# 连接mycat 服务建表插入记录
[root@mycat ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321 
mysql&amp;gt; create table testdb.user (name varchar(10), password varchar(10));
Query OK, 0 rows affected (3.52 sec)

mysql&amp;gt; insert into testdb.user values(&quot;yaya&quot;,&quot;123456&quot;);
Query OK, 1 row affected (0.39 sec)

mysql&amp;gt; select * from testdb.user;
+------+----------+
| name | password |
+------+----------+
| yaya | 123456   |
+------+----------+
1 row in set (0.02 sec)


# 测试读写分离
# 在从服务器本机插入记录，数据仅在从服务器有，主服务器没有
[root@slave1 ~]# mysql -uroot -p123 -e &apos;insert into testdb.user values(&quot;yayaA&quot;,&quot;654321&quot;)&apos;
mysql: [Warning] Using a password on the command line interface can be insecure.

[root@slave1 ~]# mysql -uroot -p123 -e &apos;select * from testdb.user&apos;
mysql: [Warning] Using a password on the command line interface can be insecure.
+-------+----------+
| name  | password |
+-------+----------+
| yaya  | 123456   |
| yayaA | 654321   |
+-------+----------+


# 主服务器数据不变，日志偏移量不不变
[root@master ~]# mysql -uroot -p123 -e &apos;select * from testdb.user&apos;
mysql: [Warning] Using a password on the command line interface can be insecure.
+------+----------+
| name | password |
+------+----------+
| yaya | 123456   |
+------+----------+

[root@master ~]# mysql -uroot -p123 -e &apos;show master status&apos;
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql56.000002 |     1503 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+

# 客户端连接mycat 服务读/写数据
#  查看到的是2条记录的行
mysql&amp;gt; select * from testdb.user;
+-------+----------+
| name  | password |
+-------+----------+
| yaya  | 123456   |
| yayaA | 654321   |
+-------+----------+
2 rows in set (1.34 sec)

#   插入记录
mysql&amp;gt; insert into testdb.user values(&quot;yayaB&quot;,&quot;123456&quot;);
Query OK, 1 row affected (0.14 sec)

mysql&amp;gt; select * from testdb.user;
+-------+----------+
| name  | password |
+-------+----------+
| yaya  | 123456   |
| yayaB | 123456   |
+-------+----------+
2 rows in set (0.00 sec)

# 在主服务器查看数据和日志偏移量
[root@master ~]# mysql -uroot -p123 -e &apos;select * from testdb.user&apos;
mysql: [Warning] Using a password on the command line interface can be insecure.
+-------+----------+
| name  | password |
+-------+----------+
| yaya  | 123456   |
| yayaB | 123456   |
+-------+----------+

[root@master ~]# mysql -uroot -p123 -e &apos;show master status&apos;
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql56.000002 |     1796 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+

# 客户端连接mycat 服务查看到的是3条记录
mysql&amp;gt; select * from testdb.user;
+-------+----------+
| name  | password |
+-------+----------+
| yaya  | 123456   |
| yayaA | 654321   |
| yayaB | 123456   |
+-------+----------+
3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;假设已有一个 MySQL 双主双从的主从复制环境，现要使用 Mycat 实现读写分离，请写出 Mycat 的具体配置步骤和配置文件示例。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;# Mycat 核心配置步骤
# 1：确认 Mycat 环境（已安装 JDK 1.8+，Mycat 已部署）

# 2：配置 Mycat 数据源（4个节点，每个节点1个配置文件）
# 2.1 主库1数据源：masterA.datasource.json
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/masterA.datasource.json
{
  &quot;dbType&quot;: &quot;mysql&quot;,
  &quot;idleTimeout&quot;: 60000,
  &quot;initSqls&quot;: [],
  &quot;initSqlsGetConnection&quot;: true,
  &quot;instanceType&quot;: &quot;WRITE&quot;,  # 主库：写角色
  &quot;maxCon&quot;: 1000,
  &quot;maxConnectTimeout&quot;: 30000,
  &quot;maxRetryCount&quot;: 5,
  &quot;minCon&quot;: 1,
  &quot;name&quot;: &quot;masterA&quot;,  # 数据源名称（与拓扑标识一致）
  &quot;password&quot;: &quot;Mycat@123&quot;,
  &quot;type&quot;: &quot;JDBC&quot;,
  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.61:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
  &quot;user&quot;: &quot;mycat_user&quot;,
  &quot;weight&quot;: 1  # 写负载权重（双主权重相同，均分写请求）
}

# 2.2 主库2数据源：masterB.datasource.json
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/masterB.datasource.json
{
  &quot;dbType&quot;: &quot;mysql&quot;,
  &quot;idleTimeout&quot;: 60000,
  &quot;initSqls&quot;: [],
  &quot;initSqlsGetConnection&quot;: true,
  &quot;instanceType&quot;: &quot;WRITE&quot;,  # 主库：写角色（双主互备）
  &quot;maxCon&quot;: 1000,
  &quot;maxConnectTimeout&quot;: 30000,
  &quot;maxRetryCount&quot;: 5,
  &quot;minCon&quot;: 1,
  &quot;name&quot;: &quot;masterB&quot;,  # 数据源名称
  &quot;password&quot;: &quot;Mycat@123&quot;,
  &quot;type&quot;: &quot;JDBC&quot;,
  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.62:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
  &quot;user&quot;: &quot;mycat_user&quot;,
  &quot;weight&quot;: 1  # 与主库1权重一致，实现写负载均衡
}

# 2.3 从库1数据源：slaveA.datasource.json
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/slaveA.datasource.json
{
  &quot;dbType&quot;: &quot;mysql&quot;,
  &quot;idleTimeout&quot;: 60000,
  &quot;initSqls&quot;: [],
  &quot;initSqlsGetConnection&quot;: true,
  &quot;instanceType&quot;: &quot;READ&quot;,  # 从库：读角色
  &quot;maxCon&quot;: 1000,
  &quot;maxConnectTimeout&quot;: 30000,
  &quot;maxRetryCount&quot;: 5,
  &quot;minCon&quot;: 1,
  &quot;name&quot;: &quot;slaveA&quot;,  # 数据源名称
  &quot;password&quot;: &quot;Mycat@123&quot;,
  &quot;type&quot;: &quot;JDBC&quot;,
  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.63:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
  &quot;user&quot;: &quot;mycat_user&quot;,
  &quot;weight&quot;: 1  # 读负载权重（双从权重相同，均分读请求）
}

# 2.4 从库2数据源：slaveB.datasource.json
[root@mycat ~]# vim /usr/local/mycat/conf/datasources/slaveB.datasource.json
{
  &quot;dbType&quot;: &quot;mysql&quot;,
  &quot;idleTimeout&quot;: 60000,
  &quot;initSqls&quot;: [],
  &quot;initSqlsGetConnection&quot;: true,
  &quot;instanceType&quot;: &quot;READ&quot;,  # 从库：读角色
  &quot;maxCon&quot;: 1000,
  &quot;maxConnectTimeout&quot;: 30000,
  &quot;maxRetryCount&quot;: 5,
  &quot;minCon&quot;: 1,
  &quot;name&quot;: &quot;slaveB&quot;,  # 数据源名称
  &quot;password&quot;: &quot;Mycat@123&quot;,
  &quot;type&quot;: &quot;JDBC&quot;,
  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.64:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
  &quot;user&quot;: &quot;mycat_user&quot;,
  &quot;weight&quot;: 1  # 与从库1权重一致，实现读负载均衡
}

# 3：配置 Mycat 集群（核心：双主双从读写策略）
[root@mycat ~]# vim /usr/local/mycat/conf/clusters/dual_master_dual_slave.cluster.json
{
  &quot;clusterType&quot;: &quot;MASTER_SLAVE&quot;,  # 集群类型：主从架构（支持双主）
  &quot;heartbeat&quot;: {  # 心跳检测（监测节点存活）
    &quot;heartbeatTimeout&quot;: 1000,
    &quot;maxRetryCount&quot;: 3,
    &quot;minSwitchTimeInterval&quot;: 300,  # 故障切换最小间隔（毫秒）
    &quot;showLog&quot;: false,
    &quot;slaveThreshold&quot;: 0.5  # 从库同步延迟阈值（秒），超过则剔除
  },
  &quot;masters&quot;: [&quot;masterA&quot;, &quot;masterB&quot;],  # 双主数据源名称（写请求路由到这里）
  &quot;maxCon&quot;: 4000,  # 集群最大连接数（4个节点总和）
  &quot;name&quot;: &quot;dual_master_dual_slave&quot;,  # 集群名称（后续关联逻辑库用）
  &quot;readBalanceType&quot;: &quot;BALANCE_ALL_READ&quot;,  # 读负载策略：所有从库均分读请求
  &quot;replicas&quot;: [&quot;slaveA&quot;, &quot;slaveB&quot;],  # 双从数据源名称（读请求路由到这里）
  &quot;switchType&quot;: &quot;SWITCH&quot;,  # 故障切换策略：自动切换（主库故障时切换到备用主库）
  &quot;writeBalanceType&quot;: &quot;BALANCE_ALL_WRITE&quot;  # 写负载策略：双主均分写请求（核心！双主特色）
}

# 4：配置 Mycat 逻辑库（关联集群）
[root@mycat mycat]# vim /usr/local/mycat/conf/schemas/business.schema.json
{
  &quot;customTables&quot;: {},
  &quot;globalTables&quot;: {},
  &quot;normalProcedures&quot;: {},
  &quot;normalTables&quot;: {},
  &quot;schemaName&quot;: &quot;business&quot;,  # 逻辑库名称（应用连接 Mycat 时使用）
  &quot;targetName&quot;: &quot;dual_master_dual_slave&quot;,  # 关联上面创建的集群名称
  &quot;shardingTables&quot;: {},
  &quot;views&quot;: {}
}

# 5：配置 Mycat 访问用户（可选，若已配置可跳过）
[root@mycat ~]# vim /usr/local/mycat/conf/users/mycat_user.user.json
{
  &quot;dialect&quot;: &quot;mysql&quot;,
  &quot;ip&quot;: null,  # 允许所有IP访问（生产环境可指定IP）
  &quot;password&quot;: &quot;Mycat@666&quot;,  # 应用连接 Mycat 的密码
  &quot;transactionType&quot;: &quot;proxy&quot;,
  &quot;username&quot;: &quot;mycat_app&quot;  # 应用连接 Mycat 的用户名
}

# **启动与验证**
# 重启 Mycat 加载配置
[root@mycat ~]# /usr/local/mycat/bin/mycat restart

# 2.1 连接 Mycat 逻辑库
[root@mycat ~]# mysql -h 127.0.0.1 -P 8066 -u mycat_app -pMycat@666
mysql&amp;gt; -- 查看逻辑库
mysql&amp;gt; show databases;
mysql&amp;gt; -- 查看 Mycat 数据源状态
mysql&amp;gt; /*+ mycat:showDataSources{}*/ \G
mysql&amp;gt; -- 查看集群状态
mysql&amp;gt; /*+ mycat:showClusters{}*/ \G

-- **验证读写分离效果**
mysql&amp;gt; -- 写操作（插入数据，会路由到双主之一）
mysql&amp;gt; use business;
mysql&amp;gt; create table test_user (id int primary key auto_increment, name varchar(20));
mysql&amp;gt; insert into test_user (name) values (&quot;user1&quot;), (&quot;user2&quot;);

# 直接连接 masterA 查看双主数据
[root@mycat ~]# mysql -h 192.168.90.61 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
# 直接连接 masterB 查看双主数据
[root@mycat ~]# mysql -h 192.168.90.62 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;

# 查看双从数据
[root@mycat ~]# mysql -h 192.168.90.63 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
[root@mycat ~]# mysql -h 192.168.90.64 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# Mycat 实现 MySQL 双主双从读写分离（配置步骤+文件示例）
## 一、环境前提（已就绪）
假设双主双从复制环境已搭建完成（**核心前提：双主互为主从，主从数据同步正常**），拓扑如下：
| 节点角色       | IP地址         | 端口 | 数据库用户 | 密码   | 实例标识（Mycat中用） |
|----------------|----------------|------|------------|--------|-----------------------|
| 主库1（MasterA） | 192.168.90.61  | 3306 | mycat_user | Mycat@123 | masterA               |
| 主库2（MasterB） | 192.168.90.62  | 3306 | mycat_user | Mycat@123 | masterB               |
| 从库1（SlaveA）  | 192.168.90.63  | 3306 | mycat_user | Mycat@123 | slaveA                |
| 从库2（SlaveB）  | 192.168.90.64  | 3306 | mycat_user | Mycat@123 | slaveB                |

### 双主双从复制要求
- 双主已配置 **互为主从**（MasterA → MasterB 同步，MasterB → MasterA 同步），支持写负载或故障切换；
- 每个主库对应从库同步正常（MasterA → SlaveA，MasterB → SlaveB），`Slave_IO_Running=Yes` 且 `Slave_SQL_Running=Yes`；
- 所有节点已创建 Mycat 访问用户（`mycat_user`），并授予权限：`GRANT ALL ON *.* TO &apos;mycat_user&apos;@&apos;%&apos; IDENTIFIED WITH mysql_native_password BY &apos;Mycat@123&apos;;`

## 二、Mycat 核心配置步骤（基于 Mycat 2.x，与你之前版本一致）
### 步骤1：确认 Mycat 环境（已安装 JDK 1.8+，Mycat 2.x 已部署）
无需额外安装，仅需配置以下文件（路径：`/usr/local/mycat/conf/`）。

### 步骤2：配置 Mycat 数据源（4个节点，每个节点1个配置文件）
在 `conf/datasources/` 目录下，创建4个数据源配置文件（描述每个 MySQL 节点的连接信息）。

#### 2.1 主库1数据源：masterA.datasource.json
	```json
	{
	  &quot;dbType&quot;: &quot;mysql&quot;,
	  &quot;idleTimeout&quot;: 60000,
	  &quot;initSqls&quot;: [],
	  &quot;initSqlsGetConnection&quot;: true,
	  &quot;instanceType&quot;: &quot;WRITE&quot;,  // 主库：写角色
	  &quot;maxCon&quot;: 1000,
	  &quot;maxConnectTimeout&quot;: 30000,
	  &quot;maxRetryCount&quot;: 5,
	  &quot;minCon&quot;: 1,
	  &quot;name&quot;: &quot;masterA&quot;,  // 数据源名称（与拓扑标识一致）
	  &quot;password&quot;: &quot;Mycat@123&quot;,
	  &quot;type&quot;: &quot;JDBC&quot;,
	  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.61:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
	  &quot;user&quot;: &quot;mycat_user&quot;,
	  &quot;weight&quot;: 1  // 写负载权重（双主权重相同，均分写请求）
	}
	```

#### 2.2 主库2数据源：masterB.datasource.json
	```json
	{
	  &quot;dbType&quot;: &quot;mysql&quot;,
	  &quot;idleTimeout&quot;: 60000,
	  &quot;initSqls&quot;: [],
	  &quot;initSqlsGetConnection&quot;: true,
	  &quot;instanceType&quot;: &quot;WRITE&quot;,  // 主库：写角色（双主互备）
	  &quot;maxCon&quot;: 1000,
	  &quot;maxConnectTimeout&quot;: 30000,
	  &quot;maxRetryCount&quot;: 5,
	  &quot;minCon&quot;: 1,
	  &quot;name&quot;: &quot;masterB&quot;,  // 数据源名称
	  &quot;password&quot;: &quot;Mycat@123&quot;,
	  &quot;type&quot;: &quot;JDBC&quot;,
	  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.62:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
	  &quot;user&quot;: &quot;mycat_user&quot;,
	  &quot;weight&quot;: 1  // 与主库1权重一致，实现写负载均衡
	}
	```

#### 2.3 从库1数据源：slaveA.datasource.json
	```json
	{
	  &quot;dbType&quot;: &quot;mysql&quot;,
	  &quot;idleTimeout&quot;: 60000,
	  &quot;initSqls&quot;: [],
	  &quot;initSqlsGetConnection&quot;: true,
	  &quot;instanceType&quot;: &quot;READ&quot;,  // 从库：读角色
	  &quot;maxCon&quot;: 1000,
	  &quot;maxConnectTimeout&quot;: 30000,
	  &quot;maxRetryCount&quot;: 5,
	  &quot;minCon&quot;: 1,
	  &quot;name&quot;: &quot;slaveA&quot;,  // 数据源名称
	  &quot;password&quot;: &quot;Mycat@123&quot;,
	  &quot;type&quot;: &quot;JDBC&quot;,
	  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.63:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
	  &quot;user&quot;: &quot;mycat_user&quot;,
	  &quot;weight&quot;: 1  // 读负载权重（双从权重相同，均分读请求）
	}
	```

#### 2.4 从库2数据源：slaveB.datasource.json
	```json
	{
	  &quot;dbType&quot;: &quot;mysql&quot;,
	  &quot;idleTimeout&quot;: 60000,
	  &quot;initSqls&quot;: [],
	  &quot;initSqlsGetConnection&quot;: true,
	  &quot;instanceType&quot;: &quot;READ&quot;,  // 从库：读角色
	  &quot;maxCon&quot;: 1000,
	  &quot;maxConnectTimeout&quot;: 30000,
	  &quot;maxRetryCount&quot;: 5,
	  &quot;minCon&quot;: 1,
	  &quot;name&quot;: &quot;slaveB&quot;,  // 数据源名称
	  &quot;password&quot;: &quot;Mycat@123&quot;,
	  &quot;type&quot;: &quot;JDBC&quot;,
	  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.64:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true&amp;amp;allowMultiQueries=true&quot;,
	  &quot;user&quot;: &quot;mycat_user&quot;,
	  &quot;weight&quot;: 1  // 与从库1权重一致，实现读负载均衡
	}
	```

### 步骤3：配置 Mycat 集群（核心：双主双从读写策略）
在 `conf/clusters/` 目录下，创建集群配置文件 `dual_master_dual_slave.cluster.json`，定义主从关系、负载策略、故障切换规则。

	```json
	{
	  &quot;clusterType&quot;: &quot;MASTER_SLAVE&quot;,  // 集群类型：主从架构（支持双主）
	  &quot;heartbeat&quot;: {  // 心跳检测（监测节点存活）
	    &quot;heartbeatTimeout&quot;: 1000,
	    &quot;maxRetryCount&quot;: 3,
	    &quot;minSwitchTimeInterval&quot;: 300,  // 故障切换最小间隔（秒）
	    &quot;showLog&quot;: false,
	    &quot;slaveThreshold&quot;: 0.5  // 从库同步延迟阈值（秒），超过则剔除
	  },
	  &quot;masters&quot;: [&quot;masterA&quot;, &quot;masterB&quot;],  // 双主数据源名称（写请求路由到这里）
	  &quot;maxCon&quot;: 4000,  // 集群最大连接数（4个节点总和）
	  &quot;name&quot;: &quot;dual_master_dual_slave&quot;,  // 集群名称（后续关联逻辑库用）
	  &quot;readBalanceType&quot;: &quot;BALANCE_ALL_READ&quot;,  // 读负载策略：所有从库均分读请求
	  &quot;replicas&quot;: [&quot;slaveA&quot;, &quot;slaveB&quot;],  // 双从数据源名称（读请求路由到这里）
	  &quot;switchType&quot;: &quot;SWITCH&quot;,  // 故障切换策略：自动切换（主库故障时切换到备用主库）
	  &quot;writeBalanceType&quot;: &quot;BALANCE_ALL_WRITE&quot;  // 写负载策略：双主均分写请求（核心！双主特色）
	}
	```

### 步骤4：配置 Mycat 逻辑库（关联集群）
在 `conf/schemas/` 目录下，创建逻辑库配置文件（例如 `business.schema.json`），指定业务逻辑库与集群的关联。

	```json
	{
	  &quot;customTables&quot;: {},
	  &quot;globalTables&quot;: {},
	  &quot;normalProcedures&quot;: {},
	  &quot;normalTables&quot;: {},
	  &quot;schemaName&quot;: &quot;business&quot;,  // 逻辑库名称（应用连接 Mycat 时使用）
	  &quot;targetName&quot;: &quot;dual_master_dual_slave&quot;,  // 关联上面创建的集群名称
	  &quot;shardingTables&quot;: {},
	  &quot;views&quot;: {}
	}
	```

### 步骤5：配置 Mycat 访问用户（可选，若已配置可跳过）
在 `conf/users/` 目录下，创建用户配置文件 `mycat_user.user.json`，定义应用连接 Mycat 的账号密码。

	```json
	{
	  &quot;dialect&quot;: &quot;mysql&quot;,
	  &quot;ip&quot;: null,  // 允许所有IP访问（生产环境可指定IP）
	  &quot;password&quot;: &quot;Mycat@666&quot;,  // 应用连接 Mycat 的密码
	  &quot;transactionType&quot;: &quot;proxy&quot;,
	  &quot;username&quot;: &quot;mycat_app&quot;  // 应用连接 Mycat 的用户名
	}
	```

## 三、关键配置说明（双主双从核心亮点）
1. **双主写负载均衡**：通过 `writeBalanceType: &quot;BALANCE_ALL_WRITE&quot;` + 双主 `instanceType: &quot;WRITE&quot;`，写请求会均匀分发到两个主库，分摊写压力；
2. **双从读负载均衡**：通过 `readBalanceType: &quot;BALANCE_ALL_READ&quot;` + 双从 `instanceType: &quot;READ&quot;`，读请求均匀分发到两个从库，最大化读性能；
3. **故障自动切换**：
   - 主库故障（如 masterA 宕机）：Mycat 通过心跳检测发现后，自动将写请求切换到 masterB，业务无感知；
   - 从库故障（如 slaveA 宕机）：自动剔除故障从库，读请求仅分发到正常从库（slaveB），不影响业务；
4. **同步延迟过滤**：`slaveThreshold: 0.5` 表示从库同步延迟超过 0.5 秒时，Mycat 会暂时剔除该从库，避免读旧数据。

## 四、启动与验证
### 1. 启动 Mycat
	```bash
	# 重启 Mycat 加载配置
	/usr/local/mycat/bin/mycat restart
	
	# 查看启动状态（确保 8066 端口监听）
	netstat -tunlp | grep 8066
	```

### 2. 验证配置正确性
#### 2.1 连接 Mycat 逻辑库
	```bash
	mysql -h 192.168.90.58 -P 8066 -u mycat_app -pMycat@666
	```

#### 2.2 验证逻辑库与集群关联
	```sql
	-- 查看逻辑库
	show databases;
	-- 应输出：business（配置的逻辑库名称）
	
	-- 查看 Mycat 数据源状态（Mycat 2.x 专用命令）
	/*+ mycat:showDataSources{}*/ \G
	-- 应显示 4 个数据源（masterA、masterB、slaveA、slaveB），状态为 OK
	
	-- 查看集群状态
	/*+ mycat:showClusters{}*/ \G
	-- 应显示集群 dual_master_dual_slave，主从节点正常
	```

#### 2.3 验证读写分离效果
	```sql
	-- 1. 写操作（插入数据，会路由到双主之一）
	use business;
	create table test_user (id int primary key auto_increment, name varchar(20));
	insert into test_user (name) values (&quot;user1&quot;), (&quot;user2&quot;);
	
	-- 2. 查看双主数据（均应存在插入的数据，证明双主同步正常）
	-- 直接连接 masterA 查看
	mysql -h 192.168.90.61 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
	-- 直接连接 masterB 查看
	mysql -h 192.168.90.62 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
	
	-- 3. 查看双从数据（均应同步主库数据，证明主从同步正常）
	mysql -h 192.168.90.63 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
	mysql -h 192.168.90.64 -u mycat_user -pMycat@123 -e &quot;select * from business.test_user&quot;;
	
	-- 4. 读操作（通过 Mycat 查询，会路由到双从之一）
	-- 多次执行，观察 Mycat 日志（conf/logs/mycat.log），确认读请求分流到 slaveA/slaveB
	select * from test_user;
	```

## 五、注意事项
1. **双主复制前提**：必须确保双主互为主从配置正确（开启 GTID 模式最佳，避免同步冲突）；
2. **权限统一**：所有 MySQL 节点的 `mycat_user` 权限必须一致（至少拥有业务库的读写权限）；
3. **生产环境优化**：
   - 限制 Mycat 访问 IP（在用户配置文件中指定 `ip: &quot;192.168.90.0/24&quot;`）；
   - 调整 `maxCon`（连接数）、`idleTimeout`（空闲超时）适配业务压力；
   - 开启 Mycat 日志审计，便于排查问题；
4. **避免写冲突**：双主架构下，若同一表存在并发写，需确保表有主键（或唯一索引），避免同步报错。

## 总结
双主双从的 Mycat 配置核心是 **“数据源分角色（双主WRITE/双从READ）+ 集群配置写负载/读负载/故障切换”**，配置步骤与单主多从一致，仅需在集群中增加主库数据源、启用写负载策略即可。你的单主多从配置思路完全可复用，只需扩展数据源和调整集群参数，放心按此方案提交作业！
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;当 Mycat 服务启动失败，如何进行故障排查和解决，请给出详细的操作流程。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
### 一、检查启动状态与基础环境
1. **查看启动状态与错误提示**
    - 用`/usr/local/mycat/bin/mycat status`查看运行状态。
    - 手动启动并观察报错：`/usr/local/mycat/bin/mycat start 2&amp;gt;&amp;amp;1 | grep -E &quot;ERROR|Exception&quot;`。
    - 若提示“command not found”，用`find / -name &quot;mycat&quot; 2&amp;gt;/dev/null`找正确路径。
2. **验证 JDK 环境**
    - 检查版本：`java -version`。
    - 检查环境变量：`echo $JAVA_HOME`。
    - 未配置则临时配置：`export JAVA_HOME=/usr/lib/jvm/java - 1.8.0 - openjdk; export PATH=$PATH:$JAVA_HOME/bin`。
    - 永久配置：在`/etc/profile`添加配置并`source /etc/profile`。

### 二、查看核心日志
日志默认路径`/usr/local/mycat/conf/logs/`：
1. **主日志 mycat.log**：`tail -100 /usr/local/mycat/conf/logs/mycat.log | grep -E &quot;ERROR|WARN|Exception&quot;`。
2. **启动器日志 wrapper.log**：`tail -100 /usr/local/mycat/conf/logs/wrapper.log | grep -E &quot;ERROR|FATAL&quot;`。

### 三、排查配置文件错误
1. **检查语法**：用`jq`工具校验 JSON 格式配置文件。
2. **检查关键参数**：核对`datasources`、`clusters`、`schemas`、`users`配置文件参数。

### 四、排查端口占用问题
Mycat 默认用 8066 和 9066 端口：
1. 用`netstat -tunlp | grep`或`lsof -i:`检查端口占用。
2. 停止占用进程或修改`/usr/local/mycat/conf/mycat.properties`中的端口。

### 五、排查权限与目录访问问题
1. 检查目录权限，不足则`chmod -R 755 /usr/local/mycat/`。
2. 检查日志目录写入权限，可`chmod 777 /usr/local/mycat/conf/logs/`。
3. 检查运行用户，必要时修改目录所有者。

### 六、排查数据源连接问题
1. 测试网络连通性：`telnet`或`nc`。
2. 验证账号密码，检查账号存在性、权限和服务状态。
3. 检查防火墙/安全组，放行 3306 端口。

### 七、排查依赖与元数据问题（Mycat 2.x 特有）
1. 检查原型库配置文件。
2. 验证原型库连接。
3. 检查依赖 jar 包，缺失则手动下载。

### 八、极端情况：恢复默认配置，逐步测试
1. 备份当前配置。
2. 删除自定义配置。
3. 恢复默认原型库配置。
4. 启动 Mycat。
5. 逐步添加自定义配置并测试。
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# Mycat 服务启动失败：故障排查与解决完整操作流程
Mycat 启动失败的核心原因集中在 **环境依赖、配置错误、端口占用、权限不足、数据源连接异常** 五类，排查需遵循“从基础到深入、从日志到配置”的逻辑，逐步定位问题。以下是详细操作流程（基于 Mycat 2.x，兼容 1.x 核心思路）：


## 一、第一步：检查启动状态与基础环境（快速排除低级问题）
### 1. 查看 Mycat 启动状态与错误提示
首先通过官方命令查看启动状态，获取直接报错信息：
	```bash
	# 1. 查看 Mycat 运行状态（Mycat 2.x 命令）
	/usr/local/mycat/bin/mycat status
	
	# 2. 尝试手动启动，观察实时报错（关键！直接输出启动失败原因）
	/usr/local/mycat/bin/mycat start 2&amp;gt;&amp;amp;1 | grep -E &quot;ERROR|Exception&quot;
	
	# 3. 若提示“command not found”，确认 Mycat 安装路径正确
	find / -name &quot;mycat&quot; 2&amp;gt;/dev/null  # 找到正确路径（如 /opt/mycat），替换执行
	```
#### 常见状态与初步判断：
- 提示“not running”：服务未启动，需进一步查日志；
- 提示“Invalid JAVA_HOME”：JDK 环境未配置；
- 提示“Address already in use”：端口被占用；
- 提示“Could not load configuration”：配置文件错误。

### 2. 验证核心依赖：JDK 环境（Mycat 必需）
Mycat 依赖 JDK 1.8+（1.x 支持 1.7，2.x 强制 1.8+），先确认环境：
	```bash
	# 1. 检查 JDK 版本
	java -version
	# 正常输出示例：openjdk version &quot;1.8.0_382&quot;（需 1.8+，低于则报错）
	
	# 2. 检查 JAVA_HOME 环境变量
	echo $JAVA_HOME
	# 正常输出示例：/usr/lib/jvm/java-1.8.0-openjdk
	
	# 3. 若未配置 JAVA_HOME，手动配置（临时生效）
	export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk
	export PATH=$PATH:$JAVA_HOME/bin
	
	# 4. 永久配置（避免重启失效）
	echo &apos;export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk&apos; &amp;gt;&amp;gt; /etc/profile
	echo &apos;export PATH=$PATH:$JAVA_HOME/bin&apos; &amp;gt;&amp;gt; /etc/profile
	source /etc/profile
	```
#### 问题解决：
- 无 JDK：执行 `yum -y install java-1.8.0-openjdk.x86_64`（CentOS）安装；
- JDK 版本过低：卸载旧版本，重新安装 1.8+。


## 二、第二步：查看核心日志（定位问题关键）
Mycat 启动失败的详细原因会记录在日志中，优先查看以下 2 个核心日志文件（默认路径：`/usr/local/mycat/conf/logs/`）：

### 1. 主日志：mycat.log（记录配置加载、数据源连接、启动流程错误）
	```bash
	# 查看日志最后 100 行（聚焦最新错误）
	tail -100 /usr/local/mycat/conf/logs/mycat.log | grep -E &quot;ERROR|WARN|Exception&quot;
	
	# 若日志过大，搜索关键词定位
	grep -n &quot;Failed to&quot; /usr/local/mycat/conf/logs/mycat.log  # 搜索失败相关记录
	```

### 2. 启动器日志：wrapper.log（记录 JVM 启动、进程启动失败原因）
	```bash
	tail -100 /usr/local/mycat/conf/logs/wrapper.log | grep -E &quot;ERROR|FATAL&quot;
	```

#### 日志常见错误与对应解决：
| 日志错误关键词                | 问题原因                          | 快速解决                          |
|-----------------------------|-----------------------------------|-----------------------------------|
| Invalid JSON syntax         | 配置文件（.json）语法错误          | 检查对应 JSON 文件的逗号、引号闭合 |
| Could not connect to datasource | 数据源（MySQL）连接失败           | 验证 MySQL 地址、账号密码、网络连通性 |
| Address already in use: 8066 | 8066/9066 端口被占用              | 查找并停止占用进程，或修改 Mycat 端口 |
| Permission denied           | Mycat 目录/文件权限不足            | 赋予读写权限：chmod -R 755 /usr/local/mycat |
| Missing jar包名              | 依赖 jar 包缺失                    | 从安装包复制缺失 jar 到 lib 目录  |


## 三、第三步：排查配置文件错误（最常见原因）
Mycat 启动时会加载 `datasources`（数据源）、`clusters`（集群）、`schemas`（逻辑库）、`users`（用户）四类核心配置文件，JSON 语法错误、参数配置错误是主要诱因。

### 1. 检查配置文件语法（JSON 格式必须严格）
Mycat 2.x 配置文件均为 JSON 格式，逗号、引号、大括号不闭合会直接导致启动失败，用 `jq` 工具验证：
	```bash
	# 1. 安装 jq 工具（JSON 语法校验）
	yum -y install jq
	
	# 2. 逐个校验核心配置文件（以 datasources 为例）
	# 校验数据源配置（所有 .datasource.json 文件）
	for file in /usr/local/mycat/conf/datasources/*.json; do
	  echo &quot;校验文件：$file&quot;
	  jq . $file  # 语法错误会直接提示行号
	done
	
	# 3. 同理校验集群、逻辑库、用户配置
	for file in /usr/local/mycat/conf/clusters/*.json; do jq . $file; done
	for file in /usr/local/mycat/conf/schemas/*.json; do jq . $file; done
	for file in /usr/local/mycat/conf/users/*.json; do jq . $file; done
	```
#### 语法错误示例与修复：
- 错误：`{&quot;name&quot;:&quot;masterA&quot;, &quot;password&quot;:&quot;123&quot;}`（末尾多逗号）
- 修复：`{&quot;name&quot;:&quot;masterA&quot;, &quot;password&quot;:&quot;123&quot;}`（删除末尾逗号）

### 2. 检查关键配置参数（参数错误导致启动失败）
重点核对以下核心参数（配置文件中最易出错）：
#### 2.1 数据源配置（datasources/*.json）
	```json
	{
	  &quot;url&quot;: &quot;jdbc:mysql://192.168.90.61:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&quot;,  // 确保 IP、端口正确
	  &quot;user&quot;: &quot;mycat_user&quot;,  // MySQL 账号存在且有权限
	  &quot;password&quot;: &quot;Mycat@123&quot;,  // 密码正确
	  &quot;instanceType&quot;: &quot;WRITE&quot;,  // 取值只能是 WRITE/READ/READ_WRITE（大小写敏感）
	  &quot;dbType&quot;: &quot;mysql&quot;  // 不能写错（如写成 &quot;mysql8&quot; 无效）
	}
	```

#### 2.2 集群配置（clusters/*.json）
	```json
	{
	  &quot;name&quot;: &quot;dual_master_dual_slave&quot;,
	  &quot;masters&quot;: [&quot;masterA&quot;, &quot;masterB&quot;],  // 数据源名称必须与 datasources 中一致
	  &quot;replicas&quot;: [&quot;slaveA&quot;, &quot;slaveB&quot;],  // 同上，不能拼写错误
	  &quot;clusterType&quot;: &quot;MASTER_SLAVE&quot;,  // 取值只能是 MASTER_SLAVE/SINGLE/CLUSTER
	  &quot;writeBalanceType&quot;: &quot;BALANCE_ALL_WRITE&quot;  // 取值符合 Mycat 规则
	}
	```

#### 2.3 逻辑库配置（schemas/*.json）
	```json
	{
	  &quot;schemaName&quot;: &quot;business&quot;,
	  &quot;targetName&quot;: &quot;dual_master_dual_slave&quot;  // 集群名称必须与 clusters 中一致
	}
	```

#### 2.4 用户配置（users/*.json）
	```json
	{
	  &quot;username&quot;: &quot;mycat_app&quot;,
	  &quot;password&quot;: &quot;Mycat@666&quot;,  // 不能包含特殊字符（如 @ 需转义，或直接用简单密码测试）
	  &quot;dialect&quot;: &quot;mysql&quot;  // 不能写错
	}
	```


## 四、第四步：排查端口占用问题
Mycat 默认占用 2 个端口：
- 8066：业务端口（应用连接 Mycat 用）
- 9066：管理端口（Mycat 管理命令用）
端口被占用会直接导致启动失败，排查流程：
	```bash
	# 1. 检查 8066 端口占用情况
	netstat -tunlp | grep 8066
	# 或用 lsof（更详细）
	lsof -i:8066
	
	# 2. 检查 9066 端口占用情况
	netstat -tunlp | grep 9066
	
	# 3. 若有占用进程，停止该进程（示例：PID 为 1234）
	kill -9 1234
	
	# 4. 若无法停止占用进程，修改 Mycat 端口（Mycat 2.x 配置）
	vi /usr/local/mycat/conf/mycat.properties
	# 修改以下参数（自定义未占用端口）
	server.port=8067  # 新业务端口
	manager.port=9067  # 新管理端口
	
	# 5. 重启 Mycat 测试
	/usr/local/mycat/bin/mycat restart
	```


## 五、第五步：排查权限与目录访问问题
Mycat 启动时需要读取配置文件、写入日志，权限不足会导致“Permission denied”错误：
	```bash
	# 1. 检查 Mycat 安装目录权限
	ls -ld /usr/local/mycat/
	# 正常权限：drwxr-xr-x（所有者、组有读写执行权限）
	
	# 2. 赋予完整权限（临时测试，生产环境可收紧）
	chmod -R 755 /usr/local/mycat/
	
	# 3. 检查日志目录写入权限（关键！日志写不进去会启动失败）
	ls -ld /usr/local/mycat/conf/logs/
	chmod 777 /usr/local/mycat/conf/logs/  # 临时赋予最大权限测试
	
	# 4. 检查运行用户（若用非 root 用户启动，需确保用户有目录权限）
	ps -ef | grep mycat  # 查看运行用户
	chown -R mycat:mycat /usr/local/mycat/  # 若用 mycat 用户，修改目录所有者
	```


## 六、第六步：排查数据源连接问题
若数据源（MySQL 主从节点）配置错误或无法连通，Mycat 启动时会因“连接数据源失败”报错：
	```bash
	# 1. 手动测试 Mycat 到 MySQL 数据源的网络连通性（以 masterA 为例）
	telnet 192.168.90.61 3306
	# 或用 nc 命令
	nc -zv 192.168.90.61 3306
	# 正常输出：succeeded!（失败则检查防火墙/安全组）
	
	# 2. 手动验证 MySQL 账号密码正确性（用 Mycat 配置的账号）
	mysql -h 192.168.90.61 -u mycat_user -pMycat@123
	# 若登录失败，检查：
	# - MySQL 账号是否存在：SELECT user, host FROM mysql.user WHERE user=&apos;mycat_user&apos;;
	# - 账号权限是否足够：GRANT ALL ON *.* TO &apos;mycat_user&apos;@&apos;%&apos; IDENTIFIED WITH mysql_native_password BY &apos;Mycat@123&apos;;
	# - MySQL 服务是否正常：systemctl status mysqld
	
	# 3. 检查 MySQL 防火墙/安全组（放行 3306 端口）
	firewall-cmd --zone=public --add-port=3306/tcp --permanent
	firewall-cmd --reload
	```


## 七、第七步：排查依赖与元数据问题（Mycat 2.x 特有）
Mycat 2.x 依赖“原型库（prototypeDs）”存储元数据，原型库配置错误会导致启动失败：
	```bash
	# 1. 检查原型库配置文件
	cat /usr/local/mycat/conf/datasources/prototypeDs.datasource.json
	# 核心要求：原型库必须是可连接的 MySQL 实例（可复用主库/独立库）
	
	# 2. 验证原型库连接
	mysql -h 192.168.90.61 -u mycat_user -pMycat@123  # 原型库配置的账号密码
	
	# 3. 检查依赖 jar 包（缺失会导致类加载失败）
	ls /usr/local/mycat/lib/ | grep -E &quot;mycat2|mysql-connector-java&quot;
	# 若缺失 mysql-connector-java（MySQL 驱动），手动下载放入 lib 目录
	wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.33/mysql-connector-java-8.0.33.jar -P /usr/local/mycat/lib/
	```


## 八、第八步：极端情况：恢复默认配置，逐步测试
若以上排查均无效，可能是配置文件错乱，可通过“恢复默认+逐步添加配置”定位问题：
	```bash
	# 1. 备份当前配置（避免丢失）
	cp -r /usr/local/mycat/conf /usr/local/mycat/conf_bak_$(date +%Y%m%d)
	
	# 2. 删除自定义配置（保留默认原型库和用户配置）
	rm -rf /usr/local/mycat/conf/datasources/*.json
	rm -rf /usr/local/mycat/conf/clusters/*.json
	rm -rf /usr/local/mycat/conf/schemas/*.json
	
	# 3. 恢复默认原型库配置（从安装包复制，或手动创建）
	cat &amp;gt; /usr/local/mycat/conf/datasources/prototypeDs.datasource.json &amp;lt;&amp;lt; EOF
	{
	  &quot;dbType&quot;:&quot;mysql&quot;,
	  &quot;idleTimeout&quot;:60000,
	  &quot;initSqls&quot;:[],
	  &quot;initSqlsGetConnection&quot;:true,
	  &quot;instanceType&quot;:&quot;READ_WRITE&quot;,
	  &quot;maxCon&quot;:1000,
	  &quot;maxConnectTimeout&quot;:3000,
	  &quot;maxRetryCount&quot;:5,
	  &quot;minCon&quot;:1,
	  &quot;name&quot;:&quot;prototypeDs&quot;,
	  &quot;password&quot;:&quot;Mycat@123&quot;,
	  &quot;type&quot;:&quot;JDBC&quot;,
	  &quot;url&quot;:&quot;jdbc:mysql://192.168.90.61:3306/mysql?serverTimezone=Asia/Shanghai&quot;,
	  &quot;user&quot;:&quot;mycat_user&quot;,
	  &quot;weight&quot;:0
	}
	EOF
	
	# 4. 启动 Mycat（若能启动，说明默认配置正常，问题在自定义配置）
	/usr/local/mycat/bin/mycat start
	
	# 5. 逐步添加自定义配置（每次添加一个文件，重启测试）
	# 先添加一个数据源 → 启动测试
	# 再添加集群 → 启动测试
	# 最后添加逻辑库 → 启动测试
	# 定位到导致失败的具体配置文件，针对性修改
	```


## 九、常见故障案例与快速解决
| 故障现象                          | 排查流程                          | 解决方法                          |
|-----------------------------------|-----------------------------------|-----------------------------------|
| 执行 mycat start 无反应，日志无输出 | 1. 检查 JAVA_HOME；2. 检查 wrapper.log | 配置 JAVA_HOME，或重新安装 Mycat 启动器 |
| 启动提示“数据源连接失败”           | 1. telnet 测试 MySQL 端口；2. 验证账号密码 | 放行 3306 端口，重新创建 MySQL 账号并授权 |
| JSON 语法错误导致启动失败          | 用 jq 工具校验所有配置文件         | 修复逗号、引号、大括号闭合问题    |
| 8066 端口被占用                    | netstat 查找占用进程               | 停止占用进程，或修改 Mycat 端口   |
| 权限不足“Permission denied”        | 检查 Mycat 目录权限               | chmod -R 755 /usr/local/mycat     |


## 十、排查总结（核心逻辑）
Mycat 启动失败排查遵循“**先基础（环境、端口、权限）→ 再日志（定位方向）→ 最后配置（精准修复）** ”的逻辑，90% 的问题集中在：
1. JDK 环境未配置或版本过低；
2. 配置文件（JSON）语法错误；
3. 数据源（MySQL）连接失败（IP/端口/账号/防火墙）；
4. 8066/9066 端口被占用；
5. Mycat 目录权限不足。

按以上流程逐步排查，均可定位并解决问题。若仍失败，可提供 `mycat.log` 和 `wrapper.log` 中的错误关键词，进一步精准分析。
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;11：mysql之分库分表&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250617154629207.webp&quot; alt=&quot;image-20250617154629207&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;某电商公司业务飞速发展，其订单数据库数据量急剧增长，查询和写入性能显著下降。数据库管理员经过分析，决定采用分库分表策略。首先，依据业务模块将订单数据库拆分为用户订单库、商品订单库等多个数据库。然后，在每个库内对订单表按照订单创建时间进行分表，例如每个月的数据存于一个独立表。分库分表完成后，开发人员对应用程序的数据库连接和查询语句进行相应修改。经过测试和优化，系统的查询和写入性能大幅提升，满足了业务持续发展的需求。&lt;/p&gt;
&lt;h2&gt;二、为什么学&lt;/h2&gt;
&lt;p&gt;学习 MySQL 分库分表具有重要的现实意义。在当今数字化时代，各行业数据量呈爆炸式增长，企业应用的数据存储和处理面临巨大挑战。当单一数据库无法承受数据压力时，分库分表能有效提升数据库的性能和可扩展性。&lt;/p&gt;
&lt;p&gt;掌握分库分表技术，能让你在处理海量数据时更加游刃有余，提高系统响应速度和稳定性。对于求职者而言，这是一项极具竞争力的技能，可增加进入大厂的机会。同时，深入理解该技术，能让你对数据库架构设计有更深刻的认识，为日后的技术进阶打下坚实基础。&lt;/p&gt;
&lt;h2&gt;三、环境准备&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250617154653018.webp&quot; alt=&quot;image-20250617154653018&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3.1 机器准备&lt;/h3&gt;
&lt;p&gt;克隆5台机器&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;mycat63&lt;/td&gt;
&lt;td&gt;192.168.90.63&lt;/td&gt;
&lt;td&gt;分库策略&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mysql59&lt;/td&gt;
&lt;td&gt;192.168.90.59&lt;/td&gt;
&lt;td&gt;master【马斯特】服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mysql60&lt;/td&gt;
&lt;td&gt;192.168.90.60&lt;/td&gt;
&lt;td&gt;slave【斯累夫】服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mysql61&lt;/td&gt;
&lt;td&gt;192.168.90.61&lt;/td&gt;
&lt;td&gt;master【马斯特】服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mysql62&lt;/td&gt;
&lt;td&gt;192.168.90.62&lt;/td&gt;
&lt;td&gt;slave【斯累夫】服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;mycat63配置IP地址和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.63/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mycat63 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mycat63
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mysql59配置IP地址和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.59/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mysql59 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql59
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mysql60配置IP地址和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.6/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mysql60 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql60
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mysql61配置IP地址和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.61/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mysql61 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql61
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mysql62配置IP地址和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.62/24 autoconnect【奥特欧 坑聂特】 yes
[root@localhost ~]# nmcli connection【肯耐申】 up ens160
[root@mysql62 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql62
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 mycat【麦-凯特】分库分表原理&lt;/h3&gt;
&lt;p&gt;Mycat【麦-凯特】是用于MySQL分库分表的数据库中间件，能实现数据库水平扩展。其原理核心在于拦截并分析SQL语句。它位于应用层和数据库间，接收应用请求后，先由SQL解析引擎解析SQL，判断是否需分库分表；再通过路由层依据分片规则和算法，决定将SQL发往哪个分片。例如按user_id取模拆分数据，Mycat【麦-凯特】解析查询语句后，会自动路由到对应数据库查询。最终，后端连接池管理数据库连接，处理结果后返回给用户，以此提升性能和可扩展性 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;think&amp;gt;&amp;lt;/think&amp;gt;Mycat 的分库分表原理可以简单理解为：**通过中间件层对数据进行逻辑拆分，并按照规则路由到不同的物理数据库/表，从而实现对大规模数据的分布式存储和访问**。具体可以从以下几个核心层面来拆解：


### 1. **数据的逻辑拆分：从“一张大表”到“多张小表”**
Mycat 首先将业务中的“大表”（比如千万级以上的订单表、用户表）在逻辑上拆分成多个“小表”，同时将存储这些小表的数据库也拆分成多个“分库”。  
- **逻辑表**：拆分前的大表在 Mycat 中被抽象为“逻辑表”（比如 `order` 表），客户端访问时只需要操作这个逻辑表，无需关心底层物理拆分。  
- **物理表**：逻辑表被拆分成的实际小表（比如 `order_001`、`order_002`），分布在不同的分库中。  
- **数据节点（DataNode）**：每个分库或分表所在的物理存储位置（通常对应某个 MySQL 实例的具体数据库），比如 `dn1` 对应 `db1` 库，`dn2` 对应 `db2` 库。  


### 2. **分片规则：决定数据“去哪存、去哪查”**
核心问题是“如何拆分”，Mycat 通过**分片规则**（Sharding Rule）来决定每条数据应该存到哪个分库或分表，以及查询时应该从哪个分库/分表获取数据。常见规则包括：  
- **范围分片**：按字段范围拆分（如订单表按时间：2023年数据存 `dn1`，2024年存 `dn2`）。  
- **哈希分片**：对字段（如用户 ID）做哈希计算，结果映射到不同分库（如 `user_id % 4` 决定存到 `dn0`~`dn3`）。  
- **枚举分片**：按固定值拆分（如按地区：北京用户存 `dn1`，上海用户存 `dn2`）。  
- **复合分片**：结合多种规则（如先按时间范围分库，再按用户 ID 哈希分表）。  

这些规则配置在 Mycat 的 `schema.xml` 或分片规则文件中，Mycat 会根据规则自动路由数据。


### 3. **中间件的路由与整合：对客户端“透明”**
Mycat 作为中间件，扮演“代理”角色，屏蔽了底层分库分表的复杂性，客户端（如应用程序）只需像访问单库单表一样操作 Mycat：  
- **SQL 解析**：客户端发送 SQL 到 Mycat（如 `select * from order where user_id=100`），Mycat 先解析 SQL，识别涉及的逻辑表、过滤条件（如 `user_id`）。  
- **规则匹配与路由**：根据解析结果和分片规则，计算数据所在的物理分库/分表（比如通过哈希规则确定 `user_id=100` 对应 `dn2` 库的 `order_002` 表）。  
- **转发执行**：Mycat 将 SQL 改写为针对物理表的语句（如 `select * from db2.order_002 where user_id=100`），转发到对应的 MySQL 实例执行。  
- **结果整合**：如果查询涉及多个分库/分表（如 `select count(*) from order`），Mycat 会并行查询所有相关节点，汇总结果后返回给客户端，让客户端感觉数据来自“一个库”。  


### 4. **与底层数据库的交互：连接池与事务协调**
- **连接池管理**：Mycat 维护与各分库的连接池，避免频繁创建/关闭连接，提高性能。  
- **事务支持**：对于跨分库的分布式事务，Mycat 可通过 XA 协议或本地消息表等方式协调，保证事务的一致性（如跨库转账时，要么都成功，要么都回滚）。  


### 总结
Mycat 分库分表的核心是“**逻辑抽象 + 规则路由 + 中间件代理**”：通过拆分大表减轻单库压力，通过规则明确数据位置，通过中间件屏蔽底层复杂性，让应用无需改动代码即可访问分布式数据。这也是它在高并发、大数据场景中常用的原因~
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250617135010626.webp&quot; alt=&quot;image-20250617135010626&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;四、配置二主二从&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250617154724356.webp&quot; alt=&quot;image-20250617154724356&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;4.1 把MySQL60配置为MySQL59的从服务器&lt;/h3&gt;
&lt;p&gt;1）配置主服务器MySQL59&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 启用binlog日志
[root@mysql59 ~]# yum –y  install【因-斯多】 mysql-server  mysql
# [root@mysql59 ~]# yum -y install ./rpm/*
[root@mysql59 ~]# systemctl【西斯屯-ctl】 start【s 达儿】 mysqld
# [root@mysql59 ~]# systemctl enable mysqld --now
[root@mysql59 ~]# vim /etc/my.cnf.d/mysql-server.cnf
# [root@mysql59 ~]# grep -vE &quot;^\s*(#|$)&quot; /etc/my.cnf
# [mysqld]
# server-id=59       # 增加这两项
# log-bin=mysql59    # 增加这两项
# datadir=/var/lib/mysql
# socket=/var/lib/mysql/mysql.sock
# log-error=/var/log/mysqld.log
# pid-file=/var/run/mysqld/mysqld.pid

[root@mysql59 ~]# systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld
# [root@mysql59 ~]# systemctl restart mysqld

# 用户授权
[root@mysql59 ~]# mysql

# 创建用户
mysql&amp;gt; create【克瑞特】 user repluser@&quot;%&quot; identified【爱-丹-提伐】 by【拜】 &quot;123qqq...A&quot;; 
# mysql&amp;gt; create user repluser@&quot;%&quot; identified by &quot;123qqq...A&quot;; 
# Query OK, 0 rows affected (0.03 sec)

# 授予权限
mysql&amp;gt; grant【古亮普】 replication【瑞普利K申】 slave【斯累夫】 on【昂】 *.*  to repluser@&quot;%&quot;; 
# mysql&amp;gt; grant replication slave on *.* to repluser@&quot;%&quot;;
# Query OK, 0 rows affected (0.02 sec)

# 查看日志信息
mysql&amp;gt; show【瘦】 master【马斯特】 status【 斯dèi 特斯】;
# mysql&amp;gt; show master status;
# +----------------+----------+--------------+------------------+-------------------+
# | File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
# +----------------+----------+--------------+------------------+-------------------+
# | mysql59.000002 |     6760 |              |                  |                   |
# +----------------+----------+--------------+------------------+-------------------+
# 1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）配置slave【斯累夫】服务器MySQL60&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 指定server-id 并重启数据库服务
[root@mysql60 ~]# yum –y  install【因-斯多】 mysql-serv    er  mysql
[root@mysql60 ~]# systemctl【西斯屯-ctl】 start【s 达儿】 mysqld
[root@mysql60 ~]# vim /etc/my.cnf.d/mysql-server.cnf
# [root@mysql60 ~]# grep -vE &quot;^\s*(#|$)&quot; /etc/my.cnf
# [mysqld]
# server-id=60       # 增加这项
# datadir=/var/lib/mysql
# socket=/var/lib/mysql/mysql.sock
# log-error=/var/log/mysqld.log
# pid-file=/var/run/mysqld/mysqld.pid

[root@mysql60 ~]# systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld
# [root@mysql60 ~]# systemctl restart mysqld

# 登陆服务指定主服务器信息
[root@mysql60 ~]# mysql

mysql&amp;gt; change【趁(chèn)吉】 master【马斯特】 to  master【马斯特】_host=&quot;192.168.90.59&quot; , master【马斯特】_user=&quot;repluser&quot; , master【马斯特】_password=&quot;123qqq...A&quot; ,master【马斯特】_log_file=&quot;mysql59.000001&quot; , master【马斯特】_log_pos=667;
mysql&amp;gt; change master to # master_host=&quot;192.168.88.59&quot;,master_user=&quot;repluser&quot;,master_password=&quot;123qqq...A&quot;,master_log_file=&quot;mysql59.000002&quot;,master_log_pos=6760;
# Query OK, 0 rows affected, 8 warnings (0.13 sec)


# 启动slave【斯累夫】进程
mysql&amp;gt; start【s 达儿】 slave【斯累夫】 ; 
# mysql&amp;gt; start slave;
# Query OK, 0 rows affected, 1 warning (0.07 sec)

# 查看状态信息
mysql&amp;gt; show【瘦】 slave【斯累夫】 status【 斯dèi 特斯】 \G  
# [root@mysql60 ~]# mysql -uroot -p123 -e &quot;show slave status \G&quot; | grep -E &quot;Slave_IO_Running|Slave_SQL_Running&quot;
# mysql: [Warning] Using a password on the command line interface can be insecure.
#              Slave_IO_Running: Yes  # 这两个线程连接为YES表示同步设置成功
#             Slave_SQL_Running: Yes  # 这两个线程连接为YES表示同步设置成功
#       Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 把MySQL62配置为MySQL61的从服务器&lt;/h3&gt;
&lt;p&gt;1）配置主服务器MySQL61&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#  启用binlog日志
[root@mysql61 ~]# yum –y  install【因-斯多】 mysql-server  mysql
[root@mysql61 ~]# systemctl【西斯屯-ctl】 start【s 达儿】 mysqld
[root@mysql61 ~]# vim /etc/my.cnf.d/mysql-server.cnf
[root@mysql61 ~]# grep -vE &quot;^\s*(#|$)&quot; /etc/my.cnf
# [mysqld]
# server-id=61       # 增加这两项
# log-bin=mysql61    # 增加这两项
# datadir=/var/lib/mysql
# socket=/var/lib/mysql/mysql.sock
# log-error=/var/log/mysqld.log
# pid-file=/var/run/mysqld/mysqld.pid

[root@mysql61 ~]# systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld
# [root@mysql61 ~]# systemctl restart mysqld

# 用户授权
[root@mysql61 ~]# mysql

# 创建用户
mysql&amp;gt; create【克瑞特】 user repluser@&quot;%&quot; identified【爱-丹-提伐】 by【拜】 &quot;123qqq...A&quot;; 
# mysql&amp;gt; create user repluser@&quot;%&quot; identified by &quot;123qqq...A&quot;;
# Query OK, 0 rows affected (0.02 sec)

# 授予权限
mysql&amp;gt; grant【古亮普】 replication【瑞普利K申】 slave【斯累夫】 on【昂】 *.*  to repluser@&quot;%&quot;; 
# mysql&amp;gt; grant replication slave on *.* to repluser@&quot;%&quot;;
# Query OK, 0 rows affected (0.03 sec)

# 查看日志信息
mysql&amp;gt; show【瘦】 master【马斯特】 status【 斯dèi 特斯】;
# mysql&amp;gt; show master status;
# +----------------+----------+--------------+------------------+-------------------+
# | File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
# +----------------+----------+--------------+------------------+-------------------+
# | mysql61.000001 |      697 |              |                  |                   |
# +----------------+----------+--------------+------------------+-------------------+
# 1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）配置slave【斯累夫】服务器MySQL62&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 指定server-id 并重启数据库服务
[root@mysql62 ~]# yum –y  install【因-斯多】 mysql-server  mysql
[root@mysql62 ~]# systemctl【西斯屯-ctl】 start【s 达儿】 mysqld
[root@mysql62 ~]# vim /etc/my.cnf.d/mysql-server.cnf
# [root@mysql62 ~]# grep -vE &quot;^\s*(#|$)&quot; /etc/my.cnf
# [mysqld]
# server-id=62
# datadir=/var/lib/mysql
# socket=/var/lib/mysql/mysql.sock
# log-error=/var/log/mysqld.log
# pid-file=/var/run/mysqld/mysqld.pid

[root@mysql62 ~]# systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld
# [root@mysql62 ~]# systemctl restart mysqld

# 登陆服务指定主服务器信息
[root@mysql62 ~]# mysql

mysql&amp;gt; change【趁(chèn)吉】 master【马斯特】 to  master【马斯特】_host=&quot;192.168.90.61&quot; , master【马斯特】_user=&quot;repluser&quot; , master【马斯特】_password=&quot;123qqq...A&quot; ,master【马斯特】_log_file=&quot;mysql61.000001&quot; , master【马斯特】_log_pos=667;
# mysql&amp;gt; change master to master_host=&quot;192.168.88.61&quot;,master_user=&quot;repluser&quot;,master_password=&quot;123qqq...A&quot;,master_log_file=&quot;mysql61.000001&quot;,master_log_pos=697;
# Query OK, 0 rows affected, 8 warnings (0.11 sec)

# 启动slave【斯累夫】进程
mysql&amp;gt; start【s 达儿】 slave【斯累夫】 ; 
# mysql&amp;gt; start slave;
# Query OK, 0 rows affected, 1 warning (0.10 sec)

# 查看状态信息
mysql&amp;gt; show【瘦】 slave【斯累夫】 status【 斯dèi 特斯】 \G  
# [root@mysql62 ~]# mysql -uroot -p123 -e &quot;show slave status \G&quot; | grep -E &quot;Slave_IO_Running|Slave_SQL_Running&quot;
#              Slave_IO_Running: Yes        # IO线程
#             Slave_SQL_Running: Yes        # SQL线程
# .........
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、配置为mycat【麦-凯特】服务器&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250617154747875.webp&quot; alt=&quot;image-20250617154747875&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;5.1 mycat【麦-凯特】安装部署&lt;/h3&gt;
&lt;p&gt;1)拷贝软件到mycat63主机&lt;/p&gt;
&lt;p&gt;mycat2-1.21-release-jar-with-dependencies.jar&lt;/p&gt;
&lt;p&gt;mycat2**-&lt;strong&gt;install&lt;/strong&gt;-**template-1.21.zip&lt;/p&gt;
&lt;p&gt;2)安装mycat【麦-凯特】软件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 安装jdk
[root@mycat63 ~]# yum -y install【因-斯多】 java-1.8.0-openjdk.x86_64
# [root@mycat63 ~]# yum -y install java-1.8.0-openjdk.x86_64

# 安装mycat
[root@mycat63 ~]# which unzip || yum -y  install【因-斯多】 unzip
# [root@mycat63 ~]# which unzip || yum -y install unzip

[root@mycat63 ~]# unzip mycat2-install-template-1.21.zip           
# [root@mycat63 ~]# unzip mycat2-install-template-1.21.zip 

[root@mycat63 ~]# mv mycat /usr/local/
# [root@mycat63 ~]# mv mycat /usr/local/

# 安装依赖
[root@mycat63 ~]# cp mycat2-1.21-release-jar-with-dependencies.jar  /usr/local/mycat/lib/
# [root@mycat63 ~]# mv mycat2-1.21-release-jar-with-dependencies.jar /usr/local/mycat/lib/

# 修改权限
[root@mycat63 ~]# chmod -R 777 /usr/local/mycat/ 
# [root@mycat63 ~]# chmod -R 777 /usr/local/mycat/ 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 配置mycat【麦-凯特】登录账号密码&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat63 ~]# vim  /usr/local/mycat/conf/users/root.user.json
{
        &quot;dialect&quot;:&quot;mysql&quot;,
        &quot;ip&quot;:null,
        &quot;password&quot;:&quot;654321&quot;,
        &quot;transactionType&quot;:&quot;proxy&quot;,
        &quot;username&quot;:&quot;mycat&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.3 配置mycat【麦-凯特】连接本机数据库&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat63 ~]# vim /usr/local/mycat/conf/datasources/prototypeDs.datasource.json
{
        &quot;dbType&quot;:&quot;mysql&quot;,
        &quot;idleTimeout&quot;:60000,
        &quot;initSqls&quot;:[],
        &quot;initSqlsGetConnection&quot;:true,
        &quot;instanceType&quot;:&quot;READ_WRITE&quot;,
        &quot;maxCon&quot;:1000,
        &quot;maxConnectTimeout&quot;:3000,
        &quot;maxRetryCount&quot;:5,
        &quot;minCon&quot;:1,
        &quot;name&quot;:&quot;prototypeDs&quot;,
        &quot;password&quot;:&quot;123456&quot;, 密码
        &quot;type&quot;:&quot;JDBC&quot;,
        &quot;url&quot;:&quot;jdbc:mysql://localhost:3306/mysql?useUnicode=true&amp;amp;serverTimezone=Asia/Shanghai&amp;amp;characterEncoding=UTF-8&quot;, 连接本机的数据库服务
        &quot;user&quot;:&quot;jam&quot;, 用户名
        &quot;weight&quot;:0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.4 安装mysql数据库配置账号&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat63 ~]# yum -y  install【因-斯多】  mysql-server  mysql
[root@mycat63 ~]# systemctl【西斯屯-ctl】 start【s 达儿】 mysqld

# 创建jam用户
[root@mycat63 ~]# mysql

# 创建用户
mysql&amp;gt; create【克瑞特】 user jam@&quot;%&quot; identified【爱-丹-提伐】 by【拜】 &quot;123456&quot;; 
# mysql&amp;gt; create user jam@&quot;%&quot; identified by &quot;123456&quot;;
# Query OK, 0 rows affected (0.02 sec)

# 授予权限
mysql&amp;gt; grant【古亮普】 all on【昂】 *.* to jam@&quot;%&quot; ; 
# mysql&amp;gt; grant all on *.* to jam@&quot;%&quot;;
# Query OK, 0 rows affected (0.17 sec)

mysql&amp;gt; exit
Bye
[root@mycat63 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、mycat【麦-凯特】配置数据源&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250617154816238.webp&quot; alt=&quot;image-20250617154816238&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;6.1 启动mycat【麦-凯特】服务&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat63 ~]# /usr/local/mycat/bin/mycat help
Usage: /usr/local/mycat/bin/mycat { console | start | stop | restart | status | dump }

[root@mycat63 ~]# /usr/local/mycat/bin/mycat start【s 达儿】
Starting mycat2...

# 半分钟左右 能看到端口
[root@mycat63 ~]# netstat  -utnlp  | grep 8066
tcp6       0      0 :::8066  :::*       LISTEN      57015/java          
[root@mycat63 ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.2 连接mycat【麦-凯特】服务器&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat63 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321

mysql&amp;gt; show【瘦】 databases;
# mysql&amp;gt; show databases;
# +--------------------+
# | `Database`         |
# +--------------------+
# | information_schema |
# | mysql              |
# | performance_schema |
# +--------------------+
# 3 rows in set (0.20 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.3 添加数据源&lt;/h3&gt;
&lt;p&gt;1）连接本机的mycat【麦-凯特】服务，添加数据源&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat63 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321

# 添加MySQL59
MySQL&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;dw0&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.90.59:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;dw0&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.59:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# Query OK, 0 rows affected (0.02 sec)

# 添加MySQL60
Mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;dr0&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.90.60:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;dr0&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.60:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# Query OK, 0 rows affected (0.01 sec)

# 添加MySQL61
Mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;dw1&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.90.61:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;dw1&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.61:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# Query OK, 0 rows affected (0.01 sec)

# 添加MySQL62
Mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;dr1&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.90.62:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;dr1&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.62:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
# Query OK, 0 rows affected (0.01 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）查看存放目录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat63 ~]# ls /usr/local/mycat/conf/datasources/
dr0.datasource.json  dr1.datasource.json  dw0.datasource.json  dw1.datasource.json  prototypeDs.datasource.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3）查看数据信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; /*+mycat:showDataSources{}*/ \G
*************************** 1. row ***************************
                   NAME: dw0
               USERNAME: jam
               PASSWORD: 123456
                MAX_CON: 1000
                MIN_CON: 1
              EXIST_CON: 0
                USE_CON: 0
        MAX_RETRY_COUNT: 5
    MAX_CONNECT_TIMEOUT: 30000
                DB_TYPE: mysql
                    URL: jdbc:mysql://192.168.90.59:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
                 WEIGHT: 0
               INIT_SQL: 
INIT_SQL_GET_CONNECTION: true
          INSTANCE_TYPE: READ_WRITE
           IDLE_TIMEOUT: 60000
                 DRIVER: {
        CreateTime:&quot;2025-05-08 16:10:26&quot;,
        ActiveCount:0,
        PoolingCount:0,
        CreateCount:0,
        DestroyCount:0,
        CloseCount:0,
        ConnectCount:0,
        Connections:[
        ]
}
                   TYPE: JDBC
               IS_MYSQL: true
*************************** 2. row ***************************
                   NAME: dw1
               USERNAME: jam
               PASSWORD: 123456
                MAX_CON: 1000
                MIN_CON: 1
              EXIST_CON: 0
                USE_CON: 0
        MAX_RETRY_COUNT: 5
    MAX_CONNECT_TIMEOUT: 30000
                DB_TYPE: mysql
                    URL: jdbc:mysql://192.168.90.61:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
                 WEIGHT: 0
               INIT_SQL: 
INIT_SQL_GET_CONNECTION: true
          INSTANCE_TYPE: READ_WRITE
           IDLE_TIMEOUT: 60000
                 DRIVER: {
        CreateTime:&quot;2025-05-08 16:10:26&quot;,
        ActiveCount:0,
        PoolingCount:0,
        CreateCount:0,
        DestroyCount:0,
        CloseCount:0,
        ConnectCount:0,
        Connections:[
        ]
}
                   TYPE: JDBC
               IS_MYSQL: true
*************************** 3. row ***************************
                   NAME: dr0
               USERNAME: jam
               PASSWORD: 123456
                MAX_CON: 1000
                MIN_CON: 1
              EXIST_CON: 0
                USE_CON: 0
        MAX_RETRY_COUNT: 5
    MAX_CONNECT_TIMEOUT: 30000
                DB_TYPE: mysql
                    URL: jdbc:mysql://192.168.90.61:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
                 WEIGHT: 0
               INIT_SQL: 
INIT_SQL_GET_CONNECTION: true
          INSTANCE_TYPE: READ_WRITE
           IDLE_TIMEOUT: 60000
                 DRIVER: {
        CreateTime:&quot;2025-05-08 16:10:26&quot;,
        ActiveCount:0,
        PoolingCount:0,
        CreateCount:0,
        DestroyCount:0,
        CloseCount:0,
        ConnectCount:0,
        Connections:[
        ]
}
                   TYPE: JDBC
               IS_MYSQL: true
*************************** 4. row ***************************
                   NAME: dr1
               USERNAME: jam
               PASSWORD: 123456
                MAX_CON: 1000
                MIN_CON: 1
              EXIST_CON: 0
                USE_CON: 0
        MAX_RETRY_COUNT: 5
    MAX_CONNECT_TIMEOUT: 30000
                DB_TYPE: mysql
                    URL: jdbc:mysql://192.168.90.62:3306?useUnicode=true&amp;amp;serverTimezone=Asia/Shanghai&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
                 WEIGHT: 0
               INIT_SQL: 
INIT_SQL_GET_CONNECTION: true
          INSTANCE_TYPE: READ_WRITE
           IDLE_TIMEOUT: 60000
                 DRIVER: {
        CreateTime:&quot;2025-05-08 16:10:26&quot;,
        ActiveCount:0,
        PoolingCount:0,
        CreateCount:0,
        DestroyCount:0,
        CloseCount:0,
        ConnectCount:0,
        Connections:[
        ]
}
                   TYPE: JDBC
               IS_MYSQL: true
*************************** 5. row ***************************
                   NAME: prototypeDs
               USERNAME: jam
               PASSWORD: 123456
                MAX_CON: 1000
                MIN_CON: 1
              EXIST_CON: 0
                USE_CON: 0
        MAX_RETRY_COUNT: 5
    MAX_CONNECT_TIMEOUT: 3000
                DB_TYPE: mysql
                    URL: jdbc:mysql://localhost:3306/mysql?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
                 WEIGHT: 0
               INIT_SQL: 
INIT_SQL_GET_CONNECTION: true
          INSTANCE_TYPE: READ_WRITE
           IDLE_TIMEOUT: 60000
                 DRIVER: {
        CreateTime:&quot;2025-05-08 16:10:26&quot;,
        ActiveCount:0,
        PoolingCount:0,
        CreateCount:0,
        DestroyCount:0,
        CloseCount:0,
        ConnectCount:0,
        Connections:[
        ]
}
                   TYPE: JDBC
               IS_MYSQL: true
5 rows in set (0.07 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.4 配置数据库服务器&lt;/h3&gt;
&lt;p&gt;1）在主服务器添加jam用户&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql59 ~]# mysql 
mysql&amp;gt; create【克瑞特】 user jam@&quot;%&quot; identified【爱-丹-提伐】 by【拜】 &quot;123456&quot;;
# mysql&amp;gt; create user jam@&quot;%&quot; identified by &quot;123456&quot;;
# Query OK, 0 rows affected (0.01 sec)
Mysql&amp;gt; grant【古亮普】 all on【昂】 *.*  to jam@&quot;%&quot;;
# mysql&amp;gt; grant all on *.* to jam@&quot;%&quot;;
# Query OK, 0 rows affected (0.07 sec)

[root@mysql61 ~]# mysql 
mysql&amp;gt; create【克瑞特】 user jam@&quot;%&quot; identified【爱-丹-提伐】 by【拜】 &quot;123456&quot;;
# mysql&amp;gt; create user jam@&quot;%&quot; identified by &quot;123456&quot;;
# Query OK, 0 rows affected (0.02 sec)
Mysql&amp;gt; grant【古亮普】 all on【昂】 *.*  to jam@&quot;%&quot;;
# mysql&amp;gt; grant all on *.* to jam@&quot;%&quot;;
# Query OK, 0 rows affected (0.02 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）在从服务器查看用户是否同步&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql60 ~]# mysql -e &apos;select【涩莱克特】 user from【弗乱】 mysql.user where【威尔】 user=&quot;jam&quot;&apos;
# mysql&amp;gt; select user from mysql.user where user=&quot;jam&quot;;
# +------+
# | user |
# +------+
# | jam  |
# +------+
# 1 row in set (0.00 sec)

[root@mysql62 ~]# mysql -e &apos;select【涩莱克特】 user from【弗乱】 mysql.user where【威尔】 user=&quot;jam&quot;&apos;
# mysql&amp;gt; select user from mysql.user where user=&quot;jam&quot;;
# +------+
# | user |
# +------+
# | jam  |
# +------+
# 1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.5 创建集群&lt;/h3&gt;
&lt;p&gt;1）连接本机的mycat【麦-凯特】服务,创建集群&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat63 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321
mysql&amp;gt; /*!mycat:createcluster{&quot;name&quot;:&quot;c0&quot;,&quot;masters&quot;:[&quot;dw0&quot;],&quot;replicas&quot;:[&quot;dr0&quot;]}*/;
mysql&amp;gt; /*!mycat:createcluster{&quot;name&quot;:&quot;c1&quot;,&quot;masters&quot;:[&quot;dw1&quot;],&quot;replicas&quot;:[&quot;dr1&quot;]}*/;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）创建的集群保存在mycat【麦-凯特】安装目录下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@MySQL63 ~]# ls /usr/local/mycat/conf/clusters/
c0.cluster.json  c1.cluster.json  prototype.cluster.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3）查看集群信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; /*+ mycat:showClusters{}*/ \G
*************************** 1. row ***************************
             NAME: prototype
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 200
             TYPE: BALANCE_ALL
         WRITE_DS: prototypeDs
          READ_DS: prototypeDs
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
*************************** 2. row ***************************
             NAME: c0
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 2000
             TYPE: BALANCE_ALL
         WRITE_DS: dw0
          READ_DS: dw0,dr0
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
*************************** 3. row ***************************
             NAME: c1
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 2000
             TYPE: BALANCE_ALL
         WRITE_DS: dw1
          READ_DS: dw1,dr1
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
3 rows in set (0.03 sec)
mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;七、分库分表策略&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250617154556706.webp&quot; alt=&quot;image-20250617154556706&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;7.1 全局表&lt;/h3&gt;
&lt;p&gt;在客户端client50 连接mycat63 存储数据 ，验证mycat63的配置&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;全局表 数据会插入到两个库中，并且两个库中都有全部的数据。&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//在mycat63 连接本机的mycat服务建库
[root@mycat63 ~]# mysql -h127.0.0.1 -umycat -p654321 -P8066

mysql&amp;gt; create【克瑞特】 database moershi;
# mysql&amp;gt; create database moershi;
# Query OK, 0 rows affected (0.09 sec)

mysql&amp;gt; exit
Bye
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;配置文件存放位置&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat63 ~]# ls /usr/local/mycat/conf/schemas/moershi.schema.json 
/usr/local/mycat/conf/schemas/moershi.schema.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;创建全局表&lt;/strong&gt;
broadcast【布落德卡斯特】：全局表关键字
&lt;strong&gt;&lt;code&gt;broadcast&lt;/code&gt; 广播规则&lt;/strong&gt;：建表时指定了 &lt;code&gt;broadcast&lt;/code&gt;，这是 Mycat 的一种分片规则，意思是 “&lt;strong&gt;将操作广播到所有关联的数据节点&lt;/strong&gt;”,建表语句会被广播到逻辑库关联的所有物理节点（主库 + 从库）。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 客户端client50 连接mycat63主机的 建表存储数据
[root@client50 ~]# mysql -h192.168.90.63 -umycat -p654321 -P8066

mysql&amp;gt; create【克瑞特】 table【忒-部】 moershi.dept(dept_id int【因特】  , dept_name char【查尔】(10),primary【普赖莫瑞】 key【kì】(dept_id)) default【迪-佛特】 charset【查赛特】 utf8  broadcast【布落德卡斯特】;
# mysql&amp;gt; create table moershi.dept(
#     -&amp;gt; dept_id int,
#     -&amp;gt; dept_name char(10),
#     -&amp;gt; primary key(dept_id)
#     -&amp;gt; )default charset utf8 broadcast;
# Query OK, 0 rows affected (1 min 0.20 sec)

# 插入记录
mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.dept values【挖柳斯】(1,&quot;开发部&quot;),(2,&quot;运维部&quot;),(3,&quot;测试部&quot;);
# mysql&amp;gt; insert into moershi.dept values(1,&quot;开发部&quot;),(2,&quot;运维部&quot;),(3,&quot;测试部&quot;);
# Query OK, 1 row affected (0.07 sec)

# 查看记录
mysql&amp;gt; select【涩莱克特】  * from【弗乱】 moershi.dept;
# mysql&amp;gt; select * from moershi.dept;
# +---------+-----------+
# | dept_id | dept_name |
# +---------+-----------+
# |       1 | 开发部    |
# |       2 | 运维部    |
# |       3 | 测试部    |
# +---------+-----------+
# 3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在4台数据库服务器查看&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql59 ~]# mysql -e &apos;select【涩莱克特】  * from【弗乱】 moershi.dept&apos;
# [root@mysql59 ~]#  mysql -uroot -p123 -e &quot;select * from moershi.dept&quot;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|       1 | 开发部    |
|       2 | 运维部    |
|       3 | 测试部    |
+---------+-----------+

[root@mysql60 ~]# mysql -e &apos;select【涩莱克特】  * from【弗乱】 moershi.dept&apos;
# m[root@mysql60 ~]# mysql -uroot -p123 -e &quot;select * from moershi.dept&quot;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|       1 | 开发部    |
|       2 | 运维部    |
|       3 | 测试部    |
+---------+-----------+
 
[root@mysql61 ~]# mysql -e &apos;select【涩莱克特】  * from【弗乱】 moershi.dept&apos;
# [root@mysql61 ~]# mysql -uroot -p123 -e &quot;select * from moershi.dept&quot;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|       1 | 开发部    |
|       2 | 运维部    |
|       3 | 测试部    |
+---------+-----------+
 
[root@mysql62 ~]# mysql -e &apos;select【涩莱克特】  * from【弗乱】 moershi.dept&apos;
# [root@mysql62 ~]# mysql -uroot -p123 -e &quot;select * from moershi.dept&quot;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|       1 | 开发部    |
|       2 | 运维部    |
|       3 | 测试部    |
+---------+-----------+
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.2 分片表&lt;/h3&gt;
&lt;h4&gt;原理&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Mycat 中分片表的原理和用法：&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;一句话总结：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“把一张大表的数据，按规则‘拆开’存到多个库、多个表里，查的时候 Mycat 自动帮你拼回来。”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;p&gt;举个生活例子：快递分拣中心&lt;/p&gt;
&lt;p&gt;想象你开了一个超大快递公司（数据库），每天有 &lt;strong&gt;100 万件包裹（数据）&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果所有包裹都堆在一个仓库（单库单表）→ 找起来慢、容易堵死。&lt;/li&gt;
&lt;li&gt;于是你建了 &lt;strong&gt;2 个分拣中心（分库）&lt;/strong&gt;，每个中心再分 &lt;strong&gt;1 个货架区（分表）&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;规则：&lt;strong&gt;按收件人手机号最后一位数字 % 2&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;偶数 → 送 1 号中心&lt;/li&gt;
&lt;li&gt;奇数 → 送 2 号中心&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这样：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每个中心只处理 50 万件，压力小；&lt;/li&gt;
&lt;li&gt;要找“张三”的包裹？直接去他手机号对应的中心，不用跑遍全国！&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;对应回你的 SQL&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE moershi.employees (
  employee_id INT PRIMARY KEY,  -- ← 相当于“手机号”
  name CHAR(10),
  dept_id INT,
  mail VARCHAR(30)
) 
DEFAULT CHARSET utf8
DBPARTITION BY MOD_HASH(employee_id)   -- 按 employee_id 分“库”
DBPARTITIONS 2                         -- 拆成 2 个库（比如 59 和 61）
TBPARTITION BY MOD_HASH(employee_id)   -- 按 employee_id 分“表”
TBPARTITIONS 1;                        -- 每个库里只建 1 张表（不分表）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;拆解说明：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;关键词&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;th&gt;大白话&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DBPARTITION BY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;分库规则&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;数据往哪个“物理服务器”存？&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DBPARTITIONS 2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;分 2 个库&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;用 2 台 MySQL 机器（59 和 61）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TBPARTITION BY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;分表规则&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;在一个库里，数据放哪张“物理表”？&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TBPARTITIONS 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;每库 1 张表&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;不分表，就叫 &lt;code&gt;employees_0&lt;/code&gt; 或 &lt;code&gt;employees_1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;因为你 &lt;code&gt;TBPARTITIONS=1&lt;/code&gt;，所以&lt;strong&gt;其实没分表，只分了库&lt;/strong&gt;。&lt;br /&gt;
如果写 &lt;code&gt;TBPARTITIONS 12&lt;/code&gt;，那每个库里会有 12 张表（如 &lt;code&gt;employees_0&lt;/code&gt;, &lt;code&gt;employees_1&lt;/code&gt;, ..., &lt;code&gt;employees_11&lt;/code&gt;）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;p&gt;数据怎么存？怎么查？&lt;/p&gt;
&lt;p&gt;插入数据：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;INSERT INTO employees VALUES (1, &apos;张三&apos;, ...);  -- employee_id = 1
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Mycat 计算：&lt;code&gt;1 % 2 = 1&lt;/code&gt; → 存到 &lt;strong&gt;第 1 个库&lt;/strong&gt;（比如 192.168.88.61）&lt;/li&gt;
&lt;li&gt;物理表名：&lt;code&gt;moershi_1.employees_0&lt;/code&gt;（Mycat 自动生成）&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;INSERT INTO employees VALUES (2, &apos;李四&apos;, ...);  -- employee_id = 2
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;2 % 2 = 0&lt;/code&gt; → 存到 &lt;strong&gt;第 0 个库&lt;/strong&gt;（比如 192.168.88.59）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;物理表名：&lt;code&gt;moershi_0.employees_0&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查询数据：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;SELECT * FROM employees WHERE employee_id = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Mycat 算出 &lt;code&gt;1 % 2 = 1&lt;/code&gt; → &lt;strong&gt;只去 61 机器查&lt;/strong&gt;，秒回！&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;SELECT * FROM employees;  -- 没带条件
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Mycat 会去 &lt;strong&gt;59 和 61 都查一遍&lt;/strong&gt;，再把结果合并给你（慢！尽量避免）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;什么时候用分片表&lt;/strong&gt;？&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;场景&lt;/th&gt;
&lt;th&gt;建议&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;表数据 &amp;gt; 500 万行&lt;/td&gt;
&lt;td&gt;✅ 考虑分片&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;经常按 &lt;code&gt;user_id&lt;/code&gt;/&lt;code&gt;order_id&lt;/code&gt; 查询&lt;/td&gt;
&lt;td&gt;✅ 用这个字段做分片键&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;需要 JOIN 其他表&lt;/td&gt;
&lt;td&gt;✅ 让关联表用&lt;strong&gt;相同分片规则&lt;/strong&gt;（ER 表）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;查询不带分片键&lt;/td&gt;
&lt;td&gt;❌ 尽量避免（会全库扫描）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;注意事项（避坑指南）&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;分片键必须出现在 WHERE 条件里&lt;/strong&gt;，否则 Mycat 会查所有库！&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不要用 &lt;code&gt;SELECT *&lt;/code&gt; 无条件查询大表&lt;/strong&gt;，性能爆炸。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分片后不能直接用自增主键&lt;/strong&gt;（不同库可能重复），建议用雪花 ID。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DDL（改表结构）要小心&lt;/strong&gt;：需在所有物理表上同步执行。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;总结（背下来！）&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;DBPARTITION&lt;/code&gt; = 分库（多台机器）&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;TBPARTITION&lt;/code&gt; = 分表（一个库里多张表）&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;MOD_HASH(id)&lt;/code&gt; = 按 id 取模，均匀分布&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分片键 = 你最常用来查数据的那个字段（如 user_id）&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mycat 是“智能快递员”，自动投递和取件，你只管用逻辑表名！&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h4&gt;实操&lt;/h4&gt;
&lt;p&gt;dbpartition【db-帕踢神】 定义分库使用的分片规则，&lt;/p&gt;
&lt;p&gt;tbpartition【tb-帕踢神】 定义分表使用的分片规则。&lt;/p&gt;
&lt;p&gt;mod【莫德】_hash【哈希】 分片规则，用employee【ing普洛伊】_id表头的值做取模计算&lt;/p&gt;
&lt;p&gt;tbpartitions【tb-帕踢神s】 1 表的分片数量&lt;/p&gt;
&lt;p&gt;dbpartitions【db-帕踢神s】 2 库的分片数量&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 连接mycat服务建表
[root@client50 ~]# mysql -h192.168.90.63 -P8066 -umycat –p654321

create【克瑞特】 table【忒-部】 moershi.employees【ing普洛伊s】(
employee【ing普洛伊】_id  int【因特】  primary【普赖莫瑞】 key【kì】,
name char【查尔】(10),dept_id int【因特】 , 
mail varchar【瓦儿-查儿】(30)
) default【迪-佛特】 charset【查赛特】 utf8
dbpartition【db-帕踢神】 by【拜】 mod【莫德】_hash【哈希】(employee【ing普洛伊】_id) tbpartition【tb-帕踢神】 by【拜】 mod【莫德】_hash【哈希】(employee【ing普洛伊】_id) 
tbpartitions【tb-帕踢神s】 1 dbpartitions【db-帕踢神s】 2;

# mysql&amp;gt; create table moershi.employees(
#     -&amp;gt; employee_id int primary key,
#     -&amp;gt; name char(10),
#     -&amp;gt; dept_id int,
#     -&amp;gt; mail varchar(30)
#     -&amp;gt; )default charset utf8
#     -&amp;gt; dbpartition by mod_hash(employee_id) tbpartition by mod_hash(employee_id)
#     -&amp;gt; tbpartitions 1 dbpartitions 2;
# Query OK, 1 row affected (1.24 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在4台数据库服务器查看表&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql59 ~]# mysql -e &apos;show【瘦】 databases&apos;
# [root@mysql59 ~]#  mysql -uroot -p123 -e &quot;show databases;&quot;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +--------------------+
# | Database           |
# +--------------------+
# | information_schema |
# | moershi            |
# | moershi_0          |
# | mysql              |
# | performance_schema |
# | sys                |
# +--------------------+

[root@mysql59 ~]# mysql -e &apos;use moershi_0 ; show【瘦】 tables【忒-部s】&apos;
# [root@mysql59 ~]#  mysql -uroot -p123 -e &quot;use moershi_0;show tables&quot;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +---------------------+
# | Tables_in_moershi_0 |
# +---------------------+
# | employees_0         |
# +---------------------+

[root@mysql60 ~]# mysql -e &apos;show【瘦】 databases&apos;
# [root@mysql60 ~]# mysql -uroot -p123 -e &quot;show databases;&quot;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +--------------------+
# | Database           |
# +--------------------+
# | information_schema |
# | moershi            |
# | moershi_0          |
# | mysql              |
# | performance_schema |
# | sys                |
# +--------------------+

[root@mysql60 ~]# mysql -e &apos;use moershi_0 ; show【瘦】 tables【忒-部s】&apos;
# [root@mysql60 ~]# mysql -uroot -p123 -e &quot;use moershi_0;show tables&quot;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +---------------------+
# | Tables_in_moershi_0 |
# +---------------------+
# | employees_0         |
# +---------------------+

[root@mysql61 ~]# mysql -e &apos;show【瘦】 databases&apos;
# [root@mysql61 ~]# mysql -uroot -p123 -e &quot;show databases;&quot;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +--------------------+
# | Database           |
# +--------------------+
# | information_schema |
# | moershi            |
# | moershi_1          |
# | mysql              |
# | performance_schema |
# | sys                |
# +--------------------+

[root@mysql61 ~]# mysql -e &apos;use moershi_1;show【瘦】 tables【忒-部s】&apos;
# [root@mysql61 ~]# mysql -uroot -p123 -e &quot;use moershi_1;show tables&quot;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +---------------------+
# | Tables_in_moershi_1 |
# +---------------------+
# | employees_1         |
# +---------------------+

[root@mysql62 ~]# mysql -e &apos;show【瘦】 databases&apos;
# [root@mysql62 ~]# mysql -uroot -p123 -e &quot;show databases;&quot;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +--------------------+
# | Database           |
# +--------------------+
# | information_schema |
# | moershi            |
# | moershi_1          |
# | mysql              |
# | performance_schema |
# | sys                |
# +--------------------+

[root@mysql62 ~]# mysql -e &apos;use moershi_1;show【瘦】 tables【忒-部s】&apos;
# [root@mysql62 ~]# mysql -uroot -p123 -e &quot;use moershi_1;show tables&quot;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +---------------------+
# | Tables_in_moershi_1 |
# +---------------------+
# | employees_1         |
# +---------------------+

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;存储数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@client50 ~]# mysql -h192.168.90.63 -P8066 -umycat –p654321

mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.employees【ing普洛伊s】 values【挖柳斯】 (9,&quot;a&quot;,&quot;1&quot;,&quot;a@163.com&quot;);
# mysql&amp;gt; insert into moershi.employees values(9,&quot;a&quot;,&quot;1&quot;,&quot;a@163.com&quot;);
# Query OK, 1 row affected (0.04 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.employees【ing普洛伊s】 values【挖柳斯】 (8,&quot;B&quot;,&quot;3&quot;,&quot;B@QQ.com&quot;);
# mysql&amp;gt; insert into moershi.employees values(8,&quot;B&quot;,&quot;3&quot;,&quot;B@QQ.com&quot;);
# Query OK, 1 row affected (0.02 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.employees【ing普洛伊s】 values【挖柳斯】 (7,&quot;C&quot;,&quot;2&quot;,&quot;c@QQ.com&quot;);
# mysql&amp;gt; insert into moershi.employees values(7,&quot;C&quot;,&quot;2&quot;,&quot;c@QQ.com&quot;);
# Query OK, 1 row affected (0.02 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.employees【ing普洛伊s】 values【挖柳斯】 (6,&quot;C&quot;,&quot;2&quot;,&quot;c@QQ.com&quot;);
# mysql&amp;gt; insert into moershi.employees values(6,&quot;C&quot;,&quot;2&quot;,&quot;c@QQ.com&quot;);
# Query OK, 1 row affected (0.01 sec)

mysql&amp;gt; select【涩莱克特】  * from【弗乱】 moershi.employees【ing普洛伊s】;
# mysql&amp;gt; select * from moershi.employees;
# +-------------+------+---------+-----------+
# | employee_id | name | dept_id | mail      |
# +-------------+------+---------+-----------+
# |           6 | C    |       2 | c@QQ.com  |
# |           8 | B    |       3 | B@QQ.com  |
# |           7 | C    |       2 | c@QQ.com  |
# |           9 | a    |       1 | a@163.com |
# +-------------+------+---------+-----------+
# 4 rows in set (1.53 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在数据库服务器本机查看数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql59 ~]# mysql -e &apos;select【涩莱克特】  * from【弗乱】 moershi_0.employees【ing普洛伊s】_0&apos;
# [root@mysql59 ~]#  mysql -uroot -p123 -e &quot;select * from moershi_0.employees_0&quot;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +-------------+------+---------+----------+
# | employee_id | name | dept_id | mail     |
# +-------------+------+---------+----------+
# |           6 | C    |       2 | c@QQ.com |
# |           8 | B    |       3 | B@QQ.com |
# +-------------+------+---------+----------+
 
[root@mysql60 ~]# mysql -e &apos;select【涩莱克特】  * from【弗乱】 moershi_0.employees【ing普洛伊s】_0&apos;
# [root@mysql60 ~]# mysql -uroot -p123 -e &quot;select * from moershi_0.employees_0&quot;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +-------------+------+---------+----------+
# | employee_id | name | dept_id | mail     |
# +-------------+------+---------+----------+
# |           6 | C    |       2 | c@QQ.com |
# |           8 | B    |       3 | B@QQ.com |
# +-------------+------+---------+----------+
 
[root@mysql61 ~]# mysql -e &apos;select【涩莱克特】 * from【弗乱】 moershi_1.employees【ing普洛伊s】_1&apos;
# [root@mysql61 ~]# mysql -uroot -p123 -e &quot;select * from moershi_1.employees_1&quot;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +-------------+------+---------+-----------+
# | employee_id | name | dept_id | mail      |
# +-------------+------+---------+-----------+
# |           7 | C    |       2 | c@QQ.com  |
# |           9 | a    |       1 | a@163.com |
# +-------------+------+---------+-----------+
 
[root@mysql62 ~]# mysql -e &apos;select【涩莱克特】 * from【弗乱】 moershi_1.employees【ing普洛伊s】_1&apos;
# [root@mysql62 ~]# mysql -uroot -p123 -e &quot;select * from moershi_1.employees_1&quot;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +-------------+------+---------+-----------+
# | employee_id | name | dept_id | mail      |
# +-------------+------+---------+-----------+
# |           7 | C    |       2 | c@QQ.com  |
# |           9 | a    |       1 | a@163.com |
# +-------------+------+---------+-----------+
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.3 ER表(关联表)&lt;/h3&gt;
&lt;p&gt;ER表，称为关联表，表示数据逻辑上有关联性的两个或多个表，例如工资表和员工表。对于关联表，通常希望他们能够有相同的分片规则，这样在进行关联查询时，能够快速定位到同一个数据分片中。MyCat2中对于关联表，不需要有过多的声明，他可以根据分片规则自行判断。&lt;/p&gt;
&lt;h4&gt;ER表原理&lt;/h4&gt;
&lt;p&gt;ER 关联表（Entity-Relationship Sharding Table）是 &lt;strong&gt;分布式数据库中间件（如 Mycat、ShardingSphere 等）中用于优化跨表 JOIN 查询的核心机制&lt;/strong&gt;。它的核心思想是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“让有关联关系的数据，落在同一个物理分片上。”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这样，即使执行 &lt;code&gt;JOIN&lt;/code&gt; 操作，也能在单个数据库节点内完成，避免跨库 JOIN 带来的性能灾难。&lt;/p&gt;
&lt;hr /&gt;
&lt;h5&gt;一、为什么需要 ER 表？&lt;/h5&gt;
&lt;p&gt;在分库分表架构中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;表 A 按 &lt;code&gt;user_id&lt;/code&gt; 分片 → 数据分散在 db0、db1、db2...&lt;/li&gt;
&lt;li&gt;表 B 也按 &lt;code&gt;user_id&lt;/code&gt; 分片 → 相同 &lt;code&gt;user_id&lt;/code&gt; 的数据也在同一分片&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;✅ 如果你查询：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT * FROM orders o 
JOIN order_items oi ON o.order_id = oi.order_id 
WHERE o.user_id = 100;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;若 &lt;code&gt;orders&lt;/code&gt; 和 &lt;code&gt;order_items&lt;/code&gt; 是 &lt;strong&gt;ER 表&lt;/strong&gt;（同分片规则），Mycat 能确定：&lt;br /&gt;
&lt;strong&gt;所有相关数据都在同一个分片（比如 db1）&lt;/strong&gt; → 直接下发 SQL 到 db1 执行 JOIN。&lt;/li&gt;
&lt;li&gt;若不是 ER 表，Mycat 只能：
&lt;ul&gt;
&lt;li&gt;分别查 &lt;code&gt;orders&lt;/code&gt; 和 &lt;code&gt;order_items&lt;/code&gt;（可能在不同库）&lt;/li&gt;
&lt;li&gt;在内存中做合并（广播 + 内存计算）&lt;/li&gt;
&lt;li&gt;性能极差，且结果可能不完整&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h5&gt;二、ER 表的核心原理&lt;/h5&gt;
&lt;h6&gt;1. &lt;strong&gt;相同的分片规则（Sharding Rule）&lt;/strong&gt;&lt;/h6&gt;
&lt;p&gt;两表必须满足：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;条件&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;分片键相同&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;如都用 &lt;code&gt;employee_id&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;分片算法相同&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;如都用 &lt;code&gt;MOD_HASH(employee_id)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;分片数量一致&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;如都是 2 个库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;分片拓扑对齐&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;数据节点列表完全一致&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;→ 这样才能保证：&lt;strong&gt;任意一条记录的关联数据，必然在同一物理节点&lt;/strong&gt;。&lt;/p&gt;
&lt;h6&gt;2. &lt;strong&gt;主外键逻辑匹配&lt;/strong&gt;&lt;/h6&gt;
&lt;ul&gt;
&lt;li&gt;主表（如 &lt;code&gt;employees&lt;/code&gt;）：&lt;code&gt;employee_id&lt;/code&gt; 是主键&lt;/li&gt;
&lt;li&gt;子表（如 &lt;code&gt;salary&lt;/code&gt;）：&lt;code&gt;employee_id&lt;/code&gt; 是主键或外键（Mycat 不强制外键约束，但逻辑上需一致）&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;📌 Mycat 2.x 不要求数据库有真实外键，但&lt;strong&gt;字段名和分片语义必须一致&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h6&gt;3. &lt;strong&gt;自动路由优化&lt;/strong&gt;&lt;/h6&gt;
&lt;p&gt;当 Mycat 解析到：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT ... FROM employees e JOIN salary s ON e.employee_id = s.employee_id
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;它会：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;提取 &lt;code&gt;WHERE&lt;/code&gt; 或 &lt;code&gt;ON&lt;/code&gt; 中的分片键值（如 &lt;code&gt;employee_id = 1&lt;/code&gt;）；&lt;/li&gt;
&lt;li&gt;计算该值应落在哪个分片（如 &lt;code&gt;1 % 2 = 1&lt;/code&gt; → db1）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;将整个 JOIN 查询直接下发到 db1 执行&lt;/strong&gt;；&lt;/li&gt;
&lt;li&gt;返回结果，&lt;strong&gt;全程无跨库操作&lt;/strong&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h5&gt;三、Mycat 2.x 中 ER 表的实现方式&lt;/h5&gt;
&lt;h6&gt;自动识别（无需配置）&lt;/h6&gt;
&lt;p&gt;Mycat 2.x 采用 &lt;strong&gt;“规则匹配 + 元数据推导”&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当你创建第二张表时，Mycat 对比已有表的分片规则；&lt;/li&gt;
&lt;li&gt;如果完全匹配 → 自动归入同一个 &lt;code&gt;groupId&lt;/code&gt;（即 ER 组）；&lt;/li&gt;
&lt;li&gt;通过命令可查看：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;/*+ mycat:showErGroup{} */;
&lt;/code&gt;&lt;/pre&gt;
&lt;h6&gt;分组标识（groupId）&lt;/h6&gt;
&lt;ul&gt;
&lt;li&gt;同一个 &lt;code&gt;groupId&lt;/code&gt; 内的所有表，被视为 &lt;strong&gt;强关联 ER 表&lt;/strong&gt;；&lt;/li&gt;
&lt;li&gt;Mycat 在路由时，会优先尝试将它们的查询合并到同一分片。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;四、ER 表 vs 广播表 vs 普通分片表&lt;/h5&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;特点&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ER 表&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;多表按相同规则分片，数据共置&lt;/td&gt;
&lt;td&gt;主子表（订单/订单项）、一对多关联&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;广播表&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;全量复制到所有分片&lt;/td&gt;
&lt;td&gt;小表（字典表、配置表），频繁 JOIN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;普通分片表&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;独立分片，无关联&lt;/td&gt;
&lt;td&gt;无关联的大表（日志、流水）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;实际系统中常组合使用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;employees&lt;/code&gt;（分片表）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dept&lt;/code&gt;（广播表）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;salary&lt;/code&gt;（ER 表，关联 employees）&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h5&gt;五、示例：ER 表工作流程&lt;/h5&gt;
&lt;h6&gt;表结构&lt;/h6&gt;
&lt;pre&gt;&lt;code&gt;-- 主表
CREATE TABLE employees (
  employee_id INT PRIMARY KEY,
  name CHAR(10)
) DBPARTITIONS 2 DBPARTITION BY MOD_HASH(employee_id);

-- 子表（ER 表）
CREATE TABLE salary (
  employee_id INT PRIMARY KEY,
  basic INT
) DBPARTITIONS 2 DBPARTITION BY MOD_HASH(employee_id);
&lt;/code&gt;&lt;/pre&gt;
&lt;h6&gt;插入数据&lt;/h6&gt;
&lt;pre&gt;&lt;code&gt;INSERT INTO employees VALUES (1, &apos;张三&apos;);
INSERT INTO salary VALUES (1, 8000);
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;employee_id=1&lt;/code&gt; → &lt;code&gt;1 % 2 = 1&lt;/code&gt; → 都写入 &lt;strong&gt;db1&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h6&gt;查询&lt;/h6&gt;
&lt;pre&gt;&lt;code&gt;SELECT e.name, s.basic 
FROM employees e JOIN salary s ON e.employee_id = s.employee_id
WHERE e.employee_id = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Mycat 计算：&lt;code&gt;1 % 2 = 1&lt;/code&gt; → 下发到 &lt;strong&gt;db1&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;db1 执行原生 JOIN → 返回结果&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;✅ &lt;strong&gt;高效、准确、无跨库&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h5&gt;六、注意事项&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;分片键必须出现在 JOIN 条件中&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- ✅ 能识别 ER
ON e.employee_id = s.employee_id

-- ❌ 无法识别（字段不同）
ON e.id = s.emp_id
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;不支持复杂表达式&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- ❌ Mycat 可能无法解析
ON e.employee_id + 100 = s.employee_id
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;动态扩容会影响 ER 关系&lt;/strong&gt;&lt;br /&gt;
从 2 库扩到 4 库时，需确保所有 ER 表同步 rehash，否则数据错位。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h5&gt;总结：ER 表的本质&lt;/h5&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;ER 表 = 数据共置（Data Co-location） + 路由协同（Routing Coordination）&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;通过&lt;strong&gt;强制关联数据落在同一分片&lt;/strong&gt;，使得分布式数据库能像单机一样高效执行 JOIN，是分库分表架构中&lt;strong&gt;保持查询能力的关键设计&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;在 Mycat 2.x 中，这一机制已高度自动化，你只需&lt;strong&gt;保证分片规则一致&lt;/strong&gt;，即可享受 ER 优化带来的性能红利。&lt;/p&gt;
&lt;h3&gt;模拟实验&lt;/h3&gt;
&lt;p&gt;1)连接mycat服务建表&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@client50 ~]# mysql -h192.168.90.63 -P8066 -umycat –p654321

mysql&amp;gt; create【克瑞特】 table【忒-部】 moershi.salary【晒了瑞】(
employee【ing普洛伊】_id int【因特】 primary【普赖莫瑞】 key【kì】, 
p_date date , basic【贝斯克】 int【因特】 , bonus【波诺斯】 int【因特】 
) default【迪-佛特】 charset【查赛特】=utf8 
dbpartition【db-帕踢神】 by【拜】 mod【莫德】_hash【哈希】(employee【ing普洛伊】_id) 
tbpartition【tb-帕踢神】 by【拜】 mod【莫德】_hash【哈希】(employee【ing普洛伊】_id) tbpartitions【tb-帕踢神s】 1;

# mysql&amp;gt; create table moershi.salary (
#     -&amp;gt; employee_id int primary key, 
#     -&amp;gt; p_date date , basic int, 
#     -&amp;gt; bonus int 
#     -&amp;gt; ) default charset=utf8 
#     -&amp;gt; dbpartition by mod_hash(employee_id) 
#     -&amp;gt; tbpartition by mod_hash(employee_id) tbpartitions 1;
# Query OK, 1 row affected (0.27 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）在MyCat2终端查看关联表关系。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat63 ~]# mysql -h127.0.0.1 -P8066 -umycat –p654321
mysql&amp;gt; /*+ mycat:showErGroup{}*/ ;
+---------+------------+-----------+
| groupId | schemaName | tableName |
+---------+------------+-----------+
| 0       | moershi     | employees |
| 0       | moershi     | salary【晒了瑞】    |
+---------+------------+-----------+
2 rows in set (0.00 sec)
mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3)在2台主服务器查看表&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql59 ~]# mysql -e &apos;use moershi_0 ; show【瘦】 tables【忒-部s】&apos;
# [root@mysql59 ~]#  mysql -uroot -p123 -e &quot;use moershi_0;show tables&quot;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +---------------------+
# | Tables_in_moershi_0 |
# +---------------------+
# | employees_0         |
# | salary_0            |
# +---------------------+

[root@mysql61 ~]# mysql -e &apos;use moershi_1;show【瘦】 tables【忒-部s】&apos;
# [root@mysql61 ~]# mysql -uroot -p123 -e &quot;use moershi_1;show tables&quot;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +---------------------+
# | Tables_in_moershi_1 |
# +---------------------+
# | employees_1         |
# | salary_1            |
# +---------------------+
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4）插入数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@client50 ~]# mysql -h192.168.90.63 -P8066 -umycat –p654321 

mysql&amp;gt; desc moershi.salary【晒了瑞】;
# mysql&amp;gt; desc moershi.salary;
# +-------------+------+------+-----+---------+-------+
# | Field       | Type | Null | Key | Default | Extra |
# +-------------+------+------+-----+---------+-------+
# | employee_id | int  | NO   | PRI | NULL    |       |
# | p_date      | date | YES  |     | NULL    |       |
# | basic       | int  | YES  |     | NULL    |       |
# | bonus       | int  | YES  |     | NULL    |       |
# +-------------+------+------+-----+---------+-------+
# 4 rows in set (0.02 sec)

mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.salary【晒了瑞】 values【挖柳斯】(6,20230110,20000,2000);

mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.salary【晒了瑞】 values【挖柳斯】(7,20230210,25000,2500);

mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.salary【晒了瑞】 values【挖柳斯】(8,20230310,30000,3000);

mysql&amp;gt; insert【因涩特】 into【因兔】 moershi.salary【晒了瑞】 values【挖柳斯】(9,20230410,35000,3500);

# mysql&amp;gt; insert into moershi.salary values (6,20230110,20000,2000),(7,20230210,25000,2500),(8,20230310,30000,3000),(9,20230410,35000,3500);
# Query OK, 4 rows affected (0.08 sec)

mysql&amp;gt; select【涩莱克特】  * from【弗乱】 moershi.salary【晒了瑞】;
# mysql&amp;gt; select * from moershi.salary;
# +-------------+------------+-------+-------+
# | employee_id | p_date     | basic | bonus |
# +-------------+------------+-------+-------+
# |           6 | 2023-01-10 | 20000 |  2000 |
# |           8 | 2023-03-10 | 30000 |  3000 |
# |           7 | 2023-02-10 | 25000 |  2500 |
# |           9 | 2023-04-10 | 35000 |  3500 |
# +-------------+------------+-------+-------+
# 4 rows in set (0.03 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;5)在4台数据库服务器本机查看&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql59 ~]# mysql -e &apos;select【涩莱克特】  * from【弗乱】 moershi_0.employees【ing普洛伊s】_0&apos;
# [root@mysql59 ~]#  mysql -uroot -p123 -e &quot;select * from moershi_0.employees_0&quot;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +-------------+------+---------+----------+
# | employee_id | name | dept_id | mail     |
# +-------------+------+---------+----------+
# |           6 | C    |       2 | c@QQ.com |
# |           8 | B    |       3 | B@QQ.com |
# +-------------+------+---------+----------+
 
[root@mysql60 ~]# mysql -e &apos;select【涩莱克特】  * from【弗乱】 moershi_0.salary【晒了瑞】_0&apos;
# [root@mysql60 ~]# mysql -uroot -p123 -e &quot;select * from moershi_0.salary_0&quot;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +-------------+------------+-------+-------+
# | employee_id | p_date     | basic | bonus |
# +-------------+------------+-------+-------+
# |           6 | 2023-01-10 | 20000 |  2000 |
# |           8 | 2023-03-10 | 30000 |  3000 |
# +-------------+------------+-------+-------+
 
[root@mysql61 ~]# mysql -e &apos;select【涩莱克特】 * from【弗乱】 moershi_1.employees【ing普洛伊s】_1&apos;
# [root@mysql61 ~]# mysql -uroot -p123 -e &quot;select * from moershi_1.employees_1&quot;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +-------------+------+---------+-----------+
# | employee_id | name | dept_id | mail      |
# +-------------+------+---------+-----------+
# |           7 | C    |       2 | c@QQ.com  |
# |           9 | a    |       1 | a@163.com |
# +-------------+------+---------+-----------+

[root@mysql62 ~]# mysql -e &apos;select【涩莱克特】 * from【弗乱】 moershi_1.salary【晒了瑞】_1&apos;
# [root@mysql62 ~]# mysql -uroot -p123 -e &quot;select * from moershi_1.salary_1&quot;
# mysql: [Warning] Using a password on the command line interface can be insecure.
# +-------------+------------+-------+-------+
# | employee_id | p_date     | basic | bonus |
# +-------------+------------+-------+-------+
# |           7 | 2023-02-10 | 25000 |  2500 |
# |           9 | 2023-04-10 | 35000 |  3500 |
# +-------------+------------+-------+-------+

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;分片配置说明&lt;/h3&gt;
&lt;p&gt;/usr/local/mycat/conf/schemas/user_order_db.schema.json&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mycat63 ~]# cat /usr/local/mycat/conf/schemas/user_order_db.schema.json 
{
       // 自定义表（高级用法），此处为空
        &quot;customTables&quot;:{},
       // 全局表（所有节点都存全量数据），此处为空
        &quot;globalTables&quot;:{},
        &quot;normalProcedures&quot;:{},
       // 普通表（不分片，只在一个节点），此处为空
        &quot;normalTables&quot;:{},
        // 逻辑库名称，应用程序连接时使用：use user_order_db;
        &quot;schemaName&quot;:&quot;user_order_db&quot;,
         // 指定该逻辑库绑定到哪个集群（必须是已存在的 cluster name）
        &quot;targetName&quot;: &quot;c0&quot;,
       // 分片表定义（重点！）
        &quot;shardingTables&quot;: {
               // 逻辑表名：应用程序写 INSERT INTO user_order_db.order_info ...
                &quot;order_info&quot;: {
                       // 分片字段：按哪个字段计算分表（必须是 DATE 或 DATETIME 类型）
                        &quot;shardingKey&quot;: &quot;order_create_date&quot;,
                       // 分片算法类：Mycat2 内置的按日期分片函数
                        &quot;shardingClass&quot;: &quot;io.mycat.router.function.PartitionByDate&quot;,
                        // 分片算法参数
                        &quot;shardingProperties&quot;: {
                               // 日期格式，必须与字段存储格式一致
                                &quot;dateFormat&quot;: &quot;yyyy-MM-dd&quot;,
                               // 分片起始日期（用于计算偏移量）
                                &quot;sBeginDate&quot;: &quot;2025-01-01&quot;,
                               // 每个分片包含多少天（30 ≈ 1个月）
                                &quot;sPartionDay&quot;: &quot;30&quot;,
                               // 总共分多少个表（这里设12，对应12个月）
                                &quot;partitionCount&quot;: &quot;12&quot;
                        },
                       // 表类型：SHARDING 表示分片表
                        &quot;tableType&quot;: &quot;SHARDING&quot;,
                       // 物理表的基础名（Mycat2 会自动拼接后缀，如 order_info_0, order_info_1...）
                       // 注意：实际物理表名需手动创建为 order_info_202501 等，但 Mycat2 默认用数字后缀
                       // 所以我们后面会通过“预建表 + 修改命名规则”或接受数字后缀
                        &quot;tableName&quot;: &quot;order_info&quot;
                }
        },
       // 视图定义，此处为空
        &quot;views&quot;:{}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;八、作业&lt;/h2&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Mycat 是用于 MySQL 分库分表的数据库中间件，以下关于 Mycat 分库分表原理的描述，错误的是（ C ）
A. Mycat 位于应用层和数据库之间，接收应用请求
B. SQL 解析引擎主要负责判断是否需要分库分表
C. 路由层根据分片规则和算法，将 SQL 语句发往所有数据库分片
D. 后端连接池管理数据库连接，处理结果后返回给用户&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;**A. Mycat 位于应用层和数据库之间，接收应用请求**  
✅ 正确。  
Mycat 是一个数据库中间件，部署在应用和数据库之间，对应用透明，接收来自应用的 SQL 请求，再转发到后端 MySQL 实例。

**B. SQL 解析引擎主要负责判断是否需要分库分表**  
✅ 基本正确。  
Mycat 的 SQL 解析模块会解析 SQL 语句，结合配置的 schema 和分片规则，判断该 SQL 是否涉及分片表，从而决定是否需要进行分库分表路由。

**C. 路由层根据分片规则和算法，将 SQL 语句发往所有数据库分片**  
⚠️ **此处有陷阱。**  
路由层确实根据分片规则（如取模、范围、一致性哈希等）决定 SQL 应该发往**哪些**分片，但**不是“所有”数据库分片**。  
- 对于带分片键的查询（如 WHERE user_id = 100），通常只路由到**一个或部分分片**。
- 只有在**未带分片键**的查询（如全表扫描）时，才会广播到**所有分片**。

因此，说“将 SQL 语句发往所有数据库分片”是**以偏概全**，**不准确**。  
所以 **C 选项描述错误**。

**D. 后端连接池管理数据库连接，处理结果后返回给用户**  
✅ 正确。  
Mycat 使用连接池管理与后端 MySQL 的连接，执行 SQL 后收集结果，进行**结果合并**（如排序、分页、聚合等），然后返回给客户端。  
虽然“处理结果”主要是由**结果合并/处理模块**完成，但连接池配合执行并获取结果，整体流程描述不算错误。

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;在配置 Mycat 数据源时，添加 MySQL59 作为数据源的语句是（ A ）
A. &lt;code&gt;/*+ mycat:createdatasource{&quot;name&quot;:&quot;dw0&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.90.59:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;&lt;/code&gt;
B. &lt;code&gt;/*+ mycat:createdatasource{&quot;name&quot;:&quot;dw1&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.90.61:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;&lt;/code&gt;
C. &lt;code&gt;/*+ mycat:createdatasource{&quot;name&quot;:&quot;dr0&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.90.60:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;&lt;/code&gt;
D. &lt;code&gt;/*+ mycat:createdatasource{&quot;name&quot;:&quot;dr1&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.90.62:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;以下关于 Mycat 分库分表策略中全局表的描述，正确的是（ C ）
A. 全局表数据只会插入到一个库中
B. 全局表数据会插入到两个库中，但只有一个库有全部数据
C. 全局表数据会插入到两个库中，并且两个库中都有全部的数据
D. 全局表数据不会存储在任何数据库中&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在配置 Mycat 登录账号密码时，修改的文件是（ B ）
A. &lt;code&gt;/usr/local/mycat/conf/datasources/prototypeDs.datasource.json&lt;/code&gt;
B. &lt;code&gt;/usr/local/mycat/conf/users/root.user.json&lt;/code&gt;
C. &lt;code&gt;/usr/local/mycat/conf/clusters/prototype.cluster.json&lt;/code&gt;
D. &lt;code&gt;/usr/local/mycat/conf/schemas/moershi.schema.json&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;对于 Mycat 中的 ER 表（关联表），以下说法错误的是（ B ）
A. ER 表表示数据逻辑上有关联性的两个或多个表
B. 在 MyCat2 中对于关联表，需要有过多的声明
C. 关联表通常希望有相同的分片规则，以便进行关联查询
D. 可以通过 &lt;code&gt;/*+ mycat:showErGroup{}*/&lt;/code&gt; 查看关联表关系&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;简述 Mycat 实现分库分表的整体流程。
答：
1、mycat作为中间层，链接双主双从或多主多从数据库。
2、应用层连接mycat数据库，执行创建插入命令，由SQL解析引擎解析SQL，判断是否需分库分表。
3、mycat服务对分片键值进行hash或其他算法计算，再依据分片规则和算法，决定将SQL发往不同分片。
4、后端连接池管理数据库连接，处理合并结果后返回给用户。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;	### 简述 Mycat 实现分库分表的整体流程：
	
	1. **架构定位**：Mycat 作为数据库中间件，部署在应用层与后端 MySQL 集群（如主从、多主或多分片）之间，对应用透明，提供统一的逻辑数据库视图。
	2. **接收请求**：应用通过 JDBC/MySQL 协议连接 Mycat，发送 SQL 语句（如 INSERT、SELECT 等）。
	3. **SQL 解析**：Mycat 的 SQL 解析引擎对 SQL 进行词法和语法分析，识别操作的表、字段、条件等，并结合 `schema.xml`（Mycat 1.x）或 `schema.json`（Mycat 2.x）中的配置，判断该表是否为分片表。
	4. **路由决策**：
	   - 若为分片表，Mycat 提取 SQL 中的**分片键**（如 WHERE user_id = 100）；
	   - 根据预定义的**分片规则**（如取模、范围、一致性哈希等），计算目标分片（dataNode）；
	   - 若未带分片键，则可能广播到所有分片（全表扫描）。
	1. **执行与结果合并**：
	   - Mycat 通过后端连接池将 SQL 路由到一个或多个真实 MySQL 节点执行；
	   - 收集各分片返回的结果，在 Mycat 内部进行**结果合并**（如排序、分页、聚合等）；
	   - 将最终结果返回给应用。
	1. **全局表与 ER 表处理**（补充）：
	   - 全局表：写入时同步到所有分片，读取时任选一个分片；
	   - ER 表：子表按父表分片键共置，确保关联查询在单分片内完成。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;请说明在配置 MySQL 二主二从时，主服务器和从服务器分别需要进行哪些关键配置步骤。
答：
1、主服务器配置文件添加唯一server-id、开启binlog选项
2、主服务数据库创建用于同步的账号和权限
3、从服务器添加唯一server-id
4、从数据库上绑定主服务器IP、同步账号密码、binlog信息、偏移量，start slave开启同步&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;	
	### 2. 请说明在配置 MySQL 二主二从时，主服务器和从服务器分别需要进行哪些关键配置步骤。
	
	#### 一、主服务器（Master）的关键配置步骤（每台主库都要独立配置）：
	
	1. 修改 MySQL 配置文件（如 `/etc/my.cnf` 或 `/etc/mysql/mysql.conf.d/mysqld.cnf`）：
	   - 设置唯一的 `server-id`（例如：主1设为 1，主2设为 2）；
	   - 开启二进制日志：`log-bin = mysql-bin`；
	   - （推荐）设置 `binlog-format = ROW`（提高数据一致性）；
	   - 启用自动递增偏移，避免双主写入冲突：
	
	     auto-increment-increment = 2   # 每次自增步长为2
	     auto-increment-offset = 1      # 主1从1开始；主2设为2
	
	   - 可选：设置 `log-slave-updates = ON`（使主库能将接收到的 relay log 再写入自己的 binlog，用于级联复制）；
	   - 可选：设置 `replicate-same-server-id = 0`（防止环路）。
	
	1. 创建用于复制的专用账号：
	
	   CREATE USER &apos;repl&apos;@&apos;%&apos; IDENTIFIED BY &apos;repl_password&apos;;
	   GRANT REPLICATION SLAVE ON *.* TO &apos;repl&apos;@&apos;%&apos;;
	   FLUSH PRIVILEGES;
	
	
	2. 记录当前 binlog 文件名和位置（Position）：
	
	   FLUSH TABLES WITH READ LOCK;  -- （可选，确保一致性）
	   SHOW MASTER STATUS;
	
	   记录 `File` 和 `Position`，供从库配置使用。
	
	---
	
	#### 二、从服务器（Slave）的关键配置步骤（每个从库对应一个主库）：
	
	1. 修改 MySQL 配置文件：
	   - 设置唯一的 `server-id`（如从1设为 3，从2设为 4）；
	   - 建议开启 `relay-log = mysql-relay-bin`（默认开启）；
	   - 若需级联或监控，可开启 `read_only = ON`（防止误写）。
	
	1. 配置主从复制关系：
	   在从库执行：
	 
	   CHANGE MASTER TO
	     MASTER_HOST=&apos;主库IP&apos;,
	     MASTER_USER=&apos;repl&apos;,
	     MASTER_PASSWORD=&apos;repl_password&apos;,
	     MASTER_LOG_FILE=&apos;mysql-bin.000001&apos;,   -- 来自主库 SHOW MASTER STATUS
	     MASTER_LOG_POS=154;                   -- 对应 Position
	 
	
	2. 启动复制线程：
	 
	   START SLAVE;
	 
	
	1. 验证复制状态：
	 
	   SHOW SLAVE STATUS\G
	 
	   确保 `Slave_IO_Running: Yes` 且 `Slave_SQL_Running: Yes`，无错误。
	
	---
	
	#### 三、特别说明：二主互为主从（双主）配置
	
	- 主1 是 主2 的从库，主2 也是 主1 的从库；
	- 因此，每台主服务器既要配置为 Master（提供 binlog），也要配置为 Slave（连接对方）；
	- 必须通过 `auto-increment-offset` 和 `auto-increment-increment` 避免自增 ID 冲突；
	- 建议应用层写入只走一台主库（避免循环复制或数据冲突），或使用 Mycat 等中间件控制写入路由。

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;解释 Mycat 分库分表策略中全局表、分片表和 ER 表的区别。
答：
全局表：数据会插入到分片库中，并且所有的分片库中都有全部的数据。
分片表：数据会根据分片规则和算法,分别写入不同的分片库。
ER 表： 作为分片表的子表，其数据按照父表的分片键进行共置存储，确保父子数据位于同一分片，从而支持高效关联查询。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;	### 建议修正后的答案：
  	全局表：在所有分片中都存储完整的全量数据，写入时同步到所有分片，用于支持本地 JOIN。  
  	分片表：数据根据分片规则（如取模、范围等）水平拆分，不同记录存储在不同分片中。  
  	ER 表：作为分片表的子表，其数据按照父表的分片键进行共置存储，确保父子数据位于同一分片，从而支持高效关联查询。
	
	### 对比总结：
	| 类型     | 数据分布                     | 写入方式           | 主要用途                     |
	|----------|------------------------------|--------------------|------------------------------|
	| 全局表   | 所有分片都有完整副本     | 广播写入所有分片   | 小表、频繁 JOIN              |
	| 分片表   | 数据分散在不同分片       | 按分片键路由写入   | 大表水平拆分                 |
	| ER 表    | 与父表共置在同一分片     | 跟随父表位置写入   | 子表与父表本地关联           |
	
	#### 1. 全局表（Global Table）
	- 定义：数据量小、变动少、需频繁与其他表关联的表（如字典表、配置表）。
	- 存储方式：在所有分片（dataNode）中都保存完整的全量数据副本。
	- 写入行为：插入/更新/删除操作会同步广播到所有分片，保证数据一致性。
	- 查询优势：可与任意分片表在本地进行 JOIN，避免跨库关联。
	
	#### 2. 分片表（Sharding Table / Partitioned Table）
	- 定义：数据量大、需要水平拆分的表。
	- 存储方式：数据按分片规则（如取模、范围、哈希等）分散存储在不同分片中，每个分片只存一部分数据。
	- 路由依据：依赖 SQL 中是否包含分片键（sharding key）。若包含，则精准路由；否则可能全分片扫描。
	- 典型场景：用户表、订单表等。
	
	#### 3. ER 表（E-R 关系表 / Child Table）
	- 定义：与另一张分片表存在父子关系的表（如订单明细表是订单表的子表）。
	- 核心机制：子表采用与父表相同的分片规则，并以父表的分片键作为自己的分片依据，从而确保父子记录落在同一个分片。
	- 目的：实现本地关联查询，避免跨分片 JOIN。
	- 配置要求：需在 Mycat 配置中声明父子关系（如 Mycat1 的 `&amp;lt;childTable&amp;gt;`，Mycat2 的 `joinKey`/`parentKey`）。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;当使用 Mycat 进行分库分表时，如果遇到数据不一致的问题，可能的原因有哪些？
答：
1、检查mycat配置，包括不限于mycat配置的数据源、集群信息、分库分表规则。
2、检查是否有更新mycat配置，但没有重启服务或加载失败。
3、检查sql语句是否使用不当。
4、检查后端mysql主从配置和主从到mycat是否有延迟或网址不通，导致返回数据缺失。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;	### 一、Mycat 配置层面的问题
			#### 1. 分片规则配置错误
		- 分片字段（sharding key）与实际 SQL 中使用的字段不一致；
		- 分片算法（如取模、范围）配置错误，导致相同逻辑数据被路由到不同分片；
		- 多租户或 schema 配置混淆，写入了错误的逻辑库。
		**数据源（DataSource）或集群（Cluster）配置错误**：指向了错误的 IP、端口、数据库名，或主从角色混淆
		
	  	📌 示例：用户 ID 为 100 的记录本应落在分片 0，但因算法写错，被写入分片 1，后续按 ID 查询时无法命中。
		
		#### 2. 全局表未正确配置
		- 应设为全局表的字典表被误配为普通分片表，导致部分分片缺少数据；
		- 全局表写入时 Mycat 广播失败（如某个分片连接异常），造成副本不一致。
		
		#### 3. ER 表关系未正确声明
		- 子表未正确关联父表分片键，导致父子数据不在同一分片；
		- JOIN 查询时 Mycat 无法本地关联，转而执行跨分片合并，但合并逻辑出错或遗漏数据。
	
	### 二、SQL 使用不当
			#### 4. 未带分片键的查询（全表扫描）
		- 执行 `SELECT * FROM user WHERE name = &apos;张三&apos;`（name 非分片键）；
		- Mycat 广播到所有分片，但某些分片因网络超时、连接池满等原因未返回结果，导致数据“看起来”缺失。
		
		#### 5. 跨分片事务未正确处理
		- Mycat 默认不支持分布式事务（除非集成 XA 或 Seata）；
		- 应用开启事务后向多个分片写入，若部分分片失败而其他成功，造成部分提交，数据不一致。
		
		#### 6. 自增主键冲突（尤其在双主或多写场景）
		- 多个 MySQL 实例使用相同 auto_increment 策略，导致主键重复；
		- 虽然 Mycat 可路由，但底层数据库插入失败或覆盖数据。
	 
	### 三、后端 MySQL 集群问题 
		#### 7. 主从复制延迟或中断
		- Mycat 读写分离配置下，读请求路由到从库；
		- 若从库存在复制延迟，会读到旧数据，看似“不一致”；
		- 若 `Slave_IO_Running` 或 `Slave_SQL_Running` 为 No，则完全不同步。
		- **主从延迟（Replication Lag）**：Mycat 配置了读写分离，读请求路由到从库，但从库尚未同步最新数据，返回旧值；
		- **主从同步中断**：`SHOW SLAVE STATUS` 显示 `Slave_IO_Running` 或 `Slave_SQL_Running` 为 `No`，导致从库数据长期不一致；
		- **网络不通或防火墙限制**：Mycat 无法连接某个分片（尤其是从库），在广播查询时跳过该节点，造成数据“看起来”缺失。
		  
		#### 8. MySQL 实例数据被绕过 Mycat 直接修改
		- DBA 或应用直接连接后端 MySQL 修改数据；
		- Mycat 无感知，导致其元数据或缓存与实际数据不符。
		
		#### 9. binlog 格式或 GTID 配置不一致
		- 在高可用切换或级联复制中，若 binlog_format 不统一（如 MIXED vs ROW），可能导致复制异常。 
	
	### 四、Mycat 自身机制限制 
		#### 10. 结果合并（Merge）逻辑缺陷
		- 对 `ORDER BY + LIMIT`、`GROUP BY`、`COUNT(*)` 等聚合操作，Mycat 需在内存中合并各分片结果；
		- 若分页偏移量大或数据分布不均，可能漏算或重复计算。
		
		#### 11. 连接池或会话状态残留
		- 某个分片连接异常断开后未重置，后续请求复用脏连接；
		- 临时表、会话变量等状态影响查询结果。
		
		#### 12. Mycat 版本 Bug
		- 某些旧版本存在 SQL 解析错误、路由缓存失效等问题，导致错误路由。 
	
	### 五、运维与部署问题 
		#### 13. 配置未热加载或加载失败
		- 修改 `schema.xml` 或 JSON 配置后未执行 `reload @@config`；
		- Mycat 仍在使用旧规则，导致新写入数据位置错误。
		
		#### 14. 时间/时区不一致
		- 各 MySQL 节点系统时间不同步，影响基于时间的分片规则（如按天分表）；
		- 应用与数据库时区设置不一致，导致条件判断偏差。 
	
	### ✅ 排查建议 
	1. 确认是否真不一致：直接登录各分片 MySQL 查询原始数据；
	2. 检查 Mycat 日志：`mycat.log` 中查看 SQL 路由目标、执行结果；
	3. 验证分片规则：使用 `EXPLAIN` 或 `/*+ mycat:sql=...*/` 查看路由计划；
	4. 监控主从状态：定期检查 `SHOW SLAVE STATUS`；
	5. 避免直连后端库：所有 DML 必须通过 Mycat；
	6. 测试边界场景：如无分片键查询、跨分片事务、大数据量分页等。 
	
	### 总结 
	数据不一致往往是 “配置 + 使用 + 运维” 多因素叠加的结果。  
	核心原则：  
  	确保“写入路径可控、读取路径可预期、副本同步可靠”。 
	通过规范配置、合理设计分片策略、避免跨分片复杂操作，并加强监控，可大幅降低数据不一致风险。
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;描述在 Mycat 中创建集群的步骤以及集群信息的查看方法。
答：
添加数据源：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;	mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;主数据源名称&quot;, &quot;url&quot;:&quot;jdbc:mysql://IP:端口&quot;,&quot;user&quot;:&quot;用户名&quot;,&quot;password&quot;:&quot;密码&quot;}*/;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;创建集群命令：
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;	mysql&amp;gt; /*!mycat:createcluster{&quot;name&quot;:&quot;集群名&quot;,&quot;masters&quot;:[&quot;主数据源名称&quot;],&quot;replicas&quot;:[&quot;从数据源名称&quot;]}*/;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;查看集群命令：
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;	mysql&amp;gt; /*+ mycat:showClusters{}*/ \G
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;	#### 一、创建集群的步骤
	
	1. **前提条件**：
	   - 已通过 `createdatasource` 命令或配置文件预先定义好**主数据源（master）** 和**从数据源（replica）**；
	   - Mycat 配置中已启用动态管理功能（如 `enableClusterManagement=true`）。
	
	1. **使用 SQL Hint 动态创建集群**：
	 
	   /*!mycat:createCluster{&quot;name&quot;:&quot;cluster1&quot;,&quot;masters&quot;:[&quot;ds_master&quot;],&quot;replicas&quot;:[&quot;ds_slave1&quot;,&quot;ds_slave2&quot;]}*/;
	 
	   - `name`：集群名称（如 `cluster1`）；
	   - `masters`：主数据源名称列表（通常一个，支持多主）；
	   - `replicas`：从数据源名称列表（可为空或多个）；
	   - **注意**：
	     - 关键字是 `createCluster`（首字母大写 C），不是 `createcluster`；
	     - 注释语法为 `/*!mycat:...*/`（非 `/*+ ... */`，后者用于查询类 hint）；
	     - 数据源名称必须与已存在的数据源（如 `prototypeDs.datasource.json` 中定义的 `name`）一致。
	
	1. **验证集群是否生效**：
	   - 可通过后续的 `showClusters` 查看；
	   - 或在 `conf/clusters/` 目录下生成对应的 `.cluster.json` 文件（若启用了持久化）。
	
	---
	
	#### 二、查看集群信息的方法
	
	执行以下 SQL 查看当前所有集群的配置信息：
	 
	/*+ mycat:showClusters{} */;
	 
	- 使用 `/*+ ... */` 语法（这是查询类 hint 的标准格式）；
	- 返回结果为 JSON 格式，包含每个集群的名称、主库、从库等信息；
	- 在 MySQL 客户端中可加 `\G` 美化输出：
	 
	  /*+ mycat:showClusters{} */\G
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3 操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;请详细描述在 Linux 系统上安装和配置 Mycat 以实现 MySQL 分库分表的完整步骤，包括机器准备、Mycat 安装部署、登录账号密码配置、连接本机数据库配置等。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;# 配置双主双从mysql服务
	## 安装mysql服务
	[root@mysql59 ~]# yum -y install rpm/*
	[root@mysql60 ~]# yum -y install rpm/*
	[root@mysql61 ~]# yum -y install rpm/*
	[root@mysql62 ~]# yum -y install rpm/*
	[root@mycat63 ~]# yum -y install rpm/*
	
	## mysql59主 -1 配置
	[root@mysql59 ~]# vim /etc/my.cnf
	[root@mysql59 ~]# grep -vE &quot;^\s*(#|$)&quot; /etc/my.cnf
	[mysqld]
	server-id=59
	log-bin=mysql59
	skip-name-resolve
	datadir=/var/lib/mysql
	socket=/var/lib/mysql/mysql.sock
	log-error=/var/log/mysqld.log
	pid-file=/var/run/mysqld/mysqld.pid
	
	[root@mysql59 ~]# systemctl restart mysqld
	[root@mysql59 ~]# cat /var/log/mysqld.log | grep &quot;password&quot;
	2025-12-08T10:10:36.085359Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: Qoy.ifK+S8Dq
	[root@mysql59 ~]# mysql -uroot -p
	Enter password: 
	mysql&amp;gt; # 创建同步账号
	mysql&amp;gt; create user repluser@&quot;%&quot; identified by &quot;repluser&quot;; 
	Query OK, 0 rows affected (0.03 sec)
	mysql&amp;gt; grant replication slave on *.* to repluser@&quot;%&quot;;
	Query OK, 0 rows affected (0.01 sec)
	mysql&amp;gt; show master status;
	+----------------+----------+--------------+------------------+-------------------+
	| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
	+----------------+----------+--------------+------------------+-------------------+
	| mysql59.000001 |      157 |              |                  |                   |
	+----------------+----------+--------------+------------------+-------------------+
	1 row in set (0.00 sec)
	
	
	## mysql60从 -1 配置
	[root@mysql60 ~]# vim /etc/my.cnf
	[root@mysql60 ~]# grep -vE &quot;^\s*(#|$)&quot; /etc/my.cnf
	[mysqld]
	server-id=60
	datadir=/var/lib/mysql
	socket=/var/lib/mysql/mysql.sock
	log-error=/var/log/mysqld.log
	pid-file=/var/run/mysqld/mysqld.pid
	
	[root@mysql60 ~]# systemctl restart mysqld
	[root@mysql60 ~]# cat /var/log/mysqld.log | grep &quot;password&quot;
	2025-12-08T10:14:18.739995Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: c!EY*oQxd70x
	[root@mysql60 ~]# mysql -uroot -p
	Enter password: 
	mysql&amp;gt; # 同步信息设置
	mysql&amp;gt; change master to master_host=&quot;192.168.88.59&quot;,master_user=&quot;repluser&quot;,master_password=&quot;repluser&quot;,master_log_file=&quot;mysql59.000001&quot;,master_log_pos=157;
	Query OK, 0 rows affected, 8 warnings (0.07 sec)
	
	mysql&amp;gt; start slave;
	Query OK, 0 rows affected, 1 warning (0.03 sec)
	
	mysql&amp;gt; show slave status \G
	........
	             Slave_IO_Running: Yes
	            Slave_SQL_Running: Yes
	
	
	## mysql61主 -2 配置
	[root@mysql61 ~]# vim /etc/my.cnf
	[root@mysql61 ~]# grep -vE &quot;^\s*(#|$)&quot; /etc/my.cnf
	[mysqld]
	server-id=61
	log-bin=mysql61
	datadir=/var/lib/mysql
	socket=/var/lib/mysql/mysql.sock
	log-error=/var/log/mysqld.log
	pid-file=/var/run/mysqld/mysqld.pid
	
	[root@mysql61 ~]# systemctl restart mysqld
	[root@mysql61 ~]# cat /var/log/mysqld.log | grep &quot;password&quot;
	2025-12-08T10:14:14.653868Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: gfMx)wwS4q;O
	[root@mysql61 ~]# mysql -uroot -p
	Enter password: 
	mysql&amp;gt; # 创建同步账号
	mysql&amp;gt; create user repluser@&quot;%&quot; identified by &quot;repluser&quot;; 
	Query OK, 0 rows affected (0.02 sec)
	mysql&amp;gt; grant replication slave on *.* to repluser@&quot;%&quot;;
	Query OK, 0 rows affected (0.01 sec)
	mysql&amp;gt; show master status;
	+----------------+----------+--------------+------------------+-------------------+
	| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
	+----------------+----------+--------------+------------------+-------------------+
	| mysql61.000001 |     1335 |              |                  |                   |
	+----------------+----------+--------------+------------------+-------------------+
	1 row in set (0.00 sec)
	
	
	## mysql62从 -2 配置
	[root@mysql62 ~]# vim /etc/my.cnf
	[root@mysql62 ~]# grep -vE &quot;^\s*(#|$)&quot; /etc/my.cnf
	[mysqld]
	server-id=62
	datadir=/var/lib/mysql
	socket=/var/lib/mysql/mysql.sock
	log-error=/var/log/mysqld.log
	pid-file=/var/run/mysqld/mysqld.pid
	
	[root@mysql62 ~]# systemctl restart mysqld
	[root@mysql62 ~]# cat /var/log/mysqld.log | grep &quot;password&quot;
	2025-12-08T10:14:21.247397Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: &amp;lt;MZxFHKt!1ql
	[root@mysql62 ~]# mysql -uroot -p
	Enter password: 
	mysql&amp;gt; # 同步信息设置
	mysql&amp;gt; change master to master_host=&quot;192.168.88.61&quot;,master_user=&quot;repluser&quot;,master_password=&quot;repluser&quot;,master_log_file=&quot;mysql61.000001&quot;,master_log_pos=1335;
	Query OK, 0 rows affected, 8 warnings (0.06 sec)
	mysql&amp;gt; start slave;
	Query OK, 0 rows affected, 1 warning (0.03 sec)
	mysql&amp;gt; show slave status \G
	.......
	             Slave_IO_Running: Yes
	            Slave_SQL_Running: Yes

# mycat服务部署
	## mycat环境
	[root@mycat63 ~]# yum -y install java-1.8.0-openjdk.x86_64 &amp;amp;&amp;gt;/dev/null 
	[root@mycat63 ~]# echo $?
	0
	[root@mycat63 ~]# unzip mycat2-install-template-1.21.zip &amp;amp;&amp;gt;/dev/null 
	[root@mycat63 ~]# mv mycat /usr/local/
	[root@mycat63 ~]# mv mycat2-1.21-release-jar-with-dependencies.jar /usr/local/mycat/lib/
	[root@mycat63 ~]# chmod -R 777 /usr/local/mycat/
	
	## 配置mycat 登录账号密码
	[root@mycat63 ~]# vim  /usr/local/mycat/conf/users/root.user.json
	[root@mycat63 ~]# cat  /usr/local/mycat/conf/users/root.user.json
	{
	        &quot;dialect&quot;:&quot;mysql&quot;,
	        &quot;ip&quot;:null,
	        &quot;password&quot;:&quot;654321&quot;,
	        &quot;transactionType&quot;:&quot;proxy&quot;,
	        &quot;username&quot;:&quot;mycat&quot;
	}
	
	## 配置mycat 连接本机数据库
	[root@mycat63 ~]# vim /usr/local/mycat/conf/datasources/prototypeDs.datasource.json
	[root@mycat63 ~]# cat /usr/local/mycat/conf/datasources/prototypeDs.datasource.json
	{
	        &quot;dbType&quot;:&quot;mysql&quot;,
	        &quot;idleTimeout&quot;:60000,
	        &quot;initSqls&quot;:[],
	        &quot;initSqlsGetConnection&quot;:true,
	        &quot;instanceType&quot;:&quot;READ_WRITE&quot;,
	        &quot;maxCon&quot;:1000,
	        &quot;maxConnectTimeout&quot;:3000,
	        &quot;maxRetryCount&quot;:5,
	        &quot;minCon&quot;:1,
	        &quot;name&quot;:&quot;prototypeDs&quot;,
	        &quot;password&quot;:&quot;123456&quot;,
	        &quot;type&quot;:&quot;JDBC&quot;,
	        &quot;url&quot;:&quot;jdbc:mysql://localhost:3306/mysql?useUnicode=true&amp;amp;serverTimezone=Asia/Shanghai&amp;amp;characterEncoding=UTF-8&quot;,
	        &quot;user&quot;:&quot;jam&quot;,
	        &quot;weight&quot;:0
	}
	
	## 安装mysql数据库配置账号
	[root@mycat63 ~]# systemctl restart mysqld
	[root@mycat63 ~]# cat /var/log/mysqld.log | grep &quot;password&quot;
	2025-12-08T10:14:10.214571Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: %6aj01&amp;gt;iV#Bb
	[root@mycat63 ~]# mysql -uroot -p123
	Enter password: 
	mysql&amp;gt; # 创建jam用户
	mysql&amp;gt; create user jam@&quot;%&quot; identified by &quot;123456&quot;;
	Query OK, 0 rows affected (0.02 sec)
	mysql&amp;gt; grant all on *.* to jam@&quot;%&quot;;
	Query OK, 0 rows affected (0.01 sec)
	mysql&amp;gt;
	
	## mycat 配置数据源
	[root@mycat63 ~]# /usr/local/mycat/bin/mycat start
	Starting mycat2...
	[root@mycat63 ~]# netstat  -utnlp  | grep 8066
	tcp6       0      0 :::8066                 :::*                    LISTEN      16588/java          
	[root@mycat63 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321
	mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;dw0&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.59:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
	Query OK, 0 rows affected (0.33 sec)
	mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;dr0&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.60:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
	Query OK, 0 rows affected (0.04 sec)
	mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;dw1&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.61:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
	Query OK, 0 rows affected (0.02 sec)
	mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;dr1&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.62:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
	Query OK, 0 rows affected (0.01 sec)
	mysql&amp;gt; /*+ mycat:showDataSources{}*/ \G
	*************************** 1. row ***************************
	                   NAME: dr1
	               USERNAME: jam
	               PASSWORD: 123456
	 ......
	                DB_TYPE: mysql
	                    URL: jdbc:mysql://192.168.88.62:3306?useUnicode=true&amp;amp;serverTimezone=Asia/Shanghai&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
	......
	*************************** 2. row ***************************
	                   NAME: dr0
	               USERNAME: jam
	               PASSWORD: 123456
	......
	                DB_TYPE: mysql
	                    URL: jdbc:mysql://192.168.88.60:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
	......
	*************************** 3. row ***************************
	                   NAME: prototypeDs
	               USERNAME: jam
	               PASSWORD: 123456
	......
	                DB_TYPE: mysql
	                    URL: jdbc:mysql://localhost:3306/mysql?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
	......
	*************************** 4. row ***************************
	                   NAME: dw1
	               USERNAME: jam
	               PASSWORD: 123456
	......
	                DB_TYPE: mysql
	                    URL: jdbc:mysql://192.168.88.61:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
	......
	*************************** 5. row ***************************
	                   NAME: dw0
	               USERNAME: jam
	               PASSWORD: 123456
	......
	                DB_TYPE: mysql
	                    URL: jdbc:mysql://192.168.88.59:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
	......
	
	## 在59和61双主服务器上添加mycat 连接使用的jam用户
	mysql&amp;gt; create user jam@&quot;%&quot; identified by &quot;123456&quot;;
	Query OK, 0 rows affected (0.01 sec)
	mysql&amp;gt; grant all on *.* to jam@&quot;%&quot;;
	Query OK, 0 rows affected (0.01 sec)
	
	## 创建集群
	[root@mycat63 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321
	mysql&amp;gt; # mycat63服务器
	mysql&amp;gt; /*! mycat:createcluster{&quot;name&quot;:&quot;c0&quot;,&quot;masters&quot;:[&quot;dw0&quot;],&quot;replicas&quot;:[&quot;dr0&quot;]}*/;
	Query OK, 0 rows affected (0.06 sec)
	
	mysql&amp;gt; /*! mycat:createcluster{&quot;name&quot;:&quot;c1&quot;,&quot;masters&quot;:[&quot;dw1&quot;],&quot;replicas&quot;:[&quot;dr1&quot;]}*/;
	Query OK, 0 rows affected (0.02 sec)
	
	mysql&amp;gt; /*+ mycat:showClusters{}*/ \G
	*************************** 1. row ***************************
	             NAME: prototype
	      SWITCH_TYPE: SWITCH
	MAX_REQUEST_COUNT: 200
	             TYPE: BALANCE_ALL
	         WRITE_DS: prototypeDs
	          READ_DS: prototypeDs
	          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
	           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
	        AVAILABLE: true
	*************************** 2. row ***************************
	             NAME: c0
	      SWITCH_TYPE: SWITCH
	MAX_REQUEST_COUNT: 2000
	             TYPE: BALANCE_ALL
	         WRITE_DS: dw0
	          READ_DS: dw0,dr0
	          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
	           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
	        AVAILABLE: true
	*************************** 3. row ***************************
	             NAME: c1
	      SWITCH_TYPE: SWITCH
	MAX_REQUEST_COUNT: 2000
	             TYPE: BALANCE_ALL
	         WRITE_DS: dw1
	          READ_DS: dw1,dr1
	          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
	           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
	        AVAILABLE: true
	3 rows in set (0.01 sec)
	
	
	## mycat63 设置分片规则
	[root@mycat63 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321
	mysql&amp;gt; # 创建全局表
	mysql&amp;gt; create database moershi;
	Query OK, 0 rows affected (0.05 sec)
	
	mysql&amp;gt; create table moershi.dept(
	    -&amp;gt; dept_id int,
	    -&amp;gt; dept_name char(10),
	    -&amp;gt; primary key(dept_id)
	    -&amp;gt; )default charset utf8 broadcast;
	Query OK, 0 rows affected (1 min 0.14 sec)
	
	mysql&amp;gt; insert into moershi.dept values(1,&quot;开发部&quot;),(2,&quot;运维部&quot;),(3,&quot;测试部&quot;);
	Query OK, 1 row affected (0.10 sec)
	
	# 查看全局表
	[root@mycat63 ~]# mysql -h 192.168.88.59 -ujam -p123456 -e &quot;select * from moershi.dept;&quot; 
	+---------+-----------+
	| dept_id | dept_name |
	+---------+-----------+
	|       1 | 开发部    |
	|       2 | 运维部    |
	|       3 | 测试部    |
	+---------+-----------+
	[root@mycat63 ~]# mysql -h 192.168.88.60 -ujam -p123456 -e &quot;select * from moershi.dept;&quot; 
	+---------+-----------+
	| dept_id | dept_name |
	+---------+-----------+
	|       1 | 开发部    |
	|       2 | 运维部    |
	|       3 | 测试部    |
	+---------+-----------+
	[root@mycat63 ~]# mysql -h 192.168.88.61 -ujam -p123456 -e &quot;select * from moershi.dept;&quot; 
	+---------+-----------+
	| dept_id | dept_name |
	+---------+-----------+
	|       1 | 开发部    |
	|       2 | 运维部    |
	|       3 | 测试部    |
	+---------+-----------+
	[root@mycat63 ~]# mysql -h 192.168.88.62 -ujam -p123456 -e &quot;select * from moershi.dept;&quot; 
	+---------+-----------+
	| dept_id | dept_name |
	+---------+-----------+
	|       1 | 开发部    |
	|       2 | 运维部    |
	|       3 | 测试部    |
	+---------+-----------+
	
	
	
	# mycat63 创建分片表 以“employee_id”为分片点
	[root@mycat63 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321
	mysql&amp;gt;  create table moershi.employees(
	    -&amp;gt;  employee_id int primary key,
	    -&amp;gt;  name char(10),
	    -&amp;gt;  dept_id int,
	    -&amp;gt;  mail varchar(30)
	    -&amp;gt;  )default charset utf8
	    -&amp;gt;  dbpartition by mod_hash(employee_id) tbpartition by mod_hash(employee_id)
	    -&amp;gt;  tbpartitions 1 dbpartitions 2;
	Query OK, 1 row affected (1.04 sec)
	
	mysql&amp;gt; INSERT INTO moershi.employees VALUES (1, &apos;张三&apos;, 1, &apos;zhangsan@example.com&apos;),(2, &apos;李四&apos;, 2, &apos;lisi@example.com&apos;);
	Query OK, 2 rows affected (0.07 sec)
	
	# 查看分片表
	[root@mycat63 ~]# mysql -h 192.168.88.59 -ujam -p123456 -e &quot;select * from moershi_0.employees_0;&quot; 
	+-------------+--------+---------+------------------+
	| employee_id | name   | dept_id | mail             |
	+-------------+--------+---------+------------------+
	|           2 | 李四   |       2 | lisi@example.com |
	+-------------+--------+---------+------------------+
	[root@mycat63 ~]# mysql -h 192.168.88.60 -ujam -p123456 -e &quot;select * from moershi_0.employees_0;&quot; 
	+-------------+--------+---------+------------------+
	| employee_id | name   | dept_id | mail             |
	+-------------+--------+---------+------------------+
	|           2 | 李四   |       2 | lisi@example.com |
	+-------------+--------+---------+------------------+
	[root@mycat63 ~]# mysql -h 192.168.88.61 -ujam -p123456 -e &quot;select * from moershi_1.employees_1;&quot; 
	+-------------+--------+---------+----------------------+
	| employee_id | name   | dept_id | mail                 |
	+-------------+--------+---------+----------------------+
	|           1 | 张三   |       1 | zhangsan@example.com |
	+-------------+--------+---------+----------------------+
	[root@mycat63 ~]# mysql -h 192.168.88.62 -ujam -p123456 -e &quot;select * from moershi_1.employees_1;&quot; 
	+-------------+--------+---------+----------------------+
	| employee_id | name   | dept_id | mail                 |
	+-------------+--------+---------+----------------------+
	|           1 | 张三   |       1 | zhangsan@example.com |
	+-------------+--------+---------+----------------------+
	
	# 创建ER关联表
	
	[root@mycat63 ~]# mysql -h127.0.0.1 -P8066 -umycat -p654321
	mysql&amp;gt; create table moershi.salary (
	    -&amp;gt; employee_id int primary key,
	    -&amp;gt; p_date date , basic int,
	    -&amp;gt; bonus int 
	    -&amp;gt; ) default charset=utf8 
	    -&amp;gt; dbpartition by mod_hash(employee_id) dbpartitions 2
	    -&amp;gt; tbpartition by mod_hash(employee_id) tbpartitions 1;
	Query OK, 0 rows affected (0.19 sec)
	
	# 查看关联表关系
	mysql&amp;gt; /*+ mycat:showErGroup{}*/ ;
	+---------+------------+-----------+
	| groupId | schemaName | tableName |
	+---------+------------+-----------+
	| 0       | moershi    | employees |
	| 0       | moershi    | salary    |
	+---------+------------+-----------+
	2 rows in set (0.00 sec)
	
	# 数据插入
	mysql&amp;gt; insert into moershi.salary values (6,20230110,20000,2000),(7,20230210,25000,2500),(8,20230310,30000,3000),(9,20230410,35000,3500);
	Query OK, 4 rows affected (0.04 sec)
	
	# 数据验证
	[root@mycat63 ~]# mysql -h 192.168.88.59 -ujam -p123456 -e&quot;select * from moershi_0.salary_0;&quot; 
	+-------------+------------+-------+-------+
	| employee_id | p_date     | basic | bonus |
	+-------------+------------+-------+-------+
	|           6 | 2023-01-10 | 20000 |  2000 |
	|           8 | 2023-03-10 | 30000 |  3000 |
	+-------------+------------+-------+-------+
	[root@mycat63 ~]# mysql -h 192.168.88.60 -ujam -p123456 -e&quot;select * from moershi_0.salary_0;&quot; 
	+-------------+------------+-------+-------+
	| employee_id | p_date     | basic | bonus |
	+-------------+------------+-------+-------+
	|           6 | 2023-01-10 | 20000 |  2000 |
	|           8 | 2023-03-10 | 30000 |  3000 |
	+-------------+------------+-------+-------+
	[root@mycat63 ~]# mysql -h 192.168.88.61 -ujam -p123456 -e&quot;select * from moershi_1.salary_1;&quot; 
	+-------------+------------+-------+-------+
	| employee_id | p_date     | basic | bonus |
	+-------------+------------+-------+-------+
	|           7 | 2023-02-10 | 25000 |  2500 |
	|           9 | 2023-04-10 | 35000 |  3500 |
	+-------------+------------+-------+-------+
	[root@mycat63 ~]# mysql -h 192.168.88.62 -ujam -p123456 -e&quot;select * from moershi_1.salary_1;&quot;
	+-------------+------------+-------+-------+
	| employee_id | p_date     | basic | bonus |
	+-------------+------------+-------+-------+
	|           7 | 2023-02-10 | 25000 |  2500 |
	|           9 | 2023-04-10 | 35000 |  3500 |
	+-------------+------------+-------+-------+
	[root@mycat63 ~]# 

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;已知一个电商系统的订单表数据量较大，需要使用 Mycat 进行分库分表。假设按照订单创建时间进行分表，每个月的数据存于一个独立表，同时按照业务模块将订单数据库拆分为用户订单库、商品订单库等多个数据库。请写出具体的分库分表配置步骤和 SQL 语句。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
# 配置双主双从mysql服务
## 安装mysql服务
[root@mysql59 ~]# yum -y install rpm/*
[root@mysql60 ~]# yum -y install rpm/*
[root@mysql61 ~]# yum -y install rpm/*
[root@mysql62 ~]# yum -y install rpm/*
[root@mycat63 ~]# yum -y install rpm/*

## mysql59主 -1 配置
[root@mysql59 ~]# vim /etc/my.cnf
[root@mysql59 ~]# grep -vE &quot;^\s*(#|$)&quot; /etc/my.cnf
[mysqld]
server-id=59
log-bin=mysql59
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

[root@mysql59 ~]# systemctl restart mysqld
[root@mysql59 ~]# cat /var/log/mysqld.log | grep &quot;password&quot;
2025-12-08T10:10:36.085359Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: Qoy.ifK+S8Dq
[root@mysql59 ~]# mysql -uroot -p
Enter password: 
mysql&amp;gt; # 创建同步账号
mysql&amp;gt; create user repluser@&quot;%&quot; identified by &quot;repluser&quot;; 
Query OK, 0 rows affected (0.03 sec)
mysql&amp;gt; grant replication slave on *.* to repluser@&quot;%&quot;;
Query OK, 0 rows affected (0.01 sec)
mysql&amp;gt; show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql59.000001 |      157 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)


## mysql60从 -1 配置
[root@mysql60 ~]# vim /etc/my.cnf
[root@mysql60 ~]# grep -vE &quot;^\s*(#|$)&quot; /etc/my.cnf
[mysqld]
server-id=60
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

[root@mysql60 ~]# systemctl restart mysqld
[root@mysql60 ~]# cat /var/log/mysqld.log | grep &quot;password&quot;
2025-12-08T10:14:18.739995Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: c!EY*oQxd70x
[root@mysql60 ~]# mysql -uroot -p
Enter password: 
mysql&amp;gt; # 同步信息设置
mysql&amp;gt; change master to master_host=&quot;192.168.88.59&quot;,master_user=&quot;repluser&quot;,master_password=&quot;repluser&quot;,master_log_file=&quot;mysql59.000001&quot;,master_log_pos=157;
Query OK, 0 rows affected, 8 warnings (0.07 sec)

mysql&amp;gt; start slave;
Query OK, 0 rows affected, 1 warning (0.03 sec)

mysql&amp;gt; show slave status \G
........
	            Slave_IO_Running: Yes
	        Slave_SQL_Running: Yes


## mysql61主 -2 配置
[root@mysql61 ~]# vim /etc/my.cnf
[root@mysql61 ~]# grep -vE &quot;^\s*(#|$)&quot; /etc/my.cnf
[mysqld]
server-id=61
log-bin=mysql61
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

[root@mysql61 ~]# systemctl restart mysqld
[root@mysql61 ~]# cat /var/log/mysqld.log | grep &quot;password&quot;
2025-12-08T10:14:14.653868Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: gfMx)wwS4q;O
[root@mysql61 ~]# mysql -uroot -p
Enter password: 
mysql&amp;gt; # 创建同步账号
mysql&amp;gt; create user repluser@&quot;%&quot; identified by &quot;repluser&quot;; 
Query OK, 0 rows affected (0.02 sec)
mysql&amp;gt; grant replication slave on *.* to repluser@&quot;%&quot;;
Query OK, 0 rows affected (0.01 sec)
mysql&amp;gt; show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql61.000001 |     1335 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)


## mysql62从 -2 配置
[root@mysql62 ~]# vim /etc/my.cnf
[root@mysql62 ~]# grep -vE &quot;^\s*(#|$)&quot; /etc/my.cnf
[mysqld]
server-id=62
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

[root@mysql62 ~]# systemctl restart mysqld
[root@mysql62 ~]# cat /var/log/mysqld.log | grep &quot;password&quot;
2025-12-08T10:14:21.247397Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: &amp;lt;MZxFHKt!1ql
[root@mysql62 ~]# mysql -uroot -p
Enter password: 
mysql&amp;gt; # 同步信息设置
mysql&amp;gt; change master to master_host=&quot;192.168.88.61&quot;,master_user=&quot;repluser&quot;,master_password=&quot;repluser&quot;,master_log_file=&quot;mysql61.000001&quot;,master_log_pos=1335;
Query OK, 0 rows affected, 8 warnings (0.06 sec)
mysql&amp;gt; start slave;
Query OK, 0 rows affected, 1 warning (0.03 sec)
mysql&amp;gt; show slave status \G
.......
	            Slave_IO_Running: Yes
	        Slave_SQL_Running: Yes

# mycat服务部署
## mycat环境
[root@mycat63 ~]# yum -y install java-1.8.0-openjdk.x86_64 &amp;amp;&amp;gt;/dev/null 
[root@mycat63 ~]# echo $?
0
[root@mycat63 ~]# unzip mycat2-install-template-1.21.zip &amp;amp;&amp;gt;/dev/null 
[root@mycat63 ~]# cp -r mycat /usr/local/
[root@mycat63 ~]# cp -r mycat2-1.21-release-jar-with-dependencies.jar /usr/local/mycat/lib/
[root@mycat63 ~]# chmod -R 777 /usr/local/mycat/

## 配置mycat 登录账号密码
[root@mycat63 ~]# vim /usr/local/mycat/conf/users/root.user.json
[root@mycat63 ~]# cat /usr/local/mycat/conf/users/root.user.json
{
	    &quot;dialect&quot;:&quot;mysql&quot;,
	    &quot;ip&quot;:null,
	    &quot;password&quot;:&quot;123456&quot;,
	    &quot;transactionType&quot;:&quot;proxy&quot;,
	    &quot;username&quot;:&quot;mycat&quot;
}

## 配置mycat 连接本机数据库
[root@mycat63 ~]# vim /usr/local/mycat/conf/datasources/prototypeDs.datasource.json
[root@mycat63 ~]# cat /usr/local/mycat/conf/datasources/prototypeDs.datasource.json
{
	    &quot;dbType&quot;:&quot;mysql&quot;,
	    &quot;idleTimeout&quot;:60000,
	    &quot;initSqls&quot;:[],
	    &quot;initSqlsGetConnection&quot;:true,
	    &quot;instanceType&quot;:&quot;READ_WRITE&quot;,
	    &quot;maxCon&quot;:1000,
	    &quot;maxConnectTimeout&quot;:3000,
	    &quot;maxRetryCount&quot;:5,
	    &quot;minCon&quot;:1,
	    &quot;name&quot;:&quot;prototypeDs&quot;,
	    &quot;password&quot;:&quot;123456&quot;,
	    &quot;type&quot;:&quot;JDBC&quot;,
	    &quot;url&quot;:&quot;jdbc:mysql://localhost:3306/mysql?useUnicode=true&amp;amp;serverTimezone=Asia/Shanghai&amp;amp;characterEncoding=UTF-8&quot;,
	    &quot;user&quot;:&quot;jam&quot;,
	    &quot;weight&quot;:0
}

## 安装mysql数据库配置账号
[root@mycat63 ~]# systemctl restart mysqld
[root@mycat63 ~]# cat /var/log/mysqld.log | grep &quot;password&quot;
2025-12-08T10:14:10.214571Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: %6aj01&amp;gt;iV#Bb
[root@mycat63 ~]# mysql -uroot -p123
Enter password: 
mysql&amp;gt; # 创建jam用户
mysql&amp;gt; create user jam@&quot;%&quot; identified by &quot;123456&quot;;
Query OK, 0 rows affected (0.02 sec)
mysql&amp;gt; grant all on *.* to jam@&quot;%&quot;;
Query OK, 0 rows affected (0.01 sec)
mysql&amp;gt;

## mycat 配置数据源
[root@mycat63 ~]# /usr/local/mycat/bin/mycat start
Starting mycat2...
[root@mycat63 ~]# netstat  -utnlp  | grep 8066
tcp6       0      0 :::8066                 :::*                    LISTEN      16588/java          
[root@mycat63 ~]# mysql -h 127.0.0.1 -P8066 -umycat -p123456
mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;dw0&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.59:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
Query OK, 0 rows affected (0.33 sec)
mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;dr0&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.60:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
Query OK, 0 rows affected (0.04 sec)
mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;dw1&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.61:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
Query OK, 0 rows affected (0.02 sec)
mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;dr1&quot;, &quot;url&quot;:&quot;jdbc:mysql://192.168.88.62:3306&quot;,&quot;user&quot;:&quot;jam&quot;,&quot;password&quot;:&quot;123456&quot;}*/;
Query OK, 0 rows affected (0.01 sec)
mysql&amp;gt; /*+ mycat:showDataSources{}*/ \G
*************************** 1. row ***************************
	                NAME: dr1
	            USERNAME: jam
	            PASSWORD: 123456
	......
	            DB_TYPE: mysql
	                URL: jdbc:mysql://192.168.88.62:3306?useUnicode=true&amp;amp;serverTimezone=Asia/Shanghai&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
......
*************************** 2. row ***************************
	                NAME: dr0
	            USERNAME: jam
	            PASSWORD: 123456
......
	            DB_TYPE: mysql
	                URL: jdbc:mysql://192.168.88.60:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
......
*************************** 3. row ***************************
	                NAME: prototypeDs
	            USERNAME: jam
	            PASSWORD: 123456
......
	            DB_TYPE: mysql
	                URL: jdbc:mysql://localhost:3306/mysql?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
......
*************************** 4. row ***************************
	                NAME: dw1
	            USERNAME: jam
	            PASSWORD: 123456
......
	            DB_TYPE: mysql
	                URL: jdbc:mysql://192.168.88.61:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
......
*************************** 5. row ***************************
	                NAME: dw0
	            USERNAME: jam
	            PASSWORD: 123456
......
	            DB_TYPE: mysql
	                URL: jdbc:mysql://192.168.88.59:3306?serverTimezone=Asia/Shanghai&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;autoReconnect=true
......

## 在59和61双主服务器上添加mycat 连接使用的jam用户
mysql&amp;gt; create user jam@&quot;%&quot; identified by &quot;123456&quot;;
Query OK, 0 rows affected (0.01 sec)
mysql&amp;gt; grant all on *.* to jam@&quot;%&quot;;
Query OK, 0 rows affected (0.01 sec)

## 创建集群
[root@mycat63 ~]# mysql -h127.0.0.1 -P8066 -umycat -p123456
mysql&amp;gt; # mycat63服务器
mysql&amp;gt; /*! mycat:createcluster{&quot;name&quot;:&quot;c0&quot;,&quot;masters&quot;:[&quot;dw0&quot;],&quot;replicas&quot;:[&quot;dr0&quot;]}*/;
Query OK, 0 rows affected (0.06 sec)

mysql&amp;gt; /*! mycat:createcluster{&quot;name&quot;:&quot;c1&quot;,&quot;masters&quot;:[&quot;dw1&quot;],&quot;replicas&quot;:[&quot;dr1&quot;]}*/;
Query OK, 0 rows affected (0.02 sec)

mysql&amp;gt; /*+ mycat:showClusters{}*/ \G
*************************** 1. row ***************************
             NAME: prototype
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 200
             TYPE: BALANCE_ALL
         WRITE_DS: prototypeDs
          READ_DS: prototypeDs
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
*************************** 2. row ***************************
             NAME: c0
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 2000
             TYPE: BALANCE_ALL
         WRITE_DS: dw0
          READ_DS: dr0
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
*************************** 3. row ***************************
             NAME: c1
      SWITCH_TYPE: SWITCH
MAX_REQUEST_COUNT: 2000
             TYPE: BALANCE_ALL
         WRITE_DS: dw1
          READ_DS: dr1
          WRITE_L: io.mycat.plug.loadBalance.BalanceRandom$1
           READ_L: io.mycat.plug.loadBalance.BalanceRandom$1
        AVAILABLE: true
3 rows in set (0.21 sec)

[root@mycat63 ~]# 读写分离设置
[root@mycat63 ~]# sed -i &apos;s/&quot;READ_WRITE&quot;/&quot;READ&quot;/g&apos; /usr/local/mycat/conf/datasources/dr0.datasource.json
[root@mycat63 ~]# sed -i &apos;s/&quot;READ_WRITE&quot;/&quot;READ&quot;/g&apos; /usr/local/mycat/conf/datasources/dr1.datasource.json
[root@mycat63 ~]# sed -i &apos;s/&quot;READ_WRITE&quot;/&quot;WRITE&quot;/g&apos; /usr/local/mycat/conf/datasources/dw0.datasource.json
[root@mycat63 ~]# sed -i &apos;s/&quot;READ_WRITE&quot;/&quot;WRITE&quot;/g&apos; /usr/local/mycat/conf/datasources/dw1.datasource.json
[root@mycat63 ~]# grep -r &quot;instanceType&quot; /usr/local/mycat/conf/datasources/*
/usr/local/mycat/conf/datasources/dr0.datasource.json:  &quot;instanceType&quot;:&quot;READ&quot;,
/usr/local/mycat/conf/datasources/dr1.datasource.json:  &quot;instanceType&quot;:&quot;READ&quot;,
/usr/local/mycat/conf/datasources/dw0.datasource.json:  &quot;instanceType&quot;:&quot;WRITE&quot;,
/usr/local/mycat/conf/datasources/dw1.datasource.json:  &quot;instanceType&quot;:&quot;WRITE&quot;,
/usr/local/mycat/conf/datasources/prototypeDs.datasource.json:  &quot;instanceType&quot;:&quot;READ_WRITE&quot;,
[root@mycat63 ~]# /usr/local/mycat/bin/mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...
[root@mycat63 ~]# 


mysql&amp;gt; # 创建用户订单逻辑库
mysql&amp;gt; create database user_order_db;
Query OK, 0 rows affected (1.13 sec)

[root@mycat63 ~]# 指定 user_order_db 集群
[root@mycat63 ~]# sed -i &apos;/&quot;schemaName&quot;:&quot;user_order_db&quot;,/a \        &quot;targetName&quot;:&quot;c0,c1&quot;,&apos; /usr/local/mycat/conf/schemas/user_order_db.schema.json
[root@mycat63 ~]# cat /usr/local/mycat/conf/schemas/user_order_db.schema.json 
{
        &quot;customTables&quot;:{},
        &quot;globalTables&quot;:{},
        &quot;normalProcedures&quot;:{},
        &quot;normalTables&quot;:{},
        &quot;schemaName&quot;:&quot;user_order_db&quot;,
        &quot;targetName&quot;:&quot;c0,c1&quot;,
        &quot;shardingTables&quot;:{},
        &quot;views&quot;:{}
}
[root@mycat63 ~]# /usr/local/mycat/bin/mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...
[root@mycat63 ~]# 

[root@mycat63 ~]# mysql -h127.0.0.1 -P8066 -umycat -p123456
mysql&amp;gt; create table user_order_db.order_info (
    -&amp;gt; order_id bigint primary key,
    -&amp;gt; user_id bigint,
    -&amp;gt; order_amount decimal(10,2),
    -&amp;gt; order_create_date date,
    -&amp;gt; order_status tinyint
    -&amp;gt; ) default charset utf8
    -&amp;gt; dbpartition by YYYYMM(order_create_date) dbpartitions 1
    -&amp;gt; tbpartition by YYYYMM(order_create_date) tbpartitions 12;
Query OK, 0 rows affected (4.07 sec)

mysql&amp;gt; insert into user_order_db.order_info values (1, 1001, 100.00, &apos;2026-12-01&apos;, 1),(2, 1002, 200.00, &apos;2026-01-15&apos;, 1),(3, 1003, 300.00, &apos;2026-02-20&apos;, 1),(1, 1001, 100.00, &apos;2026-05-01&apos;, 1),(2, 1002, 200.00, &apos;2026-04-15&apos;, 1),(3, 1003, 300.00, &apos;2026-03-20&apos;, 1),(1, 1001, 100.00, &apos;2026-08-01&apos;, 1),(2, 1002, 200.00, &apos;2026-07-15&apos;, 1),(3, 1003, 300.00, &apos;2026-06-20&apos;, 1),(1, 1001, 100.00, &apos;2026-11-01&apos;, 1),(2, 1002, 200.00, &apos;2026-10-15&apos;, 1),(3, 1003, 300.00, &apos;2026-08-20&apos;, 1);
Query OK, 12 rows affected (0.26 sec)




mysql&amp;gt; # 商品订单库
mysql&amp;gt; create database product_order_db;
Query OK, 12 rows affected (0.03 sec)

[root@mycat63 ~]# vim /usr/local/mycat/conf/schemas/product_order_db.schema.json 
[root@mycat63 ~]# cat /usr/local/mycat/conf/schemas/product_order_db.schema.json 
{
        &quot;customTables&quot;:{},
        &quot;globalTables&quot;:{},
        &quot;normalProcedures&quot;:{},
        &quot;normalTables&quot;:{},
        &quot;schemaName&quot;:&quot;product_order_db&quot;,
        &quot;targetName&quot;:&quot;c0,c1&quot;,
        &quot;shardingTables&quot;:{},
        &quot;views&quot;:{}
}
[root@mycat63 ~]# /usr/local/mycat/bin/mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...
[root@mycat63 ~]# 

mysql&amp;gt; create table product_order_db.product_order_info (
    -&amp;gt;   product_order_id bigint primary key,
    -&amp;gt;   order_id bigint,
    -&amp;gt;   product_id bigint,
    -&amp;gt;   product_num int,
    -&amp;gt;   order_create_date date
    -&amp;gt; ) default charset utf8
    -&amp;gt; dbpartition by YYYYMM(order_create_date) dbpartitions 2
    -&amp;gt; tbpartition by YYYYMM(order_create_date) tbpartitions 12;
Query OK, 0 rows affected (2.25 sec)






&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;现在需要在 Mycat 中添加一个新的 MySQL 数据源，并创建一个新的集群。请写出相应的操作步骤和 SQL 语句。
答：
添加数据源：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;主数据源名称&quot;, &quot;url&quot;:&quot;jdbc:mysql://IP:端口&quot;,&quot;user&quot;:&quot;用户名&quot;,&quot;password&quot;:&quot;密码&quot;}*/;
mysql&amp;gt; /*+ mycat:createdatasource{&quot;name&quot;:&quot;从数据源名称&quot;, &quot;url&quot;:&quot;jdbc:mysql://IP:端口&quot;,&quot;user&quot;:&quot;用户名&quot;,&quot;password&quot;:&quot;密码&quot;}*/;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;创建集群命令：
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; /*!mycat:createcluster{&quot;name&quot;:&quot;集群名&quot;,&quot;masters&quot;:[&quot;主数据源名称&quot;],&quot;replicas&quot;:[&quot;从数据源名称&quot;]}*/;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;验证集群：
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; /*+ mycat:showClusters{} */\G
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;————————————————————————————————————————————————————————————————————————————————&lt;/p&gt;
&lt;h1&gt;12：redis 数据类型&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250621155239718.webp&quot; alt=&quot;image-20250621155239718&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;h3&gt;1.1 电商平台场景&lt;/h3&gt;
&lt;p&gt;在电商平台中，会大量使用 Redis【瑞迪斯】 来提升性能和处理并发。用字符串类型缓存商品的基本信息，减轻数据库压力；用列表类型实现消息队列，处理订单任务；用散列类型存储商品的多维度属性，方便单独查询和修改；用集合类型实现商品标签系统，便于用户根据标签搜索商品；用有序集合类型实现商品销量排行榜。&lt;/p&gt;
&lt;h3&gt;1.2 社交平台场景&lt;/h3&gt;
&lt;p&gt;社交平台利用 Redis【瑞迪斯】 来实现各种功能。字符串类型用于存储用户的会话信息，保证用户登录状态一致；列表类型存储用户的动态历史记录，方便用户查看；散列类型存储用户的详细资料；集合类型存储用户的好友列表，实现共同好友推荐；有序集合类型实现用户活跃度排行榜。&lt;/p&gt;
&lt;h2&gt;二、为什么学&lt;/h2&gt;
&lt;p&gt;学习 Redis【瑞迪斯】 数据类型具有多方面重要意义。从性能上看，Redis【瑞迪斯】 作为基于内存的键值型 NoSQL 数据库，读写速度极快，官方数据显示读取速度达 110000 次/秒，写速度 81000 次/秒，掌握其数据类型能让我们在开发中充分利用这一优势，提升系统性能。&lt;/p&gt;
&lt;p&gt;从应用场景来说，不同数据类型适用场景广泛。比如字符串类型可用于缓存、计数器、分布式锁等；列表类型能实现消息队列、排行榜、历史记录存储等；散列类型适合存储用户信息、商品属性等；集合类型可用于用户管理、唯一性检查等；有序集合类型能实现排行榜、分数统计等。学习这些数据类型，能让我们在面对各种业务需求时，选择合适的数据类型解决问题。&lt;/p&gt;
&lt;p&gt;从就业角度看，Redis【瑞迪斯】 在互联网领域应用广泛，掌握 Redis【瑞迪斯】 数据类型及其应用，能增强我们在职场上的竞争力，为从事相关工作打下坚实基础。&lt;/p&gt;
&lt;h2&gt;三、搭建redis【瑞迪斯】 服务器&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250621155333031.webp&quot; alt=&quot;image-20250621155333031&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3.1 什么是redis【瑞迪斯】&lt;/h3&gt;
&lt;p&gt;Redis【瑞迪斯】 即远程字典服务，是开源的基于内存的键值型NoSQL数据库，用C语言编写。它将数据存于内存，读写快，官方数据显示读取速度达110000次/秒，写速度81000次/秒 。支持字符串、哈希、列表、集合、有序集合等丰富数据结构，每种都有专门操作命令。提供RDB和AOF两种持久化机制，还支持主从复制、哨兵机制、集群模式等。采用单线程架构结合IO多路复用技术处理请求，避免多线程开销。广泛用于缓存、会话管理、排行榜等场景。&lt;/p&gt;
&lt;h3&gt;3.2 准备环境&lt;/h3&gt;
&lt;p&gt;克隆1台新虚拟机&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;redis64&lt;/td&gt;
&lt;td&gt;192.168.90.64&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;修改IP地址和主机名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis64 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis64
[root@redis64 ~]# nmcli connection【肯耐申】 modify【莫迪fái】ens160 ipv4.addresses【额拽西斯】 192.168.90.64/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis64~]# nmcli connection【肯耐申】 up ens160 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3 安装和运行redis【瑞迪斯】&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#安装redis【瑞迪斯】
[root@redis64 ~]# yum -y install【因-斯多】 redis【瑞迪斯】

#查看redis【瑞迪斯】 版本
[root@redis64 ~]# rpm -q redis【瑞迪斯】
redis-6.2.18-1.el9_6.x86_64

#设置开机自启，并立即启动
[root@redis64 ~]# systemctl【西斯屯-ctl】 enable【ing 内 步】 redis【瑞迪斯】 --now

#查看redis端口
[root@redis64 ~]# netstat【劣 s 塔】 -antlup | grep【哥瑞普】 redis【瑞迪斯】
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      34578/redis-server  
tcp6       0      0 ::1:6379                :::*                    LISTEN      34578/redis-server
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.4 连接redis【瑞迪斯】 服务&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#连接redis【瑞迪斯】
[root@redis64 ~]# redis-cli

#检查能否正在访问
127.0.0.1:6379&amp;gt; ping   
PONG

#断开连接
127.0.0.1:6379&amp;gt; exit【诶西特】  
[root@redis64 ~]# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;完整的连接redis&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#发现通过IP无法连接
[root@redis64 ~]# redis-cli -h 192.168.90.64 -p 6379
Could not connect to Redis at 192.168.90.64:6379: Connection refused
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改redis【瑞迪斯】 配置文件，使得redis【瑞迪斯】 可以被任何机器连接&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#修改前
[root@redis64 ~]# vim /etc/redis/redis.conf 
  72 # IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
  73 # JUST COMMENT OUT THE FOLLOWING LINE.
  74 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  75 bind 127.0.0.1 -::1   #修改75行

#修改后
[root@redis64 ~]# vim /etc/redis/redis.conf 
  72 # IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
  73 # JUST COMMENT OUT THE FOLLOWING LINE.
  74 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  75 bind 0.0.0.0

#修改配置文件后重启
[root@redis64 ~]# systemctl【西斯屯-ctl】 restart【 率 s 达r】 redis【瑞迪斯】

 #现在可以连接
[root@redis64 ~]# redis-cli -h 192.168.90.64 -p 6379
192.168.90.64:6379&amp;gt; ping
PONG

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.5 给redis【瑞迪斯】 设置密码&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#修改903行
[root@redis64 ~]# vim /etc/redis/redis.conf 
 900 # The requirepass is not compatable with aclfile option and the ACL LOAD
 901 # command, these will cause requirepass to be ignored.
 902 #
 903  requirepass 123456

#修改后重启
[root@redis64 ~]# systemctl【西斯屯-ctl】 restart【 率 s 达r】 redis【瑞迪斯】

#连接redis【瑞迪斯】
[root@redis64 ~]# redis-cli

# 这时候操作失败
127.0.0.1:6379&amp;gt; ping  
(error) NOAUTH Authentication required.

# 输入密码认证
127.0.0.1:6379&amp;gt; auth 123456  
OK
127.0.0.1:6379&amp;gt; ping
PONG
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、字符串类型（string【斯jǘn】 类型）&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250621155359980.webp&quot; alt=&quot;image-20250621155359980&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;4.1 应用场景&lt;/h3&gt;
&lt;p&gt;Redis【瑞迪斯】 字符串类型是最基本的数据类型，支持存储整数、浮点数和字符串，适用于多种应用场景，以下是一些常见的应用场景：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;缓存&lt;/strong&gt;：可存储用户名、密码、会话标识符等简短字符串，也能缓存数据库查询结果、网页内容、用户信息等常用数据，减轻数据库压力，提高访问速度。例如在商品系统中，用 Redis【瑞迪斯】 String【斯jǘn】 类型缓存商品的静态信息，商品信息更新时，同步更新或使缓存失效 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;计数器&lt;/strong&gt;：利用 incr【因kuì儿】 和 decr【迪kuì儿】 命令实现计数功能，适用于统计网页访问量、点赞数、文章浏览量、商品库存数量等。比如在文章浏览量统计中，每次文章被访问，文章 ID 对应的浏览次数在 Redis【瑞迪斯】 中递增，还可定期将浏览次数同步到数据库用于历史数据分析 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分布式锁&lt;/strong&gt;：结合 setNX 命令，使用字符串实现简单的分布式锁，保证在分布式系统中的数据一致性和并发控制。例如在电商的秒杀活动或库存管理中，确保同一时间只有一个进程或线程可以修改共享资源，避免数据不一致 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;共享会话（Session【塞-神】）&lt;/strong&gt;：在分布式 Web 应用里，可集中管理用户的 Session【塞-神】 信息（如登录信息），确保用户无论访问哪台服务器都能保持一致的会话状态，避免因负载均衡到不同服务器而需重新登录。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;手机验证码&lt;/strong&gt;：存储短信验证码并设置过期时间，还可限制用户获取验证码的频率，例如限制每分钟获取不超过 5 次 。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;4.2 设置单个值&lt;/h3&gt;
&lt;p&gt;设置单个值，命令格式：&lt;/p&gt;
&lt;p&gt;set【赛特】   key【kì】   value【挖柳】&lt;/p&gt;
&lt;p&gt;查看key【kì】 对应的值&lt;/p&gt;
&lt;p&gt;get【脚(白话)特】 key【kì】&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis64 ~]# redis-cli -h 192.168.90.64 -p 6379
192.168.90.64:6379&amp;gt; auth 123456
OK
192.168.90.64:6379&amp;gt; set【赛特】 school【斯故】 moershi
OK
192.168.90.64:6379&amp;gt; get【脚(白话)特】 school【斯故】
&quot;moershi&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.4 设置多个值&lt;/h3&gt;
&lt;p&gt;设置多个值，命令格式：&lt;/p&gt;
&lt;p&gt;mset key1  value【挖柳】1  key2  value【挖柳】2  key3  value【挖柳】3...&lt;/p&gt;
&lt;p&gt;查看多个key【kì】 对应的值&lt;/p&gt;
&lt;p&gt;mget key1  key2  key3&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; mset name jam age 30 class yjs001
OK
192.168.90.64:6379&amp;gt; mget name age class
1) &quot;jam&quot;
2) &quot;30&quot;
3) &quot;yjs001&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.5 设置值的有效期&lt;/h3&gt;
&lt;p&gt;存储变量时 设置变量的有效期 px(毫秒) ex (秒)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; set【赛特】 name jam ex 10   #变量10秒过期
OK
192.168.90.64:6379&amp;gt; set【赛特】 class  nsd  px 10   #变量10毫秒过期
OK
192.168.90.64:6379&amp;gt;

# NX 不覆盖赋值
192.168.90.64:6379&amp;gt; set【赛特】 name xiaohong NX
(nil)
192.168.90.64:6379&amp;gt; get【脚(白话)特】 name
&quot;jam&quot;

# XX 覆盖赋值
192.168.90.64:6379&amp;gt; set【赛特】 name yaya XX
OK
192.168.90.64:6379&amp;gt; get【脚(白话)特】 name
&quot;yaya&quot;
192.168.90.64:6379&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;set【赛特】 命令完整格式演示&lt;/p&gt;
&lt;p&gt;set    名称        值     有效期类型     有效时间     是否覆盖
set    gender    girl        ex                20                NX&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; set【赛特】 gender girl  ex 20  NX
OK
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.6 数字增减操作&lt;/h3&gt;
&lt;h4&gt;incr【因kuì儿】 递增数字&lt;/h4&gt;
&lt;p&gt;- 递增数字：字符串类型可以存储任何形式的字符串，当存储的字符串是整数形式时，&lt;/p&gt;
&lt;p&gt;Redis【瑞迪斯】 提供了一个实用的命令 incr【因kuì儿】，其作用是让当前键值递增，并返回递增后的值。&lt;/p&gt;
&lt;p&gt;当要操作的键不存在时会默认键值为0，所以第一次递增后的结果是1。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 创建变量
192.168.90.64:6379&amp;gt; set【赛特】  num 1 
192.168.90.64:6379&amp;gt; incr【因kuì儿】 num    #+1
(integer) 2
192.168.90.64:6379&amp;gt; incr【因kuì儿】 num    #+1
(integer) 3
192.168.90.64:6379&amp;gt; get【脚(白话)特】 num     
&quot;3&quot;

# 复数递增数字 incrby
192.168.90.64:6379&amp;gt; incrby【因kuì儿 by】 num 2   #+2
(integer) 5
192.168.90.64:6379&amp;gt; incrby【因kuì儿 by】 num 3   #+3
(integer) 8
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;decr【迪kuì儿】 递减数字&lt;/h4&gt;
&lt;p&gt;- 增加指定的整数&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;- 递减数字
192.168.90.64:6379&amp;gt; decr【迪kuì儿】 num     #-1
(integer) 7

# 复数递减数字 decrby
192.168.90.64:6379&amp;gt; decrby num 3   #
(integer) 4
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;append【额 篇的】 尾部追加值&lt;/h4&gt;
&lt;p&gt;- 向尾部追加值
&lt;code&gt;append【额 篇的】&lt;/code&gt;通常指追加操作。在文件处理方面，可将数据添加到已有文件的末尾，而不是覆盖原内容。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 创建变量hi
192.168.90.64:6379&amp;gt; set【赛特】 hi Hello   
OK

# 因为字符串包含空格，需要使用引号
192.168.90.64:6379&amp;gt; append【额 篇的】 hi &quot; World&quot;   
(integer) 11        # 返回值为hi的总长度

192.168.90.64:6379&amp;gt; get【脚(白话)特】 hi
&quot;Hello World&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.7 字符串处理&lt;/h3&gt;
&lt;h4&gt;strlen【斯拽轮】 获取字符串长度&lt;/h4&gt;
&lt;p&gt;- 获取字符串长度
&lt;code&gt;strlen【斯拽轮】&lt;/code&gt;是用于获取存储在指定键的字符串值的长度的命令&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; strlen【斯拽轮】 hi
(integer) 11
- 中文字符返回字节数
192.168.90.64:6379&amp;gt; set【赛特】 name 张三
OK
192.168.90.64:6379&amp;gt; strlen【斯拽轮】 name
(integer) 6   # UTF-8编码的中文，由于“张”和“三”两个字的UTF-8编码的长度都是3，所以此例中会返回6。
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;getrange 获取变量部分数据&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;getrange【脚(白话) cùn局】&lt;/code&gt;命令用于获取存储在指定键的字符串值的子字符串。它的核心用途是按指定的起始和结束位置提取字符串的一部分。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 创建变量
192.168.90.64:6379&amp;gt; set【赛特】 zfc  ABCEF   
OK

# 输出变量值
192.168.90.64:6379&amp;gt; get zfc  
&quot;ABCEF&quot;

# 输出第1个到第2个字符
192.168.90.64:6379&amp;gt; getrange【脚(白话) cùn局】 zfc 0 1  
&quot;AB&quot;

# 输出第3个到第5个字符
192.168.90.64:6379&amp;gt; getrange【脚(白话) cùn局】 zfc 2 4  
&quot;CEF&quot;

# 输出倒数第2个到第1个字符
192.168.90.64:6379&amp;gt; getrange【脚(白话) cùn局】 zfc -2 -1 
&quot;EF&quot;
192.168.90.64:6379&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、Key【kì】的操作&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250621155426054.webp&quot; alt=&quot;image-20250621155426054&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;5.1 keys 列出所有的key【kì】&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; keys *
1) &quot;age&quot;
2) &quot;classs&quot;
3) &quot;name&quot;
4) &quot;school【斯故】&quot;

#keys 使用统配符查看变量, * 匹配所有变量名, ? 一个字符

# 变量名是3个字符
192.168.90.64:6379&amp;gt; keys ???  
1) &quot;age&quot;

# 变量名是a 开头的
192.168.90.64:6379&amp;gt; keys a*   
1) &quot;age&quot;

# 查看指定变量是否存在
192.168.90.64:6379&amp;gt; keys gender  
(empty list or set) # 说明变量没有定义

192.168.90.64:6379&amp;gt; keys name
1) &quot;name&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 select【涩莱克特】 选择数据库&lt;/h3&gt;
&lt;p&gt;（redis【瑞迪斯】总共有15个库，从0到15）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# select【涩莱克特】 切换库 默认库编号 0-15 

# 切换到 1号库里
192.168.90.64:6379&amp;gt; select【涩莱克特】 1  
OK

# 查看数据没有数据
192.168.90.64:6379[1]&amp;gt; keys * 
(empty list or set)
192.168.90.64:6379[1]&amp;gt; 
192.168.90.64:6379[1]&amp;gt; select【涩莱克特】 0  
OK
192.168.90.64:6379&amp;gt; select【涩莱克特】 16
(error) ERR DB index is out of range

# move 命令 移动变量到其他库里
192.168.90.64:6379&amp;gt; keys *
1) &quot;age&quot;
2) &quot;classs&quot;
3) &quot;name&quot;
4) &quot;school【斯故】&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.3 move 把某个key【kì】移动到某个库中&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;move&lt;/code&gt; 命令 移动变量到其他库里&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; keys *
1) &quot;age&quot;
2) &quot;classs&quot;
3) &quot;name&quot;
4) &quot;school【斯故】&quot;


# 把age 变量移动到1 号库里
192.168.90.64:6379&amp;gt; move age 1   
(integer) 1 
192.168.90.64:6379&amp;gt; keys *
1) &quot;classs&quot;
2) &quot;name&quot;
3) &quot;school【斯故】&quot;
192.168.90.64:6379&amp;gt; select【涩莱克特】  1
OK
192.168.90.64:6379[1]&amp;gt; keys *
1) &quot;age&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.4 exists【伊贼谁斯】  判断一个key【kì】是否存在&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#exists【伊贼谁斯】 检查变量是否存储  返回值1  变量存储 返回值是0 变量不存在
192.168.90.64:6379[1]&amp;gt; select【涩莱克特】 0
OK
192.168.90.64:6379&amp;gt; EXISTS【伊贼谁斯】 name  # 检查name变量是否存在
(integer) 1
192.168.90.64:6379&amp;gt; get【脚(白话)特】 name
&quot;plj&quot;
192.168.90.64:6379&amp;gt; set【赛特】 name bob
OK
192.168.90.64:6379&amp;gt; get【脚(白话)特】 name
&quot;bob&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.5 key【kì】的过期时间&lt;/h3&gt;
&lt;p&gt;expire【ī 斯 拜尔】 设置一个key【kì】的过期时间&lt;/p&gt;
&lt;p&gt;ttl  查看一个剩余的过期时间&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#EXPIRE【ī 斯 拜尔】 命令设置变量的过期时间 不设置变量永不过期
#ttl   检查变量可以在内存里存多久
192.168.90.64:6379&amp;gt; set【赛特】 sex girl
OK
192.168.90.64:6379&amp;gt; ttl sex
(integer) -1  #表示永不过期

192.168.90.64:6379&amp;gt; EXPIRE【ī 斯 拜尔】 sex 15   #设置过期时间15 秒
(integer) 1

192.168.90.64:6379&amp;gt; keys sex
1) &quot;sex&quot;

192.168.90.64:6379&amp;gt; ttl sex
(integer) 8  #还剩下8秒时间过期

192.168.90.64:6379&amp;gt; ttl sex
(integer) -2  #表示已经过期被删除

192.168.90.64:6379&amp;gt; keys  sex
(empty list or set)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;衍生命令（高频扩展）&lt;br /&gt;
Redis针对过期时间提供了更灵活的衍生命令，补充&lt;code&gt;EXPIRE&lt;/code&gt;的不足：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PEXPIRE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置毫秒级过期时间（更高精度）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PEXPIRE user:session:100 1800000&lt;/code&gt;（30分钟）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;EXPIREAT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置Key在指定Unix时间戳（秒）过期&lt;/td&gt;
&lt;td&gt;&lt;code&gt;EXPIREAT order:1001 1716643200&lt;/code&gt;（2024-05-26 00:00:00）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PEXPIREAT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置Key在指定Unix时间戳（毫秒）过期&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PEXPIREAT order:1001 1716643200000&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TTL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;查看Key剩余过期时间（秒，-1=永不过期，-2=已删除）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TTL user:session:100&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PTTL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;查看Key剩余过期时间（毫秒）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PTTL user:session:100&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PERSIST&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;移除Key的过期时间（设为永不过期）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PERSIST user:session:100&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;5.6 type【泰 普】  查看某个key【kì】是属于哪个数据类型&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#type【泰 普】 命令检查变量存储数据的类型  
#使用set【赛特】  mset命令存储的数据都字符类型。
#数据的类型不同 管理的命令也不同 
#明天讲数据类型。

192.168.90.64:6379&amp;gt; set【赛特】 x 99
OK
192.168.90.64:6379&amp;gt; mset y 108
OK
192.168.90.64:6379&amp;gt; type【泰 普】 x
string
192.168.90.64:6379&amp;gt; type【泰 普】 y
string
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.7 del  删除一个key【kì】&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#del 删除内存里的变量
192.168.90.64:6379&amp;gt; keys *
1) &quot;y&quot;
2) &quot;tea&quot;
3) &quot;name&quot;
4) &quot;school【斯故】&quot;
5) &quot;x&quot;
6) &quot;classs&quot;
192.168.90.64:6379&amp;gt; del tea y school【斯故】
(integer) 3
192.168.90.64:6379&amp;gt; keys *
1) &quot;name&quot;
2) &quot;x&quot;
3) &quot;classs&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.8 flushdb【福 辣 徐 db】 删除本库的所有的key【kì】&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#flushdb【福 辣 徐 db】  删除当前所在库的所有数据
192.168.90.64:6379&amp;gt; keys *
1) &quot;name&quot;
2) &quot;x&quot;
3) &quot;classs&quot;
192.168.90.64:6379&amp;gt; flushdb【福 辣 徐 db】
OK
192.168.90.64:6379&amp;gt; keys *
(empty list or set)
192.168.90.64:6379&amp;gt; SELECT【涩莱克特】 1
OK
192.168.90.64:6379[1]&amp;gt; keys *
1) &quot;age&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.9 flushall【福 辣 徐 ò】 删除所有库的key【kì】&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379[1]&amp;gt; flushall【福 辣 徐 ò】 #删除内存里的所有内存里所有数据 （慎用）
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、列表类型（list【lì斯特】类型）&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250621155454906.webp&quot; alt=&quot;image-20250621155454906&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;6.1 应用场景&lt;/h3&gt;
&lt;p&gt;Redis【瑞迪斯】 列表类型是一种简单的数据结构，可用来实现队列、栈和日志记录等功能。其应用场景广泛，以下是一些常见的场景：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;消息队列&lt;/strong&gt;：适合实现生产者 - 消费者模式。生产者使用LPUSH【L 普斯】 命令将消息从列表左端插入，消费者使用BRPOP或RPOP【R 扑】命令从右端取出消息处理。如在微服务架构里，一个服务可将任务作为消息放入列表，另一个服务作为消费者取出任务执行。还能用于任务队列，像电商网站中，用户下单后将订单处理任务放入列表，后台工作进程取出任务进行库存更新、订单确认等操作，避免用户等待，提升体验。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;排行榜&lt;/strong&gt;：可用于时间序列排行榜，如在游戏里将玩家得分和时间戳作为元素放入列表，对列表排序可得不同时间段的玩家排行榜。也能实现动态排行榜，在直播平台中，观众送礼物增加主播人气值，人气值变化实时反映在排行榜上，通过快速插入新元素和删除旧元素实现榜单实时更新。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;历史记录存储&lt;/strong&gt;：可存储用户操作历史，如文档编辑系统中，用LPUSH【L 普斯】 命令将用户每次编辑操作记录插入列表，用LRANGE【L 轮局】 命令获取一定范围的历史记录，方便用户查看历史版本或撤销操作。还能用于系统日志记录，Web应用中，将用户登录日志、请求日志等存储在列表，便于进行日志查询和分析，故障排查时可快速获取相关日志信息。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;栈和队列数据结构的实现&lt;/strong&gt;：可作为栈使用，用LPUSH【L 普斯】 命令将元素插入列表头部，用LPOP【L 扑】 命令从头部弹出元素，实现后进先出的栈结构，用于一些算法实现。也能当作队列，用LPUSH【L 普斯】 命令将元素插入头部，用RPOP【R 扑】 命令从尾部弹出元素，实现先进先出的队列结构，如任务调度系统中，将任务按提交顺序放入队列，工作进程依次取出执行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;社交平台相关场景&lt;/strong&gt;：如微信朋友圈点赞，按点赞顺序显示点赞好友信息，取消点赞时移除对应好友信息；Twitter、微博等社交平台中，个人用户的关注列表按关注顺序展示，粉丝列表将最近关注的粉丝列在前面。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;待办事项与购物车&lt;/strong&gt;：可以作为待办事项列表使用，用户添加待办事项时用LPUSH【L 普斯】 或RPUSH【R 普斯】插入列表，完成事项后用LPOP【L 扑】 或RPOP【R 扑】 移除。购物车也可使用列表实现，商品添加到购物车时插入列表，结算或移除商品时从列表移除 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;秒杀抢购&lt;/strong&gt;：将商品ID作为key【kì】，商品数目作为value【挖柳】 存储在列表中，在秒杀场景中使用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实时在线用户管理&lt;/strong&gt;：可用于存储实时在线用户的列表，实现实时更新和查询在线用户信息。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;日志记录&lt;/strong&gt;：在Web应用中，将用户请求的URL和请求时间push到列表，并设置列表长度为一定值，查看日志时通过lrange【L 轮局】 命令获取之前请求过的URL和请求时间。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;6.2 向列表左边增加元素&lt;/h3&gt;
&lt;h4&gt;&lt;code&gt;lpush【L 普斯】&lt;/code&gt;向列表左边增加元素&lt;/h4&gt;
&lt;p&gt;LPUSH【L 普斯】 命令用来向列表左边增加元素，返回值表示增加元素后列表的长度
&lt;code&gt;lpush【L 普斯】&lt;/code&gt;是“left push”的缩写，用于将一个或多个值插入到列表的头部（左侧）
命令格式为&lt;code&gt;LPUSH key value1 value2...&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 创建变量
192.168.90.64:6379&amp;gt; lpush【L 普斯】  letter A B C 
(integer) 3

# 查看类型
192.168.90.64:6379&amp;gt; type【泰 普】 letter  
list【lì斯特】


# 头部追加元素
192.168.90.64:6379&amp;gt; lpush【L 普斯】 letter d e
(integer) 5
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;&lt;code&gt;lrange【L 轮局】&lt;/code&gt;取出列表所有元素&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;lrange【L 轮局】&lt;/code&gt;用于获取列表指定范围内的元素。它能按索引范围提取列表中的部分或全部元素。
命令格式为&lt;code&gt;LRANGE key 开始 结束&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 起始下标为0，结束下标为-1
192.168.90.64:6379&amp;gt; lrange【L 轮局】 letter 0 -1
1) &quot;e&quot;
2) &quot;d&quot;
3) &quot;C&quot;
4) &quot;B&quot;
5) &quot;A&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;&lt;code&gt;llen【L 轮】&lt;/code&gt;统计元素个数&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;llen【L 轮】&lt;/code&gt;是用于获取列表长度的命令。它返回存储在指定键的列表中的元素数量。
格式：有一个名为&lt;code&gt;my_list&lt;/code&gt;的列表，执行&lt;code&gt;LLEN my_list&lt;/code&gt;命令，就能知道&lt;code&gt;my_list&lt;/code&gt;中有多少个元素。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; llen【L 轮】 letter
(integer) 5
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.3 lindex索引元素&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;lindex【L 因戴克斯】&lt;/code&gt;命令用于获取列表中指定索引位置的元素。
通过下标输出单个元素 第1个元素下标用0表示 第2个元素下标用1表示&lt;/p&gt;
&lt;p&gt;最后一个元素下标用-1表示&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; lindex【L 因戴克斯】 letter 0
&quot;e&quot;
192.168.90.64:6379&amp;gt; lindex【L 因戴克斯】 letter 2
&quot;C&quot;

# 最后1个
192.168.90.64:6379&amp;gt; lindex【L 因戴克斯】 letter -1 
&quot;A&quot;

# 倒数第2个
192.168.90.64:6379&amp;gt; lindex【L 因戴克斯】 letter -2 
&quot;B&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.4 lset【L 赛特】修改元素&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;lset【L 赛特】&lt;/code&gt;用于设置列表中指定索引位置的元素值。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 修改前查看
192.168.90.64:6379&amp;gt; lrange【L 轮局】 letter 0 -1  
1) &quot;e&quot;
2) &quot;d&quot;
3) &quot;C&quot;
4) &quot;B&quot;
5) &quot;A&quot;

# 修改第1元素
192.168.90.64:6379&amp;gt; lset letter 0 E  
OK

# 修改最后1个元素
192.168.90.64:6379&amp;gt; lset letter -1 a 
OK

# 修改后查看
192.168.90.64:6379&amp;gt; lrange【L 轮局】 letter 0 -1 
1) &quot;E&quot;
2) &quot;d&quot;
3) &quot;C&quot;
4) &quot;B&quot;
5) &quot;a&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.5 弹出元素（删除元素）&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;lpop【L 扑】&lt;/code&gt;是“left pop”的缩写，用于从列表的头部（左侧）移除并返回一个元素。
&lt;code&gt;rpop【R 扑】&lt;/code&gt;即“right pop”的缩写，用于从列表的尾部（右侧）移除并返回一个元素。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; lrange【L 轮局】 letter 0 -1  #修改前查看
1) &quot;E&quot;
2) &quot;d&quot;
3) &quot;C&quot;
4) &quot;B&quot;
5) &quot;a&quot;
192.168.90.64:6379&amp;gt; lpop【L 扑】 letter  #弹出头部元素
&quot;E&quot;
192.168.90.64:6379&amp;gt; rpop【R 扑】 letter  #弹出尾部元素
&quot;a&quot;
192.168.90.64:6379&amp;gt; lrange【L 轮局】 letter 0 -1  #修改后查看
1) &quot;d&quot;
2) &quot;C&quot;
3) &quot;B&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.6 尾部追加元素&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;rpush&lt;/code&gt;是“right push”的缩写，用于将一个或多个值插入到列表的尾部（右侧） 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; rpush【R 普斯】 letter e f #尾部追加元素
(integer) 5
192.168.90.64:6379&amp;gt; lrange【L 轮局】 letter 0 -1 #追加后查看
1) &quot;d&quot;
2) &quot;C&quot;
3) &quot;B&quot;
4) &quot;e&quot;
5) &quot;f&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.7 插入元素&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;linsert【L 因涩特】&lt;/code&gt;用于在列表指定元素的前或后插入新元素。
&lt;code&gt;before【B fò】&lt;/code&gt;表示在……之前。
&lt;code&gt;after【啊夫特】&lt;/code&gt; 常用于表达在……之后。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; lrange【L 轮局】 letter 0 -1 #插入前查看
1) &quot;d&quot;
2) &quot;C&quot;
3) &quot;B&quot;
4) &quot;e&quot;
5) &quot;f&quot;
192.168.90.64:6379&amp;gt; 
192.168.90.64:6379&amp;gt; linsert【L 因涩特】 letter before【B fò】 C C2   #值C前插入C2
(integer) 6
192.168.90.64:6379&amp;gt; lrange【L 轮局】 letter 0 -1  #插入后查看
1) &quot;d&quot;
2) &quot;C2&quot;
3) &quot;C&quot;
4) &quot;B&quot;
5) &quot;e&quot;
6) &quot;f&quot;
192.168.90.64:6379&amp;gt;
192.168.90.64:6379&amp;gt; linsert【L 因涩特】 letter after【啊夫特】 C C3  #值C后插入C3
(integer) 7
192.168.90.64:6379&amp;gt; lrange【L 轮局】 letter 0 -1 #插入后查看
1) &quot;d&quot;
2) &quot;C2&quot;
3) &quot;C&quot;
4) &quot;C3&quot;
5) &quot;B&quot;
6) &quot;e&quot;
7) &quot;f&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;七、散列类型（hash【哈希】类型）&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250621155520850.webp&quot; alt=&quot;image-20250621155520850&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;7.1 应用场景&lt;/h3&gt;
&lt;p&gt;Redis【瑞迪斯】 散列类型是字符串字段和字符串值之间的映射，类似 Python 字典或 Java 的 HashMap，适合存储对象，且可像数据库更新记录一样只修改特定字段。其具体应用场景如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;用户信息存储&lt;/strong&gt;：每个用户对应一个 Hash【哈希】，以用户 ID 为键名，使用字段表示用户的属性，如姓名、年龄、生日等，而字段值则存储属性值。相比用普通的 key【kì】/value【挖柳】 结构存储，避免了序列化/反序列化的开销，且在修改其中一项信息时，无需把整个对象取回，也无需引入复杂的并发保护机制。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;商品属性存储&lt;/strong&gt;：可用于存储商品的多维度属性，如价格、库存、描述等。通过散列类型，能方便地对商品的各个属性进行单独的查询、修改和更新操作，提高数据处理的效率和灵活性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配置管理&lt;/strong&gt;：适用于动态更新配置字段的场景，无需反序列化整个对象。系统的配置信息可存储在散列中，当配置发生变化时，只需更新相应的字段即可，保证系统的配置信息能实时生效，且操作简单高效。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;购物车&lt;/strong&gt;：以用户 ID 为 key【kì】，商品 ID 为 field，商品数量为 value【挖柳】。用户向购物车中添加商品时，可通过操作散列类型来记录商品信息和数量；修改商品数量或删除商品时，也能方便地对散列中的对应字段进行更新或删除操作。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文章内容存储&lt;/strong&gt;：对于文章的各种属性，如标题、作者、发布时间、内容摘要等，可以使用散列类型进行存储，以文章 ID 作为键名，各个属性作为字段和字段值，便于对文章信息进行管理和查询。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;7.2 存储数据和获取数据&lt;/h3&gt;
&lt;p&gt;赋值与取值
&lt;code&gt;hset【h 赛特】&lt;/code&gt;用于在哈希表（hash）中设置一个字段（field）的值。
&lt;code&gt;hmset【hm 赛特】&lt;/code&gt;用于同时设置哈希表中的多个字段值。
&lt;code&gt;hget【h 脚(白话)特】&lt;/code&gt;用于从哈希表中获取指定字段的值。
&lt;code&gt;hmget【hm 脚(白话)特】&lt;/code&gt;用于从哈希表中获取一个或多个指定字段的值。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; hset【h 赛特】 user1 name bob  #创建变量
(integer) 1
192.168.90.64:6379&amp;gt; type【泰 普】 user1 #查看类型
hash
192.168.90.64:6379&amp;gt;
192.168.90.64:6379&amp;gt; hset【h 赛特】 user1 gender man #赋新值
(integer) 1
192.168.90.64:6379&amp;gt; hget【h 脚(白话)特】 user1 name  #查看name列的值
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;设置多个字段&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; hmset【hm 赛特】 user1 email bob@qcjy.cn phone 13412345678
OK
192.168.90.64:6379&amp;gt; hmget【hm 脚(白话)特】 user1 email phone
1) &quot;bob@qcjy.cn&quot;
2) &quot;13412345678&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;获取所有列名及对应的值
&lt;code&gt;hgetall【h 脚(白话)特 ò】&lt;/code&gt;用于获取哈希表中所有的字段和值。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; hgetall【h 脚(白话)特 ò】 user1
1) &quot;name&quot;
2) &quot;bob&quot;
3) &quot;gender&quot;
4) &quot;male&quot;
5) &quot;email&quot;
6) &quot;bob@qcjy.cn&quot;
7) &quot;phone&quot;
8) &quot;13412345678&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.3 其他操作&lt;/h3&gt;
&lt;h4&gt;hdel删除列&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;hdel【h 戴尔】&lt;/code&gt;用于删除哈希表中的一个或多个字段。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; hdel【h 戴尔】 user1 age
(integer) 1
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;只获取列名&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;hkeys【h kì s】&lt;/code&gt;用于获取哈希表中的所有字段名。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; hkeys【h kì s】 user1
1) &quot;name&quot;
2) &quot;gender&quot;
3) &quot;email&quot;
4) &quot;phone&quot;
5) &quot;address&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;只获取值&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;hvals【h 瓦尔兹】&lt;/code&gt;命令用于获取哈希表中所有字段的值。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; hvals【h 瓦尔兹】 user1
1) &quot;bob&quot;
2) &quot;male&quot;
3) &quot;bob@qcjy.cn&quot;
4) &quot;13412345678&quot;
5) &quot;beijing&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;获得列数量&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;hlen【h 轮】&lt;/code&gt;用于获取哈希表中字段的数量。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; hlen【h 轮】 user1
(integer) 5
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;八、集合类型&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250621155548936.webp&quot; alt=&quot;image-20250621155548936&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;8.1 应用场景&lt;/h3&gt;
&lt;p&gt;Redis【瑞迪斯】 集合类型是一种不允许重复元素的非线性结构，可用于存储和管理元素集合，其应用场景广泛，以下是一些常见的场景：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;用户管理&lt;/strong&gt;：在社交网络中可存储用户特征和记录，轻松检索用户 ID、用户名等信息；也能用于会员管理，保护和检索会员记录。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;网站流量监控&lt;/strong&gt;：将客户端 IP 等唯一标识添加到 Redis【瑞迪斯】 集合中，可有效跟踪网站流量，检测重复访客或恶意行为。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;奖励管理&lt;/strong&gt;：可以跟踪和管理奖励，方便对奖励信息进行添加、查询等操作。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;排行榜&lt;/strong&gt;：在搜索引擎、电影、游戏等场景中，可维护实时热门排行榜榜单。如在游戏里，可存储玩家得分或排名信息，通过集合操作实现排行榜的更新和查询。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;标签系统&lt;/strong&gt;：可用于存储每篇文章或商品的标签，方便根据标签进行分类和搜索。例如新闻网站可以为每篇新闻文章添加标签，用户可以根据标签快速找到感兴趣的文章。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;社交应用&lt;/strong&gt;：可存储用户的好友列表，通过求交集来找出共同的好友，实现共同兴趣的推荐；还能存储关注者信息，进行关注和取消关注的操作。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;唯一性检查&lt;/strong&gt;：集合中的元素具有唯一性，可用于检查元素是否已存在。如在注册系统中，检查用户名是否已被使用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;抽奖活动&lt;/strong&gt;：将参与抽奖的用户 ID 存储在集合中，通过随机获取集合中的元素来实现抽奖功能，保证每个用户只有一次中奖机会。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;点赞和共同关注&lt;/strong&gt;：存储点赞用户的 ID 集合，判断某个用户是否点赞；也可通过集合操作找出多个用户的共同关注对象。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;8.2 无序集合&lt;/h3&gt;
&lt;p&gt;无序集合中的每个元素都是不同的，且没有顺序&lt;/p&gt;
&lt;h4&gt;8.2.1 创建/追加/删除/查看&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;sadd&lt;/code&gt;用于向集合（set）中添加一个或多个成员。集合是一个无序且唯一的字符串集合。命令格式为SADD key member1 member2... 。
例如，执行SADD myset &quot;apple&quot; &quot;banana&quot;，就会将 “apple” 和 “banana” 添加到名为myset的集合中。当需要维护一个唯一值的集合，比如用户标签集合，使用sadd添加标签，可保证标签的唯一性。
&lt;code&gt;srem【s 轮姆】&lt;/code&gt;命令用于移除集合中的一个或多个成员。集合是无序且元素唯一的结构。比如有集合&lt;code&gt;my_set&lt;/code&gt;，执行命令&lt;code&gt;SREM【s 轮姆】 my_set value1 value2&lt;/code&gt;，就会从&lt;code&gt;my_set&lt;/code&gt;集合中移除&lt;code&gt;value1&lt;/code&gt;和&lt;code&gt;value2&lt;/code&gt;。这在管理集合数据，像用户兴趣标签集合，需要删除某些用户不再感兴趣的标签时非常有用。
&lt;code&gt;smembers【s 门伯兹】&lt;/code&gt;用于获取集合中的所有成员。命令格式为&lt;code&gt;SMEMBERS key&lt;/code&gt;。例如，执行&lt;code&gt;SMEMBERS myset&lt;/code&gt;，会返回名为&lt;code&gt;myset&lt;/code&gt;集合中的所有元素。当你需要查看集合内的所有数据，比如查看用户拥有的所有标签时，&lt;code&gt;smembers&lt;/code&gt;就十分有用。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; sadd mylike film muisc game  #创建
(integer) 3
192.168.90.64:6379&amp;gt; type【泰 普】 mylike  #查看数据类型
set
192.168.90.64:6379&amp;gt; sadd mylike sleep game it  #追加，自动删除重复的值
(integer) 2
192.168.90.64:6379&amp;gt; srem【s 轮姆】 mylike sleep game #删除成员
(integer) 2
192.168.90.64:6379&amp;gt; smembers【s 门伯兹】 mylike #查看成员
1) &quot;film&quot;
2) &quot;it&quot;
3) &quot;muisc&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.2.2 判断元素是否在集合中&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;sismember【sis 门伯】&lt;/code&gt;是一个用于判断指定成员是否存在于集合中的命令 。其命令格式为&lt;code&gt;SISMEMBER key member&lt;/code&gt;。假设你有一个名为&lt;code&gt;fruits&lt;/code&gt;的集合，执行&lt;code&gt;SISMEMBER fruits &quot;banana&quot;&lt;/code&gt;，若&lt;code&gt;banana&lt;/code&gt;存在于&lt;code&gt;fruits&lt;/code&gt;集合，该命令返回1；若不存在，则返回0 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; sismember【sis 门伯】 mylike game  #输出0表示不存在
(integer) 0
192.168.90.64:6379&amp;gt; sismember【sis 门伯】 mylike music #输出1表示存在
(integer) 1
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.2.2.1输出成员个数&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;scard【s 卡德】&lt;/code&gt;用于获取集合中成员的数量。命令格式为&lt;code&gt;SCARD key&lt;/code&gt;。例如，对于名为&lt;code&gt;my_set&lt;/code&gt;的集合，执行&lt;code&gt;SCARD my_set&lt;/code&gt;，就会返回该集合包含的元素个数。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; scard【s 卡德】 mylike
(integer) 3
192.168.90.64:6379&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.2.3 集合运算&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; smembers mylike
1) &quot;film&quot;
2) &quot;it&quot;
3) &quot;muisc&quot;
192.168.90.64:6379&amp;gt; sadd helike film music game  sleep
(integer) 4
192.168.90.64:6379&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;合集 sunion【s U凝】&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;sunion【s U凝】&lt;/code&gt;用于返回一个集合的并集，即多个集合中所有不同的元素组成的集合。命令格式为&lt;code&gt;SUNION key1 key2...&lt;/code&gt;。例如，有集合&lt;code&gt;set1&lt;/code&gt;包含元素&lt;code&gt;a&lt;/code&gt;、&lt;code&gt;b&lt;/code&gt;，集合&lt;code&gt;set2&lt;/code&gt;包含元素&lt;code&gt;b&lt;/code&gt;、&lt;code&gt;c&lt;/code&gt;，执行&lt;code&gt;SUNION set1 set2&lt;/code&gt;会返回包含&lt;code&gt;a&lt;/code&gt;、&lt;code&gt;b&lt;/code&gt;、&lt;code&gt;c&lt;/code&gt;的集合。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#合集 重复的只显示一次
192.168.90.64:6379&amp;gt; sunion【s U凝】 mylike helike
1) &quot;game&quot;
2) &quot;it&quot;
3) &quot;muisc&quot;
4) &quot;film&quot;
5) &quot;sleep&quot;
6) &quot;music&quot;
192.168.90.64:6379&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;交集sinter【s 因特尔】&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;sinter【s 因特尔】&lt;/code&gt;用于返回多个集合的交集，即所有给定集合中都存在的元素组成的集合。命令格式为&lt;code&gt;SINTER key1 key2...&lt;/code&gt; 。例如，集合&lt;code&gt;set1&lt;/code&gt;包含&lt;code&gt;a&lt;/code&gt;、&lt;code&gt;b&lt;/code&gt;、&lt;code&gt;c&lt;/code&gt;，集合&lt;code&gt;set2&lt;/code&gt;包含&lt;code&gt;b&lt;/code&gt;、&lt;code&gt;c&lt;/code&gt;、&lt;code&gt;d&lt;/code&gt;，执行&lt;code&gt;SINTER set1 set2&lt;/code&gt;，返回的集合将包含&lt;code&gt;b&lt;/code&gt;、&lt;code&gt;c&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#交集
192.168.90.64:6379&amp;gt; sinter【s 因特尔】 mylike helike
1) &quot;film&quot;
192.168.90.64:6379&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;差集sdiff【s 迪夫】&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;sdiff【s 迪夫】&lt;/code&gt;用于返回给定集合之间的差集。命令格式为&lt;code&gt;SDIFF key1 key2...&lt;/code&gt; 。以两个集合为例，&lt;code&gt;sdiff&lt;/code&gt;会返回在&lt;code&gt;key1&lt;/code&gt;集合中，但不在&lt;code&gt;key2&lt;/code&gt;及后续集合中的所有元素。比如集合&lt;code&gt;set1&lt;/code&gt;包含&lt;code&gt;a&lt;/code&gt;、&lt;code&gt;b&lt;/code&gt;、&lt;code&gt;c&lt;/code&gt;，集合&lt;code&gt;set2&lt;/code&gt;包含&lt;code&gt;b&lt;/code&gt;、&lt;code&gt;c&lt;/code&gt;，执行&lt;code&gt;SDIFF set1 set2&lt;/code&gt;，返回的集合将只包含&lt;code&gt;a&lt;/code&gt; 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#差集: 用第1列的变量和第2列的变量比
192.168.90.64:6379&amp;gt; sdiff【s 迪夫】 mylike helike
1) &quot;it&quot;
2) &quot;muisc&quot;
192.168.90.64:6379&amp;gt; sdiff【s 迪夫】 helike mylike
1) &quot;game&quot;
2) &quot;sleep&quot;
3) &quot;music&quot;
192.168.90.64:6379&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.2.4 随机获得集合中的元素&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;srandmember【s 轮 门伯】&lt;/code&gt;用于从集合中随机返回一个或多个成员。命令格式为&lt;code&gt;SRANDMEMBER key [count]&lt;/code&gt;。若不指定&lt;code&gt;count&lt;/code&gt;，则随机返回一个成员；若指定&lt;code&gt;count&lt;/code&gt;，且为正数，会返回指定数量不重复的成员（若集合元素不足，返回实际数量）；若&lt;code&gt;count&lt;/code&gt;为负数，会返回指定数量可能重复的成员。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 在集合helike中随机取出两个不同元素。
192.168.90.64:6379&amp;gt; srandmember【s 轮 门伯】 helike 2
1) &quot;sleep&quot;
2) &quot;music&quot;
192.168.90.64:6379&amp;gt; srandmember【s 轮 门伯】 helike 2
1) &quot;game&quot;
2) &quot;music&quot;
192.168.90.64:6379&amp;gt; 
# 在集合helike中随机取出两个有可能相同元素。
192.168.90.64:6379&amp;gt; srandmember【s 轮 门伯】 helike -2
1) &quot;film&quot;
2) &quot;music&quot;
192.168.90.64:6379&amp;gt; srandmember【s 轮 门伯】 helike -2
1) &quot;music&quot;
2) &quot;music&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.2.5 集合中随机弹出一个元素&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;spop【s 扑】&lt;/code&gt;用于从集合中随机移除并返回一个成员。命令格式为&lt;code&gt;SPOP key&lt;/code&gt;。例如，对于名为&lt;code&gt;my_set&lt;/code&gt;的集合，执行&lt;code&gt;SPOP my_set&lt;/code&gt;，会从&lt;code&gt;my_set&lt;/code&gt;集合里随机挑选一个元素并删除它，同时返回该元素。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; spop【s 扑】 helike #第1次弹出
&quot;music&quot;
192.168.90.64:6379&amp;gt; spop【s 扑】 helike #第2次弹出
&quot;game&quot;
192.168.90.64:6379&amp;gt; smembers【s 门伯兹】 helike #查看
1) &quot;film&quot;
2) &quot;sleep&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;8.3 有序集合&lt;/h3&gt;
&lt;h4&gt;8.3.1 zadd命令的返回值是新加入到集合中的元素个数&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;zadd&lt;/code&gt;用于向有序集合（Sorted Set）中添加一个或多个成员，同时为每个成员关联一个分数（score），有序集合会根据分数对成员进行排序。命令格式为&lt;code&gt;ZADD key score1 member1 [score2 member2 ...]&lt;/code&gt; 。例如，执行&lt;code&gt;ZADD myzset 10 &quot;apple&quot; 20 &quot;banana&quot;&lt;/code&gt;，就会将“apple”和“banana”添加到名为&lt;code&gt;myzset&lt;/code&gt;的有序集合中，“apple”的分数是10，“banana”的分数是20 。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;zcard&lt;/code&gt;用于获取有序集合中的成员数量。命令格式为&lt;code&gt;ZCARD key&lt;/code&gt;。例如，对于名为&lt;code&gt;myzset&lt;/code&gt;的有序集合，执行&lt;code&gt;ZCARD myzset&lt;/code&gt;，会返回&lt;code&gt;myzset&lt;/code&gt;集合中的元素个数。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;zrange&lt;/code&gt;用于返回有序集合中指定区间内的成员。有序集合成员按分数值递增（从小到大）顺序排列。命令格式为&lt;code&gt;ZRANGE key start stop [WITHSCORES]&lt;/code&gt;。&lt;code&gt;start&lt;/code&gt;和&lt;code&gt;stop&lt;/code&gt;是元素的索引值，索引从0开始，负数表示从集合尾部开始计数， -1 代表最后一个元素。例如，执行&lt;code&gt;ZRANGE myzset 0 2 WITHSCORES&lt;/code&gt;，会返回名为&lt;code&gt;myzset&lt;/code&gt;的有序集合中索引0到2的成员及其分数
&lt;code&gt;withscores&lt;/code&gt;是一个可选参数。当使用它时，命令在返回有序集合成员的同时，还会返回每个成员对应的分数。例如&lt;code&gt;ZRANGE myzset 0 -1 WITHSCORES&lt;/code&gt;，会返回&lt;code&gt;myzset&lt;/code&gt;有序集合中所有成员及其对应的分数。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; zadd scores 88 tom 90 jerry 75 bob 92 alice  #创建变量
(integer) 4
192.168.90.64:6379&amp;gt; type【泰 普】 scores #查看类型
zset
192.168.90.64:6379&amp;gt; zcard【z 卡德】 scores #统计成员个数
(integer) 4
192.168.90.64:6379&amp;gt; zrange【z 轮局】 scores 0 -1  #输出成员名称
1) &quot;bob&quot;
2) &quot;tom&quot;
3) &quot;jerry&quot;
4) &quot;alice&quot;
192.168.90.64:6379&amp;gt; zrange【z 轮局】 scores 0 -1 withscores【维s 科s】  #输出成员名称及对应的值
1) &quot;bob&quot;
2) &quot;75&quot;
3) &quot;tom&quot;
4) &quot;88&quot;
5) &quot;jerry&quot;
6) &quot;90&quot;
7) &quot;alice&quot;
8) &quot;92&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.3.2 获得某个成员的值&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; zscore【z s科】 scores tom
&quot;88&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.3.3  获得指定分数范围的元素&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;zrangebyscore&lt;/code&gt;用于返回有序集合中指定分数区间内的成员。命令格式为&lt;code&gt;ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]&lt;/code&gt; 。&lt;code&gt;min&lt;/code&gt;和&lt;code&gt;max&lt;/code&gt;是分数范围，比如执行&lt;code&gt;ZRANGEBYSCORE myzset 80 100 WITHSCORES&lt;/code&gt;，会返回名为&lt;code&gt;myzset&lt;/code&gt;的有序集合中分数在80（含）到100（含）之间的成员及其分数。&lt;code&gt;WITHSCORES&lt;/code&gt;可选，用于显示成员对应的分数，&lt;code&gt;LIMIT&lt;/code&gt;用于指定返回结果的偏移量和数量。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; zrangebyscore【z 轮局 拜 s科】 scores 80 90 WITHSCORES【维s 科s】
1) &quot;jerry&quot;
2) &quot;85&quot;
3) &quot;tom&quot;
4) &quot;88&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.3.4 增加某个元素的分数&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;zincrby【z 因kuì儿 拜】&lt;/code&gt;用于为有序集合中的成员增加指定的分数。命令格式为&lt;code&gt;ZINCRBY key increment member&lt;/code&gt; 。例如，执行&lt;code&gt;ZINCRBY myzset 5 &quot;player1&quot;&lt;/code&gt;，会将有序集合&lt;code&gt;myzset&lt;/code&gt;中的成员“player1”的分数增加5 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; zincrby【z 因kuì儿 拜】 scores 3 bob
&quot;78&quot;
192.168.90.64:6379&amp;gt; zscore【z s科】 scores bob
&quot;78&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.3.5 获得指定分数范围内的元素个数&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;zcount【z kàn特】&lt;/code&gt;用于统计有序集合中指定分数区间内成员的数量。命令格式为&lt;code&gt;ZCOUNT key min max&lt;/code&gt;。比如执行&lt;code&gt;ZCOUNT myzset 60 80&lt;/code&gt;，就会返回名为&lt;code&gt;myzset&lt;/code&gt;的有序集合中分数在60（含）到80（含）之间的成员数量。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; zcount【z kàn特】 scores 80 90
(integer) 2
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.3.6 删除元素&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;zrem【z 轮姆】&lt;/code&gt;用于从有序集合中移除一个或多个成员。命令格式为&lt;code&gt;ZREM key member [member ...]&lt;/code&gt; 。例如，执行&lt;code&gt;ZREM myzset &quot;member1&quot; &quot;member2&quot;&lt;/code&gt;，会从名为&lt;code&gt;myzset&lt;/code&gt;的有序集合中移除“member1”和“member2” 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; zrem【z 轮姆】 scores bob
(integer) 1
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;8.3.7 获得元素的排名&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;zrank【z 软克】&lt;/code&gt;用于获取有序集合中指定成员的排名。排名从0开始，是按分数从小到大排列的索引值。命令格式为&lt;code&gt;ZRANK key member&lt;/code&gt;。例如，对于有序集合&lt;code&gt;myzset&lt;/code&gt;，执行&lt;code&gt;ZRANK myzset &quot;member1&quot;&lt;/code&gt;，会返回“member1”在&lt;code&gt;myzset&lt;/code&gt;集合中的排名。
&lt;code&gt;zrevrank【z 瑞乌 软克】&lt;/code&gt;与&lt;code&gt;zrank【z 软克】&lt;/code&gt;类似，但它是获取有序集合中指定成员按分数从大到小排列的排名。命令格式为&lt;code&gt;ZREVRANK key member&lt;/code&gt;。例如，在名为&lt;code&gt;myzset&lt;/code&gt;的有序集合里执行&lt;code&gt;ZREVRANK myzset &quot;member1&quot;&lt;/code&gt;，会返回“member1”在&lt;code&gt;myzset&lt;/code&gt;集合中按分数降序排列的排名。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;192.168.90.64:6379&amp;gt; zrank【z 软克】 scores tom   # 获取tom的排名
(integer) 1   # 升序排列，从0开始计数

192.168.90.64:6379&amp;gt; zrevrank【z 瑞乌 软克】 scores alice   # 获取alice的排名
(integer) 0   # 降序排列，从0开始计数
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;九、作业&lt;/h2&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Redis 集合类型中，以下哪个命令用于判断元素是否在集合中？ B
A. sunion
B. sismember
C. sinter
D. sdiff&lt;/li&gt;
&lt;li&gt;若要在 Redis 列表类型中从尾部追加元素，应使用以下哪个命令？C
A. LPUSH
B. RPOP
C. RPUSH
D. LPOP&lt;/li&gt;
&lt;li&gt;Redis 散列类型适合存储以下哪种数据？ C
A. 单一的字符串
B. 有序的元素列表
C. 具有多个属性的对象
D. 不允许重复的无序元素&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2 填空题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Redis 字符串类型中，使用__incr__命令可以让存储的整数值递增。&lt;/li&gt;
&lt;li&gt;在 Redis 列表类型中，用__lpop__命令可以从列表头部弹出元素。&lt;/li&gt;
&lt;li&gt;Redis 集合类型中，用于获取两个集合交集的命令是__sinter__。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3 简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;简述 Redis 散列类型在存储用户信息方面相较于普通 key/value 结构的优势。
答：
相比用普通的 key /value  结构存储， 散列类型存储每个用户对应一个 Hash，以用户 ID 为键名，使用字段表示用户的属性，如姓名、年龄、生日等，而字段值则存储属性值。避免了序列化/反序列化的开销，且在修改其中一项信息时，无需把整个对象取回，也无需引入复杂的并发保护机制。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;请说明 Redis 列表类型可以实现哪些数据结构，以及对应的命令操作。
答：&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;1. 队列：
    127.0.0.1:6379&amp;gt; lpush test3 1 2 3 4    #在列队头部插入元素
    (integer) 7
    127.0.0.1:6379&amp;gt; rpush test3 1 2 3 4    #在列队尾部插入元素
    (integer) 11
    127.0.0.1:6379&amp;gt; lpop test3             #移除并返回队列的第一个元素
    &quot;4&quot;
    127.0.0.1:6379&amp;gt; rpop test3             #移除并返回队列的最后一个元素
    &quot;4&quot;

2. 栈： 

    127.0.0.1:6379&amp;gt; lpush test3 1 2 3 4     #列表左侧（头部） 插入元素
    (integer) 4
    127.0.0.1:6379&amp;gt; lpop test3              #列表左侧（头部） 移除并获取元素
    &quot;4&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;列举 Redis 集合类型的三个常见应用场景。
答：
社交应用
唯一性检查
抽奖活动&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;4 操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;假设你已经连接到 Redis 服务，现在要创建一个散列类型的数据，键名为“product1”，包含字段“name”值为“手机”，“price”值为“3000”，“stock”值为“50”，请写出对应的 Redis 命令。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; hmset product1 name 手机 price 3000 stock 50
OK
127.0.0.1:6379&amp;gt; hmget product1 name price stock
1) &quot;\xe6\x89\x8b\xe6\x9c\xba&quot;
2) &quot;3000&quot;
3) &quot;50&quot;
127.0.0.1:6379&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;有一个 Redis 列表类型的数据“history_list”，请写出命令将元素“操作 1”插入到列表头部，并从列表尾部弹出一个元素。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; lpush history_list A B C
(integer) 3
127.0.0.1:6379&amp;gt; lrange history_list 0 -1 
1) &quot;C&quot;
2) &quot;B&quot;
3) &quot;A&quot;
127.0.0.1:6379&amp;gt; lpush history_list 操作1
(integer) 4
127.0.0.1:6379&amp;gt; lrange history_list 0 -1 
1) &quot;\xe6\x93\x8d\xe4\xbd\x9c1&quot;
2) &quot;C&quot;
3) &quot;B&quot;
4) &quot;A&quot;
127.0.0.1:6379&amp;gt; rpop history_list
&quot;A&quot;
127.0.0.1:6379&amp;gt; lrange history_list 0 -1 
1) &quot;\xe6\x93\x8d\xe4\xbd\x9c1&quot;
2) &quot;C&quot;
3) &quot;B&quot;
127.0.0.1:6379&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;现有两个 Redis 集合“set1”包含元素“a”“b”“c”，“set2”包含元素“b”“c”“d”，请写出命令获取它们的并集、交集和差集。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; sadd set1 a b c
(integer) 3
127.0.0.1:6379&amp;gt; sadd set2 b c d
(integer) 3
127.0.0.1:6379&amp;gt; sunion set1 set2    #并集
1) &quot;b&quot;
2) &quot;a&quot;
3) &quot;d&quot;
4) &quot;c&quot;
127.0.0.1:6379&amp;gt; sinter set1 set2    #交集
1) &quot;b&quot;
2) &quot;c&quot;
127.0.0.1:6379&amp;gt; sdiff set1 set2    #差集
1) &quot;a&quot;
127.0.0.1:6379&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h1&gt;13：redis集群高可用&lt;/h1&gt;
&lt;p&gt;今日工作任务路线图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250623164731874.webp&quot; alt=&quot;image-20250623164731874&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一、工作场景&lt;/h2&gt;
&lt;p&gt;为确保 Redis 服务的高可用和数据持久化，运维团队开始一系列操作。首先，团队搭建了一主一从的 Redis 结构，将 redis67 配置为主服务器，redis68 作为从服务器，实现数据的实时同步和备份。接着，为进一步提高服务的可靠性，在 redis69 上配置了哨兵服务。在一次突发状况中，主服务器 redis67 出现故障，哨兵服务迅速响应，自动将从服务器 redis68 升级为主服务器，保障业务不受影响。当 redis67 恢复后，又自动成为新主服务器的从服务器，确保整个 Redis 服务的稳定运行。&lt;/p&gt;
&lt;h2&gt;二、为什么学&lt;/h2&gt;
&lt;p&gt;在当今数据量激增的时代，企业对数据存储和访问的效率与稳定性要求极高。从文档可知，Redis 若没有高可用机制，一旦主节点故障，业务会中断，数据也可能丢失。而 Redis 高可用方案，如主从复制、哨兵服务、集群部署等，能保障数据的自动备份与实时同步。像哨兵服务可自动监控节点状态，在主节点故障时快速实现故障转移，将从节点提升为主节点。集群部署则能实现数据的分布式存储，避免单点性能瓶颈，让 Redis 服务在各种复杂环境下稳定运行，确保业务的连续性。&lt;/p&gt;
&lt;h2&gt;三、Redis持久化&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250623164803993.webp&quot; alt=&quot;image-20250623164803993&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3.1 使用RDB文件恢复数据&lt;/h3&gt;
&lt;p&gt;创建1台虚拟机&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;redis50&lt;/td&gt;
&lt;td&gt;192.168.90.50&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;配置服务器192.168.90.50&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis50 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis50
[root@redis50 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.50/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis50~]# nmcli connection【肯耐申】 up ens160 

#配置DNS
[root@redis50 ~]# vim /etc/resolv.conf
nameserver 192.168.90.2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤一：设置存盘间隔为120秒且10个key改变数据自动存盘&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;查看 redis服务存储数据到硬盘的存盘频率&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;配置行&lt;/th&gt;
&lt;th&gt;含义&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;save 3600 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;如果 &lt;strong&gt;3600 秒（1 小时）内&lt;/strong&gt;，至少有 &lt;strong&gt;1 个 key 被修改&lt;/strong&gt;，则保存快照。&lt;/td&gt;
&lt;td&gt;最宽松的持久化，防止长时间无备份&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;save 300 100&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;如果 &lt;strong&gt;300 秒（5 分钟）内&lt;/strong&gt;，至少有 &lt;strong&gt;100 个 key 被修改&lt;/strong&gt;，则保存快照。&lt;/td&gt;
&lt;td&gt;中等频率，平衡性能与安全性&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;save 60 10000&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;如果 &lt;strong&gt;60 秒（1 分钟）内&lt;/strong&gt;，至少有 &lt;strong&gt;10,000 个 key 被修改&lt;/strong&gt;，则保存快照。&lt;/td&gt;
&lt;td&gt;高频写入场景下的快速保护&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;[root@redis50 ~]# yum -y install【因-斯多】 redis

#修改之前
[root@redis50 ~]# vim /etc/redis/redis.conf
 383 # save 3600 1
 384 # save 300 100
 385 # save 60 10000
 
#修改之后
[root@redis50 ~]# vim /etc/redis/redis.conf
 383 # save 3600 1
 384 save 120 10
 385 # save 60 10000
 
#启动redis
[root@redis50 ~]# systemctl【西斯屯-ctl】 start【s 达儿】 redis

#目前还没有rdb文件
[root@redis50 ~]# ls /var/lib/redis/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在服务启动后，要在2分钟内存储大于等10个变量&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#存上4个变量
[root@redis50 ~]# redis-cli
127.0.0.1:6379&amp;gt; mset a 1 b 2 c 3 d 4
OK
127.0.0.1:6379&amp;gt; exit

#还没有达到存储的条件，还没有rdb文件
[root@redis50 ~]# ls /var/lib/redis/

#继续存上6个变量
[root@redis50 ~]# redis-cli
127.0.0.1:6379&amp;gt; mset   x 1 y 2  z 3 k 6  i 7  z 9   f 22  zz 99  cc  66
OK
127.0.0.1:6379&amp;gt; exit

#达到条件，数据已经持久化到rdb文件中了
[root@redis50 ~]# ls /var/lib/redis/
dump.rdb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤二：使用RDB文件恢复数据&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#第1步：拷贝 dump.rdb 文件就是对数据的备份
[root@redis50 ~]# cp /var/lib/redis/dump.rdb /opt/
[root@redis50 ~]# ls /opt/
dump.rdb

#第2步：清空数据
[root@redis50 ~]# redis-cli
127.0.0.1:6379&amp;gt; flushall
OK
127.0.0.1:6379&amp;gt; keys *
(empty array)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用备份的dump.rdb文件恢复&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#第1步 停止内存没有数据的redis服务
[root@redis50 ~]# systemctl【西斯屯-ctl】 stop【 s 多】 redis

#第2步 把没有数据的dump.rdb文件删除
[root@redis50 ~]# rm -rf /var/lib/redis/dump.rdb 

#第3步 把备份dump.rdb文件拷贝到数据库目录下
[root@redis50 ~]# cp /opt/dump.rdb /var/lib/redis/

#第4步 启动redis服务 并连接服务查看数据
[root@redis50 ~]# systemctl【西斯屯-ctl】 start【s 达儿】 redis
[root@redis50 ~]# redis-cli
127.0.0.1:6379&amp;gt; keys *
 1) &quot;x&quot;
 2) &quot;a&quot;
 3) &quot;y&quot;
 4) &quot;cc&quot;
 5) &quot;f&quot;
 6) &quot;c&quot;
 7) &quot;zz&quot;
 8) &quot;z&quot;
 9) &quot;d&quot;
10) &quot;i&quot;
11) &quot;k&quot;
12) &quot;b&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 使用AOF文件恢复数据&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;操作步骤
# 1. 在 A 节点（源）安全关闭 Redis（确保 AOF 完整）
redis-cli -h A_host shutdown

# 2. 拷贝 AOF 文件到 B 节点
scp /path/to/appendonly.aof user@B_host:/redis/data/

# 3. 在 B 节点（目标）：
#    - 停止 Redis
#    - 备份/删除原有 AOF 和 RDB
#    - 放入新 AOF 文件
#    - 确保 redis.conf 中 appendonly yes
#    - 启动 Redis

redis-server /etc/redis.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤一：启用AOF&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis50 ~]# redis-cli

#启用aof文件
127.0.0.1:6379&amp;gt; config set appendonly yes  
OK

#查看是否启用
192.168.88.50:6379&amp;gt; config get  appendonly  
1) &quot;appendonly&quot;
2) &quot;yes&quot;

#保存配置
127.0.0.1:6379&amp;gt; config rewrite  
OK
127.0.0.1:6379&amp;gt; exit

#数据库目录多了.aof文件
[root@redis50 ~]# ls /var/lib/redis/
appendonly.aof  dump.rdb

#查看文件行数
[root@redis50 ~]# wc -l /var/lib/redis/appendonly.aof 
2 /var/lib/redis/appendonly.aof

#存放数据
[root@redis50 ~]# redis-cli
127.0.0.1:6379&amp;gt; mset x 1 y 2 z 3
OK
127.0.0.1:6379&amp;gt; keys *
 1) &quot;x&quot;
 2) &quot;a&quot;
 3) &quot;y&quot;
 4) &quot;cc&quot;
 5) &quot;f&quot;
 6) &quot;c&quot;
 7) &quot;zz&quot;
 8) &quot;z&quot;
 9) &quot;d&quot;
10) &quot;i&quot;
11) &quot;k&quot;
12) &quot;b&quot;
127.0.0.1:6379&amp;gt; exit

#查看文件行数
[root@redis50 ~]# wc -l /var/lib/redis/appendonly.aof 
22 /var/lib/redis/appendonly.aof

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤二：使用AOF文件恢复数据&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1）备份aof文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis50 ~]# cp /var/lib/redis/appendonly.aof /opt/
[root@redis50 ~]# ls /opt/
appendonly.aof  dump.rdb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）清空数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis50 ~]# redis-cli
127.0.0.1:6379&amp;gt; flushall
OK
127.0.0.1:6379&amp;gt; exit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3）恢复数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; [root@redis50 ~]# rm -rf  /var/lib/redis/*
 [root@redis70 ~]# cp /opt/appendonly.aof  /var/lib/redis/
 [root@redis70 ~]# chown -R redis:redis /var/lib/redis
 [root@redis50 ~]# systemctl【西斯屯-ctl】 restart redis
 [root@redis50 ~]# redis-cli
 127.0.0.1:6379&amp;gt; keys *
 1) &quot;x&quot;
 2) &quot;a&quot;
 3) &quot;y&quot;
 4) &quot;cc&quot;
 5) &quot;f&quot;
 6) &quot;c&quot;
 7) &quot;zz&quot;
 8) &quot;z&quot;
 9) &quot;d&quot;
10) &quot;i&quot;
11) &quot;k&quot;
12) &quot;b&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、redis高可用集群&lt;/h2&gt;
&lt;p&gt;&amp;lt;img src=&quot;/images/数据库/数据库和监控平台/redis高可用集群.webp&quot; alt=&quot;Redis高可用集群&quot; width=&quot;90%&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250623164832292.webp&quot; alt=&quot;image-20250623164832292&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;4.1 准备环境&lt;/h3&gt;
&lt;p&gt;创建6台新虚拟机&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;redis51&lt;/td&gt;
&lt;td&gt;192.168.90.51&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redis52&lt;/td&gt;
&lt;td&gt;192.168.90.52&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redis53&lt;/td&gt;
&lt;td&gt;192.168.90.53&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redis54&lt;/td&gt;
&lt;td&gt;192.168.90.54&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redis55&lt;/td&gt;
&lt;td&gt;192.168.90.55&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redis56&lt;/td&gt;
&lt;td&gt;192.168.90.56&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;4.1.1 配置redis51&lt;/h4&gt;
&lt;p&gt;配置服务器192.168.90.51&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis51 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis51
[root@redis51 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.51/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis51~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装redis和配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis51 ~]# yum -y install【因-斯多】 redis
#修改4行配置
[root@redis51 ~]# vim /etc/redis/redis.conf
75 bind 0.0.0.0
1387 cluster-enabled yes   #启用集群功能  
1395 cluster-config-file nodes-6379.conf  #存储集群信息文件
1401 cluster-node-timeout 5000  #集群中主机通信超时时间

[root@redis51 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis51 ~]# netstat -utnlp  | grep redis-serve
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      1793/redis-server 0 
tcp        0      0 0.0.0.0:16379           0.0.0.0:*               LISTEN      1793/redis-server 0  
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4.1.1 配置redis52&lt;/h4&gt;
&lt;p&gt;配置服务器192.168.90.52&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis52 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis52
[root@redis52 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.52/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis52~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装redis和配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis52 ~]# yum -y install【因-斯多】 redis
#修改4行配置
[root@redis52 ~]# vim /etc/redis/redis.conf
75 bind 0.0.0.0
1387 cluster-enabled yes   #启用集群功能  
1395 cluster-config-file nodes-6379.conf  #存储集群信息文件
1401 cluster-node-timeout 5000  #集群中主机通信超时时间

[root@redis52 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis52 ~]# netstat -utnlp  | grep redis-serve
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      1758/redis-server 0 
tcp        0      0 0.0.0.0:16379           0.0.0.0:*               LISTEN      1758/redis-server 0   
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4.1.1 配置redis53&lt;/h4&gt;
&lt;p&gt;配置服务器192.168.90.53&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis53 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis53
[root@redis53 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.53/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis53~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装redis和配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis53 ~]# yum -y install【因-斯多】 redis
#修改4行配置
[root@redis53 ~]# vim /etc/redis/redis.conf
75 bind 0.0.0.0
1387 cluster-enabled yes   #启用集群功能  
1395 cluster-config-file nodes-6379.conf  #存储集群信息文件
1401 cluster-node-timeout 5000  #集群中主机通信超时时间

[root@redis53 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis53 ~]# netstat -utnlp  | grep redis-serve
tcp        0      0 0.0.0.0:16379           0.0.0.0:*               LISTEN      1785/redis-server 0 
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      1785/redis-server 0  
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4.1.1 配置redis54&lt;/h4&gt;
&lt;p&gt;配置服务器192.168.90.54&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis54 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis54
[root@redis54 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.54/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis54~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装redis和配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis54 ~]# yum -y install【因-斯多】 redis
#修改4行配置
[root@redis54 ~]# vim /etc/redis/redis.conf
75 bind 0.0.0.0
1387 cluster-enabled yes   #启用集群功能  
1395 cluster-config-file nodes-6379.conf  #存储集群信息文件
1401 cluster-node-timeout 5000  #集群中主机通信超时时间

[root@redis54 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis54 ~]# netstat -utnlp  | grep redis-serve
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      1745/redis-server 0 
tcp        0      0 0.0.0.0:16379           0.0.0.0:*               LISTEN      1745/redis-server 0  
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4.1.1 配置redis55&lt;/h4&gt;
&lt;p&gt;配置服务器192.168.90.55&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis55 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis55
[root@redis55 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.55/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis55~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装redis和配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis55 ~]# yum -y install【因-斯多】 redis
#修改4行配置
[root@redis55 ~]# vim /etc/redis/redis.conf
75 bind 0.0.0.0
1387 cluster-enabled yes   #启用集群功能  
1395 cluster-config-file nodes-6379.conf  #存储集群信息文件
1401 cluster-node-timeout 5000  #集群中主机通信超时时间

[root@redis55 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis55 ~]# netstat -utnlp  | grep redis-serve
tcp        0      0 0.0.0.0:16379           0.0.0.0:*               LISTEN      1778/redis-server 0 
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      1778/redis-server 0  
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4.1.1 配置redis56&lt;/h4&gt;
&lt;p&gt;配置服务器192.168.90.56&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis56 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis56
[root@redis56 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.56/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis56~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装redis和配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis56 ~]# yum -y install【因-斯多】 redis
#修改4行配置
[root@redis56 ~]# vim /etc/redis/redis.conf
75 bind 0.0.0.0
1387 cluster-enabled yes   #启用集群功能  
1395 cluster-config-file nodes-6379.conf  #存储集群信息文件
1401 cluster-node-timeout 5000  #集群中主机通信超时时间

[root@redis56 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis56 ~]# netstat -utnlp  | grep redis-serve
tcp        0      0 0.0.0.0:16379           0.0.0.0:*               LISTEN      1793/redis-server 0 
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      1793/redis-server 0
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 高可用集群原理&lt;/h3&gt;
&lt;h4&gt;4.2.1 架构与节点连接&lt;/h4&gt;
&lt;p&gt;Redis Cluster 采用无中心结构，每个节点保存数据和整个集群状态，且每个节点都和其他所有节点连接。一组三主三从集群由 6 个 Redis 实例组成，其中 3 个为主节点，3 个为从节点，每个主节点至少对应一个从节点 。&lt;/p&gt;
&lt;h4&gt;4.2.2 分布式数据分片&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;哈希槽机制&lt;/strong&gt;：Redis Cluster 将数据划分为 16384 个槽位，每个主节点负责部分槽位。例如，主节点 1 管理槽 0 - 5460，主节点 2 管理 5461 - 10922，主节点 3 管理 10923 - 16383 。当存储一个 key 时，会使用 CRC16 算法计算该 key 的哈希值，然后对 16384 取模，得到所属的槽位，进而将这个 key 分到对应槽位区间的节点上 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自动负载均衡&lt;/strong&gt;：数据按哈希值分配到不同节点，避免单点性能瓶颈。当新增节点时，还可以进行动态地、无中断地数据重新分片 。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;分布式数据分片核心好处&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;水平扩展（Scalability）&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;突破单机性能瓶颈&lt;/strong&gt;：数据和请求负载分散到多个节点，可线性提升吞吐量（QPS）和存储容量。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;动态扩容/缩容&lt;/strong&gt;：通过迁移槽位（如 &lt;code&gt;redis-cli --cluster reshard&lt;/code&gt;），可在不停服的情况下增减节点。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;高可用性（High Availability）&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;自动故障转移&lt;/strong&gt;：每个主节点可配置从节点（replica），主节点宕机时，从节点自动升主（由集群内部 Gossip 协议协调）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;无单点故障&lt;/strong&gt;：即使部分节点失效，其余节点仍可提供服务（只要大多数主节点存活）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;数据分布均衡&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;确定性分片&lt;/strong&gt;：&lt;code&gt;slot = CRC16(key) % 16384&lt;/code&gt; 确保相同 key 总路由到同一节点，避免数据重复。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;均匀分布&lt;/strong&gt;：哈希算法使 key 在槽位间近似均匀分布，结合槽位均分到节点，实现负载均衡。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;客户端智能路由&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MOVED 重定向&lt;/strong&gt;：客户端首次访问错误节点时，返回正确节点地址，后续直接连接目标节点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;本地缓存槽位映射&lt;/strong&gt;：客户端（如 &lt;code&gt;redis-py-cluster&lt;/code&gt;）缓存 &lt;code&gt;slot → node&lt;/code&gt; 映射，减少重定向开销。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;简化运维&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;去中心化架构&lt;/strong&gt;：无中心调度节点，所有节点对等通信（Gossip 协议），避免单点瓶颈。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自动发现与状态同步&lt;/strong&gt;：节点通过 &lt;code&gt;PING/PONG&lt;/code&gt; 消息交换拓扑、故障信息，无需人工干预。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;总结&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Redis 集群的分片机制在 &lt;strong&gt;性能、容量、可用性&lt;/strong&gt; 三者间取得平衡：&lt;br /&gt;
&lt;strong&gt;通过哈希槽实现数据分布式存储，既支持弹性扩展，又保障高可用，同时保持协议简洁高效&lt;/strong&gt;，是 Redis 大规模部署的核心方案。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;4.2.3 主从复制&lt;/h4&gt;
&lt;p&gt;主从节点的数据准实时一致，通过异步的主备复制保证。从节点启动时会连接主节点，发送 SYNC 命令。主节点接收到后，开始执行 BGSAVE 命令生成 RDB 文件，并使用缓冲区记录此后执行的所有写命令。主节点 BGSAVE 执行完后，向从节点发送快照文件，发送期间继续记录写命令。从节点收到快照文件后丢弃旧数据，载入快照。主节点快照发送完毕后，向从节点发送缓冲区中的写命令。之后主节点每执行一个写命令，都会向从节点发送相同的写命令 。&lt;/p&gt;
&lt;p&gt;Redis 主从复制通过异步方式实现数据准实时同步，过程如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;建立连接：从节点启动后，向主节点发起连接，并发送 PSYNC 命令（首次为 PSYNC ? -1）。&lt;/li&gt;
&lt;li&gt;全量同步（必要时）：
主节点收到首次 PSYNC 后，执行 BGSAVE 生成 RDB 快照；
同时将新写命令缓存在复制积压缓冲区（repl_backlog）；
RDB 生成后，主节点将其发送给从节点；
从节点清空本地数据，加载 RDB。&lt;/li&gt;
&lt;li&gt;增量同步：
主节点将 RDB 生成期间及之后的写命令持续发送给从节点；
从节点执行这些命令，保持与主节点一致。&lt;/li&gt;
&lt;li&gt;断线重连优化：
若网络闪断，从节点通过 PSYNC &amp;lt;runid&amp;gt; &amp;lt;offset&amp;gt; 请求部分重同步；
主节点若在 repl_backlog 中找到对应偏移量，则仅发送缺失命令，避免全量同步。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;4.2.4读写分离&lt;/h4&gt;
&lt;p&gt;在 Redis 集群中，写操作只能由主节点处理；读操作既可以在主节点上进行，也可以在从节点上进行，以此分载主节点的读操作压力 。&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/images/数据库/数据库和监控平台/image-20250621174815737.webp&quot; alt=&quot;image-20250621174815737&quot; style=&quot;zoom:200%;&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250621174815737.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;4.3 创建集群&lt;/h3&gt;
&lt;h4&gt;启用集群配置&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# 1. 绑定所有接口（允许外部连接）
bind 0.0.0.0

# 2. 禁用保护模式（因未设密码，有密码情况下可以设置为yes）
protected-mode no

# 3. 监听端口
port 6379

# 4. 不以守护进程方式运行（由 systemd 管理）
daemonize no

# 5. 启用集群模式（核心！）
cluster-enabled yes

# 6. 集群节点超时（毫秒），默认 15000，可调小测试用
cluster-node-timeout 5000

# 7. 集群配置文件（自动生成，不要手动创建）
cluster-config-file nodes-6379.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;说明：&lt;/p&gt;
&lt;p&gt;1、在任意一台redis服务器上都可以执行创建集群的命令。&lt;/p&gt;
&lt;p&gt;2、--cluster-replicas 1 给每个master服务器分配一台slave服务器，每个主至少要分配1台slave服务器，不然无法实现redis服务的高可用。&lt;/p&gt;
&lt;p&gt;3、创建集群时，会自动创建主从角色，默认把主机列表中的前3台服务器创建为 Master角色的redis服务器，剩下的均配置为slave角色服务器。&lt;/p&gt;
&lt;p&gt;4、创建集群时，会自动给master角色的主机分配hash槽 ，通过hash槽实现数据的分布式存储。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis51 ~]# redis-cli --cluster【克拉斯特】 create 192.168.90.51:6379 192.168.90.52:6379 192.168.90.53:6379 192.168.90.54:6379 192.168.90.55:6379 192.168.90.56:6379 --cluster-replicas 1
&amp;gt;&amp;gt;&amp;gt; Creating cluster
&amp;gt;&amp;gt;&amp;gt; Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.90.51:6379
192.168.90.52:6379
192.168.90.53:6379
Adding replica 192.168.90.55:6379 to 192.168.90.51:6379
Adding replica 192.168.90.56:6379 to 192.168.90.52:6379
Adding replica 192.168.90.54:6379 to 192.168.90.53:6379
M: 0eb3b7aa0493a19189cba35b0c658202cc20884b 192.168.90.51:6379
   slots:0-5460 (5461 slots) master
M: a9cb8ccd31bf3eb70433c00906c9f1a99b5e8441 192.168.90.52:6379
   slots:5461-10922 (5462 slots) master
M: f2c1bdb78d8d224c3666fa6440bdf80ba563c581 192.168.90.53:6379
   slots:10923-16383 (5461 slots) master
S: bdba77868965371680fa825badff59bf8ef95a81 192.168.90.54:6379
   replicates f2c1bdb78d8d224c3666fa6440bdf80ba563c581
S: 11510f42bfd9cf667bab5f31c01476d94984200a 192.168.90.55:6379
   replicates 0eb3b7aa0493a19189cba35b0c658202cc20884b
S: fe572ce003ee634c52adc4b42d92d15f847937d7 192.168.90.56:6379
   replicates a9cb8ccd31bf3eb70433c00906c9f1a99b5e8441
Can I set the above configuration? (type &apos;yes&apos; to accept): yes #同意 
....
....
[OK] All nodes agree about slots configuration.
&amp;gt;&amp;gt;&amp;gt; Check for open slots...
&amp;gt;&amp;gt;&amp;gt; Check slots coverage...
[OK] All 16384 slots covered.  //创建成功的提示
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.4 查看集群信息&lt;/h3&gt;
&lt;p&gt;第一列：主服务器ip地址&lt;/p&gt;
&lt;p&gt;第二列：主服务器ID&lt;/p&gt;
&lt;p&gt;第三列：存储变量个数&lt;/p&gt;
&lt;p&gt;第四列：hash槽个数 （hash槽的作用在集群存储工程过程里讲）&lt;/p&gt;
&lt;p&gt;第五列：从服务器数量&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis51 ~]# redis-cli --cluster【克拉斯特】  info【因否】  192.168.90.51:6379
192.168.90.53:6379 (f2c1bdb7...) -&amp;gt; 0 keys | 5461 slots | 1 slaves.
192.168.90.51:6379 (0eb3b7aa...) -&amp;gt; 0 keys | 5461 slots | 1 slaves.
192.168.90.52:6379 (a9cb8ccd...) -&amp;gt; 0 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.5 访问集群&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[root@redis51 ~]# redis-cli  -c -h 192.168.90.51 -p 6379
192.168.90.51:6379&amp;gt; set school  moershi
-&amp;gt; Redirected to slot [8455] located at 192.168.90.52:6379
OK
192.168.90.52:6379&amp;gt; set teacher jam
-&amp;gt; Redirected to slot [12541] located at 192.168.90.53:6379
OK
192.168.90.53:6379&amp;gt; set class NSD
-&amp;gt; Redirected to slot [741] located at 192.168.90.51:6379
OK
192.168.90.51:6379&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;会发现3个变量被分别存储到集群中的3台master服务器上，实现了数据的分布式存储。当连接集群中的任意一台redis服务器存储数据时，会调用集群CRC16算法 得出此次存储变量使用的hash 槽，然后连接hash 槽 所在的master服务器存储变量。
在创建集群时会把默认的16384个槽平均的分配给集群中的3个master服务器。可以通过查看集群信息查看每个master服务器占用hash槽的个数。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis51 ~]# redis-cli  --cluster【克拉斯特】  info【因否】  192.168.90.51:6379
192.168.90.53:6379 (f2c1bdb7...) -&amp;gt; 0 keys | 5461 slots | 1 slaves.
192.168.90.51:6379 (0eb3b7aa...) -&amp;gt; 0 keys | 5461 slots | 1 slaves.
192.168.90.52:6379 (a9cb8ccd...) -&amp;gt; 0 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;集群中slave角色的主机会自动同步master角色主机的数据，实现数据的自动备份，&lt;/p&gt;
&lt;p&gt;分别连接集群中的3台slave服务器查看变量&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis54 ~]# redis-cli -c -h 192.168.90.54 -p 6379
192.168.90.54:6379&amp;gt; keys *
1) &quot;class&quot;
[root@redis55 ~]# redis-cli -c -h 192.168.90.55 -p 6379
192.168.90.55:6379&amp;gt; keys *
1) &quot;school&quot;
[root@redis56 ~]# redis-cli -c -h 192.168.90.56 -p 6379
192.168.90.56:6379&amp;gt; keys *
1) &quot;teacher&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当master角色的服务器宕机时，对应的slave服务器会升级为master 并接手对应的hash槽，实现redis服务的高可用，例如停止host53主机的redis服务，对应的从会升级为master 。(当宕机的master恢复后 自动做当前主的从服务器)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#停止redis服务
[root@redis53 ~]# systemctl【西斯屯-ctl】  stop【 s 多】  redis  
#查看集群信息
[root@redis51 ~]#]# redis-cli --cluster【克拉斯特】  info【因否】  192.168.90.51:6379
192.168.90.54:6379 (f2c1bdb7...) -&amp;gt; 1 keys | 5461 slots | 0 slaves.
192.168.90.51:6379 (0eb3b7aa...) -&amp;gt; 1 keys | 5461 slots | 1 slaves.
192.168.90.52:6379 (a9cb8ccd...) -&amp;gt; 1 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
keys per slot on average.
#启动redis服务
[root@redis53 ~]# systemctl【西斯屯-ctl】  start【s 达儿】  redis 
#查看集群信息
[root@redis51 ~]#]# redis-cli --cluster【克拉斯特】  info【因否】  192.168.90.51:6379
192.168.90.54:6379 (f2c1bdb7...) -&amp;gt; 1 keys | 5461 slots | 1 slaves.
192.168.90.51:6379 (0eb3b7aa...) -&amp;gt; 1 keys | 5461 slots | 1 slaves.
192.168.90.52:6379 (a9cb8ccd...) -&amp;gt; 1 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
keys per slot on average.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、配置主从复制&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250623164908097.webp&quot; alt=&quot;image-20250623164908097&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;5.1 环境准备&lt;/h3&gt;
&lt;p&gt;准备3台新虚拟机&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;redis61&lt;/td&gt;
&lt;td&gt;192.168.90.61&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redis62&lt;/td&gt;
&lt;td&gt;192.168.90.62&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redis63&lt;/td&gt;
&lt;td&gt;192.168.90.63&lt;/td&gt;
&lt;td&gt;redis服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;配置服务器192.168.90.61&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis61 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis61
[root@redis61 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.61/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis61~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置服务器192.168.90.62&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis62 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis62
[root@redis62 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.62/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis62~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置服务器192.168.90.63&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis63 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis63
[root@redis63 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.63/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis63~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 配置一主一从结构&lt;/h3&gt;
&lt;p&gt;1）配置redis61为主服务器&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis61 ~]# yum -y install【因-斯多】 redis
[root@redis61 ~]# vim /etc/redis/redis.conf
75 bind 0.0.0.0
[root@redis61 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis61 ~]# redis-cli
127.0.0.1:6379&amp;gt; info【因否】 replication  #查看主从关系信息
# Replication
role:master   # 默认就是主服务器
connected_slaves:0  #没有从服务器
master_failover_state:no-failover
master_replid:bd86b885e9e6b21e452696d472e2b2852c7fea72
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）配置redids62为redis61的从服务器&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis62 ~]# yum -y install【因-斯多】 redis
[root@redis62 ~]# vim /etc/redis/redis.conf
75 bind 0.0.0.0
[root@redis62 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis62 ~]# redis-cli
127.0.0.1:6379&amp;gt; replicaof 192.168.90.61 6379  #指定主服务器ip和端口
OK
127.0.0.1:6379&amp;gt; config rewrite  #永久保存配置
OK
127.0.0.1:6379&amp;gt; exit
#查看文件末尾
[root@redis62 ~]# tail -1 /etc/redis/redis.conf  
replicaof 192.168.90.61 6379
[root@redis62 ~]# redis-cli
127.0.0.1:6379&amp;gt; info【因否】 replication  #查看主从关系信息
# Replication
role:slave   #从角色
master_host:192.168.90.61  #主服务器ip地址 
master_port:6379  #主服务器端口号
master_link_status:up  #与主服务器连接状态 （up 正常  down 连接失败）
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_read_repl_offset:84
slave_repl_offset:84
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:f2fde7a2f3f7c6b3a20b1223b0c35ba55b245d0c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:84
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:84
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3）在主服务器redis61查看复制信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:master  #主角色
connected_slaves:1  #一个从
slave0:ip=192.168.90.62,port=6379,state=online,offset=98,lag=0 #从服务器信息
master_failover_state:no-failover
master_replid:f2fde7a2f3f7c6b3a20b1223b0c35ba55b245d0c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:98
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:98
127.0.0.1:6379&amp;gt; mset x 1 y 2 z 3  #存储数据
OK
127.0.0.1:6379&amp;gt; keys *
1) &quot;x&quot;
2) &quot;z&quot;
3) &quot;y&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4）在从服务器查看是否同步数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; keys *
1) &quot;x&quot;
2) &quot;z&quot;
3) &quot;y&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.3 配置一主多从结构&lt;/h3&gt;
&lt;p&gt;把redis63也配置为redis61的从服务器&lt;/p&gt;
&lt;p&gt;1）配置redis63为redis61的从服务器&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis63 ~]# yum -y install【因-斯多】 redis
[root@redis63 ~]# vim /etc/redis/redis.conf
75 bind 0.0.0.0
[root@redis63 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis63 ~]# redis-cli
127.0.0.1:6379&amp;gt; replicaof 192.168.90.61 6379  #指定主服务器ip和端口
OK
127.0.0.1:6379&amp;gt; config rewrite  #永久保存配置
OK
127.0.0.1:6379&amp;gt; exit
#查看文件末尾
[root@redis62 ~]# tail -1 /etc/redis/redis.conf  
replicaof 192.168.90.61 6379
[root@redis63 ~]# redis-cli
127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:slave
master_host:192.168.90.61
master_port:6379
master_link_status:up
master_last_io_seconds_ago:10
master_sync_in_progress:0
slave_read_repl_offset:1507
slave_repl_offset:1507
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:f2fde7a2f3f7c6b3a20b1223b0c35ba55b245d0c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1507
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1466
127.0.0.1:6379&amp;gt; keys *
1) &quot;y&quot;
2) &quot;z&quot;
3) &quot;x&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在redis61 查看到有2台从服务器&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:master
connected_slaves:2  #2个从服务器
slave0:ip=192.168.90.62,port=6379,state=online,offset=1591,lag=0  #从1
slave1:ip=192.168.90.63,port=6379,state=online,offset=1591,lag=1  #从2
master_failover_state:no-failover
master_replid:f2fde7a2f3f7c6b3a20b1223b0c35ba55b245d0c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1591
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1591

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.4 配置主从从结构&lt;/h3&gt;
&lt;p&gt;把redis63恢复为独立的redis服务器，然后配置为redis62的从服务器&lt;/p&gt;
&lt;p&gt;1）配置redis63&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; replicaof no one #恢复为独立的数据库服务器
OK
127.0.0.1:6379&amp;gt; replicaof 192.168.90.62 6379  #指定主服务器为62
OK
127.0.0.1:6379&amp;gt; config rewrite #保存配置
OK
127.0.0.1:6379&amp;gt; exit
@查看是否保存
[root@redis63 ~]# tail -1 /etc/redis/redis.conf
replicaof 192.168.90.62 6379
[root@redis63 ~]# redis-cli
127.0.0.1:6379&amp;gt; info【因否】 replication  #查看主从关系信息
# Replication
role:slave #从角色
master_host:192.168.90.62 #主服务器IP
master_port:6379  #主服务端口
master_link_status:up #与主服务器连接状态
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_read_repl_offset:2025
slave_repl_offset:2025
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:f2fde7a2f3f7c6b3a20b1223b0c35ba55b245d0c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2025
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1956
repl_backlog_histlen:70
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）在redis62查看复制信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:slave  #本身是从服务器
master_host:192.168.90.61  #主服务器ip
master_port:6379  #主服务器redis服务端口
master_link_status:up   #与主服务器连接状态
master_last_io_seconds_ago:6
master_sync_in_progress:0
slave_read_repl_offset:2291
slave_repl_offset:2291
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:1  #本身有一个从服务器
slave0:ip=192.168.90.63,port=6379,state=online,offset=2291,lag=0 #从服务器信息
master_failover_state:no-failover
master_replid:f2fde7a2f3f7c6b3a20b1223b0c35ba55b245d0c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2291
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2291
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3)在redis61上查看信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:master
connected_slaves:1 #只有一个从了
slave0:ip=192.168.90.62,port=6379,state=online,offset=2403,lag=0
master_failover_state:no-failover
master_replid:f2fde7a2f3f7c6b3a20b1223b0c35ba55b245d0c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2403
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2403
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、置带验证的主从复制&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250623164933059.webp&quot; alt=&quot;image-20250623164933059&quot; /&gt;&lt;/p&gt;
&lt;p&gt;基于案例1做如下配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;配置主机redis61，redis服务连接密码为123456&lt;/li&gt;
&lt;li&gt;主机redis62设置连接redis61的redis服务密码&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;给redis61主机的Redis服务设置连接密码，如果从服务器不指定连接密码无法同步数据。&lt;/p&gt;
&lt;h3&gt;6.1 配置主机redis61&lt;/h3&gt;
&lt;p&gt;redis服务连接密码为123456&lt;/p&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis61 ~]# redis-cli
127.0.0.1:6379&amp;gt; config get requirepass  #查看密码，默认服务没有密码
1) &quot;requirepass&quot;
2) &quot;&quot;
127.0.0.1:6379&amp;gt; config set requirepass 123456  #设置密码
OK
127.0.0.1:6379&amp;gt; auth 123456  #密码登录
OK
127.0.0.1:6379&amp;gt; config rewrite #保存配置
OK
127.0.0.1:6379&amp;gt; exit
#保存到文件的的密码
[root@redis61 ~]# grep &quot;123456&quot; /etc/redis/redis.conf 
requirepass &quot;123456&quot;
#重启redis服务
[root@redis61 ~]# systemctl【西斯屯-ctl】 restart redis  
[root@redis61 ~]# redis-cli
127.0.0.1:6379&amp;gt; auth 123456 
OK
127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:master
connected_slaves:0 # 没有从服务器了 因为从没有输入连接密码连接不上主服务器
master_failover_state:no-failover
master_replid:7f7c394d93a5df791bbdfb207cdeaf1eb506358f
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.2 主机redis62设置连接redis61的redis服务密码&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#重启redis服务
[root@redis62 ~]# systemctl【西斯屯-ctl】 restart redis
[root@redis62 ~]# redis-cli
127.0.0.1:6379&amp;gt; info【因否】 replication  #查看主从关系信息
# Replication
role:slave
master_host:192.168.90.61
master_port:6379
master_link_status:down  #没设置密码 与master主机是断开状态
master_last_io_seconds_ago:-1
master_sync_in_progress:1
slave_read_repl_offset:1
slave_repl_offset:1
master_sync_total_bytes:-1
master_sync_read_bytes:0
master_sync_left_bytes:-1
master_sync_perc:-0.00
master_sync_last_io_seconds_ago:0
master_link_down_since_seconds:-1
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:f2fde7a2f3f7c6b3a20b1223b0c35ba55b245d0c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:3383
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;指定主服务器的密码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; config set masterauth 123456  #指定主服务器密码
OK
127.0.0.1:6379&amp;gt; config rewrite  #保存配置
OK
127.0.0.1:6379&amp;gt; info【因否】 replication  #查看主从信息
# Replication
role:slave
master_host:192.168.90.61
master_port:6379
master_link_status:up  #现在是启动状态
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_read_repl_offset:28
slave_repl_offset:28
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:1
slave0:ip=192.168.90.63,port=6379,state=online,offset=28,lag=1
master_failover_state:no-failover
master_replid:a288cad0a8747569f147c06bb63237b2751a9fb4
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:28
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:28
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3)在redis61上查看信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis61 ~]# redis-cli
127.0.0.1:6379&amp;gt; auth 123456
OK
127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.90.62,port=6379,state=online,offset=70,lag=1
master_failover_state:no-failover
master_replid:a288cad0a8747569f147c06bb63237b2751a9fb4
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:70
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:70

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;七、哨兵服务&lt;/h2&gt;
&lt;p&gt;当前任务环节&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250623164956680.webp&quot; alt=&quot;image-20250623164956680&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;7.1环境准备&lt;/h3&gt;
&lt;p&gt;准备3台新的虚拟机&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;IP地址&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;redis67&lt;/td&gt;
&lt;td&gt;192.168.90.67&lt;/td&gt;
&lt;td&gt;Master服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redis68&lt;/td&gt;
&lt;td&gt;192.168.90.68&lt;/td&gt;
&lt;td&gt;Slave服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redis69&lt;/td&gt;
&lt;td&gt;192.168.90.69&lt;/td&gt;
&lt;td&gt;哨兵服务&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;说明：&lt;/p&gt;
&lt;p&gt;1）可以使用一主一从或 一主多从 或 主从从 + 哨兵服务 做服务的高可用 和 数据自动备份&lt;/p&gt;
&lt;p&gt;2）如果主从结构中的redis服务设置连接密码的话必须全每台数据库都要设置密码且密码要一样，要么全都不设置密码。&lt;/p&gt;
&lt;p&gt;3）如果Redis服务有密码宕机的服务器启动服务后，要人为指定主服务器的连接密码。&lt;/p&gt;
&lt;p&gt;配置服务器192.168.90.67&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis67 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis67
[root@redis67 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.67/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis67~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置服务器192.168.90.68&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis68 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis68
[root@redis68 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.68/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis68~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置服务器192.168.90.69&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis69 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis69
[root@redis69 ~]# nmcli connection【肯耐申】 modify【莫迪fái】 ens160 ipv4.addresses【额拽西斯】 192.168.90.69/24 autoconnect【奥特欧 坑聂特】 yes
[root@redis69~]# nmcli connection【肯耐申】 up ens160 

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.2 哨兵服务的原理&lt;/h3&gt;
&lt;p&gt;Redis哨兵是一种分布式高可用解决方案，用于实现主从自动故障转移、集群监控以及充当配置中心自动更新客户端连接信息。其工作原理主要分为三个阶段：监控、共识和故障转移 。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;监控（Monitoring）&lt;/strong&gt;：哨兵每秒向主/从节点发送PING命令，若节点超时（down-after-milliseconds，默认30s）无响应，该哨兵会将其标记为主观下线（SDOWN）。即单个哨兵认为实例不可用（PING无响应超过 down-after-milliseconds 配置） 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;共识（Agreement）&lt;/strong&gt;：哨兵集群通过Gossip协议交换节点状态。当多数哨兵（≥ quorum）都认为主节点下线时，会将其标记为客观下线（ODOWN）。也就是当足够数量（quorum配置）的哨兵都认为主节点不可用时，才判定主节点真正不可用 。&lt;/li&gt;
&lt;li&gt;故障转移（Failover）
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;选举领导者哨兵&lt;/strong&gt;：基于Raft协议进行选举。发现主节点ODOWN的哨兵发起选举，每个哨兵在每个配置纪元（epoch）仅投一票，最先获得多数票（≥ N/2 + 1）的哨兵当选为领导者哨兵来执行故障转移；若选举超时（默认100ms），则会重新发起选举 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;选择新主节点&lt;/strong&gt;：从从节点中选出新主节点，选择规则依次基于优先级（slave-priority配置）、复制偏移量（选择数据最新的）、运行ID（选择较小的）。先排除已下线节点和replica-priority = 0的节点，然后选择优先级最高、复制偏移量最大、Run ID最小的节点 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;重新配置&lt;/strong&gt;：领导者哨兵将选中的从节点提升为主节点（执行SLAVEOF NO ONE命令）；通知其他从节点复制新的主节点（执行SLAVEOF new_master_ip port命令）；当旧主节点恢复时，将其配置为新主节点的从节点 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;通知客户端&lt;/strong&gt;：通过Redis的发布/订阅机制，将新主节点的IP和端口信息推送给客户端，让客户端更新配置，连接到新的主节点 。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;7.3 配置主机redis67为master服务器&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis67 ~]# yum -y install【因-斯多】 redis
#替换掉75行
[root@redis67 ~]# sed -i &quot;75c bind 0.0.0.0&quot; /etc/redis/redis.conf
[root@redis67 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis67 ~]# redis-cli
127.0.0.1:6379&amp;gt; info【因否】 replication  #查看主从关系信息
# Replication
role:master   # 默认就是主服务器
connected_slaves:0  #没有从服务器
master_failover_state:no-failover
master_replid:bd86b885e9e6b21e452696d472e2b2852c7fea72
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.4 配置主机redis68为redis67的slave服务器&lt;/h3&gt;
&lt;p&gt;命令操作如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis68 ~]# yum -y install【因-斯多】 redis
[root@redis68 ~]# sed -i &quot;75c bind 0.0.0.0&quot; /etc/redis/redis.conf
[root@redis68 ~]# systemctl【西斯屯-ctl】   start【s 达儿】  redis
[root@redis68 ~]# redis-cli
127.0.0.1:6379&amp;gt; replicaof 192.168.90.67 6379  #指定主服务器ip和端口
OK
127.0.0.1:6379&amp;gt; config rewrite  #永久保存配置
OK
127.0.0.1:6379&amp;gt; exit
#查看文件末尾
[root@redis68 ~]# tail -1 /etc/redis/redis.conf  
replicaof 192.168.90.67 6379
[root@redis62 ~]# redis-cli
127.0.0.1:6379&amp;gt; info【因否】 replication  #查看主从关系信息
# Replication
role:slave   #从角色
master_host:192.168.90.67  #主服务器ip地址 
master_port:6379  #主服务器端口号
master_link_status:up  #与主服务器连接状态 （up 正常  down 连接失败）
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_read_repl_offset:84
slave_repl_offset:84
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:f2fde7a2f3f7c6b3a20b1223b0c35ba55b245d0c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:84
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:84
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.5 配置主机redis69运行哨兵服务&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;安装redis软件，启动哨兵服务&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;[root@redis68 ~]# yum -y install【因-斯多】 redis
#哨兵配置文件
[root@redis69 ~]# vim /etc/redis/sentinel.conf 
15 bind 0.0.0.0
26 daemonize yes
84 sentinel monitor mymaster 192.168.90.67 6379 1

#启动哨兵服务
[root@redis69 ~]# systemctl【西斯屯-ctl】  start【s 达儿】 redis-sentinel
#查看端口号
[root@redis69 ~]#  netstat  -utnlp  | grep 26379  
tcp        0      0 0.0.0.0:26379           0.0.0.0:*               LISTEN      2179/redis-sentinel 
[root@redis69 ~]# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2）查看日志获取监视信息&lt;/p&gt;
&lt;p&gt;复制一个终端会话&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis69 ~]# tail -f /var/log/redis/sentinel.log 
2179:X 23 Jun 2025 15:47:44.301 * Supervised by systemd. Please make sure you set appropriate values for TimeoutStartSec and TimeoutStopSec in your service unit.
2179:X 23 Jun 2025 15:47:44.301 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2179:X 23 Jun 2025 15:47:44.301 # Redis version=6.2.18, bits=64, commit=00000000, modified=0, pid=2179, just started
2179:X 23 Jun 2025 15:47:44.301 # Configuration loaded
2179:X 23 Jun 2025 15:47:44.302 * monotonic clock: POSIX clock_gettime
2179:X 23 Jun 2025 15:47:44.302 * Running mode=sentinel, port=26379.
2179:X 23 Jun 2025 15:47:44.304 # Sentinel ID is 5ab8d490e1e7b600170a2a725b4679d25186b4d1
2179:X 23 Jun 2025 15:47:44.304 # +monitor master mymaster 192.168.90.67 6379 quorum 1
2179:X 23 Jun 2025 15:47:44.306 * +slave slave 192.168.90.68:6379 192.168.90.68 6379 @ mymaster 192.168.90.67 6379
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.6 测试配置&lt;/h3&gt;
&lt;p&gt;思路：停止master主机的redis 服务，原slave角色会升级为主，哨兵服务会自动监视新的master服务，宕机的master 主机恢复后自动配置为当前主的从服务器。&lt;/p&gt;
&lt;p&gt;停止master主机的redis 服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis67 ~]# systemctl【西斯屯-ctl】 stop【 s 多】 redis
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看slave&lt;/p&gt;
&lt;p&gt;原slave角色会升级为主&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:slave
master_host:192.168.90.67
master_port:6379
master_link_status:down  #master宕机了
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_read_repl_offset:22602
slave_repl_offset:22602
master_link_down_since_seconds:27
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:0f9c32408bfd386ab9c9ef00617298a969e89c73
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:22602
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1

#重新登录
[root@redis68 ~]#  redis-cli
127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:master #升级为master
connected_slaves:0
master_failover_state:no-failover
master_replid:8289cfb1acb8573be217df886ac24732f2bdb6a9
master_replid2:0f9c32408bfd386ab9c9ef00617298a969e89c73
master_repl_offset:25586
second_repl_offset:22603
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;哨兵服务会自动监视新的master服务&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/image-20250623155722362.webp&quot; alt=&quot;image-20250623155722362&quot; /&gt;&lt;/p&gt;
&lt;p&gt;宕机的master 主机恢复后自动配置为当前主的从服务器。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@redis67 ~]# redis-cli
127.0.0.1:6379&amp;gt; info【因否】 replication
Error: Server closed the connection【肯耐申】
127.0.0.1:6379&amp;gt; info【因否】 replication
# Replication
role:slave  #变成从服务器
master_host:192.168.90.68  #现在主服务器是192.168.90.68 
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_read_repl_offset:41965
slave_repl_offset:41965
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:8289cfb1acb8573be217df886ac24732f2bdb6a9
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:41965
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:41520
repl_backlog_histlen:446

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;八、作业&lt;/h2&gt;
&lt;h3&gt;1 选择题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Redis 哨兵将主节点标记为客观下线（ODOWN）的条件是？ B
A. 单个哨兵认为主节点不可用
B. 多数哨兵（≥ quorum）都认为主节点下线
C. 主节点主动发出下线通知
D. 主节点超过 1 分钟无响应&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Redis Cluster 采用的分布式数据分片机制是？ A
A. 哈希槽机制
B. 随机分配机制
C. 轮询机制
D. 顺序分配机制&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 Redis 主从复制中，从节点启动时会向主节点发送什么命令？ A
A. SYNC 命令
B. SAVE 命令
C. FLUSHALL 命令
D. info 命令&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2 简答题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;简述 Redis 哨兵服务的工作原理。
答：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;监控（Monitoring）：哨兵每秒向主/从节点发送PING命令，若节点超时（down-after-milliseconds，默认30s）无响应，该哨兵会将其标记为主观下线（SDOWN）。即单个哨兵认为实例不可用（PING无响应超过 down-after-milliseconds 配置） 。&lt;/li&gt;
&lt;li&gt;共识（Agreement）：哨兵集群通过Gossip协议交换节点状态。当多数哨兵（≥ quorum）都认为主节点下线时，会将其标记为客观下线（ODOWN）。也就是当足够数量（quorum配置）的哨兵都认为主节点不可用时，才判定主节点真正不可用 。&lt;/li&gt;
&lt;li&gt;故障转移（Failover）
&lt;ul&gt;
&lt;li&gt;选举领导者哨兵：基于Raft协议进行选举。发现主节点ODOWN的哨兵发起选举，每个哨兵在每个配置纪元（epoch）仅投一票，最先获得多数票（≥ N/2 + 1）的哨兵当选为领导者哨兵来执行故障转移；若选举超时（默认100ms），则会重新发起选举 。&lt;/li&gt;
&lt;li&gt;选择新主节点：从从节点中选出新主节点，选择规则依次基于优先级（slave-priority配置）、复制偏移量（选择数据最新的）、运行ID（选择较小的）。先排除已下线节点和replica-priority = 0的节点，然后选择优先级最高、复制偏移量最大、Run ID最小的节点 。&lt;/li&gt;
&lt;li&gt;重新配置：领导者哨兵将选中的从节点提升为主节点（执行SLAVEOF NO ONE命令）；通知其他从节点复制新的主节点（执行SLAVEOF new_master_ip port命令）；当旧主节点恢复时，将其配置为新主节点的从节点 。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;通知客户端：通过Redis的发布/订阅机制，将新主节点的IP和端口信息推送给客户端，让客户端更新配置，连接到新的主节点 。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;说明 Redis 集群中分布式数据分片的好处。
答：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;水平扩展：突破单机性能瓶颈，将数据和请求负载分散到多个节点，可线性提升吞吐量（QPS）和存储容量。动态扩容在通过迁移槽位（如 redis-cli --cluster reshard），可在不停服的情况下增减节点。&lt;/li&gt;
&lt;li&gt;高可用性：自动故障转移，每个主节点可配置从节点（replica），主节点宕机时，从节点自动升主，主节点恢复自从加入新主节点的从节点。无单点故障，即使部分节点失效，其余节点仍可提供服务（只要大多数主节点存活）。&lt;/li&gt;
&lt;li&gt;数据分布均衡：确定性分片，如slot = CRC16(key) % 16384 确保相同 key 总路由到同一节点，避免数据重复。均匀分布，哈希算法使 key 在槽位间近似均匀分布，结合槽位均分到节点，实现负载均衡。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;请阐述 Redis 主从复制的过程。
答：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;建立连接：从节点启动后，向主节点发起连接，并发送 PSYNC 命令（首次为 PSYNC ? -1）。&lt;/li&gt;
&lt;li&gt;主节点收到首次 PSYNC 后，执行 BGSAVE 生成 RDB 快照，同时将新写命令缓存在复制积压缓冲区（repl_backlog），DB 生成后，主节点将其发送给从节点，从节点清空本地数据，加载 RDB。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3 操作题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;请写出配置 Redis 一主一从结构的详细步骤。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;[root@redis60 ~]#     主配置
[root@redis60 ~]# systemctl start redis.service 
[root@redis60 ~]# redis-cli
127.0.0.1:6379&amp;gt; config set protected-mode no
OK
127.0.0.1:6379&amp;gt; config rewrite
OK
127.0.0.1:6379&amp;gt; info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:2aae21339753d355129c78fab17bd7a1c547aedf
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0



[root@redis61 ~]#     从配置
[root@redis61 ~]# systemctl start redis.service 
[root@redis61 ~]# redis-cli 
127.0.0.1:6379&amp;gt; config set protected-mode no
OK
127.0.0.1:6379&amp;gt; config rewrite
OK
127.0.0.1:6379&amp;gt; replicaof 192.168.88.60 6379
OK
127.0.0.1:6379&amp;gt; config rewrite
OK
127.0.0.1:6379&amp;gt; info replication
# Replication
role:slave
master_host:192.168.88.60
master_port:6379
master_link_status:up
master_last_io_seconds_ago:9
master_sync_in_progress:0
slave_read_repl_offset:224
slave_repl_offset:224
replica_full_sync_buffer_size:0
replica_full_sync_buffer_peak:0
master_current_sync_attempts:160
master_total_sync_attempts:160
master_link_up_since_seconds:154
total_disconnect_time_sec:0
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:a321b83129695ff3cea398fd398097e9b99f63f5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:224
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:210
127.0.0.1:6379&amp;gt; 


127.0.0.1:6379&amp;gt;    主redis状态检查
127.0.0.1:6379&amp;gt; info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.88.61,port=6379,state=online,offset=266,lag=1
master_failover_state:no-failover
master_replid:a321b83129695ff3cea398fd398097e9b99f63f5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:266
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:266
127.0.0.1:6379&amp;gt; 



127.0.0.1:6379&amp;gt;     验证：主写入数据
127.0.0.1:6379&amp;gt; mset a 1 b 2 c 3 d 4 e 5 f 6 
OK
127.0.0.1:6379&amp;gt; 

127.0.0.1:6379&amp;gt;     验证：从数据读取
127.0.0.1:6379&amp;gt; keys *
1) &quot;a&quot;
2) &quot;d&quot;
3) &quot;f&quot;
4) &quot;b&quot;
5) &quot;c&quot;
6) &quot;e&quot;
127.0.0.1:6379&amp;gt; mget a b c d e f
1) &quot;1&quot;
2) &quot;2&quot;
3) &quot;3&quot;
4) &quot;4&quot;
5) &quot;5&quot;
6) &quot;6&quot;
127.0.0.1:6379&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;描述创建 Redis 高可用集群的具体操作过程。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;# 集群配置

[root@redis59 ~]# 
[root@redis59 ~]# grep -vE &quot;^\s*($|#)&quot; /opt/redis/conf/redis.conf | grep -nE &quot;bind|protected-mode|port|daemonize|cluster&quot;
1:bind 0.0.0.0
2:protected-mode no
3:port 6379
7:daemonize no
51:cluster-enabled yes
52:cluster-config-file nodes-6379.conf
53:cluster-node-timeout 5000
[root@redis59 ~]# systemctl start redis.service

[root@redis60 ~]# 
[root@redis60 ~]# grep -vE &quot;^\s*($|#)&quot; /opt/redis/conf/redis.conf | grep -nE &quot;bind|protected-mode|port|daemonize|cluster&quot;
1:bind 0.0.0.0
2:protected-mode no
3:port 6379
7:daemonize no
51:cluster-enabled yes
52:cluster-config-file nodes-6379.conf
53:cluster-node-timeout 5000
[root@redis60 ~]# systemctl start redis.service

[root@redis61 ~]# 
[root@redis61 ~]# grep -vE &quot;^\s*($|#)&quot; /opt/redis/conf/redis.conf | grep -nE &quot;bind|protected-mode|port|daemonize|cluster&quot;
1:bind 0.0.0.0
2:protected-mode no
3:port 6379
7:daemonize no
51:cluster-enabled yes
52:cluster-config-file nodes-6379.conf
53:cluster-node-timeout 5000
[root@redis61 ~]# systemctl start redis.service

[root@redis62 ~]# 
[root@redis62 ~]# grep -vE &quot;^\s*($|#)&quot; /opt/redis/conf/redis.conf | grep -nE &quot;bind|protected-mode|port|daemonize|cluster&quot;
1:bind 0.0.0.0
2:protected-mode no
3:port 6379
7:daemonize no
51:cluster-enabled yes
52:cluster-config-file nodes-6379.conf
53:cluster-node-timeout 5000
[root@redis62 ~]# systemctl start redis.service

[root@redis63 ~]# 
[root@redis63 ~]# grep -vE &quot;^\s*($|#)&quot; /opt/redis/conf/redis.conf | grep -nE &quot;bind|protected-mode|port|daemonize|cluster&quot;
1:bind 0.0.0.0
2:protected-mode no
3:port 6379
7:daemonize no
51:cluster-enabled yes
52:cluster-config-file nodes-6379.conf
53:cluster-node-timeout 5000
[root@redis63 ~]# systemctl start redis.service

[root@redis64 ~]# 
[root@redis64 ~]# grep -vE &quot;^\s*($|#)&quot; /opt/redis/conf/redis.conf | grep -nE &quot;bind|protected-mode|port|daemonize|cluster&quot;
1:bind 0.0.0.0
2:protected-mode no
3:port 6379
7:daemonize no
51:cluster-enabled yes
52:cluster-config-file nodes-6379.conf
53:cluster-node-timeout 5000
[root@redis64 ~]# systemctl start redis.service


[root@redis59 ~]#     搭建集群 
[root@redis59 ~]# redis-cli --cluster create 192.168.88.59:6379 192.168.88.60:6379 192.168.88.61:6379 192.168.88.62:6379 192.168.88.63:6379 192.168.88.64:6379 --cluster-replicas 1
&amp;gt;&amp;gt;&amp;gt; Performing hash slots allocation on 6 nodes...
Master[0] -&amp;gt; Slots 0 - 5460
Master[1] -&amp;gt; Slots 5461 - 10922
Master[2] -&amp;gt; Slots 10923 - 16383
Adding replica 192.168.88.63:6379 to 192.168.88.59:6379
Adding replica 192.168.88.64:6379 to 192.168.88.60:6379
Adding replica 192.168.88.62:6379 to 192.168.88.61:6379
M: 4f75181056b5aefd90f2b1cc242e105f929ec5b4 192.168.88.59:6379
   slots:[0-5460] (5461 slots) master
M: e92ce91b5b3b4587c5520482e7a825b050d02dee 192.168.88.60:6379
   slots:[5461-10922] (5462 slots) master
M: 8f23c1c05cda60f570d70543c5ea3e5bf643c89c 192.168.88.61:6379
   slots:[10923-16383] (5461 slots) master
S: fa61df96aea2f9a53427eae75fd0c82e4b916ffb 192.168.88.62:6379
   replicates 8f23c1c05cda60f570d70543c5ea3e5bf643c89c
S: 1ca6b10204e7df92340b5c8318416340d4c5ec6b 192.168.88.63:6379
   replicates 4f75181056b5aefd90f2b1cc242e105f929ec5b4
S: 0d342ee7810cadea394eb62a7da4e3a1f320f680 192.168.88.64:6379
   replicates e92ce91b5b3b4587c5520482e7a825b050d02dee
Can I set the above configuration? (type &apos;yes&apos; to accept): yes
&amp;gt;&amp;gt;&amp;gt; Nodes configuration updated
&amp;gt;&amp;gt;&amp;gt; Assign a different config epoch to each node
&amp;gt;&amp;gt;&amp;gt; Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join

&amp;gt;&amp;gt;&amp;gt; Performing Cluster Check (using node 192.168.88.59:6379)
M: 4f75181056b5aefd90f2b1cc242e105f929ec5b4 192.168.88.59:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: e92ce91b5b3b4587c5520482e7a825b050d02dee 192.168.88.60:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
M: 8f23c1c05cda60f570d70543c5ea3e5bf643c89c 192.168.88.61:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 0d342ee7810cadea394eb62a7da4e3a1f320f680 192.168.88.64:6379
   slots: (0 slots) slave
   replicates e92ce91b5b3b4587c5520482e7a825b050d02dee
S: fa61df96aea2f9a53427eae75fd0c82e4b916ffb 192.168.88.62:6379
   slots: (0 slots) slave
   replicates 8f23c1c05cda60f570d70543c5ea3e5bf643c89c
S: 1ca6b10204e7df92340b5c8318416340d4c5ec6b 192.168.88.63:6379
   slots: (0 slots) slave
   replicates 4f75181056b5aefd90f2b1cc242e105f929ec5b4
[OK] All nodes agree about slots configuration.
&amp;gt;&amp;gt;&amp;gt; Check for open slots...
&amp;gt;&amp;gt;&amp;gt; Check slots coverage...
[OK] All 16384 slots covered.
[root@redis59 ~]# 


[root@redis59 ~]#      查看集群信息
[root@redis59 ~]# redis-cli --cluster info 192.168.88.59:6379
192.168.88.59:6379 (4f751810...) -&amp;gt; 0 keys | 5461 slots | 1 slaves.
192.168.88.60:6379 (e92ce91b...) -&amp;gt; 0 keys | 5462 slots | 1 slaves.
192.168.88.61:6379 (8f23c1c0...) -&amp;gt; 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
[root@redis59 ~]# 


[root@redis59 ~]#  访问集群验证数据
[root@redis59 ~]# redis-cli -c -h 192.168.88.59 -p 6379
192.168.88.59:6379&amp;gt; set a 1
-&amp;gt; Redirected to slot [15495] located at 192.168.88.61:6379
OK
192.168.88.61:6379&amp;gt; set b 2
-&amp;gt; Redirected to slot [3300] located at 192.168.88.59:6379
OK
192.168.88.59:6379&amp;gt; set c 3
-&amp;gt; Redirected to slot [7365] located at 192.168.88.60:6379
OK
192.168.88.60:6379&amp;gt; get a
-&amp;gt; Redirected to slot [15495] located at 192.168.88.61:6379
&quot;1&quot;
192.168.88.61:6379&amp;gt; get a
&quot;1&quot;
192.168.88.61:6379&amp;gt; get b
-&amp;gt; Redirected to slot [3300] located at 192.168.88.59:6379
&quot;2&quot;
192.168.88.59:6379&amp;gt; get c
-&amp;gt; Redirected to slot [7365] located at 192.168.88.60:6379
&quot;3&quot;
192.168.88.60:6379&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;说明如何使用 RDB 文件恢复 Redis 数据。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
[root@redis59 ~]# grep -vE &quot;^\s*($|#)&quot; /opt/redis/conf/redis.conf | grep save
save 3600 1 120 10 60 10000
stop-writes-on-bgsave-error yes
rdb-save-incremental-fsync yes
[root@redis59 ~]# systemctl start redis.service 
[root@redis59 ~]# ls /opt/redis/data/
[root@redis59 ~]# redis-cli 
127.0.0.1:6379&amp;gt; keys *
(empty array)
127.0.0.1:6379&amp;gt; mset a 1 b 2 c 3 d 4 x 1 y 2  z 3 k 6  i 7  z 9   f 22  zz 99  cc  66
OK
127.0.0.1:6379&amp;gt; keys * 
 1) &quot;c&quot;
 2) &quot;d&quot;
 3) &quot;k&quot;
 4) &quot;a&quot;
 5) &quot;cc&quot;
 6) &quot;x&quot;
 7) &quot;zz&quot;
 8) &quot;f&quot;
 9) &quot;y&quot;
10) &quot;b&quot;
11) &quot;i&quot;
12) &quot;z&quot;
127.0.0.1:6379&amp;gt; exit
[root@redis59 ~]# ls /opt/redis/data/
dump.rdb
[root@redis59 ~]# 


#  在60服务器上恢复数据
[root@redis60 ~]# 
[root@redis60 ~]# grep -vE &quot;^\s*($|#)&quot; /opt/redis/conf/redis.conf | grep save
save 3600 1 120 10 60 10000
stop-writes-on-bgsave-error yes
rdb-save-incremental-fsync yes
[root@redis60 ~]# systemctl start redis.service 
[root@redis60 ~]# redis-cli 
127.0.0.1:6379&amp;gt; keys *
(empty array)
127.0.0.1:6379&amp;gt; exit
[root@redis60 ~]# systemctl stop redis.service 
[root@redis60 ~]# ls /opt/redis/data/
dump.rdb
[root@redis60 ~]# rm -rf /opt/redis/data/dump.rdb 
[root@redis60 ~]# scp root@192.168.88.59:/opt/redis/data/dump.rdb /opt/redis/data/
root@192.168.88.59&apos;s password: 
dump.rdb                                                           100%  157    84.3KB/s   00:00    
[root@redis60 ~]# ll /opt/redis/data/
总用量 4
-rw-r--r-- 1 root root 157 1月  22 10:15 dump.rdb
[root@redis60 ~]# systemctl start redis.service 
[root@redis60 ~]# redis-cli 
127.0.0.1:6379&amp;gt; keys *
 1) &quot;y&quot;
 2) &quot;f&quot;
 3) &quot;c&quot;
 4) &quot;a&quot;
 5) &quot;b&quot;
 6) &quot;zz&quot;
 7) &quot;z&quot;
 8) &quot;i&quot;
 9) &quot;cc&quot;
10) &quot;x&quot;
11) &quot;k&quot;
12) &quot;d&quot;
127.0.0.1:6379&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;day01-MySQL介绍及安装&lt;/h1&gt;
&lt;h2&gt;一、 Mysql概述&lt;/h2&gt;
&lt;h3&gt;1、关系型数据库与非关系型数据库&lt;/h3&gt;
&lt;p&gt;RDBMS（relational【瑞-雷-审-呢欧】 database【得塔-贝斯】 management【脉-内吉-门特】 system【西斯屯】），关系型数据库管理系统 简单来说，关系型数据库，是指采用了二维表格来组织数据的数据库。
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111341405.webp&quot; alt=&quot;&quot; /&gt;
在行业中，数据库一般分两种，关系型数据库和非关系型数据库。非关系型数据库 并不是通过二维表格来维护数据。而是通过key/value键值对来维护数据的。&lt;/p&gt;
&lt;h3&gt;2、常见的关系型数据库&lt;/h3&gt;
&lt;p&gt;Oracle【欧瑞扣】、 mysql、 DB2（ IBM）、Sybase【赛-贝斯】、SQL server【涩·沃】（ Microsoft微软）、 IBM Informix【因佛-麦克斯】
关系型数据的最大特点就是事务的一致性：所以对事务一致性的维护会占有很大的 开销&lt;/p&gt;
&lt;h3&gt;3、什么是事务&lt;/h3&gt;
&lt;p&gt;事务是由一条或多条sql语句组成；
在事务的操作中，这些sql语句要么都成功执行，要么都不执行，这就是一个事 务。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;登陆ATM机，输入密码；&lt;/li&gt;
&lt;li&gt;连接数据库，验证密码；&lt;/li&gt;
&lt;li&gt;验证成功，获得用户信息，比如存款余额等；&lt;/li&gt;
&lt;li&gt;用户输入需要转账的金额，按下确认键；&lt;/li&gt;
&lt;li&gt;从后台数据库中减掉用户账户上的对应金额（update【阿普-得特】语句）；&lt;/li&gt;
&lt;li&gt;从后台数据库中给对方账户增加相应的金额（update【阿普-得特】语句）；&lt;/li&gt;
&lt;li&gt;确认，退卡，走人；&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;4、事务的特点（ACID）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;原子性(Atomicity【艾特米涩替】)：
事务中的全部操作在数据库中是不可分割的，要么全部完成，要么均不执行。&lt;/li&gt;
&lt;li&gt;一致性(Consistency【肯西斯腾西】)：
指事务必须使数据库从一个一致性状态变换到另一个一致性状态，也就是说一 个事务执行之前和执行之后都必须处于一致性状态，不能破坏关系数据的完整 性以及业务逻辑上的一致性。&lt;/li&gt;
&lt;li&gt;.  隔离性(Isolation【艾涩雷申】)：
一个事务的执行不受其他事务的干扰，事务执行的中间结果对其他事务必须是 透明的。隔离性是当多个用户并发访问数据库时，比如操作同一张表时，数据 库为每一个用户开启的事务，不能被其他事务的操作所干扰，多个并发事务之 间要相互隔离。&lt;/li&gt;
&lt;li&gt;持久性(Durability【杜若比勒替】)：
持久性是指一个事务一旦被提交了，那么对数据库中的数据的改变就是永久性 的，即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。对数据的一致性要求较高的，就是银行及支付系统类&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5、 Mysql数据库概述&lt;/h3&gt;
&lt;p&gt;mysql是一种关系型数据库管理系统，由瑞典Mysql AB公司开发，目前属于Oracle【欧瑞扣】旗下，Mysql是C/S架构&lt;/p&gt;
&lt;h3&gt;6、 Mysql数据库版本&lt;/h3&gt;
&lt;h4&gt;社区版： MySQL Community【肯谬尼替】 Editon【伊迪申】(GPL)&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;可以看做是企业版的广泛体验版，没有经过各个专有系统平台的压力测试和性 能测试&lt;/li&gt;
&lt;li&gt;基于GPL协议发布，可以随意下载使用&lt;/li&gt;
&lt;li&gt;没有任何官方技术支持服务。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;企业版： Mysql Enterprise【恩特普莱兹】 Edition伊迪申（commercial【克默收】）&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;提供比较全面的高级功能、管理工具以及技术支持&lt;/li&gt;
&lt;li&gt;安全性、稳定性、可扩展性比较好&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;集群版： Mysql Cluster【克拉斯特】 CGE（commercial【克默收】）&lt;/h4&gt;
&lt;p&gt;扩充：关于版本的命名方式如何去定义？&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;版本&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;α（Alpha【艾欧法】）版&lt;/td&gt;
&lt;td&gt;内测版，内部交流或者专业测试人员测试用。 Bug 较多，普通用户最好不要安装。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;β（ Beta【贝塔】）版&lt;/td&gt;
&lt;td&gt;公测版，专业爱好者大规模测试用，存在一些缺 陷，该版本也不适合一般用户安装。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;γ ( Gamma【盖么】 )版&lt;/td&gt;
&lt;td&gt;相当成熟的测试版，与即将发行的正式版相差无 几。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Final【伐呢欧】&lt;/td&gt;
&lt;td&gt;正式版本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Free【弗瑞】&lt;/td&gt;
&lt;td&gt;自由版本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Release【瑞利斯】&lt;/td&gt;
&lt;td&gt;发行版本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Standard【斯丹德的】&lt;/td&gt;
&lt;td&gt;标准版本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mini【米尼】&lt;/td&gt;
&lt;td&gt;迷你精简版本,只有最基本的功能&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Upgrade【阿普格瑞德】&lt;/td&gt;
&lt;td&gt;升级版本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GA(GenerallyAvailable【珍若里-呃 维 勒 布(白话)】)&lt;/td&gt;
&lt;td&gt;开发团队认为该版本是稳定版,可以在较为关键的 场合使用。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retail【瑞忒欧】&lt;/td&gt;
&lt;td&gt;零售版&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;7、获取MySQL软件&lt;/h3&gt;
&lt;p&gt;官网：&lt;a href=&quot;http://www.mysql.com/&quot;&gt;www.mysql.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;第一步：单机Downloads【&lt;strong&gt;当-漏的&lt;/strong&gt;】下载
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111352006.webp&quot; alt=&quot;&quot; /&gt;
第二步：找到社区版
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111409634.webp&quot; alt=&quot;&quot; /&gt;
第三步：单击进入Mysql社区版下载页面
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111417533.webp&quot; alt=&quot;&quot; /&gt;
第四步：选择合适的版本
①GLIBC【哥里布C】版本（相当于Windows中的绿色版）
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111430719.webp&quot; alt=&quot;&quot; /&gt;
②源码编译版本（需要源码编译三步走=&amp;gt;配置+编译+安装）
https://cdn.mysql.com/archives/mysql-5.7/mysql-5.7.44-linux-glibc【哥里布C】2.12-x86_64.tar.gz
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111639310.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;二、 CentOS7.6操作系统最小化安装&lt;/h2&gt;
&lt;h3&gt;1、虚拟机设置&lt;/h3&gt;
&lt;p&gt;第一步：选择自定义（根据需求设定服务器环境）
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111447750.webp&quot; alt=&quot;&quot; /&gt;
默认
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111503050.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111522783.webp&quot; alt=&quot;&quot; /&gt;
第三步：选择操作系统类型
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111531000.webp&quot; alt=&quot;&quot; /&gt;
第四步：设置虚拟机名称及路径（建议磁盘剩余空间大于等于20G）
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111540483.webp&quot; alt=&quot;&quot; /&gt;
第五步：设置CPU核数
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111550330.webp&quot; alt=&quot;&quot; /&gt;
第六步“设置MEM内存
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111558233.webp&quot; alt=&quot;&quot; /&gt;
第七步：设置网络连接（NAT模式）
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111607103.webp&quot; alt=&quot;&quot; /&gt;
剩下的全部默认，一路下一步，直至设置完成&lt;/p&gt;
&lt;h3&gt;2、安装Centos7.6最小化模式&lt;/h3&gt;
&lt;p&gt;第一步：加载光盘镜像
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111614953.webp&quot; alt=&quot;&quot; /&gt;
第二步：启动虚拟机，安装CentOS7.6
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111700084.webp&quot; alt=&quot;&quot; /&gt;
第三步：设置安装语言（必须选择全英文）
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111713100.webp&quot; alt=&quot;&quot; /&gt;
第四步：设置服务器时间（Asia/Shanghai）
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111721783.webp&quot; alt=&quot;&quot; /&gt;
第五步：软件选择，最小化然后必须要勾选开发工具*（主要是GCC编译器）
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111729684.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111740228.webp&quot; alt=&quot;&quot; /&gt;
第六步：自动分区
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111753702.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111801933.webp&quot; alt=&quot;&quot; /&gt;
第七步：设置网络连接为自动连接（开机后，自动连接网络）
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111809133.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111817917.webp&quot; alt=&quot;&quot; /&gt;
第八步：设置ROOT账户密码以及自定义用户
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111824900.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111833353.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3、 Centos7.6操作系统最小化后续配置&lt;/h3&gt;
&lt;h4&gt;①设置主机名称&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;#hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mysql 
#su
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;②更改IP获取方式为静态设置&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;#vi /etc/sysconﬁg/network【孽特 - 沃克】-scripts【斯贵 普茨】/ifcfg-ens33
TYPE=&quot;Ethernet&quot;
BOOTPROTO=&quot;none&quot;
IPADDR=192.168.20.111 
NETMASK=255.255.255.0 
GATEWAY=192.168.20.2   
DNS1=8.8.8.8
DNS2=119.29.29.29 
NAME=&quot;ens33&quot;
DEVICE=&quot;ens33&quot; 
ONBOOT=&quot;yes&quot;

#vi /etc/hosts
192.168.20.111  mysql.cn

## systemctl【西斯屯-ctl】
 restart【 率 s 达r】 network【孽特 - 沃克】
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;③关闭防火墙与SELinux&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;## systemctl【西斯屯-ctl】
 stop【 s 多】 firewalld【fai 额 沃 得】
## systemctl【西斯屯-ctl】
 disable【滴 s 步】 firewalld【fai 额 沃 得】

#setenforce【赛特-因佛尔斯】 0
#vim /etc/selinux/conﬁg
SELINUX=disabled
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;④配置公网YUM源（可以考虑腾讯）&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# yum install【因-斯多​】 wget -y
# mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS- Base.repo.backup
# wget -O /etc/yum.repos.d/CentOS-Base.repo
http://mirrors.cloud.tencent.com/repo/centos7_base.repo

# yum clean【科林恩】 all【哦】
# yum makecache
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;⑤安装扩展软件&lt;/h4&gt;
&lt;p&gt;bash-completion自动补全、VIM编辑器、 net-tools网络工具包以 及ntpdate时间同步工具&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  # yum install【因-斯多​】 bash-completion vim net-tools ntpdate -y
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;⑥ntpdate时间同步&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;#ntpdate 120.25.108.11
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4、拍摄快照：把Centos7.6最小化系统做模板&lt;/h3&gt;
&lt;p&gt;机
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111845190.webp&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111852483.webp&quot; alt=&quot;&quot; /&gt;
建议：拍摄快照完成后，可以将这台机器关机，以后专门充当克隆用的母机！&lt;/p&gt;
&lt;h2&gt;三、 Mysql的安装&lt;/h2&gt;
&lt;h3&gt;1、 Mysql的安装方式&lt;/h3&gt;
&lt;p&gt;二进制软件包安装
①yum安装和rpm安装
②glibc【哥里布C】版本安装（相当于Windows中的绿色软件） 命名： mysql-5.7.31-linux-glibc【哥里布C】2.12-x86_64.tar     依赖glibc【哥里布C】库，可以安装在通用的Linux系统下
源码包编译安装
命名： mysql-boost-5.7.31.tar，通用的Linux下都可以编译安装&lt;/p&gt;
&lt;h3&gt;2、三种安装方式的区别&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;安装 方式&lt;/th&gt;
&lt;th&gt;优点&lt;/th&gt;
&lt;th&gt;缺点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;rpm&lt;/td&gt;
&lt;td&gt;安装卸载简单&lt;/td&gt;
&lt;td&gt;可定制性差&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;glibc【哥里布C】&lt;/td&gt;
&lt;td&gt;可定制性相比rpm包灵活些&lt;/td&gt;
&lt;td&gt;安装相比rpm包复杂些，需要手动初 始化数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;源码 安装&lt;/td&gt;
&lt;td&gt;可定制性最强，根据需求和 功能定制&lt;/td&gt;
&lt;td&gt;安装麻烦，需要手动初始化数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;在企业中，数据库的安装很少使用rpm方式，大部分都是基于源码安装以及glibc【哥里布C】安 装&lt;/p&gt;
&lt;h3&gt;3、区分数据库与数据库实例&lt;/h3&gt;
&lt;h4&gt;①什么是MySQL数据库？&lt;/h4&gt;
&lt;p&gt;数据库（database【得-塔-贝斯】）： 操作系统或存储上的数据文件的集合。 mysql数据库中， 数据库文件可以是* .frm、.MYD、 .MYI、*.ibd等结尾的文件， 不同存储引擎文件 类型不同。&lt;/p&gt;
&lt;h4&gt;②什么是MySQL数据库实例？&lt;/h4&gt;
&lt;p&gt;数据库实例（instance【因-斯腾斯】）： 由后台进程或者线程以及一个共享内存区组成。共享 内存可以被运行的后台线程所共享。 数据库实例才是真正操作数据库的。
注意： MySQL的后台守护程序mysqld是单进程多线程的工作模式。&lt;/p&gt;
&lt;h4&gt;③什么是MySQL数据库服务器？&lt;/h4&gt;
&lt;p&gt;数据库服务器(database【得-塔-贝斯】 server【涩·沃】)：部署安装数据库实例的服务器。&lt;/p&gt;
&lt;h4&gt;④、数据库和数据库实例之间的关系是什么&lt;/h4&gt;
&lt;p&gt;通常情况下，数据库实例和数据库是一一对应的关系，也就是一个数据库实例对应 一个数据库； 但是，在集群环境中存在多个数据库实例共同使用一个数据库。&lt;/p&gt;
&lt;h2&gt;四、 MySQL的GLIBC【哥里布C】版本安装&lt;/h2&gt;
&lt;h3&gt;1、获取MySQL GLIBC【哥里布C】版本&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111918934.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;2、学会看官方文档&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111926816.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3、安装MySQL依赖库软件&lt;/h3&gt;
&lt;p&gt;第一步：克隆模板机，生成Mysql服务器
第二步：启动系统
第三步：更改主机名为mysql.aliyun.cn。然后重启网络
第四步：拍摄快照
第五步：安装依赖库libaio库&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#yum install【因-斯多​】 libaio -y
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4、上传软件包解压，了解目录结构&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# tar -xf mysql-5.7.31-linux-glibc【哥里布C】2.12-x86_64.tar.gz 
# ls mysql-5.7.31-linux-glibc【哥里布C】2.12-x86_64
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;解压完成后，目录结构如下图所示：
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117111943767.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;选项&lt;/th&gt;
&lt;th&gt;值（自定义也可以采用默认形式）&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;安装路径&lt;/td&gt;
&lt;td&gt;/mysql_3306&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;数据路径&lt;/td&gt;
&lt;td&gt;/mysql_3306/data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;端口号&lt;/td&gt;
&lt;td&gt;3306&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;5、软件的安装（查看官方说明）&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://dev.mysql.com/doc/refman/5.7/en/binary%E3%80%90%E6%8B%9C%E8%AE%B7%E7%91%9E%E3%80%91-installation.html&quot;&gt;官方说明&lt;/a&gt;
要安装和使用Mysql二进制发现版，命令序列如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$&amp;gt; groupadd mysql
$&amp;gt; useradd -r -g mysql -s /bin/false mysql
$&amp;gt; rm -rf /etc/my.cnf
$&amp;gt; cd /usr/local
$&amp;gt; tar zxvf /path/to/mysql-VERSION-OS.tar.gz
$&amp;gt; ln -s full-path-to-mysql-VERSION-OS mysql
$&amp;gt; cd mysql
$&amp;gt; mkdir mysql-files
$&amp;gt; chown【吃-昂】 mysql:mysql mysql-files
$&amp;gt; chmod【吃-默德】 750 mysql-files
$&amp;gt; bin/mysqld --initialize【因 尼 舍 来斯】 --user=mysql
$&amp;gt; bin/mysql_ssl_rsa_setup
$&amp;gt; bin/mysqld_safe --user=mysql &amp;amp;
# Next command is optional
$&amp;gt; cp support【瑟破特】-files/mysql.server【涩·沃】 /etc/init.d/mysql.server【涩·沃】
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第一步：创建一个数据库专用账号mysql（其所属组也为mysql）&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# useradd -r -s /sbin/nologin mysql
# id mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第二步：清空系统中的原有mariadb【玛瑞亚DB】的配置文件（/etc/my.cnf）&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# rm -rf /etc/my.cnf
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第三步：把mysql解压后的压缩包移动到根目录下&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# mv mysql-5.7.31-linux-glibc【哥里布C】2.12-x86_64 /mysql_3306
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第四步：创建一个mysql-ﬁles【伐欧兹】&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# cd /mysql_3306   
# mkdir mysql-ﬁles
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第五步：更改mysql-ﬁles权限&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# chown【吃-昂】 mysql:mysql mysql-ﬁles 
# chmod【吃-默德】 750 mysql-ﬁles
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;第六步：初始化数据库&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;# bin/mysqld --initialize【因 尼 舍 来斯】 --user=mysql --basedir=/mysql_3306
选项说明：
--initialize【因 尼 舍 来斯】    初始化（真正开始干活）
--user=mysql    以mysql用户的身份初始化数据库 ，产生文件都是mysql作为拥有者 
–basedir【贝斯-迪尔】=xxx    mysql其安装目录 ，非常重要

运行完毕后 ，观察最后一行 ，保存root账号的密码 ， 已备后期使用。
2023-12-12T07:43:11.882980Z 1 [Note] A temporary password【帕斯沃德】 is generated for【fò】 root@localhost: s+=x(&amp;gt;uqe4eK
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第七步：设置安全加密连接（SL），数据传输会采用加密形式，适合敏感数据&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# bin/mysql_ssl_rsa_setup --datadir=/mysql_3306/data
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第八步：启动数据库&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# cp support【瑟破特】-files/mysql.server【涩·沃】 /etc/init.d/mysql_3306
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;默认情况下，GBLIC版本的数据库要求安装到/usr/local/mysql目录，其
mysql.server【涩·沃】脚本中对应的目录也是/usr/local/mysql，这会导致mysql无法启动。 所以可以更改其basedir【贝斯德尔】以及datadir【得塔德尔】两个变量&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#vim /etc/init.d/mysql_3306
46行basedir【贝斯德尔】=/mysql_3306
47行datadir【得塔德尔】=/mysql_3306/data
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第九步：启动Mysql数据库（不能使用# systemctl【西斯屯-ctl】&lt;/h4&gt;
&lt;p&gt;,只能使用service【瑟为斯】）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#service【瑟为斯】 mysql_3306 start【s 达儿】
Starting【斯大-停】 MySQL.Logging【劳-京】 to &apos;/mysql_3306/data/mysql.err&apos;.
. SUCCESS【涩赛斯】! 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;特别说明：当MySQL启动成功后，其日志会自动写入到data数据目录中的主机名   称.err文件中，这个文件一定要多看，涉及MySQL无法启动、启动报错，其详细的 原因99%在.err文件中可以找到问题所在！&lt;/p&gt;
&lt;h3&gt;6、软件的安装常见问题答疑&lt;/h3&gt;
&lt;h4&gt;问题1：为什么一定要删除/etc/my.cnf文件，不删除有何影响&lt;/h4&gt;
&lt;p&gt;答：/etc/my.cnf文件是操作系统为mariadb【玛瑞亚DB】软件预留的配置的文件，之所以一定要 删除这个文件，主要原因在于数据库在初始化时，首先在自己的安装目录下寻找有 没有my.cnf配置文件，如果有，会自动根据里面的配置信息进行初始化。如果找不 到，则到/etc目录下寻找my.cnf文件，如果有，依然会按照其内部的配置进行初始  化，但是由于/etc目录下的my.cnf文件是mariadb【玛瑞亚DB】的，这会导致我们的初始化如果  按照mariadb【玛瑞亚DB】的配置，会导致初始化失败。&lt;/p&gt;
&lt;h4&gt;问题2： mysql_ﬁles文件夹到底是干什么的&lt;/h4&gt;
&lt;p&gt;答：目前mysql-ﬁles没有什么用，但是你必须要创建，因为GLIBC【哥里布C】属于二进制软件 包，其很多配置已经默认了，包括mysql-ﬁles文件夹，如果没有这个文件夹可能导 致mysql无法启动。&lt;/p&gt;
&lt;h4&gt;问题3：到底怎么判断数据库是否初始化成功？&lt;/h4&gt;
&lt;p&gt;答：数据库的安装容易出错的地方就是初始化，一旦初始化失败了，数据库100%  启动报错。如何确认数据库是否初始化成功了呢？主要看安装目录下有没有生成一 个data的文件夹。&lt;/p&gt;
&lt;h4&gt;问题4：为什么一定要把mysql.server【涩·沃】放在/etc/init.d目录下，不放可不可以？&lt;/h4&gt;
&lt;p&gt;答：不放也可以，但是这个时候就不能使用service【瑟为斯】命令启动以及添加到开机启动项 了。只能通过bin/mysqld_safe脚本启动数据库。&lt;/p&gt;
&lt;h4&gt;问题5：为什么一定要改变/etc/init.d/mysql_3306中的basedir【贝斯德尔】与datadir【得塔德尔】？&lt;/h4&gt;
&lt;p&gt;答：GLIBC【哥里布C】版本属于二进制版本，默认已经配置了很多内容，包括默认的安装路 径/usr/local/mysql ，一旦你的mysql没有安装在这个目录下，则必须手工设置  basedir【贝斯德尔】以及datadir【得塔德尔】其位置，否则脚本无法启动mysql程序&lt;/p&gt;
&lt;h4&gt;问题6：如何让mysql自动启动&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# chkconﬁg【切-坑菲格】 --list             查询系统中的所有开机启动项
# chkconfig【切-坑菲格】 --add mysql_3306    必须与/etc/in it.d目录下的脚本名称一致
# chkconﬁg【切-坑菲格】 mysql_3306 on       把2345四种模式全部开启（ 3字符界面 ，5图形界面）
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7、 Mysql CLIBC版本后续配置&lt;/h3&gt;
&lt;h4&gt;第一步：更改管理员root账户的密码&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# bin/mysqladmin【麦斯Q-艾德敏】 -uroot password【帕斯-沃德】 &apos;123&apos; -p
Enter password:输入刚刚初始化产生的临时密码
# bin/mysql -uroot -p
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第二步：把mysql客户端命令添加到环境变量，以后随时可以访问&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# echo &apos;export【e斯 破特】 PATH=$PATH:/mysql_3306/bin&apos; &amp;gt;&amp;gt; /etc/profile【普若法欧】
# source【索尔斯】 /etc/profile【普若法欧】
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第三步：手工定义MySQL的配置文件&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;#vim /mysql_3306/my.cnf
[mysqld]
basedir【贝斯德尔】=/mysql_3306
datadir【得塔德尔】=/mysql_3306/data 
socket=/tmp/mysql.sock
选项说明：
[mmysql] 	代表针对服务器端进行配置 basedir  代表数据库的安装目录
datadir  		代表数据目录 ，以后专门用于存放数据文件的（核心目录）
socket   		代表套接字文件 ，专门为客户端与服务端连接提供的一个桥梁
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第四步：安全配置&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# mysql_secure_installation【因-斯多 雷申​】  # 执行MySQL安全配置脚本

Securing the MySQL server【涩·沃】 deployment.

Enter password【帕斯沃德】 for【fò】 user root:  # 输入当前root用户的密码（若未设置直接回车）

# 选项1：是否启用密码验证插件（用于检查密码强度）
VALIDATE PASSWORD PLUGIN【普辣 京(白话)】 can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set【赛特】 only【欧利】 those passwords which are
secure enough. Would you like【赖特】 to setup VALIDATE PASSWORD plugin【普辣 京(白话)】?
Press y|Y for【fò】 Yes, any other key for【fò】 No: y  # 输入y启用（增强安全性）

# 选项2：选择密码验证策略级别
There are three levels【列沃】 of password validation policy:
LOW    Length &amp;gt;= 8  # 低：仅要求密码长度≥8位
MEDIUM Length &amp;gt;= 8, numeric, mixed case, and special characters  # 中：长度≥8位且包含数字、大小写字母、特殊字符
STRONG Length &amp;gt;= 8, numeric, mixed case, special characters and dictionary file  # 高：在中级基础上增加字典检查（防止常见弱密码）
Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 0  # 输入0选择低级策略

Using existing password for【fò】 root.
Estimated strength of the password: 50 

# 选项3：是否修改root用户密码
Change the password for【fò】 root ? ((Press y|Y for【fò】 Yes, any other key for【fò】 No) : no  # 输入no不修改现有密码（若需修改输入y）
 ... skipping.

# 选项4：是否删除匿名用户（默认存在，允许无账号登录）
By default, a MySQL installation has an anonymous user,
allowing anyone to log into【因兔】 MySQL without having to have
a user account created for【fò】 them. This is intended only【欧利】 for【fò】
testing, and to make the installation go a bit smoother.
You should remove them before moving into【因兔】 a production
environment.
Remove anonymous users? (Press y|Y for【fò】 Yes, any other key for【fò】 No) : y  # 输入y删除（推荐，减少未授权访问风险）
Success.

# 选项5：是否禁止root用户远程登录（仅允许本地登录）
Normally, root should only【欧利】 be allowed to connect from【弗乱】
&apos;localhost&apos;. This ensures that someone cannot guess at
the root password from【弗乱】 the network.
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y  # 输入y禁止（推荐，降低远程暴力破解风险）
Success.

# 选项6：是否删除test【泰斯特】数据库（默认存在，供测试使用）
By default, MySQL comes with a database named &apos;test&apos; that
anyone can access. This is also intended only【欧利】 for【fò】 testing,
and should be removed before moving into【因兔】 a production
environment.
Remove test database and access to it? (Press y|Y for【fò】 Yes, any other key for【fò】 No) : y  # 输入y删除（推荐，清理无用数据库）
 - Dropping test database...
Success.
 - Removing privileges【P符类 杰 斯】 on test database...
Success.

# 选项7：是否立即刷新权限表（使所有配置生效）
Reloading the privilege tables will ensure that all【哦】 changes
made so far will take effect immediately.
Reload【率漏德】 privilege tables now? (Press y|Y for【fò】 Yes, any other key for【fò】 No) : y  # 输入y刷新（必须执行，否则配置不生效）
Success.

All done!  # 所有安全配置完成
[root@mysql ~]# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输入密码后，一个要求是否改密码，选择N不改，后续的一直按Y就可以了&lt;/p&gt;
&lt;h2&gt;五、 MySQL的源码安装&lt;/h2&gt;
&lt;h3&gt;1、参考Mysql源码安装官方文档&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://dev.mysql.com/doc/refman/5.7/en/source-installation.html&quot;&gt;官方文档&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;源码安装三部曲：配置--&amp;gt;编译--&amp;gt;安装
安装须知&lt;/p&gt;
&lt;p&gt;软件包
&lt;code&gt;shell mysql-boost-5.7.31.tar.gz  可以在任意发行版的Linux下安装 &lt;/code&gt;
安装需求&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;安装需求&lt;/th&gt;
&lt;th&gt;具体配置&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;安装目录（basedir【贝斯德尔】）&lt;/td&gt;
&lt;td&gt;/mysql_3307&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;数据目录（datadir【得塔德尔】）&lt;/td&gt;
&lt;td&gt;/mysql_3307/data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;端口号&lt;/td&gt;
&lt;td&gt;3307&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;socket文件位置&lt;/td&gt;
&lt;td&gt;$basedir【贝斯德尔】/mysql.sock&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;字符集&lt;/td&gt;
&lt;td&gt;utf8mb4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;常用的配置选项&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;配置选项&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;th&gt;默认值&lt;/th&gt;
&lt;th&gt;建议值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CMAKE_INSTALL【因-斯多​】_PREFIX&lt;/td&gt;
&lt;td&gt;安装基目录(basedir【贝斯德尔】)&lt;/td&gt;
&lt;td&gt;/usr/local/mysql&lt;/td&gt;
&lt;td&gt;根据需求&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MYSQL_DATADIR【得塔德尔】&lt;/td&gt;
&lt;td&gt;数据目录 (datadir【得塔德尔】)&lt;/td&gt;
&lt;td&gt;$basedir【贝斯德尔】/data&lt;/td&gt;
&lt;td&gt;根据需求&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SYSCONFDIR&lt;/td&gt;
&lt;td&gt;默认配置 文件my.cnf路径&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;/etc&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MYSQL_TCP_PORT【破特】&lt;/td&gt;
&lt;td&gt;TCP/IP端口&lt;/td&gt;
&lt;td&gt;3306&lt;/td&gt;
&lt;td&gt;非默认端口&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MYSQL_UNIX_ADDR&lt;/td&gt;
&lt;td&gt;套接字socket文 件路径&lt;/td&gt;
&lt;td&gt;/tmp/mysql.sock&lt;/td&gt;
&lt;td&gt;$basedir【贝斯德尔】/&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DEFAULT_CHARSET&lt;/td&gt;
&lt;td&gt;默认字符集&lt;/td&gt;
&lt;td&gt;latin1&lt;/td&gt;
&lt;td&gt;utf8mb4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DEFAULT_COLLATION&lt;/td&gt;
&lt;td&gt;默认校验 规则&lt;/td&gt;
&lt;td&gt;latin1_swedish_ci&lt;/td&gt;
&lt;td&gt;utf8mb4_general_ci&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WITH【威付】_EXTRA_CHARSETS&lt;/td&gt;
&lt;td&gt;扩展字符 集&lt;/td&gt;
&lt;td&gt;all【哦】&lt;/td&gt;
&lt;td&gt;all【哦】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ENABLED【伊内部特】_LOCAL_INFILE&lt;/td&gt;
&lt;td&gt;是否启用 本地加载 外部数据 文件功能&lt;/td&gt;
&lt;td&gt;OFF&lt;/td&gt;
&lt;td&gt;建议开启&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WITH【威付】_SSL&lt;/td&gt;
&lt;td&gt;SSL支持 类型&lt;/td&gt;
&lt;td&gt;system&lt;/td&gt;
&lt;td&gt;建议显式指定&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WITH【威付】_BOOST&lt;/td&gt;
&lt;td&gt;Boost库  源代码的 位置&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Boost库是构建MySQL所必需的,建 议事先下载&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;存储引擎相关配置项
说明：
以下选项值均为布尔值，0或1；0代表不编译到服务器中， 1代表编译，建议都静态 编译到服务器中。
其他的存储引擎可以根据实际需求在安装时通过WITH【威付】_xxxx_STORAGE_ENGINE=1 的方式编译到服务器中。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;配置选项&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;WITH【威付】_INNOBASE_STORAGE_ENGINE&lt;/td&gt;
&lt;td&gt;将InnoDB存储引擎插件构建为静  态模块编译到服务器中；建议编译 到服务器中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WITH【威付】_PARTITION_STORAGE_ENGINE&lt;/td&gt;
&lt;td&gt;是否支持分区&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WITH【威付】_FEDERATED_STORAGE_ENGINE&lt;/td&gt;
&lt;td&gt;本地数据库是否可以访问远程 mysql数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WITH【威付】_BLACKHOLE_STORAGE_ENGINE&lt;/td&gt;
&lt;td&gt;黑洞存储引擎，接收数据，但不存 储，直接丢弃&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WITH【威付】_MYISAM【迈-艾塞姆】_STORAGE_ENGINE&lt;/td&gt;
&lt;td&gt;将MYISAM【迈-艾塞姆】存储引擎静态编译到服 务器中&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;2、 MySQL的源码编译安装&lt;/h3&gt;
&lt;p&gt;在安装之前建议拍摄一个快照&lt;/p&gt;
&lt;h4&gt;第一步：安装MySQL编译需要用到的依赖库&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# yum groupinstall【格鲁普因-斯多​】 -y &quot;Development Tools&quot;
# yum -y install【因-斯多​】 ncurses-devel cmake libaio-devel openssl-devel gcc gcc-c++ bison-devel bzip2-devel libcurl-devel 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第二步：上传软件到服务器端并解压&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# tar -xf mysql-boost-5.7.31.tar.gz 
# cd mysql-5.7.31
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第三步：配置（基于cmake进行配置）&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;#vim myconﬁg.sh
cmake . \
-DCMAKE_INSTALL【因-斯多​】_PREFIX=/mysql_3307 \
-DMYSQL_DATADIR=/mysql_3307/data \
-DMYSQL_TCP_PORT【破特】=3307 \
-DMYSQL_UNIX_ADDR=/mysql_3307/mysql.sock \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_PARTITION_STORAGE_ENGINE=1 \
-DWITH_FEDERATED_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_MYISAM_STORAGE_ENGINE=1 \
-DENABLED_LOCAL_INFILE=1 \
-DEXTRA_CHARSETS=all【哦】 \
-DDEFAULT_CHARSET=utf8mb4 \
-DDEFAULT_COLLATION=utf8mb4_general_ci \
-DWITH_SSL=system \
-DWITH_BOOST=boost

# chmod【吃-默德】 +x myconﬁg.sh
# mkdir【摸克跌儿】 -p /mysql_3307/data
# ./myconﬁg.sh

选项说明：
-DCMAKE_INSTALL【因-斯多​】_PREFIX：安装路径 
-DMYSQL_DATADIR：数据目录
-DMYSQL_TCP_PORT【破特】：端口号
-DMYSQL_UNIX_ADDR：套接字文件位置
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第四步：编译安装&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# make -j2 &amp;amp;&amp;amp; make install【因-斯多​】
选项说明：
-j2：代表同时开启多个线程共同实现编译操作
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3、编译报错常见问题解析&lt;/h3&gt;
&lt;h4&gt;问题1：没有boost导致安装失败&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112007120.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;问题2：编译安装中途报错&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112015967.webp&quot; alt=&quot;&quot; /&gt;
解决方案：只能重新编译一下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#rm -f CMake Cache.txt
#make -j2 &amp;amp;&amp;amp; make install【因-斯多​】
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;问题3：编译过程遇到了编译器问题&lt;/h4&gt;
&lt;p&gt;遇到下述报错&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql mysql-5.7.31]# ./myconﬁg.sh 
-- Running【乱宁】 cmake version 2.8.12.2
-- Could NOT find Git (missing:  GIT_EXECUTABLE) 
-- Configuring with【威付】 MAX_INDEXES = 64U
-- The C compiler identification is unknown
-- The CXX compiler identification is unknown
CMake Error: your C compiler: &quot;CMAKE_C_COMPILER-NOTFOUND&quot; was not found.   Please set CMAKE_C_COMPILER to a valid compiler path or name.
CMake Error: your CXX compiler: &quot;CMAKE_CXX_COMPILER-NOTFOUND&quot; was not found.   Please set CMAKE_CXX_COMPILER to a valid compiler path or name.
-- CMAKE_GENERATOR: Unix Makefiles
CMake Error at cmake/os/Linux.cmake:50 (MESSAGE):
  Unsupported compiler!
Call Stack (most recent call first):
  CMakeLists.txt:198 (INCLUDE)


-- Configuring incomplete, errors occurred!
See also &quot;/root/mysql-5.7.31/CMakeFiles/CMakeOutput.log&quot;.
See also &quot;/root/mysql-5.7.31/CMakeFiles/CMakeError.log&quot;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;完整解决方案
步骤1：安装编译工具链&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# CentOS/RHEL:
yum groupinstall【格鲁普因-斯多】 -y &quot;Development Tools&quot;
yum install【因-斯多​】 -y gcc gcc-c++ openssl-devel ncurses-devel

# Ubuntu/Debian:
apt update【阿普 dei 特】
apt install【因-斯多​】 -y build-essential cmake libssl-dev libncurses5-dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;步骤2：安装必需依赖包【正常执行这两个步骤就可以试试重新编译了】&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# CentOS/RHEL:
yum install【因-斯多​】 -y ncurses-devel bison-devel bzip2-devel libcurl-devel

# Ubuntu/Debian:
apt install【因-斯多​】 -y libncurses5-dev bison bzip2 libcurl4-openssl-dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;步骤3：验证GCC安装（重要）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gcc --version    # 确认显示版本信息
g++ --version    # 确认显示版本信息
# 预期输出示例：gcc (GCC) 4.8.5 20150623
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;步骤4：下载Boost库（必需）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd ~/mysql-5.7.31
wget https://sourceforge.net/projects/boost/files/boost/1.59.0/boost_1_59_0.tar.gz
tar zxf boost_1_59_0.tar.gz
ln -s boost_1_59_0 boost
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;步骤5：清理并重新配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 清理之前的错误配置
rm -rf CMakeCache.txt CMakeFiles/

# 修改脚本为正确版本
sed -i &apos;s/myconﬁg.sh/myconfig.sh/g&apos; myconfig.sh  # 修正文件名特殊字符

# 重新运行配置（确保脚本名无特殊字符）
./myconfig.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4、 Mysql数据库的初始化&lt;/h3&gt;
&lt;p&gt;进入到安装目录/mysql_3307&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#cd /mysql_3307
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第一步：创建mysql-ﬁles目录&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# mkdir【摸克跌儿】 mysql-ﬁles
# chown【吃-昂】 -R mysql:mysql /mysql_3307 
# chmod【吃-默德】 750 mysql-ﬁles
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第二步：数据库初始化操作&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# useradd -M -s /sbin/nologin mysql
# chown【吃-昂】 -R mysql:mysql /mysql_3307
# bin/mysqld --initialize【因 尼 舍 来斯】 --user=mysql --basedir=/mysql_3307 --datadir=/mysql_3307/data
2023-12-14T08:24:40.173591Z 1 [Note] A temporary password【帕斯沃德】 is generated for【fò】 root@localhost: Eq/rp?jc I2of
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第三步：拷贝mysql.server【涩·沃】脚本到/etc/init.d目录，然后启动数据库&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# cp support【瑟破特】-files/mysql.server【涩·沃】 /etc/init.d/mysql_3307
# service【瑟为斯】 mysql_3307 start【s 达儿】
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5、 MySQL源码编译安装后的后续配置&lt;/h3&gt;
&lt;h4&gt;第一步：编写mysql配置文件， my.cnf&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;#vim /mysql_3307/my.cnf
[mysqld]
basedir=/mysql_3307
datadir=/mysql_3307/data
socket=/mysql_3307/mysql.sock

#service【瑟为斯】 mysql_3307 restart【 率 s 达r】
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第二步：设置管理员密码&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# bin/mysqladmin -uroot password【帕斯沃德】 &apos;123&apos; -p
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第三步：安全设置&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# bin/mysql_secure_installation【因-斯多​ 雷申】
输入密码后 ，不更改密码 ，一直Y
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第四步：添加mysql_3307到开机启动项&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# chkconfig【切-坑菲格】 --add mysql_3307 
# chkconfig【切-坑菲格】 mysql_3307 on
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;六、 Mysql常见问题解决方案&lt;/h2&gt;
&lt;h3&gt;1、如何访问不同的数据库呢？&lt;/h3&gt;
&lt;h4&gt;方法一：直接使用对应的客户端软件访问&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# /mysql_3306/bin/mysql -uroot -p 
Enter password【帕斯沃德】:
Welcome to the MySQL monitor【魔尼特】.  Commands end with【威付】 ; or \g. Your MySQL connection id is 3
server【涩·沃】 version: 5.7.31 MySQL Community server【涩·沃】 (GPL)

[root@mysql ~]# /mysql_3307/bin/mysql -uroot -p 
Enter password【帕斯沃德】:
Welcome to the MySQL monitor【魔尼特】.  Commands end with【威付】 ; or \g. Your MySQL connection id is 3
server【涩·沃】 version: 5.7.31 Source distribution
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;方法二：定义别名的方式访问&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# alias mysql_3306=&quot;/mysql_3306/bin/mysql&quot; [root@mysql ~]# alias mysql_3307=&quot;/mysql_3307/bin/mysql&quot;
[root@mysql ~]# mysql_3306 -uroot -p 
Enter password【帕斯沃德】:
Welcome to the MySQL monitor【魔尼特】.  Commands end with【威付】 ; or \g. Your MySQL connection id is 4
server【涩·沃】 version: 5.7.31 MySQL Community server【涩·沃】 (GPL)

[root@mysql ~]# mysql_3307 -uroot -p 
Enter password【帕斯沃德】:
Welcome to the MySQL monitor【魔尼特】.  Commands end with【威付】 ; or \g. Your MySQL connection id is 4
server【涩·沃】 version: 5.7.31 Source distribution
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;方法三：拷贝相应命令到PATH可以识别的路径下并重命令&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# unalias mysql_3306 [root@mysql ~]# unalias mysql_3307
[root@mysql ~]# cp /mysql_3306/bin/mysql /usr/bin/mysql_3306 [root@mysql ~]# cp /mysql_3307/bin/mysql /usr/bin/mysql_3307 [root@mysql ~]#
[root@mysql ~]#
[root@mysql ~]# which mysql_3306 /usr/bin/mysql_3306
[root@mysql ~]# which mysql_3307 /usr/bin/mysql_3307
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;深度思考：我们之所以能够连接到数据库的本质是什么？ 答：套接字&lt;/p&gt;
&lt;h3&gt;2、 MySQL忘记密码的解决方案&lt;/h3&gt;
&lt;h4&gt;①跳过授权表&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112029717.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;②跳过授权表重启数据库&lt;/h4&gt;
&lt;h5&gt;Ⅰ关闭数据库&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# mysqladmin shutdown -p 
Enter password【帕斯沃德】:
[root@mysql ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;Ⅱ 跳过授权表启动&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;# /mysql_3306/bin/mysqld --defaults-ﬁle=/mysql_3306/my.cnf --skip-grant【古亮普】-tables -- skip-networking=on  --user=mysql &amp;amp;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;Ⅲ刷新授权表&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# mysql -uroot -p
Enter password【帕斯沃德】:    什么都不要输入 ，直接回车即可
Welcome to the MySQL monitor【魔尼特】.  Commands end with【威付】 ; or \g. Your MySQL connection id is 2
server【涩·沃】 version: 5.7.31 MySQL Community server【涩·沃】 (GPL)

mysql&amp;gt; flush【福 辣 徐】 privileges【P符类 杰 斯】;
Query OK, 0 rows afected (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;Ⅳ修改密码&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; alter【奥-特】 user &apos;root&apos;@&apos;localhost&apos; identiﬁed by &apos;123&apos;;
 Query OK, 0 rows afected (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;补充：如果未能成功，则使用一下语句修改密码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; UPDATE【阿普 dei 特】 mysql.user SET【赛特】 authentication_string = PASSWORD【帕斯沃德】(&apos;MyNewPass&apos;) WHERE User = &apos;root&apos; AND Host = &apos;localhost&apos;;
mysql&amp;gt; FLUSH【福 辣 徐】 PRIVILEGES【P符类 杰 斯】;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改密码后，使用jobs+kill命令，停止正在允许的Mysqld进程。然后使用service【瑟为斯】启动服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#jobs    
#kill %1
#service【瑟为斯】 mysql_3306 start【s 达儿】
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3、 Unix和类Unix系统重置（了解）&lt;/h4&gt;
&lt;h5&gt;①停止数据库&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;[root@node1 ~]# mysqladmin shutdown -p 
Enter password【帕斯沃德】:
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;②编写创建密码语句到文件&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;# echo &quot;ALTER【奥-特】 USER &apos;root&apos;@&apos;localhost&apos; identified【爱-丹-提伐】 BY &apos;123&apos;;&quot; &amp;gt;&amp;gt; /mysql_3306/mysql.pass
注意：该文件一定要对启动用户如mysql有所有权限
# chown【吃-昂】 -R mysql. /mysql_3306
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;③指定密码文件启动数据库&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;# mysqld --defaults-ﬁle=/mysql_3306/my.cnf --in it-ﬁle=/mysql_3306/mysql.pass  -- user=mysql &amp;amp;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;④删除密码文件，并测试&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;# rm -f /mysql_3306/mysql.pass 
# mysql -uroot -p
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Mysql5.7 源码安装实操手册&lt;/h1&gt;
&lt;h2&gt;实验一：Mysql5.7 源码安装&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;实验目的：Mysql5.7 源码安装，掌握源码安装数据库的方法，生产中更适合使用源码安装的方式。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;实验环境：centos7，内存建议 2G 及以上&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;实验步骤：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.清理环境卸载 mariadb 数据库&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;yum -y remove mariadb* 2.创建数据库运行组和用户
useradd -M -s /sbin/nologin mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3.下载源码包（使用 rz -y 去 ftp 上传）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql 需要 boost 库文件，可以单独下载 boost
也可以下载包含 boost 的 mysql 源码包
mysql-boost-5.7.31.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.解压（建议解压到/usr/local 目录下）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;tar -axf mysql-boost-5.7.31.tar.gz -C /usr/local/
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.准备源码安装的环境（工具及依赖包）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;yum -y install【因-斯多​】 ncurses ncurses-devel openssl-devel bison gcc gcc-c++ make cmake
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.配置&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;先进入解压后的目录
cmake . -DWITH_BOOST=./boost/boost_1_59_0/
可以使用默认的配置项
部分配置项在后续初始化的时候也可以指定
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.编译安装&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;make -j 2 &amp;amp;&amp;amp; make install【因-斯多​】
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;8.初始化&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;创建数据库的数据存放目录
# mkdir【摸克跌儿】 /usr/local/mysql/data
# chown【吃-昂】 -R mysql:mysql /usr/local/mysql/data
# cd /usr/local/mysql
# ./bin/mysqld --initialize【因 尼 舍 来斯】 --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;*注意：初始化的时候会自动生成 root 的默认密码
root@localhost: 6%#Uidr/d1Xh&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;9.创建配置文件：/etc/my.cnf&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[mysqld]
basedir=/usr/local/mysql 安装目录
datadir=/usr/local/mysql/data 数据存放目录
注意：路径和配置时或者初始化时指定的一致
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;10.启动服务（可以复制 server【涩·沃】 脚本）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;cd /usr/local/mysql
cp support【瑟破特】-files/mysql.server【涩·沃】 /etc/init.d/mysqld //生成 mysql.server【涩·沃】 脚本
service【瑟为斯】 mysqld start【s 达儿】 #启动 mysql 服务
service【瑟为斯】 mysqld stop【 s 多】 #关闭 mysql 服务
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;11.修改密码&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;第一次登录需要使用初始化生成的默认密码
set password【帕斯沃德】=password【帕斯沃德】(&apos;123&apos;) #修改密码为 123
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;12.添加环境变量：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# vi /etc/profile.d/mysql.sh
export【e斯 破特】 PATH=$PATH:/usr/local/mysql/bin
# source /etc/profile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;实验总结：&lt;/p&gt;
&lt;h1&gt;Mysql8.0 安装实操手册&lt;/h1&gt;
&lt;h2&gt;实验一：Mysql8.0 安装&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;实验目的：Mysql8.0 安装，熟悉并使用新版本的数据库&lt;/li&gt;
&lt;li&gt;实验环境：centos7，内存建议 2G 及以上&lt;/li&gt;
&lt;li&gt;实验步骤：&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;#yum 安装 mysql8.0&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;1.安装mysql源&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;yum install【因-斯多​】 -y https://repo.mysql.com/mysql80-community-release-el7-6.noarch.rpm
#安装后会自动生成 mysql 官方的 yum 源
会生成三个 yum 仓库配置文件只有一个默认是启用的 mysql-community.repo
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2.安装yum-utils&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;yum install【因-斯多​】 -y yum-utils #这个是 yum 管理配置文件的工具
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.导入秘钥&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
#导入密钥，如果把设置 gpgcheck=0，则不需要导入
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.关闭 mysql5.7 的仓库标签，打开 mysql8.0 的标签&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;yum-config-manager【面尼杰额】 --enable【ing 内 步】 mysql80-community #等价 enable【ing 内 步】=1
yum-config-manager【面尼杰额】 --disable【滴 s 步】 mysql57-community #等价 enable【ing 内 步】=0
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.安装客户端和服务端&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;yum install【因-斯多​】 -y mysql-community-client【克莱恩特】 mysql-community-server【涩·沃】
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6.启动服务，修改临时密码（安装时会生成一个临时密码放在日志中）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;cat /var/log/mysqld.log
mysqladmin -uroot -p 日志中的临时密码 password【帕斯沃德】 &apos;Aa123456!&apos; 密码满足复杂要求：大小写、数字、符号
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.用新密码登录即可&lt;/h3&gt;
&lt;p&gt;实验总结：&lt;/p&gt;
&lt;h1&gt;day02-Mysql基本SQL语句（上）&lt;/h1&gt;
&lt;h2&gt;一、客户端工具的使用&lt;/h2&gt;
&lt;h3&gt;1、客户端工具使用&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;shell mysql:mysql命令行工具 ，一般用来连接访问mysql数据库 &lt;/code&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;选项&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;-u, --user=name&lt;/td&gt;
&lt;td&gt;指定登录用户名&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-p, --password【帕斯沃德】&lt;/td&gt;
&lt;td&gt;指定登录密码(注意是小写p),一定要放到最后面&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-h, --host=name&lt;/td&gt;
&lt;td&gt;指定数据库的主机地址&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-P, --port【破特】=xxx&lt;/td&gt;
&lt;td&gt;指定数据库的端口号(大写P)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-S, --socket=name&lt;/td&gt;
&lt;td&gt;指定socket文件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-e, --execute=name&lt;/td&gt;
&lt;td&gt;使用非交互式操作(在shell终端执行sql语句)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;案例：使用mysql客户端工具连接服务器端（用户名：root，密码：123）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# mysql -uroot -p123
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意：以上连接方式虽然可以连接进入到Mysql，但是官方不建议直接把密码写入终端，建议-p然后直接回车，然后在终端中输入密码
案例：连接192.168.20.100服务器上的Mysql数据库（用户名：mq，密码：123）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# msyql -h 192.168.20.100 -P 3306 -umq -p
Enter password【帕斯沃德】:123
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：根据不同的套接字连接不同的数据库&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# mysql -S /mysql_3307/mysql.sock -uroot -p
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：在不进入MySQL内部的情况下，执行SQL语句，获取数据信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# mysql -e &quot;show【瘦】 databases;&quot; -uroot -p
Enter password【帕斯沃德】:123
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;扩展了解&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;默认库&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;information【因弗梅申】_schema【斯基么】&lt;/td&gt;
&lt;td&gt;1、对象信息数据库，提供对数据库元数据的访问，有关MySQL服务器的信息，例如数据库或表的名称，列的数据类型或访问权限等；&amp;lt;br&amp;gt;2、在INFORMATION【因弗梅申】_SCHEMA【斯基么】中，有数个只读表，它们实际上是视图，而不是基本表，因此你将无法看到与之相关的任何文件；&amp;lt;br&amp;gt;3、视图，是一个虚表，即视图所对应的数据不进行实际存储，数据库中只存储视图的定义，在对视图的数据进行操作时，系统根据视图的定义去操作与视图相关联的基本表&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mysql&lt;/td&gt;
&lt;td&gt;1、mysql数据库是系统数据库。它包含存储MySQL服务器运行时所需的信息的表。比如权限表、对象信息表、日志系统表、时区系统表、优化器系统表、杂项系统表等。&amp;lt;br&amp;gt;2、不可以删除,也不要轻易修改这个数据库里面的表息。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;performance_schema【斯基么】&lt;/td&gt;
&lt;td&gt;MySQL5.5开始新增一个数据库，主要用于收集数据库服务器性能；并且库里表的存储引擎均为PERFORMANCE_SCHEMA【斯基么】，而用户是不能创建存储引擎为PERFORMANCE_SCHEMA【斯基么】的表&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sys&lt;/td&gt;
&lt;td&gt;1、mysql5.7增加了sys 系统数据库，通过这个库可以快速的了解系统的元数据信息；           &amp;lt;br&amp;gt;2、sys库方便DBA发现数据库的很多信息，解决性能瓶颈； &amp;lt;br&amp;gt;3、这个库是通过视图的形式把information【因弗梅申】_schema 和performance_schema结合起来，查询出更加令人容易理解的数据&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;2、客户端工具mysqladmin使用&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;mysqladmin:客户端管理mysql数据库工具&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;①常用选项&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;选项&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;-h, --host=name&lt;/td&gt;
&lt;td&gt;指定连接数据库主机&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-p, --password【帕斯沃德】&lt;/td&gt;
&lt;td&gt;指定数据库密码&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-P, --port【破特】=#&lt;/td&gt;
&lt;td&gt;指定数据库端口&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-S, --socket=name&lt;/td&gt;
&lt;td&gt;指定数据库socket文件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-u, --user=name&lt;/td&gt;
&lt;td&gt;指定连接数据库用户&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;②常用命令&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;password【帕斯沃德】 [new-password【帕斯沃德】]&lt;/td&gt;
&lt;td&gt;更改密码&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;reload【率漏德】&lt;/td&gt;
&lt;td&gt;刷新授权表&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;shutdown&lt;/td&gt;
&lt;td&gt;停止mysql服务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;status【 斯dèi 特斯】&lt;/td&gt;
&lt;td&gt;简短查看数据库状态信息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;start【s 达儿】-slave 【斯累夫】&lt;/td&gt;
&lt;td&gt;启动slave【斯累夫】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;stop【 s 多】-slave【斯累夫】&lt;/td&gt;
&lt;td&gt;停止slave【斯累夫】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;variables【wèi 利 bóu 斯】&lt;/td&gt;
&lt;td&gt;打印可用变量&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;version&lt;/td&gt;
&lt;td&gt;查看当前mysql数据库的版本信息&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;案例：更改root账户的密码为root&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#mysqladmin password【帕斯沃德】 &apos;新密码&apos; -p
Enter password【帕斯沃德】: &apos;旧密码&apos;
#mysqladmin password【帕斯沃德】 &apos;root&apos; -p
Enter password【帕斯沃德】:123
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：更改密码后，建议刷新授权表(mysql &amp;gt; flush【福 辣 徐】 privileges【P符类 杰 斯】;)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#mysqladmin reload【率漏德】 -p
Enter password【帕斯沃德】:123
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：停止mysql&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#mysqladmin shutdown -p
Enter password【帕斯沃德】:123
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：查看mysql状态:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#mysqladmin status【 斯dèi 特斯】 -p
Enter password【帕斯沃德】:123
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：打印可用变量（mysql本身预置了很多变量信息）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#mysqladmin variables【wèi 利 bóu 斯】 -p
Enter password【帕斯沃德】:123
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：查询mysql版本&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#mysqladmin version -p
Enter password【帕斯沃德】:123
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;二、MySQL中的SQL语句&lt;/h2&gt;
&lt;h3&gt;1、什么是SQL&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;SQL 是 Structure【斯抓克彻儿】 Query【亏儿瑞】 Language【兰哥威治】(结构化查询语言)的缩写,它是使用关系模型的数据库应用语言,由 IBM 在 20 世纪 70 年代开发出来,作为 IBM 关系数据库原型 System R 的原型关系语言,实现了关系数据库中的信息检索。
20 世纪 80 年代初,美国国家标准局(ANSI)开始着手制定 SQL 标准,最早的 ANSI 标准于1986 年完成,就被叫作 SQL-86。标准的出台使 SQL 作为标准关系数据库语言的地位得到了加强。SQL 标准目前已几经修改更趋完善。
正是由于 SQL 语言的标准化,所以大多数关系型数据库系统都支持 SQL 语言,它已经发展成为多种平台进行交互操作的底层会话语言。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;2、SQL语句的分类&lt;/h3&gt;
&lt;h4&gt;DDL(Data ​​Definition【德菲尼申】 Languages【兰哥威治】)语句:&lt;/h4&gt;
&lt;p&gt;数据定义语言,这些语句定义了不同的数据段、数据库、表、列、索引等数据库对象的定义。常用的语句关键字主要包括 create【克瑞特】、drop【卓-普】、alter【奥-特】、rename【瑞-内姆】、truncate【创kí特】。&lt;/p&gt;
&lt;h4&gt;DML(Data Manipulation【么尼普雷申】 Language【兰哥威治】)语句:&lt;/h4&gt;
&lt;p&gt;数据操纵语句,用于添加、删除、更新和查询数据库记录,并检查数据完整性,常用的语句关键字主要包括 insert【因涩特】、delete【迪利特】、update【阿普 dei 特】等。&lt;/p&gt;
&lt;h4&gt;DCL(Data Control【肯错欧】 Language【兰哥威治】)语句:&lt;/h4&gt;
&lt;p&gt;数据控制语句,用于控制不同数据段直接的许可和访问级别的语句。这些语句定义了数据库、表、字段、用户的访问权限和安全级别。主要的语句关键字包括grant【古亮普】、revoke【瑞 - 沃克】 等。&lt;/p&gt;
&lt;h4&gt;DQL(Data Query【葵尔伊】 Language【兰哥威治】)语句:&lt;/h4&gt;
&lt;p&gt;数据查询语句，用于从一个或多个表中检索信息。主要的语句关键字包括select【涩莱克特】&lt;/p&gt;
&lt;h3&gt;3、MySQL中如何求帮助&lt;/h3&gt;
&lt;h4&gt;①亘古不变的官方文档（软件作用）&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://dev.mysql.com/doc/refman/5.7/en/sql-syntax.html&quot;&gt;官方文档&lt;/a&gt;（MySQL5.7）&lt;/p&gt;
&lt;h4&gt;②man文档（工作作用）&lt;/h4&gt;
&lt;p&gt;man文档可用对mysql的一些基本工具以及后台命令求帮助，比如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# man mysql
[root@mysql ~]# man mysqld
[root@mysql ~]# man mysqldump【mysql-当普】
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;③MySQL的命令行求帮助（主要针对SQL语句求帮助）&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; help;
mysql&amp;gt; ?
mysql&amp;gt; help create【克瑞特】【克瑞诶特】 table;
根据内容进行查找帮助
mysql&amp;gt; ? contents
mysql&amp;gt; help contents
You asked for【fò】 help about help category: &quot;Contents&quot;
for【fò】 more information【因弗梅申】, type &apos;help &amp;lt;item&amp;gt;&apos;, where &amp;lt;item&amp;gt; is one of the following
categories:
    Account Management
    Administration
    Compound Statements【斯忒特门特】
    Contents
    Data DeŨ nition
    Data Manipulation
    Data Types
    Functions
    Geographic Features
    Help Metadata
    Language Structure
    Plugins【普辣 京(白话)】
    Procedures
    Storage Engines
    Table Maintenance
    Transactions
    User-DeŨ ned Functions
    Utility
寻求账户管理的帮助（一级一级的向内查询）
mysql&amp;gt; ? Account Management
You asked for【fò】 help about help category: &quot;Account Management&quot;
for【fò】 more information【因弗梅申】, type &apos;help &amp;lt;item&amp;gt;&apos;, where &amp;lt;item&amp;gt; is one of the following
topics:
    ALTER【奥-特】 USER
    create【克瑞特】 USER
    DROP【卓-普】 USER
    grant【古亮普】
    RENAME【瑞-内姆】 USER
    REVOKE【瑞 - 沃克】
    set【赛特】 PASSWORD【帕斯沃德】
mysql&amp;gt; ? create【克瑞特】 USER
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4、SQL语句的基本操作&lt;/h3&gt;
&lt;h4&gt;MySQL的内部结构&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112041450.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我们平常所说的MySQL，主要指的是MySQL数据库管理软件&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;一个MYsql DBMS可用同时存放多个数据库，在理论上一个就对应一个数据库。如博客项目blog数据库、商城项目shop数据库、微信项目数据库。&lt;/li&gt;
&lt;li&gt;一个数据库中还可以同时包含多个数据表，而数据表才是真正用于存放数据的位置。（类似与我们office软件中的Excel表格），在理论上一个功能旧对应一个数据表。在博客系统中的用户管理功能，就需要一个USER数据表，博客中的文章就需要一个article【阿尔提扣】数据表、博客中的评论就需要个message【脉-西之】数据表。&lt;/li&gt;
&lt;li&gt;一个数据表又可以拆分为多个字段，每个字段就是一个属性。&lt;/li&gt;
&lt;li&gt;一个数据表中除了字段外，还有很多行，每一行都是一条完整的数据（记录）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;数据库的操作&lt;/h4&gt;
&lt;h5&gt;①创建数据库&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;创建命令 mysql&amp;gt;  create【克瑞特】
数据库标识 mysql&amp;gt;  database 【得塔-贝斯】
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;基本语法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】 数据库名称；
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;特别注意，在Mysql中，当一条SQL语句编写完毕后，一定要使用分号进行结尾，否则系统认为这条语句还没有借宿。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h6&gt;案例：创建数据库的相关案例&lt;/h6&gt;
&lt;pre&gt;&lt;code&gt;常见db1库
create【克瑞特】 database【得塔-贝斯】 db1;
mysql&amp;gt; create database db1;
Query OK, 1 row affected (0.00 sec)

创建db2库并指定默认字符集
create【克瑞特】 database【得塔-贝斯】 db2 default【迪-佛特】 charset【查赛特】 gbk;
#mysql&amp;gt; create database db2 default charset gbk;
#Query OK, 1 row affected (0.00 sec)

如果不存在（if not【nuō 特】 exists【伊贼斯】）
create【克瑞特】 database【得塔-贝斯】 if not【nuō 特】 exists【伊贼斯】 db1 default【迪-佛特】 character【k 尔特】 set【赛特】 utf8;
说明：不能创建相同名字的数据库
#mysql&amp;gt; create database if not exists db1 default character set utf8;
#Query OK, 1 row affected, 1 warning (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;扩展：编码格式，常见的gbk（中国的编码格式）与utf8（国际通用的编码格式）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;ANSI 瑞典 256字符 (abcd、1234、传统字符)
国内汉字无法通过256个字符进行描述，所以国内开发了自己的编码格式gb2312，
升级gbk
中国台湾开发了一套自己的编码格式big5
很多项目并不仅仅只在本地使用，也可能支持多国语言，标准化组织开发了一套通用编码utf8，后来5.6版本以后进行了升级utf8mb4&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;编写SQL语句是一个比较细致的工作，不建议大家直接在终端中输入SQL语句，可以先把你要写的SQL语句写入一个记事本中，然后拷贝执行。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h5&gt;②查询已创建数据库&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;显示=&amp;gt;show 【瘦】
数据库=&amp;gt;database【得塔-贝斯】
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;基本语法：
显示所有数据库&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; show【瘦】 databases【得塔-贝斯】;
#mysql&amp;gt; show databases;
#+--------------------+
#| Database           |
#+--------------------+
#| information【因弗梅申】_schema【斯基么】 |
#| db1                |
#| mysql              |
#| performance_schema【斯基么】 |
#| sys                |
#+--------------------+
#5 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h6&gt;案例：显示某个数据库的数据结构&lt;/h6&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; show【瘦】 create【克瑞特】 database【得塔-贝斯】 db1;
#mysql&amp;gt; show create database db1;
#+----------+-----------------------------------------------------------------+
#| Database | Create Database                                                 |
#+----------+-----------------------------------------------------------------+
#| db1      | CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8mb4 */ |
#+----------+-----------------------------------------------------------------+
#1 row in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;③修改数据库信息&lt;/h5&gt;
&lt;p&gt;在Mysql5以后的版本中，Mysql不支持更改数据库的名称。我们所谓的修改数据主要修改的是数据库的编码格式。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;修改=&amp;gt;alter【奥-特】
数据库=&amp;gt;database【得塔-贝斯】
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;基本语法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; alter【奥-特】 database【得塔-贝斯】 数据库名称 default【迪-佛特】 charset【查赛特】=编码格式；
&lt;/code&gt;&lt;/pre&gt;
&lt;h6&gt;案例：把db3数据库的编码格式更改为gbk&lt;/h6&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; alter【奥-特】 database【得塔-贝斯】 db3 default【迪-佛特】 charset【查赛特】=gbk;
#mysql&amp;gt; alter database db3 default charset =gbk;
#Query OK, 1 row affected (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;④删除数据库&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;删除=&amp;gt;drop【卓-普】
数据库=&amp;gt;database【得塔-贝斯】
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;基本语法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; drop【卓-普】 databse【得塔-贝斯】 数据库名称；
&lt;/code&gt;&lt;/pre&gt;
&lt;h6&gt;案例：删除db3数据库&lt;/h6&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; drop【卓-普】 database【得塔-贝斯】 db3;

#mysql&amp;gt; drop database db3;
#Query OK, 0 rows affected (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5、数据表的基本操作&lt;/h3&gt;
&lt;h4&gt;①数据表的创建&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;创建=&amp;gt; create【克瑞特】
数据表=&amp;gt;table【忒-部】
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;基本语法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql create【克瑞特】 table【忒-部】 数据表名称（
    字段1 字段类型 【字段约束】,
    字段2 字段类型 【字段约束】，
    ...
);
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;案例：创建一个admin管理表，拥有3个字段（编号、用户名称、用户密码）&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】 db_fq;
#Query OK, 1 row affected (0.00 sec)

mysql&amp;gt; use db_fq;
#Database changed
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;use在Mysql中的含义代表选择，use + 数据库名称相当于选择指定的数据库。
而且user比较特殊，其选择结束后，其尾部可以不加分号，；但是强烈建议所有的SQL语句都要加分号，养成一个号习惯&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】 TABLE【忒-部】 tb_admin(
    id TINYINT【泰尼因特】,
    username【U斯-内姆】 VARCHAR【瓦儿-查儿】(20),
    password【帕斯沃德】 CHAR【查尔】(32)
)engine【 嗯(ing) 京(白话读音) 】= innodb【伊诺 DB】 DEFAULT【迪-佛特】 charset【查赛特】=utf8;

#mysql&amp;gt; create table tb_admin(
#    -&amp;gt; id TINYINT,
#    -&amp;gt; username VARCHAR(20),
#    -&amp;gt; password CHAR(32)
#    -&amp;gt; )engine= innodb DEFAULT charset=utf8;
#Query OK, 0 rows affected (0.45 sec)
#mysql&amp;gt; 

&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;tinyint【泰尼因特】：微整形，1个字节，范围-128~127，无符号型，则表示0~255
标准字符串类型可以使用char【查尔】与varchar【瓦儿-查儿】，char【查尔】代表固定长度的字段，varchar【瓦儿-查儿】代表变化长度的字段&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;案例：创建一个article【阿尔提扣】文章表，用有4个字段（编号、标题、作者、内容）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt;use db_fq;
mysql&amp;gt;create【克瑞特】 table【忒-部】 tb_article【tb_阿尔提扣】(
    id int【因特】,
    title【泰-头】 varchar【瓦儿-查儿】(50),
    author【奥涩】 varchar【瓦儿-查儿】(20),
    content【肯-腾特】 text【泰斯特】
)engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;

#mysql&amp;gt; create table tb_article (
#    -&amp;gt;     id int,
#    -&amp;gt;     title varchar(50),
#    -&amp;gt;     author varchar(20),
#    -&amp;gt;     content text
#    -&amp;gt; )engine=innodb  default  charset=utf8;
#Query OK, 0 rows affected (0.60 sec)


&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;text【泰斯特】:文本类型，一般情况下，用varchar存储不了的字符串信息，都建议使用text【泰斯特】文本进行处理
varchar【瓦儿-查儿】存储的最大长度，理论值是65535个字符。但是实际上，有几个字符是用于存放内容的长度的，所以真正可以使用的不足65535个字符，另外varchar【瓦儿-查儿】类型存储的字符长度还和编码格式有关。1个GBK格式的占用2个字符长度，1个UTF8格式的占用3个字符长度。GBK=65532~65533/2，UTF8=65532~65533/3&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;②查询已创建数据表&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;显示=&amp;gt;show【瘦】
数据包=&amp;gt;table【忒-部】
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;显示所有数据表（当前数据库）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; use 数据库名称;
mysql &amp;gt; show【瘦】 tables【忒-部s】;
#mysql&amp;gt; show  tables;
#+-----------------+
#| Tables_in_db_fq |
#+-----------------+
#| tb_admin        |
#| tb_article      |
#+-----------------+
#2 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;显示数据表的创建过程（编码格式、字段等信息）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; show【瘦】 create【克瑞特】 table【忒-部】 数据表名称;
#mysql&amp;gt; show create table tb_admin;
#+----------#+-----------------------------------------------------------------------------------------------------------------------------------------------------------+
#| Table    | Create Table                                                                                                                                   |
#+----------+------------------------------------------------------------------------------------------------------------------------------------------------+
#| tb_admin | CREATE TABLE `tb_admin` (
#  `id` tinyint(4) DEFAULT NULL,
#  `username` varchar(20) DEFAULT NULL,
#  `password` char(32) DEFAULT NULL
#) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
#+----------+------------------------------------------------------------------------------------------------------------------------------------------------+
#1 row in set (0.00 sec)

或
mysql &amp;gt; desc 数据包名称；
#mysql&amp;gt; desc tb_admin;
#+----------+-------------+------+-----+---------+-------+
#| Field    | Type        | Null | Key | Default | Extra |
#+----------+-------------+------+-----+---------+-------+
#| id       | tinyint(4)  | YES  |     | NULL    |       |
#| username | varchar(20) | YES  |     | NULL    |       |
#| password | char(32)    | YES  |     | NULL    |       |
#+----------+-------------+------+-----+---------+-------+
#3 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;③修改数据表&lt;/h4&gt;
&lt;h5&gt;Ⅰ数据表字段添加&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;修改=&amp;gt; alter【奥-特】
数据表=&amp;gt;table【忒-部】
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;基本语法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; alter【奥-特】 table【忒-部】 数据表名称 add 新字段名称 字段类型 first【佛斯特】|after【啊夫特】 其他字段名称;
选项说明：
first【佛斯特】:把新添加字段放在第一位
after【啊夫特】 字段名称 ：把新添加字段放在指定字段的后面
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：把tb_article【tb_阿尔提扣】文章表中添加一个addtime【艾德-泰姆】字段，类型为date（年-月-日）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; alter【奥-特】 table【忒-部】 tb_article【tb_阿尔提扣】 add addtime【艾德-泰姆】 date【呆特】 after【啊夫特】 content【肯-腾特】;
#mysql&amp;gt; alter table tb_article add addtime date after content;
#Query OK, 0 rows affected (0.71 sec)
#Records: 0  Duplicates: 0  Warnings: 0

mysql &amp;gt; desc tb_article【tb_阿尔提扣】;
#mysql&amp;gt; desc tb_article;
#+---------+-------------+------+-----+---------+-------+
#| Field   | Type        | Null | Key | Default | Extra |
#+---------+-------------+------+-----+---------+-------+
#| id      | int(11)     | YES  |     | NULL    |       |
#| title   | varchar(50) | YES  |     | NULL    |       |
#| author  | varchar(20) | YES  |     | NULL    |       |
#| content | text        | YES  |     | NULL    |       |
#| addtime | date        | YES  |     | NULL    |       |
#+---------+-------------+------+-----+---------+-------+
#5 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;Ⅱ修改字段名称或字段类型&lt;/h5&gt;
&lt;p&gt;修改字段名称与字段类型（也可以只修改名称）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; alter【奥-特】 table【忒-部】 tb_admin change【趁(chèn)吉】 username【U斯-内姆】 user【U斯】 varchar【瓦儿-查儿(20);
#mysql&amp;gt; alter table tb_admin change username user varchar(20);        #把username改为user
#Query OK, 0 rows affected (0.13 sec)
#Records: 0  Duplicates: 0  Warnings: 0

mysql &amp;gt; desc tb_admin;
#mysql&amp;gt; desc tb_admin;
#+----------+-------------+------+-----+---------+-------+
#| Field    | Type        | Null | Key | Default | Extra |
#+----------+-------------+------+-----+---------+-------+
#| id       | tinyint(4)  | YES  |     | NULL    |       |
#| user     | varchar(20) | YES  |     | NULL    |       |
#| password | char(32)    | YES  |     | NULL    |       |
#+----------+-------------+------+-----+---------+-------+
#3 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;仅修改字段的类型&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; alter【奥-特】 table【忒-部】 tb_admin modify【莫迪fái】 user【U斯】 varchar【瓦儿-查儿(40);
#mysql&amp;gt; alter table tb_admin modify user varchar(40);        #varchar(20)改为varchar(40)
#Query OK, 0 rows affected (0.05 sec)
#Records: 0  Duplicates: 0  Warnings: 0

mysql &amp;gt; desc tb_admin;
#mysql&amp;gt; desc tb_admin;
#+----------+-------------+------+-----+---------+-------+
#| Field    | Type        | Null | Key | Default | Extra |
#+----------+-------------+------+-----+---------+-------+
#| id       | tinyint(4)  | YES  |     | NULL    |       |
#| user     | varchar(40) | YES  |     | NULL    |       |
#| password | char(32)    | YES  |     | NULL    |       |
#+----------+-------------+------+-----+---------+-------+
#3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;Ⅲ删除某个字段&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;#mysql&amp;gt; desc tb_article;
#+---------+-------------+------+-----+---------+-------+
#| Field   | Type        | Null | Key | Default | Extra |
#+---------+-------------+------+-----+---------+-------+
#| id      | int(11)     | YES  |     | NULL    |       |
#| title   | varchar(50) | YES  |     | NULL    |       |
#| author  | varchar(20) | YES  |     | NULL    |       |
#| content | text        | YES  |     | NULL    |       |
#| addtime | date        | YES  |     | NULL    |       |
#+---------+-------------+------+-----+---------+-------+
#5 rows in set (0.00 sec)

mysql &amp;gt; alter【奥-特】 table【忒-部】 tb_article【tb_阿尔提扣】 drop【卓-普】 字段名称；
#mysql&amp;gt; alter table tb_article drop addtime;
#Query OK, 0 rows affected (0.56 sec)
#Records: 0  Duplicates: 0  Warnings: 0

mysql &amp;gt; desc tb_article【tb_阿尔提扣】;
#mysql&amp;gt; desc tb_article;
#+---------+-------------+------+-----+---------+-------+
#| Field   | Type        | Null | Key | Default | Extra |
#+---------+-------------+------+-----+---------+-------+
#| id      | int(11)     | YES  |     | NULL    |       |
#| title   | varchar(50) | YES  |     | NULL    |       |
#| author  | varchar(20) | YES  |     | NULL    |       |
#| content | text        | YES  |     | NULL    |       |
#+---------+-------------+------+-----+---------+-------+
#4 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;Ⅳ修改数据表引擎&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;#mysql&amp;gt; show【瘦】 create table tb_article;
#+------------+----------------------------------------------------------------------------------------------------------------------------------------------+
#| Table      | Create Table                                                                                                                                                                            #|
#+------------+----------------------------------------------------------------------------------------------------------------------------------------------+
#| tb_article | CREATE TABLE `tb_article` (
#  `id` int(11) DEFAULT NULL,
#  `title` varchar(50) DEFAULT NULL,
#  `author` varchar(20) DEFAULT NULL,
#  `content` text
#) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
#+------------+----------------------------------------------------------------------------------------------------------------------------------------------+
#1 row in set (0.00 sec)
mysql &amp;gt; alter【奥-特】 table【忒-部】 tb_article【tb_阿尔提扣】 engine【 嗯(ing) 京(白话读音) 】=myisam【迈-艾塞姆】;
#mysql&amp;gt; alter table tb_article engine=myisam【迈-艾塞姆】;
#Query OK, 0 rows affected (0.40 sec)
#Records: 0  Duplicates: 0  Warnings: 0

mysql &amp;gt; show【瘦】 create【克瑞特】 table【忒-部】 tb_article【tb_阿尔提扣】;
#mysql&amp;gt; show create table tb_article;
#+------------+----------------------------------------------------------------------------------------------------------------------------------------------+
#| Table      | Create Table                                                                                                                                                                            #|
#+------------+----------------------------------------------------------------------------------------------------------------------------------------------+
#| tb_article | CREATE TABLE `tb_article` (
#  `id` int(11) DEFAULT NULL,
#  `title` varchar(50) DEFAULT NULL,
#  `author` varchar(20) DEFAULT NULL,
#  `content` text
#) ENGINE=MyISAM DEFAULT CHARSET=utf8 |
#+------------+----------------------------------------------------------------------------------------------------------------------------------------------+
#1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;Ⅴ修改数据表的编码格式&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;#mysql&amp;gt; show【瘦】 create table tb_admin;
#+----------+------------------------------------------------------------------------------------------------------------------------------------------------+
#| Table    | Create Table                                                                                                                                                         #|
#+----------+------------------------------------------------------------------------------------------------------------------------------------------------+
#| tb_admin | CREATE TABLE `tb_admin` (
#  `id` tinyint(4) DEFAULT NULL,
#  `user` varchar(20) DEFAULT NULL,
#  `password` char(32) DEFAULT NULL
#) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
#+----------+------------------------------------------------------------------------------------------------------------------------------------------------+
#1 row in set (0.00 sec)

mysql &amp;gt; alter【奥-特】 table【忒-部】 tb_admin default【迪-佛特】 charset【查赛特】=gbk;
#mysql&amp;gt; alter table tb_admin default charset=gbk;
#Query OK, 0 rows affected (0.05 sec)
#Records: 0  Duplicates: 0  Warnings: 0

mysql &amp;gt; show【瘦】 create【克瑞特】 table【忒-部】 tb_admin;
#mysql&amp;gt; show create table tb_admin;
#+----------+------------------------------------------------------------------------------------------------------------------------------------------------+
#| Table    | Create Table                                                                                                                                                         #|
#+----------+------------------------------------------------------------------------------------------------------------------------------------------------+
#| tb_admin | CREATE TABLE `tb_admin` (
#  `id` tinyint(4) DEFAULT NULL,
#  `user` varchar(20) DEFAULT NULL,
#  `password` char(32) DEFAULT NULL
#) ENGINE=InnoDB DEFAULT CHARSET=gbk |
#+----------+------------------------------------------------------------------------------------------------------------------------------------------------+
#1 row in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;Ⅵ修改数据表名称（把tb_article【tb_阿尔提扣】更改为tb_news【牛斯】）&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;修改数据表名称
#mysql&amp;gt; show tables;
#+-----------------+
#| Tables_in_db_fq |
#+-----------------+
#| tb_admin        |
#| tb_article      |
#+-----------------+
#2 rows in set (0.00 sec)
mysql &amp;gt; rename【瑞-内姆】 table【忒-部】 tb_article【tb_阿尔提扣】 to tb_news【牛斯】:
#mysql&amp;gt; rename【瑞-内姆】 table tb_article to tb_news;
#Query OK, 0 rows affected (0.00 sec)

mysql &amp;gt; show【瘦】 tables【忒-部s】;
#mysql&amp;gt; show tables;
#+-----------------+
#| Tables_in_db_fq |
#+-----------------+
#| tb_admin        |
#| tb_news         |
#+-----------------+
#2 rows in set (0.00 sec)

重命名的同时移动数据表到指定的数据表（了解）
mysql &amp;gt; create【克瑞特】 database【得塔-贝斯】 db_it
#mysql&amp;gt; create database db_it;    #创建db_it数据库
#Query OK, 1 row affected (0.00 sec)

mysql &amp;gt; rename【瑞-内姆】 table【忒-部】 db_fq.tb_news【牛斯】 to db_it.tb_article【tb_阿尔提扣】;
#mysql&amp;gt; rename【瑞-内姆】 table db_fq.tb_news to db_it.tb_article;    #剪切db_fq数据库的tb_news表 到 db_it数据库，命令为tb_article
#Query OK, 0 rows affected (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;④删除数据表&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;删除=&amp;gt;drop【卓-普】
数据表=&amp;gt;table【忒-部】
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;基本语法&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; drop【卓-普】 table【忒-部】 数据表名称;
#mysql&amp;gt; use db_it;
#Database changed
#mysql&amp;gt; show tables;
#+-----------------+
#| Tables_in_db_it |
#+-----------------+
#| tb_article      |
#+-----------------+
#1 row in set (0.00 sec)

#mysql&amp;gt; drop table tb_article;
#Query OK, 0 rows affected (0.00 sec)

#mysql&amp;gt; show tables;
#Empty set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6、数据的增删改查（重点）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;增加：insert【因涩特】
删除：delete【迪利特】
修改：update【阿普 dei 特】
查询：select【涩莱克特】
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;①数据的增加操作&lt;/h4&gt;
&lt;p&gt;基本语法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; insert【因涩特】  into【因兔】 数据表名称（[]字段1，字段2，字段3....）  values【挖柳斯】(字段1的值，字段2的值，字段3的值...);
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;特别注意：在SQL语句中，除了数字，其他类型的值，都需要使用引号引起来，否则插入时会报错&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h5&gt;第一步：准备数据表&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; use db_fq;
#mysql&amp;gt; use db_fq;
#Database changed
mysql &amp;gt; create【克瑞特】 table【忒-部】 tb_user【U斯】(
    id int【因特】,
    username【U斯-内姆】 varchar【瓦儿-查儿】(20),
    age【诶吉】 tinyint【泰尼因特】 unsigned【安赛因德】,
    gender【间德尔】 enum【ing纽某】(&apos;男&apos;,&apos;女&apos;,&apos;保密&apos;),
    address【额拽斯】 varchar【瓦儿-查儿(255)
)engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;
#mysql&amp;gt; create table tb_user(
#    -&amp;gt;     id int,
#    -&amp;gt;     username varchar(20),
#    -&amp;gt;     age tinyint unsigned,
#    -&amp;gt;     gender enum(&apos;男&apos;,&apos;女&apos;,&apos;保密&apos;),
#    -&amp;gt;     address varchar(255)
#    -&amp;gt; )engine=innodb default charset=utf8;
#Query OK, 0 rows affected (0.34 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;unsigned【安赛因德】代表无符号型，只有0到正数。tinyint【泰尼因特】 unsigned【安赛因德】无符号型，范围0~255
enum【ing纽某】【硬南姆】枚举类型，多选一。只能从给定的值选择一个&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h5&gt;第二步：使用insert【因涩特】语句插入数据&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; insert【因涩特】  into【因兔】 tb_user【U斯】  values【挖柳斯】 (1,&apos;李明&apos;,24,&apos;男&apos;,&apos;湖北省武汉市&apos;);
#mysql&amp;gt; insert into tb_user values (1,&apos;李明&apos;,24,&apos;男&apos;,&apos;湖北省武汉市&apos;);
#Query OK, 1 row affected (0.05 sec)
mysql &amp;gt; insert【因涩特】  into【因兔】 tb_user【U斯】(id,username【U斯-内姆】,age【诶吉】)  values【挖柳斯】 (2,&apos;马飞&apos;,23);
#mysql&amp;gt; insert into tb_user(id,username,age) values (2,&apos;马飞&apos;,23);
#Query OK, 1 row affected (0.06 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;②数据的查询操作&lt;/h4&gt;
&lt;p&gt;基本语法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 数据表名称 [where【威尔】 查询条件];
mysql &amp;gt; select【涩莱克特】 id,username【U斯-内姆】.age【诶吉】 from【弗乱】 数据表名称 [where【威尔】 查询条件];
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：查询tb_user【U斯】表中所有的记录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_user【U斯】;
#mysql&amp;gt; select * from tb_user;
#+------+----------+------+--------+--------------------+
#| id   | username | age  | gender | address            |
#+------+----------+------+--------+--------------------+
#|    1 | 李明     |   24 | 男     | 湖北省武汉市       |
#|    2 | 马飞     |   23 | NULL   | NULL               |
#+------+----------+------+--------+--------------------+
#2 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：查询tb_user【U斯】表中的id,username【U斯-内姆】以及age【诶吉】字段中对应的数据信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 id,username【U斯-内姆】,age【诶吉】 from【弗乱】 tb_user【U斯】;
#mysql&amp;gt; select id,username,age from tb_user;
#+------+----------+------+
#| id   | username | age  |
#+------+----------+------+
#|    1 | 李明     |   24 |
#|    2 | 马飞     |   23 |
#+------+----------+------+
#2 rows in set (0.01 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：只查询id=2的小伙伴信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_user【U斯】 where【威尔】 id=2;
#mysql&amp;gt; select * from tb_user where id=2;
#+------+----------+------+--------+---------+
#| id   | username | age  | gender | address |
#+------+----------+------+--------+---------+
#|    2 | 马飞     |   23 | NULL   | NULL    |
#+------+----------+------+--------+---------+
#1 row in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：查询年龄大于23岁的小伙伴信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_user【U斯】 where【威尔】 age【诶吉】&amp;gt;23;
#mysql&amp;gt; select * from tb_user where age &amp;gt;23;
#+------+----------+------+--------+--------------------+
#| id   | username | age  | gender | address            |
#+------+----------+------+--------+--------------------+
#|    1 | 李明     |   24 | 男     | 湖北省武汉市       |
#+------+----------+------+--------+--------------------+
#1 row in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;③数据的修改操作&lt;/h4&gt;
&lt;p&gt;基本语法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; update【阿普 dei 特】 数据表名称 set【赛特】 字段1=更新后的值，字段2=更新后的值，... where【威尔】 更新条件;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;特别说明：如果在更新数据时，不指定更新条件，则其会把这个数据表的所有记录全部更新一遍。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;案例：修改username【U斯-内姆】=&apos;马飞&apos;这条记录，将其性别更新为男，家庭住址更新为广东省深圳市&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; update【阿普 dei 特】 tb_user【U斯】 set【赛特】 gender【间德尔】=&apos;男&apos;,address【额拽斯】=&apos;广东省深圳市&apos; where【威尔】 username【U斯-内姆】=&apos;马飞&apos;;
#mysql&amp;gt; update tb_user set gender=&apos;男&apos;,address=&apos;广东省深圳市&apos; where username=&apos;马飞&apos;;
#Query OK, 1 row affected (0.04 sec)
#Rows matched: 1  Changed: 1  Warnings: 0

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：今年是2023年，假设到了2024年，现在所存储的学生信息年龄都差一岁，需要整体进行一次更新&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; update【阿普 dei 特】 tb_user【U斯】 set【赛特】 age【诶吉】=age【诶吉】+1;
#mysql&amp;gt; update tb_user set age=age+1;
#Query OK, 2 rows affected (0.05 sec)
#Rows matched: 2  Changed: 2  Warnings: 0

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;④数据的删除操作&lt;/h4&gt;
&lt;p&gt;基本语法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; delete【迪利特】 from【弗乱】 数据表名称 [where【威尔】 删除条件];
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：删除tb_user【U斯】表中,id=1的用户信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; delete【迪利特】 from【弗乱】 tb_user【U斯】 where【威尔】 id=1;
#mysql&amp;gt; delete【迪  利 特】from tb_user where id=1;
#Query OK, 1 row affected (0.07 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;delete【迪利特】 from【弗乱】与truncate【创kí特】清空数据表操作&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; delete【迪利特】 from【弗乱】 数据表;
#mysql&amp;gt; delete【迪  利 特】from tb_user;
#Query OK, 1 row affected (0.05 sec)

或
mysql &amp;gt; truncate【创kí特】 数据表；
#mysql&amp;gt; truncate tb_user;
#Query OK, 0 rows affected (0.26 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;delete【迪利特】 from【弗乱】与truncate【创kí特】区别在哪里？&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;delete【迪利特】：删除数据记录
数据操作语言（DML）
在事务控制里，DML要么commit【肯米特】，要么rollback【柔拜克】
删除大量记录速度慢，只删除数据部回收高水位线
可以带条件删除&lt;/li&gt;
&lt;li&gt;truncate【创kí特】：删除所有数据记录
数据定义语言（DDL）
不在事务控制里，DDL语句执行前会提交前面所有未提交的事务
清理大量数据速度快，回收高水位线
不能带条件删除&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;7、自动增长（水位线）与主键约束&lt;/h3&gt;
&lt;h4&gt;①自动增长（对某个字段进行自动编号）&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; create【克瑞特】 table【忒-部】 tb_user【U斯】(
    id int【因特】 not【nuō 特】 null【nò】 auto_increment【奥特欧_因克瑞门特】,
    username【U斯-内姆】 varchar【瓦儿-查儿】(20),
    age【诶吉】 tinyint【泰尼因特】 unsigned【安赛因德】,
    gender【间德尔】 enum【ing纽某】(&apos;男&apos;,&apos;女&apos;,&apos;保密&apos;),
    address【额拽斯】 varchar【瓦儿-查儿(255)
)engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;
#mysql&amp;gt; create table tb_user(
#    -&amp;gt;     id int not null auto_increment,
#    -&amp;gt;     username varchar(20),
#    -&amp;gt;     age tinyint unsigned,
#    -&amp;gt;     gender enum(&apos;男&apos;,&apos;女&apos;,&apos;保密&apos;),
#    -&amp;gt;     address varchar(255)
#    -&amp;gt; )engine=innodb default charset=utf8;
#ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key
#这个错误 ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key 表示在表定义中，MySQL 要求自增列（auto_increment 修饰的列）只能有一个，并且必须将其定义为键（通常是主键）
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;not null【nò】代表非空约束，这个字段只要是插入数据就必须要有值&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;②主键约束（非空、唯一）&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt;create【克瑞特】 table【忒-部】 tb_user【U斯】(
    id int【因特】 not【nuō 特】 null【nò】 auto_increment【奥特欧_因克瑞门特】,
    username【U斯-内姆】 varchar【瓦儿-查儿】(20),
    age【诶吉】 tinyint【泰尼因特】 unsigned【安赛因德】,
    gender【间德尔】 enum【ing纽某】(&apos;男&apos;,&apos;女&apos;,&apos;保密&apos;),
    address【额拽斯】 varchar【瓦儿-查儿(255),
    primary key(id)
) engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;
#mysql&amp;gt; create table tb_user(
#    -&amp;gt;     id int not null auto_increment,
#    -&amp;gt;     username varchar(20),
#    -&amp;gt;     age tinyint unsigned,
#    -&amp;gt;     gender enum(&apos;男&apos;,&apos;女&apos;,&apos;保密&apos;),
#    -&amp;gt;     address varchar(255),
#    -&amp;gt;     primary key(id)
#    -&amp;gt; ) engine=innodb default charset=utf8;
#Query OK, 0 rows affected (0.34 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;插入数据时,id位置直接写NULL【nò】即可&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; insert【因涩特】  into【因兔】 tb_user【U斯】  values【挖柳斯】 (null【nò】,&apos;李明&apos;,24,&apos;男&apos;,&apos;湖北省武汉市&apos;);
#mysql&amp;gt; insert into tb_user values (null,&apos;李明&apos;,24,&apos;男&apos;,&apos;湖北省武汉市&apos;);
#Query OK, 1 row affected (0.05 sec)

mysql &amp;gt; insert【因涩特】  into【因兔】 tb_user【U斯】  values【挖柳斯】 (null【nò】,&apos;马飞&apos;,23,&apos;男&apos;,&apos;广东省深圳市&apos;);
#mysql&amp;gt; insert into tb_user values (null,&apos;马飞&apos;,23,&apos;男&apos;,&apos;广东省深圳市&apos;);
#Query OK, 1 row affected (0.06 sec)

mysql &amp;gt; insert【因涩特】  into【因兔】 tb_user【U斯】  values【挖柳斯】 (null【nò】,&apos;李淑&apos;,18,&apos;女&apos;,&apos;浙江省杭州市&apos;);
#mysql&amp;gt; insert into tb_user values (null,&apos;李淑&apos;,18,&apos;女&apos;,&apos;浙江省杭州市&apos;);
#Query OK, 1 row affected (0.06 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;day03-MySQL的基本SQL语句（下）&lt;/h1&gt;
&lt;h2&gt;一、常见的数据类型&lt;/h2&gt;
&lt;h3&gt;1、回顾数据表的创建语法&lt;/h3&gt;
&lt;p&gt;基本语法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; create【克瑞特】 table【忒-部】 数据表名称（
字段名称1 字段类型 字段约束
字段名称1 字段类型 字段约束
...
primary【普赖莫瑞】 key【发音&apos;ki&apos;】（主键字段 =&amp;gt; 不能为空、必须唯一）
）engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;经验：一般情况下，我们在设计数据表时，必须拥有一个id主键字段，非空，自动编号，主键约束&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在创建数据表时，必须明确指定字段的名称以及字段的类型，那到底Mysql中的SQL语句支持哪些字段类型呢？&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;参考下图
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112050702.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;2、数值类型&lt;/h3&gt;
&lt;h4&gt;⭐整数类型（整数、精准）&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112100800.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;应用场景：人的年龄、考试成绩等等相关的信息都可以使用整数类型进行存储，那整数类型有这么多的形式，我应该选择哪一个呢？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;答：整数类型的选择主要取决于数值的范围&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;比如存储中国的人口类型，可以用INT【因特】类型或者BIGINT【比格因特】类型，但是在数据库设计原则中，不是越大越好，而是正好满足条件即可。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;案例：设计一个数据表如tb_student【tb_斯丢等特】学生表（id,username【U斯-内姆】,age【诶吉】,mobile【抹拜儿】）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; use 数据库名称；
MySQL &amp;gt; create【克瑞特】 table【忒-部】 tb_student【tb_斯丢等特】(
id mediumint【咪迪厄姆-因特】 unsigned【安赛因德】 not【nuō 特】 null【nò】 auto_increment【奥特欧_因克瑞门特】,
username【U斯-内姆】 varchar【瓦儿-查儿】(20),
age【诶吉】 tinyint【泰尼因特】 unsigned【安赛因德】,
mobile【抹拜儿】 char【查尔】(11),
primary【普赖莫瑞】 key【发音&apos;ki&apos;】(id)
) engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# create table tb_student( 
# id mediumint unsigned not null auto_increment,
# username varchar(20),
# age tinyint unsigned,
# mobile char(11),
# primary key (id)
# ) engine=innodb default charset=utf8;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;⭐小数类型（浮点类型、定点类型）&lt;/h4&gt;
&lt;h5&gt;①浮点类型（近似值）&lt;/h5&gt;
&lt;p&gt;FLOAT【弗洛特】和DOUBLE【答步】&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;float【弗洛特】和double【答步】类型代表近似数字数据值。Mysql对于单精度值使用四个字节，对于双精度值使用八个字节。FLOAT【弗洛特】单精度浮点数精确到7位小数，double【答步】双精度浮点数精确道大约15位小数。float【弗洛特】类型会随着数值的增大精度会减小&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;举例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FLOAT【弗洛特】（M,D），M表示存储的有效位数，D代表小数点后面的位数；即整数位数+小数部分不能超过M值。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;column【科勒姆】1 FLOAT【弗洛特】(7,4)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果插入一个999.00009到column【科勒姆】1列，那么mysql在存储时会四舍五入变为999.0001插入&lt;/li&gt;
&lt;li&gt;DOUBLE【答步】(7,4)：DOUBLE【答步】类型的使用与FLOAT【弗洛特】类型完全一致，唯一的区别就是占用字节不同浮点数的精度有所不同。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;②定点类型（精确值）&lt;/h5&gt;
&lt;p&gt;decimal【戴希莫】和NUMERIC【纽麦一克】&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;decimal【戴希莫】E和NUMERIC【纽麦一克】类型的存储精确的数值数据。使用这些类型时，重要的是要保留精确的精度，例如使用货币数据。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;举例说明：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;salary【晒了瑞】 decimal【戴希莫】(5,2)

在上面的例子中，薪水字段的类型为decimal【戴希莫】，表示精确的数字。其中，5代表精度，2代表刻度。
精度表示数值存储的有效位数，刻度表示小数点后面可存储的位数。
decimal【戴希莫】(5,2)能够存储五位数和两位小数的任何值，因此可以存储在salary【晒了瑞】 列中的值的范围-999.99是 999.99

特殊注意：
decimal【戴希莫】(M)和decimal【戴希莫】(M,0)是相等的，存储长度取决于M的值，默认情况下M值为10.刻度为0表示没有小数。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：定义一个职员表tb_staff【tb_斯戴夫】，定义字段（id,username【U斯-内姆】,salary【晒了瑞】,addtime【艾德泰姆】)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; use db_fq;
mysql &amp;gt; create【克瑞特】 table【忒-部】 tb_staff【tb_斯戴夫】 (
    id smallint【斯莫尔因特】 unsigned【安赛因德】 not【nuō 特】 null【nò】 auto_increment【奥特欧_因克瑞门特】,
    username【U斯-内姆】 varchar【瓦儿-查儿】(20),
    salary【晒了瑞】 decimal【戴希莫】(11,2),
    addtime【艾德泰姆】 date【得塔】 ,
    primary【普赖莫瑞】 key【发音&apos;ki&apos;】(id)
) engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# mysql&amp;gt; create table tb_staff(
# id smallint unsigned not null auto_increment,
# username varchar(20),
# salary decimal(11,2),
# addtime date,
# primary key(id)
# )engine=innodb default charset=utf8;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3、字符串类型&lt;/h3&gt;
&lt;h4&gt;⭐CHAR【查尔】类型&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;CHAR【查尔】类型的字符串为定长，长度范围是0到255之间的任何值，占用定长的存储空间，不足的部分用空格填充；读取时删掉后面的空格。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;password【帕斯沃德】 char【查尔】 (32)
username【U斯-内姆】 (10)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;①存储空间&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;CHAR【查尔】（M）类型的存储空间和字符集有关系，一个中文在utf8字符集中占用3个bytes、gbk占用2个bytes、数字和字符统一用一个字符表示。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;②存储机制&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;在不够M长度时，Mysq老在存储数据时，需要填充特殊的空格&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;③举例说明&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;字段名称 CHAR【查尔】（M），M表示字符数&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;应用场景：加密后的密码=&amp;gt;char【查尔】(32)，手机号码mobile【抹拜儿】（11），身份证号码等待&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;案例：创建一个tb_admin数据表，定义字段（id,username【U斯-内姆】,password【帕斯沃德】）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; use db_fq;
mysql &amp;gt; create【克瑞特】 table【忒-部】 tb_admin(
    id tinyint【泰尼因特】 unsigned【安赛因德】 not【nuō 特】 null【nò】 auto_increment【奥特欧_因克瑞门特】,
    username【U斯-内姆】 varchar【瓦儿-查儿】(10),
    password【帕斯沃德】 char【查尔】(32),
    primary【普赖莫瑞】 key【发音&apos;ki&apos;】(id)
) engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;⭐varchar【瓦儿-查儿】类型&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;varchar【瓦儿-查儿】是变长存储，仅使用必要的存储空间
name varchar【瓦儿-查儿】(10)
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;①存储空间&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;varchar【瓦儿-查儿】（M）类型的存储空间和字符集有关，一个中文在utf8中占用3各bytes、gbk占用2各bytes、数字和字符用一个字符表示&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;②存储机制&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;varchar【瓦儿-查儿】（M）字段存储实际是从第二个字节开始存储，然后用1到2各字节表示实际长度，剩下的才是可以存储数据的范围，因为最大可用存储范围是65535-3=65532字节；&lt;/li&gt;
&lt;li&gt;第一个字节标识是否为空（长度小于255字节，使用一个字节来表示长度；大于255字节使用两个字节来表示长度）。&lt;/li&gt;
&lt;li&gt;应用场景：主要适合存储长度不固定的字符串信息，入用户名称、产品标题、新闻标题、新闻描述（不超过255个字符）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;案例：创建一个tb_news【纽斯】数据表，定义段（id、title【泰头】、description【迪斯克瑞普申】、addtime【艾德泰姆】）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; use db_fq;
mysql &amp;gt; create【克瑞特】 table【忒-部】 tb_news【纽斯】(
    id int【因特】 not【nuō 特】 null【nò】 auto_increment【奥特欧_因克瑞门特】,
    title【泰头】 varchar【瓦儿-查儿】(80),
    description【迪斯克瑞普申】 varchar【瓦儿-查儿】(255),
    addtime【艾德泰姆】 date【呆特】 ,
    primary【普赖莫瑞】 key【发音&apos;ki&apos;】(id)
)engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;⭐TEXT【泰斯特】类型&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;TEXT【泰斯特】代表的是文本类型的数据，当我们使用varchar【瓦儿-查儿】类型存储数据时（早期最大只能存储255个字符，mysql5版本中，gbk可用存储3万多个字符，utf格式可用存储2万多个字符），如果超过了varchar【瓦儿-查儿】的最大存储范围，则可以考虑使用TEXT【泰斯特】文本类型&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;经验之谈：255个字符以内（包括），定长就使用CHAR【查尔】类型，变长就使用varchar【瓦儿-查儿】类型，如果超过了255个字符，则使用TEXT【泰斯特】文本类型&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;应用场景：文本内容、产品的详细介绍等&lt;/p&gt;
&lt;p&gt;案例：创建一个tb_goods【故兹】产品表、定义字段（id、name、price【普莱斯】、content）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; use db_fq;
mysql &amp;gt; create【克瑞特】 table【忒-部】 tb_goods【故兹】(
    id int【因特】 not【nuō 特】 null【nò】 auto_increment【奥特欧_因克瑞门特】,
    name varchar【瓦儿-查儿】(80),
    price【普莱斯】 decimal【戴希莫】(11,2),
    content text【泰斯特】,
    primary【普赖莫瑞】 key【发音&apos;ki&apos;】(id)
)engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;⭐其他类型&lt;/h4&gt;
&lt;p&gt;BLOB【拉布】：保存二进制的大型数据（字符串），没有字符集，eg:图片、音频、视频等&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;实际的运维工作中，很少将文件之间保存在数据库端，一般文件的存储都是基于路径操作&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;ENUM【伊牛姆】枚举类型：多选一，从给定的多个选择中选择一个，如 gender【詹德尔】【詹德尔】 enum【伊牛姆】（&apos;男&apos;,&apos;女&apos;,&apos;保密&apos;）&lt;/li&gt;
&lt;li&gt;SET【赛特】集合类型：多选多，从给定的多个选项中选中多个，如hobby【合比】 set【赛特】(&apos;吃饭&apos;,&apos;睡觉&apos;,&apos;看书&apos;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4、日期时间类型&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112110603.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;经验：时间的选择比较简单，主要看你需要的时间格式，是年月日、小时分钟秒等等&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;㈠ DATE【呆特】类型（年-月-日）&lt;/h4&gt;
&lt;p&gt;The  date  type is used for【fò】 values【挖柳斯】 with【威付】 a date part but no time part. MySQL retrieves and displays  date  values【挖柳斯】 in &apos;YYYY-MM-DD&apos;  format. The supported【瑟破踢的】 range is  &apos;1000-01-01&apos;  to  &apos;9999-12-31&apos; .&lt;/p&gt;
&lt;h4&gt;㈡ DATE【呆特】TIME（年月日小时分钟秒）&lt;/h4&gt;
&lt;p&gt;The  DATETIME【dei 特泰姆】  type is used for【fò】 values【挖柳斯】 that contain both date and time parts. MySQL retrieves and displays DATETIME 【dei 特泰姆】 values【挖柳斯】 in  &apos;YYYY-MM-DD-HH:MM:SS&apos;  format. The supported【瑟破踢的】 range is  &apos;1000-01-01 00:00:00&apos;  to  &apos;9999-12-31 23:59:59&apos; .&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DATETIME【dei 特泰姆】范围相对于TIMESTAMP【泰姆斯当普】范围更广，1000-01-01 00:00:00&apos;` to `&apos;9999-12-31 23:59:59&apos;`
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;㈢ TIMESTAMP【泰姆斯当普】（年月日小时分钟秒）&lt;/h4&gt;
&lt;p&gt;The  TIMESTAMP  data type is used for【fò】 values【挖柳斯】 that contain both date and time parts.  TIMESTAMP  has a range&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TIMESTAMP【泰姆斯当普】选项如果不插入时间，则MYSQL会自动调用系统时间写入数据
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;㈣ TIME（小时：分钟：秒）&lt;/h4&gt;
&lt;p&gt;MySQL retrieves and displays  TIME  values【挖柳斯】 in  &apos;HH:MM:SS&apos;  format (or  &apos;HHH:MM:SS&apos;  format 【佛(4声)】 large hours values). TIME  values【挖柳斯】 may range  from【弗乱】  &apos;-838:59:59&apos;  to  &apos;838:59:59&apos; .&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;说明：小时部分可以是这么大，因为可以使用TIME类型不仅代表一个时间(必须小于24小时),而且可以表示运行时间或两个事件之间的时间间隔(可能大于24小时,甚至负数)。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TIME这一列如果存储缩写，需要注意mysql的解释方式。无效的时间值会被转换成&apos;00:00:00&apos; 。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;㈤ YEAR&lt;/h4&gt;
&lt;p&gt;YEAR(4)  and  YEAR(2)  diƊer in display format, but have the same range of values.
For 4-digit format, MySQL displays  YEAR  values【挖柳斯】 in  YYYY  format, with【威付】 a range of  1901  to  2155 , or  0000 .
For 2-digit format, MySQL displays only the last two (least signiŨcant) digits; for example,  70  (1970 or 2070) or  69  (2069).&lt;/p&gt;
&lt;h4&gt;无效的值将会被转换成&apos;0000&apos;.&lt;/h4&gt;
&lt;p&gt;案例：编写tb_article【阿踢扣】文章表，定义字段（id、title【泰头】、description【迪斯克瑞普申】、addtime【艾德泰姆】）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; use db_fq:

mysql &amp;gt; create【克瑞特】 table【忒-部】 tb_article1【阿踢扣】(
    id int【因特】 not【nuō 特】 null【nò】 auto_increment【奥特欧_因克瑞门特】,
    title【泰头】 varchar【瓦儿-查儿】(80),
    description【迪斯克瑞普申】 varchar【瓦儿-查儿】(255),
    addtime【艾德泰姆】 datetime【dei 特-泰姆】,
    primary【普赖莫瑞】 key【发音&apos;ki&apos;】(id)
)engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;

mysql &amp;gt; create【克瑞特】 table【忒-部】 tb_article2【阿踢扣】(
    id int【因特】 not【nuō 特】 null【nò】 auto_increment【奥特欧_因克瑞门特】,
    title【泰头】 varchar【瓦儿-查儿】(80),
    description【迪斯克瑞普申】 varchar【瓦儿-查儿】(255),
    addtime【艾德泰姆】 timestamp【泰姆斯当普】,
    primary【普赖莫瑞】 key【发音&apos;ki&apos;】(id)
)engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;

mysql &amp;gt; insert【因涩特】  into【因兔】 tb_article【阿踢扣】1 values【挖柳斯】 (null【nò】,&apos;mysql你好&apos;,&apos;mysql很好用&apos;,null【nò】);

mysql &amp;gt; insert【因涩特】  into【因兔】 tb_article【阿踢扣】2 values【挖柳斯】 (null【nò】,&apos;mysql你好&apos;,&apos;mysql很好用&apos;,null【nò】);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;&lt;strong&gt;二、SQL查询语句（重点）&lt;/strong&gt;&lt;/h2&gt;
&lt;h3&gt;1、回顾SQL查询语句&lt;/h3&gt;
&lt;p&gt;基本语法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 */字段列表 from【弗乱】 数据表名称 where【威尔】 查询条件;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2、SQL查询五子句&lt;/h3&gt;
&lt;p&gt;基本语法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 */字段列表 from【弗乱】 数据表名称 where【威尔】  子句 group【格鲁普】  by【拜】 子句 having【嗨夫营】 子句 order【欧朵】 by【拜】 子句 limit【肋梅特】 子句;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;①where【威尔】 子句
②group【格鲁普】 by【拜】子句
③having【嗨夫营】子句
④order【欧朵】 by【拜】子句
⑤limit【肋梅特】子句&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;特别注意：五子句的顺序是固定的，不能颠倒&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;3、WHERE【威尔】 子句&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;符号&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;%&lt;/td&gt;
&lt;td&gt;匹配0个或任意多个字符&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;_(下划线)&lt;/td&gt;
&lt;td&gt;匹配单个字符&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;like【赖特】&lt;/td&gt;
&lt;td&gt;模糊匹配&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;=&lt;/td&gt;
&lt;td&gt;等于,精确匹配&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;gt;&lt;/td&gt;
&lt;td&gt;大于&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt;&lt;/td&gt;
&lt;td&gt;小于&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;gt;=&lt;/td&gt;
&lt;td&gt;大于等于&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt;=&lt;/td&gt;
&lt;td&gt;小于等于&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;!=和&amp;lt;&amp;gt;&lt;/td&gt;
&lt;td&gt;不等于&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;! 和 not【nuō 特】&lt;/td&gt;
&lt;td&gt;逻辑非&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;||  和 or&lt;/td&gt;
&lt;td&gt;逻辑或&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;amp;&amp;amp; 和 and&lt;/td&gt;
&lt;td&gt;逻辑与&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;between【B豚ing】...and....&lt;/td&gt;
&lt;td&gt;两者之间&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;in (....)&lt;/td&gt;
&lt;td&gt;在...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;not【nuō 特】 in (....)&lt;/td&gt;
&lt;td&gt;不在&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;准备测试数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; use db_fq;
mysql &amp;gt; create【克瑞特】 table【忒-部】 tb_student【tb_斯丢等特】(
    id mediumint【咪迪厄姆-因特】 not【nuō 特】 null【nò】 auto_increment【奥特欧_因克瑞门特】,
    name varchar【瓦儿-查儿】(20),
    age【诶吉】 tinyint【泰尼因特】 unsigned【安赛因德】 default【迪-佛特】 0,
    gender【詹德尔】 enum【伊牛姆】(&apos;男&apos;,&apos;女&apos;),
    address【额拽斯】 varchar【瓦儿-查儿】(255),
    primary【普赖莫瑞】 key【发音&apos;ki&apos;】(id)
) engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;
#插入测试数据
mysql &amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;刘备&apos;,33,&apos;男&apos;,&apos;湖北省武汉市&apos;);
mysql &amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;貂蝉&apos;,18,&apos;女&apos;,&apos;湖南省长沙市&apos;);
mysql &amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;关羽&apos;,31,&apos;男&apos;,&apos;湖北省荆州市&apos;);
mysql &amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;大桥&apos;,20,&apos;女&apos;,&apos;浙江省杭州市&apos;);
mysql &amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;赵云&apos;,25,&apos;男&apos;,&apos;河北省石家庄市&apos;);
mysql &amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;小桥&apos;,18,&apos;女&apos;,&apos;江苏省扬州市&apos;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：使用like【赖特】模糊查询语句，查询姓&quot;关&quot; 的同学信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_student【tb_斯丢等特】 where【威尔】  name like【赖特】 &apos;关%&apos;;
# mysql&amp;gt; select * from tb_student where  name like &apos;关%&apos;;
# +----+--------+------+--------+--------------------+
# | id | name   | age  | gender | address            |
# +----+--------+------+--------+--------------------+
# |  3 | 关羽   |   31 | 男     | 湖北省荆州市       |
# +----+--------+------+--------+--------------------+
# 1 row in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;like【赖特】模糊查询，有点类似于管道命令中的数据检索。有两个关键字：%和_，%百分号代表任意个任意字符，下划线代表任意的某个字符（只能匹配一个）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;案例：like【赖特】模糊查询语句，查询名字中带&quot;蝉&quot;字的同学信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_student【tb_斯丢等特】 where【威尔】  name like【赖特】 &apos;%蝉%&apos;;
# mysql&amp;gt; select * from tb_student where name like &apos;%蝉%&apos;;
# +----+--------+------+--------+--------------------+
# | id | name   | age  | gender | address            |
# +----+--------+------+--------+--------------------+
# |  2 | 貂蝉   |   18 | 女     | 湖南省长沙市       |
# +----+--------+------+--------+--------------------+
# 1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：like【赖特】模糊查询语句，查询云字结尾且名字为两个字的同学信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_student【tb_斯丢等特】 where【威尔】  name like【赖特】 &apos;_云&apos;;
# mysql&amp;gt; select * from tb_student where name like &apos;_云&apos;;
# +----+--------+------+--------+-----------------------+
# | id | name   | age  | gender | address               |
# +----+--------+------+--------+-----------------------+
# |  5 | 赵云   |   25 | 男     | 河北省石家庄市        |
# +----+--------+------+--------+-----------------------+
# 1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：获取学生表中，id编号为3的同学信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_student【tb_斯丢等特】 where【威尔】  id=3;
# mysql&amp;gt; select * from tb_student where id=3;
# +----+--------+------+--------+--------------------+
# | id | name   | age  | gender | address            |
# +----+--------+------+--------+--------------------+
# |  3 | 关羽   |   31 | 男     | 湖北省荆州市       |
# +----+--------+------+--------+--------------------+
# 1 row in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：获取年龄大于25周岁的同学信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_student【tb_斯丢等特】 where【威尔】  age【诶吉】&amp;gt;25;
# mysql&amp;gt; select  * from tb_student where age &amp;gt;25;
# +----+--------+------+--------+--------------------+
# | id | name   | age  | gender | address            |
# +----+--------+------+--------+--------------------+
# |  1 | 刘备   |   33 | 男     | 湖北省武汉市       |
# |  3 | 关羽   |   31 | 男     | 湖北省荆州市       |
# +----+--------+------+--------+--------------------+
# 2 rows in set (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：获取学生表中，性别不为男的同学信息（获取女同学的信息）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_student【tb_斯丢等特】 where【威尔】  gender【詹德尔】&amp;lt;&amp;gt;&apos;男&apos;;
# mysql&amp;gt; select * from tb_student where gender &amp;lt;&amp;gt;&apos;男&apos;;
# +----+--------+------+--------+--------------------+
# | id | name   | age  | gender | address            |
# +----+--------+------+--------+--------------------+
# |  2 | 貂蝉   |   18 | 女     | 湖南省长沙市       |
# |  4 | 大桥   |   20 | 女     | 浙江省杭州市       |
# |  6 | 小乔   |   18 | 女     | 江苏省扬州市       |
# +----+--------+------+--------+--------------------+
# 3 rows in set (0.00 sec)

#mysql&amp;gt; select * from tb_student where gender !=&apos;男&apos;;
#+----+--------+------+--------+--------------------+
#| id | name   | age  | gender | address            |
#+----+--------+------+--------+--------------------+
#|  2 | 貂蝉   |   18 | 女     | 湖南省长沙市       |
#|  4 | 大桥   |   20 | 女     | 浙江省杭州市       |
#|  6 | 小乔   |   18 | 女     | 江苏省扬州市       |
#+----+--------+------+--------+--------------------+
#3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：获取班级中年龄大于30岁的男同学信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_student【tb_斯丢等特】 where【威尔】  age【诶吉】&amp;gt;30 &amp;amp;&amp;amp;  gender【詹德尔】=&apos;男&apos;;
#mysql&amp;gt; select * from tb_student where age&amp;gt;30 and gender=&apos;男&apos;;
#+----+--------+------+--------+--------------------+
#| id | name   | age  | gender | address            |
#+----+--------+------+--------+--------------------+
#|  1 | 刘备   |   33 | 男     | 湖北省武汉市       |
#|  3 | 关羽   |   31 | 男     | 湖北省荆州市       |
#+----+--------+------+--------+--------------------+
#2 rows in set (0.00 sec)

#mysql&amp;gt; select * from tb_student where age&amp;gt;30 &amp;amp;&amp;amp; gender=&apos;男&apos;;
#+----+--------+------+--------+--------------------+
#| id | name   | age  | gender | address            |
#+----+--------+------+--------+--------------------+
#|  1 | 刘备   |   33 | 男     | 湖北省武汉市       |
#|  3 | 关羽   |   31 | 男     | 湖北省荆州市       |
#+----+--------+------+--------+--------------------+
#2 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：获取id值为1、3、5的同学信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_student【tb_斯丢等特】 where【威尔】  id=1 or id=3 or id=5;
# mysql&amp;gt; select * from tb_student where id=1 or id=3 or id=5;
# +----+--------+------+--------+-----------------------+
# | id | name   | age  | gender | address               |
# +----+--------+------+--------+-----------------------+
# |  1 | 刘备   |   33 | 男     | 湖北省武汉市          |
# |  3 | 关羽   |   31 | 男     | 湖北省荆州市          |
# |  5 | 赵云   |   25 | 男     | 河北省石家庄市        |
# +----+--------+------+--------+-----------------------+
# 3 rows in set (0.00 sec)
# 
# mysql&amp;gt; select * from tb_student where id=1 || id=3 || id=5;
# +----+--------+------+--------+-----------------------+
# | id | name   | age  | gender | address               |
# +----+--------+------+--------+-----------------------+
# |  1 | 刘备   |   33 | 男     | 湖北省武汉市          |
# |  3 | 关羽   |   31 | 男     | 湖北省荆州市          |
# |  5 | 赵云   |   25 | 男     | 河北省石家庄市        |
# +----+--------+------+--------+-----------------------+
# 3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：获取年龄在18周岁~25周岁之间的同学信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_student【tb_斯丢等特】 where【威尔】  age【诶吉】&amp;gt;=18 and age【诶吉】&amp;lt;=25;
或
mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_student【tb_斯丢等特】 where【威尔】  age【诶吉】 between【B豚ing】 18 and 25;
# mysql&amp;gt; select * from tb_student where age&amp;gt;=18 and age&amp;lt;=25;
# +----+--------+------+--------+-----------------------+
# | id | name   | age  | gender | address               |
# +----+--------+------+--------+-----------------------+
# |  2 | 貂蝉   |   18 | 女     | 湖南省长沙市          |
# |  4 | 大桥   |   20 | 女     | 浙江省杭州市          |
# |  5 | 赵云   |   25 | 男     | 河北省石家庄市        |
# |  6 | 小乔   |   18 | 女     | 江苏省扬州市          |
# +----+--------+------+--------+-----------------------+
# 4 rows in set (0.00 sec)
# 
# mysql&amp;gt; select * from tb_student where age between 18 and 25;
# +----+--------+------+--------+-----------------------+
# | id | name   | age  | gender | address               |
# +----+--------+------+--------+-----------------------+
# |  2 | 貂蝉   |   18 | 女     | 湖南省长沙市          |
# |  4 | 大桥   |   20 | 女     | 浙江省杭州市          |
# |  5 | 赵云   |   25 | 男     | 河北省石家庄市        |
# |  6 | 小乔   |   18 | 女     | 江苏省扬州市          |
# +----+--------+------+--------+-----------------------+
# 4 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：获取id值为2、4、6的同学信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_student【tb_斯丢等特】 where【威尔】  id in (2,4,6);
# mysql&amp;gt; select * from tb_student where id=2 || id=4 || id=6;
# +----+--------+------+--------+--------------------+
# | id | name   | age  | gender | address            |
# +----+--------+------+--------+--------------------+
# |  2 | 貂蝉   |   18 | 女     | 湖南省长沙市       |
# |  4 | 大桥   |   20 | 女     | 浙江省杭州市       |
# |  6 | 小乔   |   18 | 女     | 江苏省扬州市       |
# +----+--------+------+--------+--------------------+
# 3 rows in set (0.00 sec)
# 
# mysql&amp;gt; select * from tb_student where id in(2,4,6);
# +----+--------+------+--------+--------------------+
# | id | name   | age  | gender | address            |
# +----+--------+------+--------+--------------------+
# |  2 | 貂蝉   |   18 | 女     | 湖南省长沙市       |
# |  4 | 大桥   |   20 | 女     | 浙江省杭州市       |
# |  6 | 小乔   |   18 | 女     | 江苏省扬州市       |
# +----+--------+------+--------+--------------------+
# 3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4、distinct【迪斯定特】数据去重&lt;/h3&gt;
&lt;p&gt;案例：获取tb_student【tb_斯丢等特】学生表中学员年龄的分布情况。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 distinct【迪斯定特】 age【诶吉】 from【弗乱】 tb_student【tb_斯丢等特】;
# mysql&amp;gt; select distinct age from tb_student;
# +------+
# | age  |
# +------+
# |   33 |
# |   18 |
# |   31 |
# |   20 |
# |   25 |
# +------+
# 5 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5、GROUP【格鲁普】 BY【拜】子句（重点和难度）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;group【格鲁普】  by【拜】子句的作用：对数据进行分组操作，为什么要进行分组呢？分组的目标就是进行分组统计&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;日常生活中的分组太多了，如按男女进行分组，按成绩进行分组，按院校，系部分组，按部门进行分组。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;根据给定数据列的查询结果进行分组统计，最终得到一个分组汇总表
注：一般情况下group【格鲁普】 by 【拜】需与统计函数一起使用才有意义&lt;/p&gt;
&lt;h4&gt;①统计函数&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;常见统计函数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;max【mà 斯】&lt;/td&gt;
&lt;td&gt;求最大值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;min【敏ì】&lt;/td&gt;
&lt;td&gt;求最小值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sum【桑à姆】&lt;/td&gt;
&lt;td&gt;求和&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;avg【A 付阁】&lt;/td&gt;
&lt;td&gt;求平均值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;count【kàn特】&lt;/td&gt;
&lt;td&gt;求总行数&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;案例：求tb_student【tb_斯丢等特】表中一共有多少个记录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】 tb_student【tb_斯丢等特】;
# mysql&amp;gt; select count(*) from tb_student;
# +----------+
# | count(*) |
# +----------+
# |        6 |
# +----------+
# 1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：求年龄的最大值与最小值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 max【mà 斯】(age【诶吉】) from【弗乱】 tb_student【tb_斯丢等特】;
与
mysql &amp;gt; select【涩莱克特】 mi(age【诶吉】) from【弗乱】 tb_student【tb_斯丢等特】;
# mysql&amp;gt; select max(age) from tb_student;    #最大
# +----------+
# | max(age) |
# +----------+
# |       33 |
# +----------+
# 1 row in set (0.00 sec)
# 
# mysql&amp;gt; select min(age) from tb_student;    #最小
# +----------+
# | min(age) |
# +----------+
# |       18 |
# +----------+
# 1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：求针对id字段求和&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 sum【桑à姆】(id) from【弗乱】 tb_student【tb_斯丢等特】;
# mysql&amp;gt; select sum(id) from tb_student;
# +---------+
# | sum(id) |
# +---------+
# |      21 |
# +---------+
# 1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：求学员表中年龄的平均值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 avg【A 付阁】(age【诶吉】) from【弗乱】 tb_student【tb_斯丢等特】;
# mysql&amp;gt; select avg(age) from tb_student;
# +----------+
# | avg(age) |
# +----------+
# |  24.1667 |
# +----------+
# 1 row in set (0.01 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;②GROUP【格鲁普】 BY【拜】分组&lt;/h4&gt;
&lt;p&gt;案例：求tb_student【tb_斯丢等特】表中，男同学的总数量与女同学的总数量&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】  gender【詹德尔】,count【kàn特】(*) from【弗乱】 tb_student【tb_斯丢等特】 group【格鲁普】  by【拜】  gender【詹德尔】;
# mysql&amp;gt; select gender,count(*) from tb_student group by gender;
# +--------+----------+
# | gender | count(*) |
# +--------+----------+
# | 男     |        3 |
# | 女     |        3 |
# +--------+----------+
# 2 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;在MySQL5.7以后版本中，分组字段必须出现在select【涩莱克特】后面的查询字段中&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;案例：求tb_student【tb_斯丢等特】表中，男同学年龄的最大值与女同学年龄的最大值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】  gender【詹德尔】,max【mà 斯】(age【诶吉】) from【弗乱】 tb_student【tb_斯丢等特】 group【格鲁普】  by【拜】  gender【詹德尔】;
# mysql&amp;gt; select gender,max(age) from tb_student group by gender;
# +--------+----------+
# | gender | max(age) |
# +--------+----------+
# | 男     |       33 |
# | 女     |       20 |
# +--------+----------+
# 2 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;③GROUP【格鲁普】 BY【拜】分组原理&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112123850.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;以后只要涉及到要求每个学科，每个部分、每个年级、每个系部薪资最高、成绩最好、薪资的平均值等等，就是基于GROUP【格鲁普】 BY【拜】 + 统计函数&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;6、HAVING【嗨夫营】子句&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;having【嗨夫营】与where【威尔】 类似，根据条件对数据进行过滤筛选&lt;/li&gt;
&lt;li&gt;where【威尔】 针对表中的列发挥作用，查询数据&lt;/li&gt;
&lt;li&gt;having【嗨夫营】针对查询结果集发挥作用，筛选数据&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;案例：having【嗨夫营】在做简单查询时可以替代where【威尔】 子句&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_student【tb_斯丢等特】 having【嗨夫营】 age【诶吉】&amp;gt;20;
# mysql&amp;gt; select * from tb_student having age&amp;gt;20;
# +----+--------+------+--------+-----------------------+
# | id | name   | age  | gender | address               |
# +----+--------+------+--------+-----------------------+
# |  1 | 刘备   |   33 | 男     | 湖北省武汉市          |
# |  3 | 关羽   |   31 | 男     | 湖北省荆州市          |
# |  5 | 赵云   |   25 | 男     | 河北省石家庄市        |
# +----+--------+------+--------+-----------------------+
# 3 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：按学科进行分组，求每个学科拥有多少人&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; drop【卓-普】 table【忒-部】 tb_student【tb_斯丢等特】;
mysql &amp;gt; create【克瑞特】 table【忒-部】 tb_student【tb_斯丢等特】(
    id mediumint【咪迪厄姆-因特】 not【nuō 特】 null【nò】 auto_increment【奥特欧_因克瑞门特】,
    name varchar【瓦儿-查儿】(20),
    age【诶吉】 tinyint【泰尼因特】 unsigned【安赛因德】 default【迪-佛特】 0,
     gender【詹德尔】 enum【伊牛姆】(&apos;男&apos;,&apos;女&apos;),
    subject【萨布杰克特】 enum【伊牛姆】(&apos;ui&apos;,&apos;java&apos;,&apos;yunwei&apos;,&apos;python&apos;),
    primary【普赖莫瑞】 key【发音&apos;ki&apos;】(id)
) engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;
# mysql&amp;gt; drop table tb_student;
# Query OK, 0 rows affected (0.14 sec)
# 
# mysql&amp;gt; create table tb_student(
# -&amp;gt; id mediumint not null auto_increment,
# -&amp;gt; name varchar(20),
# -&amp;gt; age tinyint unsigned default 0,
# -&amp;gt; gender enum(&apos;男&apos;,&apos;女&apos;),
# -&amp;gt; subject enum(&apos;ui&apos;,&apos;java&apos;,&apos;yunwei&apos;,&apos;python&apos;),
# -&amp;gt; primary key(id)
# -&amp;gt; )engine=innodb default charset=utf8;
# Query OK, 0 rows affected (0.33 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;悟空&apos;,255,&apos;男&apos;,&apos;ui&apos;);
mysql&amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;八戒&apos;,250,&apos;男&apos;,&apos;python&apos;),;
mysql&amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;唐僧&apos;,30,&apos;男&apos;,&apos;yunwei&apos;);
mysql&amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;沙僧&apos;,150,&apos;男&apos;,&apos;java&apos;);
mysql&amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;小白龙&apos;,100,&apos;男&apos;,&apos;yunwei&apos;);
mysql&amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;白骨精&apos;,28,&apos;女&apos;,&apos;ui&apos;);
mysql&amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;兔子精&apos;,22,&apos;女&apos;,&apos;yunwei&apos;);
mysql&amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;狮子精&apos;,33,&apos;男&apos;,&apos;yunwei&apos;);
# mysql&amp;gt; insert into tb_student values (null,&apos;悟空&apos;,255,&apos;男&apos;,&apos;ui&apos;);
# Query OK, 1 row affected (0.04 sec)
# 
# mysql&amp;gt; insert into tb_student values (null,&apos;八戒&apos;,250,&apos;男&apos;,&apos;python&apos;);
# Query OK, 1 row affected (0.04 sec)
# 
# mysql&amp;gt; insert into tb_student values (null,&apos;唐僧&apos;,30,&apos;男&apos;,&apos;yunwei&apos;);
# Query OK, 1 row affected (0.04 sec)
# 
# mysql&amp;gt; insert into tb_student values (null,&apos;小白&apos;,100,&apos;男&apos;,&apos;yunwei&apos;);
# Query OK, 1 row affected (0.05 sec)
# 
# mysql&amp;gt; insert into tb_student values (null,&apos;白骨精&apos;,28,&apos;女&apos;,&apos;ui&apos;);
# Query OK, 1 row affected (0.05 sec)
# 
# mysql&amp;gt; insert into tb_student values (null,&apos;兔子&apos;,22,&apos;女&apos;,&apos;yunwei&apos;);
# Query OK, 1 row affected (0.06 sec)
# 
# mysql&amp;gt; insert into tb_student values (null,&apos;狮子&apos;,33,&apos;男&apos;,&apos;yunwei&apos;);
# Query OK, 1 row affected (0.04 sec)
或
insert【因涩特】 into【因兔】 tb_student【tb_斯丢等特】 values(null【nò】,&apos;悟空&apos;,255,&apos;男&apos;,&apos;ui&apos;),(null【nò】,&apos;八戒&apos;,250,&apos;男&apos;,&apos;python&apos;),
    (null【nò】,&apos;唐僧&apos;,30,&apos;男&apos;,&apos;yunwei&apos;),(null【nò】,&apos;沙僧&apos;,150,&apos;男&apos;,&apos;java&apos;),(null【nò】,&apos;小白龙&apos;,100,&apos;男&apos;,&apos;yunwei&apos;),
    (null【nò】,&apos;白骨精&apos;,28,&apos;女&apos;,&apos;ui&apos;),(null【nò】,&apos;兔子精&apos;,22,&apos;女&apos;,&apos;yunwei&apos;),(null【nò】,&apos;狮子精&apos;,33,&apos;男&apos;,&apos;yunwei&apos;);
    
# mysql&amp;gt; insert into tb_student values (null,&apos;悟空&apos;,255,&apos;男&apos;,&apos;ui&apos;),(null,&apos;八戒&apos;,250,&apos;男&apos;,&apos;python&apos;),(null,&apos;唐僧&apos;,30,&apos;男&apos;,&apos;yunwei&apos;),(null,&apos;小白&apos;,100,&apos;男&apos;,&apos;yunwei&apos;),(null,&apos;白骨精&apos;,28,&apos;女&apos;,&apos;ui&apos;),(null,&apos;兔子&apos;,22,&apos;女&apos;,&apos;yunwei&apos;),(null,&apos;狮子&apos;,33,&apos;男&apos;,&apos;yunwei&apos;);
# Query OK, 7 rows affected (0.03 sec)
# Records: 7  Duplicates: 0  Warnings: 0
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 subject【萨布杰克特】,count【kàn特】(*) from【弗乱】 tb_student【tb_斯丢等特】 group【格鲁普】  by【拜】 subject【萨布杰克特】;
# mysql&amp;gt; select subject,count(*) from tb_student group by subject;
# +---------+----------+
# | subject | count(*) |
# +---------+----------+
# | ui      |        2 |
# | yunwei  |        4 |
# | python  |        1 |
# +---------+----------+
# 3 rows in set (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：求每个学科中，学科人数大于3人的学科信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 subject【萨布杰克特】,count【kàn特】(*) from【弗乱】 tb_student【tb_斯丢等特】 group【格鲁普】  by【拜】 subject【萨布杰克特】 having【嗨夫营】 count【kàn特】(*)&amp;gt;3;
# mysql&amp;gt; select subject,count(*) from tb_student group by subject having count(*)&amp;gt;3;
# +---------+----------+
# | subject | count(*) |
# +---------+----------+
# | yunwei  |        4 |
# +---------+----------+
# 1 row in set (0.01 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7、ORDER【欧朵】 BY【拜】子句&lt;/h3&gt;
&lt;p&gt;主要作用就是对数据进行排序（升序、降序）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;升序：从小到大 1，2，3，4，5&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 数据表名称 ... order【欧朵】 by【拜】 字段名称 asc;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;降序：从大到小，5，4，3，2，1&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 数据表名称 ... order【欧朵】 by【拜】 字段名称 desc;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：按年龄进行排序（由大到小）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_student【tb_斯丢等特】 order【欧朵】 by【拜】 age【诶吉】 desc;
# mysql&amp;gt; select * from tb_student order by age desc;
# +----+-----------+------+--------+---------+
# | id | name      | age  | gender | subject |
# +----+-----------+------+--------+---------+
# |  1 | 悟空      |  255 | 男     | ui      |
# |  2 | 八戒      |  250 | 男     | python  |
# |  4 | 小白      |  100 | 男     | yunwei  |
# |  7 | 狮子      |   33 | 男     | yunwei  |
# |  3 | 唐僧      |   30 | 男     | yunwei  |
# |  5 | 白骨精    |   28 | 女     | ui      |
# |  6 | 兔子      |   22 | 女     | yunwei  |
# +----+-----------+------+--------+---------+
# 7 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;8、LIMIT【肋梅特】子句&lt;/h3&gt;
&lt;p&gt;基本语法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 数据表名称 ... limit【肋梅特】 number【能波】;查询满足条件的number【能波】数量
或
mysql &amp;gt; select【涩莱克特】 * from【弗乱】 数据表名称 ... limit【肋梅特】 offset【奥夫赛特】,number【能波】; 从偏移量为offset【奥夫赛特】开始查询，查询number【能波】条记录，offset【奥夫赛特】的值从0开始
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;offset【奥夫赛特】偏移量：
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112133585.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;案例：获取学生表中，年龄最大的学员&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_student【tb_斯丢等特】 order【欧朵】 by【拜】 age【诶吉】 desc limit【肋梅特】 1;
# mysql&amp;gt; select * from tb_student order by age desc limit 1;
# +----+--------+------+--------+---------+
# | id | name   | age  | gender | subject |
# +----+--------+------+--------+---------+
# |  1 | 悟空   |  255 | 男     | ui      |
# +----+--------+------+--------+---------+
# 1 row in set (0.01 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：从偏移量为1的元素开始查询，查询2条记录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_student【tb_斯丢等特】 limit【肋梅特】 1,2;
# mysql&amp;gt; select * from tb_student limit 1,2;
# +----+--------+------+--------+---------+
# | id | name   | age  | gender | subject |
# +----+--------+------+--------+---------+
# |  2 | 八戒   |  250 | 男     | python  |
# |  3 | 唐僧   |   30 | 男     | yunwei  |
# +----+--------+------+--------+---------+
# 2 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;limit【肋梅特】子句在开发项目中，主要应用于数据分页。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;案例：实现数据分页
第一页：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_student【tb_斯丢等特】 limit【肋梅特】 0,2;
# mysql&amp;gt; select * from tb_student limit 0,2;
# +----+--------+------+--------+---------+
# | id | name   | age  | gender | subject |
# +----+--------+------+--------+---------+
# |  1 | 悟空   |  255 | 男     | ui      |
# |  2 | 八戒   |  250 | 男     | python  |
# +----+--------+------+--------+---------+
# 2 rows in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第二页：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_student【tb_斯丢等特】 limit【肋梅特】 2,2;
# mysql&amp;gt; select * from tb_student limit 2,2;
# +----+--------+------+--------+---------+
# | id | name   | age  | gender | subject |
# +----+--------+------+--------+---------+
# |  3 | 唐僧   |   30 | 男     | yunwei  |
# |  4 | 小白   |  100 | 男     | yunwei  |
# +----+--------+------+--------+---------+
# 2 rows in set (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;三、SQL多表查询&lt;/h2&gt;
&lt;h3&gt;1、什么是多表查询&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;我们刚才学习的SQL五子句都主要是针对单表情况，我们在实际工作中，也可能会接触到一些复杂的多表查询&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2、union【U凝】联合查询&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;UNION【U凝】联合查询的作用：把多个表中的数据联合在一起进行显示。应用场景：分库分表&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;第一步：创建两个结构相同的学生表tb_student【tb_斯丢等特】1于tb_student【tb_斯丢等特】2&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; create【克瑞特】 table【忒-部】 tb_student【tb_斯丢等特】1(
    id mediumint【咪迪厄姆-因特】 not【nuō 特】 null【nò】 auto_increment【奥特欧_因克瑞门特】,
    name varchar【瓦儿-查儿】(20),
    age【诶吉】 tinyint【泰尼因特】 unsigned【安赛因德】 default【迪-佛特】 0,
     gender【詹德尔】 enum【伊牛姆】(&apos;男&apos;,&apos;女&apos;),
    subject【萨布杰克特】 enum【伊牛姆】(&apos;ui&apos;,&apos;java&apos;,&apos;yunwei&apos;,&apos;python&apos;),
    primary【普赖莫瑞】 key【发音&apos;ki&apos;】(id)
) engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;
# mysql&amp;gt; create table tb_student1( 
#     id mediumint not null auto_increment,
#     name varchar(20),
#     age tinyint unsigned default 0,
#     gender enum(&apos;男&apos;,&apos;女&apos;),
#     subject enum(&apos;ui&apos;,&apos;java&apos;,&apos;yunwei&apos;,&apos;python&apos;),
#     primary key(id)
#     )engine=innodb default charset=utf8;
# Query OK, 0 rows affected (0.42 sec)
# 
mysql &amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】1 values【挖柳斯】 (1,&apos;悟空&apos;,255,&apos;男&apos;,&apos;ui&apos;);
# mysql&amp;gt; insert into tb_student1 values (1,&apos;悟空&apos;,255,&apos;男&apos;,&apos;ui&apos;);
# Query OK, 1 row affected (0.04 sec)
# 

mysql &amp;gt; create【克瑞特】 table【忒-部】 tb_student【tb_斯丢等特】2(
    id mediumint【咪迪厄姆-因特】 not【nuō 特】 null【nò】 auto_increment【奥特欧_因克瑞门特】,
    name varchar【瓦儿-查儿】(20),
    age【诶吉】 tinyint【泰尼因特】 unsigned【安赛因德】 default【迪-佛特】 0,
     gender【詹德尔】 enum【伊牛姆】(&apos;男&apos;,&apos;女&apos;),
    subject【萨布杰克特】 enum【伊牛姆】(&apos;ui&apos;,&apos;java&apos;,&apos;yunwei&apos;,&apos;python&apos;),
    primary【普赖莫瑞】 key【发音&apos;ki&apos;】(id)
) engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;
# mysql&amp;gt; create table tb_student2(
#     id mediumint not null auto_increment,
#     name varchar(20),
#     age tinyint unsigned default 0,
#     gender enum(&apos;男&apos;,&apos;女&apos;),
#     subject enum(&apos;ui&apos;,&apos;java&apos;,&apos;yunwei&apos;,&apos;python&apos;),
#     primary key(id)
#     )engine=innodb default charset=utf8;
# Query OK, 0 rows affected (0.40 sec)

mysql &amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】2 values【挖柳斯】 (2,&apos;唐僧&apos;,30,&apos;男&apos;,&apos;yunwei&apos;);
# mysql&amp;gt; insert into tb_student2 values (2,&apos;唐僧&apos;,30,&apos;男&apos;,&apos;yunwei&apos;);
# Query OK, 1 row affected (0.11 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第二步：使用UNION【U凝】进行联合查询&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_student【tb_斯丢等特】1 union【U凝】 select【涩莱克特】 * from【弗乱】 tb_student【tb_斯丢等特】2;
# mysql&amp;gt; select * from tb_student1 union select * from tb_student2;
# +----+--------+------+--------+---------+
# | id | name   | age  | gender | subject |
# +----+--------+------+--------+---------+
# |  1 | 悟空   |  255 | 男     | ui      |
# |  2 | 唐僧   |   30 | 男     | yunwei  |
# +----+--------+------+--------+---------+
# 2 rows in set (0.01 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3、交叉查询（了解）&lt;/h3&gt;
&lt;p&gt;基本语法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 */字段列表 from【弗乱】 数据表1,数据表2;
或
mysql &amp;gt; select【涩莱克特】 */字段列表 form【佛乱】 数据表1 cross【克洛斯】 join【载(白话)】 数据表2;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;tb_category【tb_凯特厄戈瑞】&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; create【克瑞特】 table【忒-部】 tb_category【tb_凯特厄戈瑞】(
    id smallint【斯莫尔因特】 not【nuō 特】 null【nò】 auto_increment【奥特欧_因克瑞门特】,
    name varchar【瓦儿-查儿】(20),
    pid smallint【斯莫尔因特】 default【迪-佛特】 0,
    primary【普赖莫瑞】 key【发音&apos;ki&apos;】(id)
) engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;
# mysql&amp;gt; create table tb_category(
# -&amp;gt; id smallint not null auto_increment,
# -&amp;gt; name varchar(20),
# -&amp;gt; pid smallint default 0,
# -&amp;gt; primary key(id)
# -&amp;gt; )engine=innodb default charset=utf8;
# Query OK, 0 rows affected (0.39 sec)
# 
insert【因涩特】 into【因兔】 tb_category【tb_凯特厄戈瑞】 values【挖柳斯】 (null【nò】,&apos;手机&apos;,0);
insert【因涩特】 into【因兔】 tb_category【tb_凯特厄戈瑞】 values【挖柳斯】 (null【nò】,&apos;电脑&apos;,0);
insert【因涩特】 into【因兔】 tb_category【tb_凯特厄戈瑞】 values【挖柳斯】 (null【nò】,&apos;游戏手机&apos;,1); =&amp;gt;首席手机属于手机分类
# mysql&amp;gt; insert into tb_category values (null,&apos;手机&apos;,0);
# Query OK, 1 row affected (0.05 sec)
# 
# mysql&amp;gt; insert into tb_category values (null,&apos;电脑&apos;,0);
# Query OK, 1 row affected (0.06 sec)
# 
# mysql&amp;gt; insert into tb_category values (null,&apos;游戏手机&apos;,1);
# Query OK, 1 row affected (0.05 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;pid代表所属的父级类别，如果自己就是顶级分类，则为0&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;tb_goods【故兹】&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】 table【忒-部】 tb_goods【故兹】(
    id int【因特】 not【nuō 特】 null【nò】 auto_increment【奥特欧_因克瑞门特】,
    title【泰头】 varchar【瓦儿-查儿】(80),
    price【普莱斯】 decimal【戴希莫】(11,2),
    cid smallint【斯莫尔因特】 default【迪-佛特】 0,
    primary【普赖莫瑞】 key【发音&apos;ki&apos;】(id)
) engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;
# mysql&amp;gt; create table tb_goods(
# -&amp;gt; id int not null auto_increment,
# -&amp;gt; title varchar(80),
# -&amp;gt; price decimal(11,2),
# -&amp;gt; cid smallint default 0,
# -&amp;gt; primary key(id)
# -&amp;gt; )engine=innodb default charset=utf8;
# Query OK, 0 rows affected (0.34 sec)
# 
insert【因涩特】 into【因兔】 tb_goods【故兹】 values【挖柳斯】 (null【nò】,&apos;IPhone 11&apos;,5699.00,1);
insert【因涩特】 into【因兔】 tb_goods【故兹】 values【挖柳斯】 (null【nò】,&apos;MI 10&apos;,4699.00,1);
insert【因涩特】 into【因兔】 tb_goods【故兹】 values【挖柳斯】 (null【nò】,&apos;ThinkPad X1&apos;,9999.00,2);
insert【因涩特】 into【因兔】 tb_goods【故兹】 values【挖柳斯】 (null【nò】,&apos;Nike gt&apos;,999.00,10);
# mysql&amp;gt; insert into tb_goods values (null,&apos;IPhone&apos;,5699.00,1),(null,&apos;MI 10&apos;,4699.00,1),(null,&apos;ThinkPad X1&apos;,9999.00,2),(null,&apos;Nike gt&apos;,999.00,10);
# Query OK, 4 rows affected (0.05 sec)
# Records: 4  Duplicates: 0  Warnings: 0
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;cid代表产品的所属分类编号，与tb_category【tb_凯特厄戈瑞】要一一对应&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;案例：把分类表与产品进行交叉，就结果&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt;select【涩莱克特】 * from【弗乱】 tb_category【tb_凯特厄戈瑞】 cross【克洛斯】 join【载(白话)】 tb_goods【故兹】;
# mysql&amp;gt; select * from tb_category cross join tb_goods;
# +----+--------------+------+----+-------------+---------+------+
# | id | name         | pid  | id | title       | price   | cid  |
# +----+--------------+------+----+-------------+---------+------+
# |  1 | 手机         |    0 |  1 | IPhone      | 5699.00 |    1 |
# |  2 | 电脑         |    0 |  1 | IPhone      | 5699.00 |    1 |
# |  3 | 游戏手机     |    1 |  1 | IPhone      | 5699.00 |    1 |
# |  1 | 手机         |    0 |  2 | MI 10       | 4699.00 |    1 |
# |  2 | 电脑         |    0 |  2 | MI 10       | 4699.00 |    1 |
# |  3 | 游戏手机     |    1 |  2 | MI 10       | 4699.00 |    1 |
# |  1 | 手机         |    0 |  3 | ThinkPad X1 | 9999.00 |    2 |
# |  2 | 电脑         |    0 |  3 | ThinkPad X1 | 9999.00 |    2 |
# |  3 | 游戏手机     |    1 |  3 | ThinkPad X1 | 9999.00 |    2 |
# |  1 | 手机         |    0 |  4 | Nike gt     |  999.00 |   10 |
# |  2 | 电脑         |    0 |  4 | Nike gt     |  999.00 |   10 |
# |  3 | 游戏手机     |    1 |  4 | Nike gt     |  999.00 |   10 |
# +----+--------------+------+----+-------------+---------+------+
# 12 rows in set (0.00 sec) 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112154350.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;交叉连接本身是没有意义的，其只是强制把两个表甚至多个表进行连接在一起。但是交叉查询中也有正确的结果，所以我们所谓的多表连接只需要在交叉连接的基础上增加一个连接条件，则就是我们想要的结果了。所以交叉查询是多表查询的基础&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;4、内连接查询&lt;/h3&gt;
&lt;p&gt;基本语法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 数据表1.字段列表，数据表2.字段列表 from【弗乱】 数据表1 inner【ing呐】 join【载(白话)】 数据表2 on【昂】 连接条件；
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：获取产品表中每个产品的分类信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 tb_goods【故兹】.*,tb_category【tb_凯特厄戈瑞】.name from【弗乱】 tb_goods【故兹】 inner【ing呐】 join【载(白话)】 tb_category【tb_凯特厄戈瑞】 on【昂】 tb_goods【故兹】.cid=tb_category【tb_凯特厄戈瑞】.id;
# mysql&amp;gt; select tb_goods.*,tb_category.name from tb_goods inner join tb_category on tb_goods.cid=tb_category.id;
# +----+-------------+---------+------+--------+
# | id | title       | price   | cid  | name   |
# +----+-------------+---------+------+--------+
# |  1 | IPhone      | 5699.00 |    1 | 手机   |
# |  2 | MI 10       | 4699.00 |    1 | 手机   |
# |  3 | ThinkPad X1 | 9999.00 |    2 | 电脑   |
# +----+-------------+---------+------+--------+
# 3 rows in set (0.03 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;内连接查询：把两个表甚至多个表进行连接，然后拿表1 中的每一条记录与表2中的每一条记录进行匹配，如果有与之对应的结果，则显示。反之，则忽略这条记录&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;5、外连接查询&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;内连接查询要求：表1和表2中的每一条记录都必须要一一对应，如果无法匹配，则这条记录会被自动忽略掉，那如果我需要保留表1中的所有记录或表2 中的所有记录怎么办呢？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;答：可以使用外连接查询&lt;/p&gt;
&lt;p&gt;基本语法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;左连接查询：把左表中的每一条数据都保留，右表匹配到结果就显示，匹配不到就null【nò】&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】 数据表1.字段列表,数据表2.字段列表 from【弗乱】 数据表1 left【列夫特】 数据表2 on【昂】 连接条件；
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;右连接查询：把右表中的每一条数据都保留，左表匹配到结果就显示，匹配不到就null【nò】&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;select【涩莱克特】 数据表1.字段列表,数据表2.字段列表 from【弗乱】 数据表1 right【来特】 join【载(白话)】 数据表2 on【昂】 连接条件；
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：获取产品表中每个产品的分类信息（无论匹配到与否）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 tb_goods【故兹】.*,tb_category【tb_凯特厄戈瑞】.name from【弗乱】 tb_goods【故兹】 left【列夫特】 join【载(白话)】 tb_category【tb_凯特厄戈瑞】 on【昂】 tb_goods【故兹】.cid=tb_category【tb_凯特厄戈瑞】.id;
# mysql&amp;gt; select  tb_goods.*,tb_category.name from tb_goods left join tb_category on tb_goods.cid=tb_category.id;
# +----+-------------+---------+------+--------+
# | id | title       | price   | cid  | name   |
# +----+-------------+---------+------+--------+
# |  1 | IPhone      | 5699.00 |    1 | 手机   |
# |  2 | MI 10       | 4699.00 |    1 | 手机   |
# |  3 | ThinkPad X1 | 9999.00 |    2 | 电脑   |
# |  4 | Nike gt     |  999.00 |   10 | NULL   |
# +----+-------------+---------+------+--------+
# 4 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6、别名机制：简化内外连接&lt;/h3&gt;
&lt;p&gt;案例：获取产品表中每个产品的分类信息（无论匹配到与否）
原始语句：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 tb_goods【故兹】.*,tb_category【tb_凯特厄戈瑞】.name from【弗乱】 tb_goods【故兹】 left【列夫特】 join【载(白话)】 tb_category【tb_凯特厄戈瑞】 on【昂】 tb_goods【故兹】.cid=tb_category【tb_凯特厄戈瑞】.id;
# mysql&amp;gt; select tb_goods.*,tb_category.name from tb_goods left join tb_category on tb_goods.cid=tb_category.id;
# +----+-------------+---------+------+--------+
# | id | title       | price   | cid  | name   |
# +----+-------------+---------+------+--------+
# |  1 | IPhone      | 5699.00 |    1 | 手机   |
# |  2 | MI 10       | 4699.00 |    1 | 手机   |
# |  3 | ThinkPad X1 | 9999.00 |    2 | 电脑   |
# |  4 | Nike gt     |  999.00 |   10 | NULL   |
# +----+-------------+---------+------+--------+
# 4 rows in set (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;给数据表起个简单的名字，如tb_category【tb_凯特厄戈瑞】叫c，tb_goods【故兹】叫做g&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;原句
①mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_goods【故兹】 left【列夫特】 join【载(白话)】 tb_category【tb_凯特厄戈瑞】;

起别名
②mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_goods【故兹】 g left【列夫特】 join【载(白话)】 tb_category【tb_凯特厄戈瑞】 c;

写on条件
③mysql &amp;gt; select【涩莱克特】 * from【弗乱】 tb_goods【故兹】 g left【列夫特】 join【载(白话)】 tb_category【tb_凯特厄戈瑞】 c on【昂】 g.cid=c.id;

筛选字段
④mysql &amp;gt; select【涩莱克特】 g.*,c.name from【弗乱】 tb_goods【故兹】 g left【列夫特】 join【载(白话)】 tb_category【tb_凯特厄戈瑞】 c on【昂】 g.cid=c.id;
# mysql&amp;gt; select g.*,c.name from tb_goods g left join tb_category c on g.cid=c.id;
# +----+-------------+---------+------+--------+
# | id | title       | price   | cid  | name   |
# +----+-------------+---------+------+--------+
# |  1 | IPhone      | 5699.00 |    1 | 手机   |
# |  2 | MI 10       | 4699.00 |    1 | 手机   |
# |  3 | ThinkPad X1 | 9999.00 |    2 | 电脑   |
# |  4 | Nike gt     |  999.00 |   10 | NULL   |
# +----+-------------+---------+------+--------+
# 4 rows in set (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;day04-MySQL备份与恢复一&lt;/h1&gt;
&lt;h2&gt;一、用户管理与权限管理&lt;/h2&gt;
&lt;h3&gt;⭐用户管理&lt;/h3&gt;
&lt;h4&gt;1、创建MySQL用户&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;注意：MySQL中不能单纯通过用户名来创建用户，必须要加上主机。如 jack@192.168.1.1&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;#创建用户
mysql &amp;gt; create【克瑞特】 user &apos;用户名&apos;@&apos;被允许连接的主机名称或主机的IP地址&apos; identified【爱-丹-提伐】 by【拜】 &apos;用户密码&apos;;

#查询MySQL服务器中所有用户及其允许连接的主机。
mysql &amp;gt; select【涩莱克特】 user,host from【弗乱】 mysql.user;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：创建一个MySQL账号，用户名：tom，用户密码：123&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; create【克瑞特】 user &apos;tom&apos;@&apos;localhotst&apos; identified【爱-丹-提伐】 by【拜】 &apos;123&apos;;
# mysql&amp;gt; create user &apos;tom&apos;@&apos;localhost&apos; identified by &apos;123&apos;;
# Query OK, 0 rows affected (0.15 sec)
#
或
mysql &amp;gt; create【克瑞特】 user &apos;tom&apos;@&apos;127.0.0.1&apos; identified【爱-丹-提伐】 by【拜】 &apos;123&apos;;
# mysql&amp;gt; create user &apos;tom&apos;@&apos;127.0.0.1&apos; identified by &apos;123&apos;;
# Query OK, 0 rows affected (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：创建一个MySQL账号（要求开通远程连接），主机IP地址：192.168.20.110，用户名：harry，密码：1234&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; create【克瑞特】 user &apos;harry&apos;@&apos;192.168.20.110&apos; identified【爱-丹-提伐】 by【拜】 &apos;123&apos;;

# mysql&amp;gt; create user &apos;harry&apos;@&apos;192.168.20.110&apos; identified by &apos;1234&apos;;
# Query OK, 0 rows affected (0.00 sec)
#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;测试：在IP地址为192.168.20.110的主机上&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# yum install【因-斯多​】 mysql -y
# mysql -h 192.168.20.111 -P 3306 -uharry -p
Enter password【帕斯沃德】:123
选项说明：
192.168.20.111:MySQL服务器端的IP地址
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;yum安装Mysql：代表安装的是MySQL的客户端
YUM安装mysql-server【涩·沃】：代表安装的是MySQL服务器端&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;案例：创建一个MySQL账号（要求开通远程连接），主机IP的网段：192.168.20.0，用户名：jack ，用户密码：1234&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; create【克瑞特】 user &apos;jack&apos;@&apos;192.168.20.%&apos; identified【爱-丹-提伐】 by【拜】 &apos;1234&apos;;
# mysql&amp;gt; create user &apos;jack&apos;@&apos;192.168.20.%&apos; identified by &apos;1234&apos;;
# Query OK, 0 rows affected (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：创建一个MySQL账号（要求开通远程连接），要求面向所有主机开放，用户名：root，用户密码：1234&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; create【克瑞特】 user &apos;root&apos;@&apos;%&apos; identified【爱-丹-提伐】 by【拜】 &apos;1234&apos;;
# mysql&amp;gt; create user &apos;root&apos;@&apos;%&apos; identified by &apos;1234&apos;;
# Query OK, 0 rows affected (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2、删除用户&lt;/h4&gt;
&lt;p&gt;基本语法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; drop【卓-普】 user &apos;用户名&apos;@&apos;主机名称或主机的IP地址&apos;;
特别说明：
如果在删除用户时没有指定主机的名称或主机的IP地址，则默认删除这个账号的所有信
息。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：删除tom这个账号&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; drop【卓-普】 user &apos;tom&apos;@&apos;localhost&apos;；
# mysql&amp;gt; drop user &apos;tom&apos;@&apos;127.0.0.1&apos;;
# Query OK, 0 rows affected (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：删除jack这个账号&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; drop【卓-普】 user &apos;jacl&apos;@&apos;192.168.20.%&apos;;
# mysql&amp;gt; drop user &apos;jack&apos;@&apos;192.168.20.%&apos;;
# Query OK, 0 rows affected (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：创建两个harry账号（localhost/192.168.20.110）,然后删除其中的某个&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; create【克瑞特】 user &apos;harry&apos;@&apos;192.168.20.110&apos; identified【爱-丹-提伐】 by【拜】 &apos;1234&apos;;
mysql &amp;gt; create【克瑞特】 user &apos;harry&apos;@&apos;localhost&apos; identified【爱-丹-提伐】 by【拜】 &apos;1234&apos;;
mysql &amp;gt; drop【卓-普】 user &apos;harry&apos;@&apos;192.168.20.110&apos;;
# mysql&amp;gt; create user &apos;harry&apos;@&apos;localhost&apos; identified by &apos;123&apos;;
# Query OK, 0 rows affected (0.00 sec)
# 
# mysql&amp;gt; create user &apos;harry&apos;@&apos;192.168.20.110&apos; identified by &apos;123&apos;;
# Query OK, 0 rows affected (0.00 sec)
# 
# mysql&amp;gt; drop user &apos;harry&apos;@&apos;192.168.20.110&apos;;
# Query OK, 0 rows affected (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;扩展：删除MySQL账号的另外一种方式&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; delete【迪  利 特】from【弗乱】 mysql.user where【威尔】  user=&apos;root&apos; and host =&apos;%&apos;;
mysql &amp;gt; flush【福 辣 徐】 privileges【P符类 杰 斯】;
# mysql&amp;gt; delete from mysql.user where user=&apos;harry&apos; and host=&apos;localhost&apos;;
# Query OK, 1 row affected (0.00 sec)
# 
# mysql&amp;gt; flush privileges;
# Query OK, 0 rows affected (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3、修改MySQL用户&lt;/h4&gt;
&lt;p&gt;特别说明：Mysql用户重命名通常可以更改两部分，一部分是用户的名称，一部分是被允许访问的主机名称或主机的IP地址。
基本语法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; rename【瑞-内姆】 user 旧用户信息 to 新用户信息;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：把用户&apos;root&apos;@&apos;%&apos;更改为&apos;root&apos;@&apos;192.168.20.%&apos;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; create【克瑞特】 user &apos;root&apos;@&apos;%&apos; identified【爱-丹-提伐】 by【拜】 &apos;mysql1234&apos;;
mysql &amp;gt; rename【瑞-内姆】 user &apos;root&apos;@&apos;%&apos; to &apos;root&apos;@&apos;192.168.20.%&apos;;
# mysql&amp;gt; create user &apos;root&apos;@&apos;%&apos; identified by &apos;mysql1234&apos;;
# Query OK, 0 rows affected (0.00 sec)
# mysql&amp;gt; rename user &apos;root&apos;@&apos;%&apos; to &apos;root&apos;@&apos;192.168.20.%&apos;;
# Query OK, 0 rows affected (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：把&apos;tom&apos;@&apos;localhost&apos;更名为&apos;harry&apos;@&apos;localhost&apos;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; create【克瑞特】 user &apos;tom&apos;@&apos;localhost&apos; identified【爱-丹-提伐】 by【拜】 &apos;mysql1234&apos;;
mysql &amp;gt; rename【瑞-内姆】 user &apos;tom&apos;@&apos;localhotst&apos; to &apos;jack&apos;@&apos;localhost&apos;
# mysql&amp;gt; create user &apos;tom&apos;@&apos;localhost&apos;  identified by &apos;mysql1234&apos;;
# Query OK, 0 rows affected (0.00 sec)
# 
# mysql&amp;gt; rename user &apos;tom&apos;@&apos;localhost&apos; to &apos;jack&apos;@&apos;localhost&apos;;
# Query OK, 0 rows affected (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;扩展：使用update【阿普 dei 特】语句更新用户信息&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; update【阿普 dei 特】 mysql.user set【赛特】 user=&apos;tom&apos;,host=&apos;localhost&apos; where【威尔】  user=&apos;jack&apos; and host=&apos;localhost&apos;;
mysql &amp;gt; flush【福 辣 徐】 privileges【P符类 杰 斯】;
# mysql&amp;gt; update mysql.user set user=&apos;tom&apos;,host=&apos;localhost&apos; where user=&apos;jack&apos; and host=&apos;localhost&apos;;
# Query OK, 1 row affected (0.00 sec)
# Rows matched: 1  Changed: 1  Warnings: 0
# 
# mysql&amp;gt; flush privileges;
# Query OK, 0 rows affected (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;⭐权限管理&lt;/h3&gt;
&lt;h4&gt;1、权限说明&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://dev.mysql.com/doc/refman/5.7/en/privileges-provided.html&quot;&gt;所有权限说明&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;USAGE 无权限,只有登录数据库,只可以使用test【泰斯特】或test_*数据库
ALL【哦】 所有权限
以下权限为指定权限
select【涩莱克特】/update【阿普 dei 特】/delete【迪利特】/super/replication【瑞普利K申】 slave【斯累夫】/reload【率漏德】...
with【威付】 grant【古亮普】 option【阿普申】 选项表示允许把自己的权限授予其它用户或者从其他用户收回自己的
权限
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;默认情况下，分配权限时如果没有指定with【威付】 grant【古亮普】 option【阿普申】，代表这个用户不能下发权限给其他用户，但是这个权限分配不能超过自身权限&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;2、权限保存位置（了解）&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql.user             所有mysql用户的账号和密码，以及用户对全库全表权限（*.*）
mysql.db               非mysql库的授权都保存在此(db.*)
mysql.table【忒-部】_priv       某库某表的授权(db.table【忒-部】)
mysql.columns_priv     某库某表某列的授权(db.table【忒-部】.col1)
mysql.procs_priv       某库存储过程的授权
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3、给用户授权&lt;/h4&gt;
&lt;p&gt;基本语法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; grant【古亮普】 权限1，权限2 on【昂】 库.表 to 用户@主机
mysql &amp;gt; grant【古亮普】 权限（列1,列2,...） on【昂】 库.表 to 用户@主机
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;库.表表示方法：.代表所有数据库的所有数据表，db_fq.*代表db_fq数据库中的所有数据表，db_fq.tb_admin，代表db_fq数据库中的tb_admin表&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;案例：给tom账号分配db_fq的查询权限&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; grant【古亮普】 select【涩莱克特】 on【昂】 db_fq.* to &apos;tom&apos;@&apos;localhost&apos;;
mysql &amp;gt; flush【福 辣 徐】 privileges【P符类 杰 斯】;mysql&amp;gt; grant select on db_fq.* to &apos;tom&apos;@&apos;localhost&apos;;
# mysql&amp;gt; grant select on db_fq.* to &apos;tom&apos;@&apos;localhost&apos;;
# Query OK, 0 rows affected (0.15 sec)
# 
# mysql&amp;gt; flush privileges;
# Query OK, 0 rows affected (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：给tom账号分配db_fq.tb_student【tb_斯丢等特】数据表的权限（要求只能更改age【诶吉】字段）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; grant【古亮普】 update【阿普 dei 特】(age【诶吉】) on【昂】 db_fq.tb_student【tb_斯丢等特】 to &apos;tom&apos;@&apos;localhost&apos;;
mysql &amp;gt; flush【福 辣 徐】 privileges【P符类 杰 斯】;
# mysql&amp;gt; grant update(age) on db_fq.tb_student to &apos;tom&apos;@&apos;localhost&apos;;
# Query OK, 0 rows affected (0.10 sec)
# 
# mysql&amp;gt; flush privileges;
# Query OK, 0 rows affected (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：添加一个root@%账号，然后分配所有权限&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; create【克瑞特】 user &apos;root&apos;@&apos;%&apos; identified【爱-丹-提伐】 by【拜】 &apos;mysql1234&apos;;
mysql &amp;gt; grant【古亮普】 all【哦】 on【昂】 *.* to &apos;root&apos;@&apos;%&apos;;
mysql &amp;gt; flush【福 辣 徐】 privileges【P符类 杰 斯】;
# mysql&amp;gt; create user &apos;root&apos;@&apos;%&apos; identified by &apos;mysql1234&apos;;
# Query OK, 0 rows affected (0.00 sec)
# mysql&amp;gt; grant all on *.* to &apos;root&apos;@&apos;%&apos;;
# Query OK, 0 rows affected (0.00 sec)
# 
# mysql&amp;gt; flush privileges;
# Query OK, 0 rows affected (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4、查询用户权限&lt;/h4&gt;
&lt;p&gt;查询当前用户权限&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; show【瘦】 grants【哥亮特s】;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查询其他用户权限&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; show【瘦】 grants【哥亮特s】 for【fò】 &apos;用户名称&apos;@&apos;授权的主机名称或IP地址&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;5、with【威付】 grant【古亮普】 option【阿普申】选项&lt;/h4&gt;
&lt;p&gt;with【威付】 grant【古亮普】 option【阿普申】选项作用：代表此账号可以为其他用户下发权限，但是下发权限不能超过自身权限&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; grant【古亮普】 all【哦】 on【昂】 *.* to &apos;amy&apos;@&apos;10.1.1.%&apos; identified【爱-丹-提伐】 by【拜】 &apos;123&apos; with【威付】 grant【古亮普】 option【阿普申】;
mysql&amp;gt; grant【古亮普】 all【哦】 on【昂】 *.* to &apos;harry&apos;@&apos;10.1.1.%&apos; identified【爱-丹-提伐】 by【拜】 &apos;123&apos;;
如以上命令显示：
amy拥有下发权限的功能,而harry不具备下发权限的功能
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;如果grant【古亮普】授权时，没有with【威付】 grant【古亮普】 option【阿普申】选项，则其无法为其他用户授权&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;6、使用grant【古亮普】创建用户&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;说明：5.7以后不推荐，未来会被弃用
基本语法：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;mysql grant【古亮普】 权限 on【昂】 数据库.数据表 to &apos;新用户名称&apos;@&apos;授权主机名称或IP地址&apos; identified【爱-丹-提伐】 by【拜】 &apos;用户的密码&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：创建一个root账号,主机为%,授予所有权限，密码为mysql1234&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; grant【古亮普】 all【哦】 on【昂】 *.* to &apos;root&apos;@&apos;%&apos; identified【爱-丹-提伐】 by【拜】 &apos;mysql1234&apos;;
# mysql&amp;gt; grant all on *.* to &apos;root&apos;@&apos;%&apos; identified by &apos;mysql1234&apos;;
# Query OK, 0 rows affected, 1 warning (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;7、revoke【瑞 - 沃克】回收权限&lt;/h4&gt;
&lt;p&gt;基本语法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;revoke【瑞 - 沃克】 权限 on【昂】 库.表 from【弗乱】 用户;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;案例：从tom张中回收select【涩莱克特】权限&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;撤消指定的权限
mysql&amp;gt; revoke【瑞 - 沃克】 update【阿普 dei 特】 on【昂】 db01.tt1 from【弗乱】 &apos;tom&apos;@&apos;10.1.1.1&apos;;
# mysql&amp;gt; revoke update on db01.tt1 from &apos;tom&apos;@&apos;10.1.1.1&apos;;
撤消所有的权限
mysql&amp;gt; revoke【瑞 - 沃克】 select【涩莱克特】 on【昂】 db01.* from【弗乱】 &apos;tom&apos;@&apos;10.1.1.1&apos;;
# mysql&amp;gt; revoke select on db01.* from &apos;tom&apos;@&apos;10.1.1.1&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;二、MySQL备份的任务背景&lt;/h2&gt;
&lt;h3&gt;1、任务需求&lt;/h3&gt;
&lt;p&gt;某天，公司领导安排刚入职不久的小冯同学将生产环境中的数据(MySQL数据库)全部导入到测试环境给测试人员使用。当小冯去拿备份数据时发现，备份数据是1个礼拜之前的。原因是之前运维同事通过脚本每天对数据库进行备份，根据结果判断应该是脚本的问题导致备份失败。于是乎，领导让小冯重新制定备份策略对数据库进行备份，并且把数据导入到测试环境。&lt;/p&gt;
&lt;h3&gt;2、核心技术&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;①掌握MySQL的备份工具使用及各自特点&lt;/li&gt;
&lt;li&gt;②熟悉SHELL脚本&lt;/li&gt;
&lt;li&gt;③熟悉MySQL数据的导入到出&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3、任务步骤&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;①选择合适的工具和方法对mysql数据库进行备份&lt;/li&gt;
&lt;li&gt;②编写脚本实现自动化备份&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4、任务目标：&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;了解MySQL常见的备份方式和类型&lt;/li&gt;
&lt;li&gt;能够使用mysqldump【mysql-当普】工具进行数据库的备份。如全库备份，库级别备份，表级别备份&lt;/li&gt;
&lt;li&gt;能够使用mysqldump【mysql-当普】工具+binlog【宾-劳格】日志实现增量备份&lt;/li&gt;
&lt;li&gt;理解xtrabackup【xtra-拜克阿普】工具实现增量备份的原理和方法&lt;/li&gt;
&lt;li&gt;能够使用xtrabackup【xtra-拜克阿普】工具对数据库进行全备和增备&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;三、MySQL备份概述&lt;/h2&gt;
&lt;h3&gt;1、关于数据保存你要知道&lt;/h3&gt;
&lt;h4&gt;备份和冗余有什么区别？&lt;/h4&gt;
&lt;h5&gt;备份&lt;/h5&gt;
&lt;blockquote&gt;
&lt;p&gt;能够防止由于机械故障以及人为误操作带来的数据丢失，例如将数据库文件保存在了其它地方。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h5&gt;冗余&lt;/h5&gt;
&lt;blockquote&gt;
&lt;p&gt;数据有多份冗余，但不等备份，只能防止机械故障带来的数据丢失，例如主备模式、数据库集群。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;2、到底要备份什么&lt;/h3&gt;
&lt;h4&gt;⭐备份什么&lt;/h4&gt;
&lt;p&gt;数据库：一堆物理文件的集合：日志文件+数据文件+配置文件&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;①数据文件&lt;/li&gt;
&lt;li&gt;②配置文件 =&amp;gt; my.cnf&lt;/li&gt;
&lt;li&gt;③日志文件（主要是二进制日志文件）&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;⭐MySQL体系结构&lt;/h4&gt;
&lt;p&gt;扩展：MySQL体系结构（MySQL =&amp;gt; DBMS软件到底是由哪些层构成的）
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112207323.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;⭐存储引擎层（MyLSAM与innodb【伊诺 DB】引擎）&lt;/h4&gt;
&lt;p&gt;存储引擎层：简单来所，就是数据的存储方式。在MySQL中，我们可以使用show【瘦】 engines【 嗯(ing) 京(白话读音)s 】查看当前数据库版本支持哪些引擎，常见的数据库引擎：innodb【伊诺 DB】、MyISAM【迈-艾塞姆】、NDB、、、&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;常见面试题：请简述MySQL的MyISAM【迈-艾塞姆】引擎与innodb【伊诺 DB】引擎的区别&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;①MyISAM【迈-艾塞姆】引擎：擅长数据的查询，支持全文索引
②innodb【伊诺 DB】引擎：支持事务处理、行级锁、支持外键
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;⭐存储层（数据文件是如何进行存储的）&lt;/h4&gt;
&lt;p&gt;问题：存储引擎到底是如何保存数据文件的？&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; create【克瑞特】 database【得塔-贝斯】  db_fq default【迪-佛特】 charset【查赛特】=utf8;
#mysql &amp;gt; create database db_fq default charset =utf8;

&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;问题：能不能不进入MySQL终端，然后在命令行中直接创建一个数据库呢？ -e
当数据库创建完毕后，查看/mysql_3306/data文件夹：
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112248868.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在db_fq文件夹中还有一个文件db.opt，存放内容为数据库的编码格式。&lt;/p&gt;
&lt;h5&gt;MyISAM【迈-艾塞姆】引擎&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; use db_fq;
mysql &amp;gt; create【克瑞特】 table【忒-部】 tb_user(id int, name char【查尔】(1)) engine【 嗯(ing) 京(白话读音) 】=myisam【迈-艾塞姆】 default【迪-佛特】 charset【查赛特】=utf8;
# mysql&amp;gt; create table tb_user(id int, name char(1)) engine=myisam default charset=utf8;
# Query OK, 0 rows affected (0.07 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112300434.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;创建完成后，查看db_fq目录信息，发现产生了3个文件&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;*.frm：框架文件，定义数据表结构 *.MYI：INDEX索引，主要用于存放索引文件 *.MYD：数据文件&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h5&gt;innodb【伊诺 DB】引擎&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; use db_fq;
mysql &amp;gt; create【克瑞特】 table【忒-部】 tb_user(id int, name char【查尔】(1)) engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;
# mysql&amp;gt; create table tb_user(id int, name char(1)) engine=innodb default charset=utf8;
# Query OK, 0 rows affected (0.49 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建完成后，查看db_fq目录信息，发现产生了2个文件
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112314185.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;*.frm：框架文件，定义数据表结构 *.ibd：索引文件+数据文件&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;其实innodb【伊诺 DB】引擎不仅仅会产生两个文件，其在外部data目录下也会产生一个文件
（确切来说不能叫做产生文件，而应该叫做共享文件）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112327969.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;所以由此可知，innodb【伊诺 DB】引擎的数据备份不能简单的通过拷贝方式实现，必须使用专业的备份工具。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;⭐日志文件（MySQL中我们需要了解哪些日志）&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;日志类型&lt;/th&gt;
&lt;th&gt;写入日志的信息&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;error【诶 若】错误日志&lt;/td&gt;
&lt;td&gt;存放数据库的启动、停止或运行时的错误信息（找ERROR【诶 若】）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;binlog【宾-劳格】二进制日志&lt;/td&gt;
&lt;td&gt;数据库的所有更改操作（DDL/DML/DCL），不包含select【涩莱克特】或者show【瘦】这类语句&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;error【诶 若】错误日志的命令规则与存放的目录：/data目录下+主机名称.err&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;更改错误日志的存放位置：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vim my.cnf
[mysqld]
...
log_error【劳格-诶 若】=data数据目录/主机名称.err或mysql.err
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;binlog【宾-劳格】二进制日志应用场景：
用户主从复制，master【马斯特】主服务器将二进制日志中的更改操作发送给slave【斯累夫】从服务器，从服务器执行这些更改操作 目的和主服务器的更改相同用于数据的恢复操作&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;binlog【宾-劳格】二进制日志如何开启？
默认binlog【宾-劳格】日志是关闭的，可以通过修改配置文件完成开启，如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vim my.cnf
[mysqld]
...
server【涩·沃】-id=1
log_bin=data数据目录/binlog【宾-劳格】
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;当我们更改了my.cnf配置文件，一定要记得重启MySQL服务器。service【瑟为斯】命令&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# service mysql_3306 restart【 率 s 达r】 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3、备份过程考虑的因素&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;必须制定详细的备份计划(策略)（备份频率、时间点、周期）&lt;/li&gt;
&lt;li&gt;备份数据应该放在非数据库本地，并建议有多份副本&lt;/li&gt;
&lt;li&gt;必须做好数据恢复的演练（每隔一段时间，对备份的数据在测试环境中进行模拟恢复，保证当出现数据灾难的时候能够及时恢复数据。）&lt;/li&gt;
&lt;li&gt;根据数据应用的场合、特点选择正确的备份工具。&lt;/li&gt;
&lt;li&gt;数据的一致性&lt;/li&gt;
&lt;li&gt;服务的可用性&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4、备份的类型&lt;/h3&gt;
&lt;h4&gt;⭐逻辑备份&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;备份的是建表、建库、插入等操作所执行SQL语句（DDL DML DCL）。&lt;/li&gt;
&lt;li&gt;适用于中小型数据库，效率相对较低。 一般在数据库正常提供服务的前提下进行，如：mysqldump【mysql-当普】、mydumper【my-邓破儿~】、into【因兔】 outfile【奥特-伐尔】（表的导出导入）等。&lt;/li&gt;
&lt;li&gt;备份的本质：就是把备份的数据导出成.sql文件或.txt文件&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;⭐物理备份&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;直接复制数据库文件&lt;/li&gt;
&lt;li&gt;适用于大型数据库环境，不受存储引擎的限制，但不能恢复到不同的MySQL版本。&lt;/li&gt;
&lt;li&gt;一般是在数据库彻底关闭或者不能完成正常提供服务的前提下进行的备份）；如：tar、cp、xtrabackup【xtra-拜克阿普】（数据库可以正常提供服务）、lvm snapshot【斯奈普肖特】、rsync【啊 xing(4声)可】等&lt;/li&gt;
&lt;li&gt;备份的实质：对数据文件+配置文件+日志文件进行拷贝操作&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;⭐在线热备&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;MySQL的replication【瑞普利K申】架构，如M-S|M-S-S|M-M-S等&lt;/li&gt;
&lt;li&gt;实时在线备份&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5、备份工具&lt;/h3&gt;
&lt;h4&gt;㈠ 社区版安装包中的备份工具&lt;/h4&gt;
&lt;h5&gt;① mysqldump【mysql-当普】(逻辑备份，只能全量备份）&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;1）企业版和社区版都包含&lt;/li&gt;
&lt;li&gt;2）本质上使用SQL语句描述数据库及数据并导出&lt;/li&gt;
&lt;li&gt;3）在MYISAM【迈-艾塞姆】引擎上锁表，innodb【伊诺 DB】引擎上锁行&lt;/li&gt;
&lt;li&gt;4）数据量很大时不推荐使用&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;② mysqlhotcopy(物理备份工具）&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;1）企业版和社区版都包含&lt;/li&gt;
&lt;li&gt;2）perl写的一个脚本，本质上是使用锁表语句后再拷贝数据&lt;/li&gt;
&lt;li&gt;3）只支持MYISAM【迈-艾塞姆】数据引擎&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;㈡ 企业版安装包中的备份工具&lt;/h4&gt;
&lt;p&gt;mysqlbackup【mysql-拜克阿普】&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1）在线备份&lt;/li&gt;
&lt;li&gt;2）增量备份&lt;/li&gt;
&lt;li&gt;3）部分备份&lt;/li&gt;
&lt;li&gt;4）在某个特定时间的一致性状态的备份&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;㈢ 第三方备份工具&lt;/h4&gt;
&lt;h5&gt;① xtrabackup【xtra-拜克阿普】和innobackupex(物理备份）&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;1）xtrabackup【xtra-拜克阿普】是一个对innodb【伊诺 DB】做数据备份的工具，支持在线热备份（备份时不影响数据读写），是商业备份工具innodb【伊诺 DB】 Hotbackup的一个很好的替代品。&lt;/li&gt;
&lt;li&gt;2）xtrabackup【xtra-拜克阿普】有两个主要的工具：xtrabackup【xtra-拜克阿普】、innobackupex&lt;/li&gt;
&lt;li&gt;a、xtrabackup【xtra-拜克阿普】只能备份innodb【伊诺 DB】和XtraDB【插穴-DB】两种数据表，不能备份myisam类型的表。&lt;/li&gt;
&lt;li&gt;b、innobackupex是将xtrabackup【xtra-拜克阿普】进行封装的perl脚本，所以能同时备份处理innodb【伊诺 DB】和myisam【迈-艾塞姆】的存储引擎，但在处理myisam【迈-艾塞姆】时需要加一个读锁。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;② mydumper【my-邓破儿~】(逻辑备份，备份SQL语句）&lt;/h5&gt;
&lt;p&gt;多线程备份工具
https://launchpad.net/mydumper/mydumper-0.9.1.tar.gz 2015-11-06（最后更新时间）&lt;/p&gt;
&lt;h3&gt;6、备份方法&lt;/h3&gt;
&lt;p&gt;完全备份
增量备份&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112337735.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;四、MySQL逻辑备份&lt;/h2&gt;
&lt;h3&gt;1、mysqldump【mysql-当普】基本备份&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;本质：导出的是sql语句文件&lt;/li&gt;
&lt;li&gt;优点：无论是什么存储引擎，都可以用mysqldump【mysql-当普】备份成sql语句&lt;/li&gt;
&lt;li&gt;缺点：速度较慢，导入时可能会出现格式不兼容的突发状况，无法直接做增量备份提供三种级别的备份，表级，库级和全库级&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2、mysqldump【mysql-当普】基本语法&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#表级别备份
mysqldump【mysql-当普】 [OPTIONS]【阿普申s】 database【得塔-贝斯】 [table【忒-部】s]
#库级别备份
mysqldump【mysql-当普】 [OPTIONS]【阿普申s】 --databases【得塔-贝斯】 [OPTIONS]【阿普申s】 DB1 [DB2 DB3...]
#全库级别备份
mysqldump【mysql-当普】 [OPTIONS]【阿普申s】 --all【哦】-databases【得塔-贝斯】 [OPTIONS]【阿普申s】
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;准备一些要备份的数据：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】  db_fq default【迪-佛特】 charset【查赛特】=utf8;
mysql&amp;gt; use db_fq;
mysql&amp;gt; create【克瑞特】 table【忒-部】 tb_student【tb_斯丢等特】(
    id int【因特】 not【nuō 特】 null【nò】 auto_increment【奥特欧_因克瑞门特】,
    name varchar【瓦儿-查儿】(20),
    age【诶吉】 tinyint【泰尼因特】 unsigned【安赛因德】 default【迪-佛特】 0,
     gender【詹德尔】 enum【伊牛姆】(&apos;male&apos;,&apos;female&apos;),
    subject【萨布杰克特】 enum【伊牛姆】(&apos;ui&apos;,&apos;java&apos;,&apos;yunwei&apos;,&apos;python&apos;),
    primary【普赖莫瑞】 key【发音&apos;ki&apos;】(id)
) engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;
mysql &amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;刘备&apos;,&apos;33&apos;,&apos;male&apos;,&apos;java&apos;);
mysql &amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;关羽&apos;,&apos;32&apos;,&apos;male&apos;,&apos;yunwei&apos;);
mysql &amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;张飞&apos;,&apos;30&apos;,&apos;male&apos;,&apos;python&apos;);
mysql &amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;貂蝉&apos;,&apos;18&apos;,&apos;female&apos;,&apos;ui&apos;);
mysql &amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;大乔&apos;,&apos;18&apos;,&apos;female&apos;,&apos;ui&apos;);


# mysql&amp;gt; create database db_fq default charset=utf8;
# Query OK, 1 row affected (0.00 sec)
# 
# mysql&amp;gt; use db_fq;
# Database changed
# mysql&amp;gt; create table tb_student(
# -&amp;gt;     id int not null auto_increment,
# -&amp;gt;     name varchar(20),
# -&amp;gt;     age tinyint unsigned default 0,
# -&amp;gt;     gender enum(&apos;male&apos;,&apos;female&apos;),
# -&amp;gt;     subject enum(&apos;ui&apos;,&apos;java&apos;,&apos;yunwei&apos;,&apos;python&apos;),
# -&amp;gt;     primary key(id)
# -&amp;gt; ) engine=innodb default charset=utf8;
# Query OK, 0 rows affected (0.45 sec)
#
# mysql&amp;gt; insert into tb_student values (null,&apos;刘备&apos;,&apos;33&apos;,&apos;male&apos;,&apos;java&apos;);
# Query OK, 1 row affected (0.09 sec)
#
# mysql&amp;gt; insert into tb_student values (null,&apos;关羽&apos;,&apos;32&apos;,&apos;male&apos;,&apos;yunwei&apos;);
# Query OK, 1 row affected (0.06 sec)
#
# mysql&amp;gt; insert into tb_student values (null,&apos;张飞&apos;,&apos;30&apos;,&apos;male&apos;,&apos;python&apos;);
# Query OK, 1 row affected (0.05 sec)
#
# mysql&amp;gt; insert into tb_student values (null,&apos;貂蝉&apos;,&apos;18&apos;,&apos;female&apos;,&apos;ui&apos;);
# Query OK, 1 row affected (0.07 sec)
#
# mysql&amp;gt; insert into tb_student values (null,&apos;大乔&apos;,&apos;18&apos;,&apos;female&apos;,&apos;ui&apos;);
# Query OK, 1 row affected (0.16 sec)
#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3、mysqldump【mysql-当普】表级备份与还原&lt;/h3&gt;
&lt;h4&gt;⭐备份&lt;/h4&gt;
&lt;p&gt;案例：把db_fq数据库中的tb_student【tb_斯丢等特】数据表进行备份&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#mkdir【摸克跌儿】 /tmp/sqlbak
#mysqldump【mysql-当普】 db_fq tb_student【tb_斯丢等特】 &amp;gt; /tmp/sqlbak/tb_student【tb_斯丢等特】.sql -p
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;⭐还原&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# mysql 数据库名称 &amp;lt; .sql文件位置 -p
Enter password【帕斯沃德】:123
或
#mysql -uroot -p
Enter password【帕斯沃德】:123
mysql &amp;gt; use db_fq;
mysql &amp;gt; source .sql文件位
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4、mysqldump【mysql-当普】库级备份与还原&lt;/h3&gt;
&lt;h4&gt;⭐备份&lt;/h4&gt;
&lt;h5&gt;单库&lt;/h5&gt;
&lt;p&gt;案例：把db_fq数据库进行备份&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#mysqldump【mysql-当普】 --databases【得塔-贝斯】 db_fq &amp;gt; /tmp/sqlbak/db_fq.sql -p
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;多库&lt;/h5&gt;
&lt;p&gt;案例：把db_fq2和db30数据库进行备份&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#mysqldump【mysql-当普】 --databases【得塔-贝斯】 db_fq2 db30 &amp;gt; /root/sqlbak/db_fq2-db30.sql -p
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;⭐还原&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# mysql &amp;lt; .sql文件位置 -p
Enter password【帕斯沃德】：123
或
#  mysq -uroot -p
Enter password【帕斯沃德】：123
mysql &amp;gt; source .sql文件的位置

-- 通过 -D参数直接指定数据库，一步到位
mysql -u root -p -D your_database &amp;lt; /path/to/your_database.sql
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5、mysqldump【mysql-当普】全库级备份&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;在MySQL中，如果想使用mysqldump【mysql-当普】进行全库备份，必须开启二进制日志！！！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;开启二进制日志&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#vim my.cnf
[mysqld]
...
server【涩·沃】-id=1
log_bin=/mysql_3306/data/binlog【宾-劳格】
#service【瑟为斯】 mysql_3306 restart【 率 s 达r】
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mysqldump【mysql-当普】高级选项说明：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;常用选项&lt;/th&gt;
&lt;th&gt;描述说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;--flush【福 辣 徐】-logs,-F&lt;/td&gt;
&lt;td&gt;开始备份前刷新日志（二进制日志）binlog【宾-劳格】.000001 =&amp;gt;binlog【宾-劳格】.000002&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--flush【福 辣 徐】-privileges【P符类 杰 斯】&lt;/td&gt;
&lt;td&gt;备份包含mysql数据库时刷新授权表 =&amp;gt; 刷新用户和授权信息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--lock【拉克】-all【哦】-table【忒-部】s,-x&lt;/td&gt;
&lt;td&gt;MyISAM【迈-艾塞姆】一致性，服务可用性（针对所有库所有表）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--lock【拉克】-table【忒-部】s,-l&lt;/td&gt;
&lt;td&gt;备份前锁表（针对要备份的库）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--single【辛格欧】-transaction【穿插神】&lt;/td&gt;
&lt;td&gt;适用innodb【伊诺 DB】引擎，保证一致性，服务可用性&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--master【马斯特】-data=2&lt;/td&gt;
&lt;td&gt;表示将二进制日志位置和文件名写入到备份文件并在dump文件中注释掉这一行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--master【马斯特】-data=1&lt;/td&gt;
&lt;td&gt;表示将二进制日志位置和文件名写入到备份文件,在dump文件中不注释这一行&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;--master【马斯特】-data参数其他说明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1）恢复时会执行，默认是1&lt;/li&gt;
&lt;li&gt;2）需要RELOAD【率漏德】 privilege【P符类 杰 】并必须打开二进制文件&lt;/li&gt;
&lt;li&gt;3）这个选项会自动打开--lock-all【哦】-table【忒-部】s，关闭--lock-table【忒-部】s&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;⭐备份&lt;/h4&gt;
&lt;p&gt;前提：一定要开启二进制日志&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#mysqldump【mysql-当普】 --all【哦】--databases【得塔-贝斯】 --master【马斯特】-data --single【辛格欧】-transaction【穿插神】 &amp;gt; /tmp/sqlbak/all【哦】.sql -p
Enter password【帕斯沃德】:123

说明：
1.​​--all-databases【得塔-贝斯】​​：备份所有数据库（注意拼写）
2.​​--master【马斯特】-data​​：在备份中包含二进制日志位置信息（用于复制）
3.​​--single【辛格欧】-transaction【穿插神】​​：使用事务保证备份一致性（适合 InnoDB 表）
4.​​&amp;gt; sqlbak/all.sql​​：输出到指定文件
5.​​-p​​：提示输入密码
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;⭐还原&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;#mysql &amp;lt; all【哦】.sql -p
Enter password【帕斯沃德】:123
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;总结&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;mysqldump【mysql-当普】工具备份的是SQL语句，故备份不需要停服务&lt;/li&gt;
&lt;li&gt;使用备份文件恢复时，要保证数据库处于运行状态&lt;/li&gt;
&lt;li&gt;只能实现全库，指定库，表级别的某一时刻的备份，本身不能增量备份&lt;/li&gt;
&lt;li&gt;适用于中小型数据库&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;五、mysqldump【mysql-当普】 + binlog【宾-劳格】实现增量备份&lt;/h2&gt;
&lt;h3&gt;1、核心思路&lt;/h3&gt;
&lt;h4&gt;什么是增量备份？&lt;/h4&gt;
&lt;p&gt;答：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;①要有全量备份&lt;/li&gt;
&lt;li&gt;②继续增删改数据&lt;/li&gt;
&lt;li&gt;③再次需要备份时i，不需要进行全量备份，&lt;/li&gt;
&lt;li&gt;只需要备份binlog【宾-劳格】日志文件即可（因为binlog【宾-劳格】日志记记录了增删改操作的所有SQL语句）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2、增量备份实验步骤&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;第一步：先准备数据（前提）&lt;/li&gt;
&lt;li&gt;第二步：开启二进制，然后做全量备份（全库备份）&lt;/li&gt;
&lt;li&gt;第三步：继续对数据库进行增删改操作&lt;/li&gt;
&lt;li&gt;第四步：突然发生了硬件故障，数据库丢失了&lt;/li&gt;
&lt;li&gt;第五步：恢复全量备份导出的数据（不完整，可能只有90%）&lt;/li&gt;
&lt;li&gt;第六步：备份二进制日志，根据其信息（导入剩余的10%的数据）&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;li&gt;完成&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3、增量备份的具体实践&lt;/h3&gt;
&lt;h4&gt;第一步：准备数据&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】 database【得塔-贝斯】 db_fq default【迪-佛特】 charset【查赛特】=utf8;
mysql&amp;gt; use db_fq;
mysql&amp;gt; create【克瑞特】 table【忒-部】 tb_student【tb_斯丢等特】(
    id int【因特】 not【nuō 特】 null【nò】 auto_increment【奥特欧_因克瑞门特】,
    name varchar【瓦儿-查儿】(20),
    age【诶吉】 tinyint【泰尼因特】 unsigned【安赛因德】 default【迪-佛特】 0,
     gender【詹德尔】 enum【伊牛姆】(&apos;male&apos;,&apos;female&apos;),
    subject【萨布杰克特】 enum【伊牛姆】(&apos;ui&apos;,&apos;java&apos;,&apos;yunwei&apos;,&apos;python&apos;),
    primary【普赖莫瑞】 key【发音&apos;ki&apos;】(id)
) engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8;
mysql &amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;刘备&apos;,&apos;33&apos;,&apos;male&apos;,&apos;java&apos;);
mysql &amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;关羽&apos;,&apos;32&apos;,&apos;male&apos;,&apos;yunwei&apos;);
mysql &amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;张飞&apos;,&apos;30&apos;,&apos;male&apos;,&apos;python&apos;);
mysql &amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;貂蝉&apos;,&apos;18&apos;,&apos;female&apos;,&apos;ui&apos;);
mysql &amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;大乔&apos;,&apos;18&apos;,&apos;female&apos;,&apos;ui&apos;);


# mysql&amp;gt; create database db_fq default charset=utf8;
# mysql&amp;gt; use db_fq;
# mysql&amp;gt; create table tb_student(
# id int not null auto_increment,
# name varchar(20),
# age tinyint unsigned default 0,
# gender enum(&apos;male&apos;,&apos;female&apos;),
# subject enum(&apos;ui&apos;,&apos;java&apos;,&apos;yunwei&apos;,&apos;python&apos;),
# primary key(id)
# ) engine=innodb default charset=utf8;
# mysql &amp;gt; insert  into tb_student values (null,&apos;刘备&apos;,&apos;33&apos;,&apos;male&apos;,&apos;java&apos;);
# mysql &amp;gt; insert  into tb_student values (null,&apos;关羽&apos;,&apos;32&apos;,&apos;male&apos;,&apos;yunwei&apos;);
# mysql &amp;gt; insert  into tb_student values (null,&apos;张飞&apos;,&apos;30&apos;,&apos;male&apos;,&apos;python&apos;);
# mysql &amp;gt; insert  into tb_student values (null,&apos;貂蝉&apos;,&apos;18&apos;,&apos;female&apos;,&apos;ui&apos;);
# mysql &amp;gt; insert  into tb_student values (null,&apos;大乔&apos;,&apos;18&apos;,&apos;female&apos;,&apos;ui&apos;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第二步：开启二进制日志，重启服务，然后进行全库备份&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# vim my.cnf
[mysqld]
...
server【涩·沃】-id=1
log_bin=/mysql_3306/data/binlog【宾-劳格】

[root@mysql ~]# service【瑟为斯】 mysql_3306 restart【 率 s 达r】
[root@mysql ~]# rm -rf /tmp/sqlbak/*
[root@mysql ~]# mysqldump【mysql-当普】 --single【辛格欧】-transaction【穿插神】 --flush【福 辣 徐】-logs --master【马斯特】-data=2 --all-databases【得塔-贝斯】 &amp;gt; /tmp/sqlbak/all.sql -p

#[root@mysql ~]# mysqldump --single-transaction --flush-logs --master-data=2 --all-databases【得塔-贝斯】 &amp;gt; sqlbak/all.sql -p
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第三步：继续对数据库进行增删改操作&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; insert【因涩特】  into【因兔】 tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;小乔&apos;,16,&apos;female&apos;,&apos;ui&apos;);
mysql &amp;gt; delete【迪  利 特】from【弗乱】 tb_student【tb_斯丢等特】 where【威尔】  id = 3;
# mysql&amp;gt; insert into tb_student values (null,&apos;小乔&apos;,16,&apos;female&apos;,&apos;ui&apos;);
# Query OK, 1 row affected (0.12 sec)
# 
# mysql&amp;gt; delete from tb_student where id=3;
# Query OK, 1 row affected (0.16 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第四步：突然发生了硬件故障，数据库丢失了&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;#mysql -e &quot;drop【卓-普】 database【得塔-贝斯】 db_fq;&quot; -p
Enter password【帕斯沃德】:123
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;...故事了（删库）&lt;/p&gt;
&lt;h4&gt;第五步：动员运维工程师开始进行数据恢复，马上把最新的二进制文件进行备份&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;#cp /mysql_3306/data/binlog【宾-劳格】.000006 /tmp/sqlbak
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第六步：先进行全库恢复&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;#mysql &amp;lt; /tmp/sqlbak/all.sql -p
Enter password【帕斯沃德】:123
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第七步：通告binlog【宾-劳格】增量备份还原数据到100%&lt;/h4&gt;
&lt;p&gt;学会读二进制日志文件，必须通过专业工具&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# mysqlbinlog【mysql-宾-劳格】 /tmp/sqlbak/binlog【宾-劳格】.000006 =》重点找事故的临界点，如drop【卓-普】 database【得塔-贝斯】 确认at位置
[root@mysql ~]# mysqlbinlog【mysql-宾-劳格】 --start【s 达儿】-position【珀谁申】=4 --stop【 s 多】-position【珀谁申】=720 /tmp/sqlbak/binlog【宾-劳格】.000006 |mysql -p

# [root@mysql ~]# mysqlbinlog sqlbak/binlog.000002
# /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE【眸的】=1*/;
# /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
# DELIMITER /*!*/;
# at 4
# #250902 13:40:56 server【涩·沃】 id 1  end_log_pos 123 CRC32 0x1a85e54f  Start: binlog v 4, server【涩·沃】 v 5.7.31-log created 250902 13:40:56
# Warning: this binlog is either in use or was not closed properly.
# BINLOG &apos;
# aIO2aA8BAAAAdwAAAHsAAAABAAQANS43LjMxLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
# AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
# AU/lhRo=
# &apos;/*!*/;
# at 123
# .........
# [root@mysql ~]# mysqlbinlog --start【s 达儿】-position【珀谁申】=4 --stop【 s 多】-position【珀谁申】=783 sqlbak/binlog.000002 | mysql -p
# Enter password:
# [root@mysql ~]#

说明：
1. mysqlbinlog sqlbak/binlog.000002 命令是读取binlog日记，检索你需要恢复的操作范围
2. --start【s 达儿】-position【珀谁申】=4 是你需要恢复的起始位置
3. --stop【 s 多】-position【珀谁申】=783 是你需要恢复的结束位置
4. 起始和结束位置是binlog文件中的&apos;at 数字&apos;位置
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;day05-MySQL备份与恢复（二）&lt;/h1&gt;
&lt;h2&gt;一、逻辑备份&lt;/h2&gt;
&lt;h3&gt;1、回顾什么是逻辑备份&lt;/h3&gt;
&lt;p&gt;逻辑备份就是把数据库、数据包或者数据进行导出，导出到一个文本文件中。&lt;/p&gt;
&lt;h3&gt;2、逻辑备份工具&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;mysqldump【mysql-当普】：提供全库级、数据库级别以及表级别的数据备份&lt;/li&gt;
&lt;li&gt;mysqldump【mysql-当普】+binlog【宾-劳格】：二进制日志实现增量备份&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3、逻辑的导出与导入&lt;/h3&gt;
&lt;h4&gt;⭐导出（数据备份）&lt;/h4&gt;
&lt;p&gt;无论是什么存储引擎，以下方式本身是一种数据导出的方法，同时可以用来辅助备份，它可以对一个表的其中一列或者某几列做备份。备份的是数据记录&lt;/p&gt;
&lt;p&gt;案例：把tb_student数据表中的数据记录进行逻辑导出&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#mysql -uroot -p
Enter password【帕斯沃德】:123
mysql &amp;gt; select【涩莱克特】 * into【因兔】 outfile【奥特-伐尔】&apos;/tmp/sqlbak/tb_student【tb_斯丢等特】.txt&apos; from【弗乱】 db_fq.tb_student【tb_斯丢等特】;
ERROR 1290 (HY000): The MySQL server【涩·沃】 is running【乱宁】 with【威付】 the --secure-file-priv option【阿普申】 so it cannot execute this statement【斯忒特门特】
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;出现以上问题的主要原因在于我们没有指定MySQL逻辑导出时指定的路径&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#vim my.cnf
[mysqld]
...
secure【瑟Q儿】_file【伐尔】_priv【破略夫】=/tmp/sqlbak

[root@mysql ~]# mkdir【摸克跌儿】 /tmp/sqlbak
[root@mysql ~]# chown【吃-昂】 -R mysql:mysql /tmp/sqlbak
[root@mysql ~]#chmod【吃-默德】-R 750 /tmp/sqlbak
[root@mysql ~]# service【瑟为斯】 mysql_3306 restart【 率 s 达r】
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 * into【因兔】 outfile【奥特-伐尔】 &apos;/tmp/sqlbak/tb_student【tb_斯丢等特】.txt&apos; from【弗乱】 db_fq.tb_student【tb_斯丢等特】;
ERROR 1 (HY000): Can&apos;t create/write to file &apos;/tmp/sqlbak/tb_student.txt&apos; (Errcode: 13 - Permission denied)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;出现以上问题的主要原因在于mysql账户对/tmp/sqlbak没有写入权限&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#setfacl -m u:mysql:rwx /tmp/sqlbak
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;⭐导入（数据还原）&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;#mysql -uroot -p
Enter password【帕斯沃德】:123
mysql&amp;gt; truncate【创kí特】 tb_student【tb_斯丢等特】;
mysql&amp;gt; load【漏德】 data local infile【因-伐尔】 &apos;/tmp/sqlbak/tb_student【tb_斯丢等特】.txt&apos; into【因兔】 table【忒-部】 tb_student【tb_斯丢等特】;
或
#mysqlimport dbname /path/file -p =&amp;gt; 要求，导出的文件必须何数据表名称完全一致
例如：
#mysqlimport db_fq /tmp/sqlbak/tb_student【tb_斯丢等特】.txt -p
Enter password【帕斯沃德】:123
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;典型应用场景：可以把一些规则的文本文件导入到数据表中
案例：把/etc/passwd文件中的数据导入到password【帕斯沃德】数据表中
第一步：创建一个password【帕斯沃德】数据表，password【帕斯沃德】是mysql保留关键字，建议适用``反引号括起来&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; use db_fq;
mysql&amp;gt; create【克瑞特】 table【忒-部】 `password【帕斯沃德】` (
    `uname` varchar【瓦儿-查儿】(50) default【迪-佛特】 null【nò】,
    `pass` char【查尔】(2) default【迪-佛特】 null【nò】,
    `uid` int(11) default【迪-佛特】 null【nò】,
    `gid` int(11) default【迪-佛特】 null【nò】,
    `comment【坑门特】` varchar【瓦儿-查儿】(255) default【迪-佛特】 null【nò】,
    `home` varchar【瓦儿-查儿】(50) default【迪-佛特】 null【nò】,
    `shell` varchar【瓦儿-查儿】(50) default【迪-佛特】 null【nò】
) engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】 default【迪-佛特】 charset【查赛特】=utf8mb4;

# mysql&amp;gt; create table `password` (
# -&amp;gt;     `uname` varchar(50) default null,
# -&amp;gt;     `pass` char(2) default null,
# -&amp;gt;     `uid` int(11) default null,
# -&amp;gt;     `gid` int(11) default null,
# -&amp;gt;     `comment` varchar(255) default null,
# -&amp;gt;     `home` varchar(50) default null,
# -&amp;gt;     `shell` varchar(50) default null
# -&amp;gt; ) engine=innodb default charset=utf8mb4;
# Query OK, 0 rows affected (0.40 sec)
# 
# mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;第二步：把/etc/passwd文件拷贝到/tmp/sqlbak目录下，起名叫password【帕斯沃德】.txt&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;#cp /etc/passwd /tmp/sqlbak/password【帕斯沃德】.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;第三步：使用mysqlimport把password【帕斯沃德】.txt文件中的内容写入到数据表&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# mysqlimport db_fq --fields-terminated-by=&apos;:&apos; --lines-terminated-by=&apos;\n&apos; /tmp/sqlbak/password【帕斯沃德】.txt -p
Enter password【帕斯沃德】: 
db_fq.password【帕斯沃德】: Records: 25  Deleted: 0  Skipped: 0  Warnings: 0

选项说明
--fields-terminated-by=&apos;:&apos;，指定导出文件的分隔符为冒号：
--lines-terminated-by=&apos;\n&apos;，指定每一行的结尾使用的符号,\n代表换行符
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4、扩展：逻辑备份还原小工具&lt;/h3&gt;
&lt;p&gt;MySQL其实还支持很多管理软件（windows版）：MySQL-Front、Navicat
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112346636.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;第一步：选择MySQL连接
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112356812.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;第二步：输入MySQL连接信息
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112419503.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;第三步：功能演示=&amp;gt; 创建数据库、创建数据表、插入数据...&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;第四步：数据库的备份与还原&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;①逻辑的导出与导入
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112429750.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;②数据表的备份和还原
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112437505.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;③数据库的备份与还原
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112444624.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;二、物理备份&lt;/h2&gt;
&lt;h3&gt;1、xtrabackup【xtra-拜克阿普】备份介绍&lt;/h3&gt;
&lt;h4&gt;㈠ xtrabackup【xtra-拜克阿普】优缺点&lt;/h4&gt;
&lt;h5&gt;优点：&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;备份过程快速、可靠(因为是物理备份)；&lt;/li&gt;
&lt;li&gt;支持增量备份，更为灵活&lt;/li&gt;
&lt;li&gt;备份过程不会打断正在执行的事务；&lt;/li&gt;
&lt;li&gt;能够基于压缩等功能节约磁盘空间和流量；&lt;/li&gt;
&lt;li&gt;自动实现备份检验；&lt;/li&gt;
&lt;li&gt;还原速度快；&lt;/li&gt;
&lt;/ol&gt;
&lt;h5&gt;缺点：&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;只能对innodb【伊诺 DB】表增量备份，myisam【迈-艾塞姆】表增量备份时是全备&lt;/li&gt;
&lt;li&gt;innobackupex备份MyISAM【迈-艾塞姆】表之前要对全库进行加READ【滤德】 LOCK【拉克】，阻塞写操作，若备份是在从库上进行的话会影响主从同步，造成延迟。对innodb【伊诺 DB】表备份不会阻塞读写。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;㈡ xtrabackup【xtra-拜克阿普】备份原理&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;innobackupex首先会启动一个xtrabackup_log【埃斯-拜克阿普-劳格】后台检测的进程，实时检测mysql的redo【率度】 log的变化，一旦发现redo【率度】有新的日志写入，立刻将日志写入到日志文件xtrabackup_log【埃斯-拜克阿普-劳格】中。&lt;/li&gt;
&lt;li&gt;物理拷贝innodb【伊诺 DB】的数据文件和系统表空间文件idbdata1到对应的以默认时间戳为备份目录的地方&lt;/li&gt;
&lt;li&gt;复制结束后，执行flush【福 辣 徐】 table【忒-部】 with【威付】 read【滤德】 lock【拉克】操作进行全库锁表准备备份非innodb【伊诺 DB】文件&lt;/li&gt;
&lt;li&gt;物理复制.frm .myd .myi等非innodb【伊诺 DB】引擎文件到备份目录&lt;/li&gt;
&lt;li&gt;查看二进制日志的位置&lt;/li&gt;
&lt;li&gt;解锁表unlock【嗯 拉克】 table【忒-部】s&lt;/li&gt;
&lt;li&gt;停止xtrabackup_log【埃斯-拜克阿普-劳格】进程
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112455108.webp&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;扩展：redo【率度】 log日志&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;事务日志或称redo【率度】日志，在mysql中默认以ib_logfile0,ib_logfile1名称存在。&lt;/li&gt;
&lt;li&gt;redo【率度】 log通常是物理日志，记录的是数据页的物理修改，而不是某一行或某几行修改成怎样怎样，它用来恢复提交后的物理数据页（恢复数据页，且只能恢复到最后一次提交的位置）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;㈢ xtrabackup【xtra-拜克阿普】备份恢复原理&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112506769.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;具体文字描述如下（了解）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;在innodb【伊诺 DB】内部会维护一个redo【率度】日志文件，我们也可以叫做事务日志文件。事务日志会存储每一个innodb【伊诺 DB】表数据的记录修改。当innodb【伊诺 DB】启动时，innodb【伊诺 DB】会检查数据文件和事务日志，并执行两个步骤：它应用（前滚）已经提交的事务日志到数据文件，并将修改过但没有提交的数据进行回滚操作。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;xtrabackup【xtra-拜克阿普】在启动时会记住log sequence【西・捆斯】 number【能波】（LSN），并且复制所有的数据文件。复制过程需要一些时间，所以这期间如果数据文件有改动，那么将会使数据库处于一个不同的时间点。这时，xtrabackup【xtra-拜克阿普】会运行一个后台进程，用于监视事务日志，并从事务日志复制最新的修改。xtrabackup【xtra-拜克阿普】必须持续的做这个操作，是因为事务日志是会轮转重复的写入，并且事务日志可以被重用。所以xtrabackup【xtra-拜克阿普】自启动开始，就不停的将事务日志中每个数据文件的修改都记录下来。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;上面就是xtrabackup【xtra-拜克阿普】的备份过程。接下来是准备（prepare【普・佩尔】）过程。在这个过程中，xtrabackup【xtra-拜克阿普】使用之前复制的事务日志，对各个数据文件执行灾难恢复（就像MySQL刚启动时要做的一样）。当这个过程结束后，数据库就可以做恢复还原了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;以上的过程在xtrabackup【xtra-拜克阿普】的编译二进制程序中实现。程序innobackupex可以允许我们备份MyISAM【迈-艾塞姆】表和frm文件从而增加了便捷和功能。Innobackupex会启动xtrabackup【xtra-拜克阿普】，直到xtrabackup【xtra-拜克阿普】复制数据文件后，然后执行FLUSH【福 辣 徐】 table【忒-部】S WITH【威付】 READ【滤德】 LOCK【拉克】来阻止新的写入进来并把MyISAM【迈-艾塞姆】表数据刷到硬盘上，之后复制MyISAM【迈-艾塞姆】数据文件，最后释放锁。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;备份MyISAM【迈-艾塞姆】和innodb【伊诺 DB】表最终会处于一致，在准备（prepare【普・佩尔】）过程结束后，innodb【伊诺 DB】表数据已经前滚到整个备份结束的点，而不是回滚到xtrabackup【xtra-拜克阿普】刚开始时的点。这个时间点与执行FLUSH【福 辣 徐】 table【忒-部】S WITH【威付】 READ【滤德】 LOCK【拉克】的时间点相同，所以MyISAM【迈-艾塞姆】表数据与innodb【伊诺 DB】表数据是同步的。类似Oracle【欧 瑞 扣】的recover【率 卡沃】和restore【瑞斯多尔】，innodb【伊诺 DB】的prepare【普・佩尔】过程可以称为recover【率 卡沃】（恢复），MyISAM【迈-艾塞姆】的数据复制过程可以称为restore【瑞斯多尔】（还原）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2、获取xtrabackup【xtra-拜克阿普】备份工具&lt;/h3&gt;
&lt;p&gt;网站域名：www.percona.com
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112518420.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3、xxtarbackup软件的安装&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;第一步：上传软件及依赖库到Linux服务器端&lt;/li&gt;
&lt;li&gt;第二步：安装依赖库&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;#rpm -ivh libev-4.15-3.el7.x86_64.rpm
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;第三步：安装xtrabackup【xtra-拜克阿普】软件&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;#yum install【因-斯多​】 percona-xtrabackup【xtra-拜克阿普】-24-2.4.7-2.el7.x86_64.rpm -y
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4、xtrabackup【xtra-拜克阿普】全库备份与恢复&lt;/h3&gt;
&lt;p&gt;备份核心思路：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用innobackupex对数据库中的所有库进行全量备份，备份完成后，不能立即进行数据恢复（数据不完成，缺少12:00~12:30这个过程中的数据）&lt;/li&gt;
&lt;li&gt;预备阶段，备份过程中产生的xtrabackup_log【埃斯-拜克阿普-劳格】应用到全量备份集&lt;/li&gt;
&lt;li&gt;模拟故障（删除数据） =&amp;gt; rm -rf data/*&lt;/li&gt;
&lt;li&gt;动员运维工程师进行全库恢复&lt;/li&gt;
&lt;li&gt;测试验证&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;第一步：准备数据&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; create【克瑞特】 database【得塔-贝斯】 db_sql default【迪-佛特】 charset【查赛特】=utf8;
mysql &amp;gt; use db_sql;
mysql &amp;gt; create【克瑞特】 table【忒-部】 t1(id int,name varchar【瓦儿-查儿】(10)) engine【 嗯(ing) 京(白话读音) 】=myisam【迈-艾塞姆】;
mysql &amp;gt; insert【因涩特】  into【因兔】 t1 values【挖柳斯】 (1,&apos;吕布&apos;);
mysql &amp;gt; create【克瑞特】 table【忒-部】 t2(id int,name varchar【瓦儿-查儿】(10)) engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】;
mysql &amp;gt; insert【因涩特】  into【因兔】 t2 values【挖柳斯】 (1,&apos;貂蝉&apos;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第二步：准备一个数据库备份账号，开通相应权限&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;创建备份用户admin，并授予相应权限
mysql&amp;gt; grant【古亮普】 reload【率漏德】,process【坡塞斯】,lock【拉克】 table【忒-部】s,replication【瑞普利K申】 client【克莱恩特】 on【昂】 *.* to &apos;admin&apos;@&apos;localhost&apos; identified【爱-丹-提伐】 by【拜】 &apos;mysql123&apos;;
mysql&amp;gt; flush【福 辣 徐】 privileges【P符类 杰 斯】;

说明：
在数据库中需要以下权限：
RELOAD【率漏德】和LOCK【拉克】 table【忒-部】S权限:为了执行FLUSH【福 辣 徐】 table【忒-部】S WITH【威付】 READ【滤德】 LOCK【拉克】 
REPLICATION【瑞普利K申】 CLIENT【克莱恩特】权限：为了获取binary【拜讷瑞】 log位置
PROCESS【坡塞斯】权限：显示有关在服务器中执行的线程的信息（即有关会话执行的语句的信息），允许使用SHOW【瘦】 engine【 嗯(ing) 京(白话读音) 】
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第三步：使用innobackupex工具进行备份&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# innobackupex --user=admin --password【帕斯沃德】=mysql123 /full_xtrabackup【xtra-拜克阿普】
IMPORTANT: Please check【切克】 that the backup run completes successfully.
    At the end of a successful backup run innobackupex
    prints &quot;completed OK!&quot;.
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;第一次运行报错&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# innobackupex --user=admin --password【帕斯沃德】=mysql123 /full_xtrabackup
250903 16:48:51 innobackupex: Starting the backup operation

IMPORTANT: Please check【切克】 that the backup run completes successfully.
           At the end of a successful backup run innobackupex
           prints &quot;completed OK!&quot;.

Can&apos;t locate Digest/MD5.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at - line 693.
BEGIN failed--compilation aborted at - line 693.
250903 16:48:52 Connecting to MySQL server host: localhost, user: admin, password【帕斯沃德】: set, port【破特】: not set, socket: not set
Failed to connect to MySQL server: Can&apos;t connect to local MySQL server through socket &apos;/var/lib/mysql/mysql.sock&apos; (2).
[root@mysql ~]# 
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;出现以上问题的原因主要在于我们的mysql.sock并不在/var/lib/mysql目录下，和Perl 模块缺失&lt;/li&gt;
&lt;li&gt;错误一：Can&apos;t locate Digest/MD5.pm in @INC ... 这是一个 ​​Perl 模块缺失​​的错误。innobackupex是一个用 Perl 编写的脚本，它运行时需要 Digest::MD5这个 Perl 模块&lt;/li&gt;
&lt;li&gt;​​原因​​：您的系统上可能没有安装这个必要的 Perl 模块。&lt;/li&gt;
&lt;li&gt;​​解决方案​​：安装 perl-Digest-MD5包。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# yum install【因-斯多​】 -y perl-Digest-MD5
[root@mysql ~]# yum install【因-斯多​】 -y perl-DBD-MySQL
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;为什么会自动连接/var/lib/mysql目录下的mysql.sock呢？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;原因1：可能在/etc目录下还有my.cnf文件，影响了innobackupex的执行&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;原因2：innobackupex拥有自己的默认配置，默认读取了/var/lib/mysql/mysql.sock文件&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;解决方案：
方案1：把你的套接字文件创建一个软链接，放置于/var/lib/mysql/mysql.sock文件中&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# mkdir【摸克跌儿】 /var/lib/mysql
[root@mysql ~]# ln -s /tmp/mysql.sock /var/lib/mysql/mysql.sock
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;方案2：；在innobackupex中添加一个-S选项，执行套接字&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# innobackupex -S /tmp/mysql.sock --user=admin --password【帕斯沃德】=mysql123 /full_xtrabackup【xtra-拜克阿普】
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第四步：预备阶段，把备份这段时间内产生的日志整合到全量备份中&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# innobackupex --user=admin --password【帕斯沃德】=mysql123 --apply0【阿普来】-log /full_xtrabackup【xtra-拜克阿普】/2024-01-06_11-12-53
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第五步：模拟数据库故障&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# rm -rf /mysql_3306/data/*
[root@mysql ~]# pkill mysqld
[root@mysql ~]# # systemctl【西斯屯-ctl】
 stop【 s 多】 mysql_3306.service 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第六步：快速的恢复数据库中的数据&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# rm -rf /mysql_3306/data/*
[root@mysql ~]# innobackupex --copy-back /full_xtrabackup【xtra-拜克阿普】/2024-01-06_11-12-53
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第一次恢复报错&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# innobackupex  --copy-back /full_xtrabackup/2025-09-03_17-28-59
250903 18:00:47 innobackupex: Starting the copy-back operation

IMPORTANT: Please check【切克】 that the copy-back run completes successfully.
           At the end of a successful copy-back run innobackupex
           prints &quot;completed OK!&quot;.

innobackupex version 2.4.7 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 05f1fcf)
Error: datadir must be specified.
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;出现以上问题的主要原因在于，innobackupex工具无法找到MySQL中的数据目录&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;解决方案：把my.cnf配置文件传递给innobackupex，让其自动识别这个文件中的datadir&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# innobackupex --default【迪-佛特】s-file=/mysql_3306/my.cnf --copy-back /full_xtrabackup【xtra-拜克阿普】/2024-01-06_11-12-53
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第七步：恢复数据时，一定要记得更改/mysql_3306/data目录下的文件拥有者以及所属组权限，否则mysql无法启动&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# chown【吃-昂】 -R mysql.mysql /mysql_3306/data
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第八步：启动MySQL，测试是否正常&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# service【瑟为斯】 mysql_3306 start【s 达儿】
[root@mysql ~]# mysql -p
Enter password【帕斯沃德】:123
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5、xtrabackup【xtra-拜克阿普】增量备份与恢复&lt;/h3&gt;
&lt;p&gt;什么是增量？增量一定要有一个前提，必须要现有一个全量
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112542122.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;①全量备份&lt;/li&gt;
&lt;li&gt;②把全量备份产生的日志整合到全量备份&lt;/li&gt;
&lt;li&gt;③进行数据的增删改操作&lt;/li&gt;
&lt;li&gt;④增量备份&lt;/li&gt;
&lt;li&gt;⑤把增量备份及备份产生的日志文件全部整合到全量备份中&lt;/li&gt;
&lt;li&gt;⑥模拟故障&lt;/li&gt;
&lt;li&gt;⑦数据恢复&lt;/li&gt;
&lt;li&gt;⑧启动数据库，测试验证数据&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;第一步：准备数据&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; create【克瑞特】 database【得塔-贝斯】 db_sql default【迪-佛特】 charset【查赛特】=utf8;
mysql &amp;gt; use db_sql;
mysql &amp;gt; create【克瑞特】 table【忒-部】 t1(id int,name varchar【瓦儿-查儿】(10)) engine【 嗯(ing) 京(白话读音) 】=myisam【迈-艾塞姆】;
mysql &amp;gt; insert【因涩特】  into【因兔】 t1 values【挖柳斯】 (1,&apos;吕布&apos;);
mysql &amp;gt; create【克瑞特】 table【忒-部】 t2(id int,name varchar【瓦儿-查儿】(10)) engine【 嗯(ing) 京(白话读音) 】=innodb【伊诺 DB】;
mysql &amp;gt; insert【因涩特】  into【因兔】 t2 values【挖柳斯】 (1,&apos;貂蝉&apos;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第二步：创建一个账号，专门用于备份&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;创建备份用户admin，并授予相应权限
mysql&amp;gt; grant【古亮普】 reload【率漏德】,process【坡塞斯】,lock【拉克】 table【忒-部】s,replication【瑞普利K申】 client【克莱恩特】 on【昂】 *.* to &apos;admin&apos;@&apos;localhost&apos; identified【爱-丹-提伐】 by【拜】 &apos;mysql123&apos;;
mysql&amp;gt; flush【福 辣 徐】 privileges【P符类 杰 斯】;

# mysql&amp;gt; grant reload,process,lock tables,replication client on *.* to &apos;admin&apos;@&apos;localhost&apos; identified by &apos;mysql123&apos;;
# Query OK, 0 rows affected, 1 warning (0.05 sec)
# mysql&amp;gt; flush privileges;

说明：
在数据库中需要以下权限：
1. RELOAD【率漏德】和LOCK table【忒-部】S权限:为了执行FLUSH【福 辣 徐】  table【忒-部】S WITH【威付】 READ【滤德】 LOCK【拉克】
2. REPLICATION【瑞普利K申】 CLIENT【克莱恩特】权限：为了获取binary【拜讷瑞】 log位置
3. PROCESS【坡塞斯】权限：显示有关在服务器中执行的线程的信息（即有关会话执行的语句的信息），允许使用SHOW【瘦】 engine【 嗯(ing) 京(白话读音) 】
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第三步：全量备份&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# rm -rf /full_xtrabackup【xtra-拜克阿普】/*
[root@mysql ~]# innobackupex --user=admin --password【帕斯沃德】=mysql123 /full_xtrabackup【xtra-拜克阿普】/
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第四步：把全备过程中产生的日志进行整合&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# innobackupex --user=admin --password【帕斯沃德】=mysql123 --apply【阿普来】-log --redo【率度】-only【欧利】 /full_xtrabackup【xtra-拜克阿普】/2024-01-06_17-29-11

选项说明：
1. &quot;--apply【阿普来】-log&quot; 表示整合日志
2. &quot;--redo【率度】-only【欧利】&quot; 表示只应用以及提交的事务，不回滚未提交的事务（12:00~12:30产生很多事务操作，事务处理=&amp;gt;开启事务，成功了提交事务，写入磁盘，失败了回滚事务，不写入硬盘）
注意：如果已经回滚了未提交事务，那么就无法再应用增量备份
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Preparing an Incremental Backup with【威付】 innobackupex Preparing
incremental backups is a bit diƊerent than full ones. This is, perhaps, the
stage where【威尔】  more attention is needed:
• First, only【欧利】 the committed transactions must be replayed on each
backup. This will merge the base full backup with【威付】 the incremental ones.
• Then, the uncommitted transaction must be rolled back in order【欧朵】 to have
a ready-to-use backup.
对于增量备份的Prepare【普・佩尔】阶段，有2个需要注意的地方，一个是提交的事务需要
replayed，一个未提交的事务需要rollback【柔拜克】。
If you replay the committed transactions and rollback【柔拜克】 the uncommitted
ones on the base backup, you will not【nuō 特】 be able to add the incremental
ones. If you do this on an incremental one, you won’t be able to add data
from【弗乱】 that moment and the remaining increments. Having【嗨夫营】 this in mind,
the procedure is very straight-forward using the --redo【率度】-only【欧利】 option【阿普申】,
starting with【威付】 the base backup:
如果在Prepare【普・佩尔】阶段replay了已提交的事务以及回滚了未提交的事务，则后续
的增量备份无法添加到当前全备。因此在Prepare【普・佩尔】阶段全备应使用--redo【率度】-only【欧利】
选项。
--redo【率度】-only【欧利】 should be used when merging all incrementals except the last
one. That’s why the previous line doesn’t contain the --redo【率度】-only【欧利】 option【阿普申】.
Even if the --redo【率度】-only【欧利】 was used on the last step, backup would still be
consistent but in that case server would perform the rollback【柔拜克】 phase.
对于存在多次增量的情形，仅仅只有最后一个增量不需要使用--redo【率度】-only【欧利】 选
项。如果使用了的话，rollback【柔拜克】将由服务器启动的时候来完成。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;第五步：修改数据（进行增删改操作，让其产生增量数据）&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;#mysql -p
Enter password【帕斯沃德】:123
mysql &amp;gt; insert【因涩特】  into【因兔】 db_sql.t1 values【挖柳斯】 (2,&apos;王朗&apos;);
mysql &amp;gt; insert【因涩特】  into【因兔】 db_sql.t1 values【挖柳斯】 (3,&apos;袁术&apos;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第六步：做增量备份&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# innobackupex --user=admin --password【帕斯沃德】=mysql123 --incremental /incre_backup --incremental-basedir=/full_xtrabackup【xtra-拜克阿普】/2024-01-06_17-29-11

选项说明：
1. &quot;--incremental&quot; 设置增量备份目录&quot;/incre_backup&quot;
2. &quot;--incremental-basedir&quot; 这个增量是相对于哪个全量的
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第七步：把增量备份产生的数据以及日志文件整合到全量备份中&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# innobackupex --user=admin --password【帕斯沃德】=mysql123 --apply【阿普来】-log  /full_xtrabackup【xtra-拜克阿普】/2024-01-06_17-29-11 --incremental-dir=/incre_backup/2024-01-06_17-39-15

说明：
1. &quot;--redo【率度】-only【欧利】&quot; 除了最后一个不用加之外，其他的增量应用都要加，最后一个应用的时候可以直接进入回滚未提交事务阶段;如果加了也没事，服务启动的时候会进入recovery【率 卡沃】过程，来回滚
2. 应用增量备份的时候只能按照备份的顺序来应用。如果应用顺序错误，那么备份就不可用。如果无法确定顺序，可以使用xtrabackup【xtra-拜克阿普】-checkpoints【切克破安茨】来确定顺序。周天做了一个全量，周一、周二、周三、周四、周五、周六全部做增量
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;到此，增量备份就全部结束了&lt;/p&gt;
&lt;h4&gt;第八步：模拟数据库故障&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# rm -rf /mysql_3306/data/*
[root@mysql ~]# pkill mysqld
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第九步：数据恢复&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;#innobackupex --defaults【迪-佛特】-file=/mysql_3306/my.cnf --user=admin --password【帕斯沃德】=mysql123 --copy-back /full_xtrabackup【xtra-拜克阿普】/2024-01-06_17-29-11

[root@mysql ~]# innobackupex --defaults-file=/mysql_3306/my.cnf --user=admin --password【帕斯沃德】=mysql123 --copy-back /full_xtrabackup/2025-09-03_18-14-56
#chown【吃-昂】 -R mysql.mysql /mysql_3306/data
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;启动数据库，测试验证是否正常&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql ~]# service【瑟为斯】 mysql_3306 start【s 达儿】
[root@mysql ~]# mysql -p
Enter password【帕斯沃德】:123
mysql &amp;gt; use db_sql;
mysql &amp;gt; select【涩莱克特】 * from【弗乱】 t1;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;day06-MySQL主从复制架构&lt;/h1&gt;
&lt;p&gt;MySQL主从复制架构&lt;/p&gt;
&lt;h2&gt;一、任务背景&lt;/h2&gt;
&lt;h3&gt;1、真实案例&lt;/h3&gt;
&lt;p&gt;某同学刚入职公司，在熟悉公司业务环境的时候，发现他们的数据库架构是一主两从，但是两台从数据库和主库不同步。询问得知，已经好几个月不同步了，但是每天会全库备份主服务器上的数据到从服务器上，由于数据量不是很大，所以一直没有人处理主从不同步的问题。这次正好问到了，于是乎就安排该同学处理一下这个主从不同步的问题。&lt;/p&gt;
&lt;h3&gt;2、案例背后的核心技术&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;熟悉MySQL数据库常见的主从架构&lt;/li&gt;
&lt;li&gt;理解MySQL主从架构的实现原理&lt;/li&gt;
&lt;li&gt;掌握MySQL主从架构的搭建&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3、任务场景&lt;/h3&gt;
&lt;p&gt;随着业务量不断增长，公司对数据的安全性越来越重视，由于常规的备份不能够实时记录下数据库的所有状态，为了能够保障数据库的实时备份冗余，希望将现有单机数据库变成双机热备。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;①任务要求
备份数据库
搭建双机热备数据库架构M-S&lt;/li&gt;
&lt;li&gt;②任务目标
了解什么是MySQL的Replication【瑞普利K申】
理解MySQL的Replication【瑞普利K申】的架构原理
掌握MySQL的基本复制架构的搭建（M-S重点）
了解和掌握基于GTIDs的复制特点及搭建&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;二、MySQL集群概述&lt;/h2&gt;
&lt;h3&gt;1、集群的主要类型&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;高可用集群（High【嗨】 Available【呃 维 勒 布(白话)】 Cluster【克拉斯特】，HA Cluster【克拉斯特】）&lt;/li&gt;
&lt;li&gt;高可用集群是指通过特殊的软件把独立的服务器连接起来，组成一个能够提供故障切换功能的集群&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2、如何衡量高可用&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;可用性级别(指标)&lt;/th&gt;
&lt;th&gt;年度宕机时间&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;th&gt;叫法&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;99%&lt;/td&gt;
&lt;td&gt;3.65天/年&lt;/td&gt;
&lt;td&gt;基本可用系统&lt;/td&gt;
&lt;td&gt;2个9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99.9%&lt;/td&gt;
&lt;td&gt;8.76小时/年&lt;/td&gt;
&lt;td&gt;可用系统&lt;/td&gt;
&lt;td&gt;3个9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99.99%&lt;/td&gt;
&lt;td&gt;52.6分钟/年&lt;/td&gt;
&lt;td&gt;高可用系统&lt;/td&gt;
&lt;td&gt;4个9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99.999%&lt;/td&gt;
&lt;td&gt;5.3分钟/年&lt;/td&gt;
&lt;td&gt;抗故障系统&lt;/td&gt;
&lt;td&gt;5个9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99.9999%&lt;/td&gt;
&lt;td&gt;32秒/年&lt;/td&gt;
&lt;td&gt;容错系统&lt;/td&gt;
&lt;td&gt;6个9&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;计算方法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1年 = 365天 = 8760小时
99% = 8760 * 1% = 8760 * 0.01 = 87.6小时=3.65天
99.9 = 8760 * 0.1% = 8760 * 0.001 = 8.76小时
99.99 = 8760 * 0.0001 = 0.876小时 = 0.876 * 60 = 52.6分钟
99.999 = 8760 * 0.00001 = 0.0876小时 = 0.0876 * 60 = 5.26分钟
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3、常用的集群架构&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;MySQL Replication【瑞普利K申】 主从架构&lt;/li&gt;
&lt;li&gt;MySQL Cluster【克拉斯特】 集群架构&lt;/li&gt;
&lt;li&gt;MySQL Group【格鲁普】 Replication【瑞普利K申】 （MGR） 多主一从&lt;/li&gt;
&lt;li&gt;MariaDB Galera【哥 雷 拉】 Cluster【克拉斯特】&lt;/li&gt;
&lt;li&gt;MHA | Keepalived【ki 普赖夫】 | HeartBeat【哈迪 比踢】 | Lvs，HAproxy【哈扑若西】等技术构建高可用集群&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;三、MySQL复制&lt;/h2&gt;
&lt;h3&gt;1、什么是MySQL复制&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Replication【瑞普利K申】可以实现将数据从一台数据库服务器（master【马斯特】）复制到一台到多台数据库服务器(slave【斯累夫】)&lt;/li&gt;
&lt;li&gt;默认情况下，属于异步复制，所以无需维持长连接&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2、MySQL复制原理&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;简单来说，master【马斯特】将数据库的改变写入二进制日志，slave【斯累夫】同步这些二进制日志，并根据这些二进制日志进行数据重演操作，实现数据异步同步。&lt;/li&gt;
&lt;li&gt;master【马斯特】：主&lt;/li&gt;
&lt;li&gt;slave【斯累夫】：从
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117113749340.webp&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;详细描述：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当主从同步配置完毕后：&lt;/li&gt;
&lt;li&gt;slave【斯累夫】端的IO线程发送请求给master【马斯特】端的binlog【宾-劳格】 dump【邓破】线程&lt;/li&gt;
&lt;li&gt;master【马斯特】端binlog【宾-劳格】 dump【邓破】线程获取二进制日志信息(文件名和位置信息)发送给slave【斯累夫】端的IO线程&lt;/li&gt;
&lt;li&gt;slave【斯累夫】端IO线程获取到的内容依次写到slave【斯累夫】端relay【瑞雷】 log(中继日志)里，并把master【马斯特】端的bin-log文件名和位置记录到master【马斯特】.info【因否】里&lt;/li&gt;
&lt;li&gt;slave【斯累夫】端的SQL线程，检测到relay【瑞雷】 log中内容更新，就会解析relay【瑞雷】 log里更新的内容，并执行这些操作，从而达到和master【马斯特】数据一致&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;relay【瑞雷】 log中继日志&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;作用：记录从（slave【斯累夫】）服务器接收来自主（master【马斯特】）服务器的二进制日志&lt;/li&gt;
&lt;li&gt;场景：用于主从复制&lt;/li&gt;
&lt;li&gt;master【马斯特】主服务器将自己的二进制日志发送给slave【斯累夫】从服务器，slave【斯累夫】先保存在自己的中继日志中，然后再执行自己本地的relay【瑞雷】 log里的sql达到数据库更改和master【马斯特】保持一致。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如何开启？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;默认中继日志没有开启，可以通过修改配置文件完成开启。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;# vim my.cnf
[mysqld]
#指定二进制日志存放位置及文件名
relay【瑞雷】_log=/mysql_3306/data/relay【瑞雷】log
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3、MySQL复制架构&lt;/h3&gt;
&lt;h4&gt;①双机热备（AB复制）&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117113741259.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;默认情况下，master【马斯特】接收读写请求，slave【斯累夫】只接收读请求以减轻master【马斯特】的压力&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;②级联复制&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117113730976.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;优点：进一步分担读压力&lt;/li&gt;
&lt;li&gt;缺点：slave【斯累夫】 1出现故障，后面的所有级联slave【斯累夫】服务器都会同步失败&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;③并联复制（一主多从）&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117113820640.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;优点：解决上面的slave【斯累夫】1的单点故障，同时也分担读压力&lt;/li&gt;
&lt;li&gt;缺点：间接增加master【马斯特】的压力&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;④双主复制&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117113809206.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;特点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;从名称上来看，两台master【马斯特】好像都能接受读、写 请求，但实际上，往往运作的过程中，同一时刻只有其中一台master【马斯特】会接收请求，另外一台只接收读请求。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;四、MySQL主从复制的搭建（AB复制）&lt;/h2&gt;
&lt;h3&gt;1、传统AB复制架构&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;说明：在配置MySQL主从架构时，必须保障数据库的版本高度一致，统一版本为5.7.31&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2、环境规划&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;编号&lt;/th&gt;
&lt;th&gt;主机名称&lt;/th&gt;
&lt;th&gt;主机地址&lt;/th&gt;
&lt;th&gt;角色信息&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;master【马斯特】.it.cn&lt;/td&gt;
&lt;td&gt;192.168.20.50&lt;/td&gt;
&lt;td&gt;MASTER【马斯特】主服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;slave【斯累夫】.it.cn&lt;/td&gt;
&lt;td&gt;192.168.20.60&lt;/td&gt;
&lt;td&gt;SLAVE【斯累夫】从服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;3、安装前准备工作&lt;/h3&gt;
&lt;h4&gt;第一步：克隆服务器&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;克隆两台全新的数据库服务器，MASTER【马斯特】/SLAVE【斯累夫】&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;第二步：更改主机名称&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;首先启动MASTER【马斯特】，然后启动SLAVE【斯累夫】，更改主机名称&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Master【马斯特】：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 master【马斯特】.it.cn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Slave【斯累夫】:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 slave【斯累夫】.it.cn
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第三步：设置静态IP&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;更改静态IP地址，把Master【马斯特】和Slave【斯累夫】配置与规划一致
Master【马斯特】&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;#vim /etc/sysconfig【西斯肯菲格】/network【孽特 - 沃克】-scripts【斯贵 普茨】/ifcfg-ens33
...
IPADDR=192.168.20.50
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Slave【斯累夫】&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#vim /etc/sysconfig【西斯肯菲格】/network【孽特 - 沃克】-scripts【斯贵 普茨】/ifcfg-ens33
...
IPADDR=192.168.20.60
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Master【马斯特】/Slave【斯累夫】&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;## systemctl【西斯屯-ctl】
 stop【 s 多】 NetworkManager【孽特沃克 面尼杰额】
## systemctl【西斯屯-ctl】
 disable【滴 s 步】 NetworkManager【孽特沃克 面尼杰额】
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;注意：关闭 NetworkManager【孽特沃克 面尼杰额】服务是配置静态IP过程中一个非常关键且常见的步骤，​​为了避免 NetworkManager【孽特沃克 面尼杰额】服务与传统的 network【孽特 - 沃克】-scripts【斯贵 普茨】服务发生冲突，让系统只通过传统的 network【孽特 - 沃克】-scripts【斯贵 普茨】方式来管理网络，从而确保静态IP地址配置的稳定性和可靠性&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;设置完成后，重启网络，然后使用shell或MX远程连接&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;第四步：绑定hosts&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;由于两台机器处于集群架构，需要相互连接。绑定主机名称与IP地址到/etc/hosts&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Master【马斯特】/Slave【斯累夫】：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vim /etc/hosts
192.168.20.50 master【马斯特】.it.cn
192.168.20.60 slave【斯累夫】.it.cn
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第五步：关闭防火墙与SElinux&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;关闭防火墙与SElinux&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;## systemctl【西斯屯-ctl】
 stop【 s 多】 firewalld【fai 额 沃 得】
## systemctl【西斯屯-ctl】
 disable【滴 s 步】 firewalld【fai 额 沃 得】
#setenforce【赛特-因佛尔斯】 0
#vim /etc/selinux/cong
SELINUX=disable【滴 s 步】
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第六步：配置yum源&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;配置yum源（建议使用腾讯源）&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;# yum install【因-斯多​】 wget -y
# mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.cloud.tencent.com/repo/centos7_base.repo
# yum clean【科林恩】 all
# yum makecache
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第七步：时间同步&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;时间同步&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;#ntpdate 182.92.12.11
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4、MySQL主从复制核心思路&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112555119.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;slave【斯累夫】必须安装相同版本的mysql数据库软件&lt;/li&gt;
&lt;li&gt;master【马斯特】端必须开启二进制日志；slave【斯累夫】端必须开启relay【瑞雷】 log日志&lt;/li&gt;
&lt;li&gt;master【马斯特】端和slave【斯累夫】端的server【涩·沃】-id号不能一致&lt;/li&gt;
&lt;li&gt;slave【斯累夫】端配置向master【马斯特】来同步数据&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;master【马斯特】端必须创建一个复制用户
保证master【马斯特】和slave【斯累夫】端初始数据一致
配置主从复制（slave【斯累夫】端）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;5、MySQL主从复制的具体实践&lt;/h3&gt;
&lt;h4&gt;第一步：上传MySQL软件包到Master【马斯特】与Slave【斯累夫】&lt;/h4&gt;
&lt;h4&gt;第二步：在Master【马斯特】端安装、初始化以及运行mysql软件&lt;/h4&gt;
&lt;p&gt;安装需求：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;选项&lt;/th&gt;
&lt;th&gt;值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;安装路径&lt;/td&gt;
&lt;td&gt;/usr/local/mysql&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;数据路径&lt;/td&gt;
&lt;td&gt;/usr/local/mysql/data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;端口号&lt;/td&gt;
&lt;td&gt;3306&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h5&gt;①安装MySQL软件&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;[root@master ~]# vim mysql.sh
#!/bin/bash
yum install【因-斯多​】 libaio -y
tar -xf mysql-5.7.31-linux-glibc【哥里布C】2.12-x86_64.tar.gz
rm -rf /usr/local/mysql
mv mysql-5.7.31-linux-glibc【哥里布C】2.12-x86_64 /usr/local/mysql
useradd -r -s /sbin/nologin mysql
rm -rf /etc/my.cnf
cd /usr/local/mysql
mkdir【摸克跌儿】 mysql-files
chown【吃-昂】 mysql:mysql mysql-files
chmod【吃-默德】750 mysql-files
bin/mysqld --initialize【因 尼 舍 来斯】 --user=mysql --basedir=/usr/local/mysql &amp;amp;&amp;gt; /root/password【帕斯沃德】.txt
bin/mysql_ssl_rsa_setup --datadir=/usr/local/mysql/data
cp /usr/local/mysql/support【瑟破特】-files/mysql.server【涩·沃】 /etc/init.d/mysqld
service【瑟为斯】 mysqld start【s 达儿】
echo &apos;export【e斯 破特】 PATH=$PATH:/usr/local/mysql/bin&apos; &amp;gt;&amp;gt; /etc/profile
source /etc/profile

[root@master ~]# source mysql.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;shell脚本其实就是命令的堆砌，把一堆Linux命令写在同一个文件中，一起执行&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;②安全配置&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;[root@master ~]# mysql_secure_installation【因-斯多 雷申​】

Securing the MySQL server【涩·沃】 deployment.

Enter password for【fò】 user root: # 输入原始root密码

The existing password for【fò】 the user account root has expired. Please set a new password.

New password: # 设置新root密码

Re-enter new password: 

VALIDATE PASSWORD PLUGIN【普辣 京(白话)】 can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only【欧利】 those passwords which are
secure enough. Would you like【赖特】 to setup VALIDATE PASSWORD plugin【普辣 京(白话)】?

Press y|Y for Yes, any other key for No: n # 是否安装“密码验证插件”。这个插件可以强制要求用户设置高强度的密码（例如，要求包含数字、大小写字母、特殊符号，并达到最小长度）
Using existing password for root.
Change the password for root ? ((Press y|Y for Yes, any other key for No) : n # 是否更改root密码

 ... skipping.
By default, a MySQL installation has an anonymous user,
allowing anyone to log into【因兔】 MySQL without having to have
a user account created for them. This is intended only【欧利】 for
testing, and to make the installation go a bit smoother.
You should remove them before moving into【因兔】 a production
environment.

Remove anonymous users? (Press y|Y for Yes, any other key for No) : y # 移除匿名用户
Success.


Normally, root should only【欧利】 be allowed to connect from【弗乱】
&apos;localhost&apos;. This ensures that someone cannot guess at
the root password from【弗乱】 the network.

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y # 禁止root远程登录
Success.

By default, MySQL comes with a database named &apos;test&apos; that
anyone can access. This is also intended only【欧利】 for testing,
and should be removed before moving into【因兔】 a production
environment.


Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y # 移除测试数据库
 - Dropping test database...
Success.

 - Removing privileges on test database...
Success.

Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.

Reload【率漏德】 privilege tables now? (Press y|Y for Yes, any other key for No) : y # 重载权限表
Success.

All done! 
[root@slave ~]# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;③配置my.cnf（重点开启二进制日志）&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;[root@master ~]# cd /usr/local/mysql
[root@master mysql]# vim my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
port【破特】=3306
log_error=/usr/local/mysql/data/master【马斯特】.err
log_bin=/usr/local/mysql/data/binlog【宾-劳格】 一定要开启二进制日志
server【涩·沃】_id=10
character_set_server【涩·沃】=utf8mb4 utf8mb4相当于utf8升级版
配置完成后，重启mysqld服务

[root@master mysql]# service【瑟为斯】 mysqld restart【 率 s 达r】
[root@master mysql]# chkconfig【切-坑菲格】 --add mysqld
[root@master mysql]# chkconfig【切-坑菲格】 mysqld on
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第三步：在Slave【斯累夫】从服务器端安装mysql软件（不需要初始化）&lt;/h4&gt;
&lt;h5&gt;①安装MySQL软件&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;[root@slave ~]# vim mysql.sh
#!/bin/bash
yum install【因-斯多​】 libaio -y
tar -xf mysql-5.7.31-linux-glibc【哥里布C】2.12-x86_64.tar.gz
rm -rf /usr/local/mysql
mv mysql-5.7.31-linux-glibc【哥里布C】2.12-x86_64 /usr/local/mysql
useradd -r -s /sbin/nologin mysql
rm -rf /etc/my.cnf
cd /usr/local/mysql
mkdir【摸克跌儿】 mysql-files
chown【吃-昂】 mysql:mysql mysql-files
chmod【吃-默德】750 mysql-files
cp /usr/local/mysql/support【瑟破特】-files/mysql.server【涩·沃】 /etc/init.d/mysqld
echo &apos;export【e斯 破特】 PATH=$PATH:/usr/local/mysql/bin&apos; &amp;gt;&amp;gt; /etc/profile
source /etc/profile

[root@slave ~]# source mysql.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;相对于主服务器MySQL的安装与配置，从服务器端不需要进行初始化操作，因为其数据将来自于主服务器&lt;/p&gt;
&lt;h5&gt;②配置my.cnf文件&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;[root@slave ~]# cd /usr/local/mysql
[root@slave mysql]# vim my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
port【破特】=3310
log_error=/usr/local/mysql/data/slave【斯累夫】.err
relay【瑞雷】_log=/usr/local/mysql/data/relay【瑞雷】log
server【涩·沃】_id=100
character_set_server【涩·沃】=utf8mb4
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;③把master【马斯特】主服务器的数据目录同步到slave【斯累夫】从服务器&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;把Master【马斯特】服务器中的mysqld停止掉&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;[root@master mysql]# service【瑟为斯】 mysqld stop【 s 多】
Shutting down MySQL... SUCCESS! 
[root@master mysql]# 
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;把MASTER【马斯特】服务器中的/usr/local/mysql/data目录下的auto【奥特欧】.cnf文件删除&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;[root@master ~]# rm -rf /usr/local/mysql/data/auto【奥特欧】.cnf
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;每安装一个mysql软件，其data数据目录都会产生一个auto【奥特欧】.cnf文件，里面是一个唯一性的编号，相当于我们每个人的身份证号码&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;把master【马斯特】服务器中的/usr/local/mysql中的data目录拷贝一份到slave【斯累夫】从服务器的/usr/local/mysql目录&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;[root@master ~]# rsync -av /usr/local/mysql/data root@192.168.20.60:/usr/local/mysql
或
[root@master ~]# scp -r /usr/local/mysql/data root@192.168.20.60:/usr/local/mysql/

slave端授权
[root@slave ~]# chown【吃-昂】 -R mysql:mysql /usr/local/mysql/data

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;同步完成后，把主服务器与从服务器中的mysqld启动&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;#service【瑟为斯】 mysqld start【s 达儿】
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;常见问题解决方案&lt;/h5&gt;
&lt;h6&gt;⭐常见问题1：MySQL无法启动&lt;/h6&gt;
&lt;pre&gt;&lt;code&gt;#service【瑟为斯】 mysql start【s 达儿】
Redirecting to /bin/# systemctl【西斯屯-ctl】
 start【s 达儿】 mysqld.service【瑟为斯】
Failed to start【s 达儿】 mysqld.service【瑟为斯】: Unit not found.
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;出现以上问题的原因在于/etc/init.d目录中没有Mysqld这个文件，换句话说就是cpmysql.servet脚本&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;#cp /usr/local/mysql/support0files【瑟破踢的-0-伐尔】/mysql.server【涩·沃】 /etc/init.d/mysqld
记录：/etc/init.d目录中的文件叫什么名字，我们service【瑟为斯】的时候就应该使用什么名字
#service【瑟为斯】 mysql start【s 达儿】
&lt;/code&gt;&lt;/pre&gt;
&lt;h6&gt;常见问题2：MySQL没有安装在/usr/local/mysql目录中，service【瑟为斯】也无法启动&lt;/h6&gt;
&lt;pre&gt;&lt;code&gt;#service【瑟为斯】 mysqld start【s 达儿】
无法启动的原因可能是你的MySQL并没有安装在/usr/local/mysql目录中，因为/etc/init.d/mysqld脚本中的basedir于datadir默认指向的都是/usr/local/mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;所以如果我们更换了Mysql的安装位置，则必须更改/etc/init.d/mysqld脚本中basedir与datadir目录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#vim /etc/init.d/mysqld
basedir=你的安装路径
datadir=你的安装路径/data
&lt;/code&gt;&lt;/pre&gt;
&lt;h6&gt;常见问题3：因为my.cn配置文件导致mysql无法启动&lt;/h6&gt;
&lt;pre&gt;&lt;code&gt;#vim my.cnf
[mysqld]
basedir=/usr/local/mysql =&amp;gt;安装路径
datadir=/usr/local/mysql/data =&amp;gt;数据目录
socket=/tmp/mysql.sock =&amp;gt; GLIBC【哥里布C】默认就是/tmp/mysql.sock
port【破特】=3310
log_error=/usr/local/mysql/data/slave【斯累夫】.err =&amp;gt;错误日志放在哪里
relay【瑞雷】_log=/usr/local/mysql/data/relay【瑞雷】log
server【涩·沃】_id=100
character_set_server【涩·沃】=utf8mb4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;启动时报错问题&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;2024-01-15T06:18:55.566951Z mysqld_safe error: log-error set to
&apos;/usr/local/mysql/slave【斯累夫】.err&apos;, however le don&apos;t exists. Create writable for【fò】 user
&apos;mysql&apos;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;产生以上问题的主要原因在于mysql这个用户对/usr/local/mysql文件夹没有写入权限&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#ll -d /usr/local/mysql
drwxr-xr-x. 11 7161 31415 174 Jan 15 14:18 /usr/local/mysql
发现文件拥有者位置与所属组位置都是两个数字，正常应该是文件拥有者的名称与文件所属组的名称。但是由于GLIBC【哥里布C】已经提前打包了，我们解压后，如果在我们系统中，找不到源文件对应的文件拥有者与所属组，则以两个数字代替文件拥有者与所属组的显示。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;解决方案：
方案一：建议把错误日志，丢在数据目录中&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#vim my.cnf
...
log_error=/usr/local/mysql/data/slave【斯累夫】.err
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;方法二：直接更改/usr/local/mysql目录的权限&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#chown【吃-昂】 -R mysql.mysql /usr/local/mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;④配置MASTER【马斯特】-SLAVE【斯累夫】主从同步&lt;/h5&gt;
&lt;h6&gt;1.在MASTER【马斯特】主服务器中创建一个账户，专门用于实现数据同步&lt;/h6&gt;
&lt;p&gt;Mysql5.7及以下版本：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; grant【古亮普】 replication【瑞普利K申】 slave【斯累夫】 on *.* to &apos;slave【斯累夫】&apos;@&apos;192.168.20.%&apos; identified【爱-丹-提伐】 by &apos;123&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;MySQL新版本中：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】 user &apos;slave【斯累夫】&apos;@&apos;192.168.20.%&apos; identified【爱-丹-提伐】 by &apos;123&apos;;
mysql&amp;gt; grant【古亮普】 replication【瑞普利K申】 slave【斯累夫】 on *.* to &apos;slave【斯累夫】&apos;@&apos;10.1.1.%&apos;;
mysql&amp;gt; flush【福 辣 徐】 privileges【P符类 杰 斯】;
&lt;/code&gt;&lt;/pre&gt;
&lt;h6&gt;2. 在MASTER【马斯特】中锁表，然后查看二进制文件的名称及位置&lt;/h6&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; flush【福 辣 徐】 tables with【威付】 read【滤德】 lock【拉克】;
mysql&amp;gt; show【瘦】 master【马斯特】 status【 斯dèi 特斯】;
+---------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog【宾-劳格】_Do_DB | Binlog【宾-劳格】_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog【宾-劳格】.000006 | 449 | | | |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h6&gt;3.在SLVAE【斯累夫】从服务器中，使用change【趁(chèn)吉】 master【马斯特】 to 指定主服务器，并实现数据同步&lt;/h6&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; change【趁(chèn)吉】 master【马斯特】 to master【马斯特】_host=&apos;192.168.20.50&apos;,master【马斯特】_user=&apos;slave【斯累夫】&apos;,master【马斯特】_password【帕斯沃德】=&apos;123&apos;,master【马斯特】_port【破特】=3306,master【马斯特】_log_file=&apos;binlog【宾-劳格】.000006&apos;,master【马斯特】_log_pos=449;

说明：
MASTER【马斯特】_HOST=：主机的IP地址
MASTER【马斯特】_USER=：主机的user账号
MASTER【马斯特】_PASSWORD【帕斯沃德】=：主机的user账号密码
MASTER【马斯特】_PORT【破特】=主机MYSQL端口号
MASTER【马斯特】_LOG_FILE=：二进制文件名称
MASTER【马斯特】_LOG_POS=：二进制文件位置
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;主从复制的change【趁(chèn)吉】 master【马斯特】 to语句不知道怎么写或记不住怎么办
答：求帮助&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; help change【趁(chèn)吉】 master【马斯特】 to;
CHANGE【趁(chèn)吉】 MASTER【马斯特】 TO
MASTER【马斯特】_HOST=&apos;master【马斯特】2.example.com&apos;,
MASTER【马斯特】_USER=&apos;replication【瑞普利K申】&apos;,
MASTER【马斯特】_PASSWORD【帕斯沃德】=&apos;password【帕斯沃德】&apos;,
MASTER【马斯特】_PORT【破特】=3306,
MASTER【马斯特】_LOG_FILE=&apos;master【马斯特】2-bin.001&apos;,
MASTER【马斯特】_LOG_POS=4,
MASTER【马斯特】_CONNECT_RETRY=10;
&lt;/code&gt;&lt;/pre&gt;
&lt;h6&gt;4.启动slave【斯累夫】数据同步&lt;/h6&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; start【s 达儿】 slave【斯累夫】;
mysql &amp;gt; show【瘦】 slave【斯累夫】 status【 斯dèi 特斯】\G
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;常见问题解决方案
在配置主从时，一般遇到错误，大部分都是change【趁(chèn)吉】 master【马斯特】 to语句写错了（80%）
解决方案&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; stop【 s 多】 slave【斯累夫】;
mysql &amp;gt; change【趁(chèn)吉】 master【马斯特】 to master【马斯特】_host=&apos;192.168.20.50&apos;,master【马斯特】_user=&apos;slave【斯累夫】&apos;,master【马斯特】_password【帕斯沃德】=&apos;123&apos;,master【马斯特】_port【破特】=3306,master【马斯特】_log_le=&apos;binlog【宾-劳格】.000006&apos;,master【马斯特】_log_pos=449;
mysql &amp;gt; start【s 达儿】 slave【斯累夫】;
mysql &amp;gt; show【瘦】 slave【斯累夫】 status【 斯dèi 特斯】\G
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;⑤主MASTER【马斯特】服务解锁&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; unlock【嗯 拉克】 tables;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;⑥SLAVE【斯累夫】从服务器不小心写入数据解决方案&lt;/h5&gt;
&lt;p&gt;正常情况下：
MASTER【马斯特】既可以读，也可以写。但是SLAVE【斯累夫】从服务器，只能执行读取操作。一旦我们在SLQVE从服务器种写入数据，则主从架构会失败。
SLAVE【斯累夫】：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#show【瘦】 slave【斯累夫】 status【 斯dèi 特斯】\G
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112609637.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;遇到以上问题：如果数量较少，还可以通过当前语句的方式解决，但是如果从服务器写入数据过多，则以上架构必须要重新搭建&lt;/p&gt;
&lt;p&gt;解决方案：
如果由于人为操作或者其他原因直接将数据更改到从服务器导致数据同步失效，怎么解决？
答：可以通过变量 sql_slave【斯累夫】_skip_counter【坑俀】 临时跳过事务进行处理&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SET GLOBAL【格喽部】 sql_slave【斯累夫】_skip_counter【坑俀】 = N N代表跳过N个事务
举例说明：
mysql&amp;gt; SET GLOBAL【格喽部】 sql_slave【斯累夫】_skip_counter【坑俀】=1;
mysql&amp;gt; stop【 s 多】 slave【斯累夫】;
mysql&amp;gt; start【s 达儿】 slave【斯累夫】;
注意：
1. 跳过事务应该在slave【斯累夫】上进行
2. 传统的AB复制方式可以使用变量：sql_slave【斯累夫】_skip_counter【坑俀】，基于GTIDs的方式不支持
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、基于GTIDs的AB复制架构（M-S）&lt;/h2&gt;
&lt;h3&gt;1、GTIDs概述&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;什么是GTIDs以及有什么特点？&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;GTIDs（Global【格喽部】 transaction【穿插神】 identifiers【爱垫德伐 r s】）全局事务标识符，是mysql 5.6新加入的一项技术&lt;/li&gt;
&lt;li&gt;当使用GTIDs时，每一个事务都可以被识别并且跟踪&lt;/li&gt;
&lt;li&gt;添加新的slave【斯累夫】或者当发生故障需要将master【马斯特】身份或者角色迁移到slave【斯累夫】上时，都无需考虑是哪一个二进制日志以及哪个position【珀谁申】值，极大简化了相关操作&lt;/li&gt;
&lt;li&gt;GTIDs是完全基于事务的，因此不支持MYISAM【迈-艾塞姆】存储引擎&lt;/li&gt;
&lt;li&gt;GTID由source【索尔斯】_id和transaction【穿插神】_id组成：&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;1）source【索尔斯】_id来自于server【涩·沃】_uuid,可以在auto【奥特欧】.cnf中看到
2）transaction【穿插神】_id是一个序列数字，自动生成.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;使用GTIDs的限制条件有哪些？&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;不支持非事务引擎（MyISAM【迈-艾塞姆】），因为可能会导致多个gtid分配给同一个事务&lt;/li&gt;
&lt;li&gt;create【克瑞特】 table【忒-部】 ... select【涩莱克特】 语句不支持（主库语法报错）&lt;/li&gt;
&lt;li&gt;create【克瑞特】/drop temporary table【忒-部】 语句不支持&lt;/li&gt;
&lt;li&gt;必须使用enforce【因佛尔斯】-gtid-consistency【肯西斯腾西】参数&lt;/li&gt;
&lt;li&gt;sql-slave【斯累夫】-skip-counter【坑俀】不支持(传统的跳过错误方式)&lt;/li&gt;
&lt;li&gt;GTID复制环境中必须要求统一开启和GTID或者关闭GTID&lt;/li&gt;
&lt;li&gt;在mysql 5.6.7之前，使用mysql_upgrade【阿普格瑞德】   命令会出现问题&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2、基于GTIDs的主从复制&lt;/h3&gt;
&lt;p&gt;在生产环境中，大多数情况下使用的MySQL5.6基本上都是从5.5或者更低的版本升级而来，这就意味着之前的mysql replication【瑞普利K申】方案是基于传统的方式部署，并且已经在运行，因此，接下来我们就利用已有的环境升级至基于GITDs的Replication【瑞普利K申】&lt;/p&gt;
&lt;p&gt;思路：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;修改配置文件支持GTIDs (主+从)&lt;/li&gt;
&lt;li&gt;重启数据库 (主+从)&lt;/li&gt;
&lt;li&gt;为了保证数据一致性，master【马斯特】和slave【斯累夫】设置为只读模式 (主+从)&lt;/li&gt;
&lt;li&gt;从服务器上重新配置同步 （从）&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3、基于GTIDs的主从复制实践&lt;/h3&gt;
&lt;h4&gt;①修改配置文件支持GTIDs&lt;/h4&gt;
&lt;p&gt;MASTER【马斯特】 =&amp;gt; my.cnf&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vim my.cnf
...
gtid_mode【眸的】=on
log_slave【斯累夫】_updates【阿普 dei 茨】=1
enforce【因佛尔斯】_gtid_consistency【肯西斯腾西】

# gtid_mode=on
# log_slave_updates=1
# enforce_gtid_consistency=on
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SLAVE【斯累夫】 =&amp;gt; my.cnf&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#rm -rf data/binlog【宾-劳格】.*
# vim my.cnf
...
log_bin=/usr/local/mysql/data/binlog【宾-劳格】 =&amp;gt; 必须要开启二进制  
gtid_mode【眸的】=on
log_slave【斯累夫】_updates【阿普 dei 茨】=1
enforce【因佛尔斯】_gtid_consistency【肯西斯腾西】
skip_slave【斯累夫】_start【s 达儿】 =&amp;gt;当MASTER【马斯特】主服务器GTIDs没有启动时，跳过SLAVE【斯累夫】服务器的启动

# [root@slave ~]# rm -rf /usr/local/mysql/data/binlog.*
# [root@slave ~]# cat /usr/local/mysql/my.cnf 
# [mysqld]
# ...... 
# log_bin=/usr/local/mysql/data/binlog
# gtid_mode=on
# log_slave_updates=1
# enforce_gtid_consistency
# skip_slave_start
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;说明：
1）开启GITDs需要在master【马斯特】和slave【斯累夫】上都配置gtid-mode【眸的】，log-bin，log-slave【斯累夫】-updates【阿普 dei 茨】，enforce【因佛尔斯】-gtid-consistency【肯西斯腾西】（该参数在5.6.9之前是--disable【滴 s 步】-gtid-unsafe【安 谁夫】-statement【斯忒特门特】）
2）其次，slave【斯累夫】还需要增加skip-slave【斯累夫】-start【s 达儿】参数,目的是启动的时候，先不要把 slave【斯累夫】起来，需要做一些配置
3）基于GTIDs复制从服务器必须开启二进制日志！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;②重新启动mysqld服务&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;#service【瑟为斯】 mysqld restart【 率 s 达r】

# [root@master/slave ~]# service mysqld restart
# Shutting down MySQL.. SUCCESS! 
# Starting MySQL. SUCCESS!
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;③主从配置只读模式（配置切换期间，防止用户意外写入从库导致数据混乱）&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; set【赛特】 @@global【格喽部】.read【滤德】_only【欧利】=ON;

# mysql&amp;gt; set @@global.read_only=ON;
# Query OK, 0 rows affected (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;④SLAVE【斯累夫】重新配置change【趁(chèn)吉】 master【马斯特】 to&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; stop【 s 多】 slave【斯累夫】;
mysql &amp;gt; reset【瑞 赛特】 slave【斯累夫】;
mysql &amp;gt; change【趁(chèn)吉】 master【马斯特】 to master【马斯特】_host=&apos;192.168.20.50&apos;,master【马斯特】_user=&apos;slave【斯累夫】&apos;,master【马斯特】_password【帕斯沃德】=&apos;123&apos;,master【马斯特】_port【破特】=3306,master【马斯特】_auto【奥特欧】_position【珀谁申】=1;
注意：
1、确保有复制用户
2、主要区别于传统复制的参数是：
change【趁(chèn)吉】 master【马斯特】 to master【马斯特】_host=&apos;192.168.20.50&apos;,master【马斯特】_user=&apos;slave【斯累夫】&apos;,master【马斯特】_password【帕斯沃德】=&apos;123&apos;,master【马斯特】_port【破特】=3306,master【马斯特】_auto【奥特欧】_position【珀谁申】=1;
mysql &amp;gt; start【s 达儿】 slave【斯累夫】;
mysql &amp;gt; show【瘦】 slave【斯累夫】 status【 斯dèi 特斯】\G

# mysql&amp;gt; stop slave;
# Query OK, 0 rows affected, 1 warning (0.00 sec)
# 
# mysql&amp;gt; reset slave;
# Query OK, 0 rows affected (0.30 sec)
# 
# mysql&amp;gt; change master to master_host=&apos;192.168.88.50&apos;,master_user=&apos;slave&apos;,master_password=&apos;123&apos;,master_port=3306,master_auto_position=1;
# Query OK, 0 rows affected, 2 warnings (0.66 sec)
# 
# mysql&amp;gt; start slave;
# Query OK, 0 rows affected (0.02 sec)
# 
# mysql&amp;gt; show slave status\G
# *************************** 1. row ***************************
# Slave_IO_State: Waiting for master to send event
# Master_Host: 192.168.88.50
# Master_User: slave
# Master_Port: 3306
# Connect_Retry: 60
# Master_Log_File: binlog.000006
# Read_Master_Log_Pos: 194
# Relay_Log_File: relaylog.000004
# Relay_Log_Pos: 401
# Relay_Master_Log_File: binlog.000006
# Slave_IO_Running: Yes
# Slave_SQL_Running: Yes
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;⑤关闭主从服务器的只读模式（恢复主从服务器写入权限）&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; set【赛特】 @@global【格喽部】.read【滤德】_only【欧利】=OFF;

# mysql&amp;gt; set @@global.read_only=OFF;
# Query OK, 0 rows affected (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;⑥设置slave同步自动重连&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[mysqld]
...
# 取消跳过启动
# skip_slave_start=1

# 添加自动重连
relay_log_recovery = ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;测试验证（往主服务器在写入部分数据，验证一下）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; insert【因涩特】 into【因兔】 db_fq.tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;j&apos;);
mysql&amp;gt; select【涩莱克特】 * from【弗乱】 db_fq.tb_student【tb_斯丢等特】;

# mysql&amp;gt; insert into db_fq.tb_sutdent values (null,null,null,&apos;男&apos;,&apos;ui&apos;);
# Query OK, 1 row affected (0.11 sec)
# 
# mysql&amp;gt; select * from db_fq.tb_sutdent;
# +----+------+------+--------+---------+
# | id | name | age  | gender | subject |
# +----+------+------+--------+---------+
# |  1 | NULL | NULL | 男     | ui      |
# +----+------+------+--------+---------+
# 1 row in set (0.01 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4、SLAVE【斯累夫】从服务器不小心写入数据解决方案&lt;/h3&gt;
&lt;p&gt;方法一：重新同步data目录，重新change【趁(chèn)吉】 master【马斯特】 to...
方法二：跳过事务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;指定需要跳过的GTIDs编号
SET【赛特】 GTID_NEXT=&apos;aaa-bbb-ccc-ddd:N&apos;;
开始一个空事务
BEGIN;
COMMIT;
使用下一个自动生成的全局事务ID。
SET【赛特】 GTID_NEXT=&apos;AUTOMATIC&apos;;
举例说明：
insert【因涩特】 into【因兔】 db_fq.tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;h&apos;);
SET【赛特】 @@SESSION.GTID_NEXT= &apos;23e8dd07-b12d-11ee-bcfa-000c29e151df:3&apos;/*!*/;
mysql &amp;gt; stop【 s 多】 slave【斯累夫】;
mysql &amp;gt; SET【赛特】 @@SESSION.GTID_NEXT= &apos;23e8dd07-b12d-11ee-bcfa-
000c29e151df:4&apos;/*!*/;
mysql &amp;gt; BEGIN;
mysql &amp;gt; commit;
mysql &amp;gt; SET【赛特】 @@SESSION.GTID_NEXT= &apos;AUTOMATIC&apos;;
mysql &amp;gt; start【s 达儿】 slave【斯累夫】;
mysql &amp;gt; show【瘦】 slave【斯累夫】 status【 斯dèi 特斯】\G
说明：需要跳过哪个事务，需要手动查看relay【瑞雷】log文件得到
#mysqlbinlog【宾-劳格】 relay【瑞雷】log.000002
# at 624
#240116 15:25:35 server id 10 end_log_pos 522 CRC32 0xb1e9834d GTID
last_committed=1 sequence_number=2 rbr_only【欧利】=yes
/*!50718 SET【赛特】 TRANSACTION ISOLATION LEVEL【列沃】 READ COMMITTED*//*!*/;
SET【赛特】 @@SESSION.GTID_NEXT= &apos;23e8dd07-b12d-11ee-bcfa-000c29e151df:3&apos;/*!*/;
# at 689
#240116 15:25:35 server id 10 end_log_pos 590 CRC32 0x66bee6ef Query
thread【素瑞德】_id=2 exec_time=0 error_code=0
SET【赛特】 TIMESTAMP=1705389935/*!*/;
BEGIN

&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;day07-半同步复制与MHA高可用架构设计&lt;/h1&gt;
&lt;h2&gt;一、半同步复制&lt;/h2&gt;
&lt;h3&gt;1、什么是半同步复制&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112634720.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;所谓的半同步复制就是master【马斯特】每commit【肯米特】一个事务(简单来说就是做一个改变数据的操作）,要确保slave【斯累夫】接受完主服务器发送的binlog【宾-劳格】日志文件并写入到自己的中继日志relay【瑞雷】 log里，然后会给master【马斯特】信号，告诉对方已经接收完毕，这样master【马斯特】才能把事物成功commit【肯米特】。这样就保证了master【马斯特】-slave【斯累夫】的数据绝对的一致（但是以牺牲master【马斯特】的性能为代价).但等待时间也是可以调整的。&lt;/p&gt;
&lt;h3&gt;2、半同步复制的基本实现&lt;/h3&gt;
&lt;h4&gt;第一步：准备一套M-S的主从架构（建议使用基于GTIDs架构设计）&lt;/h4&gt;
&lt;h4&gt;第二步：给MASTER【马斯特】与SLAVE【斯累夫】安装插件plugin【普辣 京(白话)】&lt;/h4&gt;
&lt;p&gt;MASTER【马斯特】:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; install【因-斯多​】 plugin【普辣 京(白话)】 rpl_semi【射米】_sync【xing(4声)可】_master【马斯特】 soname【搜 内姆】 &apos;semisync【射米 xing(4声)可】_master【马斯特】.so【搜】&apos;;
mysql&amp;gt; show【瘦】 global【格喽部】 variables【wèi 利 bóu 斯】 like【赖特】 &apos;rpl_semi【射米】_sync【xing(4声)可】%&apos;;

# mysql&amp;gt; install plugin rpl_semi_sync_master soname &apos;semisync_master.so&apos;;
# 
# Query OK, 0 rows affected (0.14 sec)
# 
# mysql&amp;gt; show global variables like &apos;rpl_semi_sync%&apos;;
# +-------------------------------------------+------------+
# | Variable_name                             | Value      |
# +-------------------------------------------+------------+
# | rpl_semi_sync_master_enabled              | OFF        |
# | rpl_semi_sync_master_timeout              | 10000      |
# | rpl_semi_sync_master_trace_level          | 32         |
# | rpl_semi_sync_master_wait_for_slave_count | 1          |
# | rpl_semi_sync_master_wait_no_slave        | ON         |
# | rpl_semi_sync_master_wait_point           | AFTER_SYNC |
# +-------------------------------------------+------------+
# 6 rows in set (0.01 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SLAVE【斯累夫】:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; install【因-斯多​】 plugin【普辣 京(白话)】 rpl_semi【射米】_sync【xing(4声)可】_slave【斯累夫】 soname【搜 内姆】 &apos;semisync【射米 xing(4声)可】_slave【斯累夫】.so【搜】&apos;;
mysql&amp;gt; show【瘦】 global【格喽部】 variables【wèi 利 bóu 斯】 like【赖特】 &apos;rpl_semi【射米】_sync【xing(4声)可】%&apos;;

# mysql&amp;gt; install plugin rpl_semi_sync_slave soname &apos;semisync_slave.so&apos;;
# Query OK, 0 rows affected (0.13 sec)
# 
# mysql&amp;gt; show global variables like &apos;rpl_semi_sync%&apos;;
# +---------------------------------+-------+
# | Variable_name                   | Value |
# +---------------------------------+-------+
# | rpl_semi_sync_slave_enabled     | OFF   |
# | rpl_semi_sync_slave_trace_level | 32    |
# +---------------------------------+-------+
# 2 rows in set (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第三步：激活MASTER【马斯特】与SLAVE【斯累夫】服务器中的半同步复制插件&lt;/h4&gt;
&lt;p&gt;MASTER【马斯特】：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; set【赛特】 global【格喽部】 rpl_semi【射米】_sync【xing(4声)可】_master【马斯特】_enabled【伊内部特】=on【昂】;
mysql&amp;gt; show【瘦】 global【格喽部】 variables【wèi 利 bóu 斯】 like【赖特】 &apos;rpl_semi【射米】_sync【xing(4声)可】%&apos;;

# mysql&amp;gt; set global rpl_semi_sync_master_enabled=on;
# Query OK, 0 rows affected (0.00 sec)
# 
# mysql&amp;gt; show global variables like &apos;rpl_semi_sync%&apos;;
# +-------------------------------------------+------------+
# | Variable_name                             | Value      |
# +-------------------------------------------+------------+
# | rpl_semi_sync_master_enabled              | ON         |
# | rpl_semi_sync_master_timeout              | 10000      |
# | rpl_semi_sync_master_trace_level          | 32         |
# | rpl_semi_sync_master_wait_for_slave_count | 1          |
# | rpl_semi_sync_master_wait_no_slave        | ON         |
# | rpl_semi_sync_master_wait_point           | AFTER_SYNC |
# +-------------------------------------------+------------+
# 6 rows in set (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SLAVE【斯累夫】：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; set【赛特】 global【格喽部】 rpl_semi【射米】_sync【xing(4声)可】_slave【斯累夫】_enabled【伊内部特】=on【昂】;
mysql&amp;gt; show【瘦】 global【格喽部】 variables【wèi 利 bóu 斯】 like【赖特】 &apos;rpl_semi【射米】_sync【xing(4声)可】%&apos;;

# mysql&amp;gt; set global rpl_semi_sync_slave_enabled=on;
# Query OK, 0 rows affected (0.00 sec)
# 
# mysql&amp;gt; show global variables like &apos;rpl_semi_sync%&apos;;
# +---------------------------------+-------+
# | Variable_name                   | Value |
# +---------------------------------+-------+
# | rpl_semi_sync_slave_enabled     | ON    |
# | rpl_semi_sync_slave_trace_level | 32    |
# +---------------------------------+-------+
# 2 rows in set (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第四步：在SLAVE【斯累夫】服务器中重启IO线程&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; stop【 s 多】 slave【斯累夫】 IO_THREAD【素瑞德】;
MYSQL &amp;gt; START【s 达儿】 SLAVE【斯累夫】 IO_THREAD【素瑞德】;

# mysql&amp;gt; stop slave IO_THREAD;
# Query OK, 0 rows affected (0.02 sec)
# 
# mysql&amp;gt; start slave IO_THREAD;
# Query OK, 0 rows affected (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第五步：测试验证半同步复制&lt;/h4&gt;
&lt;p&gt;注意：当slave【斯累夫】从库的IO_Thread【素瑞德】 线程将binlog【宾-劳格】日志接受完毕后，要给master【马斯特】一个确认，如果超过10s未收到slave【斯累夫】的接收确认信号，那么就会自动转换为传统的异步复制模式。&lt;/p&gt;
&lt;h5&gt;①master【马斯特】插入一条记录，查看slave【斯累夫】是否有成功返回&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; insert【因涩特】 into【因兔】 db_fq.tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;k&apos;);
mysql&amp;gt; show【瘦】 global【格喽部】 status【 斯dèi 特斯】 like【赖特】 &apos;rpl_semi【射米】_sync【xing(4声)可】%_yes_tx&apos;;
+-----------------------------------------------------------+-------+
| Variable【V啊伊部】_name【内母】                            | Value |
+-----------------------------------------------------------+-------+
| Rpl_semi【射米】_sync【xing(4声)可】_master【马斯特】_yes_tx | 2     |
表示这次事务成功从slave【斯累夫】返回一次确认信息
该值表示 ​​主库已成功通过半同步复制提交的事务数量​​
自 MySQL 启动以来，已有 2 个事务​​ 被至少一个从库确认接收
+-----------------------------------------------------------+-------+
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;说明：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;状态变量&lt;/th&gt;
&lt;th&gt;含义&lt;/th&gt;
&lt;th&gt;健康值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rpl_semi_sync_master_yes_tx&lt;/td&gt;
&lt;td&gt;半同步成功的事务数&lt;/td&gt;
&lt;td&gt;​​持续增长​&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rpl_semi_sync_master_no_tx&lt;/td&gt;
&lt;td&gt;超时降级为异步的事务数&lt;/td&gt;
&lt;td&gt;接近0​&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rpl_semi_sync_master_status&lt;/td&gt;
&lt;td&gt;半同步功能状态&lt;/td&gt;
&lt;td&gt;ON&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rpl_semi_sync_master_clients&lt;/td&gt;
&lt;td&gt;连接的半同步从库数&lt;/td&gt;
&lt;td&gt;≥1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;# mysql&amp;gt; insert into db_fq.tb_student values (null,null,null,&apos;男&apos;,&apos;ui&apos;);
# Query OK, 1 row affected (0.12 sec)
# 
# mysql&amp;gt; show global status like &apos;rpl_semi_sync%_yes_tx&apos;;
# +-----------------------------+-------+
# | Variable_name               | Value |
# +-----------------------------+-------+
# | Rpl_semi_sync_master_yes_tx | 4     |
# +-----------------------------+-------+
# 1 row in set (0.01 sec)
# 
# 该值表示 ​​主库已成功通过半同步复制提交的事务数量​​
# 自 MySQL 启动以来，已有 4 个事务​​ 被至少一个从库确认接收
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;②模拟SLAVE【斯累夫】服务器故障&lt;/h5&gt;
&lt;p&gt;SLAVE【斯累夫】：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#service【瑟为斯】 mysqld stop【 s 多】
# [root@slave ~]# service mysqld stop
# Shutting down MySQL... SUCCESS! 
# [root@slave ~]# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;MASTER【马斯特】&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; insert【因涩特】 into【因兔】 db_fq.tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;m&apos;);
默认等待10s时间
mysql&amp;gt; insert【因涩特】 into【因兔】 db_fq.tb_student【tb_斯丢等特】 values【挖柳斯】 (null【nò】,&apos;n&apos;);
现在自动转变了原来的异步模式
# mysql&amp;gt; insert into db_fq.tb_student values (null,&apos;m&apos;,null,&apos;男&apos;,&apos;ui&apos;);
# Query OK, 1 row affected (10.14 sec)
# 
# mysql&amp;gt; insert into db_fq.tb_student values (null,&apos;n&apos;,null,&apos;男&apos;,&apos;ui&apos;);
# Query OK, 1 row affected (0.12 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;③重新启动半同步复制&lt;/h5&gt;
&lt;p&gt;SLAVE【斯累夫】：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#service【瑟为斯】 mysqld start【s 达儿】
#mysql -P 3310 -p
mysql &amp;gt; set【赛特】 global【格喽部】 rpl_semi【射米】_sync【xing(4声)可】_slave【斯累夫】_enabled【伊内部特】=on【昂】;
mysql &amp;gt; stop【 s 多】 slave【斯累夫】 IO_THREAD【素瑞德】;
MYSQL &amp;gt; START【s 达儿】 SLAVE【斯累夫】 IO_THREAD【素瑞德】;

# [root@slave ~]# service mysqld start 
# Starting MySQL. SUCCESS! 
# [root@slave ~]# mysql -uroot -p
# Enter password: 
# ......
# mysql&amp;gt; set global rpl_semi_sync_slave_enabled=on;
# Query OK, 0 rows affected (0.00 sec)
# 
# mysql&amp;gt; stop slave IO_THREAD;
# Query OK, 0 rows affected, 1 warning (0.00 sec)
# 
# mysql&amp;gt; start slave IO_THREAD;
# Query OK, 0 rows affected (0.00 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;master【马斯特】需要等到slave【斯累夫】确认后才能提交，如果等不到确认消息，master【马斯特】等到10s钟后自动变成异步模式；slave【斯累夫】启动后，master【马斯特】上改变的数据还是会自动复制过来，数据又会回到一致。&lt;/p&gt;
&lt;h5&gt;常见故障&lt;/h5&gt;
&lt;p&gt;当重启半同步复制之后，发现数据没有同步过来，大多数情况下都是GTIDs复制没有配置自启动，导致重启服务后同步失效&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
mysql&amp;gt; show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.88.50
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000011
          Read_Master_Log_Pos: 1444
               Relay_Log_File: relaylog.000019
                Relay_Log_Pos: 445
        Relay_Master_Log_File: binlog.000011
             Slave_IO_Running: No
            Slave_SQL_Running: No


[root@slave ~]# vim /usr/local/mysql/my.cnf
[mysqld]
...
# 取消跳过启动
# skip_slave_start=1

# 添加自动重连
relay_log_recovery = ON
master_info_repository = TABLE
relay_log_info_repository = TABLE

之后重新配置半同步设置
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3、等待时间的修改（默认10s）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; show【瘦】 global【格喽部】 variables【wèi 利 bóu 斯】 like【赖特】 &apos;rpl_semi【射米】_sync【xing(4声)可】%&apos;;
mysql&amp;gt; set【赛特】 global【格喽部】 rpl_semi【射米】_sync【xing(4声)可】_master【马斯特】_timeout【泰毛特】=3600000;
+------------------------------------------------------------------------------------------------------------+---------------------------+
| Variable【V啊伊部】_name【内母】                                                                             | Value                     |
+------------------------------------------------------------------------------------------------------------+---------------------------+
| rpl_semi【射米】_sync【xing(4声)可】_master【马斯特】_enabled【伊内部特】                                      | ON【昂】                   |
| rpl_semi【射米】_sync【xing(4声)可】_master【马斯特】_timeout【泰毛特】                                        | 3600000                   |
| rpl_semi【射米】_sync【xing(4声)可】_master【马斯特】_trace【崔丝】_level【列沃】                               | 32                        |
| rpl_semi【射米】_sync【xing(4声)可】_master【马斯特】_wait【威特】_for【fò】_slave【斯累夫】_count【kàn特】   | 1                         |
| rpl_semi【射米】_sync【xing(4声)可】_master【马斯特】_wait【威特】_no_slave【斯累夫】                           | ON【昂】                   |
| rpl_semi【射米】_sync【xing(4声)可】_master【马斯特】_wait【威特】_point【破因特】                              | AFTER【啊夫特】_SYNC【xing(4声)可】  |
+------------------------------------------------------------------------------------------------------------+---------------------------+
6 rows in set【赛特】 (0.00 sec)


# mysql&amp;gt; set global rpl_semi_sync_master_timeout=3600000;
# Query OK, 0 rows affected (0.00 sec)
# 
# mysql&amp;gt; show global variables like &apos;rpl_semi_sync%&apos;;
# +-------------------------------------------+------------+
# | Variable_name                             | Value      |
# +-------------------------------------------+------------+
# | rpl_semi_sync_master_enabled              | ON         |
# | rpl_semi_sync_master_timeout              | 3600000    |
# | rpl_semi_sync_master_trace_level          | 32         |
# | rpl_semi_sync_master_wait_for_slave_count | 1          |
# | rpl_semi_sync_master_wait_no_slave        | ON         |
# | rpl_semi_sync_master_wait_point           | AFTER_SYNC |
# +-------------------------------------------+------------+
# 6 rows in set (0.00 sec)
# 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4、卸载半同步复制插件&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select【涩莱克特】 plugin【普辣 京(白话)】_name,load【漏德】_option【阿普申】 from【弗乱】 information【因弗梅申】_schema【斯基么】.plugins【普辣 京(白话)】; 获取插件名称
mysql &amp;gt; uninstall【安 因-斯多​】 plugin【普辣 京(白话)】 插件名称;

# mysql&amp;gt; select plugin_name,load_option from information_schema.plugins;
# +----------------------------+-------------+
# | plugin_name                | load_option |
# +----------------------------+-------------+
# | binlog                     | FORCE       |
# | mysql_native_password      | FORCE       |
# | sha256_password            | FORCE       |
# | PERFORMANCE_SCHEMA         | FORCE       |
# | MEMORY                     | FORCE       |
# | ...............                          |
# | CSV                        | FORCE       |
# | MyISAM                     | FORCE       |
# | partition                  | ON          |
# | FEDERATED                  | OFF         |
# | BLACKHOLE                  | ON          |
# | ARCHIVE                    | ON          |
# | ngram                      | ON          |
# | rpl_semi_sync_master       | ON          |
# +----------------------------+-------------+
# 45 rows in set (0.00 sec)
# 
# mysql&amp;gt; uninstall plugin rpl_semi_sync_master;
# ERROR 1883 (HY000): Plugin &apos;rpl_semi_sync_master&apos; cannot be uninstalled now. Stop any active semisynchronous slaves of this master first.
# mysql&amp;gt;  #因为半同步服务还在运行所有卸载失败
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;卸载插件步骤：需先获取插件名称
步骤一：先停止slave【斯累夫】的IO线程
mysql&amp;gt; stop【 s 多】 slave【斯累夫】 IO_THREAD【素瑞德】;
步骤二：卸载slave【斯累夫】的插件
mysql&amp;gt; uninstall【安 因-斯多​】 plugin【普辣 京(白话)】 rpl_semi【射米】_sync【xing(4声)可】_slave【斯累夫】;
步骤三：将master【马斯特】插件状态改为off
mysql&amp;gt; set【赛特】 global【格喽部】 rpl_semi【射米】_sync【xing(4声)可】_master【马斯特】_enabled【伊内部特】=off;
步骤四：卸载master【马斯特】的插件
mysql&amp;gt; uninstall【安 因-斯多​】 plugin【普辣 京(白话)】 rpl_semi【射米】_sync【xing(4声)可】_master【马斯特】;

# slave服务器操作
# mysql&amp;gt; stop slave IO_THREAD;
# Query OK, 0 rows affected (0.06 sec)
# 
# mysql&amp;gt; uninstall plugin rpl_semi_sync_slave;
# Query OK, 0 rows affected (0.06 sec)
# 
# master服务器操作
# mysql&amp;gt; set global rpl_semi_sync_master_enabled=off;
# Query OK, 0 rows affected (0.01 sec)
# 
# mysql&amp;gt; uninstall plugin rpl_semi_sync_master;
# Query OK, 0 rows affected (0.05 sec)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;补充：mysqld重启后，需要手工启动主从同步&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#service【瑟为斯】 mysqld stop【 s 多】
#service【瑟为斯】 mysqld start【s 达儿】
#mysql -P 3310 -p
mysql &amp;gt; show【瘦】 slave【斯累夫】 status【 斯dèi 特斯】\G
Slav【斯累夫】e_IO_Running【乱宁】: No
Slave【斯累夫】_SQL_Running【乱宁】: No
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;出现以上情况代表mysqld重启后，主从同步也会随之关闭，需要手工启动&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; start【s 达儿】 slave【斯累夫】;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;二、MHA任务背景&lt;/h2&gt;
&lt;h3&gt;1、真实案例&lt;/h3&gt;
&lt;p&gt;公司现在需要做MySQL数据库迁移，之前数据库是一主两从，使用MHA做了高可用，跑在私有云平台，现在需要这三台数据库迁移到物理机上，而且云上的数据库正在跑，希望做到热迁移，即不影响业务的情况下，把现有数据库从私有云平台迁移到物理真机上。&lt;/p&gt;
&lt;h3&gt;2、需要掌握的技术&lt;/h3&gt;
&lt;p&gt;①熟悉MHA高可用的原理和部署
②掌握MySQL数据库的迁移
③熟悉MySQL主从复制的模式和搭建（基于GTIDs）&lt;/p&gt;
&lt;h2&gt;三、MHA简介&lt;/h2&gt;
&lt;h3&gt;1、什么是MHA&lt;/h3&gt;
&lt;p&gt;MHA（Master【马斯特】 High【嗨】 Availability【呃维勒倍勒提】）目前在MySQL高可用方面是一个相对成熟的解决方案，它由日本DeNA公司youshimaton【哟西马通】（现就职于Facebook【非斯步可】公司）开发，是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。在MySQL故障切换过程中，MHA能做到在0~30秒之内自动完成数据库的故障切换操作，并且在进行故障切换的过程中，MHA能在较大程度上保证数据的一致性，以达到真正意义上的高可用。&lt;/p&gt;
&lt;h3&gt;2、MHA工作原理&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112820554.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;当master【马斯特】出现故障时，通过对比slave【斯累夫】之间I/O线程读取master【马斯特】上binlog【宾-劳格】的位置，选取最接近的slave【斯累夫】做为最新的slave【斯累夫】（latest【累提斯特】 slave【斯累夫】）。&lt;/li&gt;
&lt;li&gt;其它slave【斯累夫】通过与latest【累提斯特】 slave【斯累夫】对比生成差异中继日志，并应用。&lt;/li&gt;
&lt;li&gt;在latest【累提斯特】 slave【斯累夫】上应用从master【马斯特】保存的binlog【宾-劳格】，同时将latest【累提斯特】  slave【斯累夫】提升为master【马斯特】。&lt;/li&gt;
&lt;li&gt;最后在其它slave【斯累夫】上应用相应的差异中继日志并开始从新的master【马斯特】开始复制.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3、MHA组件&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;MHA Manager【面尼杰额】(管理节点)
MHA Manager【面尼杰额】可以单独部署在一台独立的机器上管理多个master【马斯特】-slave【斯累夫】集群，也可以部署在一台slave【斯累夫】节点上。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MHA Node【NO 德】（数据节点）
MHA Node【NO 德】运行在每台MySQL服务器上，MHA Manager【面尼杰额】会定时探测集群中的master【马斯特】节点，当master【马斯特】出现故障时，它可以自动将数据的slave【斯累夫】提升为新的master【马斯特】，然后将所有其他的slave【斯累夫】重新指向新的master【马斯特】。整个故障转移过程对应用程序完全透明。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4、MHA组件介绍&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;MHA Manager【面尼杰额】
运行一些工具，比如masterha【马斯特-哈】_Manager【面尼杰额】工具实现自动监控MySQL Master【马斯特】和实现master【马斯特】故障切换，其它工具手动实现master【马斯特】故障切换、在线master【马斯特】转移、连接检查等等。一个Manager【面尼杰额】可以管理多 个master【马斯特】-slave【斯累夫】集群&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MHA Node【NO 德】
部署在所有运行MySQL的服务器上，无论是master【马斯特】还是slave【斯累夫】。主要有三个作用：
1）保存二进制日志
如果能够访问故障master【马斯特】，会拷贝master【马斯特】的二进制日志
2）应用差异中继日志
从拥有最新数据的slave【斯累夫】上生成差异中继日志，然后应用差异日志。
3）清除中继日志
在不停止SQL线程的情况下删除中继日志&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5、MHA工具介绍&lt;/h3&gt;
&lt;p&gt;(一) Manager【面尼杰额】工具&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;工具&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;masterha【马斯特-哈】_check【切克】_ssh&lt;/td&gt;
&lt;td&gt;检查MHA的SSH配置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;masterha【马斯特-哈】_check【切克】_repl&lt;/td&gt;
&lt;td&gt;检查MySQL复制&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;masterha【马斯特-哈】_manager【面尼杰额】&lt;/td&gt;
&lt;td&gt;启动MHA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;masterha【马斯特-哈】_check【切克】_status【 斯dèi 特斯】&lt;/td&gt;
&lt;td&gt;检测当前MHA运行状态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;masterha【马斯特-哈】_master【马斯特】_monitor【魔尼特】&lt;/td&gt;
&lt;td&gt;监测master【马斯特】是否宕机&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;masterha【马斯特-哈】_master【马斯特】_switch【斯微曲】&lt;/td&gt;
&lt;td&gt;控制故障转移(自动或手动)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;masterha【马斯特-哈】_conf【坑富】_host&lt;/td&gt;
&lt;td&gt;添加或删除配置的server【涩·沃】信息&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;(二) Node【NO 德】工具&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;工具&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;save【C 符】_binary【拜讷瑞】_logs&lt;/td&gt;
&lt;td&gt;保存和复制master【马斯特】的二进制日志&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;apply【阿普来】_di_relay【瑞雷】_logs&lt;/td&gt;
&lt;td&gt;识别差异的中继日志事件并应用于其它slave【斯累夫】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;lter【诶特】_mysqlbinlog【宾-劳格】&lt;/td&gt;
&lt;td&gt;去除不必要的ROLLBACK【柔拜克】事件(MHA已不再使用这个工具)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;purge【pò取】_relay【瑞雷】_logs&lt;/td&gt;
&lt;td&gt;清除中继日志(不会阻塞SQL线程)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;注意：Node【NO 德】这些工具通常由MHA Manager【面尼杰额】的脚本触发,无需人手操作。&lt;/p&gt;
&lt;h2&gt;四、MHA部署架构&lt;/h2&gt;
&lt;h3&gt;1、部署规划&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;角色&lt;/th&gt;
&lt;th&gt;IP&lt;/th&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;server【涩·沃】-id&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;备注&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MHA-Manager【面尼杰额】&lt;/td&gt;
&lt;td&gt;192.168.20.40&lt;/td&gt;
&lt;td&gt;mha.it.cn&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;管理节点&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MHA-Node【NO 德】（Master【马斯特】）&lt;/td&gt;
&lt;td&gt;192.168.20.10&lt;/td&gt;
&lt;td&gt;master【马斯特】.it.cn&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;数据节点&lt;/td&gt;
&lt;td&gt;写&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MHA-Node【NO 德】（Slave【斯累夫】1）&lt;/td&gt;
&lt;td&gt;192.168.20.20&lt;/td&gt;
&lt;td&gt;slave【斯累夫】1.it.cn&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;数据节点&lt;/td&gt;
&lt;td&gt;读&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MHA-Node【NO 德】（Slave【斯累夫】2）&lt;/td&gt;
&lt;td&gt;192.168.20.30&lt;/td&gt;
&lt;td&gt;slave【斯累夫】2.it.cn&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;数据节点&lt;/td&gt;
&lt;td&gt;读&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;2、系统和软件版本&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;系统版本&lt;/th&gt;
&lt;th&gt;MySQL版本&lt;/th&gt;
&lt;th&gt;MHA版本&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CentOS7.6&lt;/td&gt;
&lt;td&gt;MySQL-5.7.31&lt;/td&gt;
&lt;td&gt;mha4mysql-manager【面尼杰额】-0.57 mha4mysql-node【NO 德】-0.57&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;3、系统环境初始化&lt;/h3&gt;
&lt;p&gt;第一步：克隆机器，首先启动MASTER【马斯特】，然后在一次启动SLAVE【斯累夫】1、SLAVE【斯累夫】2以及MHA&lt;/p&gt;
&lt;p&gt;第二步：更改计算机的主机名称&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 master【马斯特】.it.cn
#su
#hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 slave【斯累夫】1.it.cn
#su
#hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 slave【斯累夫】2.it.cn
#su
#hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 mha.it.cn
#su
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第三步：更改IP地址以及绑定主机名称及IP地址到/ets/hosts文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#vim /etc/sysconfig【西斯肯菲格】/network【孽特 - 沃克】-scripts【斯贵 普茨】/ifcfg-ens33
...
IPADDR=192.168.20.10 IPADDR=192.168.20.20 IPADDR=192.168.20.30
IPADDR=192.168.20.40
...
## systemctl【西斯屯-ctl】
 stop【 s 多】 NetworkManager【孽特沃克 面尼杰额】
## systemctl【西斯屯-ctl】
 disable【滴 s 步】 NetworkManager【孽特沃克 面尼杰额】
## systemctl【西斯屯-ctl】
 restart【 率 s 达r】 network【孽特 - 沃克】
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用MX连接4台服务器，绑定IP地址与主机名称到/etc/hosts文件中&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#vim /etc/hosts
192.168.20.10 master【马斯特】.it.cn
192.168.20.20 slave1【斯累夫】.it.cn
192.168.20.30 slave2【斯累夫】.it.cn
192.168.20.40 mha.it.cn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第四步：关闭防护墙与SElinux&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;## systemctl【西斯屯-ctl】
 stop【 s 多】 firewalld【fai 额 沃 得】
## systemctl【西斯屯-ctl】
 disable【滴 s 步】 firewalld【fai 额 沃 得】
#setenforce【赛特-因佛尔斯】 0
#vim /etc/selinux/cong
SELINUX=disable【滴 s 步】
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第五步：配置YUM源
基础源（建议使用腾讯源。略）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# yum install【因-斯多​】 wget -y
# mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.cloud.tencent.com/repo/centos7_base.repo
# yum clean【科林恩】 all
# yum makecache
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置epel源&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#wget -O /etc/yum.repos.d/epel.repo http://mirrors.cloud.tencent.com/repo/epel-7.repo
#yum clean【科林恩】 all
#yum makecache
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置本地自建仓库的yum源
①上传mha-yum软件包到/soft【索夫特】/mha目录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#mkdir【摸克跌儿】 -p /soft【索夫特】/mha
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;②配置本地yum源，当我们使用yum时，可以自动找到mha-yum这个仓库目录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#vim /etc/yum.repos.d/local.repo
[mha]
name=mha soft【索夫特】
baseurl=le:///soft【索夫特】/mha/mha-yum
enabled【伊内部特】=1
gpgcheck=0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;测试MHA依赖软件库的安装&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#cd /etc/yum.repos.d/
#mv local.repo local.repo.bak
#yum provides【普歪尺】 createrepo【克瑞特-瑞婆】
#yum install【因-斯多​】 createrepo【克瑞特-瑞婆】 -y
#createrepo【克瑞特-瑞婆】 /soft【索夫特】/mha/mha-yum
#mv local.repo.bak local.repo
#yum clean【科林恩】 all
#yum makecache fast
yum -y install【因-斯多​】 perl-DBD-MySQL \
perl-Cong-Tiny \
perl-Time-HiRes \
perl-Mail-Sender \
perl-Mail-Sendmail \
perl-MIME-Base32 \
perl-MIME-Charset \
perl-MIME-EncWords \
perl-Params-Classify \
perl-Params-Validate.x86_64 \
perl-Log-Dispatch \
perl-Parallel-ForkManager \
net-tools
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第六步：ntpdate时间同步&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#ntpdate 182.92.12.11
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4、部署MySQL主从复制环境&lt;/h3&gt;
&lt;p&gt;数据库安装位置：/usr/local/mysql
数据库的数据目录：/usr/local/mysql/data
套接字文件：/tmp/mysql.sock
端口设置：3306
配置文件位置：/usr/local/mysql/my.cnf （MySQL =&amp;gt; 安装目录下 =&amp;gt; /etc目录下）&lt;/p&gt;
&lt;p&gt;⭐MASTER【马斯特】主服务器
第一步：上传软件到/root目录
第二步：使用脚本安装MySQL软件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@master mysql]# vim mysql.sh
#!/bin/bash
yum install【因-斯多​】 libaio -y
tar -xf mysql-5.7.31-linux-glibc【哥里布C】2.12-x86_64.tar.gz
mv mysql-5.7.31-linux-glibc【哥里布C】2.12-x86_64 /usr/local/mysql
useradd -r -s /sbin/nologin mysql
rm -rf /etc/my.cnf
cd /usr/local/mysql
mkdir【摸克跌儿】 mysql-files
chown【吃-昂】 mysql:mysql mysql-files
chmod【吃-默德】750 mysql-files
bin/mysqld --initialize【因 尼 舍 来斯】 --user=mysql --basedir=/usr/local/mysql &amp;amp;&amp;gt; /root/password【帕斯沃德】.txt
bin/mysql_ssl_rsa_setup --datadir=/usr/local/mysql/data
cp support【瑟破特】-files/mysql.server【涩·沃】 /etc/init.d/mysqld
service【瑟为斯】 mysqld start【s 达儿】
echo &apos;export【e斯 破特】 PATH=$PATH:/usr/local/mysql/bin&apos; &amp;gt;&amp;gt; /etc/profile
source【索尔斯】 /etc/profile
[root@master mysql]# source【索尔斯】 mysql.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第三步：设置MySQL密码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@master mysql]# mysql -p
mysql &amp;gt; set【赛特】 password【帕斯沃德】=&apos;123&apos;
mysql &amp;gt; flush【福 辣 徐】 privileges【P符类 杰 斯】;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第四步：进行安全初始化&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@master mysql]# mysql_secure_installation;【因-斯多 雷申​】
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第五步：编写MSTER主机中的my.cnf配置文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@master mysql]# vim /usr/local/mysql/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
port【破特】=3306
log_error=/usr/local/mysql/data/master【马斯特】.err
log_bin=/usr/local/mysql/data/binlog【宾-劳格】
server【涩·沃】_id=10
character_set【赛特】_server【涩·沃】=utf8mb4
gtid_mode【眸的】=on
log_slave【斯累夫】_updates【阿普 dei 茨】=1
enforce【因佛尔斯】_gtid_consistency【肯西斯腾西】
[root@master mysql]# service【瑟为斯】 mysqld restart【 率 s 达r】

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;⭐SLAVE1【斯累夫】/SLAVE2【斯累夫】从服务器
第一步：上传MySQL软件到服务器端
第二步：使用脚本安装MySQL。但是不需要进行初始化&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vim mysql.sh
#!/bin/bash
yum install【因-斯多​】 libaio -y
tar -xf mysql-5.7.31-linux-glibc【哥里布C】2.12-x86_64.tar.gz
rm -rf /usr/local/mysql
mv mysql-5.7.31-linux-glibc【哥里布C】2.12-x86_64 /usr/local/mysql
useradd -r -s /sbin/nologin mysql
rm -rf /etc/my.cnf
cd /usr/local/mysql
mkdir【摸克跌儿】 mysql-files
chown【吃-昂】 mysql:mysql mysql-files
chmod【吃-默德】750 mysql-files
cp support【瑟破特】-files/mysql.server【涩·沃】 /etc/init.d/mysqld
echo &apos;export【e斯 破特】 PATH=$PATH:/usr/local/mysql/bin&apos; &amp;gt;&amp;gt; /etc/profile
source【索尔斯】 /etc/profile
#source【索尔斯】 mysql.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第三步：使用rsync【啊 xing(4声)可】把MASTER【马斯特】服务器中的data数据目录同步到SLAVE1【斯累夫】与SLAVE2【斯累夫】
MASTER【马斯特】&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#rm -rf /usr/local/mysql/data/auto【奥特欧】.cnf
#rsync【啊 xing(4声)可】 -av /usr/local/mysql/data root@192.168.20.20:/usr/local/mysql/
#rsync【啊 xing(4声)可】 -av /usr/local/mysql/data root@192.168.20.30:/usr/local/mysql/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第四步：给SLAVE1【斯累夫】与SLAVE2【斯累夫】配置my.cnf文件
SLAVE1【斯累夫】：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#vim /usr/local/mysql/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
port【破特】=3306
log_error=/usr/local/mysql/data/slave1【斯累夫】.err
log_bin=/usr/local/mysql/data/binlog【宾-劳格】
relay【瑞雷】_log=/usr/local/mysql/data/relay【瑞雷】log
server【涩·沃】_id=20
character_set【赛特】_server【涩·沃】=utf8mb4
gtid_mode【眸的】=on
log_slave【斯累夫】_updates【阿普 dei 茨】=1
enforce【因佛尔斯】_gtid_consistency【肯西斯腾西】
skip_slave【斯累夫】_start【s 达儿】
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SLAVE2【斯累夫】：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#vim /usr/local/mysql/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
port【破特】=3306
log_error=/usr/local/mysql/data/slave2【斯累夫】.err
log_bin=/usr/local/mysql/data/binlog【宾-劳格】
relay【瑞雷】_log=/usr/local/mysql/data/relay【瑞雷】log
server【涩·沃】_id=30
character_set【赛特】_server【涩·沃】=utf8mb4
gtid_mode【眸的】=on
log_slave【斯累夫】_updates【阿普 dei 茨】=1
enforce【因佛尔斯】_gtid_consistency【肯西斯腾西】
skip_slave【斯累夫】_start【s 达儿】
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置完成后，启动MySQL软件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#service【瑟为斯】 mysql restart【 率 s 达r】
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;⭐配置主从数据同步
第一步：在MASTER【马斯特】服务器中创建一个slave【斯累夫】同步账号&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; create【克瑞特】 user &apos;slave【斯累夫】&apos;@&apos;192.168.20.%&apos; identified【爱-丹-提伐】 by &apos;123&apos;;
mysql &amp;gt; grant【古亮普】 replication【瑞普利K申】 slave【斯累夫】 on *.* to &apos;slave【斯累夫】&apos;@&apos;192.168.20.%&apos;;
mysql &amp;gt; flush【福 辣 徐】 privileges【P符类 杰 斯】;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第二步：创建一个mha账号（方便后期MHA监控主从同步状态）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create【克瑞特】 user &apos;mha&apos;@&apos;192.168.20.40&apos; identified【爱-丹-提伐】 by &apos;123&apos;;
mysql&amp;gt; grant【古亮普】 all【哦】 privileges【P符类 杰 斯】 on *.* to &apos;mha&apos;@&apos;192.168.20.40&apos;;
mysql&amp;gt; flush【福 辣 徐】 privileges【P符类 杰 斯】;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第三步：在SLAVE1【斯累夫】与SLAVE2【斯累夫】中配置主从数据同步&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; change【趁(chèn)吉】 master【马斯特】 to master【马斯特】_host=&apos;192.168.20.10&apos;,master【马斯特】_port【破特】=3306,master【马斯特】_user=&apos;slave【斯累夫】&apos;,master【马斯特】_password【帕斯沃德】=&apos;123&apos;,master【马斯特】_auto【奥特欧】_position【珀谁申】=1;
mysql &amp;gt; start【s 达儿】 slave【斯累夫】;
mysql &amp;gt; show【瘦】 slave【斯累夫】 status【 斯dèi 特斯】\G
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;到此整个一主两从就配置完毕了！&lt;/p&gt;
&lt;h3&gt;5、MHA软件的安装&lt;/h3&gt;
&lt;h4&gt;①不同节点安装软件&lt;/h4&gt;
&lt;p&gt;说明：在所有节点安装mha-node【NO 德】软件包，在mha管理端再安装mha-manager【面尼杰额】软件包&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mha ~]# yum –y install【因-斯多​】 mha4mysql-node【NO 德】-0.57-0.el7.noarch.rpm
[root@master【马斯特】 ~]# yum –y install【因-斯多​】 mha4mysql-node【NO 德】-0.57-0.el7.noarch.rpm
[root@slave1【斯累夫】 ~]# yum -y install【因-斯多​】 mha4mysql-node【NO 德】-0.57-0.el7.noarch.rpm
[root@slave2【斯累夫】 ~]# yum –y install【因-斯多​】 mha4mysql-node【NO 德】-0.57-0.el7.noarch.rpm
[root@mha ~]# yum –y install【因-斯多​】 mha4mysql-manager【面尼杰额】-0.57-0.el7.noarch.rpm
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;如果以及提前安装依赖软件，则大家可以使用rpm -ivh直接安装&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;②配置SSH互信（免密登录）&lt;/h4&gt;
&lt;p&gt;说明：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在生产环境中几乎都是禁止root远程登陆服务器的，所以ssh免密码登陆要在admin用户下进行配置，这是处于安全角度考虑出发。&lt;/li&gt;
&lt;li&gt;admin用户可以是任意普通用户&lt;/li&gt;
&lt;li&gt;该普通用户用于mha的管理节点远程访问mysql复制组中的所有主机，完成一些其他工作&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;第一步：在所有机器上创建一个普通账号admin，密码123&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#useradd admin
#echo 123|passwd --stdin admin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第二步：配置mha主机到其他主机的admin用户互信&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mha端
[root@mha ~]# su - admin
[admin@mha ~]$ ssh-keygen -P &quot;&quot; -f ~/.ssh/id_rsa
[admin@mha ~]$ cd .ssh/
[admin@mha .ssh]$ ls
id_rsa id_rsa.pub
[admin@mha .ssh]$ mv id_rsa.pub authorized_keys
[admin@mha .ssh]$ for【fò】 i in 10 20 30;do scp -r ../.ssh/ 192.168.20.$i:~/;done
测试免密登录
[admin@mha .ssh]$ ssh 192.168.20.10
[admin@mha .ssh]$ ssh 192.168.20.20
[admin@mha .ssh]$ ssh 192.168.20.30
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;疑问：SSH免密只需要拷贝公钥，但是以上代码把整个.ssh目录拷贝过去了
答：因为MHA的互信，要求的不仅仅是MHA免密到MASTER【马斯特】、SLAVE1【斯累夫】、SLAVE2【斯累夫】、MASTER【马斯特】也要免密到MHA、SLAVE1【斯累夫】、SLAVE2【斯累夫】...&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;③配置admin用户的sudo权限&lt;/h4&gt;
&lt;p&gt;MASTER【马斯特】主机上：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@master【马斯特】 ~]# vim /etc/sudoers.d/admin
#User_Alias 表示具有sudo权限的用户列表; Host_Alias表示主机的列表
User_Alias MYSQL_USERS = admin
#Runas_Alias 表示用户以什么身份登录
Runas_Alias MYSQL_RUNAS = root
#Cmnd_Alias 表示允许执行命令的列表（命令需要使用完整路径）
Cmnd_Alias MYSQL_CMNDS = /sbin/ifconfig, /sbin/ip, /sbin/arping
MYSQL_USERS ALL = (MYSQL_RUNAS) NOPASSWD: MYSQL_CMNDS
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;把这个权限分发给SLAVE1【斯累夫】与SLAVE2【斯累夫】一份（当故障发生时，从服务器也可以自己设置VIP）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@master ~]# for【fò】 i in 20 30;do scp /etc/sudoers.d/admin 192.168.20.$i:/etc/sudoers.d/;done
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;测试admin用户是否可以挂载VIP（只能在MASTER【马斯特】机器上挂载VIP）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#su -admin
[admin@master ~]$ sudo /sbin/ifcong ens33:1 192.168.20.100 broadcast 192.168.20.255 netmask 255.255.255.0
[admin@master ~]$ sudo /sbin/arping -fqc 5 -w 5 -I ens33 -s 192.168.20.100 -U 192.168.20.10
[admin@master ~]$ ip a

补充：
arping：用来向局域网内的其它主机发送ARP请求的指令，可以用来测试局域网内的某个IP是否已被使用。
-f：收到第一个响应包后退出。
-q：quite模式，不显示输出。
-c：发送指定的count【kàn特】个ARP REQUEST包后停止。如果指定了-w参数，则会等待相同数量的ARP REPLY包，直到超时为止。
-w：指定一个超时时间，单位为秒，arping在到达指定时间后退出，无论期间发送或接收了多少包。在这种情况下，arping在发送完指定的count【kàn特】（-c）个包后并不会停止，而是等待到超时或发送的count【kàn特】个包都进行了回应后才会退出。
-I：指定设备名，用来发送ARP REQUEST包的网络设备的名称。
-D：重复地址探测模式，用来检测有没有IP地址冲突，如果没有IP冲突则返回0。
-s：设置发送ARP包的IP资源地址
-U：无理由的（强制的）ARP模式去更新别的主机上的ARP CACHE列表中的本机的信息，不需要响应。
-h：显示帮助页。
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;④创建mha相关配置文件&lt;/h4&gt;
&lt;p&gt;MHA服务器：创建工作目录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#mkdir【摸克跌儿】 /etc/mha
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建mha局部配置文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#vim /etc/mha/app1.conf【坑富】
[server【涩·沃】 default]
# 设置监控用户和密码（修改1）
user=mha
password【帕斯沃德】=123
# 设置复制环境中的复制用户和密码（修改2）
repl_user=slave【斯累夫】
repl_password【帕斯沃德】=123
# 设置ssh的登录用户名（修改3）
ssh_user=admin
# 设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行failover
ping_interval=3
# 设置mgr的工作目录
manager【面尼杰额】_workdir=/data/mha/masterha【马斯特-哈】/app1
# 设置mysql master【马斯特】保存binlog【宾-劳格】的目录,以便MHA可以找到master【马斯特】的二进制日志（修改4）
master【马斯特】_binlog【宾-劳格】_dir=/usr/local/mysql/data
# 设置master【马斯特】的pid文件（修改5）
master【马斯特】_pid_file=/usr/local/mysql/data/master【马斯特】.it.cn.pid
# 设置mysql master在发生切换时保存binlog【宾-劳格】的目录（在mysql master【马斯特】上创建这个目录）
remote_workdir=/data/mysql/mha
# 设置mgr日志文件（MHA遇到问题，主要看这个日志）
manager【面尼杰额】_log=/data/mha/masterha【马斯特-哈】/app1/app1-3306.log
# MHA到master【马斯特】的监控之间出现问题,MHA Manager【面尼杰额】将会尝试从slave1【斯累夫】和slave2【斯累夫】登录到master【马斯特】上
secondary_check【切克】_script=/usr/bin/masterha【马斯特-哈】_secondary_check【切克】 -s 192.168.20.20 -s 192.168.20.30 --user=admin --port【破特】=22 --master【马斯特】_host=192.168.20.10 --master【马斯特】_port【破特】=3306
# 设置自动failover时候的切换脚本（故障发生时，自动挂载VIP到SLAVE1【斯累夫】或SLAVE2【斯累夫】）
master【马斯特】_ip_failover_script=&quot;/etc/mha/master【马斯特】_ip_failover.sh 192.168.20.100 1&quot;
# 设置手动切换时候的切换脚本
#master【马斯特】_ip_online_change【趁(chèn)吉】_script=&quot;/etc/mha/master【马斯特】_ip_online_change【趁(chèn)吉】.sh 192.168.20.100 1&quot;
# 设置故障发生后关闭故障主机脚本
# shutdown_script=&quot;/etc/mha/power_manager【面尼杰额】&quot;
[server【涩·沃】1]
hostname=192.168.20.10
port【破特】= 3306
candidate_master【马斯特】=1
[server【涩·沃】2]
hostname=192.168.20.20
port【破特】= 3306
candidate_master【马斯特】=1
[server【涩·沃】3]
hostname=192.168.20.30
port【破特】= 3306
candidate_master【马斯特】=1
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;⑤上传相应脚本/etc/mha目录。然后更改配置信息，授权&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[root@mha ~]# ls /etc/mha/
app1.conf【坑富】 master【马斯特】_ip_failover.sh
注意：脚本内容中要修改网卡名字和连接用户为admin
my $vip = shift;
my $interface = &apos;ens33&apos;; 网卡名（38行）
my $key = shift;
...
sub stop_vip() {
    my $ssh_user = &quot;admin&quot;; 用户名（110行）
    print &quot;=======$ssh_stop_vip==================\n&quot;;
    `ssh $ssh_user\@$orig_master【马斯特】_host \&quot; $ssh_stop_vip \&quot;`;
}
[root@mha ~]#chmod【吃-默德】+x /etc/mha/master【马斯特】_ip_*
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6、检测SSH互信以及MySQL主从状态&lt;/h3&gt;
&lt;p&gt;MHA：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#su - admin
#检测SSH互信
[admin@mha ~]$ masterha【马斯特-哈】_check【切克】_ssh --conf【坑富】=/etc/mha/app1.conf【坑富】
#检测集群状态
[admin@mha ~]$ masterha【马斯特-哈】_check【切克】_repl --conf【坑富】=/etc/mha/app1.conf【坑富】
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7、检查MHA状态，然后运行MHA（监控开始）&lt;/h3&gt;
&lt;p&gt;MHA：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[admin@mha ~]$ masterha【马斯特-哈】_check【切克】_status【 斯dèi 特斯】 --conf【坑富】=/etc/mha/app1.conf【坑富】
app1 is stopped(2:NOT_RUNNING【乱宁】).
开启MHA Manager【面尼杰额】监控（关键，代表启动MHA）：
[admin@mha ~]$ nohup masterha【马斯特-哈】_manager【面尼杰额】 --conf【坑富】=/etc/mha/app1.conf【坑富】 --remove_dead_master【马斯特】_conf【坑富】 --ignore_last_failover &amp;amp;
再次查看监控状态：
[admin@mha ~]$ masterha【马斯特-哈】_check【切克】_status【 斯dèi 特斯】 --conf【坑富】=/etc/mha/app1.conf【坑富】
app1 (pid:8913) is running【乱宁】(0:PING_OK), master【马斯特】:192.168.20.10
注意：
1. 如果正常，会显示”PING_OK ”，否则会显示”NOT_RUNNING【乱宁】 ”，说明 MHA监控没有开启
2. 使用admin用户启动监控，否则会报权限拒绝
3. 手动停止监控命令:masterha【马斯特-哈】_stop【 s 多】 --conf【坑富】=/etc/mha/app1.conf【坑富】
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;到此为止，MHA就已经配置完毕了&lt;/p&gt;
&lt;h2&gt;五、自动failover测试&lt;/h2&gt;
&lt;h3&gt;1、在MASTER【马斯特】服务器安装测试工具&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[root@master【马斯特】 ~]# yum -y install【因-斯多​】 sysbench
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2、插入测试数据&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;master【马斯特】服务器上创建测试库test
mysql&amp;gt; create【克瑞特】 database test charset【查赛特】 utf8mb4;
Query OK, 1 row aected (0.17 sec)
mysql&amp;gt; grant【古亮普】 all on *.* to &apos;mha&apos;@&apos;localhost&apos; identified【爱-丹-提伐】 by &apos;123&apos;;
Query OK, 0 rows aected (0.14 sec)
mysql&amp;gt; flush【福 辣 徐】 privileges【P符类 杰 斯】;
Query OK, 0 rows aected (0.11 sec)
mysql&amp;gt; exit 【诶西特】
Bye
[root@master【马斯特】 ~]# sysbench /usr/share/sysbench/oltp_read【滤德】_only【欧利】.lua \
--mysql-host=192.168.20.10 --mysql-port【破特】=3306 --mysql-user=mha \
--mysql-password【帕斯沃德】=123 --mysql-socket=/tmp/mysql.sock \
--mysql-db=test --db-driver=mysql --tables【忒-部】=1 \
--table【忒-部】-size=100000 --report【瑞破特】-interval=10 --threads【素瑞德s】=128 --time=120 prepare
mysql&amp;gt; select【涩莱克特】 count【kàn特】(*) from【弗乱】 sbtest1;
+----------+
| count【kàn特】(*) |
+----------+
| 100000 |
+----------+
1 row in set【赛特】 (0.01 sec)
select【涩莱克特】 * from【弗乱】 sbtest1 limit 0,10;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3、拍摄快照&lt;/h3&gt;
&lt;p&gt;MHA、MASTER【马斯特】、SLAVE1【斯累夫】、SLAVE2【斯累夫】&lt;/p&gt;
&lt;h3&gt;4、模拟MASTER【马斯特】服务器故障&lt;/h3&gt;
&lt;p&gt;MHA服务器：监控日志&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@mgr ~]# tail -f /data/mha/masterha【马斯特-哈】/app1/app1-3306.log
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;MASTER【马斯特】服务器：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#service【瑟为斯】 mysqld stop【 s 多】
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;MHA日志显示结果：
故障切换：
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112809855.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;VIP漂移：
&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112759706.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;常见问题&lt;/h3&gt;
&lt;h4&gt;1、管理节点配置文件错误&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[root@mgr ~]# cat /etc/mha/app1.conf【坑富】
[server【涩·沃】 default]
# 设置监控用户和密码,该用户是master【马斯特】上创建的数据库管理账号，拥有所有权限
user=mha
password【帕斯沃德】=123
# 设置复制环境中的复制用户和密码，注意需要有以下权限：
#REPLICATION【瑞普利K申】 SLAVE【斯累夫】和REPLICATION【瑞普利K申】 CLIENT
repl_user=slave【斯累夫】
repl_password【帕斯沃德】=123
# 设置ssh的登录用户名
ssh_user=admin
....
[server【涩·沃】1]
hostname=10.1.1.10
port【破特】= 3306
candidate_master【马斯特】=1
[server【涩·沃】2]
hostname=10.1.1.20
port【破特】= 3306
candidate_master【马斯特】=1
[server【涩·沃】3]
hostname=10.1.1.30
port【破特】= 3306
candidate_master【马斯特】=1
注意：一定要配置正确的IP和端口号
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2、配置MHA时数据只读设置&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112746391.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;解决办法：设置从服务器为只读&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; set【赛特】 @@global【格喽部】.read【滤德】_only【欧利】=1;
Query OK, 0 rows aected (0.00 sec)
mysql&amp;gt; show【瘦】 variables【wèi 利 bóu 斯】 like【赖特】 &apos;read【滤德】_only【欧利】&apos;;
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| read【滤德】_only【欧利】 | ON |
+---------------+-------+
1 row in set【赛特】 (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3、复制用户权限密码错误&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/images/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/file-20251117112735925.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;原因：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;复制用户slave【斯累夫】没有相关权限，REPLICATION【瑞普利K申】 SLAVE【斯累夫】和REPLICATION【瑞普利K申】 CLIENT&lt;/li&gt;
&lt;li&gt;从服务器没有创建复制用户&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;4、其他错误&lt;/h4&gt;
&lt;p&gt;MHA集群至少需要2个slave【斯累夫】，所以如果只有一台slave【斯累夫】的话，检查也是通不过的！&lt;/p&gt;
&lt;h1&gt;Mysql 主从复制实操手册&lt;/h1&gt;
&lt;h2&gt;实验一：Mysql 主从复制集群部署&lt;/h2&gt;
&lt;h3&gt;实验目的：&lt;/h3&gt;
&lt;p&gt;部署 mysql 主从复制集群，实现 mysql 数据库服务的高可用&lt;/p&gt;
&lt;h3&gt;实验环境：&lt;/h3&gt;
&lt;p&gt;centos7，内存建议 2G 及以上&lt;/p&gt;
&lt;h3&gt;实验步骤：&lt;/h3&gt;
&lt;h4&gt;一、主服务配置&lt;/h4&gt;
&lt;p&gt;1.如果主机已经有数据了，需要先备份数据，后期去从机上恢复因为，主从复制只会同步配置好以后的数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysqldump【mysql-当普】 -uroot -p123 -A --single-transaction【穿插神】 &amp;gt; /tmp/all.sql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;1.需要开启二进制日志(8.0 默认开启)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vim /etc/my.cnf
server【涩·沃】_id=1
log_bin=binlog【宾-劳格】 （5.7 版本需要开启）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2.重启服务，创建复制用户&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;create【克瑞特】 user &apos;repl&apos;@&apos;%&apos; identified【爱-丹-提伐】 by &apos;Aa123456!&apos;;
grant【古亮普】 replication【瑞普利K申】 slave【斯累夫】 on *.* to &apos;repl&apos;@&apos;%&apos;;
flush【福 辣 徐】 privileges【P符类 杰 斯】;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3.查看 binlog【宾-劳格】 二进制的 postition 位置点（从哪个位置开始读取新的日志内容）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;show【瘦】 master【马斯特】 status【 斯dèi 特斯】;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;二、从服务器配置&lt;/h4&gt;
&lt;p&gt;1.安装（略） 恢复主服务器上的旧数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql -uroot -pAa123456! &amp;lt; all.sql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2.自定标识符，不可与主机或其他从机重复&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vim /etc/my.cnf
server【涩·沃】_id=2 #不可重复
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;重启服务&lt;/p&gt;
&lt;p&gt;3.启动主从复制，指定主机相关参数&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;change【趁(chèn)吉】 master【马斯特】 to
-&amp;gt; master【马斯特】_host=&apos;192.168.100.170&apos;, #指定主服务器 ip 地址
-&amp;gt; master【马斯特】_user=&apos;repl&apos;, #指定用与复制的用户名
-&amp;gt; master【马斯特】_password【帕斯沃德】=&apos;Aa123456!&apos;, 密码
-&amp;gt; master【马斯特】_log_file=&apos;mybinlog【宾-劳格】.000003&apos;, #指定从哪个二进制日志开始同步
-&amp;gt; master【马斯特】_log_pos=469; #指定从上面这个日志的哪个位置开始同步，这两个信息在主服务器上执行 show【瘦】 master【马斯特】 status【 斯dèi 特斯】 查看
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4.启动主从复制&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;start【s 达儿】 slave【斯累夫】;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;5.验证
查看从服务状态：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;show【瘦】 slave【斯累夫】 status【 斯dèi 特斯】\G;
结果里重点看这两行：
....
Slave【斯累夫】_IO_Running【乱宁】: Yes
Slave【斯累夫】_SQL_Running【乱宁】: Yes
都是 Yes，表示成功
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在主服务器上修改数据，从服务器上可以自动同步&lt;/p&gt;
&lt;p&gt;实验总结：&lt;/p&gt;
</content:encoded></item><item><title>数据库命令</title><link>https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%91%BD%E4%BB%A4/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%91%BD%E4%BB%A4/</guid><description>目录 - 运维知识库笔记</description><pubDate>Tue, 02 Jun 2026 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1&gt;数据库命令&lt;/h1&gt;
&lt;h2&gt;MySQL 查询命令详解（针对初学者）&lt;/h2&gt;
&lt;p&gt;以下是每个查询命令的详细参数说明，帮助您理解每个关键字的作用：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;关键字/参数&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;th&gt;语法说明&lt;/th&gt;
&lt;th&gt;示例值&lt;/th&gt;
&lt;th&gt;解释说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SELECT&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;选择要显示的列&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT 列名 AS 别名&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT A.emp_name AS 姓名&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;决定查询结果中显示哪些数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;为列或表指定别名&lt;/td&gt;
&lt;td&gt;&lt;code&gt;原始名 AS 别名&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A.emp_name AS 姓名&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;给列或表起一个更易读的名称&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;FROM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;指定数据来源的表&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FROM 表名 AS 别名&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FROM employee AS A&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;告诉数据库从哪个表获取数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;JOIN&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;连接其他表&lt;/td&gt;
&lt;td&gt;&lt;code&gt;JOIN 表名 AS 别名 ON 条件&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;JOIN department AS B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;将多个表的数据关联起来&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ON&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;指定连接条件&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ON 表1.列 = 表2.列&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ON A.dep_id = B.dep_id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;定义两个表如何关联的规则&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;WHERE&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;过滤条件&lt;/td&gt;
&lt;td&gt;&lt;code&gt;WHERE 条件表达式&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;WHERE emp_name=&apos;tom&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;筛选满足特定条件的记录&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GROUP BY&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;分组依据&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GROUP BY 列名&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GROUP BY dep_name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;将数据按指定列分组&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ORDER BY&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;排序方式&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ORDER BY 列名 [ASC/DESC]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ORDER BY A.age ASC&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;按指定列排序结果&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LIMIT&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;限制返回行数&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIMIT 行数&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIMIT 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;只返回指定数量的记录&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;COUNT()&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;计算行数&lt;/td&gt;
&lt;td&gt;&lt;code&gt;COUNT(列名)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;COUNT(A.emp_name)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;统计记录数量&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SUM()&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;计算总和&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUM(数值列)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SUM(A.age)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;计算数值列的总和&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AVG()&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;计算平均值&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AVG(数值列)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AVG(A.age)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;计算数值列的平均值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LEFT JOIN&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;左连接&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LEFT JOIN 表名 ON 条件&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LEFT JOIN department AS B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;包含左表所有记录，即使右表无匹配&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RIGHT JOIN&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;右连接&lt;/td&gt;
&lt;td&gt;&lt;code&gt;RIGHT JOIN 表名 ON 条件&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;RIGHT JOIN department AS B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;包含右表所有记录，即使左表无匹配&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;特殊符号说明：&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;符号&lt;/th&gt;
&lt;th&gt;含义&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;th&gt;解释&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;表与列的连接符&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A.emp_name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;表示表A的emp_name列&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;=&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;等于比较&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A.dep_id = B.dep_id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;判断两个值是否相等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&apos; &apos;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;字符串定界符&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&apos;it&apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;表示文本值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;**; **&lt;/td&gt;
&lt;td&gt;语句结束符&lt;/td&gt;
&lt;td&gt;每个查询结尾的;&lt;/td&gt;
&lt;td&gt;表示SQL语句结束&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;表名和列名说明：&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名称&lt;/th&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;th&gt;解释&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;employee&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;表名&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FROM employee&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;员工信息表&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;department&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;表名&lt;/td&gt;
&lt;td&gt;&lt;code&gt;JOIN department&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;部门信息表&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;emp_name&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;列名&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A.emp_name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;员工姓名字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;dep_name&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;列名&lt;/td&gt;
&lt;td&gt;&lt;code&gt;B.dep_name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;部门名称字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;age&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;列名&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A.age&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;员工年龄字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;dep_id&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;列名&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A.dep_id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;部门ID字段&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;别名说明：&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;别名&lt;/th&gt;
&lt;th&gt;对应表&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;th&gt;解释&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;A&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;employee&lt;/td&gt;
&lt;td&gt;&lt;code&gt;employee AS A&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;员工表的别名&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;B&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;department&lt;/td&gt;
&lt;td&gt;&lt;code&gt;department AS B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;部门表的别名&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;姓名&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;emp_name&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A.emp_name AS 姓名&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;员工姓名的显示名称&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;部门&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;dep_name&lt;/td&gt;
&lt;td&gt;&lt;code&gt;B.dep_name AS 部门&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;部门名称的显示名称&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;查询示例详解：&lt;/h3&gt;
&lt;h4&gt;示例1：查询所有人所在的部门名称&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    A.emp_name AS 姓名,   -- 从员工表选择姓名列，显示为&quot;姓名&quot;
    B.dep_name AS 部门    -- 从部门表选择部门列，显示为&quot;部门&quot;
FROM employee AS A        -- 主表是员工表，别名为A
JOIN department AS B      -- 连接部门表，别名为B
    ON A.dep_id = B.dep_id; -- 连接条件：员工表的部门ID = 部门表的部门ID
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;示例5：查询哪个员工目前所在的部门还没有成立&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    A.emp_name AS 姓名, 
    B.dep_name AS 部门 
FROM employee AS A 
LEFT JOIN department AS B  -- 左连接：保留所有员工记录
    ON A.dep_id = B.dep_id
WHERE B.dep_name IS NULL;   -- 只显示部门名称为空的记录
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;示例8：查询哪个部门的年龄总和最高&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    SUM(A.age) AS 年龄总和,  -- 计算年龄总和
    B.dep_name AS 部门 
FROM employee AS A 
JOIN department AS B 
    ON A.dep_id = B.dep_id 
GROUP BY B.dep_name        -- 按部门分组
ORDER BY 年龄总和 DESC    -- 按年龄总和降序排序
LIMIT 1;                  -- 只显示第一条记录（最高值）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;总结：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;​​SELECT​​：指定要显示的列。&lt;/li&gt;
&lt;li&gt;​​FROM​​：指定数据来源的表。&lt;/li&gt;
&lt;li&gt;​​JOIN ... ON​​：连接另一个表，并指定连接条件。&lt;/li&gt;
&lt;li&gt;​​WHERE​​：过滤行。&lt;/li&gt;
&lt;li&gt;​​GROUP BY​​：分组，通常与聚合函数一起使用。&lt;/li&gt;
&lt;li&gt;​​ORDER BY​​：排序。&lt;/li&gt;
&lt;li&gt;​​LIMIT​​：限制返回的行数。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;创建用户&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; create【克瑞特】 user &apos;用户名&apos;@&apos;被允许连接的主机名称或主机的IP地址&apos; identified ed by【拜】 &apos;用户密码&apos;;
mysql &amp;gt; create【克瑞特】 user &apos;用户名&apos;@&apos;被允许连接的主机名称或主机的IP地址&apos; identified ed by &apos;用户密码&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;查询MySQL服务器中所有用户及其允许连接的主机。&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;mysql &amp;gt; select【涩莱克特】 user,host from【弗乱】 mysql.user;
mysql &amp;gt; select user.host from mysql.user;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;查看所有数据库信息&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;SHOW DATABASES;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;配置远程访问权限&lt;/h2&gt;
&lt;h3&gt;查看 &lt;code&gt;root&lt;/code&gt; 用户的权限情况 ：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;SELECT host, user FROM mysql.user WHERE user = &apos;root&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;添加和更新用户权限：&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;CREATE USER IF NOT EXISTS &apos;root&apos;@&apos;%&apos; IDENTIFIED BY &apos;123&apos;;
--    **作用**：创建用户账号。
--    **说明**：这条命令创建了一个名为 `root` 的用户，并设置其密码为 `123`。`&apos;%&apos;` 表示该用户可以从任何远程主机连接到 MySQL 服务器。命令成功执行，

GRANT ALL PRIVILEGES ON *.* TO &apos;root&apos;@&apos;%&apos; WITH GRANT OPTION;
--    **作用**：授予权限。
--    **说明**：
--        `ALL PRIVILEGES`: 这意味着授予所有数据库的**所有操作权限**，包括 `SELECT`（查询）, `INSERT`（插入）, `UPDATE`（更新）, `DELETE`（删除）, `DROP`（删除表）等。
--        `WITH GRANT OPTION`: 这表示 `root` 用户**可以将其拥有的权限（这里是所有权限）再授予其他用户**。

FLUSH PRIVILEGES;  # 刷新权限使更改生效
--    **作用**：重新加载权限表。
--        **说明**：MySQL 的权限信息主要存储在 `mysql` 数据库的权限表（如 `user`, `db`, `tables_priv` 等）中。通常，使用 `GRANT`/`REVOKE` 等权限管理语句后，权限会自动更新到内存中，无需手动执行 `FLUSH PRIVILEGES`
--        **何时需要**：如果你**直接使用 `INSERT`、`UPDATE` 或 `DELETE` 语句手动修改了权限表**，那么必须执行 `FLUSH PRIVILEGES;` 来通知服务器重新加载权限，使更改生效。在你的操作流程中，这条命令是**多余的，但不是错误的**。

-- 授予root账户对moershi.user表【仅查询】权限 (核心修正)
GRANT SELECT ON moershi.user TO &apos;root&apos;@&apos;%&apos;;



-- 1. 撤销该用户在 moershi.user 表上的所有权限
REVOKE ALL PRIVILEGES ON moershi.user FROM &apos;roor&apos;@&apos;%&apos;;

-- 2. 撤销其授予权限的能力
REVOKE GRANT OPTION ON moershi.user FROM &apos;roor&apos;@&apos;%&apos;;

-- 3. 授予它本应拥有的唯一权限：查询(SELECT)
GRANT SELECT ON moershi.user TO &apos;roor&apos;@&apos;%&apos;;

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;解释选项：&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;		&apos;root&apos;@&apos;sfta188299c.sf.com&apos;：显式指定客户端主机名（精确匹配）。
		GRANT ALL PRIVILEGES：授予完全权限（可根据需求调整，如 GRANT SELECT, INSERT ON database.*）。
		IDENTIFIED BY：设置或更新密码（如未定义用户，会创建新用户）。
	更安全的替代：如果客户端使用 IP 而非域名，可以用 IP 地址授权（如 &apos;root&apos;@&apos;192.168.99.1&apos;），减少 DNS 依赖。
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;在 MySQL 5.7 中修改 root 用户密码，可以通过以下方法操作：&lt;/h1&gt;
&lt;h3&gt;方法一：在 MySQL 命令行中直接修改&lt;/h3&gt;
&lt;h4&gt;1. 登录后，执行以下命令（替换 &lt;code&gt;新密码&lt;/code&gt; 为你要设置的密码）：&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;   ALTER USER &apos;root&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;新密码&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;（如果 root 允许远程连接，可能需要同时修改 &lt;code&gt;&apos;root&apos;@&apos;%&apos;&lt;/code&gt; 的密码）&lt;/p&gt;
&lt;h4&gt;2. 刷新权限使修改生效：&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;   FLUSH PRIVILEGES;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3. 退出 MySQL 重新登录验证：&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;   exit;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;方法二：使用 &lt;code&gt;set password&lt;/code&gt; 命令&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;    SET PASSWORD FOR &apos;root&apos;@&apos;localhost&apos; = PASSWORD(&apos;新密码&apos;);
    FLUSH PRIVILEGES;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;方法三：使用 &lt;code&gt;bin/mysqladmin&lt;/code&gt; 命令&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[root@mysql mysql_3306]# bin/mysqladmin -uroot password &apos;123456&apos; -p #&apos;123456&apos;要设置的密码
Enter password: ##旧密码\初始密码
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@mysql mysql_3306]# bin/mysql -uroot -p
Enter password: ##修改后的新密码
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.31 MySQL Community Server (GPL)

Copyright (c) 2000, 2020, 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 &apos;help;&apos; or &apos;\h&apos; for help. Type &apos;\c&apos; to clear the current input statement.

mysql&amp;gt; exit
Bye
[root@mysql mysql_3306]# pwd
/mysql_3306
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;注意事项&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;密码需符合 MySQL 的安全策略（默认要求包含大小写字母、数字和特殊字符，长度至少 8 位）。&lt;/li&gt;
&lt;li&gt;如果后续登录提示密码错误，可检查是否是 &lt;code&gt;&apos;root&apos;@&apos;localhost&apos;&lt;/code&gt; 和 &lt;code&gt;&apos;root&apos;@&apos;%&apos;&lt;/code&gt; 权限的密码未统一设置。&lt;/li&gt;
&lt;li&gt;若忘记密码，需通过 &lt;code&gt;--skip-grant-tables&lt;/code&gt; 方式启动 MySQL 进行重置（此为特殊场景操作）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;修改字符集&lt;/h2&gt;
&lt;h3&gt;修改数据库字符集&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;-- 修改数据库字符集
ALTER DATABASE db_fq CHARACTER SET utf8 COLLATE utf8_general_ci;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;修改服务器字符集配置&lt;/h3&gt;
&lt;p&gt;编辑 MySQL 配置文件（通常是 /etc/my.cnf或 /mysql_3306/my.cnf）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci

[client]
default-character-set=utf8
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;重启 MySQL 服务：&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;service mysql_3306 restart
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;验证字符集配置&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;SHOW VARIABLES LIKE &apos;character_set%&apos;;
SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME 
FROM INFORMATION_SCHEMA.SCHEMATA 
WHERE SCHEMA_NAME = &apos;db_fq&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;数据库权限修改&lt;/h1&gt;
&lt;h2&gt;解决方案&lt;/h2&gt;
&lt;p&gt;您需要为这个新创建的 &lt;code&gt;&apos;root&apos;@&apos;%&apos;&lt;/code&gt; 用户授予适当的数据库访问权限：&lt;/p&gt;
&lt;h3&gt;方案1：授予所有权限（推荐用于管理）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;-- 授予所有数据库的所有权限（类似超级用户）
GRANT ALL PRIVILEGES ON *.* TO &apos;root&apos;@&apos;%&apos; WITH GRANT OPTION;

-- 刷新权限
FLUSH PRIVILEGES;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;方案2：授予特定数据库的权限&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;-- 授予特定数据库的所有权限（例如 test 数据库）
GRANT ALL PRIVILEGES ON test.* TO &apos;root&apos;@&apos;%&apos;;

-- 刷新权限
FLUSH PRIVILEGES;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;方案3：授予只读权限（更安全）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;-- 授予所有数据库的只读权限
GRANT SELECT ON *.* TO &apos;root&apos;@&apos;%&apos;;

-- 刷新权限
FLUSH PRIVILEGES;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;验证权限&lt;/h3&gt;
&lt;p&gt;授予权限后，您可以验证用户的权限：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 查看用户权限
SHOW GRANTS FOR &apos;root&apos;@&apos;%&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;安全建议&lt;/h3&gt;
&lt;p&gt;虽然使用 &lt;code&gt;root&lt;/code&gt; 作为远程用户名很方便，但从安全角度考虑，我建议：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;创建专用管理账户&lt;/strong&gt;：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;CREATE USER &apos;admin_remote&apos;@&apos;%&apos; IDENTIFIED BY &apos;复杂密码&apos;;
GRANT ALL PRIVILEGES ON *.* TO &apos;admin_remote&apos;@&apos;%&apos; WITH GRANT OPTION;
FLUSH PRIVILEGES;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;限制访问来源&lt;/strong&gt;（更安全）：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;-- 只允许从特定IP段连接
CREATE USER &apos;admin_remote&apos;@&apos;192.168.88.%&apos; IDENTIFIED BY &apos;复杂密码&apos;;
GRANT ALL PRIVILEGES ON *.* TO &apos;admin_remote&apos;@&apos;192.168.88.%&apos;;
FLUSH PRIVILEGES;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;您遇到的问题是因为新创建的 &lt;code&gt;&apos;root&apos;@&apos;%&apos;&lt;/code&gt; 用户还没有被授予访问普通数据库的权限。只需要执行相应的 &lt;code&gt;GRANT&lt;/code&gt; 语句即可解决。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;建议操作&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 在每台MySQL服务器上执行
GRANT ALL PRIVILEGES ON *.* TO &apos;root&apos;@&apos;%&apos; WITH GRANT OPTION;
FLUSH PRIVILEGES;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;执行后，您再用这个账户远程连接，就能看到所有数据库了。&lt;/p&gt;
&lt;h1&gt;因GTID 不一致导致复制中断，无法同步从库&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;all.sql&lt;/code&gt; 备份文件包含了 GTID 信息&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当您导入 &lt;code&gt;all.sql&lt;/code&gt; 时，它可能包含 &lt;code&gt;SET @@GLOBAL.GTID_PURGED&lt;/code&gt; 语句&lt;/li&gt;
&lt;li&gt;这会修改主库的 GTID 执行历史，但与从库的 GTID 历史不匹配&lt;/li&gt;
&lt;li&gt;从库检测到 GTID 不一致，会停止复制或跳过这些事务&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;moershi.sql&lt;/code&gt; 可能不包含 GTID 信息&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这个文件可能是使用 &lt;code&gt;--set-gtid-purged=OFF&lt;/code&gt; 选项生成的&lt;/li&gt;
&lt;li&gt;或者是一个不包含 GTID 信息的传统备份&lt;/li&gt;
&lt;li&gt;因此导入后不会影响 GTID 一致性，复制可以正常进行&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;解决方案&lt;/h2&gt;
&lt;p&gt;请按照以下步骤彻底解决这个问题：&lt;/p&gt;
&lt;h3&gt;方案1：完全重置 GTID（推荐）&lt;/h3&gt;
&lt;p&gt;这是最彻底的解决方案，但需要在维护窗口进行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 1. 停止所有从库复制
mysql -uroot -p -e &quot;STOP SLAVE;&quot; 

# 2. 在主库上重置 GTID 信息（会清除所有二进制日志）
mysql -uroot -p -e &quot;RESET MASTER;&quot;

# 3. 重新导入清理后的备份文件
sed -i &apos;/SET @@GLOBAL.GTID_PURGED/d&apos; all.sql
mysql -uroot -p &amp;lt; all.sql

# 4. 在从库上重新配置复制
mysql -uroot -p -e &quot;
STOP SLAVE;
RESET SLAVE ALL;
CHANGE MASTER TO 
  MASTER_HOST=&apos;192.168.88.10&apos;,
  MASTER_USER=&apos;slave&apos;,
  MASTER_PASSWORD=&apos;123&apos;,
  MASTER_AUTO_POSITION=1;
START SLAVE;
&quot;

# 5. 检查复制状态
mysql -uroot -p -e &quot;SHOW SLAVE STATUS\G&quot; | grep -E &apos;Slave_IO_Running|Slave_SQL_Running&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;方案2：手动跳过冲突的 GTID&lt;/h3&gt;
&lt;p&gt;如果不想完全重置，可以尝试跳过冲突的 GTID：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 在从库上执行
STOP SLAVE;
SET GLOBAL sql_slave_skip_counter = 1;
START SLAVE;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或者对于 GTID 复制：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 在从库上执行
STOP SLAVE;
SET GTID_NEXT=&apos;冲突的GTID编号&apos;;
BEGIN; COMMIT;
SET GTID_NEXT=&apos;AUTOMATIC&apos;;
START SLAVE;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;方案3：重新生成正确的备份文件&lt;/h3&gt;
&lt;p&gt;最好的长期解决方案是重新生成不包含 GTID 信息的备份：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 在主库上重新生成备份
mysqldump --single-transaction --set-gtid-purged=OFF -u root -p --databases db_fq db_it db_my test1 &amp;gt; all_new.sql

# 导入新备份
mysql -uroot -p &amp;lt; all_new.sql
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;验证和确认&lt;/h3&gt;
&lt;p&gt;执行解决方案后，请验证：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查主库数据库&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql -uroot -p -e &quot;SHOW DATABASES;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查从库复制状态&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql -uroot -p -e &quot;SHOW SLAVE STATUS\G&quot; | grep -E &apos;Slave_IO_Running|Slave_SQL_Running&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查数据同步&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 在主库上创建测试数据
mysql -uroot -p -e &quot;USE test1; CREATE TABLE IF NOT EXISTS sync_test (id INT); INSERT INTO sync_test VALUES (1);&quot;

# 在从库上检查
mysql -uroot -p -e &quot;USE test1; SELECT * FROM sync_test;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;预防措施&lt;/h3&gt;
&lt;p&gt;为了避免未来出现类似问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;使用正确的备份选项&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 生成用于主从环境的备份
mysqldump --single-transaction --set-gtid-purged=OFF -u root -p --databases your_database &amp;gt; backup.sql
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;定期检查 GTID 一致性&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 在主库上执行
SHOW GLOBAL VARIABLES LIKE &apos;gtid_executed&apos;;

-- 在从库上执行
SHOW GLOBAL VARIABLES LIKE &apos;gtid_executed&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;监控复制状态&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 定期检查复制状态
mysql -uroot -p -e &quot;SHOW SLAVE STATUS\G&quot; | grep -E &apos;Slave_IO_Running|Slave_SQL_Running|Seconds_Behind_Master&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;您遇到的问题是由于 &lt;code&gt;all.sql&lt;/code&gt; 备份文件包含 GTID 信息，导致主从库的 GTID 历史不一致，从而阻止了复制。而 &lt;code&gt;moershi.sql&lt;/code&gt; 不包含 GTID 信息，所以能够正常同步。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;推荐解决方案&lt;/strong&gt;：使用方案1完全重置 GTID，这是最彻底的方法。如果您需要更详细的指导或在执行过程中遇到问题，请随时告诉我！&lt;/p&gt;
&lt;h1&gt;关闭/降低数据库密码策略等级&lt;/h1&gt;
&lt;h2&gt;完全卸载密码验证组件&lt;/h2&gt;
&lt;h3&gt;1. 登录 MySQL：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;mysql -uroot -p
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 检查并卸载密码验证组件：&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;-- 初次登录需要复杂密码
ALTER USER &apos;root&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;Password123!&apos;;

-- 查看已安装的组件
SELECT * FROM mysql.component;

-- 卸载密码验证组件
UNINSTALL COMPONENT &apos;file://component_validate_password&apos;;

-- 再次检查密码验证相关变量
SHOW VARIABLES LIKE &apos;validate_password%&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 现在尝试修改密码：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;ALTER USER &apos;root&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;123&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;mysql 密码强度设置&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;validate_password_policy=0&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;含义&lt;/strong&gt;：设置密码策略的&lt;strong&gt;安全级别&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可选值&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;0&lt;/code&gt;/ &lt;code&gt;LOW&lt;/code&gt;&lt;/strong&gt;：只检查密码长度&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;1&lt;/code&gt;/ &lt;code&gt;MEDIUM&lt;/code&gt;&lt;/strong&gt;：长度 + 数字 + 大小写字母 + 特殊字符（默认值）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;2&lt;/code&gt;/ &lt;code&gt;STRONG&lt;/code&gt;&lt;/strong&gt;：在 MEDIUM 基础上增加字典文件检查&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;validate_password_length=4&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;含义&lt;/strong&gt;：设置密码的&lt;strong&gt;最小长度要求&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;默认值&lt;/strong&gt;：通常是 &lt;code&gt;8&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;相关参数说明（扩展）&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参数&lt;/th&gt;
&lt;th&gt;含义&lt;/th&gt;
&lt;th&gt;默认值&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;validate_password_number_count&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;最少数字数量&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;密码中至少包含的数字个数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;validate_password_mixed_case_count&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;最少大小写字母数量&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;至少需要的大小写字母总数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;validate_password_special_char_count&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;最少特殊字符数量&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;如 &lt;code&gt;!@#$%&lt;/code&gt;等符号的数量要求&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;validate_password_dictionary_file&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;字典文件路径&lt;/td&gt;
&lt;td&gt;空&lt;/td&gt;
&lt;td&gt;强策略下检查密码是否在字典中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;validate_password_policy&lt;/td&gt;
&lt;td&gt;设置密码策略的&lt;strong&gt;安全级别&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;**`validate_password_length=4&lt;/td&gt;
&lt;td&gt;设置密码的&lt;strong&gt;最小长度要求&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h3&gt;正确做法（生产环境）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[mysqld]
# 保持中等或强密码策略
validate_password_policy=1   # 或 2

# 建议最小长度12+
validate_password_length=12

# 增强要求（可选）
validate_password_mixed_case_count=2  # 至少2个大小写字母
validate_password_special_char_count=1 # 至少1个特殊符号
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;合规密码示例：&lt;code&gt;MyDB@Pass123!&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;如何生效？&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;修改配置文件（如 &lt;code&gt;/etc/my.cnf&lt;/code&gt;）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;重启MySQL服务&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl restart mysqld
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;验证配置：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SHOW VARIABLES LIKE &apos;validate_password%&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;密码忘记&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;# 修改主配置文件
# 手动添加此行 作用登陆时不验证密码
[root@mysql50 ~]# vim /etc/my.cnf.d/mysql-server.cnf  
[mysqld]
skip-grant-tables【忒-部s】  
:wq
# 重启服务 作用让服务以新配置运行
[root@mysql50 ~]# # systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld 
# 连接服务
[root@mysql50 ~]# mysql 
# 把mysql库下user表中 用户root的密码设置为无；
mysql&amp;gt; update mysql.user set authentication_string=&quot;&quot; where user=&quot;root&quot;;
Query OK, 1 row affected (0.05 sec)
mysql&amp;gt; exit;

# 编辑配置文件
# 注释添加的行
[root@mysql50 ~]# vim  /etc/my.cnf.d/mysql-server.cnf  
[mysqld]
#skip-grant-tables【忒-部s】   
:wq
# 重启服务 作用让注释生效
[root@mysql50 ~]# systemctl【西斯屯-ctl】  restart【 率 s 达r】 mysqld 
# 无密码登陆
[root@localhost ~]# mysql
# 设置root用户本机登陆密码
mysql&amp;gt; alter user root@&quot;localhost&quot; identified by &quot;123&quot;;
mysql&amp;gt; exit;


总结
忘记密码

1. 修改mysql配置文件
`vim /etc/my.cnf.d/mysql-server.cnf  `
`skip-grant-tables  不需要密码验证`

2. 重启mysql服务
`systemctl restart mysqld`

3. 无密码登录
`mysql`

4. 把密码修改为空
`update user set authentication_string=&quot;&quot; where user=&quot;root&quot;;`

5. 修改mysql配置文件
`vim /etc/my.cnf.d/mysql-server.cnf  `
去掉skip-grant-tables

6. 重启mysql服务
`systemctl restart mysqld`

7. 无密码登录
`mysql`

8. 在mysql终端里面设置密码
`alter user root@&quot;localhost&quot; identified by  &quot;NSD123456...a&quot;`


&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;maccms&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;//查询
select art_id,art_name from maccms.mac_art where art_name like &quot;%sds%&quot;;
select art_id,art_name from maccms.mac_art where art_name like &quot;%sd%&quot;;
select art_id,art_name from maccms.mac_art where art_name like &quot;%妈%&quot; or art_name like &quot;%母%&quot; or art_name like &quot;%狗%&quot;;
select vod_id,vod_name from maccms.mac_vod where vod_name like &quot;%妈%&quot; or vod_name like &quot;%母%&quot; or vod_name like &quot;%狗%&quot;;
//删除
delete from maccms.mac_art where art_name like &quot;%妈%&quot; or art_name like &quot;%母%&quot; or art_name like &quot;%狗%&quot;;
delete from maccms.mac_vod where vod_name like &quot;%妈%&quot; or vod_name like &quot;%母%&quot; or vod_name like &quot;%狗%&quot;;

//导出
mysqldump -uroot -p maccms mac_vod --where=&quot;vod_name LIKE &apos;%妈%&apos;&quot; &amp;gt; mac_vod.sql


// 第一次导出时包含表结构
mysqldump -uroot -p123 maccms mac_vod --where=&quot;vod_name like &apos;%妈%&apos; or vod_name like &apos;%母%&apos; or vod_name like &apos;%狗%&apos;&quot; &amp;gt; mac_vod.sql
// 后续导出只追加数据，不包含表结构
mysqldump -uroot -p123 maccms mac_vod --no-create-info --where=&quot;vod_name like &apos;%妈%&apos; or vod_name like &apos;%母%&apos; or vod_name like &apos;%狗%&apos;&quot; &amp;gt;&amp;gt; mac_vod.sql

// 第一次导出时包含表结构
mysqldump -uroot -p123 maccms mac_art --where=&quot;art_name like &apos;%妈%&apos; or art_name like &apos;%母%&apos; or art_name like &apos;%狗%&apos;&quot; &amp;gt; mac_art.sql
// 后续导出只追加数据，不包含表结构
mysqldump -uroot -p123 maccms mac_art --no-create-info --where=&quot;art_name like &apos;%妈%&apos; or art_name like &apos;%母%&apos; or art_name like &apos;%狗%&apos;&quot; &amp;gt;&amp;gt; mac_art.sql

// 删除
mysql -uroot -p123 -e &quot;delete from maccms.mac_art where art_name like &apos;%妈%&apos; or art_name like &apos;%母%&apos; or art_name like &apos;%狗%&apos;;&quot;
mysql -uroot -p123 -e &quot;delete from maccms.mac_vod where vod_name like &apos;%妈%&apos; or vod_name like &apos;%母%&apos; or vod_name like &apos;%狗%&apos;;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;vim export_and_delete.sh

#!/bin/bash

# 数据库配置
DB_USER=&quot;root&quot;
DB_PASSWORD=&quot;123&quot;
DB_NAME=&quot;maccms&quot;

# 导出文件路径
VOD_FILE=&quot;mac_vod.sql&quot;
ART_FILE=&quot;mac_art.sql&quot;

# 创建日志函数
log() {
    echo &quot;[$(date &apos;+%Y-%m-%d %H:%M:%S&apos;)] $1&quot;
}

# 检查并执行 mac_vod 表的导出
if [ ! -f &quot;$VOD_FILE&quot; ]; then
    log &quot;首次导出 mac_vod 表（包含表结构）&quot;
    mysqldump -u$DB_USER -p$DB_PASSWORD $DB_NAME mac_vod --where=&quot;vod_name like &apos;%妈%&apos; or vod_name like &apos;%母%&apos; or vod_name like &apos;%狗%&apos;&quot; &amp;gt; $VOD_FILE
else
    log &quot;追加导出 mac_vod 表数据&quot;
    mysqldump -u$DB_USER -p$DB_PASSWORD $DB_NAME mac_vod --no-create-info --where=&quot;vod_name like &apos;%妈%&apos; or vod_name like &apos;%母%&apos; or vod_name like &apos;%狗%&apos;&quot; &amp;gt;&amp;gt; $VOD_FILE
fi

# 检查并执行 mac_art 表的导出
if [ ! -f &quot;$ART_FILE&quot; ]; then
    log &quot;首次导出 mac_art 表（包含表结构）&quot;
    mysqldump -u$DB_USER -p$DB_PASSWORD $DB_NAME mac_art --where=&quot;art_name like &apos;%妈%&apos; or art_name like &apos;%母%&apos; or art_name like &apos;%狗%&apos;&quot; &amp;gt; $ART_FILE
else
    log &quot;追加导出 mac_art 表数据&quot;
    mysqldump -u$DB_USER -p$DB_PASSWORD $DB_NAME mac_art --no-create-info --where=&quot;art_name like &apos;%妈%&apos; or art_name like &apos;%母%&apos; or art_name like &apos;%狗%&apos;&quot; &amp;gt;&amp;gt; $ART_FILE
fi

# 删除数据库中的对应数据
log &quot;删除数据库中符合条件的数据&quot;
mysql -u$DB_USER -p$DB_PASSWORD -e &quot;DELETE FROM $DB_NAME.mac_vod WHERE vod_name like &apos;%妈%&apos; or vod_name like &apos;%母%&apos; or vod_name like &apos;%狗%&apos;;&quot;
mysql -u$DB_USER -p$DB_PASSWORD -e &quot;DELETE FROM $DB_NAME.mac_art WHERE art_name like &apos;%妈%&apos; or art_name like &apos;%母%&apos; or art_name like &apos;%狗%&apos;;&quot;

log &quot;操作完成&quot;


chmod +x export_and_delete.sh
bash export_and_delete.sh

crontab -e
0 6 * * * /root/maccms/sql/export_and_delete.sh &amp;gt;&amp;gt; /root/maccms/sql/export_log.txt 2&amp;gt;&amp;amp;1

&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>mysql基础</title><link>https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql%E5%9F%BA%E7%A1%80/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql%E5%9F%BA%E7%A1%80/</guid><description>mysql基础 - 运维知识库笔记</description><pubDate>Tue, 02 Jun 2026 22:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;mysql基础&lt;/h1&gt;
&lt;p&gt;&amp;lt;!-- ![图片: 71618566525460.png] --&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph LR
    %% 使用 LR 方向，更符合阅读习惯
    开始[mysql基础]

    subgraph SG_A [数据库与服务]
        direction LR
        a[mysql数据库]
        a --&amp;gt; a1[包:mysql-server]
        a --&amp;gt; a2[服务:mysqld]
        a --&amp;gt; a3[端口:3306]
        a --&amp;gt; a4[端口:33060]
    end

    subgraph SG_B [常用命令]
        direction LR
        b[mysql必备命令]
        b --&amp;gt; b1[select version()  查询版本]
        b --&amp;gt; b2[select user()  查询登录用户]
        b --&amp;gt; b3[select database()  查询使用的使用的数据库]
        b --&amp;gt; b4[use  database名字：使用数据库]
        b --&amp;gt; b5[show databases  显示所有的数据库]
        b --&amp;gt; b6[show  talbes  显示当前库下面的所有表]
        b --&amp;gt; b7[desc 表名：查看表结构]
    end

    subgraph SG_C [安全与管理]
        direction LR
        c[密码管理]
        c --&amp;gt; c1[mysql  连接数据库服务                ]
        c --&amp;gt; c2[mysql -u root -p密码                 ]
        c --&amp;gt; c3[mysqladmin -u root password 密码]
        c --&amp;gt; c4[忘记密码                             ]
    end

    subgraph SG_D [查询操作]
        direction LR
        d[条件查询]
        d --&amp;gt; d1[=  等值查询]
        d --&amp;gt; d2[!=  不等值查询]
        d --&amp;gt; d3[&amp;gt; ,&amp;lt; , &amp;gt;=,  &amp;lt;=,]
        d --&amp;gt; d4[between x  and y  范围查询]
        d --&amp;gt; d5[like  模糊查询]
        d --&amp;gt; d6[逻辑查查（and ,  or）]
        d --&amp;gt; d7[为空：字符串空，真空（is null   is not null）]
        d --&amp;gt; d8[别名，合并，去重]
    end

    subgraph SG_C_a [忘记密码]
        direction LR
        c_a[忘记密码]
        c_a --&amp;gt; c_a1[
            1. 修改mysql配置文件
            vim /etc/my.cnf.d/mysql-server.cnf  
            skip-grant-tables  不需要密码验证
        ]
        c_a --&amp;gt; c_a2[
            2. 重启mysql服务
            systemctl restart mysqld
        ]
        c_a --&amp;gt; c_a3[
            3. 无密码登录
            mysql
        ]
        c_a --&amp;gt; c_a4[
            4. 把密码修改为空
            update user set authentication_string=&apos;&apos; where user=&apos;root&apos;;
        ]
        c_a --&amp;gt; c_a5[
            5 修改mysql配置文件
            vim /etc/my.cnf.d/mysql-server.cnf  
            去掉skip-grant-tables
        ]
        c_a --&amp;gt; c_a6[
            6.重启mysql服务
            systemctl restart mysqld
        ]
        c_a --&amp;gt; c_a7[
            7.无密码登录
            mysql
        ]
        c_a --&amp;gt; c_a8[
            8. 在mysql终端里面设置密码
            alter user root@&apos;localhost&apos; identified by  &apos;NSD123456...a&apos;
        ]
    end
    %% 重新规划连接线
    开始 --&amp;gt; SG_A
    开始 --&amp;gt; SG_B
    开始 --&amp;gt; SG_C
    开始 --&amp;gt; SG_D
    c4 --&amp;gt; SG_C_a


    linkStyle 0,1,2,3,4 stroke:gray;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Markdown 扩展功能</title><link>https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/markdown-extended/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/markdown-extended/</guid><description>了解 Fuwari 中的更多 Markdown 功能</description><pubDate>Wed, 01 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;GitHub 仓库卡片&lt;/h2&gt;
&lt;p&gt;你可以添加指向 GitHub 仓库的动态卡片，页面加载时从 GitHub API 拉取仓库信息。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;Fabrizz/MMM-OnSpotify&quot;}&lt;/p&gt;
&lt;p&gt;使用代码 &lt;code&gt;::github{repo=&quot;&amp;lt;owner&amp;gt;/&amp;lt;repo&amp;gt;&quot;}&lt;/code&gt; 创建 GitHub 仓库卡片。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;::github{repo=&quot;saicaca/fuwari&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;提示框&lt;/h2&gt;
&lt;p&gt;支持以下类型的提示框：&lt;code&gt;note&lt;/code&gt; &lt;code&gt;tip&lt;/code&gt; &lt;code&gt;important&lt;/code&gt; &lt;code&gt;warning&lt;/code&gt; &lt;code&gt;caution&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;:::note
强调用户应注意的信息，即使只是浏览。
:::&lt;/p&gt;
&lt;p&gt;:::tip
帮助用户更成功的可选信息。
:::&lt;/p&gt;
&lt;p&gt;:::important
用户成功所必需的关键信息。
:::&lt;/p&gt;
&lt;p&gt;:::warning
需要用户立即关注的危险内容。
:::&lt;/p&gt;
&lt;p&gt;:::caution
某项操作可能的负面后果。
:::&lt;/p&gt;
&lt;h3&gt;基本语法&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;:::note
强调用户应注意的信息，即使只是浏览。
:::

:::tip
帮助用户更成功的可选信息。
:::
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;自定义标题&lt;/h3&gt;
&lt;p&gt;提示框的标题可以自定义。&lt;/p&gt;
&lt;p&gt;:::note[自定义标题]
这是一个自定义标题的提示。
:::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::note[自定义标题]
这是一个自定义标题的提示。
:::
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;GitHub 语法&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
同样支持 &lt;a href=&quot;https://github.com/orgs/community/discussions/16925&quot;&gt;GitHub 语法&lt;/a&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; [!NOTE]
&amp;gt; 同样支持 GitHub 语法。

&amp;gt; [!TIP]
&amp;gt; 同样支持 GitHub 语法。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;剧透&lt;/h3&gt;
&lt;p&gt;你可以为文字添加剧透效果。文本也支持 &lt;strong&gt;Markdown&lt;/strong&gt; 语法。&lt;/p&gt;
&lt;p&gt;内容 :spoiler[被隐藏了 &lt;strong&gt;嘿嘿&lt;/strong&gt;]！&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;内容 :spoiler[被隐藏了 **嘿嘿**]！
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Expressive Code 示例</title><link>https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/expressive-code/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/expressive-code/</guid><description>看看代码块在 Markdown 中使用 Expressive Code 的样子。</description><pubDate>Wed, 10 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;下面我们来探索代码块使用 &lt;a href=&quot;https://expressive-code.com/&quot;&gt;Expressive Code&lt;/a&gt; 后的效果。提供的示例基于官方文档。&lt;/p&gt;
&lt;h2&gt;Expressive Code&lt;/h2&gt;
&lt;h3&gt;语法高亮&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/key-features/syntax-highlighting/&quot;&gt;语法高亮&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;常规语法高亮&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;这段代码有语法高亮！&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;渲染 ANSI 转义序列&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;ANSI 颜色:
- 常规: [31m红色[0m [32m绿色[0m [33m黄色[0m [34m蓝色[0m [35m品红[0m [36m青色[0m
- 粗体: [1;31m红色[0m [1;32m绿色[0m [1;33m黄色[0m [1;34m蓝色[0m [1;35m品红[0m [1;36m青色[0m
- 暗色: [2;31m红色[0m [2;32m绿色[0m [2;33m黄色[0m [2;34m蓝色[0m [2;35m品红[0m [2;36m青色[0m

256 色（显示颜色 160-177）:
[38;5;160m160 [38;5;161m161 [38;5;162m162 [38;5;163m163 [38;5;164m164 [38;5;165m165[0m
[38;5;166m166 [38;5;167m167 [38;5;168m168 [38;5;169m169 [38;5;170m170 [38;5;171m171[0m
[38;5;172m172 [38;5;173m173 [38;5;174m174 [38;5;175m175 [38;5;176m176 [38;5;177m177[0m

完整 RGB 颜色:
[38;2;34;139;34m森林绿 - RGB(34, 139, 34)[0m

文本格式: [1m粗体[0m [2m暗色[0m [3m斜体[0m [4m下划线[0m
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;编辑器和终端框架&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/key-features/frames/&quot;&gt;编辑器和终端框架&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;代码编辑器框架&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;标题属性示例&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- src/content/index.html --&amp;gt;
&amp;lt;div&amp;gt;文件名注释示例&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;终端框架&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;这个终端框架没有标题&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;Write-Output &quot;这个有标题！&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;覆盖框架类型&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;看，没有框架！&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;# 如果不覆盖，这默认为终端框架
function Watch-Tail { Get-Content -Tail 20 -Wait $args }
New-Alias tail Watch-Tail
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;文本和行标记&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/key-features/text-markers/&quot;&gt;文本和行标记&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;标记整行和行范围&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// 第 1 行 - 按行号选中
// 第 2 行
// 第 3 行
// 第 4 行 - 按行号选中
// 第 5 行
// 第 6 行
// 第 7 行 - 按范围 &quot;7-8&quot; 选中
// 第 8 行 - 按范围 &quot;7-8&quot; 选中
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;选择行标记类型 (mark, ins, del)&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;function demo() {
  console.log(&apos;这行被标记为已删除&apos;)
  // 本行和下一行被标记为已插入
  console.log(&apos;这是第二行已插入的内容&apos;)

  return &apos;这行使用中性的默认标记类型&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;为行标记添加标签&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// labeled-line-markers.jsx
&amp;lt;button
  role=&quot;button&quot;
  {...props}
  value={value}
  className={buttonClassName}
  disabled={disabled}
  active={active}
&amp;gt;
  {children &amp;amp;&amp;amp;
    !active &amp;amp;&amp;amp;
    (typeof children === &apos;string&apos; ? &amp;lt;span&amp;gt;{children}&amp;lt;/span&amp;gt; : children)}
&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;在单独行上添加长标签&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// labeled-line-markers.jsx
&amp;lt;button
  role=&quot;button&quot;
  {...props}

  value={value}
  className={buttonClassName}

  disabled={disabled}
  active={active}
&amp;gt;

  {children &amp;amp;&amp;amp;
    !active &amp;amp;&amp;amp;
    (typeof children === &apos;string&apos; ? &amp;lt;span&amp;gt;{children}&amp;lt;/span&amp;gt; : children)}
&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;使用类似 diff 的语法&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;+这行被标记为已插入
-这行被标记为已删除
这是普通行
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
+这是一个实际的 diff 文件
-所有内容保持不变
也不会删除任何空白字符
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;将语法高亮与 diff 语法结合&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;  function thisIsJavaScript() {
    // 整个代码块被高亮为 JavaScript，
    // 同时我们仍然可以添加 diff 标记！
-   console.log(&apos;要删除的旧代码&apos;)
+   console.log(&apos;闪亮的新代码！&apos;)
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;标记行内的文本&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;function demo() {
  // 标记行内的任何给定文本
  return &apos;支持标记给定文本的多个匹配项&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;正则表达式&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;单词 yes 和 yep 将被标记&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;转义正斜杠&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;Test&quot; &amp;gt; /home/test.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;选择行内标记类型 (mark, ins, del)&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;function demo() {
  console.log(&apos;这些是插入和删除标记类型&apos;);
  // return 语句使用默认标记类型
  return true;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;自动换行&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/key-features/word-wrap/&quot;&gt;自动换行&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;为每个代码块配置自动换行&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// 带自动换行的示例
function getLongString() {
  return &apos;这是一个非常长的字符串，除非容器非常宽，否则很可能无法放入可用空间&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;// wrap=false 的示例
function getLongString() {
  return &apos;这是一个非常长的字符串，除非容器非常宽，否则很可能无法放入可用空间&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;配置换行缩进&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// 带 preserveIndent 的示例（默认启用）
function getLongString() {
  return &apos;这是一个非常长的字符串，除非容器非常宽，否则很可能无法放入可用空间&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;// preserveIndent=false 的示例
function getLongString() {
  return &apos;这是一个非常长的字符串，除非容器非常宽，否则很可能无法放入可用空间&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;可折叠代码段&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/plugins/collapsible-sections/&quot;&gt;可折叠代码段&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 所有这些样板设置代码将被折叠
import { someBoilerplateEngine } from &apos;@example/some-boilerplate&apos;
import { evenMoreBoilerplate } from &apos;@example/even-more-boilerplate&apos;

const engine = someBoilerplateEngine(evenMoreBoilerplate())

// 这部分代码默认可见
engine.doSomething(1, 2, 3, calcFn)

function calcFn() {
  // 可以有多个折叠部分
  const a = 1
  const b = 2
  const c = a + b

  // 这部分保持可见
  console.log(`计算结果: ${a} + ${b} = ${c}`)
  return c
}

// 到代码块结束为止的所有内容再次折叠
engine.closeConnection()
engine.freeMemory()
engine.shutdown({ reason: &apos;样板代码示例结束&apos; })
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;行号&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/plugins/line-numbers/&quot;&gt;行号&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;为每个代码块显示行号&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// 这个代码块将显示行号
console.log(&apos;来自第 2 行的问候！&apos;)
console.log(&apos;我在第 3 行&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;// 此块禁用行号
console.log(&apos;你好？&apos;)
console.log(&apos;抱歉，你知道我在哪一行吗？&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;更改起始行号&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;来自第 5 行的问候！&apos;)
console.log(&apos;我在第 6 行&apos;)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Fuwari 使用指南</title><link>https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/</guid><description>如何使用这个博客模板。</description><pubDate>Mon, 01 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;封面图片来源：[Source](https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/208fc754-890d-4adb-9753-2c963332675d/width=2048/01651-1456859105-(colour_1.5),girl,_Blue,yellow,green,cyan,purple,red,pink,_best,8k,UHD,masterpiece,male%20focus,%201boy,gloves,%20ponytail,%20long%20hair,&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;本博客模板基于 &lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt; 构建。本指南未提及的内容，可在 &lt;a href=&quot;https://docs.astro.build/&quot;&gt;Astro 文档&lt;/a&gt; 中找到答案。&lt;/p&gt;
&lt;h2&gt;文章的 Front-matter&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;---
title: 我的第一篇博客
published: 2023-09-09
description: 这是我的新 Astro 博客的第一篇文章。
image: ./cover.jpg
tags: [Foo, Bar]
category: 前端
draft: false
---
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;属性&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;文章标题&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;published&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;文章发布日期&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;description&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;文章简短描述，会显示在首页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;image&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;文章封面图路径。&amp;lt;br/&amp;gt;1. 以 &lt;code&gt;http://&lt;/code&gt; 或 &lt;code&gt;https://&lt;/code&gt; 开头：使用网络图片&amp;lt;br/&amp;gt;2. 以 &lt;code&gt;/&lt;/code&gt; 开头：图片在 &lt;code&gt;public&lt;/code&gt; 目录&amp;lt;br/&amp;gt;3. 无前缀：相对于 markdown 文件路径&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tags&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;文章标签&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;category&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;文章分类&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;draft&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;是否为草稿，草稿不会对外显示&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;文章文件存放位置&lt;/h2&gt;
&lt;p&gt;文章文件应放在 &lt;code&gt;src/content/posts/&lt;/code&gt; 目录下。你也可以创建子目录来更好地组织文章和资源。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;src/content/posts/
├── post-1.md
└── post-2/
    ├── cover.png
    └── index.md
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Markdown 示例</title><link>https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/markdown/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/markdown/</guid><description>一个简单的 Markdown 博客文章示例。</description><pubDate>Sun, 01 Oct 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;一级标题&lt;/h1&gt;
&lt;p&gt;段落之间用空行分隔。&lt;/p&gt;
&lt;p&gt;第二段。&lt;em&gt;斜体&lt;/em&gt;、&lt;strong&gt;粗体&lt;/strong&gt;和&lt;code&gt;等宽字体&lt;/code&gt;。项目列表如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一项&lt;/li&gt;
&lt;li&gt;第二项&lt;/li&gt;
&lt;li&gt;第三项&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注意：不考虑星号，实际文字从第 4 列开始缩进。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;块引用是这样写的。&lt;/p&gt;
&lt;p&gt;它们可以跨多个段落，
如果你喜欢的话。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;用 3 个破折号表示长破折号。用 2 个破折号表示范围（例如，&quot;这一切都在第 12--14 章&quot;）。三个点...会变成省略号。支持 Unicode。☺&lt;/p&gt;
&lt;h2&gt;二级标题&lt;/h2&gt;
&lt;p&gt;这是一个编号列表：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;第一项&lt;/li&gt;
&lt;li&gt;第二项&lt;/li&gt;
&lt;li&gt;第三项&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;再次注意实际文字从第 4 列开始缩进（从左侧起 4 个字符）。这是一个代码示例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 让我重申一下...
for i in 1 .. 10 { do-something(i) }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;你可能已经猜到，缩进 4 个空格。顺便说一下，你也可以使用分隔块：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;define foobar() {
    print &quot;欢迎来到风味之国！&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;（这让复制粘贴更容易）。你可以为 Pandoc 标记分隔块以进行语法高亮：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import time
# 快，数到十！
for i in range(10):
    # （但不要太快）
    time.sleep(0.5)
    print(i)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;三级标题&lt;/h3&gt;
&lt;p&gt;现在是一个嵌套列表：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;首先，准备这些材料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;胡萝卜&lt;/li&gt;
&lt;li&gt;芹菜&lt;/li&gt;
&lt;li&gt;扁豆&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;烧一些水。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;把所有东西扔进锅里，按照以下算法操作：&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;找到木勺
揭开锅盖
搅拌
盖上锅盖
把木勺摇摇欲坠地搭在锅把上
等待 10 分钟
回到第一步（或者做完后关火）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意不要让木勺掉下来。&lt;/p&gt;
&lt;p&gt;这里有一个&lt;a href=&quot;http://foo.bar&quot;&gt;网站链接&lt;/a&gt;、一个&lt;a href=&quot;local-doc.html&quot;&gt;本地文档&lt;/a&gt;和一个&lt;a href=&quot;#%E4%BA%8C%E7%BA%A7%E6%A0%87%E9%A2%98&quot;&gt;当前文档的章节标题链接&lt;/a&gt;。这里有一个脚注&lt;a href=&quot;%E8%84%9A%E6%B3%A8%E5%86%85%E5%AE%B9%E5%86%99%E5%9C%A8%E8%BF%99%E9%87%8C%E3%80%82&quot;&gt;^1&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;表格可以这样：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;尺寸&lt;/th&gt;
&lt;th&gt;材料&lt;/th&gt;
&lt;th&gt;颜色&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;皮革&lt;/td&gt;
&lt;td&gt;棕色&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;麻帆布&lt;/td&gt;
&lt;td&gt;自然色&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;玻璃&lt;/td&gt;
&lt;td&gt;透明&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;表：鞋子、尺码及其材质&lt;/p&gt;
&lt;p&gt;水平线如下：&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;这是一个定义列表：&lt;/p&gt;
&lt;p&gt;苹果
: 适合做苹果酱。
橙子
: 柑橘类！
番茄
: tomato 里没有 e。&lt;/p&gt;
&lt;p&gt;同样，文字缩进 4 个空格。&lt;/p&gt;
&lt;p&gt;这是一个行块：&lt;/p&gt;
&lt;p&gt;| 第一行
| 第二行
| 第三行&lt;/p&gt;
&lt;p&gt;图片可以这样指定：&lt;/p&gt;
&lt;p&gt;行内数学公式这样写：$\omega = d\phi / dt$。显示数学公式应该单独一行，并使用双美元符号：&lt;/p&gt;
&lt;p&gt;$$I = \int \rho R^{2} dV$$&lt;/p&gt;
&lt;p&gt;$$
\begin{equation*}
\pi
=3.1415926535
;8979323846;2643383279;5028841971;6939937510;5820974944
;5923078164;0628620899;8628034825;3421170679;\ldots
\end{equation*}
$$&lt;/p&gt;
&lt;p&gt;注意，你可以用反斜杠转义任何标点符号来原样显示，例如：`foo`、*bar* 等。&lt;/p&gt;
</content:encoded></item><item><title>在文章中嵌入视频</title><link>https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/video/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%8C%87%E5%8D%97/video/</guid><description>这篇文章演示了如何在博客文章中嵌入视频。</description><pubDate>Tue, 01 Aug 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;只需从 YouTube 或其他平台复制嵌入代码，然后粘贴到 markdown 文件中即可。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: 在文章中嵌入视频
published: 2023-10-19
// ...
---

&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;https://www.youtube.com/embed/5gIf0_xpFPI?si=N1WTorLKL0uwLsU_&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;YouTube&lt;/h2&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;https://www.youtube.com/embed/5gIf0_xpFPI?si=N1WTorLKL0uwLsU_&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h2&gt;Bilibili&lt;/h2&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;//player.bilibili.com/player.html?bvid=BV1fK4y1s7Qf&amp;amp;p=1&quot; scrolling=&quot;no&quot; border=&quot;0&quot; frameborder=&quot;no&quot; framespacing=&quot;0&quot; allowfullscreen=&quot;true&quot;&amp;gt; &amp;lt;/iframe&amp;gt;&lt;/p&gt;
</content:encoded></item></channel></rss>