
1) “结构体 ↔ 数据库表”
一般情况下:
一个 type Xxx struct { ... }(模型结构体) ↔ 数据库里一张表
结构体里的字段 ↔ 表里的列(字段)
比如你这个 UserModel,迁移后通常会对应一张 user_models / users 之类的表(具体表名取决于你的命名策略)。
2) “标签 ↔ 列的规则”
字段上写的:
gorm:"size:16":影响数据库列类型/长度等
json:"username":影响接口返回的 JSON 字段名
json:"-":表示接口不会返回该字段(比如密码)
3) 什么时候会真的创建表?
必须在代码里做类似操作(举例):
db.AutoMigrate(&models.UserModel{}, &models.OtherModel{})
只有被 AutoMigrate(或你自己写的迁移脚本)传进去的模型,才会被创建/更新成表。
所以不是 “models 目录下每个文件都会变成表”,而是 “你迁移时注册/迁移的那些模型 struct 会变成表”。
4) “内容会变成表里面的内容”是什么意思?
结构体定义(字段/标签) 会决定表结构(列名、类型、长度、索引等)
结构体里的数据(你创建/查询出来的值) 才是表里的行数据
也就是说:struct 是“表的蓝图”,你 Create/Find 时才是“写入/读取数据”
LastLoginAt 和 LastLoginTime 有什么区别?
它们表达“上次登录时间”这件事,但存储方式不同:
A. LastLoginTime int64
通常表示 Unix 时间戳(秒或毫秒):
例如:1700000000(秒)
或 1700000000000(毫秒)
优点:
存得很简单、跨语言好用、占空间小
缺点:
不直观,要转换
容易搞错单位(秒/毫秒)
数据库层面做时间函数/范围查询时没 datetime 方便(看数据库)
B. LastLoginAt time.Time / *time.Time
表示 真正的时间类型:
在 Go 里是 time.Time
在数据库里通常会映射成 datetime/timestamp 之类
优点:
语义清晰,可读性好
数据库做时间范围查询、排序、时间函数更顺手
缺点:
JSON 输出时是字符串(例如 RFC3339),前端要按字符串解析
需要考虑时区/序列化格式
还有一个关键差别:time.Time vs *time.Time
time.Time:永远有值(默认是 0001-01-01...),很难表达“从未登录”
*time.Time:可以为 nil,数据库可为 NULL,更适合“从未登录过”的场景
你该选哪个?
大多数项目更推荐:
用 *time.Time LastLoginAt(允许 NULL)
或者你想 JSON 简单一点就用 int64 时间戳,但要统一单位(强烈建议统一毫秒或秒并写注释)
你现在注释写了“单位为秒”,如果继续用 int64 就保持秒;如果改成毫秒要改注释并保证全项目一致。
评论 (0)