Home Database Mysql Tutorial 为mysql数据表添加外键(三)总结

为mysql数据表添加外键(三)总结

Jun 07, 2016 pm 03:46 PM
innodb mysql foreign key Summarize support data sheet Add to

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 {

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

<span>[CONSTRAINT <em>symbol</em>] FOREIGN KEY [<em>id</em>] (<em>index_col_name</em>, ...)</span>
Copy after login
<span><span>    </span>REFERENCES <em>tbl_name</em> (<em>index_col_name</em>, ...)</span>
Copy after login
Copy after login
<span><span>    </span>[ON DELETE {RESTRICT | <font>CASCADE</font> | SET NULL | NO ACTION}]</span>
Copy after login
Copy after login
<span><span>    </span>[ON UPDATE {RESTRICT | <font>CASCADE</font> | SET NULL | NO ACTION}]</span>
Copy after login
Copy after login

外键定义服从下列情况:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

对SQL标准的背离:如果在父表内有数个行,其中有相同的被引用键值,然后InnoDB在外键检查中采取动作,就仿佛其它有相同键值的父行不存在一样。例如,如果你已定义一个RESTRICT类型的约束,并且有一个带数个父行的子行,InnoDB不允许任何对这些父行的删除。

居于对应外键约束的索引内的记录,InnoDB通过深度优先选法施行级联操作。

对SQL标准的背离: 如果ON UPDATE CASCADE或ON UPDATE SET NULL递归更新相同的表,之前在级联过程中该表一被更新过,它就象RESTRICT一样动作。这意味着你不能使用自引用ON UPDATE CASCADE或者ON UPDATE SET NULL操作。这将阻止级联更新导致的无限循环。另一方面,一个自引用的ON DELETE SET NULL是有可能的,就像一个自引用ON DELETE CASCADE一样。级联操作不可以被嵌套超过15层深。

对SQL标准的背离: 类似一般的MySQL,在一个插入,删除或更新许多行的SQL语句内,InnoDB逐行检查UNIQUE和FOREIGN KEY约束。按照SQL的标准,默认的行为应被延迟检查,即约束仅在整个SQL语句被处理之后才被检查。直到InnoDB实现延迟的约束检查之前,一些事情是不可能的,比如删除一个通过外键参考到自身的记录。

注释:当前,触发器不被级联外键的动作激活。

一个通过单列外键联系起父表和子表的简单例子如下:

<span>CREATE TABLE parent(id INT NOT NULL,</span>
Copy after login
<span><span>                    </span>PRIMARY KEY (id)</span>
Copy after login
<span>) TYPE=INNODB;</span>
Copy after login
Copy after login
<span>CREATE TABLE child(id INT, parent_id INT,</span>
Copy after login
<span><span>                   </span>INDEX par_ind (parent_id),</span>
Copy after login
<span><span>                   </span>FOREIGN KEY (parent_id) REFERENCES parent(id)</span>
Copy after login
<span><span>                     </span>ON DELETE <font><font>CASCADE</font></font></span>
Copy after login
<span>) TYPE=INNODB;</span>
Copy after login
Copy after login

如下是一个更复杂的例子,其中一个product_order表对其它两个表有外键。一个外键引用一个product表中的双列索引。另一个引用在customer表中的单行索引:

<span>CREATE TABLE product (category INT NOT NULL, id INT NOT NULL,</span>
Copy after login
<span><span>                      </span>price DECIMAL,</span>
Copy after login
<span><span>                      </span>PRIMARY KEY(category, id)) TYPE=INNODB;</span>
Copy after login
<span>CREATE TABLE customer (id INT NOT NULL,</span>
Copy after login
<span><span>                      </span>PRIMARY KEY (id)) TYPE=INNODB;</span>
Copy after login
<span>CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT,</span>
Copy after login
<span><span>                      </span>product_category INT NOT NULL,</span>
Copy after login
<span><span>                      </span>product_id INT NOT NULL,</span>
Copy after login
<span><span>                      </span>customer_id INT NOT NULL,</span>
Copy after login
<span><span>                      </span>PRIMARY KEY(no),</span>
Copy after login
<span><span>                      </span>INDEX (product_category, product_id),</span>
Copy after login
<span><span>                      </span>FOREIGN KEY (product_category, product_id)</span>
Copy after login
<span><span>                        </span>REFERENCES product(category, id)</span>
Copy after login
<span><span>                        </span>ON UPDATE <font>CASCADE</font> ON DELETE RESTRICT,</span>
Copy after login
<span><span>                      </span>INDEX (customer_id),</span>
Copy after login
<span><span>                      </span>FOREIGN KEY (customer_id)</span>
Copy after login
<span><span>   </span><span>                     </span>REFERENCES customer(id)) TYPE=INNODB;</span>
Copy after login

InnoDB允许你用ALTER TABLE往一个表中添加一个新的外键约束:

