FOREIGN KEY 约束

FOREIGN KEY 约束外键约束MySql外键约束外键约束InnoDB也支持外键约束。InnoDB中对外键约束定义的语法看起来如下:[CONSTRAINTsymbol]FOREIGNKEY[id](index_col_name,…)

外键约束

MySql外键约束

外键约束

InnoDB也支持外键约束。InnoDB中对外键约束定义的语法看起来如下:

[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)
    REFERENCES tbl_name (index_col_name, ...)
    [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION}]
    [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION}]

// CONSTRAINT `usertable2_ibfk_1` FOREIGN KEY (`USER_ID`) REFERENCES `usertable` (`ID`) ON DELETE CASCADE//

   子表(有外键的表)中约束名为 ` usertable2_ibfk_1` 的 外键  USER_ID 关联到主表 usertable表的 ID 

 

外键定义服从下列情况:

·         所有tables必须是InnoDB型,它们不能是临时表。

·         在引用表中,必须有一个索引,外键列以同样的顺序被列在其中作为第一列。这样一个索引如果不存在,它必须在引用表里被自动创建。

·         在引用表中,必须有一个索引,被引用的列以同样的顺序被列在其中作为第一列。

·         不支持对外键列的索引前缀。这样的后果之一是BLOBTEXT列不被包括在一个外键中,这是因为对这些列的索引必须总是包含一个前缀长度。

·         如果CONSTRAINTsymbol被给出,它在数据库里必须是唯一的。如果它没有被给出,InnoDB自动创建这个名字。

InnoDB拒绝任何试着在子表创建一个外键值而不匹配在父表中的候选键值的INSERTUPDATE操作。一个父表有一些匹配的行的子表,InnoDB对任何试图更新或删除该父表中候选键值的UPDATEDELETE操作有所动作,这个动作取决于用FOREIGN KEY子句的ON UPDATEON DETETE子句指定的referential action。当用户试图从一个父表删除或更新一行之时,且在子表中有一个或多个匹配的行,InnoDB根据要采取的动作有五个选择:

·         CASCADE: 从父表删除或更新且自动删除或更新子表中匹配的行。ON DELETE CASCADEON UPDATE CASCADE都可用。在两个表之间,你不应定义若干在父表或子表中的同一列采取动作的ON UPDATE CASCADE子句。

·         SET NULL: 从父表删除或更新行,并设置子表中的外键列为NULL。如果外键列没有指定NOT NULL限定词,这就是唯一合法的。ON DELETE SET NULLON UPDATE SET NULL子句被支持。

·         NO ACTION: ANSI SQL-92标准中,NO ACTION意味这不采取动作,就是如果有一个相关的外键值在被参考的表里,删除或更新主要键值的企图不被允许进行(Gruber, 掌握SQL, 2000:181)。 InnoDB拒绝对父表的删除或更新操作。

·         RESTRICT: 拒绝对父表的删除或更新操作。NO ACTIONRESTRICT都一样,删除ON DELETEON UPDATE子句。(一些数据库系统有延期检查,并且NO ACTION是一个延期检查。在MySQL中,外键约束是被立即检查的,所以NO ACTIONRESTRICT是同样的)。

·         SET DEFAULT: 这个动作被解析程序识别,但InnoDB拒绝包含ON DELETE SET DEFAULTON UPDATE SET DEFAULT子句的表定义。

当父表中的候选键被更新的时候,InnoDB支持同样选择。选择CASCADE,在子表中的外键列被设置为父表中候选键的新值。以同样的方式,如果在子表更新的列参考在另一个表中的外键,更新级联。

注意,InnoDB支持外键在一个表内引用,在这些情况下,子表实际上意味这在表内附属的记录。

InnoDB需要对外键和被引用键的索引以便外键检查可以快速进行且不需要一个表扫描。对外键的索引被自动创建。这是相对于一些老版本,在老版本中索引必须明确创建,否则外键约束的创建会失败。

InnoDB内,外键里和被引用列里相应的列必须有类似的内部数据类型,以便它们不需类型转换就可被比较。整数类型的大小和符号必须相同。字符串类型的长度不需要相同。如果你指定一个SET NULL动作,请确认你没有在子表中宣告该列为为NOT NULL

如果MySQLCREATE TABLE语句报告一个错误号1005,并且错误信息字符串指向errno 150,这意思是因为一个外键约束被不正确形成,表创建失败。类似地,如果ALTER TABLE失败,且它指向errno 150, 那意味着对已变更的表,外键定义会被不正确的形成。你可以使用SHOW INNODB STATUS来显示一个对服务器上最近的InnoDB外键错误的详细解释。

注释:InnoDB不对那些外键或包含NULL列的被引用键值检查外键约束。

 

 

创建和修改 FOREIGN KEY 约束

FOREIGN KEY 约束可以:

  • 作为表定义的一部分在创建表时创建。
  • 如果 FOREIGN KEY 约束与另一个表(或同一表)已有的 PRIMARY KEY 约束或 UNIQUE 约束相关联,则可向现有表添加 FOREIGN KEY 约束。一个表可以有多个 FOREIGN KEY 约束。
  • 对已有的 FOREIGN KEY 约束进行修改或删除。例如,要使一个表的 FOREIGN KEY 约束引用其它列。定义了 FOREIGN KEY 约束列的列宽不能更改。

说明  若要使用 Transact-SQL SQL-DMO修改 FOREIGN KEY 约束,必须首先删除已有的 FOREIGN KEY 约束,然后再通过新定义重新创建。

