
本文介绍如何在基于 dao 模式的多数据库架构中统一 id 字段设计,推荐采用 uuid v4 作为业务层与数据层解耦的通用标识符,兼顾 sql 与 mongodb 等异构数据库的兼容性、唯一性与可移植性。
本文介绍如何在基于 dao 模式的多数据库架构中统一 id 字段设计,推荐采用 uuid v4 作为业务层与数据层解耦的通用标识符,兼顾 sql 与 mongodb 等异构数据库的兼容性、唯一性与可移植性。
在实现支持多数据库(如 PostgreSQL/MySQL 与 MongoDB)的 DAO 架构时,ID 字段的类型不一致是典型痛点:SQL 数据库习惯用自增 uint64 或序列 ID,而 MongoDB 原生使用 ObjectID(12 字节 BSON 类型)。若强行在领域模型中暴露底层 ID 类型(如 interface{} 或泛型 ID 结构),将导致业务逻辑耦合、序列化复杂、API 不一致,且难以保障跨库查询的一致性。
推荐方案:以 UUID v4 作为统一业务主键(UID)
UUID v4 是完全随机生成的 128 位标识符(格式如 f47ac10b-58cc-4372-a567-0e02b2c3d479),具备全局唯一、无序、无需中心协调、语言与数据库无关等优势,完美适配多持久化后端场景。
✅ 数据层设计示例
-
SQL 数据库(如 PostgreSQL)
CREATE TABLE users ( id SERIAL PRIMARY KEY, -- 内部自增 ID,仅用于外键/索引优化 uid UUID NOT NULL UNIQUE, -- 业务主键,对外暴露,所有 DAO 操作以此为依据 name TEXT, created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_users_uid ON users(uid);
-
MongoDB 集合
{ "_id": ObjectId("65a1b2c3d4e5f67890123456"), "uid": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "name": "Alice", "created_at": { "$date": "2024-01-01T00:00:00Z" } }✅
_id保留为 MongoDB 原生 ObjectID,用于高效索引与分片;uid字段单独存储 UUID,作为跨库查询与业务逻辑的唯一锚点。
✅ Go 语言结构体与 DAO 实现示意
type User struct {
ID int64 `db:"id"` // SQL 内部 ID(可选,非业务主键)
UID string `db:"uid"` // 统一业务主键 —— 所有 DAO 方法均以此为准
Name string `db:"name"`
}
// DAO 接口定义(数据库无关)
type UserRepository interface {
FindByUID(ctx context.Context, uid string) (*User, error)
Create(ctx context.Context, u *User) error
UpdateByUID(ctx context.Context, uid string, updates map[string]interface{}) error
}
// 使用 github.com/google/uuid 生成 v4 UUID
import "github.com/google/uuid"
func NewUser(name string) *User {
return &User{
UID: uuid.NewString(), // 每次创建新用户,生成唯一 UID
Name: name,
}
}✅ 关键优势与注意事项
-
解耦清晰:业务逻辑、REST API 响应、缓存 Key、消息队列 payload 全部使用
UID,彻底屏蔽底层数据库 ID 差异; -
查询一致:DAO 层所有
FindByUID、UpdateByUID等方法行为跨数据库完全一致,上层服务无需感知数据源; - 安全可靠:UUID v4 不含时间/机器信息,避免泄露系统细节;其 128 位熵值在合理规模下碰撞概率可忽略(远低于硬件故障率);
-
性能提示:UUID 作为主键在 SQL 中可能影响插入性能(非顺序写入),可通过
uuid-ossp扩展(PostgreSQL)或应用层预生成 + 批量插入缓解;MongoDB 中uid字段建议建立独立索引(db.users.createIndex({uid: 1})); -
迁移友好:存量系统升级时,可为老数据批量生成 UUID 并填充
uid字段,平滑过渡。
综上,放弃“适配多种 ID 类型”的复杂抽象,转而采用标准化、广泛支持的 UUID v4 作为跨数据库统一标识符,是兼顾简洁性、健壮性与可维护性的最佳实践。


















