我有两张桌子在这里:
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从猫中删除,我尝试了上面的方法但是不起作用,在我清理了表格书之后,表格类别仍然填充,出了什么问题?
答案 0 :(得分:63)
具有级联删除的外键意味着如果删除父表中的记录,则将自动删除子表中的相应记录。这称为级联删除。
您反过来说,这不是从子表中删除时,记录将从父表中删除。
UPDATE 1:
ON DELETE CASCADE选项用于指定在父表中删除相应行时是否要在子表中删除行。如果未指定级联删除,则数据库服务器的默认行为会阻止您删除表中的数据(如果其他表引用它)。
如果指定此选项,稍后在删除父表中的行时,数据库服务器还会删除子表中与该行(外键)关联的所有行。级联删除功能的主要优点是它允许您减少执行删除操作所需的SQL语句数量。
所以当你从父表中删除行而不是从子表中删除行时会发生什么。
因此,在用户从CAT表中删除条目的情况下,将从books表中删除行。 :)
希望这可以帮助你:)
答案 1 :(得分:18)
Exerpt :
限制和级联删除是两种最常见的选项。 [...]
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
部族将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)
为单位。
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:firstname, :secondname, :email, :password, :password_confirmation, :remember_me) }
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:login, :email, :password, :remember_me) }
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:firstname, :secondname ,:email, :password, :password_confirmation, :current_password) }
end
如果你真的需要相反的(由数据库检查),你将不得不写一个触发器!
答案 2 :(得分:0)
在我使用postgres 9.6的简单经验中,级联删除在实践中对于增长超过平凡大小的表格不起作用。
答案 3 :(得分:-6)
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
);