<span>ALTER TABLE yourtablename</span>
Copy after login
<span><span>    </span>ADD [CONSTRAINT <em>symbol</em>] FOREIGN KEY [<em>id</em>] (<em>index_col_name</em>, ...)</span>
Copy after login
<span><span>    </span>REFERENCES <em>tbl_name</em> (<em>index_col_name</em>, ...)</span>
Copy after login
Copy after login
<span><span>    </span>[ON DELETE {RESTRICT | <font>CASCADE</font> | SET NULL | NO ACTION}]</span>
Copy after login
Copy after login
<span><span>    </span>[ON UPDATE {RESTRICT | <font>CASCADE</font> | SET NULL | NO ACTION}]</span>
Copy after login
Copy after login

记住先创建需要的索引。你也可以用ALTER TABLE往一个表添加一个自引用外键约束。

InnoDB也支持使用ALTER TABLE来移除外键:

<span>ALTER TABLE <em>yourtablename</em> DROP FOREIGN KEY <em>fk_symbol</em>;</span>
Copy after login

当年创建一个外键之时,如果FOREIGN KEY子句包括一个CONSTRAINT名字,你可以引用那个名字来移除外键。另外,当外键被创建之时,fk_symbol值被InnoDB内部保证。当你想要移除一个外键之时,要找出标记,请使用SHOW CREATE TABLE语句。例子如下:

<span>mysql> <strong>SHOW CREATE TABLE ibtest<chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="11" unitname="C">11c</chmetcnv>/G</strong></span>
Copy after login
<span>*************************** 1. row ***************************</span>
Copy after login
<span><span>       </span>Table: ibtest<chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="11" unitname="C">11c</chmetcnv></span>
Copy after login
<span>Create Table: CREATE TABLE `ibtest<chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="11" unitname="C">11c</chmetcnv>` (</span>
Copy after login
<span><span>  </span>`A` int(11) NOT NULL auto_increment,</span>
Copy after login
<span><span>  </span>`D` int(11) NOT NULL default '0',</span>
Copy after login
<span><span>  </span>`B` varchar(200) NOT NULL default '',</span>
Copy after login
<span><span>  </span>`C` varchar(175) default NULL,</span>
Copy after login
<span><span>  </span>PRIMARY KEY<span>  </span>(`A`,`D`,`B`),</span>
Copy after login
<span><span>  </span>KEY `B` (`B`,`C`),</span>
Copy after login
<span><span>  </span>KEY `C` (`C`),</span>
Copy after login
<span><span>  </span>CONSTRAINT `0_38775` FOREIGN KEY (`A`, `D`)</span>
Copy after login
<span>REFERENCES `ibtest<chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="11" unitname="a">11a</chmetcnv>` (`A`, `D`)</span>
Copy after login
<span>ON DELETE <font>CASCADE</font> ON UPDATE <font>CASCADE</font>,</span>
Copy after login
<span><span>  </span>CONSTRAINT `0_38776` FOREIGN KEY (`B`, `C`)</span>
Copy after login
<span>REFERENCES `ibtest<chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="11" unitname="a">11a</chmetcnv>` (`B`, `C`)</span>
Copy after login
<span>ON DELETE <font>CASCADE</font> ON UPDATE <font><font>CASCADE</font></font></span>
Copy after login
<span>) ENGINE=INNODB CHARSET=latin1</span>
Copy after login
<span>1 row in set (0.01 sec)</span>
Copy after login
Copy after login
<span>mysql> <strong>ALTER TABLE ibtest<chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="11" unitname="C">11c</chmetcnv> DROP FOREIGN KEY 0_38775;</strong></span>
Copy after login

