Gorm(十三)主从表的判断
下面这张“速查表”把 GORM 里所有常见关系的主键、外键、主表/从表一次讲清。
背下来即可 5 秒钟拆任何模型。
速查口诀(先背再往下看)
- “外键字段落在谁,谁就是从表”
 - “被引用的一方就是主表”
 - “多对多外键在中间表,两边原表都是主表”
 
- 一对多(1 ↔ N)
 
例子:1 个部门有多名员工
type Dept struct {ID   uintName stringEmps []Employee // 主表:无外键字段
}type Employee struct {ID     uintName   stringDeptID uint // 外键字段 → 从表Dept   Dept
}
| 角色 | 表 | 主键 | 外键字段 | 外键指向 | 
|---|---|---|---|---|
| 主表 | Dept | ID | — | — | 
| 从表 | Employee | ID | DeptID | Dept.ID | 
- 多对一(N ↔ 1)——本质就是一对多反向看
 
同上,Employee 仍是从表,判断方式完全一致。
- 一对一(1 ↔ 1)
 
例子:1 用户对应 1 身份证
type User struct {ID   uintName stringCard IDCard `gorm:"foreignKey:UserID"` // 主表
}type IDCard struct {ID     uintNumber stringUserID uint  // 外键字段 → 从表
}
| 角色 | 表 | 主键 | 外键字段 | 外键指向 | 
|---|---|---|---|---|
| 主表 | User | ID | — | — | 
| 从表 | IDCard | ID | UserID | User.ID | 
- 多对多(N ↔ N)
 
例子:学生 ↔ 课程
type Student struct {ID      uintCourses []Course `gorm:"many2many:stu_course"`
}
type Course struct {ID   uintName string
}
中间表 stu_course 由 GORM 自动生成:
| 角色 | 表名 | 主键 | 外键字段 | 外键指向 | 
|---|---|---|---|---|
| 主表 | Student | ID | — | — | 
| 主表 | Course | ID | — | — | 
| 从表 | stu_course | 联合主键(student_id, course_id) | student_id / course_id | Student.ID / Course.ID | 
- 自引用(树形,1 ↔ N)
 
例子:分类树
type Category struct {ID       uintName     stringParentID *uint      // 外键字段 → 自己就是从表Parent   *Category  `gorm:"foreignKey:ParentID"`Children []Category `gorm:"foreignKey:ParentID"`
}
| 角色 | 表 | 主键 | 外键字段 | 外键指向 | 
|---|---|---|---|---|
| 主表 | Category | ID | — | — | 
| 从表 | Category | ID | ParentID | Category.ID | 
一句话总结
“外键字段落在谁,谁就是从表;被引用的对面就是主表;多对多外键在中间表。”
