在 MySQL 中,外键(Foreign Key)是用于建立两个表之间关联的约束,它确保一个表中的数据与另一个表中的数据保持一致性和完整性。外键通常用于实现 “一对多” 或 “多对多” 的关系模型。
-
数据完整性:阻止无效数据插入(如引用了不存在的关联数据)。
-
一致性维护:当主表数据更新或删除时,从表可自动触发相应操作(如级联删除)。
-
关系定义:明确表之间的业务关系(如 “订单表” 关联 “用户表” 表示 “哪个用户创建了订单”)。
-
主表(父表):被引用的表,通常包含主键(PRIMARY KEY)。
-
从表(子表):包含外键的表,外键列的值必须匹配主表中主键列的值(或为 NULL)。
-
外键约束:定义在从表上,指定外键列与主表主键列的关联关系。
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL
) ENGINE=InnoDB;
CREATE TABLE orders (
order_id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT,
order_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id)
REFERENCES users(id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB;
ALTER TABLE orders
ADD CONSTRAINT fk_orders_users
FOREIGN KEY (user_id)
REFERENCES users(id)
ON DELETE SET NULL
ON UPDATE RESTRICT;
当主表数据发生变化时,从表的关联记录可触发以下操作(通过 ON DELETE
和 ON UPDATE
定义):
示例:若 orders
表外键设置为 ON DELETE CASCADE
,当删除 users
表中某用户时,该用户的所有订单会被自动删除。
-
引擎支持:仅 InnoDB 引擎支持外键,MyISAM 等引擎会忽略外键约束。
-
数据类型一致:外键列与主表主键列的数据类型必须完全一致(如
INT
对应 INT
)。
-
索引要求:主表的被引用列必须是主键或唯一索引;从表的外键列建议创建索引(提升查询效率)。
-
级联更新限制:若主表主键是自增列(AUTO_INCREMENT),
ON UPDATE CASCADE
通常无意义(自增主键一般不更新)。
-
性能影响:外键会增加写入操作(插入 / 更新 / 删除)的开销,高并发场景需权衡使用。
DESCRIBE orders;
SELECT
CONSTRAINT_NAME,
COLUMN_NAME,
REFERENCED_TABLE_NAME,
REFERENCED_COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME = 'orders' AND REFERENCED_TABLE_NAME IS NOT NULL;
ALTER TABLE orders DROP FOREIGN KEY fk_orders_users;
-
强一致性要求的业务(如订单必须关联存在的用户)。
-
避免手动维护关联关系(如级联删除减少代码逻辑)。
-
逻辑外键:不在数据库层面定义外键,仅通过应用程序保证关联关系(减少数据库开销)。
-
索引关联:在从表外键列创建索引,通过 JOIN 查询实现表关联,由代码维护数据一致性。
外键是维护数据完整性的重要工具,尤其适合中小型应用或对一致性要求严格的场景。但在高并发、高性能需求的系统中,需权衡其带来的性能开销,可考虑通过应用程序逻辑替代物理外键。使用时需注意引擎支持、数据类型匹配和级联操作的合理配置。