2012-10-12 86 views
8

Actualmente estoy usando la PartitionKey para diferenciar los dispositivos que almacenan datos en Azure Table Services. Me gustaría construir un visor que me permita navegar por esos datos, pero sería bueno poder estructurarlo para poder ver los datos "por dispositivo" o por PartitionKey. La aplicación del visor no tendrá ningún conocimiento de qué dispositivos existen, por lo que sería genial si pudiera volver a obtener una lista de PartionKeys distintas en una tabla determinada. ¿Es esto posible, o voy a ser relegado a la creación de una tabla de metadatos en la que inserte una nueva fila para cada dispositivo, luego la uso para consultar?¿Hay alguna manera de obtener PartionKeys distintas de una Tabla

Respuesta

6

No creo que haya una forma de recuperar todas las claves de partición. He aquí una solución inteligente, sin embargo: http://blogs.msdn.com/b/avkashchauhan/archive/2011/10/23/retrieving-partition-key-range-in-windows-azure-table-storage.aspx

Para citar el blog de Avkash:

de excavación más, me pareció que no está construido en API para obtener una lista de claves de partición, en lugar tendría que crear una solución para mi Así que termino insertando una sola fila ficticia en cada partición y cuando quise obtener una lista de claves de partición, solo consulté esos ítems ficticios y me dieron la lista que estaba buscando.

estoy seguro de que ya habrá visto esto, pero para otros que pueden suceder en esta pregunta, creo que esta es la mejor guía para la funcionalidad de servicio de mesa: http://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-tables/ con ejemplos y enlaces a los documentos detallados del API.

+7

¿No resultaría este enfoque en un escaneo completo de la tabla? Un mejor enfoque sería crear una tabla separada para cada partición (dispositivo) o crear una tabla que solo tenga la información sobre cada dispositivo (tipo de enfoque de detalle maestro). –

+4

@GauravMantri - Sí, creo que podría dar como resultado una exploración completa de la tabla. Supongo que se trata de si desea menos sobrecarga en la creación y administración de una tabla adicional, o una mayor eficiencia en la realización del escaneo, que dependerá de su caso de uso y del volumen de datos. Sin embargo, no necesita una tabla separada: una partición de índice con nada más que las claves de las otras particiones también lo haría. – JcFx

+2

No hay forma de devolver todas las particiones (hoy). Tendría que escanear toda la mesa para saberlo. Use metadatos o algoritmos comunes que calculan qué tecla de partición sería. – dunnry

2

Lamentablemente, las Tablas Azure no tienen funciones como distintas u otras, considérelo un almacenamiento estructurado basado en claves como un diccionario en la memoria. Cualquier operación que realice tendrá que recorrer todos los elementos para obtener un subconjunto a menos que sepa qué teclas desea cargar primero y procesar esa sublista.

Personalmente, simplemente usaría una segunda tabla azul y almacenaría las claves de partición allí (como teclas de fila), lo que le da la oportunidad de agruparlas por otro factor. O simplemente use una sola tecla de partición para esta segunda tabla.

Esto le daría el mejor rendimiento y la menor cantidad de dolor de cabeza.

A veces, el enfoque más simple es el mejor, ya que puede hacer el trabajo.

Espero que esto ayude,

11

crear una sola tabla para almacenar sus particiones. Particione la tabla por los nombres de tabla que utiliza y agregue una entrada para cada partición que cree.

public class PartitionEntry : TableServiceEntity { } 

tableServiceContext.AddObject("TablePartitions", new PartitionEntry 
{ 
    PartitionKey = "<table name>", 
    RowKey = "<partition key>", 
}); 
tableServiceContext.BeginSaveChanges(SaveChangesOptions.ContinueOnError, null, null); 

luego solo consulte esta tabla para obtener una lista de las particiones. Esto es muy manejable para mí.

var tbl = tableServiceContext.CreateQuery<PartitionEntry>("TablePartitions"); 
return tbl.Where(i => i.PartitionKey == "<table name>") 
      .Select(i => new { PartitionKey = i.RowKey, }); 

Apuesto a que esto se puede optimizar.

0

Esto le dará una lista de todas las claves de partición en la tabla:

ConcurrentDictionary<string, byte> partitionKeys = new ConcurrentDictionary<string, byte>(); 
Parallel.ForEach(myTable.ExecuteQuery(new TableQuery()), entity => 
{ 
    partitionKeys.TryAdd(entity.PartitionKey, 0); 
}); 

Incluso si usted tiene una mesa grande, se debe llenar rápidamente becauwse se está ejecutando en paralelo. No existe un "ConcurrentSet", si lo desea, así que tenemos que usar ConcurrentDictionary. El byte es solo un marcador de posición; todos los valores estarán en partitionKeys.Keys.

0

he intentado enfoque similar antes con:

TableQuery queryRows = new TableQuery() { SelectColumns = new List<string> { "PartitionKey" } }; 
... 
var tableClientSrc = storageAcctScr.CreateCloudTableClient(); 
var tablesSrc = tableClientSrc.ListTables(); 
var tableSrc = tablesSrc.FirstOrDefault(o => o.Name.Equals(nameSrc)); 
int cntSrc = tableSrc.ExecuteQuery(queryRows).Count(); 
... 

superior, así como el suyo funcione muy lento en grande (una duración de 70 millones de filas de la tabla - alrededor de 2 horas) o medio, pero con mesa muchas propiedades

Cuestiones relacionadas