Respuesta

21

La mejor opción depende de sus requisitos. He aquí algunas soluciones (estoy asumiendo que usted está utilizando Python, ya que no se ha especificado):

  1. Si necesita hacer cambios transaccionales en un árbol completo, y no vamos a tener más que aproximadamente 1QPS de actualizaciones sostenidas a cualquier árbol, puede usar el soporte integrado para almacenamiento jerárquico. Al crear una entidad, puede pasar el atributo "principal" para especificar una entidad o clave principal, y al consultar, puede usar el método .ancestor() (o 'ANCESTOR IS' en GQL para recuperar todos los descendientes de una entidad dada
  2. Si no necesita actualizaciones transaccionales, puede replicar la funcionalidad de grupos de entidades sin los problemas de contención (y seguridad de la transacción): Agregue un db.ListProperty (db.Key) a su modelo llamado 'ancestros', y rellene con la lista de ancestros del objeto que está insertando. A continuación, puede recuperar fácilmente todo lo que desciende de un ancestro determinado con MyModel.all(). filter ('ancestros =', parent_key).
  3. Si lo usa No necesita transacciones, y solo le interesa recuperar los hijos directos de una entidad (no todos los descendientes), utilice el enfoque descrito anteriormente, pero en lugar de un ListProperty ju st usa una propiedad de referencia para la entidad principal. Esto se conoce como Lista de adyacencia.

Existen otros enfoques disponibles, pero esos tres deberían cubrir los casos más comunes.

+0

Point (2) responde a mi consulta! Gracias. – MathOldTimer

+2

Parece que (2) y (1) hacen lo mismo, pero eso (1) sería mucho más económico. Me sorprende que una lista de claves sea bastante costosa en términos de costos de almacenamiento, lo que empeoraría a medida que el árbol se hiciera más profundo. Además, ¿(1) no conduciría a una buena localidad? –

+3

El soporte ancestro incorporado utiliza la misma técnica que 2 - almacena una lista de antepasados ​​internamente. La ventaja de 2 es que no tiene la limitación de velocidad de transacción. La localidad no es un problema. –

2

Bueno, intente mantener sus datos lo más lineales posible. Si necesita consultar rápidamente una estructura de árbol de datos, tendrá que almacenarla encuadrada en la base de datos (o codificada en JSON si lo prefiere) si eso es posible para sus datos, o tendría que generar índices de árbol que puedan ser utilizado para consultar rápidamente una pieza de una estructura de árbol. Sin embargo, no estoy seguro de cómo Google App Engine funcionaría al actualizar esos índices.

Cuando se trata de Google App Engine, su principal preocupación debe ser reducir el número de consultas que necesita realizar, y que sus consultas regresen lo menos posible. Las operaciones son costosas, pero el almacenamiento no lo es, por lo que la redundancia no debe verse como algo malo.

Estas son algunas reflexiones sobre el tema encontré por google (aunque para MySQL, pero se puede obtener la idea general de él): Managing Hierarchical Data in MySQL

Ah y aquí es una discusión para Google App Engine: Modeling Hierarchical Data

0

Una forma es usar el atributo principal del Modelo. Luego puede hacer uso de las funciones query.ancestor() y model.parent().

Supongo que depende del tipo de operaciones que desee hacer con estos datos, lo que determinaría la mejor manera de representarlo.

+2

No es una buena idea. Los grupos de entidades solo deben usarse cuando sea necesario para las transacciones. De la documentación: "Utilice únicamente grupos de entidades cuando sean necesarios para las transacciones. Para otras relaciones entre entidades, use propiedades de Propiedades de referencia y valores de clave, que se pueden usar en las consultas". – Blixt

+0

Recuerde también: el padre de una entidad no puede ser cambiado, ¡pero un ReferenceProperty sí puede! – Trevor