PostgreSQL 中的非唯一外键?

Non-unique foreign key in PostgreSQL?

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

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

当用户编辑"root node"中的信息时;我不想仅仅替换现有日志中的值,而是想保留以前值的日志,因此我创建了一个新的 "revision" 行 - 这样用户在将来的某个时候可以执行 "undo"和return到节点之前的配置。

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

我知道我不能添加从 Nodes.parent_nodeidNodes.node_id 的外键,因为 PostgreSQL 需要外键来引用具有唯一值的列 - 但我有点不知道如何添加某种约束至少保证 Nodes.parent_nodeid 引用现有的 Nodes.node_id 值,即使它不是唯一的。

任何 help/ideas 将不胜感激!

你不需要树结构,因为你总是只有一层依赖。规范化数据库设计:

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 上的触发器,它将旧行复制到 insertupdate 上的 descriptions,并从 revisions 复制一行而不是 delete,实施 undo.

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