zoukankan      html  css  js  c++  java
  • MySQL 中的外键

    表和表之间可存在引用关系,这在抽象数据到表时,是很常见的。这种联系是通过在表中创建外键(foreign key)来实现的。

    比如一个订单,可能关联用户表和产品表,以此来记录买了什么产品

    约定两个概念:

    父表:被引用的表。
    从表:表中有相应的外键引用父表中的字段。

    示例:

    CREATE TABLE parent (
        id INT NOT NULL,
        PRIMARY KEY (id)
    ) ENGINE=INNODB;
    

    CREATE TABLE child (
    id INT,
    parent_id INT,
    INDEX par_ind (parent_id),
    FOREIGN KEY (parent_id)
    REFERENCES parent(id)
    ON DELETE CASCADE
    ) ENGINE=INNODB;

    这里 parent 为父表,child 为从表。

    外键关联表的同步操作

    当表和表之间建立起合适的关联后, INSERTUPDATE 操作会自动检查所插入的记录中指定的外键在相应表中是否存在;

    建立外键时,可指定 ON UPDATE <action>ON DELETE <action> 子语句来指定发生 UPDATEDELETE 操作时,外键关联表中数据该如何处理。MySQL 中支持五种处理(action):

    • CASCADE:更新或删除父表记录时,自动更新或删除从表中匹配的记录。实际使用时注意不要在父表或从表中对同一列重复定义 ON UPDATE CASCADE。CASCADE 类型的操作不会激活触发器 (triggers)。
    • SET NULL:更新或删除父表中记录时,将从表中匹配的记录其外键设置为 NULL,前提时从表中该外键没有指定为 NOT NULL
    • RESTRICT:默认为该项。禁用父表中的更新或删除操作,这与缺省 ON DELETEON UPDATE 子语句效果一样。
    • NO ACTION:来自 SQL 标准中定义的一种操作,与上面 RESTRICT 等效。一些数据库支持延迟检查(deferred check), NO ACTION 便是这种可延迟检查的操作。在 MySQL 中,外键的检查是及时的,所以 NO ACTIONRESTRICT 完全等效。
    • SET DEFAULT: MySQL 能够解析识别该动作,但 InnoDBNDB 引擎不支持。

    添加外键

    创建外键的语法
    [CONSTRAINT [symbol]] FOREIGN KEY
        [index_name] (col_name, ...)
        REFERENCES tbl_name (col_name,...)
        [ON DELETE reference_option]
        [ON UPDATE reference_option]
    

    reference_option:
    RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT

    文章开头提到的订单表示例:

    CREATE TABLE product (
        category INT NOT NULL, id INT NOT NULL,
        price DECIMAL,
        PRIMARY KEY(category, id)
    )   ENGINE=INNODB;
    

    CREATE TABLE customer (
    id INT NOT NULL,
    PRIMARY KEY (id)
    ) ENGINE=INNODB;

    CREATE TABLE product_order (
    no INT NOT NULL AUTO_INCREMENT,
    product_category INT NOT NULL,
    product_id INT NOT NULL,
    customer_id INT NOT NULL,

    <span class="pl-k">PRIMARY KEY</span>(no),
    INDEX (product_category, product_id),
    INDEX (customer_id),
    
    <span class="pl-k">FOREIGN KEY</span> (product_category, product_id)
      <span class="pl-k">REFERENCES</span> product(category, id)
      <span class="pl-k">ON</span> <span class="pl-k">UPDATE</span> CASCADE <span class="pl-k">ON DELETE</span> RESTRICT,
    
    <span class="pl-k">FOREIGN KEY</span> (customer_id)
      <span class="pl-k">REFERENCES</span> customer(id)
    

    ) ENGINE=INNODB;

    所以这个关系里有两个父表 customerproduct,一个从表 product_order

    对现有表添加外键可使用如下的语句:

    ALTER TABLE tbl_name
        ADD [CONSTRAINT [symbol]] FOREIGN KEY
        [index_name] (col_name, ...)
        REFERENCES tbl_name (col_name,...)
        [ON DELETE reference_option]
        [ON UPDATE reference_option]

    创建外键时可指定 [symbol],即给外键取一个名称,这样在其他操作时可以引用,比如删除外键时。

    删除外键

    同样是通过 ALTER TABLE 语句来完成。

    ALTER TABLE tbl_name DROP FOREIGN KEY fk_symbol;

    删除外键时,如果该外键在创建时取了名称,名通过该名称来删除,如果没有,则需要先查询 MySQL 在创建该外键时自动生成的名称 fk_symbol 是什么。可通过 SHOW CREATE TABLE <table_name> 来完成查询。譬如:

    mysql> SHOW CREATE TABLE dept_managerG
    *************************** 1. row ***************************
           Table: dept_manager
    Create Table: CREATE TABLE `dept_manager` (
      `emp_no` int(11) NOT NULL,
      `dept_no` char(4) COLLATE utf8mb4_general_ci NOT NULL,
      `from_date` date NOT NULL,
      `to_date` date NOT NULL,
      PRIMARY KEY (`emp_no`,`dept_no`),
      KEY `dept_no` (`dept_no`),
      CONSTRAINT `dept_manager_ibfk_1` FOREIGN KEY (`emp_no`) REFERENCES `employees` (`emp_no`) ON DELETE CASCADE,
      CONSTRAINT `dept_manager_ibfk_2` FOREIGN KEY (`dept_no`) REFERENCES `departments` (`dept_no`) ON DELETE CASCADE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
    1 row in set (0.00 sec)

    相关资源

  • 相关阅读:
    js node 节点 原生遍历 createNodeIterator
    nodejs fs copy本地文件src dst
    axios 请求常用组件,及其错误
    【IntelliJ IDEA学习之三】IntelliJ IDEA常用快捷键
    【IntelliJ IDEA学习之二】IntelliJ IDEA常用配置
    【IntelliJ IDEA学习之一】IntelliJ IDEA安装激活、VM参数
    【python学习案例】python判断自身是否正在运行
    【Linux脚本学习案例】shell脚本多通道并发执行存储过程
    【Activiti学习之四】Activiti API(三)
    【Activiti学习之三】Activiti API(二)
  • 原文地址:https://www.cnblogs.com/Wayou/p/mysql_foreign_key.html
Copyright © 2011-2022 走看看