web-dev-qa-db-ja.com

「TRUNCATEはON DELETEトリガーを実行しません」trueまたはfalse

なぜTRUNCATEがDMLではなくDDLに配置されるのかというトピックについて検索していましたが、ここで次の回答が見つかりました なぜDDLが切り捨てられるのですか?

私はこの答え私は以下のように文を見つけました

「TRUNCATEがON DELETEトリガーを実行しないという事実は、通常のDML操作とは異なります」

これは MYSQLリファレンスマニュアル と競合します。

「FOREIGN KEY制約がDELETE CASCADEを指定している場合、子(参照)テーブルからの行が削除され、切り捨てられたテーブルは空になります。」

私は混乱した状態にあります。この問題について詳しく説明してください。

ありがとうございました

4
geeksal

最初のリンク( なぜDDLが切り捨てられているのですか? )は、MySQLではなくOracleに関するものです。関連性はありますが、DBMSが異なると、同じ機能の実装も異なります。 OracleおよびSQL Serverでは、TRUNCATEはDDLではなくDDLです。

MySQLでは、使用するバージョンが重要です。

  • バージョン5.1まで、ドキュメントには次のように書かれています:

論理的には、TRUNCATE TABLEは、すべての行を削除するDELETEステートメントとequivalentですが、実際の違い状況によっては。

InnoDBテーブルの場合:

  • FOREIGN KEY制約がない場合、InnoDBは元のテーブルを削除し、同じ定義で空のテーブルを作成することで高速トランケーションを実行します。これは、行を1つずつ削除するよりもはるかに高速です。

  • innodb_file_per_tableオプションを有効にしてこの高速トランケーション手法を使用すると、オペレーティングシステムは解放されたディスク領域を再利用できます。 InnoDBプラグインのユーザーの場合、TRUNCATE TABLEによるディスク領域の再利用で説明されているように、領域は自動的に再利用されます。 InnoDBプラグインをインストールしていない場合は、OPTIMIZE TABLEステートメントを発行して、テーブルのディスク領域を解放します。

  • テーブルを参照するFOREIGN KEY制約がある場合、InnoDBはTRUNCATE TABLEで処理します行を1つずつ削除します制約を処理しながら処理しますFOREIGN KEY制約がDELETE CASCADEを指定している場合、子(参照されている)テーブルから行が削除され、切り捨てられたテーブルは空になります。 FOREIGN KEY制約でCASCADEが指定されていない場合、TRUNCATE TABLEステートメントは行を1つずつ削除し、子が参照する親行を検出すると停止し、次のエラーを返します。

    ERROR 1451 (23000): Cannot delete or update a parent row: a foreign  
    key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1`  
    FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))  
    

ただし、バージョン5.5以降の場合、ドキュメントには次のように記載されています。

論理的には、TRUNCATE TABLEは、すべての行またはDROP TABLEのシーケンスを削除するDELETEステートメントとsimilarです。およびCREATE TABLEステートメント。高いパフォーマンスを達成するために、データを削除するDMLメソッドをバイパスします。したがって、ロールバックすることはできません、それはON DELETEトリガーを起動させません、およびそれは、親子外部キー関係を持つInnoDBテーブルでは実行できません。

TRUNCATE TABLEDELETEに似ていますが、DMLステートメントではなくDDLステートメントとして分類されます。 MySQL 5.5では、次の点でDELETEと異なります。

...

3
ypercubeᵀᴹ