很多人刚学 GORM:
会觉得:
go
gorm:"primaryKey"
gorm:"index"
gorm:"not null"
这些东西:
像"魔法字符串"。
其实:
它本质上是在告诉 GORM:
txt
数据库这一列应该怎么创建
也就是:
txt
表结构规则
一、结构体标签本质是什么
例如:
go
type User struct {
Username string `gorm:"column:username"`
}
这里:
go
gorm:"..."
本质:
是给 GORM 的说明书。
告诉它:
txt
这个字段:
在数据库里叫什么
有什么限制
怎么建立索引
二、结构体标签(重点)
| 标签 | 场景 | 数据流向 |
|---|---|---|
json:"xxx" |
前后端交互 | 前端 ↔ Go结构体 |
gorm:"column:xxx" |
数据库映射 | Go结构体 ↔ MySQL |
toml:"xxx" / ini:"xxx" |
配置文件读取 | 配置文件 → Go结构体 |
三、gorm 标签到底在干什么
例如:
go
type User struct {
ID uint `gorm:"primaryKey"`
Username string `gorm:"uniqueIndex;not null"`
}
GORM:
看到后:
会自动生成:
sql
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(255) NOT NULL UNIQUE
);
也就是说:
txt
gorm 标签
本质是在控制 SQL
四、primaryKey(主键)
示例
go
ID uint `gorm:"primaryKey"`
五、主键是什么
主键:
本质:
txt
每条数据的唯一身份证
例如:
| id | username |
|---|---|
| 1 | zhangsan |
| 2 | lisi |
这里:
txt
id
就是主键
六、主键三个核心特性
1. 唯一
txt
不能重复
不能:
txt
两个用户都是 id=1
2. 不能为空
每条数据:
必须有主键。
3. 一张表通常只有一个主键
因为:
txt
身份证只能有一个
七、GORM 里的 primaryKey 默认自增
例如:
go
ID uint `gorm:"primaryKey"`
插入时:
go
db.Create(&user)
你不用写:
go
ID:1
MySQL:
会自动:
txt
1
2
3
4
增长。
八、uniqueIndex(唯一索引)
示例
go
Username string `gorm:"uniqueIndex"`
九、作用
txt
值不能重复
例如:
用户名。
十、为什么用户名必须唯一
如果:
txt
两个用户都叫 zhangsan
登录:
就乱了。
所以:
需要:
txt
唯一索引
十一、底层 SQL
GORM:
会生成:
sql
UNIQUE INDEX
数据库:
自动保证:
txt
不能重复
十二、index(普通索引)
示例
go
Phone string `gorm:"index"`
十三、索引到底是什么(重点)
很多新人:
只知道:
txt
WHERE 查询
但:
真正决定查询速度的是:
txt
索引
十四、没有索引会怎样
例如:
sql
SELECT * FROM users
WHERE phone='123'
如果没索引:
数据库:
只能:
txt
一行一行找
这叫:
txt
全表扫描
非常慢。
十五、有索引会怎样
有索引后:
数据库:
类似:
txt
查目录
直接定位。
速度:
会快非常多。
十六、为什么索引像书目录
例如:
字典。
你不会:
txt
第一页开始翻
而是:
txt
查目录
索引:
本质:
就是:
txt
数据库目录
十七、普通索引 vs 唯一索引
| 类型 | 能重复吗 | 查询快吗 |
|---|---|---|
| index | 能 | 快 |
| uniqueIndex | 不能 | 快 |
十八、not null(不能为空)
示例
go
Username string `gorm:"not null"`
十九、作用
数据库:
会限制:
txt
这一列必须有值
不能:
txt
NULL
二十、为什么需要 not null
例如:
用户名。
你总不能:
txt
用户名为空
否则:
系统逻辑会炸。
二十一、type 指定字段类型
示例
go
Phone string `gorm:"type:char(11)"`
或者:
go
Username string `gorm:"type:varchar(20)"`
二十二、char 和 varchar 区别(重点)
很多新人:
这里会懵。
char
txt
固定长度
例如:
txt
char(11)
永远:
txt
占11位
varchar
txt
可变长度
例如:
txt
varchar(20)
最多20。
实际多少占多少。
二十三、什么时候用 char
例如:
手机号:
txt
长度固定11位
适合:
txt
char(11)
二十四、什么时候用 varchar
例如:
用户名:
txt
长度不固定
适合:
txt
varchar
二十五、default 默认值
示例
go
Status int `gorm:"default:1"`
二十六、作用
插入数据时:
如果没传:
自动:
txt
使用默认值
二十七、真实场景
例如:
用户状态:
txt
1 正常
0 封禁
注册时:
默认:
txt
1
二十八、comment 注释
示例
go
Username string `gorm:"comment:用户名"`
二十九、作用
只给开发人员看。
数据库里:
会显示:
txt
字段说明
但:
txt
不影响功能
三十、多个标签同时写
真实开发:
经常这样:
go
type User struct {
ID uint `gorm:"primaryKey"`
Username string `gorm:"type:varchar(20);uniqueIndex;not null;comment:用户名"`
Phone string `gorm:"type:char(11);index"`
Status int `gorm:"default:1"`
}
三十一、分号是什么意思
txt
多个规则
例如:
go
gorm:"type:varchar(20);not null"
表示:
txt
varchar(20)
+
不能为空
三十二、GORM 自动建表
很多时候:
go
db.AutoMigrate(&User{})
GORM:
会根据:
txt
结构体 + gorm标签
自动生成表。
三十三、真实项目最常见字段
真实开发:
几乎都有:
go
type User struct {
ID uint `gorm:"primaryKey"`
Username string `gorm:"type:varchar(20);uniqueIndex;not null"`
Password string `gorm:"type:varchar(255);not null"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
三十四、CreatedAt 和 UpdatedAt
GORM:
会自动维护:
txt
创建时间
更新时间
三十五、DeletedAt(软删除)
go
DeletedAt gorm.DeletedAt
表示:
txt
软删除
删除时:
不是:
sql
DELETE
而是:
sql
UPDATE deleted_at = NOW()
三十六、为什么真实项目大量使用软删除
因为:
很多数据:
txt
不能真删
例如:
- 订单
- 用户
- 日志
需要:
txt
可恢复
三十七、gorm 标签真正核心思想
你一定要理解:
txt
gorm 标签
本质是在描述数据库表结构
它不是:
txt
Go语法
而是:
txt
数据库规则
三十八、最后总结
GORM 标签:
本质:
txt
控制数据库字段规则
最核心标签:
| 标签 | 作用 |
|---|---|
| primaryKey | 主键 |
| uniqueIndex | 唯一索引 |
| index | 普通索引 |
| not null | 非空 |
| type | 指定字段类型 |
| default | 默认值 |
| comment | 注释 |
真正核心理解:
txt
结构体 = Go里的数据模型
gorm标签 = 数据库规则
GORM = 自动帮你生成SQL