Attualmente sto utilizzando PartitionKey per differenziare i dispositivi che stanno memorizzando i dati in Azure Table Services. Mi piacerebbe creare un visualizzatore che mi permetta di sfogliare quei dati, ma sarebbe bello poterli strutturare in modo da poter visualizzare i dati "per dispositivo" o per PartitionKey. L'app visualizzatore non avrà alcuna conoscenza di quali dispositivi esistono, quindi sarebbe bello se potessi in qualche modo recuperare un elenco di PartionKeys distinti in una determinata tabella. È possibile, o sto per essere relegato alla creazione di una tabella di meta-dati in cui inserisco una nuova riga per ogni dispositivo, quindi la uso per l'interrogazione?C'è un modo per ottenere PartionKeys distinti da una tabella
risposta
Non penso che ci sia un modo per recuperare tutte le chiavi della partizione. Ecco una soluzione intelligente, però: http://blogs.msdn.com/b/avkashchauhan/archive/2011/10/23/retrieving-partition-key-range-in-windows-azure-table-storage.aspx
Citando dal blog di Avkash:
Scavando ulteriormente, ho trovato non c'è è costruito in API per ottenere un elenco di chiavi di partizione, invece avrei dovuto creare una soluzione per me stesso. Quindi, finisco per inserire una singola fila fittizia in ogni partizione e quando volevo ottenere un elenco di chiavi di partizione, ho appena interrogato quegli articoli fittizi e mi hanno dato la lista che stavo cercando.
sono certo avrete già visto questo, ma per gli altri che possono accadere su questa questione, credo che questo è la migliore guida per la funzionalità servizio al tavolo: http://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-tables/ con esempi e collegamenti alle dettagliate documentazione API.
Con rammarico, le tabelle di Azure non hanno funzioni come distinte o di altro tipo - considerano una memoria strutturata basata su chiavi come un dizionario in memoria. Qualsiasi operazione eseguita, dovrà scorrere tutti gli elementi per ottenere un sottoinsieme di essi a meno che non sappia quali chiavi si desidera caricare per prima e elaborare tale sotto-lista.
Vorrei, personalmente, utilizzare semplicemente una seconda tabella azzurra e memorizzare le chiavi delle partizioni lì (come le chiavi di riga) che ti danno l'opportunità di raggrupparle per un altro fattore. O semplicemente usa una singola chiave di partizione per questa seconda tabella.
Questo ti darebbe le migliori prestazioni e il minor numero di mal di testa.
A volte, l'approccio più semplice è il migliore in quanto è possibile ottenere il lavoro.
Spero che questo aiuti,
creare una singola tabella per memorizzare le partizioni. Partiziona la tabella in base ai nomi delle tabelle che utilizzi e aggiungi una voce per ogni partizione creata.
public class PartitionEntry : TableServiceEntity { }
tableServiceContext.AddObject("TablePartitions", new PartitionEntry
{
PartitionKey = "<table name>",
RowKey = "<partition key>",
});
tableServiceContext.BeginSaveChanges(SaveChangesOptions.ContinueOnError, null, null);
quindi basta interrogare questa tabella per ottenere un elenco di partizioni. Questo è molto gestibile per me.
var tbl = tableServiceContext.CreateQuery<PartitionEntry>("TablePartitions");
return tbl.Where(i => i.PartitionKey == "<table name>")
.Select(i => new { PartitionKey = i.RowKey, });
Scommetto che potrebbe essere ottimizzato.
questo modo si ottiene un elenco di tutte le chiavi di partizione nella tabella:
ConcurrentDictionary<string, byte> partitionKeys = new ConcurrentDictionary<string, byte>();
Parallel.ForEach(myTable.ExecuteQuery(new TableQuery()), entity =>
{
partitionKeys.TryAdd(entity.PartitionKey, 0);
});
Anche se si dispone di un grande tavolo, è necessario popolare rapidamente becauwse è in esecuzione in parallelo. Non c'è "ConcurrentSet", se lo si desidera, quindi dobbiamo usare ConcurrentDictionary. Il byte è solo un segnaposto; tutti i valori saranno in partitionKeys.Keys.
ho provato approccio simile prima 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();
...
superiore così come il vostro lavoro molto lenta su grande (funzionare per 70 milioni di righe della tabella - circa 2 ore) o medie ma con tavolo molte proprietà
Questo approccio non darebbe luogo a una scansione completa della tabella? Un approccio migliore sarebbe quello di creare una tabella separata per ogni partizione (dispositivo) o creare una tabella che abbia solo le informazioni su ciascun dispositivo (tipo di approccio ai dettagli principali). –
@GauravMantri - Sì, penso che potrebbe causare un'intera scansione della tabella. Suppongo che si tratti di ridurre le spese generali nella creazione e nella gestione di una tabella aggiuntiva o di una maggiore efficienza nell'esecuzione della scansione, che dipenderà dal caso d'uso e dal volume dei dati. Tuttavia non è necessaria una tabella separata: una partizione di indice con nient'altro che le chiavi delle altre partizioni. – JcFx
Non è possibile restituire tutte le partizioni (oggi). Dovresti scansionare l'intero tavolo per sapere. Utilizzare i metadati o l'algoritmo comune che calcola la chiave della partizione. – dunnry