2012-10-12 6 views
8

Derzeit verwende ich den PartitionKey, um Geräte zu unterscheiden, die Daten in Azure Table Services speichern. Ich möchte einen Viewer erstellen, der es mir erlaubt, diese Daten zu durchsuchen, aber es wäre schön, sie so strukturieren zu können, dass ich Daten "nach Gerät" oder mit PartitionKey anzeigen kann. Die Viewer-App wird keine Kenntnis davon haben, welche Geräte existieren, also wäre es großartig, wenn ich irgendwie eine Liste von verschiedenen PartionKeys in einer gegebenen Tabelle zurückbekommen könnte. Ist das möglich, oder werde ich dazu verleitet, eine Metadatentabelle zu erstellen, in die ich für jedes Gerät eine neue Zeile einfüge, und diese dann für die Abfrage verwende?Gibt es eine Möglichkeit, bestimmte PartionKeys aus einer Tabelle zu erhalten

Antwort

6

Ich glaube nicht, dass es eine Möglichkeit gibt, alle Partitionsschlüssel abzurufen. Hier ist eine clevere Abhilfe, aber: http://blogs.msdn.com/b/avkashchauhan/archive/2011/10/23/retrieving-partition-key-range-in-windows-azure-table-storage.aspx

Zitat aus Avkash Blog:

weiter Graben, ich fand es nicht in API gebaut wird eine Liste der Partition Schlüssel zu bekommen, stattdessen hätte ich erstellen eine Lösung für mich. Also am Ende ich eine einzelne Dummy-Zeile in jede Partition einfügen und wenn Ich wollte eine Liste der Partition Schlüssel, die ich nur für diese Dummy Artikel abfragen und sie gaben mir die Liste, die ich suchte.

Ich bin sicher, dass Sie das schon gesehen haben, aber für andere, die auf diese Frage kann passieren, ich denke, das ist die beste Anleitung zur Bedienung am Tisch Funktionalität: http://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-tables/ mit Beispielen und Links zu den ausführlichen API-Dokumentation.

+7

Würde diese Vorgehensweise nicht zu einem vollständigen Tabellenscan führen? Ein besserer Ansatz wäre, entweder eine separate Tabelle für jede Partition (Gerät) zu erstellen oder eine Tabelle zu erstellen, die nur die Informationen über jedes Gerät enthält (Art des Hauptdetailansatzes). –

+4

@GauravMantri - Ja, ich denke, es könnte zu einem ganzen Tabellen-Scan führen. Ich denke, es ist eine Frage, ob Sie weniger Aufwand beim Erstellen und Verwalten einer zusätzlichen Tabelle oder mehr Effizienz bei der Durchführung des Scans haben wollen - was von Ihrem Anwendungsfall und dem Datenvolumen abhängen wird. Sie brauchen jedoch keine separate Tabelle - eine Indexpartition mit nichts als Schlüsseln zu den anderen Partitionen würde ebenfalls funktionieren. – JcFx

+2

Es gibt keine Möglichkeit, alle Partitionen (heute) zurückzugeben. Sie müssten die gesamte Tabelle scannen, um zu wissen. Verwenden Sie Metadaten oder einen gemeinsamen Algorithmus, der den Partitionsschlüssel berechnet. – dunnry

2

Bedauerlicherweise haben Azure Tables keine Funktionen wie distinct oder andere - betrachten Sie es als strukturierten Schlüsselspeicher wie ein Dictionary im Speicher. Jede Operation, die Sie ausführen, muss alle Elemente durchlaufen, um eine Teilmenge davon zu erhalten, es sei denn, Sie wissen, welche Schlüssel zuerst geladen werden sollen, und verarbeiten diese Unterliste.

Ich würde persönlich einfach eine zweite azurblaue Tabelle verwenden und die Partitionsschlüssel dort (als Zeilenschlüssel) speichern, die Ihnen dann eine Gelegenheit gibt, diese durch einen anderen Faktor zu gruppieren. Oder verwenden Sie einfach einen einzelnen Partitionsschlüssel für diese zweite Tabelle.

Dies würde Ihnen die beste Leistung und die geringste Menge an Kopfschmerzen geben.

Manchmal ist der einfachste Ansatz der beste, da Sie den Job erledigen können.

hoffe, das hilft,

11

Erstellen Sie eine einzelne Tabelle, um Ihre Partitionen zu speichern. Partitionieren Sie die Tabelle nach den von Ihnen verwendeten Tabellennamen, und fügen Sie für jede von Ihnen erstellte Partition einen Eintrag hinzu.

public class PartitionEntry : TableServiceEntity { } 

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

dann nur diese Tabelle abfragen, um eine Liste der Partitionen zu erhalten. Das ist sehr überschaubar für mich.

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

Ich wette, das könnte optimiert werden.

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

Auch wenn Sie einen großen Tisch haben, sollte es schnell füllen becauwse es parallel ausgeführt wird:

0

Dies wird Ihnen eine Liste aller Partitionsschlüssel in der Tabelle erhalten. Es gibt kein "ConcurrentSet", wenn Sie wollen, also müssen wir ConcurrentDictionary verwenden. Das Byte ist nur ein Platzhalter; Alle Werte werden in partitionKeys.Keys angegeben.

0

i ähnlichen Ansatz versucht, bevor mit:

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(); 
... 

oberen als auch bei Ihnen auf großen sehr langsam arbeiten (für 70 Millionen Zeilen Tabelle laufen - ca. 2 Stunden) oder Medium, aber mit vielen Eigenschaften Tabelle

Verwandte Themen