InnoDB解析程序允许你在FOREIGN KEY ... REFERENCES ...子句中用`(backticks)把表和列名名字围起来。InnoDB解析程序也考虑到lower_case_table_names系统变量的设置。

InnoDB返回一个表的外键定义作为SHOW CREATE TABLE语句输出的一部分:

<span>SHOW CREATE TABLE <em>tbl_name</em>;</span>
Copy after login

从这个版本起,mysqldump也将表的正确定义生成到转储文件中,且并不忘记外键。

你可以如下对一个表显示外键约束:

<span>SHOW TABLE STATUS FROM <em>db_name</em> LIKE '<em>tbl_name</em>';</span>
Copy after login

外键约束被列在输出的Comment列。

当执行外键检查之时,InnoDB对它照看着的子或父记录设置共享的行级锁。InnoDB立即检查外键约束,检查不对事务提交延迟。

要使得对有外键关系的表重新载入转储文件变得更容易,mysqldump自动在转储输出中包括一个语句设置FOREIGN_KEY_CHECKS为0。这避免在转储被重新装载之时,与不得不被以特别顺序重新装载的表相关的问题。也可以手动设置这个变量:

<span>mysql> <strong>SET FOREIGN_KEY_CHECKS = 0;</strong></span>
Copy after login
<span>mysql> <strong>SOURCE <em>dump_file_name</em>;</strong></span>
Copy after login
<span>mysql> <strong>SET FOREIGN_KEY_CHECKS = 1;</strong></span>
Copy after login

如果转储文件包含对外键是不正确顺序的表,这就以任何顺序导入该表。这样也加快导入操作。设置FOREIGN_KEY_CHECKS为0,对于在LOAD DATA和ALTER TABLE操作中忽略外键限制也是非常有用的。

InnoDB不允许你删除一个被FOREIGN KEY表约束引用的表,除非你做设置SET FOREIGN_KEY_CHECKS=0。当你移除一个表的时候,在它的创建语句里定义的约束也被移除。

如果你重新创建一个被移除的表,它必须有一个遵从于也引用它的外键约束的定义。它必须有正确的列名和类型,并且如前所述,它必须对被引用的键有索引。如果这些不被满足,MySQL返回错误号1005 并在错误信息字符串中指向errno 150。

 
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Roblox: Bubble Gum Simulator Infinity - How To Get And Use Royal Keys
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Fusion System, Explained
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers Of The Witch Tree - How To Unlock The Grappling Hook
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1670
14
PHP Tutorial
1274
29
C# Tutorial
1256
24
Laravel Introduction Example Laravel Introduction Example Apr 18, 2025 pm 12:45 PM

Laravel is a PHP framework for easy building of web applications. It provides a range of powerful features including: Installation: Install the Laravel CLI globally with Composer and create applications in the project directory. Routing: Define the relationship between the URL and the handler in routes/web.php. View: Create a view in resources/views to render the application's interface. Database Integration: Provides out-of-the-box integration with databases such as MySQL and uses migration to create and modify tables. Model and Controller: The model represents the database entity and the controller processes HTTP requests.

MySQL and phpMyAdmin: Core Features and Functions MySQL and phpMyAdmin: Core Features and Functions Apr 22, 2025 am 12:12 AM

MySQL and phpMyAdmin are powerful database management tools. 1) MySQL is used to create databases and tables, and to execute DML and SQL queries. 2) phpMyAdmin provides an intuitive interface for database management, table structure management, data operations and user permission management.

MySQL vs. Other Programming Languages: A Comparison MySQL vs. Other Programming Languages: A Comparison Apr 19, 2025 am 12:22 AM

Compared with other programming languages, MySQL is mainly used to store and manage data, while other languages ​​such as Python, Java, and C are used for logical processing and application development. MySQL is known for its high performance, scalability and cross-platform support, suitable for data management needs, while other languages ​​have advantages in their respective fields such as data analytics, enterprise applications, and system programming.

Laravel framework installation method Laravel framework installation method Apr 18, 2025 pm 12:54 PM

Article summary: This article provides detailed step-by-step instructions to guide readers on how to easily install the Laravel framework. Laravel is a powerful PHP framework that speeds up the development process of web applications. This tutorial covers the installation process from system requirements to configuring databases and setting up routing. By following these steps, readers can quickly and efficiently lay a solid foundation for their Laravel project.

Explain the purpose of foreign keys in MySQL. Explain the purpose of foreign keys in MySQL. Apr 25, 2025 am 12:17 AM

In MySQL, the function of foreign keys is to establish the relationship between tables and ensure the consistency and integrity of the data. Foreign keys maintain the effectiveness of data through reference integrity checks and cascading operations. Pay attention to performance optimization and avoid common errors when using them.

Compare and contrast MySQL and MariaDB. Compare and contrast MySQL and MariaDB. Apr 26, 2025 am 12:08 AM

The main difference between MySQL and MariaDB is performance, functionality and license: 1. MySQL is developed by Oracle, and MariaDB is its fork. 2. MariaDB may perform better in high load environments. 3.MariaDB provides more storage engines and functions. 4.MySQL adopts a dual license, and MariaDB is completely open source. The existing infrastructure, performance requirements, functional requirements and license costs should be taken into account when choosing.

What software is better for yi framework? Recommended software for yi framework What software is better for yi framework? Recommended software for yi framework Apr 18, 2025 pm 11:03 PM

Abstract of the first paragraph of the article: When choosing software to develop Yi framework applications, multiple factors need to be considered. While native mobile application development tools such as XCode and Android Studio can provide strong control and flexibility, cross-platform frameworks such as React Native and Flutter are becoming increasingly popular with the benefits of being able to deploy to multiple platforms at once. For developers new to mobile development, low-code or no-code platforms such as AppSheet and Glide can quickly and easily build applications. Additionally, cloud service providers such as AWS Amplify and Firebase provide comprehensive tools

SQL vs. MySQL: Clarifying the Relationship Between the Two SQL vs. MySQL: Clarifying the Relationship Between the Two Apr 24, 2025 am 12:02 AM

SQL is a standard language for managing relational databases, while MySQL is a database management system that uses SQL. SQL defines ways to interact with a database, including CRUD operations, while MySQL implements the SQL standard and provides additional features such as stored procedures and triggers.

See all articles