像引用计数或数据库行的共享指针?

时间:2011-08-31 14:14:23

标签: sql postgresql foreign-keys

首先,我使用的是Postgres 9.1。

我有一个名为filepaths的表和其他表,这些表的行指向其相应文件路径的id。是否存在一种用于引用计数文件路径的通用设计方法,以便在删除其他行并且不再引用特定文件路径行时,也可以删除它?

示例:

    [filepaths]
    1 | c:\windows\system32\test.exe
    2 | c:\windows\calc.exe

    [events_2011_08_30]
    [1][timestamp][other data] [ filepaths = 1]
    [2][timestamp][other data] [ filepaths = 2]

    [events_2011_08_31]
    [1][timestamp][other data] [ filepaths = 1]

所以我将把数据存储在表中进行分区,并且我想在旧表超过30天时删除旧表(仍然会将它们存档)。在上面的例子中,我们假设只有那两个events_表。如果我删除2011_08_30,我想要一种方法来知道没有任何东西指向文件路径'2'并因此删除它,但是知道一行仍指向文件路径'1'并因此保留它。

有任何想法,建议等吗?我相信我读过的一些策略,至少对于postgres和触发器,仍然有关于哪个线程首先锁定主键列和其他相关问题的竞争条件。

谢谢!

2 个答案:

答案 0 :(得分:2)

首先,我要挑战每个日期在一个表上划分数据的愿望。相反,我建议您在表格中添加一个名为effective_date或类似的列。


filepaths的引用计数而言,可以通过多种方式实现,但为了确保代码的封装,我建议采用以下两种方法之一......

<强> 1。存储过程API

通过确保通过存储过程处理所有 INSERT,UPDATE和DELETE操作,您还可以在filepaths上封装引用计数器的递增和递减。然后,没有用户/登录需要访问表以进行写入活动,而只需使用存储过程。

<强> 2。触发器

可以在每个events表上创建一个触发器,以封装引用计数器递增和递减代码。每当修改表内容时,触发器都会触发并传播业务逻辑的后果。

许多人回避触发器,因为他们觉得它们被隐藏起来,如果过度使用会产生复杂的相互作用。但是,我认为它们非常有用。

在任何一种情况下,通过只有一个表而不是多个表来简化一切。

此外,大多数SQL设计模式不会将“删除表格”视为“常规业务”操作。在我看来,创建或删除表应该被视为设计更改,而不是数据活动。

答案 1 :(得分:1)

您不需要引用计数。 (你可以使用触发器实现它,如果你真的想要它) 你想要的是一个外键[约束]

清理文件路径表的最简单方法是使用NOT EXISTS结构,例如

DELETE FROM filepaths fp
WHERE NOT EXISTS ( SELECT * FROM events ev where ev.file_id = fp.file_id)
AND NOT EXISTS (SELECT * FROM events_version_xxx ev where ev.file_id = fp.file_id)
AND NOT EXISTS (SELECT * FROM events_version_yyy ev where ev.file_id = fp.file_id)
...
;

这太丑了。但数据库模型也很难看。