应使用独立的 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 字段,而是用 mapstringjson.RawMessage 或自定义类型(如 type Preference mapstringinterface{})承载动态键值避免用 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助手
相关推荐
Database_Cool_16 分钟前
单机 MySQL 迁移到分布式数据库方便吗?阿里云 PolarDB-X 100% MySQL 协议兼容零改造平滑迁移玉鸯41 分钟前
Agent Hook:在概率推理之上,为 Agent 叠加确定性控制姜太小白1 小时前
【MySQL】 索引优化实战:解决 WHERE 等值 + IS NULL 查询,TEXT 字段报错 1167 的完整指南weixin_446260851 小时前
HACO:面向动态部署环境的对冲式智能计算可靠多智能体调度框架窝子面2 小时前
手搓最简前后端协作-node我的xiaodoujiao2 小时前
API 接口自动化测试详细图文教程学习系列32--Allure测试报告2吳所畏惧2 小时前
宝塔面板Redis密码修改指南:SSH命令修改 vs 面板UI界面修改,哪个更靠谱?DFT计算杂谈2 小时前
无 Root 权限在 Tesla K80 零门槛部署 DeepSeek 大模型qetfw2 小时前
MXU:Tauri 2 + React 的 MaaFramework 跨平台 GUI 源码