検索
ホームページデータベースmysql チュートリアル为mysql数据表添加外键(三)总结

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

Jun 07, 2016 pm 03:46 PM
innodbmysql外部キー要約するサポートデータシートに追加

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>
<span><span>    </span>REFERENCES <em>tbl_name</em> (<em>index_col_name</em>, ...)</span>
<span><span>    </span>[ON DELETE {RESTRICT | <font>CASCADE</font> | SET NULL | NO ACTION}]</span>
<span><span>    </span>[ON UPDATE {RESTRICT | <font>CASCADE</font> | SET NULL | NO ACTION}]</span>

外键定义服从下列情况:

·         所有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>
<span><span>                    </span>PRIMARY KEY (id)</span>
<span>) TYPE=INNODB;</span>
<span>CREATE TABLE child(id INT, parent_id INT,</span>
<span><span>                   </span>INDEX par_ind (parent_id),</span>
<span><span>                   </span>FOREIGN KEY (parent_id) REFERENCES parent(id)</span>
<span><span>                     </span>ON DELETE <font><font>CASCADE</font></font></span>
<span>) TYPE=INNODB;</span>

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

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

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

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

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

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

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

当年创建一个外键之时,如果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>
<span>*************************** 1. row ***************************</span>
<span><span>       </span>Table: ibtest<chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="11" unitname="C">11c</chmetcnv></span>
<span>Create Table: CREATE TABLE `ibtest<chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="11" unitname="C">11c</chmetcnv>` (</span>
<span><span>  </span>`A` int(11) NOT NULL auto_increment,</span>
<span><span>  </span>`D` int(11) NOT NULL default '0',</span>
<span><span>  </span>`B` varchar(200) NOT NULL default '',</span>
<span><span>  </span>`C` varchar(175) default NULL,</span>
<span><span>  </span>PRIMARY KEY<span>  </span>(`A`,`D`,`B`),</span>
<span><span>  </span>KEY `B` (`B`,`C`),</span>
<span><span>  </span>KEY `C` (`C`),</span>
<span><span>  </span>CONSTRAINT `0_38775` FOREIGN KEY (`A`, `D`)</span>
<span>REFERENCES `ibtest<chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="11" unitname="a">11a</chmetcnv>` (`A`, `D`)</span>
<span>ON DELETE <font>CASCADE</font> ON UPDATE <font>CASCADE</font>,</span>
<span><span>  </span>CONSTRAINT `0_38776` FOREIGN KEY (`B`, `C`)</span>
<span>REFERENCES `ibtest<chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="11" unitname="a">11a</chmetcnv>` (`B`, `C`)</span>
<span>ON DELETE <font>CASCADE</font> ON UPDATE <font><font>CASCADE</font></font></span>
<span>) ENGINE=INNODB CHARSET=latin1</span>
<span>1 row in set (0.01 sec)</span>

<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>

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

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

<span>SHOW CREATE TABLE <em>tbl_name</em>;</span>

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

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

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

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

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

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

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

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

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

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

 
声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
複数の単一列インデックスに対して複合インデックスをいつ使用する必要がありますか?複数の単一列インデックスに対して複合インデックスをいつ使用する必要がありますか?Apr 11, 2025 am 12:06 AM

データベースの最適化では、クエリ要件に従ってインデックス作成戦略を選択する必要があります。1。クエリに複数の列が含まれ、条件の順序が固定されている場合、複合インデックスを使用します。 2。クエリに複数の列が含まれているが、条件の順序が修正されていない場合、複数の単一列インデックスを使用します。複合インデックスは、マルチコラムクエリの最適化に適していますが、単一列インデックスは単一列クエリに適しています。

MySQLでスロークエリを識別して最適化する方法は? (スロークエリログ、Performance_schema)MySQLでスロークエリを識別して最適化する方法は? (スロークエリログ、Performance_schema)Apr 10, 2025 am 09:36 AM

MySQLスロークエリを最適化するには、slowquerylogとperformance_schemaを使用する必要があります。1。LowerQueryLogを有効にし、しきい値を設定して、スロークエリを記録します。 2。performance_schemaを使用してクエリの実行の詳細を分析し、パフォーマンスのボトルネックを見つけて最適化します。

