10

スレッド化されたコメントを支援するために、アプリケーションでPostgreSQL のLtree モジュールを使用することを検討しています。スレッド化されたコメントに使用するためにしばらく注目していました。コメントとその返信を非表示にする場合など、ノードとその子を更新する必要がある場合に役立つと思います。

ltree (またはそれに似たもの) を従来の隣接リスト ("comment_id"/"parent_comment_id") と組み合わせると便利だと思います。

ltree の使用に飛び込む前に、いくつか疑問に思っていることがあります。

  1. ltree を使用していますか、または使用したことがありますか? それは「生産準備完了」と呼ばれるものですか?
  2. もしそうなら、それを使ってどのような問題を解決しましたか? うまくいきましたか?
  3. スレッド化されたコメント システムに適していると思いますか?
    1. 使用した場合、パスの「テキスト」部分には何を使用しましたか? 「Top.Astronomy.Cosmology」を使用する DMOZ の例のようなものを設定しましたか、それとも主キー「1.403.29.5」のようなものに基づいていますか?
    2. これを行うより良い方法はありますか?ネストされたリストのアプローチを使用するのは少し緊張しています-私が読んだすべてのことは、UPDATESまたはINSERTSですべてがホットではないことを示唆しています(すべてを並べ替える必要はありませんか?)。私も CS 専攻ではありません。そのようなデータ構造は、将来忘れてしまうかもしれません。ネストされたリストをコメントなどに使用している人はいますか?

参考になれば、私が検討しているスキーマは次のとおりです。

CREATE TABLE comments (
    comment_id SERIAL PRIMARY KEY,
    parent_comment_id int REFERENCES comments(comment_id) ON UPDATE CASCADE ON DELETE CASCADE,
    thread_id int NOT NULL  REFERENCES threads(thread_id) ON UPDATE CASCADE ON DELETE CASCADE,
    path ltree NOT NULL,
    comment_body text NOT NULL,
    hide boolean not null default false
);

ltree で使用される「パス」列は、次のようになります。

<thread_id>.<parent_comment_id_#1>.<parent_comment_id_#2>.<my_comment_id>

パスで主キーを使用することに問題はありますか? ノード自身の主キーをパスに含める必要がありますか? もしそうなら、制約として機能する一意のインデックスを配置することは理にかなっていますか?

4

3 に答える 3

6
  1. はい、はい。
  2. ナレッジ ベースのセクションの階層 (実装の 1 つ)。
  3. はい;

問題のテーブルの 1 つの定義:

                                                   Table "knowledgebase.section"
           Column           |           Type           |                                  Modifiers
----------------------------+--------------------------+-----------------------------------------------------------------------------
 section_sid                | integer                  | not null default nextval('knowledgebase.section_section_sid_seq'::regclass)
 section                    | character varying        | not null
 description                | character varying        |
 path                       | ltree                    | not null
 is_active                  | boolean                  | not null default true
 role_sid                   | integer                  | not null
 last_modified_by           | integer                  | not null
 creation_datetime          | timestamp with time zone | not null default now()
 last_modification_datetime | timestamp with time zone | not null default now()
 is_expanded                | boolean                  | not null default false
 section_idx                | tsvector                 |
Indexes:
    "section_sid_pkey" PRIMARY KEY, btree (section_sid)
    "section_section_key" UNIQUE, btree (section)
    "idxsection_idx" gist (section_idx)
    "path_gist_idx" gist (path)
Foreign-key constraints:
    "last_modified_by_fkey" FOREIGN KEY (last_modified_by) REFERENCES "user"."role"(role_sid) ON UPDATE CASCADE ON DELETE RESTRICT
    "role_sid_fkey" FOREIGN KEY (role_sid) REFERENCES "user"."role"(role_sid) ON  UPDATE CASCADE ON DELETE RESTRICT
Triggers:
    section_idx_update BEFORE INSERT OR UPDATE ON knowledgebase.section FOR EACH ROW EXECUTE PROCEDURE tsearch2('section_idx', 'section')

「パス」列は、主キーをラベルとして使用します。

そのテーブルの現在の内容のサンプル (主キーと「パス」列に関して):

  section_sid | path
 -------------+-------
           53 | 34.53
           56 | 56
           55 | 29.55
           35 | 35
           54 | 34.54
           37 | 30.37
          ... | ...
于 2009-03-03T17:39:31.260 に答える
4

SQL で階層関係を実装する人には、Joe Celko の Trees and Hierarchies in SQL for Smarties を読むことをお勧めします。

任意の深さの親子リンクをトラバースすることは、parent_id だけを使用すると非常に非効率になる可能性があります。この本では、このアクセスを高速化するテクニックについて説明しています。

この一連の記事では、1 つの戦略 (私がたまたま使用しています) も無料で見つけることができます。

于 2009-03-03T23:53:07.803 に答える
2

バージョン 8.4 の PostgreSQL では、式WITHと式を使用して共通テーブル式機能がコアに組み込まれWITH... RECURSIVEます。古いコードを変更している場合は、8.4 がリリースされるまで待つことをお勧めします。8.4 がリリースされると、Ltree と新しいコア構文の間の非互換性について心配する必要がなくなります。古いコードを使用している場合、または 8.4 を待ちたくない場合、特に古いスキーマを変更したり新しいスキーマを設計したりする場合は、新しい構文に簡単に変換できるコードを作成する必要があります。 1。

以下も参照してください。

于 2009-03-03T04:40:32.007 に答える