標準 UUID:05ba463f-1dab-471f-81c7-58e0b06f35f0 (36 字符)。
UUID 128 位 = 16 字節。移除橫線後 32 字符 Hex → UNHEX() → 16 字節二進制 → 存入 BINARY(16)。
UUID_TO_BIN()/BIN_TO_UUID(),舊版自建)-- 字符串 UUID → BINARY(16) (RFC 4122 標準字節序調整)
CREATE FUNCTION `GuidToBinary`($Data VARCHAR(36)) RETURNS BINARY(16)
BEGIN
DECLARE $Result BINARY(16) DEFAULT NULL;
IF $Data IS NOT NULL THEN
SET $Data = REPLACE($Data, '-', '');
-- 關鍵:調整 time_low/time_mid/time_hi_and_version 字節序為大端序
SET $Result = CONCAT(
UNHEX(SUBSTRING($Data, 7, 2)), UNHEX(SUBSTRING($Data, 5, 2)),
UNHEX(SUBSTRING($Data, 3, 2)), UNHEX(SUBSTRING($Data, 1, 2)),
UNHEX(SUBSTRING($Data, 11, 2)), UNHEX(SUBSTRING($Data, 9, 2)),
UNHEX(SUBSTRING($Data, 15, 2)), UNHEX(SUBSTRING($Data, 13, 2)),
UNHEX(SUBSTRING($Data, 17, 16))
);
END IF;
RETURN $Result;
END;
-- BINARY(16) → 標準 UUID 字符串
CREATE FUNCTION `ToGuid`($Data BINARY(16)) RETURNS CHAR(36) CHARSET utf8
BEGIN
DECLARE $Result CHAR(36) DEFAULT NULL;
IF $Data IS NOT NULL THEN
SET $Result = CONCAT(
HEX(SUBSTRING($Data, 4, 1)), HEX(SUBSTRING($Data, 3, 1)),
HEX(SUBSTRING($Data, 2, 1)), HEX(SUBSTRING($Data, 1, 1)), '-',
HEX(SUBSTRING($Data, 6, 1)), HEX(SUBSTRING($Data, 5, 1)), '-',
HEX(SUBSTRING($Data, 8, 1)), HEX(SUBSTRING($Data, 7, 1)), '-',
HEX(SUBSTRING($Data, 9, 2)), '-', HEX(SUBSTRING($Data, 11, 6))
);
END IF;
RETURN $Result;
END;
-- 簡化版:直接生成二進制 UUID (無字節序調整,適合純主鍵)
CREATE FUNCTION `UUIDTOBIN`() RETURNS BINARY(16)
BEGIN
DECLARE my_uuid CHAR(36);
SET my_uuid = UUID();
RETURN CONCAT(
UNHEX(LEFT(my_uuid, 8)), UNHEX(MID(my_uuid, 10, 4)),
UNHEX(MID(my_uuid, 15, 4)), UNHEX(MID(my_uuid, 20, 4)),
UNHEX(RIGHT(my_uuid, 12))
);
END;
CREATE TABLE users (
id BINARY(16) PRIMARY KEY, -- 或 VARBINARY(16)
name VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
-- 插入
INSERT INTO users (id, name) VALUES (GuidToBinary('05ba463f-1dab-471f-81c7-58e0b06f35f0'), 'Alice');
-- 查詢 (應用層轉換或 SQL 轉換)
SELECT ToGuid(id) AS uuid, name FROM users WHERE id = GuidToBinary('...');
-- 或 MySQL 8.0+ 內置函數
SELECT BIN_TO_UUID(id) FROM users;
INSERT INTO users (id) VALUES (UUID_TO_BIN(UUID()));
| 函數 | 語法 | 說明 |
|---|---|---|
UUID_TO_BIN() | UUID_TO_BIN(uuid [, swap_flag]) | swap_flag=1 將 time_low/time_mid 移至高位,提升插入局部性 (推薦主鍵用 1) |
BIN_TO_UUID() | BIN_TO_UUID(bin [, swap_flag]) | 對應反向轉換,swap_flag 需與存儲時一致 |
IS_UUID() | IS_UUID(str) | 驗證字符串是否合法 UUID 格式 |
| 指標 | CHAR(36) UUID | BINARY(16) + swap=1 |
|---|---|---|
| 主鍵索引大小 | ~1.2 GB | ~550 MB |
| 批量插入耗時 | 基準 | -40% (順序性提升) |
| 點查 QPS | 基準 | +15% (緩存友好) |
| 範圍掃描 | 極慢 | 可用 (時間有序) |
swap_flag 設置。BINARY(16) 到 byte[]/string,避免編碼損壞。UUID 存儲鐵律:移除橫線 → 二進制存儲 → 啟用字節序優化。MySQL 8.0+ 內置函數已成熟,舊版本自建函數同理。這是分佈式系統主鍵設計的「黃金標準」,兼顧全局唯一、寫入效能、存儲空間與查詢速度。