2009-07-11 30 views
24

Viniendo de un mundo Relacional, las cosas son obviamente muy diferentes con el almacenamiento de Azure Table. La primera gran cosa con la que me he encontrado es cómo almacenar correctamente las relaciones de muchos a muchos.¿Cómo guardo correctamente las relaciones de datos con Microsoft Azure Table Storage?

Por ejemplo, puedo tener un sistema que realiza un seguimiento de los usuarios y libros que poseen. Encontré otra publicación aquí en SO que sugería tener una propiedad de cadena en el usuario que básicamente almacenaba una lista de las identificaciones de libros que poseía el usuario. Si bien entiendo que a veces esta es una forma aceptada de almacenar datos, el problema es que Azure solo le permite almacenar 64 KB de datos en una Cadena. Eso definitivamente pone un límite a la cantidad de libros que un usuario podría poseer.

Otra posible solución es tener datos duplicados. Es posible que tenga una tabla que almacena todos los libros conocidos en el sistema. Pero cuando un usuario necesita estar asociado con un libro, copio los datos del libro en una tabla diferente llamada OwnedBooks que, en esencia, es exactamente igual a la tabla de libros, excepto que también tiene una propiedad OwnedByUserID.

¿Hay otras posibles soluciones?

Además de este problema, ¿alguien tiene alguna sugerencia buena para otros patrones y prácticas al utilizar el almacenamiento de tablas Azure?

Respuesta

16

Hay una serie de soluciones a este - todas con inconvenientes, por supuesto :-)

  1. Utilizar una tabla de asignación simple como lo haría en un RDBMS. Cada fila contendría una tecla Libro y una tecla Usuario.

    Luego, para buscar todos los Libros para un usuario, debe seleccionar las teclas del Libro en la tabla de asignación, y luego para cada una de esas teclas, seleccionar la entidad Libro de la tabla Libros. Podrías hacer las recuperaciones de libros en paralelo usando la recuperación asíncrona, pero aun así, esta solución obviamente no escala.

  2. Utilice una tabla de asignación como la anterior, pero incluya también todos los datos del Libro que necesite en la tabla de asignación. Esta es la solución denormalizada o de "datos duplicados" que ya ha propuesto con su tabla de OwnedBooks.

    El principal inconveniente de este método es que si necesita actualizar alguno de los datos del Libro, estará potencialmente actualizando muchas entidades, y como viven en una tabla separada del Libro en sí, no podrá para completar en una sola transacción/lote (y me imagino que usaría la identidad del Usuario como la clave de la Partición en la tabla de asignación de todos modos, que ya impide una actualización por lotes única en esa tabla).

  3. Almacene las claves del Libro unidas en una sola propiedad del Usuario. De nuevo, ya sugirió este método.

    Esto en realidad no sería tan malo si no fuera por el hecho de que Azure no admite actualmente consultas de tipo "contiene", es decir, no se puede buscar en una subcadena, por lo que si alguna vez descubrir qué Usuarios poseían un Libro en particular, esto sería imposible.Curiosamente, Google App Engine admite esto de forma bastante transparente en su sistema de almacenamiento, e indexará la lista también para usted. En cualquier caso, igual tendrá que recuperar los datos de cada libro con este método también.

  4. Utilice la naturaleza "sin esquema" del almacenamiento de tablas Azure para almacenar claves de libro asociadas como propiedades individuales. Por ejemplo, una entidad de usuario puede tener este aspecto:

    { Name: "User1", Book_4325: true, Book_5123: true }

    mientras que otro puede tener este aspecto:

    { Name: "User2", Book_5346: true, Book_8753: true, Book_6135: true }

    Entonces Y si lo desea encontrar todos los usuarios que poseen un determinado libro se puede seleccionar dónde esa propiedad en particular es verdadera (bueno, solo necesita existir realmente).

    Los inconvenientes obvios de esto son que es un poco frágil, necesita tocar las teclas en los nombres de las propiedades, y no podría usar los métodos estándar de StorageClient para esto - tendría que rodar su propio. Además, Azure solo admite 255 propiedades en una entidad. Dicho todo esto, creo que se escalaría bastante bien, aunque nunca lo intenté.

Fuera de todas estas opciones, yo diría que el que se va a ir con la opción 2 sería la mejor, sólo por el hecho de que está soportado actualmente por Azure y normalmente se puede lograr todo con menos consultas

Solo necesita examinar sus Casos de uso para decidir cómo y cuándo se actualizarían los datos, teniendo en cuenta que las transacciones atómicas están fuera de la ventana. Casi puedo garantizarle que podrá vivir con cosas "eventualmente consistentes" y solo dar cuenta del hecho de que su tabla de mapeo puede no estar siempre 100% actualizada.

Si se vuelve demasiado caro actualizar los datos en la tabla de asignación al mismo tiempo que la tabla principal, puede colocar un mensaje en una cola y obtener un rol de trabajador para realizar las actualizaciones de forma asincrónica.

+0

¡Respuesta fantástica, gracias! – Vyrotek

+0

La opción de la opción 2, parece que sería bastante barata a pesar de su inconveniente. Como solo costó $ 0.01 por cada 100 000 transacciones. Cada transacción es una consulta al almacenamiento ¿no? Así que cambiar el título de un libro solo incurriría en una consulta, y luego cada entidad encontrada se actualizará en la tabla. Pero depende de la cantidad de datos que está actualizando. Pero si las actualizaciones son escasas, entonces está bien. ¿No es así? – starcorn

9

No es así. Aquí hay un buen y comprensivo white paper (enlace .docx) en Azure Table que tiene una sección sobre mejores prácticas. Sin embargo, debe usar Table para bolsa de propiedades no relacionales o diseño de tipo ORM. Si desea relacional en la nube, debe usar SQL Azure Database.

Aquí hay otro good article en el esquema de almacenamiento libre en comparación con relacional. Es para un different schema free cloud storage offering, pero los conceptos son los mismos.

+3

No necesariamente quiero 'real' en la nube. Estaba buscando aprender cómo las personas usarían estas bases de datos de keystore/bag con el simple ejemplo que proporcioné. No puedo imaginar que cualquier proyecto que requiera relaciones entre datos no pueda/no se deba usar con esta o bases de datos similares. – Vyrotek

+2

+1 para el documento técnico de Azure Table. Un poco fuera de tema, pero realicé una búsqueda rápida en Internet después de leer esta respuesta y encontré esta url en todos los documentos técnicos relacionados con Azure, que podría resultar muy útil en diferentes contextos: http://www.microsoft.com/ windowsazure/whitepapers/ –

Cuestiones relacionadas