PostgreSQLのLtreeモジュールは、スレッド化されたコメントに適していますか?
-
03-07-2019 - |
質問
PostgreSQLの Ltreeモジュールを使用することを検討していますスレッド化されたコメントを支援するアプリケーション。スレッド化されたコメントに使用するために、私はしばらくそれを探していました。コメントとその返信を非表示にする場合など、ノードとその子を更新する必要がある場合に役立つと思います。
ltree(またはそれに似たもの)は、従来の隣接リスト(" comment_id" /" parent_comment_id")と組み合わせると便利だと考えています。
ltreeを使用する前に、いくつかのことを考えています:
- ltreeを使用していますか? 「生産準備完了」と呼ばれるものですか?
- もしそうなら、あなたはそれを解決するためにどのような問題を使いましたか?良い仕事をしましたか?
- それはに適していると思いますか
スレッドコメントシステム?
- 使用した場合、「テキスト」に何を使用しましたかパスの一部? 「Top.Astronomy.Cosmology」を使用するDMOZの例のようなものを設定しましたか?または、主キー" 1.403.29.5"のようなものに基づいていますか?
- これを行うより良い方法はありますか?ネストされたリストのアプローチを使用すると、少し緊張します。これまで読んだすべてのことから、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>
パスで主キーを使用するのに問題はありますか?ノードの独自のプライマリキーをパスに含める必要がありますか?もしそうなら、制約として機能する一意のインデックスを置くことは理にかなっていますか?
解決
- はい、はい;
- 知識ベースのセクションの階層(実装の1つ);
- はい;
問題のテーブルの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')
&quot;パス&quot;列は主キーをラベルとして使用します。
そのテーブルの現在の内容のサンプル(主キーと「パス」列に関する):
section_sid | path
-------------+-------
53 | 34.53
56 | 56
55 | 29.55
35 | 35
54 | 34.54
37 | 30.37
... | ...
他のヒント
SQLで階層関係を実装している人には、 Joe Celko's Trees and Hierarchies in SQL for readスマーティーズ。
parent_idのみを使用する場合、任意の深さの親子リンクを走査することは非常に非効率的です。この本では、このアクセスを高速化する手法について説明しています。
このシリーズの記事では、1つの戦略(たまたま使用しています)も無料で見つけることができます。
PostgreSQLのバージョン8.4では、 WITH
および WITH ... RECURSIVE
式を使用して、共通テーブル式機能をコアに導入します。古いコードを変更する場合は、8.4がリリースされるまで待つことをお勧めします。Ltreeと新しいコア構文の非互換性について心配する必要はありません。古いコードで作業している場合、または8.4を待ちたくない場合は、特に古いスキーマを変更したり新しいスキーマを設計する場合は特に、新しい構文に簡単に変換できるコードを作成する必要があります。 1つ。
参照: