[英]PostgreSQL: FOREIGN KEY/ON DELETE CASCADE
I have two tables like here:我有两个像这里的表:
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)
);
So the logic is simple, after user removes all book under category x, x gets removed from cats, i tried method above but doesn't work, after i clean table book, table category still populated, what's wrong?所以逻辑很简单,在用户删除类别 x 下的所有书后,x 从猫中删除,我尝试了上面的方法但不起作用,在我清理表书后,表类别仍然填充,这是怎么回事?
A foreign key with a cascade delete means that if a record in the parent table is deleted, then the corresponding records in the child table will automatically be deleted.级联删除的外键意味着如果父表中的一条记录被删除,那么子表中对应的记录将被自动删除。 This is called a cascade delete.
这称为级联删除。
You are saying in a opposite way, this is not that when you delete from child table then records will be deleted from parent table.您以相反的方式说,这并不是说当您从子表中删除时,记录将从父表中删除。
UPDATE 1:
ON DELETE CASCADE option is to specify whether you want rows deleted in a child table when corresponding rows are deleted in the parent table. ON DELETE CASCADE选项用于指定在父表中删除相应行时是否要删除子表中的行。 If you do not specify cascading deletes, the default behaviour of the database server prevents you from deleting data in a table if other tables reference it.
如果您不指定级联删除,则数据库服务器的默认行为会阻止您在其他表引用该表时删除该表中的数据。
If you specify this option, later when you delete a row in the parent table, the database server also deletes any rows associated with that row (foreign keys) in a child table.如果您指定此选项,稍后当您删除父表中的一行时,数据库服务器也会删除与子表中该行(外键)关联的所有行。 The principal advantage to the cascading-deletes feature is that it allows you to reduce the quantity of SQL statements you need to perform delete actions.
cascading-deletes 功能的主要优点是它允许您减少执行删除操作所需的 SQL 语句的数量。
So it's all about what will happen when you delete rows from Parent table not from child table.因此,这就是当您从父表而不是子表中删除行时会发生什么。
So in your case when user removes entries from categories
table then rows will be deleted from books table.因此,在您的情况下,当用户从
categories
表中删除条目时,行将从书籍表中删除。 :) :)
Hope this helps you :)希望这可以帮助你:)
Excerpt from PostgreSQL documentation : PostgreSQL 文档摘录:
Restricting and cascading deletes are the two most common options.
限制和级联删除是两个最常见的选项。 [...]
CASCADE
specifies that when a referenced row is deleted, row(s) referencing it should be automatically deleted as well.[...]
CASCADE
指定当引用的行被删除时,引用它的行也应该被自动删除。
This means that if you delete a row in schemas.category
, referenced by category_id
in schemas.books
, any such referencing row will also be deleted by ON DELETE CASCADE
.这意味着如果您删除
schemas.books
中由schemas.category
中的category_id
引用的行,任何此类引用行也将被ON DELETE CASCADE
。
Example :示例:
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
clans will CASCADE
to hobbits by REFERENCES
. 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)
If you really need the opposite (checked by the database), you will have to write a trigger!如果你真的需要相反的(由数据库检查),你将不得不写一个触发器!
In my humble experience with postgres 9.6, cascade delete doesn't work in practice for tables that grow above a trivial size.根据我对 postgres 9.6 的简陋经验,级联删除在实践中对于增长超过微不足道大小的表不起作用。
PostgreSQL Forging Key DELETE, UPDATE CASCADE
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.