PostgreSQL中非唯一的外键?

时间:2016-10-12 07:30:29

标签: postgresql foreign-keys foreign-key-relationship

我有一个数据库设计问题,以下两个中的任何一个都会对我有所帮助:

1)解释为什么我正在做的是一个糟糕的设计决策,以及如何更好地设计

2)示例如何在PostgreSQL中实际实现所需的设计

简而言之,我正在做的是设计一个树结构,其中每个节点都应该有这样的修订历史:

CREATE TABLE Nodes
(
  nid BIGSERIAL PRIMARY KEY,
  node_id BIGINT NOT NULL,
  parent_nodeid BIGINT,
  revision_id INTEGER NOT NULL,

  .. additional columns with info about this node ..
)

这个想法如下;我可能有这样的结构:

root node
    child node 1
    child node 2

当用户编辑“根节点”中的信息时;而不是仅仅替换现有日志中的值,我想保留以前值的日志,所以我改为创建行的新“修订版” - 因此用户将来某个时候可以执行“撤消”并返回到节点的先前配置。

我想要实现的是,子节点自动引用新的父节点而不必更新子节点parent_nodeid,因为根节点的新修订版不应更改节点树的层次结构。

我知道我无法将Nodes.parent_nodeid的外键添加到Nodes.node_id,因为PostgreSQL需要外键来引用具有唯一值的列 - 但我有点迷失在如何添加某种类型约束,至少保证Nodes.parent_nodeid引用现有的Nodes.node_id值,即使它不是唯一的。

任何帮助/想法都将受到高度赞赏!

1 个答案:

答案 0 :(得分:1)

您不需要树结构,因为您始终只有一个级别的依赖项。规范化数据库设计:

create table nodes (
    node_id bigserial primary key,
    description text
)

create table revisions (
    revision_id bigserial primary key,
    node_id bigint references nodes,
    description text
);

您需要nodes上的触发器,它会将旧行复制到descriptionsinsert上的update,并从revisions而不是{{1}复制一行实现delete

还不清楚为什么要保留两个节点标识符undonid?这似乎是多余的。