《MySQL表的创建与约束:定义结构化数据的存储载体》

《MySQL表的创建与约束:定义结构化数据的存储载体》

MySQL 中的表(Table) 是关系型数据库最核心的存储单元,它定义了数据的结构、类型、约束和关系,是结构化数据的物理载体。

本篇从最基础的建表语法开始,逐步深入到各种约束(Constraint)的定义、使用场景、常见写法和生产注意事项,帮助你系统掌握“如何正确地定义一张表”。

1. 基本建表语法(CREATE TABLE)

最简洁的建表语句:

CREATE TABLE users (
    id         BIGINT         NOT NULL AUTO_INCREMENT COMMENT '主键ID',
    username   VARCHAR(50)    NOT NULL COMMENT '用户名',
    email      VARCHAR(100)   UNIQUE COMMENT '邮箱',
    age        INT            DEFAULT 18 COMMENT '年龄',
    status     TINYINT        DEFAULT 1 COMMENT '状态:1正常 0禁用',
    created_at DATETIME       DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    updated_at DATETIME       DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

    PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';

关键组成部分拆解

部分说明2025–2026 推荐写法
表名建议使用小写 + 下划线风格(users、order_items)避免使用 MySQL 关键字、避免驼峰
列定义列名 + 数据类型 + 约束 + 默认值 + COMMENT每列都加 COMMENT(文档化)
主键几乎所有业务表都应该有主键(通常是自增 ID)BIGINT + AUTO_INCREMENT
存储引擎InnoDB(事务、行锁、外键) vs MyISAM(只读快照)99% 场景选 InnoDB
字符集 & 排序规则utf8mb4(支持 emoji) + unicode_ci(不区分大小写)utf8mb4_unicode_ci(主流)
表注释COMMENT=’xxx’必须写,方便后期维护

2. MySQL 常用数据类型速查(业务最常用)

分类类型字节数适用场景推荐替代(8.0+)
整数TINYINT1状态、性别、是否删除(0/1)
INT / INTEGER4普通 ID、数量
BIGINT8主键、自增 ID、雪花算法 ID
浮点数DECIMAL(p,s)金额、汇率(绝对不要用 FLOAT/DOUBLEDECIMAL(18,4) 或更高精度
字符串VARCHAR(n)n+1~n+4用户名、标题、邮箱
CHAR(n)n固定长度(如身份证号、邮编)很少用
TEXT / MEDIUMTEXT可变文章正文、富文本
时间DATETIME8创建/更新时间(精确到秒)
TIMESTAMP4带时区、自动更新8.0+ 推荐 DATETIME
DATE / TIME3/3只存日期/时间
其他JSON可变非结构化扩展字段8.0+ 非常常用
ENUM(‘男’,’女’)1~2性别、状态(枚举值少时)建议用 TINYINT + 注释代替

金额字段强烈建议

amount DECIMAL(18,4) COMMENT '金额,精确到4位小数'

3. 表级约束 vs 列级约束

约束类型语法位置作用是否允许 NULL典型写法示例
NOT NULL列级该列不允许为空username VARCHAR(50) NOT NULL
DEFAULT列级默认值status TINYINT DEFAULT 1
AUTO_INCREMENT列级自增(必须是主键或唯一键)id BIGINT AUTO_INCREMENT
UNIQUE列级 / 表级值唯一(允许 NULL,但 NULL 算不同)允许 1 个 NULLemail VARCHAR(100) UNIQUE
PRIMARY KEY列级 / 表级主键(唯一 + 非空)PRIMARY KEY (id)
FOREIGN KEY表级外键约束FOREIGN KEY (user_id) REFERENCES users(id)
CHECK表级(8.0+)自定义校验CHECK (age >= 18)

推荐生产级建表模板(2025–2026 主流写法)

CREATE TABLE orders (
    id          BIGINT         NOT NULL AUTO_INCREMENT COMMENT '订单ID',
    user_id     BIGINT         NOT NULL COMMENT '用户ID',
    order_no    VARCHAR(32)    NOT NULL UNIQUE COMMENT '订单号',
    amount      DECIMAL(18,4)  NOT NULL DEFAULT 0.0000 COMMENT '订单金额',
    status      TINYINT        NOT NULL DEFAULT 0 COMMENT '订单状态:0待支付 1已支付 2已发货 3已完成 -1已取消',
    created_at  DATETIME       NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    updated_at  DATETIME       NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

    PRIMARY KEY (id),
    UNIQUE KEY uk_order_no (order_no),
    INDEX idx_user_id_status (user_id, status),           -- 复合索引
    CONSTRAINT fk_orders_user FOREIGN KEY (user_id) 
        REFERENCES users(id) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB 
  DEFAULT CHARSET=utf8mb4 
  COLLATE=utf8mb4_unicode_ci 
  COMMENT='订单主表';

4. 约束行为总结表(非常重要)

约束INSERT 空值UPDATE 违反DELETE 主表记录推荐场景
NOT NULL报错报错必填字段
UNIQUE允许 NULL报错业务唯一键(如订单号、邮箱)
PRIMARY KEY报错报错表的主标识
FOREIGN KEY允许(若从表允许 NULL)报错(若违反引用完整性)可配置(RESTRICT / CASCADE / SET NULL)强关联关系(8.0+ 推荐)
CHECK报错报错年龄、状态范围(8.0+)

5. 生产环境常见约束最佳实践(2025–2026)

  1. 每张表必须有主键(绝大多数情况用 BIGINT 自增)
  2. 业务唯一约束用 UNIQUE KEY(而非靠应用层控制)
  3. 外键约束谨慎使用(大型系统建议用逻辑外键 + 应用层保证)
  4. 字段必须加 COMMENT(团队协作必备)
  5. 统一字符集:utf8mb4_unicode_ci(支持 emoji、不区分大小写)
  6. 金额字段永远用 DECIMAL(绝不用 FLOAT/DOUBLE)
  7. 时间字段用 DATETIME(TIMESTAMP 有 2038 年问题,且时区敏感)
  8. 状态字段用 TINYINT + 注释(比 ENUM 更灵活)

6. 快速自测题(巩固)

  1. 下列哪种写法可以让 status 字段默认值为 1 且不允许为空?
    A. status TINYINT DEFAULT 1
    B. status TINYINT NOT NULL DEFAULT 1
    C. status TINYINT DEFAULT 1 NOT NULL
  2. 想让 email 字段唯一但允许为空,应该怎么写?
    UNIQUE KEY uk_email (email)
  3. 想在删除用户时自动删除该用户的所有订单,应该在外键上写什么?
    ON DELETE CASCADE

答案:1-B,2-正确(UNIQUE 允许一个 NULL),3-ON DELETE CASCADE

如果你想继续深入某个部分,比如:

  • 外键 vs 逻辑外键 的生产取舍
  • 复合唯一索引 vs 唯一键 的区别
  • JSON 字段在表结构中的最佳实践
  • 建表规范检查工具(SQL 审核)

告诉我,我们继续展开!

文章已创建 4138

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部