Pergunta

Estou pensando em usar PostgreSQL do Ltree módulo na minha aplicativo para ajudar com os comentários de rosca. Eu tenho eying-lo por um tempo para uso de comentários de rosca. Eu acho que ele iria ajudar com casos em que você precisa atualizar um nó e seus filhos, como quando você quer esconder um comentário e as suas respostas.

Estou pensando ltree (ou algo parecido) seria útil se ele foi acoplado com uma lista de adjacência tradicional ( "comment_id" / "parent_comment_id").

Antes de tomar a mergulhar usando ltree, eu estou querendo saber algumas coisas:

  1. É você, ou você tem, ltree usado? É o que se pode chamar de "produção pronta"?
  2. Se sim, quais os problemas que você usá-lo para resolver? Será que fazer um bom trabalho?
  3. Você acha que é um bom ajuste para uma sistema de comentários de rosca?
    1. Se você usou, o que você usou para a parte "texto" do caminho? Você quis criar algo como o exemplo DMOZ eles usam "Top.Astronomy.Cosmology" ou base-lo em algo como a chave primária "1.403.29.5"?
    2. Existe uma maneira melhor de fazer isso? Estou um pouco nervoso usando uma abordagem de lista aninhada - tudo que li sugere que não é toda a quente com atualizações ou inserções (não que você tem que reorganizar toda a coisa?). Eu também não sou um CS importante e que tipo de estrutura de dados é algo que eu poderia esquecer no futuro. Tem alguém usando listas aninhadas para comentários ou algo parecido?

Se for de alguma ajuda, aqui é o esquema que eu estou considerando:

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

A coluna "caminho", usado por ltree, seria algo parecido com:

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

Existe errado alguma coisa com o uso de chaves primárias no caminho? Eu deveria estar incluindo própria chave principal do nó no caminho? Se eu fiz, faria sentido colocar um índice exclusivo sobre ele para servir como uma restrição?

Foi útil?

Solução

  1. Sim e sim;
  2. Hierarquia das seções em uma base de conhecimento (uma das implementações);
  3. Sim;

A definição de uma das mesas em questão:

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

A coluna "caminho" usa a chave primária como um rótulo.

Uma amostra do conteúdo atual dessa tabela (sobre a chave primária e a coluna "caminho"):

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

Outras dicas

Eu recomendo ninguém a implementação relações hierárquicas no SQL ler árvores e hierarquias Joe Celko em SQL para smarties .

atravessando profundidade arbitrária ligações criança pais pode ser muito ineficiente quando se utiliza apenas um parent_id. O livro descreve técnicas que tornam este rápido acesso.

Uma estratégia (que acontece que eu uso) também podem ser encontrados gratuitamente nesta série de artigos:

A versão 8.4 do PostgreSQL estará trazendo funcionalidade Expressões de tabelas comuns para o núcleo com expressões WITH e WITH... RECURSIVE. Se você está modificando um código antigo, você pode querer esperar até 8.4 é liberado, como então você não terá que se preocupar com quaisquer incompatibilidades entre Ltree ea nova sintaxe núcleo. Se você está trabalhando com código antigo, ou não quiser esperar para 8,4, você provavelmente vai querer certificar-se de que você escrever código que é facilmente transponível para a nova sintaxe, especialmente se você está mudando um esquema de idade ou concepção de um novo um.

Veja também:

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top