> ## Documentation Index
> Fetch the complete documentation index at: https://villagesql.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MySQL 的 vsql_uuid 扩展

> vsql_uuid 扩展为 MySQL 添加原生的 16 字节 uuid 列类型，并在 SQL 中生成版本 1、3、4、5、6 和 7 的 UUID。

MySQL 将 UUID 存储为文本，或存储为需要您手动转换的 `BINARY(16)`。
`vsql_uuid` 添加了一个真正的 `uuid` 列类型，它占用 16 字节，以常见的
36 字符形式显示，并按自己的比较规则排序。它还能生成版本 1、3、4、5、6 和 7，
而 MySQL 自带的 `UUID()` 只能生成版本 1。

| | |
| - | - |
| **维护者** | VillageSQL |
| **源代码和完整文档** | [villagesql/vsql-uuid](https://github.com/villagesql/vsql-uuid) |
| **许可证** | GPL-2.0 |

## 安装

如果您使用安装脚本、Docker 镜像或发行版压缩包安装了 VillageSQL，
`vsql_uuid.veb` 已经位于服务器的 `lib/veb/` 目录中。
用一条语句将它安装到服务器中：

```sql theme={null}
INSTALL EXTENSION vsql_uuid;
```

确认它已存在：

```sql theme={null}
SELECT EXTENSION_NAME
FROM INFORMATION_SCHEMA.EXTENSIONS
WHERE EXTENSION_NAME = 'vsql_uuid';
```

```
+----------------+
| EXTENSION_NAME |
+----------------+
| vsql_uuid      |
+----------------+
```

要自行构建，请按照[存储库](https://github.com/villagesql/vsql-uuid)中的
构建说明进行操作。

## 新增内容

### uuid 类型

将列声明为 `uuid`。它占用 16 字节，可以用作主键。

```sql theme={null}
CREATE TABLE orders (
    id     uuid PRIMARY KEY,
    placed DATETIME,
    total  DECIMAL(8,2)
);
```

### 函数

| 函数 | 返回 | 作用 |
| - | - | - |
| `UUID_V1()` | `uuid` | 基于时间，使用主机的 MAC 地址 |
| `UUID_V1MC()` | `uuid` | 基于时间，使用随机多播地址代替 MAC 地址 |
| `UUID_V3(namespace, name)` | `uuid` | 基于名称，MD5 |
| `UUID_V4()` | `uuid` | 随机 |
| `UUID_V5(namespace, name)` | `uuid` | 基于名称，SHA-1 |
| `UUID_V6()` | `uuid` | 按时间排序，在同一连接内单调递增 |
| `UUID_V7()` | `uuid` | 按 Unix 毫秒时间戳排序 |
| `UUID_NIL()`、`UUID_MAX()` | `uuid` | 全零值和全一值 |
| `UUID_NS_DNS()`、`UUID_NS_URL()`、`UUID_NS_OID()`、`UUID_NS_X500()` | 文本 | RFC 9562 命名空间常量，供 `UUID_V3` 和 `UUID_V5` 使用 |
| `UUID_IS_VALID(s)` | 整数 | 字符串能被 `uuid` 列接受时为 1，否则为 0 |
| `UUID_VERSION(u)` | 整数 | 版本半字节 |
| `UUID_TIMESTAMP(u)` | 文本 | 内嵌的时间，格式为 UTC 的 `'YYYY-MM-DD HH:MM:SS'`；不携带时间的版本返回 NULL |
| `UUID_EPOCH(u)` | 整数 | 同一时间，以 Unix 秒表示 |
| `UUID_COMPARE(a, b)` | 整数 | -1、0 或 1 |

## 示例

使用版本 7 标识符作为主键，这样后写入的行会排在先写入的行之后，
然后读回版本号：

```sql theme={null}
INSERT INTO orders VALUES (UUID_V7(), NOW(), 42.50);
DO SLEEP(0.01);
INSERT INTO orders VALUES (UUID_V7(), NOW(), 19.99);

SELECT UUID_VERSION(id) AS version, total FROM orders ORDER BY id;
```

```
+---------+-------+
| version | total |
+---------+-------+
|       7 | 42.50 |
|       7 | 19.99 |
+---------+-------+
```

从名称派生一个稳定的标识符：

```sql theme={null}
SELECT UUID_V5(UUID_NS_DNS(), 'villagesql.com') AS dns_uuid;
```

```
+--------------------------------------+
| dns_uuid                             |
+--------------------------------------+
| fc51a94b-5261-5a4c-a5ec-48199b58d67b |
+--------------------------------------+
```

> [!NOTE]
>
> 上面的顺序只在跨毫秒时成立。版本 7 将毫秒时间戳放在最前面，
> 其余部分随机填充，没有计数器，因此同一毫秒内生成的两个值
> 彼此之间的排序是随机的。这就是示例用两条单独的语句插入两行的原因。
> 需要比这更细的排序时，请使用 `UUID_V6()`。

> [!NOTE]
>
> `uuid` 列接受字符串字面量，但不接受字符串表达式。因此
> `INSERT INTO orders VALUES ('550e8400-e29b-41d4-a716-446655440000', ...)`
> 可以执行，而 `INSERT INTO orders VALUES (UUID(), ...)` 会失败并报
> `ERROR 3219 (HY000): Incorrect uuid value: cannot implicitly cast string
>     expression. Use explicit conversion for column 'id' at row 1`。请改用上面
> 的某个函数生成该值。

## 另请参阅

* [MySQL 中的 UUID](https://villagesql.com/docs/en/guides/uuids.md) — 每个版本的用途以及如何选择
* [主键策略](https://villagesql.com/docs/en/guides/primary-key-strategies.md) — UUID 键在哪些情况下有帮助，在哪些情况下有代价
* [安装扩展](https://villagesql.com/docs/zh/extensions/install.md) — `INSTALL EXTENSION` 如何工作，以及服务器在哪里查找包
* [可用扩展](https://villagesql.com/docs/zh/extensions/catalog) — 完整目录
* [villagesql/vsql-uuid](https://github.com/villagesql/vsql-uuid) — 源代码、构建说明和已知限制


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.