Domanda

Sto pensando di utilizzare il modulo Ltree di PostgreSQL nel mio applicazione per aiutare con i commenti thread. Lo sto osservando da un po 'da usare per i commenti thread. Immagino che sarebbe di aiuto nei casi in cui è necessario aggiornare un nodo e i suoi figli, come quando si desidera nascondere un commento e le sue risposte.

Sto pensando che ltree (o qualcosa del genere) sarebbe utile se fosse abbinato a un elenco di adiacenza tradizionale (" comment_id " / " parent_comment_id ").

Prima di immergermi nell'uso di ltree, mi chiedo alcune cose:

  1. Usi o hai usato ltree? È ciò che si potrebbe chiamare "pronto per la produzione"?
  2. In tal caso, quali problemi hai usato per risolverlo? Ha fatto un buon lavoro?
  3. Pensi che sia adatto per a sistema di commenti filettati?
    1. Se l'hai usato, cosa hai usato per il "testo"? parte del percorso? Hai impostato qualcosa come l'esempio DMOZ che usano " Top.Astronomy.Cosmology " oppure basalo su qualcosa come la chiave primaria "1.403.29.5"?
    2. C'è un modo migliore per farlo? Sono un po 'nervoso usando un approccio elenco annidato - tutto ciò che ho letto suggerisce che non è tutto caldo con AGGIORNAMENTI o INSERTI (non è necessario riordinare il tutto?). Inoltre non sono un CS maggiore e quel tipo di struttura di dati è qualcosa che potrei dimenticare in futuro. Qualcuno sta usando liste nidificate per commenti o qualcosa del genere?

Se è di qualche aiuto, ecco lo schema che sto prendendo in considerazione:

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

Il percorso " " La colonna, usata da ltree, assomiglierebbe a:

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

C'è qualcosa di sbagliato nell'usare le chiavi primarie nel percorso? Dovrei includere la chiave primaria del nodo nel percorso? Se lo facessi, avrebbe senso mettere un indice univoco su di esso per fungere da vincolo?

È stato utile?

Soluzione

  1. Sì e sì;
  2. Gerarchia di sezioni in una knowledge base (una delle implementazioni);
  3. Sì;

La definizione di una delle tabelle in questione:

                                                   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')

Il percorso " " colonna utilizza la chiave primaria come etichetta.

Un esempio del contenuto corrente di quella tabella (per quanto riguarda la chiave primaria e la colonna "percorso"):

  section_sid | path
 -------------+-------
           53 | 34.53
           56 | 56
           55 | 29.55
           35 | 35
           54 | 34.54
           37 | 30.37
          ... | ...

Altri suggerimenti

Consiglio a tutti coloro che implementano relazioni gerarchiche in SQL di leggere Alberi e gerarchie di Joe Celko in SQL per smarties .

Il passaggio di collegamenti figlio parent di profondità arbitraria può essere molto inefficiente quando si utilizza solo parent_id. Il libro descrive le tecniche che rendono rapido questo accesso.

Una strategia (che mi capita di usare) può anche essere trovata gratuitamente in questa serie di articoli:

La versione 8.4 di PostgreSQL introdurrà la funzionalità Common Table Expressions nel core con le espressioni WITH e WITH ... RECURSIVE . Se stai modificando il vecchio codice, potresti voler aspettare fino al rilascio dell'8.4, in quanto non dovrai preoccuparti di incompatibilità tra Ltree e la nuova sintassi principale. Se stai lavorando con un vecchio codice o non vuoi aspettare la 8.4, probabilmente vorrai assicurarti di scrivere un codice che sia facilmente traducibile nella nuova sintassi, specialmente se stai modificando un vecchio schema o progettando un nuovo uno.

Vedi anche:

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top