【问题标题】:Deleting linked data across tables in PostgreSQL删除 PostgreSQL 中跨表的链接数据
【发布时间】:2012-01-07 02:21:25
【问题描述】:

我正在寻找处理删除三个 PostgreSQL 表中链接数据的最佳方法(技术上更多,但想法相同)。

这三个表是机构、地址和机构地址。一个机构可以有多个地址,因此机构地址只是一个链接表,有两列,机构 ID 和地址 ID(定义为它们各自的外键)

我想设置它,以便在删除代理时,它会自动删除代理地址中的链接表行和相关的地址行。 (所以如果一个机构被删除,它的所有地址也会被删除)

我可以得到它来清除链接表,但不知道如何到达地址表。

(另外,地址是一个通用模型,会被其他人引用,比如一个有自己的链接表的“站点”。)

【问题讨论】:

  • 您的描述自相矛盾:如果地址为will be referenced by others,那么您不应将代理上的删除级联到所有链接地址。他们可以与其他人(机构?)联系起来。
  • 对不起,地址表(对象)本身会被其他对象使用。就像一个站点会使用存储在地址表中的地址,但它是唯一的。我们不允许两种不同的事物使用相同的地址,无论是两个以上的代理机构、一个网站和一个代理机构,还是两个以上的网站。

标签: postgresql database-design cascading-deletes


【解决方案1】:

在表定义中使用带有ON DELETE CASCADE 的外键。

ALTER TABLE agency_address
  ADD CONSTRAINT agency_address_agency_fkey FOREIGN KEY (agency_id)
      REFERENCES agency (agency_id) ON DELETE CASCADE;

您似乎也不确定是否应该自动删除地址。

如果是这样,您的数据模型是错误的,地址应该直接依赖于机构,具有类似于上述的外键约束,不需要 n:m 链接表。


更多信息后编辑:

所以地址可以链接到代理机构或网站,但不能同时链接到两者。

该模型可以按照您的方式工作,但您必须以某种方式确保链接到代理机构的地址也不会链接到站点。

addressagency_address 之间的外键约束指向“错误”方向,因此您不能简单地添加另一个ON DELETE CASCADE。您可以使用额外的外键来实现它,但这很棘手。这种每个触发器的方法要简单得多:

CREATE OR REPLACE FUNCTION trg_agency_address_delaft()
  RETURNS trigger AS
$BODY$
BEGIN

DELETE FROM address
WHERE address_id = OLD.address_id;

END;
$BODY$
  LANGUAGE plpgsql;


CREATE TRIGGER delaft
  AFTER DELETE ON agency_address
  FOR EACH ROW EXECUTE PROCEDURE trg_agency_address_delaft();

有关trigger functionstriggers 的更多信息,请参阅手册。

【讨论】:

  • 这个想法是有一个单一的地址表来存储我们所有的地址用于不同的资源。 (例如,机构和站点的地址,两者都可以有多个)这使我们可以为我们的地址提供一个模型/对象,供我们的机构和站点对象使用。地址对象不关心谁/什么在使用它,它只是管理地址表中的东西。代理对象看到/知道它有 N 个地址并创建那么多地址对象。有单独的地址表并扩展代理和站点的地址对象以使用不同的表会更好吗?
  • @jshrc:我在答案中添加了针对这种情况的可能解决方案。
猜你喜欢
  • 2012-05-25
  • 2013-09-14
  • 2013-02-12
  • 2020-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-29
  • 2012-05-22
相关资源
最近更新 更多