
本文详解如何使用 gorm 的结构体标签(struct tags)正确声明跨多个字段的唯一复合索引,确保数据库层面的数据完整性,并避免常见配置错误。
本文详解如何使用 gorm 的结构体标签(struct tags)正确声明跨多个字段的唯一复合索引,确保数据库层面的数据完整性,并避免常见配置错误。
在 GORM(v2)中,实现多列唯一约束(即复合唯一索引)不能通过为每个字段单独添加 unique 标签来完成——那样会创建两个独立的单列唯一索引,而非一个覆盖多列的联合索引。正确做法是:为多个字段指定相同的索引名,并统一启用 unique 选项,GORM 将据此自动在迁移时创建一个包含所有标注字段的唯一复合索引。
以下是一个标准示例:
type Something struct {
gorm.Model
First string `gorm:"index:idx_first_second,unique"`
Second string `gorm:"index:idx_first_second,unique"`
Third string `gorm:"column:third_name"` // 非索引字段,仅作示意
}✅ 此配置将生成如下 SQL(以 PostgreSQL 为例):
CREATE UNIQUE INDEX idx_first_second ON somethings (first, second);
⚠️ 注意事项:
- 索引名(如 idx_first_second)必须完全一致,且推荐采用语义化命名(如 idx_
_ ),便于维护与排查; - 所有参与复合索引的字段都需显式标注 index:
,unique,缺一不可; - GORM 不支持在 struct tag 中直接指定字段顺序;索引列顺序由结构体中字段声明的先后顺序决定(即 First 在前、Second 在后 → 索引按 (first, second) 排序);
- 若需额外控制索引行为(如降序、表达式索引等),应使用 db.Session().Migrator().CreateIndex() 手动管理,而非依赖 struct tag;
- 迁移前请确保已调用 AutoMigrate 或 Migrate,且数据库用户具备 CREATE INDEX 权限。
总结:多列唯一索引的本质是「单个索引对象 + 多个字段 + unique 属性」,GORM 通过共享索引名实现这一语义。切勿误用 sql: 标签(已弃用)或分散的 unique 标签——它们无法达成复合约束目标。遵循上述模式,即可安全、可复现地构建符合业务需求的数据完整性保障机制。










