16

Lo siento si esta pregunta es demasiado simple; Solo estoy ingresando al noveno grado.¿Relaciones más eficaces de uno a muchos en el almacén de datos de Google App Engine?

Estoy tratando de aprender sobre el diseño de bases de datos NoSQL. Quiero diseñar un modelo de Google Datastore que minimice el número de lecturas/escrituras.

Aquí hay un ejemplo de juguete para una publicación de blog y comentarios en una relación de uno a varios. ¿Qué es más eficiente: almacenar todos los comentarios en una propiedad estructurada o usar KeyProperty en el modelo de comentarios?

Una vez más, el objetivo es minimizar el número de lecturas/escrituras en el almacén de datos. Puede hacer las siguientes suposiciones:

  • Los comentarios no se recuperarán independientemente de sus respectivas publicaciones de blog. (Sospecho que esto hace que el StructuredProperty más preferible.)
  • Comentarios tendrán que ser clasificables por fecha, clasificación, autor, etc. (subpropiedades en el almacén de datos no pueden ser indexados, así que quizás esto podría afectar al rendimiento?)
  • Tanto las publicaciones de blog como los comentarios se pueden editar (o incluso eliminar) una vez que se hayan creado.

Usando StructuredProperty:

from google.appengine.ext import ndb 

class Comment(ndb.Model): 
    various properties... 

class BlogPost(ndb.Model): 
    comments = ndb.StructuredProperty(Comment, repeated=True) 
    various other properties... 

Usando propiedadClave:

from google.appengine.ext import ndb 

class BlogPost(ndb.Model): 
    various properties... 

class Comment(ndb.Model): 
    blogPost = ndb.KeyProperty(kind=BlogPost) 
    various other properties... 

dude en plantear cualquier otras consideraciones que se refieren a la representación de forma eficaz una relación de uno a varios con respecto a la minimización el número de lecturas/escrituras en el almacén de datos.

Gracias.

+0

Considere cómo resolvería el problema del tamaño total de los comentarios y la publicación de blog que es mayor que 1MB. ¿Puede pasar alguna vez? Si pudiera y no tiene una buena solución para lidiar con eso, parecería desde el punto de vista de la funcionalidad pura que ni siquiera se molestaría con una sola entidad que contenga ambos. –

+0

Una alternativa podría ser simplemente almacenar todas las claves de los comentarios en la publicación del blog. Luego puede recuperar todos los comentarios con un solo ndb.get_multi (claves), pero permitiría un número significativamente mayor de comentarios, y si aún supera los 1MB, puede delegar la recuperación de los comentarios individualmente –

Respuesta

13

Podría estar equivocado, pero por lo que entiendo, una propiedad estructurada es solo una propiedad dentro de una entidad, pero con subpropiedades.

Esto significa leer un BlogPost y todos sus comentarios solo costarán una lectura. Entonces, cuando renderiza su página, solo necesita una operación de lectura para toda su página.

Las escrituras serían más baratas también. Necesitará una operación de lectura para obtener el BlogPost, y siempre que no actualice las propiedades indexadas, solo será una operación de escritura.

Puede manejar la clasificación de comentarios por su cuenta después de leer la entidad fuera del almacén de datos.

Deberá sincronizar las actualizaciones/ediciones de sus comentarios con las transacciones, para asegurarse de que un comentario no sobrescriba a otro, ya que ambos están modificando la misma entidad. Puede encontrarse con problemas indestructibles si todos comentan y editan la misma publicación de blog al mismo tiempo.

Sin embargo, al optimizar el costo, golpeará una pared con el tamaño de entidad máximo de 1MB. Esto limitará la cantidad de comentarios que puede almacenar por publicación de blog.

Ir con KeyProperty sería un poco más caro.

Necesitará una lectura para obtener la publicación del blog, más 1 consulta más 1 lectura pequeña para cada comentario.

Cada comentario es una entidad nueva, por lo que serán al menos 4 operaciones de escritura. Es posible que desee indexar para el orden de clasificación, por lo que terminará costando incluso más operaciones de escritura.

En el lado positivo, tendrá comentarios ilimitados por entrada de blog, no tiene que preocuparse por la sincronización de nuevos comentarios. Es posible que deba preocuparse por la sincronización para editar comentarios, pero si limita la edición al creador, eso no debería ser realmente un problema. Tampoco tienes que hacer una clasificación tú mismo.

Es un costo vs características tradeoff.

3

¿Qué hay de:

from google.appengine.ext import ndb 

class Comment(ndb.Model): 
    various properties... 

class BlogPost(ndb.Model): 
    comments = ndb.KeyProperty(Comment, repeated=True) 
    various other properties... 

De esta manera, se pueden almacenar hasta 5000 comentarios por entrada de blog (el número máximo de propiedades repetidas) independientes del tamaño de cada entrada del blog. No necesitará una consulta para buscar un comentario en los blogs, solo puede hacer ndb.get_multi(blog_post.comments). Y para esta operación, puede intentar confiar en la memcache de ndb. Por supuesto, depende de su caso de uso si esta es una buena suposición o no.

1

ser conscientes de esta advertencia cuando se utiliza un StructuredProperty repetida:

no utilice propiedades repetidas si usted tiene más de 100-1000 valores. (1000 probablemente ya lo esté presionando). No fueron diseñados para tal uso.

Ver la respuesta de Guido en GAE ndb design, performance and use of repeated properties.

Si bien es posible que no alcance el límite de entidad de 1 MB con StructuredProperty, puede alcanzar fácilmente el máximo 100-1000 sugerido.

+0

¿Cuál es la alternativa? Solo KeyProperty, como en la pregunta? ¿O hay un mejor camino? – Ajedi32

+0

Un KeyProperty podría funcionar si está por debajo del límite de valor 100-1000, pero si tiene más que eso, consideraría repensar su modelo de datos y las características necesarias. En el caso del ejemplo de blog, almacenar los comentarios como una sola propiedad JSON podría funcionar también. De esta forma, solo está actualizando/leyendo 1 entidad (BlogPost) y actualizando su propiedad JSON para los comentarios. Esto es similar a la solución StructuredProperty sin la limitación de 100-1000 valores. Por supuesto, si la entidad obtiene más de 1 MB, esto no funcionará (a menos que lo fragmente en varias entidades ...), pero esto podría funcionar para su caso de uso. –

Cuestiones relacionadas