原始操作记录 #

UUID 基于 16 进制,由 32 位小写的 16 进制数字组成,如下:

aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee

MySQL 实现了 UUID,并且提供 UUID() 函数方便用户生成 UUID。在 MySQL 的 UUID() 函数中,前三组数字从时间戳中生成,第四组数字暂时保持时间戳的唯一性,第五组数字是一个 IEEE 802 节点标点值,保证空间唯一。使用 UUID() 函数,可以生成时间、空间上都独一无二的值。据说只要是使用了 UUID,都不可能看到两个重复的 UUID 值。当然,这个只是在理论情况下。

UUID 是 32 位,因为 MySQL 生成的 UUID 有四个中划线,所以在 utf8 字符集里,长度为 36 位。

在 MySQL 中创建表的时候,无法在默认值中设置UUID函数,实际上其它函数除TIMESTAMP之外都不可以。

所以,只能用触发器来实现。

首先,创建一个表:

TEXT
CREATE TABLE `test` (
  `uuid` varchar(36) NOT NULL,
  `content` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`uuid`)
)

然后,创建一个触发器:

SQL
DELIMITER $$

CREATE
    TRIGGER `sddci`.`test` BEFORE INSERT
    ON `sddci`.`test`
    FOR EACH ROW BEGIN
        IF new.uuid='' OR new.uuid IS NULL THEN
            SET new.uuid = UUID();
        END IF;
    END$$

好了,测试一下触发器工作是否正常:

SQL
INSERT INTO `test` (content) VALUES ('www.aspone.me');
SELECT * FROM `test`;

结果出来了:

TEXT
uuid	content
f6a57736-eb23-11e7-8ac5-525400ed11ea	www.aspone.me

完成

但是,MySQL 会返回一个警告:

TEXT
1 queries executed, 1 success, 0 errors, 1 warnings
查询:insert into `test` (content) values ('www.aspone.me')
共 1 行受到影响, 1 个警告
执行耗时   : 0.025 sec
传送时间   : 0 sec
总耗时      : 0.025 sec
Warning Code : 1364
Field 'uuid' doesn't have a default value

当然,我们忽略这个警告,因为语句里并未写入主键 'uuid' 的值,这个值是在触发器里生成的。

关键理解 #

这类笔记最重要的不是把命令背下来,而是弄清楚它解决的是什么问题、依赖什么环境、执行后会改变什么。以后再次遇到类似情况时,可以先根据标题判断问题方向,再对照原始命令确认是否适合当前系统版本。

如果命令中包含具体路径、网卡名、磁盘名、进程名、IP 地址、端口号、用户名称或软件版本,实际执行时都要替换成自己环境中的真实值。不要直接照抄示例里的占位内容。

验证方法 #

执行完成后不要只看命令是否返回成功,还应结合服务状态、配置文件内容、日志输出和实际访问结果一起判断。常用检查命令包括 systemctl statusjournalctl -xeip addrip routecatgrep 等。

如果验证结果和预期不一致,建议先不要继续叠加更多修改,而是回到第一步检查环境差异。很多问题并不是命令本身错误,而是当前系统版本、软件版本、路径名称或权限条件与原记录不一致。

注意事项 #

如果是在远程服务器上操作,尤其是网络、SSH、DNS、防火墙相关配置,必须提前准备控制台、VNC、快照或备份,避免因为配置错误导致无法重新连接。

对于旧文章中的命令,还要考虑软件版本变化。浏览器 flags、Linux 发行版默认配置、Python 包版本、Windows 系统设置都会随着时间调整。再次使用时,最好把这篇记录当成排查思路,而不是绝对固定的唯一答案。

小结 #

这篇记录可以作为一个快速索引:先看标题确认问题类型,再看原始命令找到核心操作,最后结合验证方法确认是否真正生效。这样既保留了早期备忘的简洁性,也能减少以后重复排查的时间。