SQL表结构设计核心是确保数据准确、查询高效、修改稳定,需围绕业务逻辑、一致性和扩展性权衡;主键用自增INT或UUID,禁用业务字段;唯一约束保障业务规则;字段类型遵循够用、不冗余原则;外键提升一致性;命名规范、注释清晰。

SQL表结构设计的核心是让数据存得准、查得快、改得稳。不是字段越多越好,也不是越省事越简单,而是围绕业务逻辑、数据一致性和未来扩展来权衡。
明确主键和唯一约束
每张表必须有主键,推荐用自增整型(INT UNSIGNED AUTO_INCREMENT)或UUID(若需分布式兼容)。避免用业务字段(如手机号、身份证号)当主键——它们可能变更、有隐私风险、长度不一影响索引效率。
业务上要求唯一的字段(如用户名、邮箱、订单号)要加UNIQUE约束,不能只靠应用层校验。数据库才是唯一可信的防线。
- 主键字段命名统一用 id(不要写 user_id、order_id 等)
- 联合唯一约束适用于多字段组合唯一场景(如“一个用户每天只能签到一次” → (user_id, date))
- 主键默认带聚集索引,对范围查询和排序友好;若用 UUID,注意其随机性会导致插入性能下降,可考虑用 UUID_TO_BIN() + 倒序时间戳优化
字段类型要够用、不冗余
选型原则:能用小不用大,能用定长不用变长,能用数字不用字符串。
- 状态类字段(如启用/禁用、订单状态)优先用 TINYINT(1) 或 ENUM(MySQL支持),别用 VARCHAR 存“enabled”“disabled”
- 金额一律用 DECIMAL(10,2),不用 FLOAT/DOUBLE(浮点精度丢失问题在支付场景会致命)
- 文本内容区分场景:VARCHAR(255) 存标题/昵称;超长内容(如文章正文)用 TEXT;固定长度编码(如国家代码 ISO 3166-1 alpha-2)用 CHAR(2)
- 时间字段用 DATETIME(而非 TIMESTAMP),因后者受时区和 2038 年限制;创建/更新时间建议都保留:created_at、updated_at
合理使用外键与关联设计
外键不是必须,但强烈建议在单体应用或强一致性要求场景下启用(如金融、库存)。它能防止脏数据、自动级联操作(如删除用户时清空其订单),代价是写入稍慢、跨库难支持。
- 外键字段名应与被引用表主键名一致(如 user_id 引用 users.id)
- 被引用字段必须有索引(主键天然满足,否则需手动添加)
- 一对多关系,外键放“多”的一侧(如订单表放 user_id);多对多必须拆成中间表(如 user_role 表含 user_id + role_id)
- 软删除慎用外键级联,建议用逻辑标记(is_deleted=1)+ 应用层控制
命名与注释要清晰可读
表名、字段名不是写给自己看的,是写给半年后的同事、写给接手的新人、写给排查问题的DBA看的。
- 全部小写,单词间用下划线分隔(order_item,不是 OrderItem 或 orderItem)
- 避免缩写歧义(如 addr 不如 address,cnt 不如 count)
- 每个表加 COMMENT 说明用途(COMMENT '用户基本信息表')
- 关键字段也加 COMMENT(COMMENT 'UTC 时间戳,精确到秒')










