应使用独立的 user_preferences 表存储动态偏好,以 JSON 字段支持灵活扩展、区分"未设置"与"显式关闭",并通过乐观锁和事务封装避免并发覆盖。如何用 Go 实现可扩展的用户订阅偏好存储直接存数据库字段不是不行,但硬编码 email_newsletter、push_promo 这类布尔字段会快速失控------加个新渠道就得改表、改 struct、改所有 CRUD 逻辑。真正可持续的做法是把"偏好"当独立资源建模。用一张 user_preferences 表,字段至少包含:user_id(外键)、preference_key(如 "weekly_digest")、value(JSON 或布尔/字符串,推荐 JSON)、updated_atGo struct 不要嵌套一堆 bool 字段,而是用 map[string]json.RawMessage 或自定义类型(如 type Preference map[string]interface{})承载动态键值避免用 sql.NullBool 存每个偏好------它无法表达"未设置"和"明确关闭"的区别,而业务上这两者常需不同处理为什么用 JSON 字段比多个布尔列更可靠看似多一次序列化/反序列化,实则换来关键灵活性:新增偏好无需 DDL 变更,灰度发布时可对部分用户写入新 key,老代码读不到就忽略,不会 panic。value 字段类型选 JSON(PostgreSQL/MySQL 5.7+)或 TEXT(需手动 json.Marshal/json.Unmarshal),别用 BOOLEAN 或 VARCHAR(10)注意 PostgreSQL 的 JSONB 支持索引,但 Go 的 json.RawMessage 写入前必须确保是合法 JSON,否则 INSERT 会报 "invalid input syntax for type json"不要在 JSON 里存复杂结构(如嵌套 map + slice 混用),前端解析容易出错;简单扁平对象足够,例如:{"enabled": true, "frequency": "daily", "channels": ["email", "web"]}并发更新用户偏好时怎么避免覆盖丢失用户可能在 App 和网页端同时修改偏好,两个请求都读旧值 → 各自计算新值 → 同时写回,后到的会覆盖先到的变更。这不是 Go 特有问题,但 Go 的默认 HTTP handler 容易让人忽略事务边界。用 UPDATE ... WHERE user_id = ? AND updated_at = ? 做乐观锁,失败时重试(最多 3 次),别直接 UPDATE ... SET value = ? WHERE user_id = ? AND preference_key = ?如果用 Redis 缓存偏好,务必和 DB 更新放在同一事务中(或用延时双删),否则出现 "已关闭推送但依然收到通知" 这类典型不一致避免在 HTTP handler 里直接调 db.Exec ------ 把更新逻辑封装进 service 方法,强制传入 context.Context 和 *sql.Tx,让调用方控制事务生命周期测试订阅偏好逻辑时最容易漏掉的边界多数人只测"开/关",但真实场景下有三个状态:未设置(null)、显式开启、显式关闭------尤其"未设置"常被当成 false,导致新用户收不到欢迎邮件。 RedClaw 百度推出的手机端万能AI Agent助手
相关推荐
lee_curry1 小时前
第四章 jvm中的垃圾回收器smj2302_796826522 小时前
解决leetcode第3911题.移除子数组元素后第k小偶数早日退休!!!2 小时前
《数据结构选型指南》笔记xcLeigh2 小时前
KES数据库性能优化实战阿正呀2 小时前
Redis怎样实现本地缓存的高效失效通知yoyo_zzm2 小时前
Laravel9.x新特性全解析2501_901200533 小时前
mysql如何设置InnoDB引擎参数_优化innodb_buffer_pool_.Switch3 小时前
东方财富股票数据JS逆向:secids字段和AES加密实战Mr_sst3 小时前
Claude Code 部署与使用保姆级教程(2026 最新)