Erste Schritte mit Azure Table Storage und der Azure Cosmos DB-Tabellen-API mit F#
Azure Table Storage ist ein Dienst, bei dem strukturierte NoSQL-Daten in der Cloud gespeichert werden. Bei Table Storage handelt es sich um einen Schlüssel-/Attributspeicher mit einem schemalosen Design. Aufgrund der Schemalosigkeit von Table Storage ist es einfach, Ihre Daten an die Entwicklung Ihrer Anwendungen anzupassen. Der Datenzugriff ist für alle Arten von Anwendungen schnell und kostengünstig. Table Storage ist in der Regel erheblich günstiger als herkömmliche SQL-Lösungen für ähnliche Datenmengen.
Mit Table Storage können Sie flexible Datasets wie Benutzerdaten für Webanwendungen, Adressbücher, Geräteinformationen und jegliche Art von Metadaten speichern, die Ihr Dienst erfordert. Sie können eine beliebige Anzahl von Entitäten in einer Tabelle speichern, und ein Speicherkonto kann eine beliebige Anzahl von Tabellen enthalten (bis zur Speicherkapazitätsgrenze eines Speicherkontos).
Azure Cosmos DB stellt die Table-API für Anwendungen bereit, die für Azure Table Storage geschrieben wurden und Premium-Funktionen benötigen, z. B.:
- Globale, sofort einsatzbereite Verteilung
- Dedizierter Durchsatz weltweit.
- Einstellige Latenzzeiten im Millisekundenbereich im 99. Perzentil.
- Garantierte Hochverfügbarkeit.
- Automatische sekundäre Indizierung
Anwendungen, die für Azure Table Storage geschrieben sind, können mit der Table-API ohne Codeänderungen zu Azure Cosmos DB migriert werden und Premium-Funktionen nutzen. Die Table-API verfügt über Client-SDKs, die für .NET, Java, Python und Node.js verfügbar sind.
Weitere Informationen finden Sie in der Einführung in Azure Cosmos DB for Table.
Informationen zu diesem Tutorial
In diesem Tutorial wird gezeigt, wie Sie F#-Code schreiben, um einige gängige Aufgaben mit Azure Table Storage oder der Tabellen-API von der Azure Cosmos DB auszuführen, z. B. Erstellen und Löschen einer Tabelle sowie Einfügen, Aktualisieren, Löschen und Abfragen von Tabellendaten.
Voraussetzungen
Um diesen Leitfaden verwenden zu können, müssen Sie zuerst ein Azure-Speicherkonto oder ein Azure Cosmos DB-Konto erstellen.
Erstellen eines F#-Skripts und Starten von F# Interactive
Die Beispiele in diesem Artikel können in einer F#-Anwendung oder in einem F#-Skript verwendet werden. Um ein F#-Skript zu erstellen, erstellen Sie eine Datei mit der Erweiterung .fsx
, z. B. tables.fsx
, in Ihrer F#-Entwicklungsumgebung.
Ausführen von Skripts
F# Interactive dotnet fsi
kann interaktiv oder von der Befehlszeile aus gestartet werden, um ein Skript auszuführen. Die Befehlszeilensyntax lautet wie folgt:
> dotnet fsi [options] [ script-file [arguments] ]
Hinzufügen von Paketen in einem Skript
Verwenden Sie als Nächstes #r
nuget:package name
, um das Paket Azure.Data.Tables
und die open
-Namespaces zu installieren. Beispielsweise
> #r "nuget: Azure.Data.Tables"
open Azure.Data.Tables
Hinzufügen von Namespace-Deklarationen
Fügen Sie am Anfang der Datei tables.fsx
die folgenden open
-Anweisungen ein:
open System
open Azure
open Azure.Data.Tables // Namespace for Table storage types
Abrufen der Azure Storage-Verbindungszeichenfolge
Wenn Sie eine Verbindung zum Azure Storage-Tabellendienst herstellen, benötigen Sie Ihre Verbindungszeichenfolge für dieses Tutorial. Sie können Ihre Verbindungszeichenfolge aus dem Azure-Portal kopieren. Weitere Informationen zu Verbindungszeichenfolgen finden Sie unter Konfigurieren von Azure Storage-Verbindungszeichenfolgen.
Abrufen der Azure Cosmos DB-Verbindungszeichenfolge
Wenn Sie eine Verbindung zu Azure Cosmos DB herstellen, benötigen Sie Ihre Verbindungszeichenfolge für dieses Tutorial. Sie können Ihre Verbindungszeichenfolge aus dem Azure-Portal kopieren. Wechseln Sie im Azure-Portal in Ihrem Cosmos DB-Konto zu Einstellungen>Verbindungszeichenfolge, und wählen Sie die Schaltfläche Kopieren aus, um Ihre primäre Verbindungszeichenfolge zu kopieren.
Für das Tutorial geben Sie die Verbindungszeichenfolge, wie im folgenden Beispiel gezeigt, in Ihr Skript ein:
let storageConnString = "UseDevelopmentStorage=true" // fill this in from your storage account
Erstellen des Tabellendienstclients
Mit der TableServiceClient
-Klasse können Sie Tabellen und Entitäten im Tabellenspeicher abrufen. Hier sehen Sie eine Möglichkeit zum Erstellen des Dienstclients:
let tableClient = TableServiceClient storageConnString
Jetzt können Sie Code schreiben, der Daten aus dem Tabellenspeicher liest und Daten in den Tabellenspeicher schreibt.
Erstellen einer Tabelle
Dieses Beispiel zeigt, wie Sie eine Tabelle erstellen, falls sie nicht bereits vorhanden ist:
// Retrieve a reference to the table.
let table = tableClient.GetTableClient "people"
// Create the table if it doesn't exist.
table.CreateIfNotExists () |> ignore
Hinzufügen einer Entität zu einer Tabelle
Eine Entität muss über einen Typ verfügen, der ITableEntity
implementiert. Sie können ITableEntity
beliebig erweitern, der Typ muss aber einen parameterlosen Konstruktor aufweisen. Nur Eigenschaften, die sowohl über get
als auch über set
verfügen, werden in Ihrer Azure-Tabelle gespeichert.
Der Partitions- und Zeilenschlüssel einer Entität kennzeichnen eine Entität in der Tabelle eindeutig. Entitäten mit demselben Partitionsschlüssel können schneller abgerufen werden als Entitäten mit unterschiedlichen Partitionsschlüsseln, die Verwendung verschiedener Partitionsschlüssel ermöglicht jedoch eine größere Skalierbarkeit paralleler Vorgänge.
Hier sehen Sie ein Beispiel für Customer
, in dem lastName
als Partitionsschlüssel und firstName
als Zeilenschlüssel verwendet wird.
type Customer (firstName, lastName, email: string, phone: string) =
interface ITableEntity with
member val ETag = ETag "" with get, set
member val PartitionKey = "" with get, set
member val RowKey = "" with get, set
member val Timestamp = Nullable() with get, set
new() = Customer(null, null, null, null)
member val Email = email with get, set
member val PhoneNumber = phone with get, set
member val PartitionKey = lastName with get, set
member val RowKey = firstName with get, set
Fügen Sie nun Customer
zur Tabelle hinzu. Dazu können wir die AddEntity()-Methode verwenden.
let customer = Customer ("Walter", "Harp", "Walter@contoso.com", "425-555-0101")
table.AddEntity customer
Einfügen eines Entitätsbatchs
Sie können einen Batch von Entitäten in einer einzelnen Schreiboperation in eine Tabelle einfügen. Batchvorgänge bieten die Möglichkeit, Operationen in einer einzelnen Ausführung zu kombinieren. Dabei gelten jedoch einige Einschränkungen:
- Sie können Aktualisierungs-, Lösch- und Einfügevorgänge in einer einzigen Batchoperation ausführen.
- Eine Batchoperation kann bis zu 100 Entitäten umfassen.
- Alle Entitäten in eine Batchoperation müssen über denselben Partitionsschlüssel verfügen.
- Eine Abfrage kann als Batchoperation durchgeführt werden, dabei muss es sich jedoch um die einzige Operation im Batch handeln.
Der folgende Code kombiniert zwei Einfügevorgänge in einer Batchoperation kombiniert:
let customers =
[
Customer("Jeff", "Smith", "Jeff@contoso.com", "425-555-0102")
Customer("Ben", "Smith", "Ben@contoso.com", "425-555-0103")
]
// Add the entities to be added to the batch and submit it in a transaction.
customers
|> List.map (fun customer -> TableTransactionAction (TableTransactionActionType.Add, customer))
|> table.SubmitTransaction
Abrufen aller Entitäten einer Partition
Verwenden Sie ein Query<T>
-Objekt, um für eine Tabelle alle Entitäten einer Partition abzufragen. Hier filtern Sie nach Entitäten mit dem Partitionsschlüssel „Smith“.
table.Query<Customer> "PartitionKey eq 'Smith'"
Abrufen eines Entitätsbereichs in einer Partition
Wenn Sie nicht alle Entitäten in einer Partition abrufen möchten, können Sie einen Bereich angeben, indem Sie den Partitionsschlüsselfilter mit einem Zeilenschlüsselfilter kombinieren. Hier verwenden Sie zwei Filter, um alle Entitäten in der „Smith“-Partition abzurufen, in der der Zeilenschlüssel (Vorname) mit einem Buchstaben vor „M“ im Alphabet beginnt.
table.Query<Customer> "PartitionKey eq 'Smith' and RowKey lt 'J'"
Abrufen einer einzelnen Entität
Um eine einzelne, bestimmte Entität abzurufen, verwenden Sie GetEntityAsync
, um den Kunden „Ben Smith“ anzugeben. Anstelle einer Auflistung wird ein Customer
zurückgegeben. Die Angabe von Partitions- und Zeilenschlüssel in einer Abfrage ist die schnellste Möglichkeit, um eine einzelne Entität aus dem Tabellendienst abzurufen.
let singleResult = table.GetEntity<Customer>("Smith", "Ben").Value
Jetzt geben Sie die Ergebnisse aus:
// Evaluate this value to print it out into the F# Interactive console
singleResult
Aktualisieren einer Entität
Um eine Entität zu aktualisieren, rufen Sie sie aus dem Tabellendienst ab, ändern Sie das Entitätsobjekt, und speichern Sie die Änderungen dann mit einer TableUpdateMode.Replace
-Operation wieder im Tabellendienst. Dadurch wird die Entität auf dem Server vollständig ersetzt, es sei denn, dass die Entität auf dem Server seit dem letzten Abruf geändert wurde. In diesem Fall würde die Operation fehlschlagen. Dadurch soll verhindert werden, dass die Anwendung versehentlich Änderungen aus anderen Quellen überschreibt.
singleResult.PhoneNumber <- "425-555-0103"
try
table.UpdateEntity (singleResult, ETag "", TableUpdateMode.Replace) |> ignore
printfn "Update succeeded"
with
| :? RequestFailedException as e ->
printfn $"Update failed: {e.Status} - {e.ErrorCode}"
Upsert für eine Entität
Manchmal wissen Sie nicht, ob eine Entität in der Tabelle vorhanden ist. Und wenn dies der Fall ist, werden die aktuell gespeicherten Werte nicht mehr benötigt. Unabhängig vom Zustand können Sie die UpsertEntity
-Methode verwenden, um die Entität zu erstellen oder zu ersetzen, wenn sie vorhanden ist.
singleResult.PhoneNumber <- "425-555-0104"
table.UpsertEntity (singleResult, TableUpdateMode.Replace)
Abfragen einer Teilmenge von Entitätseigenschaften
Mit einer Tabellenabfrage können nicht nur alle, sondern auch nur einige Eigenschaften aus einer Entität abgerufen werden. Diese Projektion genannte Technik kann die Abfrageleistung verbessern, insbesondere für große Entitäten. Hier geben Sie mit Query<T>
und Select
nur E-Mail-Adressen zurück. Projektion nicht im lokalen Speicheremulator unterstützt wird, sodass dieser Code nur ausgeführt wird, wenn Sie ein Konto für den Tabellendienst verwenden.
query {
for customer in table.Query<Customer> () do
select customer.Email
}
Asynchrones Abrufen von Entitäten in Seiten
Wenn Sie eine Vielzahl von Entitäten lesen und verarbeiten möchten, während sie abgerufen werden, statt zu warten, bis sie alle zurückgeben wurden, können Sie eine segmentierte Abfrage verwenden. Hier werden Sie Ergebnisse mit einem Async-Workflow seitenweise zurückgeben, sodass die Ausführung nicht blockiert ist, während Sie auf die Rückgabe umfangreicher Ergebnisse warten.
let pagesResults = table.Query<Customer> ()
for page in pagesResults.AsPages () do
printfn "This is a new page!"
for customer in page.Values do
printfn $"customer: {customer.RowKey} {customer.PartitionKey}"
Löschen einer Entität
Sie können eine Entität löschen, nachdem sie abgerufen wurde. Wie beim Aktualisieren einer Entität schlägt dies fehl, wenn sich die Entität seit dem Abruf geändert hat.
table.DeleteEntity ("Smith", "Ben")
Löschen einer Tabelle
Sie können eine Tabelle aus einem Speicherkonto löschen. Eine gelöschte Tabelle kann für eine gewisse Zeit nach dem Löschvorgang nicht neu erstellt werden.
table.Delete ()
Siehe auch
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für