MySQL 数据类型与约束

5 minBeginner

数值、字符串、日期类型及主键、外键、唯一约束。

1. 数据型选择原则 (Selection Principles)

核心目标:

  • 正确表达业务含义(语义清晰)
  • 保证数据完整性(约束与校验)
  • 兼顾性能与存储成本(索引友好、空间可控) 实践要点:
  • 能用更小的型就不用更大型(但不要牺牲语义)
  • 经常参与过滤/排序/Join 的列优先选择“可索引且稳定”的
  • 避免把结构化字段塞进一个字符串里(除非确实是原始文本)

2. 数值型 (Numeric)

2.1 整数

常用:TINYINTINTBIGINT 实践建议:

  • 业务自增主键常用 BIGINT(预留增长空间)
  • 状态枚举常用 TINYINT(配合业务层枚举)
  • 需要非负时用 UNSIGNED

2.2 定点与浮点

  • 金额优先用 DECIMAL(p, s),避免浮点误差
  • 测量数据/近似值可用 DOUBLE

3. 字符串型 (String)

3.1 CHAR vs VARCHAR

  • CHAR(n):定长,适合长度固定的值(如国家码、短编码),更新更稳定
  • VARCHAR(n):变长,适合长度变化较大的值(如昵称、标题) 实践建议:
  • VARCHAR 不是越大越好,过大的上限会影响行格式与索引策略
  • 经常参与索引的长文本字段慎用 VARCHAR(1024+)

3.2 TEXT 家族

用于长文本(文章内容、描述)。注意:

  • TEXT 列通常不适合直接做常规索引(需要前缀索引或全文索引)
  • TEXT 列会影响行存储与读取代价

4. 日期与时间 (Date & Time)

常用:DATEDATETIMETIMESTAMP

  • DATETIME范围大,存储不依赖时区转换(更“客观”)
  • TIMESTAMP:存储与时区有关(读取/写入可能发生转换),范围较小 实践建议:
  • 业务“发生时间”通常用 DATETIME,统一用 UTC 或在应用层明确时区策略
  • 保存“仅日期”用 DATE,避免在应用层反复截断

5. JSON 型 (JSON)

MySQL 的 JSON 适合存放:

  • 结构频繁变化的扩展字段
  • 不适合拆表但需要一定结构的配置项 注意:
  • JSON 查询需要函数/生成列配合索引,否则易慢
  • 不要用 JSON 替代关键业务字段(关键字段应拆列以便约束、索引与统计)

6. 字符集与排序规则 (Charset & Collation)

实践建议:

  • 统一使用 utf8mb4
  • 明确排序规则(collation),避免跨表/跨库比较时发生隐式转换

7. 约束 (Constraints)

7.1 NOT NULL

优先用 NOT NULL 来表达“必填”。配合默认值要谨慎,确保默认值也符合业务语义。

7.2 DEFAULT

示例:

 created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP

注意:不要用默认值掩盖业务层输入缺失,应区分“未知/未填”与“默认”。

7.3 UNIQUE

用于业务唯一性约束(如手机号、邮箱、业务单号)。 实践建议:

  • 唯一约束应该从业务语义出发,而不是“为了查得快”
  • 可组合唯一:例如 (tenant_id, email)

7.4 PRIMARY KEY

通常建议:

  • 使用单列自增或雪花 ID 作为主键
  • 避免使用可变业务字段(例如手机号)作为主键

7.5 FOREIGN KEY

MySQL 支持外键,但很多互联网业务会选择在应用层维护约束,原因包括:

  • 高并发下跨表约束可能放大锁冲突
  • 分库分表/异构存储下外键不可用 是否使用外键取决于:
  • 业务规模与一致性要求
  • 团队治理与数据质量策略

8. 建表示例 (Example)

 CREATE TABLE user_account (
  id BIGINT UNSIGNED NOT NULL PRIMARY KEY,
  email VARCHAR(255) NOT NULL,
  status TINYINT NOT NULL DEFAULT 1,
  created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  UNIQUE KEY uk_email (email)
 )

更新日志 (Changelog)

  • 2026-04-06: 新增「数据型与约束」知识点,补全型选择与约束实践