簡體   English   中英

PostgreSQL:外鍵/刪除級聯

[英]PostgreSQL: FOREIGN KEY/ON DELETE CASCADE

我有兩個像這里的表:

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 從貓中刪除,我嘗試了上面的方法但不起作用,在我清理表書后,表類別仍然填充,這是怎么回事?

級聯刪除的外鍵意味着如果父表中的一條記錄被刪除,那么子表中對應的記錄將被自動刪除。 這稱為級聯刪除。

您以相反的方式說,這並不是說當您從子表中刪除時,記錄將從父表中刪除。

UPDATE 1:

ON DELETE CASCADE選項用於指定在父表中刪除相應行時是否要刪除子表中的行。 如果您不指定級聯刪除,則數據庫服務器的默認行為會阻止您在其他表引用該表時刪除該表中的數據。

如果您指定此選項,稍后當您刪除父表中的一行時,數據庫服務器也會刪除與子表中該行(外鍵)關聯的所有行。 cascading-deletes 功能的主要優點是它允許您減少執行刪除操作所需的 SQL 語句的數量。

因此,這就是當您從父表而不是子表中刪除行時會發生什么。

因此,在您的情況下,當用戶從categories表中刪除條目時,行將從書籍表中刪除。 :)

希望這可以幫助你:)

PostgreSQL 文檔摘錄

限制和級聯刪除是兩個最常見的選項。 [...] CASCADE指定當引用的行被刪除時,引用它的行也應該被自動刪除。

這意味着如果您刪除schemas.books中由schemas.category中的category_id引用的行,任何此類引用行也將被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 CASCADE將通過REFERENCES級聯到霍比特人。

sauron@mordor> 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)

如果你真的需要相反的(由數據庫檢查),你將不得不寫一個觸發器!

根據我對 postgres 9.6 的簡陋經驗,級聯刪除在實踐中對於增長超過微不足道大小的表不起作用。

  • 更糟糕的是,當刪除級聯進行時,所涉及的表被鎖定,因此這些表(可能還有您的整個數據庫)無法使用。
  • 更糟糕的是,很難讓 postgres 告訴你它在刪除級聯期間做了什么。 如果需要很長時間,哪個或哪些表使它變慢? 也許它在 pg_stats 信息中的某個地方? 很難說。

PostgreSQL Forging Key DELETE, UPDATE CASCADE

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM