zoukankan      html  css  js  c++  java
  • MySQL:外键约束

    1 什么是外键 

    •   外键指的是在从表中,与主表的主键对应的那个字段
    •        比如员工表的 dept_id,就是外键
    •        使用外键约束可以让两张表之间产生一个对应关系,从而保证主从表的引用的完整性

    • 多表关系中的主表和从表
      • 主表: 主键id所在的表, 约束别人的表 
      •        从表: 外键所在的表, 被约束的表

    2 创建外键约束 

    1.语法格式:

      <1>新建表时添加外键

    [CONSTRAINT] [外键约束名称] FOREIGN KEY(外键字段名) REFERENCES 主表名(主键字段名) 

      <2>已有表添加外键

    ALTER TABLE 从表 ADD [CONSTRAINT] [外键约束名称] FOREIGN KEY (外键字段名) REFERENCES 主表(主键字段名);

    2.代码示例

      <1>重新创建employee表, 添加外键约束

    -- 先删除 employee表 
    DROP TABLE employee;
    
    -- 重新创建 employee表,添加外键约束 
    CREATE TABLE employee(
        eid INT PRIMARY KEY AUTO_INCREMENT,
        ename VARCHAR(20),
        age INT, 
        dept_id INT,
        -- 添加外键约束
        CONSTRAINT emp_dept_fk FOREIGN KEY(dept_id) REFERENCES department(id)
    );

      <2> 插入数据

    -- 正常添加数据 (从表外键 对应主表主键)
    INSERT INTO employee (ename, age, dept_id) VALUES ('张百万', 20, 1); 
    INSERT INTO employee (ename, age, dept_id) VALUES ('赵四', 21, 1); 
    INSERT INTO employee (ename, age, dept_id) VALUES ('广坤', 20, 1);
    INSERT INTO employee (ename, age, dept_id) VALUES ('小斌', 20, 2);
    INSERT INTO employee (ename, age, dept_id) VALUES ('艳秋', 22, 2);
    INSERT INTO employee (ename, age, dept_id) VALUES ('大玲子', 18, 2); 
    -- 插入一条有问题的数据 (部门id不存在) 
    -- Cannot add or update a child row: a foreign key constraint fails 
    INSERT INTO employee (ename, age, dept_id) VALUES ('错误', 18, 3);

    添加外键约束,就会产生强制性的外键数据检查, 从而保证了数据的完整性和一致性

     

    3 删除外键约束 

    语法格式

    alter table 从表 drop foreign key 外键约束名称

    代码示例

    <1>  删除外键约束

    -- 删除employee 表中的外键约束,外键约束名 
    emp_dept_fk ALTER TABLE employee DROP FOREIGN KEY emp_dept_fk;

    <2>  再将外键添加回来

    语法格式

    ALTER TABLE 从表 ADD [CONSTRAINT] [外键约束名称] FOREIGN KEY (外键字段名) REFERENCES 主表(主键字段名);
    -- 可以省略外键名称, 系统会自动生成一个 
    ALTER TABLE employee ADD FOREIGN KEY (dept_id) REFERENCES department (id);

    4 外键约束的注意事项

    <1> 从表外键类型,必须与主表主键类型一致,否则创建失败.

     <2>  添加数据时: 应该先添加主表中的数据.

    -- 添加一个新的部门 (市场部)
    INSERT INTO department(dep_name,dep_location) VALUES('市场部','北京');
    -- 添加一个属于新部门(市场部)的员工
    INSERT INTO employee(ename,age,dept_id) VALUES('老胡',24,3);

    <3>  删除数据时:应该先删除从表中的数据

    -- 删除数据时 应该先删除从表中的数据 
    -- 报错 Cannot delete or update a parent row: a foreign key constraint fails 
    -- 报错原因 不能删除主表的这条数据,因为在从表中有对这条数据的引用 
    DELETE FROM department WHERE id = 3;
    -- 先删除从表的关联数据 
    DELETE FROM employee WHERE dept_id = 3;
    
    -- 再删除主表的数据 
    DELETE FROM department WHERE id = 3;

    可以把主表和从表的关系想象为:

      主表:地基

      从表:地基上的建筑

  • 相关阅读:
    并行和并发
    怎样用第三方开源免费软件portecle从https站点上导出SSL的CA证书?
    我持续推动Rust语言支持Windows XP系统
    Android——4.2.2 文件系统文件夹分析
    hadoop(八)
    自己定义html中a标签的title提示tooltip
    多个返回 顶部的代码
    同学们,OpenCV出3.0了,速去围观!
    hdu1002
    好记性不如烂笔头(一)
  • 原文地址:https://www.cnblogs.com/JasperZhao/p/15015633.html
Copyright © 2011-2022 走看看