MySQLおよびSQL:開発者にとって不可欠なスキルMySQLおよびSQL:開発者にとって不可欠なスキルApr 10, 2025 am 09:30 AM

MySQLとSQLは、開発者にとって不可欠なスキルです。 1.MYSQLはオープンソースのリレーショナルデータベース管理システムであり、SQLはデータベースの管理と操作に使用される標準言語です。 2.MYSQLは、効率的なデータストレージと検索機能を介して複数のストレージエンジンをサポートし、SQLは簡単なステートメントを通じて複雑なデータ操作を完了します。 3.使用の例には、条件によるフィルタリングやソートなどの基本的なクエリと高度なクエリが含まれます。 4.一般的なエラーには、SQLステートメントをチェックして説明コマンドを使用することで最適化できる構文エラーとパフォーマンスの問題が含まれます。 5.パフォーマンス最適化手法には、インデックスの使用、フルテーブルスキャンの回避、参加操作の最適化、コードの読み取り可能性の向上が含まれます。

MySQL非同期マスタースレーブレプリケーションプロセスを説明してください。MySQL非同期マスタースレーブレプリケーションプロセスを説明してください。Apr 10, 2025 am 09:30 AM

MySQL非同期マスタースレーブレプリケーションにより、BINLOGを介したデータの同期が可能になり、読み取りパフォーマンスと高可用性が向上します。 1)マスターサーバーレコードはBinlogに変更されます。 2)スレーブサーバーは、I/Oスレッドを介してBINLOGを読み取ります。 3)サーバーSQLスレッドは、BINLOGを適用してデータを同期させます。

MySQL:簡単な学習のためのシンプルな概念MySQL:簡単な学習のためのシンプルな概念Apr 10, 2025 am 09:29 AM

MySQLは、オープンソースのリレーショナルデータベース管理システムです。 1)データベースとテーブルの作成:createdatabaseおよびcreateTableコマンドを使用します。 2)基本操作:挿入、更新、削除、選択。 3)高度な操作:参加、サブクエリ、トランザクション処理。 4)デバッグスキル:構文、データ型、およびアクセス許可を確認します。 5)最適化の提案:インデックスを使用し、選択*を避け、トランザクションを使用します。

MySQL:ユーザーフレンドリーなデータベースの紹介MySQL:ユーザーフレンドリーなデータベースの紹介Apr 10, 2025 am 09:27 AM

MySQLのインストールと基本操作には、次のものが含まれます。1。mysqlをダウンロードしてインストールし、ルートユーザーパスワードを設定します。 2。sqlコマンドを使用して、createdatabaseやcreateTableなどのデータベースとテーブルを作成します。 3. CRUD操作を実行し、挿入、選択、更新、コマンドを削除します。 4.パフォーマンスを最適化し、複雑なロジックを実装するためのインデックスとストアドプロシージャを作成します。これらの手順を使用すると、MySQLデータベースをゼロから構築および管理できます。

InnoDBバッファープールはどのように機能し、なぜパフォーマンスに不可欠なのですか?InnoDBバッファープールはどのように機能し、なぜパフォーマンスに不可欠なのですか?Apr 09, 2025 am 12:12 AM

Innodbbufferpoolは、データとインデックスページをメモリにロードすることにより、MySQLデータベースのパフォーマンスを向上させます。 1)データページは、ディスクI/Oを削減するためにBufferPoolにロードされます。 2)汚れたページは、定期的にディスクにマークされ、リフレッシュされます。 3)LRUアルゴリズム管理データページの排除。 4)読み出しメカニズムは、可能なデータページを事前にロードします。

MySQL:初心者向けのデータ管理の容易さMySQL:初心者向けのデータ管理の容易さApr 09, 2025 am 12:07 AM

MySQLは、インストールが簡単で、強力で管理しやすいため、初心者に適しています。 1.さまざまなオペレーティングシステムに適した、単純なインストールと構成。 2。データベースとテーブルの作成、挿入、クエリ、更新、削除などの基本操作をサポートします。 3.参加オペレーションやサブクエリなどの高度な機能を提供します。 4.インデックス、クエリの最適化、テーブルパーティション化により、パフォーマンスを改善できます。 5。データのセキュリティと一貫性を確保するために、バックアップ、リカバリ、セキュリティ対策をサポートします。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境