当向表的现有列添加 FOREIGN KEY 约束时,默认情况下 Microsoft® SQL Server™ 2000 检查列中的现有数据,以确保除 NULL 外的所有数据存在于被引用的 PRIMARY KEY UNIQUE 约束的列中。不过,SQL Server 也可不对列数据的新约束进行检查,不考虑列中的数据而添加新约束。当现有数据已符合新的 FOREIGN KEY 约束,或业务规则要求从此开始强制约束时,使用此选项比较有用。

不过,添加约束而不进行数据检查时一定要注意,因为这样放弃了 SQL Server 对表中数据完整性的控制。

 

1在创建表时创建 FOREIGN KEY 约束

2在已有表中创建 FOREIGN KEY 约束

语法

ALTER TABLE

通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。

语法

ALTER TABLE table
{
[ ALTER COLUMN column_name

    {
new_data_type [ ( precision [ , scale ] ) ]
        [ COLLATE < collation_name > ]
        [ NULL | NOT NULL ]
        | {ADD | DROP } ROWGUIDCOL }
    ]
    | ADD
        {
[ < column_definition > ]
        | column_name AS computed_column_expression
        } [ ,...n ]
    | [ WITH CHECK | WITH NOCHECK ] ADD
        {
< table_constraint > } [ ,...n ]
    | DROP
        {
[ CONSTRAINT ] constraint_name
            | COLUMN column } [ ,...n ]
    | { CHECK | NOCHECK } CONSTRAINT
        {
ALL | constraint_name [ ,...n ] }
    | { ENABLE | DISABLE } TRIGGER
        {
ALL | trigger_name [ ,...n ] }
}

< column_definition > ::=
    {
column_name data_type }
    [ [ DEFAULT constant_expression ] [ WITH VALUES ]
    | [ IDENTITY [ ( seed , increment ) [ NOT FOR REPLICATION ] ] ]
        ]
    [ ROWGUIDCOL ]
    [ COLLATE < collation_name > ]
    [ < column_constraint > ] [ ...n ]

< column_constraint > ::=
    [ CONSTRAINT constraint_name ]
    {
[ NULL | NOT NULL ]
        | [ { PRIMARY KEY | UNIQUE }
            [ CLUSTERED | NONCLUSTERED ]
            [ WITH FILLFACTOR = fillfactor ]
            [ ON { filegroup | DEFAULT } ]
            ]
        | [ [ FOREIGN KEY ]
            REFERENCES ref_table [ ( ref_column ) ]
            [ ON DELETE { CASCADE | NO ACTION } ]
            [ ON UPDATE { CASCADE | NO ACTION } ]
            [ NOT FOR REPLICATION ]
            ]
        | CHECK [ NOT FOR REPLICATION ]
            ( logical_expression )
    }

< table_constraint > ::=
    [ CONSTRAINT constraint_name ]
    {
[ { PRIMARY KEY | UNIQUE }
        [ CLUSTERED | NONCLUSTERED ]
        {
( column [ ,...n ] ) }
        [ WITH FILLFACTOR = fillfactor ]
        [ ON { filegroup | DEFAULT } ]
        ]
        |    FOREIGN KEY
            [ ( column [ ,...n ] ) ]
            REFERENCES ref_table [ ( ref_column [ ,...n ] ) ]
            [ ON DELETE { CASCADE | NO ACTION } ]
            [ ON UPDATE { CASCADE | NO ACTION } ]
            [ NOT FOR REPLICATION ]
        | DEFAULT constant_expression
            [ FOR column ] [ WITH VALUES ]
        |    CHECK [ NOT FOR REPLICATION ]
            ( search_conditions )
    }

 

 

例子:

MSSQL下:

CREATE TABLE [detail] (

       [id] [int] IDENTITY (1, 1) NOT NULL ,

       [age] [int] NOT NULL ,

       [long] [int] NOT NULL ,

       [code] [int] NULL ,

       CONSTRAINT [PK_detail] PRIMARY KEY  CLUSTERED

       (

              [id]

       )  ON [PRIMARY] ,

       CONSTRAINT [FK_detail_Uname] FOREIGN KEY

       (

              [code]

       ) REFERENCES [Uname] (

              [code]

       ) ON DELETE CASCADE

) ON [PRIMARY]

GO

 

可视化工具创建外键关联:

MySql下:SQLyog Enterprise

 

 

 

3创建 FOREIGN KEY 约束时不对现有数据进行检查

4修改 FOREIGN KEY 约束

5 INSERT UPDATE 语句禁用 FOREIGN KEY 约束

6复制时禁用 FOREIGN KEY 约束

7删除 FOREIGN KEY 约束

FOREIGN KEY 约束

禁用 FOREIGN KEY 约束

下列情况可以禁用 FOREIGN KEY 约束:

  • INSERT UPDATE 语句

这种情况允许不经约束验证就可修改表中的数据。在执行 INSERT UPDATE 语句过程中,如果新数据违反约束或约束只应适用于数据库中已有的数据,那么禁用 FOREIGN KEY 约束。

  • 复制处理。

如果一个 FOREIGN KEY 约束为源数据库特有,请在复制时禁用该约束。复制表时,表定义和数据从源数据库复制到目的数据库。这两个数据库通常(但不一定)在不同的服务器上。如果 FOREIGN KEY 约束为源数据库特有而在复制时未禁用,则有可能无谓地妨碍向目标数据库输入数据。

删除 FOREIGN KEY 约束,从而删除了强制外键列和另一表中相关主键(或 UNIQUE 约束)列的引用完整性要求。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/37308.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注