2013-01-03 12 views
12

DELETE CASCADE ON FOREIGN KEY /:ユーザーがカテゴリの下にあるすべてのブックを削除した後PostgreSQLは:私はここのような二つのテーブル持って

DROP TABLE IF EXISTS schemas.book; 
DROP TABLE IF EXISTS schemas.category; 
DROP SCHEMA IF EXISTS schemas; 
CREATE SCHEMA schemas; 

CREATE TABLE schemas.category (
    id   BIGSERIAL PRIMARY KEY, 
    name  VARCHAR NOT NULL, 
    UNIQUE(name) 
); 

CREATE TABLE schemas.book (
    id   BIGSERIAL PRIMARY KEY, 
    published DATE  NOT NULL, 
    category_id BIGINT NOT NULL REFERENCES schemas.category ON DELETE CASCADE ON UPDATE CASCADE, 
    author  VARCHAR NOT NULL, 
    name  VARCHAR NOT NULL, 
    UNIQUE(published, author, name), 
    FOREIGN KEY(category_id) REFERENCES schemas.category (id) 
); 

だからロジックは、シンプルで、X、X catsから削除される、私は上記の方法を試してみましたしかし、私はテーブルの本をきれいにした後、テーブルのカテゴリがまだ人口、何が問題なのですか?

+1

答えはあなたの質問を解決しましたか?もしそうなら、受け入れてください。 OTherwise @Mariはあなたが必要とするものを知っています。 – bonCodigo

+0

はい、[crosspost](http://stackoverflow.com/questions/14161212/how-to-create-one-table-which-shares-common-id-with-another-and-which-row-gets- r/14161296#comment19641520_14161296) – juk

答えて

41

カスケード削除の外部キーとは、親テーブルのレコードを削除すると、子テーブルの対応するレコードが自動的に削除されることを意味します。これはカスケード削除と呼ばれます。

逆の言い方をすると、これは、子テーブルから削除して親テーブルからレコードを削除した場合とは異なります。 DELETE CASCADEオプションON

UPDATE 1: 

は、対応する行が親テーブルで削除されたときに、子テーブルで削除された行をしたいかどうかを指定することです。カスケード削除を指定しない場合、データベースサーバーのデフォルトの動作により、他のテーブルが参照する場合は、テーブル内のデータを削除できなくなります。

このオプションを指定すると、後で親表の行を削除すると、データベース・サーバーは子表のその行(外部キー)に関連付けられている行も削除します。カスケード削除機能の主な利点は、削除操作を実行するために必要なSQL文の量を減らすことができることです。

親テーブルから子テーブルから行を削除すると、すべてのことが起こります。

したがって、ユーザーがCATsテーブルからエントリを削除すると、ブックテーブルから行が削除されます。 :)

ホープこれはあなたを助けます:) PostgreSQLのdocumentationから

+0

お願い:p – juk

+1

さらに詳しい説明を追加しています。質問があれば教えてください。 – Mari

+3

SQLにはツリー構造はありません。あなたは実際には、参照の観点からこの回答を書き直そうと試みるべきであり、 "親"や "子供"ではありません。 – Martin

5

抜粋

制限および削除をカスケードの2つの最も一般的なオプションです。 [...] CASCADEは、参照された行が削除されると、それを参照する行も自動的に削除されるべきであることを指定します。

つまり、書籍で参照されるカテゴリを削除すると、参照先の書籍もON DELETE CASCADEで削除されます。

CREATE SCHEMA shire; 

CREATE TABLE shire.clans (
    id serial PRIMARY KEY, 
    clan varchar 
); 

CREATE TABLE shire.hobbits (
    id serial PRIMARY KEY, 
    hobbit varchar, 
    clan_id integer REFERENCES shire.clans (id) ON DELETE CASCADE 
); 

DELETE FROM氏族がREFERENCESによってホビットにCASCADEます。

[email protected]> psql 
sauron=# SELECT * FROM shire.clans; 
id | clan  
----+------------ 
    1 | Baggins 
    2 | Gamgi 
(2 rows) 

sauron=# SELECT * FROM shire.hobbits; 
id | hobbit | clan_id 
----+----------+--------- 
    1 | Bilbo |  1 
    2 | Frodo |  1 
    3 | Samwise |  2 
(3 rows) 

sauron=# DELETE FROM shire.clans WHERE id = 1 RETURNING *; 
id | clan 
----+--------- 
    1 | Baggins 
(1 row) 

DELETE 1 
sauron=# SELECT * FROM shire.hobbits; 
id | hobbit | clan_id 
----+----------+--------- 
    3 | Samwise |  2 
(1 row) 

本当に逆の(データベースによってチェックされている)必要がある場合は、トリガーを作成する必要があります!

-5

PostgreSQLの鍛造キーのPostgres 9.6との私の謙虚な経験で

CREATE TABLE apps_user(
    user_id SERIAL PRIMARY KEY, 
    username character varying(30), 
    userpass character varying(50), 
    created_on DATE 
); 

CREATE TABLE apps_profile(
    pro_id SERIAL PRIMARY KEY, 
    user_id INT4 REFERENCES apps_user(user_id) ON DELETE CASCADE ON UPDATE CASCADE, 
    firstname VARCHAR(30), 
    lastname VARCHAR(50), 
    email VARCHAR UNIQUE, 
    dob DATE 
); 
+3

この切り取りと貼り付けは、質問とは関係のない貧弱な例であり、最も重要なキーワードは、そのような種類の音がランダムに入れ替わるものです。 – Martin

+0

が公正であるとするには、 'FORGING' sort-ofはそれを放棄します。 –

1

、UPDATE CASCADEをDELETE、カスケード削除些細な大きさの上に成長したテーブルのために、実際には機能しません。

  • さらに悪いことに、カスケード削除が起こっている間、テーブルは を関係者テーブル(および潜在的にあなたの全体のデータベースが) 使用できないので、ロックされています。
  • さらに悪いことに、削除カスケード中に何をしているのかをポストグレストに伝えるのは難しいです。 時間がかかっている場合は、 どのテーブルが遅くなっていますか?おそらく、それは のどこかのpg_stats情報ですか?それは伝えにくいです。
+0

これは、適切なトランザクションを持つデータベース内での作業の定義です。第二に、これは質問に対する答えではありません。 – Martin

関連する問題