Pregunta

Estoy considerando usar el módulo Ltree de PostgreSQL en mi aplicación para ayudar con comentarios enhebrados. Lo he estado mirando durante un tiempo para usarlo en comentarios enhebrados. Supongo que ayudaría con los casos en los que necesita actualizar un nodo y sus elementos secundarios, como cuando desea ocultar un comentario y sus respuestas.

Estoy pensando que ltree (o algo así) sería útil si se combinara con una lista de adyacencia tradicional (" comment_id " / " parent_comment_id ").

Antes de lanzarme a usar ltree, me pregunto algunas cosas:

  1. ¿Estás o has usado ltree? ¿Es lo que se podría llamar "producción lista"?
  2. Si es así, ¿qué problemas lo usó para resolver? ¿Hizo un buen trabajo?
  3. ¿Crees que es una buena opción para un sistema de comentarios roscados?
    1. Si lo usó, ¿qué utilizó para el " texto " parte del camino? ¿Configuraste algo como el ejemplo de DMOZ que usan " Top.Astronomy.Cosmology " o basarlo en algo como la clave primaria " 1.403.29.5 " ;?
    2. ¿Hay una mejor manera de hacer esto? Estoy un poco nervioso usando un enfoque de lista anidada: todo lo que he leído sugiere que no todo está de moda con ACTUALIZACIONES o INSERTOS (¿no tiene que reordenar todo?). Tampoco soy un experto en CS y ese tipo de estructura de datos es algo que podría olvidar en el futuro. ¿Alguien está usando listas anidadas para comentarios o algo así?

Si es de alguna ayuda, aquí está el esquema que estoy 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
);

La " ruta " La columna, utilizada por ltree, se vería así:

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

¿Hay algún problema con el uso de las claves primarias en la ruta? ¿Debería incluir la clave principal propia del nodo en la ruta? Si lo hiciera, ¿tendría sentido poner un índice único para que sirva como restricción?

¿Fue útil?

Solución

  1. Sí y sí;
  2. Jerarquía de secciones en una base de conocimiento (una de las implementaciones);
  3. Sí;

La definición de una de las tablas en cuestión:

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

La " ruta " La columna utiliza la clave principal como etiqueta.

Una muestra del contenido actual de esa tabla (con respecto a la clave primaria y la columna "ruta"):

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

Otros consejos

Recomiendo a cualquiera que implemente relaciones jerárquicas en SQL leer Árboles y jerarquías de Joe Celko en SQL para Smarties .

Recorrer enlaces primarios secundarios de profundidad arbitraria puede ser muy ineficiente cuando se usa solo un parent_id. El libro describe técnicas que hacen que este acceso sea rápido.

Una estrategia (que uso) también se puede encontrar de forma gratuita en esta serie de artículos:

La versión 8.4 de PostgreSQL traerá la funcionalidad de expresiones de tabla comunes al núcleo con las expresiones WITH y WITH ... RECURSIVE . Si está modificando el código antiguo, es posible que desee esperar hasta que se publique 8.4, ya que no tendrá que preocuparse por las incompatibilidades entre Ltree y la nueva sintaxis central. Si está trabajando con código antiguo, o no quiere esperar a 8.4, probablemente querrá asegurarse de escribir código que sea fácilmente traducible a la nueva sintaxis, especialmente si está cambiando un esquema antiguo o diseñando uno nuevo uno.

Ver también:

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top