Skip to content

在数据库中,约束(Constraint)是用来限制数据合法性的手段,UNIQUE 只是其中一种。MySQL 及其他关系型数据库还支持以下几种常见约束类型:

🔒 常见的约束类型汇总

约束类型关键字保证示例用途描述
✅ 主键约束PRIMARY KEY唯一 + 非空,每表仅一个id INT PRIMARY KEY唯一标识每一行,不能为 NULL
✅ 唯一约束UNIQUE值唯一,允许多个NULLemail VARCHAR(100) UNIQUE限制字段值不能重复,可为 NULL
✅ 非空约束NOT NULL非空name VARCHAR(50) NOT NULL限制字段值不能为 NULL
✅ 默认值约束DEFAULT默认值status VARCHAR(10) DEFAULT 'active'设置字段的默认值
✅ 外键约束FOREIGN KEY关联父表字段,保证数据合法性FOREIGN KEY (x) REFERENCES y(z)建立两个表之间的关联关系
✅ 检查约束(MySQL 8+)CHECK条件约束age INT CHECK (age > 0)限制字段必须满足某种条件(如值范围)

🧠 示例综合建表语句:

sql
CREATE TABLE students (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(50) NOT NULL,
  email VARCHAR(100) UNIQUE,
  age INT CHECK (age >= 0 AND age <= 120),
  status VARCHAR(10) DEFAULT 'active',
  class_id INT,
  FOREIGN KEY (class_id) REFERENCES classes(id)
);

🔑 外键与唯一索引

外键(FOREIGN KEY

作用: 确保子表字段在父表中存在对应值,维护表间参照完整性。

少用外键的五大原因
  1. 性能与运维成本

    • 写入开销:外键检查导致锁竞争和性能下降(高并发场景敏感)。
    • 表结构变更困难:需先删除外键才能修改父表结构,影响迭代效率。
  2. 应用层依赖

    • ORM框架(如Hibernate)通过代码管理关联,替代数据库级约束。
    • 微服务架构下,跨服务数据库无法使用外键,依赖RPC/消息队列保证一致性。
  3. 测试与迁移灵活性

    • 自动化测试需按依赖顺序插入数据,复杂度增加。
    • 数据迁移(ETL)时外键检查降低导入速度。
  4. 软删除与历史追踪冲突

    • 软删除(deleted_at)需保留子表数据,与外键级联删除(ON DELETE CASCADE)矛盾。
  5. 团队经验与文化

    • 敏捷开发优先快速迭代,数据库约束常被代码校验替代。
    • 部分开发者对数据库设计不熟悉,依赖应用层逻辑。
那么,什么时候还要用外键?
适用场景
  • 核心业务:如支付、库存系统,需严格一致性。
  • 多表联合报表:避免“孤儿数据”。
  • 大型单体应用:集中式数据库管理。
总结
  • 优点:最简单、最透明的“数据层”完整性保证。
  • 缺点:写性能/运维迭代成本高,ORM 和微服务下难以跨库使用。
  • 实践:小项目、CRUD 频繁且不可容忍“孤儿数据”的核心业务表,依然推荐加外键;其余场景可权衡内部代码检查或使用分布式事务/幂等保证。

唯一索引(UNIQUE

作用: 确保字段值唯一(允许NULL,且多个NULL不冲突)。

唯一约束的两种实现方式
  1. 字段级定义

    sql
    CREATE TABLE students (  
      email VARCHAR(100) UNIQUE  
    );
    • 简洁,适合单字段唯一。
    • 系统自动命名索引。
  2. 表级定义

    sql
    CREATE TABLE users (  
      UNIQUE KEY uni_phone (phone)  
    );
    • 支持多字段联合唯一(如UNIQUE(user_id, role_id))。
    • 可自定义索引名称,便于维护。

联合唯一 vs 单字段唯一
类型规则示例场景
联合唯一约束组合值唯一,单字段可重复(country_code, phone)唯一
单字段唯一约束每个字段单独唯一username唯一

索引对比
类型适用场景特点
联合索引组合查询(左前缀原则)查询(a, b)快,单独查b效率低
单字段索引独立字段查询单字段查询快,组合查询优化有限

实战建议

  1. 外键使用

    • 核心业务表推荐使用,牺牲性能换取数据安全。
    • 微服务或高并发场景优先依赖代码逻辑校验。
  2. 唯一约束

    • 单字段唯一用字段级定义,联合唯一用表级定义。
    • 生产环境建议表级写法,便于维护和扩展。
  3. 索引设计

    • 高频联合查询字段使用联合索引(如(user_id, order_id))。
    • 独立查询字段单独建索引。

总结

  • 外键:强一致性场景的“双刃剑”,权衡性能与安全。
  • 唯一索引:灵活保障数据唯一性,注意NULL处理与联合约束。
  • 设计原则:根据业务需求选择约束类型,优先代码校验或数据库约束,避免过度设计。

所有文章版权皆归博主所有,仅供学习参考。