2009-03-02 12 views
8

Estoy considerando utilizar Ltree module de PostgreSQL en mi aplicación para ayudar con los comentarios enhebrados. Lo he estado buscando por un tiempo para usarlo para comentarios enhebrados. Me imagino que ayudaría con los casos en los que necesita actualizar un nodo y sus hijos, como cuando quiere ocultar un comentario y sus respuestas.¿El módulo Ltree de PostgreSQL es adecuado para los comentarios de subprocesos?

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

Antes de dar el paso en el uso de ltree, me pregunto algunas cosas:

  1. está usted, o ha, ltree utilizados? ¿Es lo que uno podría llamar "producción lista"?
  2. Si es así, ¿qué problemas usó para resolverlo? Hizo un buen trabajo?
  3. ¿Cree que es una buena opción para un sistema de comentarios roscados ?
    1. Si lo usaste, ¿qué usaste para la parte de "texto" de la ruta? ¿Configuraron algo así como el ejemplo de DMOZ que usan "Top.Astronomy.osmology" o lo basan en algo así como la clave principal "1.403.29.5"?
    2. ¿Hay una manera mejor de hacer esto? Estoy un poco nervioso usando un enfoque de lista anidada: todo lo que he leído sugiere que no todo está demasiado caliente con ACTUALIZACIONES o INSERTOS (¿no tienes que volver a ordenar todo?). Tampoco soy especialista 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 se trata de alguna ayuda, aquí es 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 columna "camino", utilizado por ltree, sería algo como:

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

¿Hay algún problema con el uso de las teclas principales 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 en él para que sirva como una restricción?

+0

ltree es una implementación de 'ruta materializada'. vea http://www.dbazine.com/oracle/or-articles/tropashko4 para una comparación de soluciones posibles, incluyendo métodos más portátiles (pero menos eficientes) como conjuntos anidados. – vladr

+0

no dude en agregar esto como una respuesta. estoy abierto a otras ideas He analizado conjuntos anidados, pero parecen ser un fastidio para implementar y más lentos en las actualizaciones/inserciones (¿no tienes que cambiar todo?). –

+0

oh, y estaba pensando en usar lree además de la lista de adyacencia. de ahí "comment_id" y "parent_comment_id". lo que tenía en mente era usar ltree para acelerar operaciones en una rama –

Respuesta

6
  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 mesas 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 columna "camino" utiliza la clave principal como una etiqueta.

Una muestra de los contenidos actuales de la mesa (con respecto a la clave principal y la columna de la "ruta"):

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

¿cómo se ve la ruta como una cadena? ¿Estás usando texto o números? –

+0

¿Cómo hace que las rutas incluyan su propia identificación, ya que se calcula cuando se inserta? ¿Utiliza un disparador, un 'ACTUALIZACIÓN' o algo más? – Un3qual

2

La versión 8.4 de PostgreSQL traerá la funcionalidad de Common Table Expressions al núcleo con las expresiones WITH y WITH... RECURSIVE. Si está modificando el código anterior, puede esperar hasta que se libere 8.4, ya que entonces no tendrá que preocuparse por ninguna incompatibilidad entre Ltree y la nueva sintaxis del núcleo. Si está trabajando con un código anterior, o no quiere esperar 8.4, probablemente querrá asegurarse de escribir código que se pueda traducir fácilmente a la nueva sintaxis, especialmente si está cambiando un esquema anterior o está diseñando un nuevo uno.

Consulte también:

+0

que es muy, muy bueno.Que CON cosas parece que será útil para más que solo comentarios. Encontrar etiquetas y sus etiquetas relacionadas parece ser otro buen candidato, ya que está realizando algunas autocombinaciones. –

4

Lo recomendaría a cualquiera implementar relaciones jerárquicas en SQL leer Joe Celko's Trees and Hierarchies in SQL for Smarties.

Atravesar enlaces 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 se me ocurre usar) también se pueden encontrar de forma gratuita en esta serie de artículos:

Cuestiones relacionadas