2011-08-11 19 views
6

Tengo dos modelos en mi aplicación, Transacción y Persona, con una relación muchos a muchos. Hay personas incluidas en cada transacción. Para cada persona, también hay una cantidad conectada a cada transacción a la que está conectada la persona. Por lo tanto, necesito modelar una relación de muchos a muchos con datos de relación. Google sugerir este enfoque:Modelado de muchos a muchos con datos de relaciones en Google App Engine

http://code.google.com/intl/sv-SE/appengine/articles/modeling.html

Con este enfoque Tengo un modelo como este:

class TransactionPerson(db.Model): 
    # References 
    transaction = db.ReferenceProperty(Transaction, required=True) 
    person = db.ReferenceProperty(Person, required=True) 
    # Values 
    amount = db.FloatProperty(required=True) 

Pero me parece muy malo para el rendimiento porque si tengo que resumir la cantidad para cada persona en todas las Transacciones, necesito hacer un ciclo de Person * Transaction * TransactionPerson veces para implementar el "join" mientras suman los montos.

mi idea

Mi idea es tener dos listas en el modelo de transacción:

class Transaction(db.Model): 
    persons = ListProperty(db.Key) 
    persons_amount = ListProperty(float) 

De esta manera no necesito para recorrer todos TransactionPerson para cada persona para encontrar el asociado Transacción. Y aún puedo consultar Transacciones basadas en una Persona.

PREGUNTAS

  1. Es esto posible? ¿Puedes confiar en que el orden de la lista es siempre el mismo cuando se almacena/recupera para que los índices se sincronicen entre las listas?
  2. ¿Es esta una buena manera de implementar una relación de varios a muchos con datos asociados?

Respuesta

2

Sospecho que estás resolviendo el problema incorrecto. La entidad de asociación intermedia es un buen enfoque. El problema que tiene es que los resúmenes tardan mucho tiempo en computarse; Deberías preocuparte más por eso;

El enfoque preferido es calcular los datos de resumen por adelantado.

En el caso específico de "Total de transacciones por persona", significaría que desea agregar un campo adicional al modelo Persona y actualizarlo con un total acumulado de todas sus transacciones. Debería actualizar esto cada vez que se modifique una TransactionPerson, de modo que el valor de resumen sea siempre correcto.

+0

¿Pero por qué es una entidad de asociación intermedia un buen enfoque cuando causará operaciones menos eficientes? Por ejemplo con su enfoque; si una transacción se actualiza, a menudo necesito actualizar todos los objetos de persona asociados con la transacción. No lo necesito si utilizo mi enfoque? ¿Cuáles son las razones por las cuales es mejor usar una entidad de asociación? – thejaz

+0

Cualquiera puede ser la mejor opción para lo que estás haciendo, pero mi respuesta se centra en la cuestión específica de calcular datos de resumen. Si tiene que cargar más de un puñado de entidades para satisfacer una solicitud en particular, probablemente necesite encontrar una manera de extraer ese proceso de la solicitud y crearlo de alguna otra manera, como cuando el valor cambiará. – SingleNegationElimination

+0

Los datos de resumen fueron solo un ejemplo. Con frecuencia deseo obtener todas las personas en una transacción que, en la práctica, da como resultado la misma persona * Transaction * TransactionPerson loops que _won't_ no serán aceptables para el rendimiento, incluso si lo hago más raro (cuando agrego o edito una TransactionPerson). Incluso si tuviera que guardar en caché esa información (una lista de personas) en la transacción, sería la misma que sugerí en mi pregunta, pero con la adición de tener los datos de la relación en una lista también. No daría lugar a datos duplicados. ¿Como lo harias? – thejaz

1

1. Sí, puede confiar en que se mantendrá el pedido. Desde el docs:

cuando las entidades son devueltos por las consultas y obtener(), las propiedades de la lista los valores están en el mismo orden que cuando se almacenaron. Hay una excepción a esto: los valores Blob y Text se mueven al final de la lista; sin embargo, conservan su orden original relativa entre sí.

2. Sí, propiedadeslista son tus amigos de relaciones-de normalización. Tiendo a duplicar mucho los datos, y uso propiedades de lista como 'caches' de datos des-normalizados de esta manera.

+0

Con respecto a (2), ¿qué quiere decir con la duplicación de datos? En mi caso, no es una duplicación, solo una forma de almacenar los datos de la relación? – thejaz

+0

Como en algunas ocasiones mantendré una configuración normalizada, 'A tiene muchas B' pero cada vez que guardo' B's', también guardo en memoria caché algunos de los datos importantes de las listas en 'A' para un procesamiento más rápido más adelante. –

Cuestiones relacionadas