优惠券主表必含字段:id、title、description、discount_type、discount_value、start_time、end_time、status、use_limit、min_order_amount、scope_type;需避免用字符串存类型、漏时区处理、缺状态人工干预能力。
优惠券主表设计:字段选哪些才不踩坑
电商优惠券的核心是「可用性」和「可追溯性」,coupon 表不能只存面值和有效期。常见错误是漏掉 use_limit(每人限用次数)、min_order_amount(满减门槛)和 scope_type(适用范围:全店/指定类目/指定商品)。这些字段缺失会导致后续发券逻辑反复改表,甚至要加冗余字段补救。
建议必填字段清单:
-
id(主键,bigint 自增或 UUID) -
title、description(运营侧可见) -
discount_type(enum: 'fixed', 'percent', 'free_shipping')——别用字符串自由输入,避免脏数据 -
discount_value(数值型,固定金额存分,百分比存 0–100 整数) -
start_time/end_time(datetime,注意时区;Navicat 默认用本地时区,上线前务必确认服务器时区设置) -
status(tinyint,1=启用,0=停用,-1=已过期——别只靠时间判断状态,方便人工干预)
用户领券记录怎么建才支持高并发查询
user_coupon 表是高频读写点,Navicat 建表时容易忽略索引和唯一约束。典型错误是只加主键,没建 (user_id, coupon_id) 联合索引,导致「用户是否已领该券」查询变慢;更糟的是没设 UNIQUE KEY (user_id, coupon_id),结果同一用户重复领同一张券。
实操建议:
- 主键用
id(自增 bigint),方便分页和日志追踪 - 必须建联合索引:
INDEX idx_user_coupon (user_id, coupon_id) - 必须加唯一约束:
UNIQUE KEY uk_user_coupon (user_id, coupon_id)—— Navicat 在「索引」标签页里勾选「Unique」即可 - 加
used_at字段(datetime NULL),配合status字段区分「已领取未使用」和「已使用」,避免用is_used布尔值硬编码状态流转
优惠券与商品/类目的关联关系:用中间表还是 JSON 字段
当优惠券限制「仅适用于某几个商品 ID」或「某几个类目 ID」时,Navicat 里有人图省事直接加 target_ids text 或 JSON 字段。短期快,长期痛:无法走索引、没法做外键校验、统计「某商品被多少券覆盖」时只能全表扫描。
正确做法是建中间表:
-
coupon_target表,字段含:coupon_id、target_type('product'/'category'/'brand')、target_id - 在 Navicat 的「外键」标签页里,为
coupon_id关联coupon.id,为target_id暂不设外键(因 target_type 多态) - 查「某商品能用哪些券」时,SQL 是:
SELECT c.* FROM coupon c JOIN coupon_target ct ON c.id = ct.coupon_id WHERE ct.target_type = 'product' AND ct.target_id = 12345
JSON 字段只适合极低频查询、且目标 ID 数量极少(≤5)的场景,比如「仅限新用户首单使用」这种业务规则,存在 rule_json 字段里反而更清晰。
Navicat 导出 SQL 时容易丢的关键配置
用 Navicat 设计完模型后导出 SQL,常发现线上执行报错,多数因为 Navicat 默认导出不含字符集和存储引擎声明,或者把 TIMESTAMP 写成 DATETIME 导致 MySQL 5.6+ 兼容问题。
导出前必须手动检查:
- 在「导出向导」→「高级选项」里勾选「导出表结构」+「导出表数据」(按需),并确认「字符集」选
utf8mb4,「排序规则」选utf8mb4_unicode_ci - 「存储引擎」显式指定为
InnoDB(Navicat 默认可能用 MyISAM) - 检查生成的 SQL 中所有时间字段类型:MySQL 5.7+ 推荐统一用
DATETIME,避免TIMESTAMP的自动更新陷阱(如ON UPDATE CURRENT_TIMESTAMP会意外改时间) - 导出后先在测试库执行一遍,重点看
CREATE TABLE语句里有没有漏掉NOT NULL或默认值(Navicat 界面里设了「默认值」,但导出时可能没勾「导出默认值」)
真正麻烦的不是建表,而是后期加字段或改类型——Navicat 的「表设计器」里双击改字段,背后执行的是 ALTER TABLE,大表会锁表。线上环境务必先在测试库验证 DDL 影响。


















