在MySQL数据库表设计中,主键和外键是保障数据完整性和规范表关系的重要约束,二者在定义、作用和使用规则上存在明显差异,同时也有着紧密的关联。

主键的定义与特性
主键是表中用于唯一标识每一行记录的字段或字段组合,一张表只能有一个主键,且主键的取值必须满足非空和唯一两个核心要求,即使表中没有显式定义主键,InnoDB存储引擎也会自动生成一个隐藏的6字节主键。
主键的常见定义方式如下:
-- 方式1:创建表时直接定义单列主键
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
age INT
);
-- 方式2:创建表时定义联合主键
CREATE TABLE user_role (
user_id INT,
role_id INT,
PRIMARY KEY (user_id, role_id)
);
-- 方式3:表创建后添加主键
ALTER TABLE user ADD PRIMARY KEY (id);
外键的定义与特性
外键是用于建立两张表之间关联关系的约束,外键字段的取值必须对应另一张表(主表)的主键或唯一键的取值,也可以为NULL,一张表中可以定义多个外键。
外键的定义示例如下:
-- 先创建主表
CREATE TABLE role (
id INT PRIMARY KEY AUTO_INCREMENT,
role_name VARCHAR(50) NOT NULL
);
-- 创建从表,定义外键关联主表的主键
CREATE TABLE user_role (
user_id INT,
role_id INT,
-- 定义外键,关联role表的id字段
FOREIGN KEY (role_id) REFERENCES role(id)
);
外键的主要作用是保证参照完整性,避免从表中出现主表不存在的关联数据,同时可以设置级联操作,比如主表记录删除时自动删除从表对应记录,或者主表主键更新时自动更新从表的外键值。
主键和外键的核心区别
二者的差异可以从多个维度对比,具体如下表所示:
| 对比维度 | 主键 | 外键 |
|---|---|---|
| 唯一性要求 | 必须唯一,不能重复 | 可以重复,也可以为NULL |
| 非空性要求 | 必须非空,不允许NULL值 | 允许NULL值 |
| 一张表的数量限制 | 只能有1个(可以是联合主键) | 可以有多个 |
| 核心作用 | 唯一标识本表记录,保障记录唯一性 | 建立表之间的关联关系,保障参照完整性 |
| 关联对象 | 不需要关联其他表 | 必须关联另一张表的主键或唯一键 |
主键和外键的关联关系
外键的参照对象通常是另一张表的主键,二者共同构成了数据库的参照完整性约束体系:主键作为主表的唯一标识,为外键提供合法的取值来源;外键作为从表的关联字段,依赖主键的取值来保证关联数据的有效性。
比如在用户和订单的场景中,用户表的主键user_id是唯一的,订单表的外键user_id关联用户表的user_id,这样就能保证每个订单都对应一个真实存在的用户,避免出现无归属的订单数据。
使用注意事项
- 主键尽量选择和业务无关的字段,比如自增ID,避免业务变更导致主键取值冲突。
- 外键虽然能保障数据完整性,但会增加数据库的性能开销,高并发场景下很多团队会选择不在数据库层定义外键,而是在业务代码中实现关联校验。
- 定义外键时,主表和从表的关联字段类型必须完全一致,否则会创建失败。
注意:MySQL中只有InnoDB存储引擎支持外键约束,MyISAM等其他存储引擎不支持外键定义,使用前需要确认表的存储引擎类型。