2011-05-03 14 views
5

¡Soy un novato total con Azure! El objetivo es devolver las filas según la marca de tiempo almacenada en RowKey. Ya que hay un costo de transacción con cada consulta, quiero minimizar el número de transacciones/consultas, mientras que mantener el rendimientoAzure Table Storage - Selección de PartitionKey y RowKey para usar entre la consulta

Estos son los Partición propuesto y teclas de la fila:

  • clave de reparto TextCache_ (AccountID) _ (ParentMessageId)
  • fila de teclas: (DateOfMessage) _ (MessageId)

Leyenda:

  • AccountId - es un entero
  • ParentMessageId - El messageId padre si es que existe, en blanco si es el padre
  • DateOfMessage - Fecha en que se creó el mensaje - formato será DateTime.Ticks. ToString ("D19")
  • MessageId - el ID único del mensaje

me gustaría volver de una sola consulta las filas y las childrows que es> o < DateOfMessage_MessageId

¿Se puede hacer esto a través de mis PartitionKeys y RowKeys propuestos?

es decir .. (en pseudo código)

var results = ctx.PartitionKey.StartsWith(TextCache_AccountId) 
    && ctx.RowKey > (TimeStamp)_MessageId 

En segundo lugar, si no tengo un número de cuentas, y sólo quiere volver detrás de los primeros 10, que podría hacerse a través de una única consulta

es decir .. (en pseudo código)

var results = ( 
     ( 
     ctx.PartitionKey.StartsWith(TextCache_(AccountId1)) && 
      && ctx.RowKey > (TimeStamp1)_MessageId1) 
    ) 
     || 
     ( 
     ctx.PartitionKey.StartsWith(TextCache_(AccountId2)) && 
      && ctx.RowKey > (TimeStamp2)_MessageId2) 
    ) ... 
     ) 
     .Take(10) 

Respuesta

5

La respuesta corta a sus preguntas es sí, pero hay algunas cosas que hay que tener en cuenta.

El almacenamiento de tablas Azure no tiene un equivalente directo de .StartsWith(). Si está utilizando la biblioteca de almacenamiento en combinación con LINQ puede usar .CompareTo() (> y < no traducir correctamente) lo que significa que si ejecuta una búsqueda de la cuenta 1 y solicita a la consulta que devuelva 1000 resultados, pero hay son solo 600 resultados para la cuenta 1, los últimos 400 resultados serán para la cuenta 10 (el siguiente número de cuenta léxicamente). Por lo tanto, deberá ser un poco inteligente acerca de cómo maneja sus resultados.

Si acolchada a cabo la identificación de la cuenta con 0s principales que podría hacer algo como esto (pseudo código aquí también)

ctx.PartionKey > "TextCache_0000000001" 
&& ctx.PartitionKey < "TextCache_0000000002" 
&& ctx.RowKey > "123465798" 

Otra cosa a tener en cuenta es que las consultas a las tablas de Azure devuelven sus resultados en PartitionKey luego RowKey orden. Por lo tanto, en su caso, los mensajes sin ParentMessageId se devolverán antes de los mensajes con ParentMessageId. Si nunca va a consultar esta tabla por ParentMessageId, movería esto a una propiedad.

Si TextCache_ es solo una constante de cadena, no agrega nada al incluirse en PartitionKey a menos que esto realmente signifique algo para su código cuando se devuelve.

Mientras se ejecuta la segunda consulta, no creo que produzca lo que está buscando. Si desea las primeras diez filas en el orden DateOfMessage, entonces no funcionará (consulte mi punto anterior sobre las órdenes de clasificación). Si ejecutó esta consulta tal como está y la cuenta 1 tuvo 11 mensajes, solo devolverá los primeros 10 mensajes relacionados con la cuenta 1 independientemente de si la cuenta 2 tenía un mensaje anterior.

Al intentar minimizar el número de transacciones que utiliza es una buena práctica, no se preocupe demasiado por ello. El costo de ejecutar sus roles de trabajador/web eclipsará los costos de transacción. 1,000,000 de transacciones le costará $ 1, que es menos que el costo de ejecutar una pequeña instancia durante 9 horas.

+0

Gracias a knightpfhor, estaba más preocupado por golpear las 500 trans/seg en el almacenamiento de la mesa, lo que daría como resultado el estrangulamiento. No pensé en el relleno de AccountId, que definitivamente será necesario. Hará algunas pruebas –

+0

Vale la pena señalar que el límite del acelerador es por partición, no global (aunque el límite global es de varios miles de trans/seg – knightpfhor

+0

En cuanto al 'TextCache_', lo agregué como identificador de tabla. Si tuviera entidades múltiples, ¿cómo lo haría? Los diferencio? –

Cuestiones relacionadas