2016-10-12 10 views
1

は、私は、データベース設計の問題は、次の2つのいずれかが、私は感謝の助けになる必要があります: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 

ユーザーが「ルートノード」の情報を編集すると、次のような構造になることがあります。既存のログの値を置き換えるのではなく、以前の値のログを残して、代わりに行の新しい「リビジョン」を作成する必要があるため、いつか遠くのユーザーが "元に戻す"ノードの以前の構成に戻します。

達成したいのは、ルートノードの新しいリビジョンがノードツリーの階層を変更すべきではないので、子ノードが子ノードのparent_nodeidを更新することなく、自動的に新しい親ノードを参照することです。

PostgreSQLは一意の値を持つ列を参照するために外部キーを必要とするため、Nodes.parent_nodeidからNodes.node_idに外部キーを追加できないことを理解していますが、少なくとも保証する種類の制約を追加する方法はありませんNodes.parent_nodeidは、既存のNodes.node_id値を参照しますが、一意ではありません。

どのようなヘルプやアイデアも高く評価されます。

答えて

1

常に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 
); 

あなたはundoを実装し、revisions代わりのdeleteからinsertまたはupdatedescriptionsコピーの行に、古い行を複製しnodesにトリガーを必要とします。

なぜ2つのノード識別子をnidnode_idのままにしておくべきか明確ではありませんか?これは冗長なようです。

+0

ありがとうございました!私は私の最初の質問にいくつかの詳細を残したかもしれないと思う: - ノード自体がツリーを記述する。このデザインの目的は、ドキュメントの典型的な複合リーフスタイルのGUIエディタのストレージモデルとして機能することです。 - バージョン管理する必要のある一般的なユーザー編集アクションの例は、「子ノードNを新しい親に移動する」、 ;私はその後、変更されたパラメータが親ノードidである子ノードの新しいリビジョンを作成したいが、子ノード自体には、変更後にそれが新しいリビジョンを参照する他の子を持つことができる – simonfi

+0

しかし、私はこれを正常化する方法について、私の問題を解決すると思うあなたのポイントを見ています。ありがとうございました! – simonfi

関連する問題