mysql外键设置

在mysql表设计时,如果巧用外键设置,可以给我们的开发带有很大的便利。

应用场景:子表依赖于父表,或父子表存在某种关联;

那么就存在父表或子表数据发生变化时,对应的子表或父表的数据应该作何改变;

主要涉及以下处理:CASCADE,NO ACTION,RESTRICT,SET NULL; 

mysql外键设置_第1张图片

下面简要概括下这4个设置适用的场景:

1. CASCADE(级联操作)

  • ON DELETE CASCADE:当父表中的某条记录被删除时,子表中所有关联的记录也会被自动删除。

  • ON UPDATE CASCADE:当父表中的某条记录的主键被更新时,子表中所有关联的外键值也会被自动更新。

适用场景

  • 父子表之间存在强依赖关系,子表数据完全依赖于父表数据。

  • 例如:订单表(父表)和订单项表(子表)。如果删除一个订单,那么该订单的所有订单项也应该被删除。

示例:

CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    order_date DATE
);

CREATE TABLE order_items (
    item_id INT PRIMARY KEY,
    order_id INT,
    product_name VARCHAR(255),
    FOREIGN KEY (order_id) REFERENCES orders(order_id) ON DELETE CASCADE
);

2. RESTRICT(限制操作)

  • ON DELETE RESTRICT:如果子表中存在关联记录,则不允许删除父表中的记录。

  • ON UPDATE RESTRICT:如果子表中存在关联记录,则不允许更新父表中的主键。

适用场景

  • 父子表之间存在依赖关系,但不希望自动删除或更新子表数据。

  • 例如:部门表(父表)和员工表(子表)。如果某个部门下有员工,则不允许删除该部门。

示例

CREATE TABLE departments (
    dept_id INT PRIMARY KEY,
    dept_name VARCHAR(255)
);

CREATE TABLE employees (
    emp_id INT PRIMARY KEY,
    dept_id INT,
    emp_name VARCHAR(255),
    FOREIGN KEY (dept_id) REFERENCES departments(dept_id) ON DELETE RESTRICT
);

3. NO ACTION(无操作)

  • ON DELETE NO ACTION:如果子表中存在关联记录,则不允许删除父表中的记录。

  • ON UPDATE NO ACTION:如果子表中存在关联记录,则不允许更新父表中的主键。

适用场景

  • RESTRICT行为相同,但在某些数据库系统中,NO ACTION可能会延迟检查约束,直到事务提交时才检查。

  • 例如:在复杂的业务逻辑中,可能需要延迟检查外键约束。

示例:

CREATE TABLE customers (
    customer_id INT PRIMARY KEY,
    customer_name VARCHAR(255)
);

CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT,
    order_date DATE,
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id) ON DELETE NO ACTION
);

4. SET NULL(置空操作)

  • ON DELETE SET NULL:当父表中的某条记录被删除时,子表中所有关联的外键值会被设置为NULL

  • ON UPDATE SET NULL:当父表中的某条记录的主键被更新时,子表中所有关联的外键值会被设置为NULL

适用场景

  • 父子表之间存在依赖关系,但子表数据可以独立存在。

  • 例如:用户表(父表)和评论表(子表)。如果用户被删除,评论可以保留,但评论的用户ID字段会被置为NULL

注意:外键字段必须允许NULL值。

示例

CREATE TABLE users (
    user_id INT PRIMARY KEY,
    username VARCHAR(255)
);

CREATE TABLE comments (
    comment_id INT PRIMARY KEY,
    user_id INT,
    comment_text TEXT,
    FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE SET NULL
);

5. 总结对比

行为 删除父表记录时 更新父表主键时 适用场景
CASCADE 子表关联记录被删除 子表外键值被更新 强依赖关系,子表数据随父表数据一起删除或更新
RESTRICT 阻止删除父表记录 阻止更新父表主键 不允许删除或更新父表数据,除非子表无关联记录
NO ACTION 阻止删除父表记录(可能延迟检查) 阻止更新父表主键(可能延迟检查) RESTRICT类似,但可能延迟检查约束
SET NULL 子表外键值被置为NULL 子表外键值被置为NULL 子表数据可独立存在,外键字段允许NULL

 

6. 选择建议

  • 如果子表数据完全依赖于父表数据,使用CASCADE

  • 如果子表数据不能独立存在,且不希望自动删除或更新,使用RESTRICTNO ACTION

  • 如果子表数据可以独立存在,且外键字段允许NULL,使用SET NULL

通过合理选择外键行为,可以确保数据库的数据完整性和一致性。

你可能感兴趣的:(mysql,数据库)