You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MySQL 8的「集合」表中设置UUID为默认主键

解决MySQL 8中JSON文档_id与主键UUID一致的问题

要让JSON文档里的_id和自动生成的UUID主键保持一致,有两种实用方案:

方案一:用触发器自动同步(推荐)

先把表结构改成主键自动生成UUID,再通过触发器把主键的UUID同步到JSON文档里:

1. 修改表结构

把原来从JSON提取的_id生成列,改成带UUID默认值的普通列:

ALTER TABLE `users`
-- 改成自动生成紧凑格式的二进制UUID(16字节,更省空间)
MODIFY COLUMN `_id` varbinary(16) NOT NULL DEFAULT (UUID_TO_BIN(UUID(), TRUE)),
-- 更新JSON Schema校验规则,确保doc包含_id字段
DROP CONSTRAINT `$val_strict`,
ADD CONSTRAINT `$val_strict` CHECK (json_schema_valid('{"type":"object","required":["_id"],"properties":{"_id":{"type":"string"}}}',`doc`)) /*!80016 NOT ENFORCED */;

如果偏好36字节的字符串格式UUID,把默认值改成(CAST(UUID() AS BINARY)),同时把varbinary(16)改成varbinary(36)。

2. 创建同步触发器

插入前自动把主键的二进制UUID转成字符串,写入JSON文档的_id字段:

DELIMITER //
CREATE TRIGGER sync_users_doc_id BEFORE INSERT ON users
FOR EACH ROW
BEGIN
    -- 把紧凑格式的二进制UUID转成标准字符串(如果用36字节格式,直接用CAST(NEW._id AS CHAR))
    SET NEW.doc = JSON_SET(COALESCE(NEW.doc, JSON_OBJECT()), '$._id', BIN_TO_UUID(NEW._id, TRUE));
END //
DELIMITER ;

这样不管插入时有没有给doc的_id,触发器都会自动用主键的UUID填充,保证两者完全一致。如果要支持更新主键(不建议这么做),可以再建一个BEFORE UPDATE触发器同步。

方案二:插入时手动指定UUID

如果不想用触发器,每次插入时手动生成UUID,同时赋值给主键和JSON文档:

-- 生成UUID并转成二进制(紧凑格式)
SET @uuid_str = UUID();
SET @uuid_bin = UUID_TO_BIN(@uuid_str, TRUE);

-- 插入数据时同时指定主键和doc里的_id
INSERT INTO users (_id, doc)
VALUES (@uuid_bin, JSON_OBJECT('_id', @uuid_str, 'username', 'lisi', 'age', 28));

这种方式需要每次插入都显式处理UUID,适合对插入逻辑有完全控制权的场景。

内容的提问来源于stack exchange,提问作者Azucena H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 14:50:37