30

私は2つのテーブルを持っています:

TableY:
    id, name, description

TableX:
    id, name, y_id

TableX( )内に外部キーを追加しましたy_id REFERENCING tableY id ON DELETE CASCADE。から削除するTableXと、TableY id残ります(理論的には削除する必要があります)。ON DELETE CASCADEオプションの仕組みを誤解していると思います。誰が私が間違っているのか教えてもらえますか?

これもON DELETE CASCADEを見ましたが、あまり意味がありませんでした。

4

2 に答える 2

61

簡潔な答え

ON DELETE CASCADE は制約オプションを指定します。あなたの場合 (table_x に依存する table_x と table_y があるとします)、table_x の行を削除し、この行が table_y から参照されている場合、table_x の行が削除され、table_y のこの行を参照していたすべての行も削除されます。

テーブルを削除し、このテーブルに 1 つ以上の他のテーブルが依存する場合は、CASCADE キーワードを指定して DROP TABLE を使用します。

DROP、DELETE、および ON DELETE CASCADE 制約オプションの詳細

ドロップと削除

データベースからテーブルを削除したい場合は、drop という単語を使用します。ワードdeleteを使用する場合、テーブルからコンテンツを削除/削除することを意味します(ただし、テーブルを維持したい=データベースに存在し続ける)。

他のテーブルから参照されている行の削除

テーブルに行があり (たとえば、table_x と ID 1 の行)、この行が他のテーブルから参照されている場合 (他のテーブルには、このエントリにリンクされた外部キーがあります)、次のように行を削除することはできません。エラーが発生します。

DELETE FROM table_x WHERE id = 1;

ERROR:  update or delete on table "table_x" violates foreign key constraint "constraint_name" on table "table_y"
DETAIL:  Key (id)=(1) is still referenced from table "table_y".

理由は、エラーの詳細部分に記載されています。他のテーブルのエントリはこのエントリを参照します。例として、テーブル account とテーブル account_activity を想像できます。テーブル account からエントリを削除する (1 つのアカウントを削除する) 場合、テーブル account_activity から、テーブル account のこの特定のエントリを参照するすべてのエントリを削除する必要があります。そうしないと、どのアカウントも参照しないアカウント アクティビティになってしまいます。

達成したい内容に応じて、次の 2 つの可能性があります。

  1. テーブル全体 (table_x) の内容と、このテーブルへの参照 (外部キー) を持つすべてのテーブルの内容を削除します。
  2. 1 つのテーブルから WHERE 句で指定された 1 つ以上のエントリ (行) を削除し、このエントリを参照するすべての行も削除します (上記の account と account_activity の例のように)。

1) CASCADE キーワードで TRUNCATE を使用する

TRUNCATE table_x CASCADE;

2) 列の table_y にある制約を変更して、ON DELETE CASCADE オプションを持つようにします。

ALTER TABLE table_y   
    DROP CONSTRAINT constraint_name,   
    ADD CONSTRAINT constraint_name FOREIGN KEY (column_in_table_y)
          REFERENCES table_x (referenced_column_in_table_x) ON DELETE CASCADE;

他のテーブルが依存しているテーブルの削除

テーブル (table_x など) があり、他のテーブルがそれに依存している場合、このテーブルを削除することはできません。依存とは、他のテーブルがこのテーブル (table_x) を参照する (外部キーを持つ) ことを意味します。そのようなテーブルを削除しようとすると、エラーが発生します。

DROP TABLE table_x;

ERROR:  cannot drop table table_x because other objects depend on it
DETAIL:  constraint id_x_fk on table table_y depends on table table_x
HINT:  Use DROP ... CASCADE to drop the dependent objects too.

エラーはヒントを与えます。そのようなテーブルを削除したい場合は、カスケード キーワードで drop を使用する必要があります。テーブルが削除され、このテーブルを参照するすべての制約も削除されます。

DROP TABLE table_x CASCADE;

table_x と table_y を作成します。

CREATE TABLE table_x
(
  id integer NOT NULL,
  text character varying(255) NOT NULL,
  CONSTRAINT table_x_pk PRIMARY KEY (id)
);

CREATE TABLE table_y
(
  id integer NOT NULL,
  text character varying(255) NOT NULL,
  id_x integer NOT NULL,
  CONSTRAINT table_y_pk PRIMARY KEY (id)
);

table_y の列 id_x に id_x_fk という名前の制約を作成します。

ALTER TABLE table_y
  ADD CONSTRAINT id_x_fk FOREIGN KEY (id_x)
      REFERENCES table_x (id);

table_x と table_y にテスト データを挿入します。

INSERT INTO table_x VALUES
    (1, 'super x'),
    (2, 'great x');

INSERT INTO table_y VALUES
    (1, 'y one', 2),
    (2, 'y two', 1),
    (3, 'y three', 1);

table_x から削除しています (エラー)。

DELETE FROM table_x WHERE id = 1;

同じ名前の制約を削除して追加しています。

ALTER TABLE table_y
  DROP CONSTRAINT id_x_fk,
  ADD CONSTRAINT id_x_fk FOREIGN KEY (id_x)
      REFERENCES table_x (id) ON DELETE CASCADE;

table_x からも table_y からも削除します (正しい)。

DELETE FROM table_x WHERE id = 1;

table_x と table_y からすべてのコンテンツを削除します。

TRUNCATE table_x CASCADE;

table_x をドロップ (削除) し、table_y の id_x_fk 制約をドロップします。

DROP TABLE table_x CASCADE;

知らせ

table_x に行があり (例: ID = 3)、このエントリ (この ID) が table_y から参照されていない場合、制約に ON DELETE CASCADE オプションがなくても (制約違反がないため)、行を削除できます。

コードは、「Visual C++ ビルド 1600、64 ビットでコンパイルされた PostgreSQL 9.2.4」でテストされました。

ソース:

http://www.postgresql.org/docs/current/static/sql-droptable.html

http://www.postgresql.org/docs/current/static/sql-delete.html

http://www.postgresql.org/docs/current/static/ddl-constraints.html

http://www.postgresql.org/docs/current/static/sql-altertable.html

PostgreSQLはすべてのコンテンツを削除します

于 2014-08-26T06:48:07.823 に答える
17

誤解されたと思います。から行を削除しようとすると、からTableYの対応する行TableXがカスケード削除されます。このオプションは、セカンダリ関連のテーブルがあり、制約に違反したりゴミを残したりせずにプライマリテーブルから親行を削除してすべてをクリーンアップする場合に不可欠です。

于 2012-07-16T12:57:48.917 に答える