跳到主要内容

在内置全局 ID 功能标志推出之前,迁移工具曾提供 WithGlobalUniqueID 选项允许用户将迁移模式以使用全局唯一 ID。 该选项现已弃用,取而代之用户应改用全局 ID 功能标志。 现有用户可通过以下步骤迁移模式以使用全局唯一ID。

之前的解决方案利用一个名为 ent_types 的数据表来存储 Ent 模式及其相关的 id 范围之间的映射信息。 新的解决方案使用一个静态配置文件来存储这一映射。 为迁移到新的 全球唯一 ID 功能,可以使用 entfix 命令来将已有的 ent_types 数据表迁移到新的配置文件。

注意

请注意 “ent_types” 数据表可能在不同的应用程序部署环境中会有差异。 特别是使用自动迁移而不是版本化迁移时。 请检查所有部署的所有 “ent_types” 数据表都是一样的。 如果不是这样你可能无法转换为新的全球唯一 ID 功能。

第一步是运行如下命令安装 entfix 工具:

go install entgo.io/ent/cmd/entfix@latest

下一步可以运行 entfix globalid 命令迁移模式到全球唯一 ID 功能。 此命令需要访问数据库读取 ent_types 数据表。 你可以连接到部署的数据库或连接到读取副本,若是版本化迁移连接所有迁移应用后的临时数据库。

entfix globalid --dialect mysql --dsn "root:pass@tcp(localhost:3306)/app" --path ./ent
IMPORTANT INFORMATION

'entfix globalid' will convert the allocated id ranges for your nodes from the
database stored 'ent_types' table to the new static configuration on the ent
schema itself.

Please note, that the 'ent_types' table might differ between different environments
where your app is deployed. This is especially true if you are using
auto-migration instead of versioned migrations.

Please check, that all 'ent_types' tables for all deployments are equal!

Only 'yes' will be accepted to approve.

Enter a value: yes

Success! Please run code generation to complete the process.

通过再次运行代码生成完成迁移后。你应该看到在生成的代码中有一个新的文件 internal/globalid.go , 仅包含由 const IncrementStarts 开始的一行代码,这表明迁移过程成功完成了。 最后一步是确保迁移设置中移除 migrate.WithGlobalUniqueID(true) 选项。

可选: 保留 ent_types 数据表

你可能期望保留 ent_types 数据表而不是删除它,直到确认无需再进行回滚计算。可以通过使用 Atlas 复合模式做到这一点:

schema "ent" {}

table "ent_types" {
schema = schema.ent
collate = "utf8mb4_bin"
column "id" {
null = false
type = bigint
unsigned = true
auto_increment = true
}
column "type" {
null = false
type = varchar(255)
}
primary_key {
columns = [column.id]
}
index "type" {
unique = true
columns = [column.type]
}
}

通用 ID(废弃的迁移选项)

默认情况下,SQL 主键在每个表中从 1 开始计数,这意味着不同类型的多个实体可能共享相同的ID。 这与 AWS Neptune 不同,后者使用 UUID 作为节点 ID。

如果你使用 GraphQL 则不能很好地运行,因为它要求对象 ID 是唯一的。

若为项目开启通用 ID 支持,将 WithGlobalUniqueID 选项传入迁移。

备注

版本化迁移用户在使用 MySQL 5.* 数据库上使用 WithGlobalUniqueID 应遵从 此文档

package main

import (
"context"
"log"

"<project>/ent"
"<project>/ent/migrate"
)

func main() {
client, err := ent.Open("mysql", "root:pass@tcp(localhost:3306)/test")
if err != nil {
log.Fatalf("failed connecting to mysql: %v", err)
}
defer client.Close()
ctx := context.Background()
// Run migration.
if err := client.Schema.Create(ctx, migrate.WithGlobalUniqueID(true)); err != nil {
log.Fatalf("failed creating schema resources: %v", err)
}
}

它如何工作? ent 迁移为每个实体(表)分配 1<<32 范围的 ID,并将这些信息存储在生成的代码中(internal/globalid.go)。 例如类型 A 的 ID 范围是 [1,4294967296),类型 B 的范围是 [4294967296,8589934592) 等。

注意如果此选项被启用,可能存在的表的最大数量是 65535