Introdução ao armazenamento de tabelas do Azure e ao Azure Cosmos DB API de Tabela usando F#Get started with Azure Table storage and the Azure Cosmos DB Table API using F#

O armazenamento de tabelas do Azure é um serviço que armazena dados NoSQL estruturados na nuvem.Azure Table storage is a service that stores structured NoSQL data in the cloud. O armazenamento de tabela é um repositório de chave/atributo com um design sem esquema.Table storage is a key/attribute store with a schemaless design. Como o armazenamento de tabelas não tem Esquema, é fácil adaptar seus dados à medida que as necessidades de seu aplicativo evoluem.Because Table storage is schemaless, it's easy to adapt your data as the needs of your application evolve. O acesso aos dados é rápido e econômico para todos os tipos de aplicativos.Access to data is fast and cost-effective for all kinds of applications. O armazenamento de tabela normalmente é significativamente menor em relação ao custo do que o SQL tradicional para volumes de dados semelhantes.Table storage is typically significantly lower in cost than traditional SQL for similar volumes of data.

Você pode usar o armazenamento de tabelas para armazenar conjuntos de dados flexíveis, como os de usuário para aplicativos Web, catálogos de endereços, informações de dispositivo e qualquer outro tipo de metadados que seu serviço requer.You can use Table storage to store flexible datasets, such as user data for web applications, address books, device information, and any other type of metadata that your service requires. Você pode armazenar qualquer número de entidades em uma tabela e uma conta de armazenamento pode conter qualquer número de tabelas, até o limite de capacidade da conta de armazenamento.You can store any number of entities in a table, and a storage account may contain any number of tables, up to the capacity limit of the storage account.

Azure Cosmos DB fornece a API de Tabela para aplicativos que são escritos para o armazenamento de tabelas do Azure e que exigem recursos premium, como:Azure Cosmos DB provides the Table API for applications that are written for Azure Table storage and that require premium capabilities such as:

  • Distribuição global pronta para uso.Turnkey global distribution.
  • Taxa de transferência dedicada em todo o mundo.Dedicated throughput worldwide.
  • Latências de milissegundos de dígito único no 99 º percentil.Single-digit millisecond latencies at the 99th percentile.
  • Alta disponibilidade garantida.Guaranteed high availability.
  • Indexação secundária automática.Automatic secondary indexing.

Os aplicativos escritos para o armazenamento de tabelas do Azure podem migrar para Azure Cosmos DB usando o API de Tabela sem alterações de código e aproveitar os recursos premium.Applications written for Azure Table storage can migrate to Azure Cosmos DB by using the Table API with no code changes and take advantage of premium capabilities. O API de Tabela tem SDKs de cliente disponíveis para .NET, Java, Python e node. js.The Table API has client SDKs available for .NET, Java, Python, and Node.js.

Para obter mais informações, consulte introdução ao Azure Cosmos DB API de tabela.For more information, see Introduction to Azure Cosmos DB Table API.

Sobre este tutorialAbout this tutorial

Este tutorial mostra como escrever F# código para fazer algumas tarefas comuns usando o armazenamento de tabelas do Azure ou o Azure Cosmos DB API de tabela, incluindo a criação e a exclusão de uma tabela e inserção, atualização, exclusão e consulta de dados de tabela.This tutorial shows how to write F# code to do some common tasks using Azure Table storage or the Azure Cosmos DB Table API, including creating and deleting a table and inserting, updating, deleting, and querying table data.

Pré-requisitosPrerequisites

Para usar este guia, você deve primeiro criar uma conta de armazenamento do Azure ou Azure Cosmos DB conta.To use this guide, you must first create an Azure storage account or Azure Cosmos DB account.

Criar um F# script e iniciar F# interativoCreate an F# Script and Start F# Interactive

Os exemplos neste artigo podem ser usados em um F# aplicativo ou um F# script.The samples in this article can be used in either an F# application or an F# script. Para criar um F# script, crie um arquivo com a .fsx extensão, por exemplo tables.fsx, em seu F# ambiente de desenvolvimento.To create an F# script, create a file with the .fsx extension, for example tables.fsx, in your F# development environment.

Em seguida, use um Gerenciador de pacotes , como paket ou NuGet , WindowsAzure.Storage para instalar o WindowsAzure.Storage.dll pacote e a referência em #r seu script usando uma diretiva.Next, use a package manager such as Paket or NuGet to install the WindowsAzure.Storage package and reference WindowsAzure.Storage.dll in your script using a #r directive. Faça isso novamente para Microsoft.WindowsAzure.ConfigurationManager para obter o namespace Microsoft. Azure.Do it again for Microsoft.WindowsAzure.ConfigurationManager in order to get the Microsoft.Azure namespace.

Adicionar declarações de namespaceAdd namespace declarations

Adicione as seguintes open instruções à parte superior tables.fsx do arquivo:Add the following open statements to the top of the tables.fsx file:

open System
open System.IO
open Microsoft.Azure // Namespace for CloudConfigurationManager
open Microsoft.Azure.Storage // Namespace for CloudStorageAccount
open Microsoft.Azure.Storage.Table // Namespace for Table storage types

Obter sua cadeia de conexão de armazenamento do AzureGet your Azure Storage connection string

Se você estiver se conectando ao serviço tabela de armazenamento do Azure, precisará de sua cadeia de conexão para este tutorial.If you're connecting to Azure Storage Table service, you'll need your connection string for this tutorial. Você pode copiar a cadeia de conexão do portal do Azure.You can copy your connection string from the Azure portal. Para obter mais informações sobre cadeias de conexão, consulte Configurar cadeias de conexão de armazenamento.For more information about connection strings, see Configure Storage Connection Strings.

Obter sua cadeia de conexão do Azure Cosmos DBGet your Azure Cosmos DB connection string

Se estiver se conectando ao Azure Cosmos DB, você precisará da sua cadeia de conexão para este tutorial.If you're connecting to Azure Cosmos DB, you'll need your connection string for this tutorial. Você pode copiar a cadeia de conexão do portal do Azure.You can copy your connection string from the Azure portal. Na portal do Azure, em sua conta do cosmos DB, vá para configurações > cadeia de conexãoe clique no botão copiar para copiar a cadeia de conexão primária.In the Azure portal, in your Cosmos DB account, go to Settings > Connection String, and click the Copy button to copy your Primary Connection String.

Para o tutorial, insira sua cadeia de conexão em seu script, como no exemplo a seguir:For the tutorial, enter your connection string in your script, like the following example:

let storageConnString = "..." // fill this in from your storage account

No entanto, isso não é recomendado para projetos reais.However, this is not recommended for real projects. Sua chave de conta de armazenamento é semelhante à senha raiz da sua conta de armazenamento.Your storage account key is similar to the root password for your storage account. Sempre tenha cuidado para proteger sua chave de conta de armazenamento.Always be careful to protect your storage account key. Evite distribuí-lo a outros usuários, embuti-lo em código ou salvá-lo em um arquivo de texto sem formatação que seja acessível para outras pessoas.Avoid distributing it to other users, hard-coding it, or saving it in a plain-text file that is accessible to others. Você pode regenerar sua chave usando o portal do Azure se acreditar que ele pode ter sido comprometido.You can regenerate your key using the Azure Portal if you believe it may have been compromised.

Para aplicativos reais, a melhor maneira de manter a cadeia de conexão de armazenamento está em um arquivo de configuração.For real applications, the best way to maintain your storage connection string is in a configuration file. Para buscar a cadeia de conexão de um arquivo de configuração, você pode fazer isso:To fetch the connection string from a configuration file, you can do this:

// Parse the connection string and return a reference to the storage account.
let storageConnString = 
    CloudConfigurationManager.GetSetting("StorageConnectionString")

Usar o Configuration Manager do Azure é opcional.Using Azure Configuration Manager is optional. Você também pode usar uma API como o ConfigurationManager tipo de .NET Framework.You can also use an API such as the .NET Framework's ConfigurationManager type.

Analisar a cadeia de conexãoParse the connection string

Para analisar a cadeia de conexão, use:To parse the connection string, use:

// Parse the connection string and return a reference to the storage account.
let storageAccount = CloudStorageAccount.Parse(storageConnString)

Isso retorna um CloudStorageAccount.This returns a CloudStorageAccount.

Criar o cliente do serviço tabelaCreate the Table service client

A CloudTableClient classe permite que você recupere tabelas e entidades no armazenamento de tabelas.The CloudTableClient class enables you to retrieve tables and entities in Table storage. Aqui está uma maneira de criar o cliente de serviço:Here's one way to create the service client:

// Create the table client.
let tableClient = storageAccount.CreateCloudTableClient()

Agora você está pronto para escrever código que lê dados e grava dados no armazenamento de tabelas.Now you are ready to write code that reads data from and writes data to Table storage.

Criar uma tabelaCreate a table

Este exemplo mostra como criar uma tabela se ela ainda não existir:This example shows how to create a table if it does not already exist:

// Retrieve a reference to the table.
let table = tableClient.GetTableReference("people")

// Create the table if it doesn't exist.
table.CreateIfNotExists()

Adicionar uma entidade a uma tabelaAdd an entity to a table

Uma entidade deve ter um tipo que herda de TableEntity.An entity has to have a type that inherits from TableEntity. Você pode estender TableEntity de qualquer forma que desejar, mas seu tipo deve ter um construtor sem parâmetros.You can extend TableEntity in any way you like, but your type must have a parameter-less constructor. Somente as propriedades que têm get e set são armazenadas em sua tabela do Azure.Only properties that have both get and set are stored in your Azure Table.

A chave de partição e de linha de uma entidade identifica exclusivamente a entidade na tabela.An entity's partition and row key uniquely identify the entity in the table. As entidades com a mesma chave de partição podem ser consultadas mais rápido do que aquelas com chaves de partição diferentes, mas o uso de chaves de partição diversas permite maior escalabilidade de operações paralelas.Entities with the same partition key can be queried faster than those with different partition keys, but using diverse partition keys allows for greater scalability of parallel operations.

Aqui está um exemplo de um Customer que usa o lastName como a chave de partição e firstName o como a chave de linha.Here's an example of a Customer that uses the lastName as the partition key and the firstName as the row key.

type Customer(firstName, lastName, email: string, phone: string) =
    inherit TableEntity(partitionKey=lastName, rowKey=firstName)
    new() = Customer(null, null, null, null)
    member val Email = email with get, set
    member val PhoneNumber = phone with get, set

let customer = 
    Customer("Walter", "Harp", "Walter@contoso.com", "425-555-0101")

Agora, Customer adicione à tabela.Now add Customer to the table. Para fazer isso, crie um TableOperation que seja executado na tabela.To do so, create a TableOperation that executes on the table. Nesse caso, você cria uma Insert operação.In this case, you create an Insert operation.

let insertOp = TableOperation.Insert(customer)
table.Execute(insertOp)

Inserir um lote de entidadesInsert a batch of entities

Você pode inserir um lote de entidades em uma tabela usando uma única operação de gravação.You can insert a batch of entities into a table using a single write operation. As operações em lote permitem combinar operações em uma única execução, mas têm algumas restrições:Batch operations allow you to combine operations into a single execution, but they have some restrictions:

  • Você pode executar atualizações, exclusões e inserções na mesma operação em lote.You can perform updates, deletes, and inserts in the same batch operation.
  • Uma operação em lote pode incluir até 100 entidades.A batch operation can include up to 100 entities.
  • Todas as entidades em uma operação em lote devem ter a mesma chave de partição.All entities in a batch operation must have the same partition key.
  • Embora seja possível executar uma consulta em uma operação em lote, ela deve ser a única operação no lote.While it is possible to perform a query in a batch operation, it must be the only operation in the batch.

Aqui está um código que combina duas inserções em uma operação em lote:Here's some code that combines two inserts into a batch operation:

let customer1 =
    Customer("Jeff", "Smith", "Jeff@contoso.com", "425-555-0102")

let customer2 =
    Customer("Ben", "Smith", "Ben@contoso.com", "425-555-0103")

let batchOp = TableBatchOperation()
batchOp.Insert(customer1)
batchOp.Insert(customer2)
table.ExecuteBatch(batchOp)

Recuperar todas as entidades em uma partiçãoRetrieve all entities in a partition

Para consultar uma tabela para todas as entidades em uma partição, use TableQuery um objeto.To query a table for all entities in a partition, use a TableQuery object. Aqui, você filtra as entidades em que "Smith" é a chave de partição.Here, you filter for entities where "Smith" is the partition key.

let query =
    TableQuery<Customer>().Where(
        TableQuery.GenerateFilterCondition(
            "PartitionKey", QueryComparisons.Equal, "Smith"))

let result = table.ExecuteQuery(query)

Agora você imprime os resultados:You now print the results:

for customer in result do 
    printfn "customer: %A %A" customer.RowKey customer.PartitionKey

Recuperar um intervalo de entidades em uma partiçãoRetrieve a range of entities in a partition

Se você não quiser consultar todas as entidades em uma partição, poderá especificar um intervalo combinando o filtro de chave de partição com um filtro de chave de linha.If you don't want to query all the entities in a partition, you can specify a range by combining the partition key filter with a row key filter. Aqui, você usa dois filtros para obter todas as entidades na partição "Smith", em que a chave de linha (primeiro nome) começa com uma letra anterior à "M" no alfabeto.Here, you use two filters to get all entities in the "Smith" partition where the row key (first name) starts with a letter earlier than "M" in the alphabet.

let range =
    TableQuery<Customer>().Where(
        TableQuery.CombineFilters(
            TableQuery.GenerateFilterCondition(
                "PartitionKey", QueryComparisons.Equal, "Smith"),
            TableOperators.And,
            TableQuery.GenerateFilterCondition(
                "RowKey", QueryComparisons.LessThan, "M")))

let rangeResult = table.ExecuteQuery(range)

Agora você imprime os resultados:You now print the results:

for customer in rangeResult do 
    printfn "customer: %A %A" customer.RowKey customer.PartitionKey

Recuperar uma única entidadeRetrieve a single entity

Você pode escrever uma consulta para recuperar uma única entidade específica.You can write a query to retrieve a single, specific entity. Aqui, você usa um TableOperation para especificar o cliente "Ben Smith".Here, you use a TableOperation to specify the customer "Ben Smith". Em vez de uma coleção, você obtém um Customer.Instead of a collection, you get back a Customer. A especificação da chave de partição e da chave de linha em uma consulta é a maneira mais rápida de recuperar uma única entidade do serviço tabela.Specifying both the partition key and the row key in a query is the fastest way to retrieve a single entity from the Table service.

let retrieveOp = TableOperation.Retrieve<Customer>("Smith", "Ben")

let retrieveResult = table.Execute(retrieveOp)

Agora você imprime os resultados:You now print the results:

// Show the result
let retrieveCustomer = retrieveResult.Result :?> Customer
printfn "customer: %A %A" retrieveCustomer.RowKey retrieveCustomer.PartitionKey

Substituir uma entidadeReplace an entity

Para atualizar uma entidade, recupere-a do serviço tabela, modifique o objeto de entidade e salve as alterações de volta no serviço tabela usando uma Replace operação.To update an entity, retrieve it from the Table service, modify the entity object, and then save the changes back to the Table service using a Replace operation. Isso faz com que a entidade seja totalmente substituída no servidor, a menos que a entidade no servidor tenha sido alterada desde que foi recuperada; nesse caso, a operação falhará.This causes the entity to be fully replaced on the server, unless the entity on the server has changed since it was retrieved, in which case the operation fails. Essa falha é impedir que seu aplicativo substitua inadvertidamente as alterações de outras fontes.This failure is to prevent your application from inadvertently overwriting changes from other sources.

try
    let customer = retrieveResult.Result :?> Customer
    customer.PhoneNumber <- "425-555-0103"
    let replaceOp = TableOperation.Replace(customer)
    table.Execute(replaceOp) |> ignore
    Console.WriteLine("Update succeeeded")
with e ->
    Console.WriteLine("Update failed")

Inserir ou substituir uma entidadeInsert-or-replace an entity

Às vezes, você não sabe se existe uma entidade na tabela.Sometimes, you don't know whether an entity exists in the table. E, se tiver, os valores atuais armazenados nela não serão mais necessários.And if it does, the current values stored in it are no longer needed. Você pode usar InsertOrReplace o para criar a entidade ou substituí-la, se ela existir, independentemente de seu estado.You can use InsertOrReplace to create the entity, or replace it if it exists, regardless of its state.

try
    let customer = retrieveResult.Result :?> Customer
    customer.PhoneNumber <- "425-555-0104"
    let replaceOp = TableOperation.InsertOrReplace(customer)
    table.Execute(replaceOp) |> ignore
    Console.WriteLine("Update succeeeded")
with e ->
    Console.WriteLine("Update failed")

Consultar um subconjunto de propriedades de entidadeQuery a subset of entity properties

Uma consulta de tabela pode recuperar apenas algumas propriedades de uma entidade em vez de todas elas.A table query can retrieve just a few properties from an entity instead of all of them. Essa técnica, chamada projeção, pode melhorar o desempenho da consulta, especialmente para grandes entidades.This technique, called projection, can improve query performance, especially for large entities. Aqui, você retorna apenas endereços de email DynamicTableEntity usando EntityResolvero e o.Here, you return only email addresses using DynamicTableEntity and EntityResolver. Observe que a projeção não tem suporte no emulador de armazenamento local, portanto, esse código é executado somente quando você está usando uma conta no serviço tabela.Note that projection is not supported on the local storage emulator, so this code runs only when you're using an account on the Table service.

// Define the query, and select only the Email property.
let projectionQ = TableQuery<DynamicTableEntity>().Select [|"Email"|]

// Define an entity resolver to work with the entity after retrieval.
let resolver = EntityResolver<string>(fun pk rk ts props etag ->
    if props.ContainsKey("Email") then
        props.["Email"].StringValue
    else
        null
    )

let resolvedResults = table.ExecuteQuery(projectionQ, resolver, null, null)

Recuperar entidades em páginas de forma assíncronaRetrieve entities in pages asynchronously

Se você estiver lendo um grande número de entidades e quiser processá-las à medida que elas forem recuperadas em vez de esperar que todas elas retornem, você poderá usar uma consulta segmentada.If you are reading a large number of entities, and you want to process them as they are retrieved rather than waiting for them all to return, you can use a segmented query. Aqui, você retorna resultados em páginas usando um fluxo de trabalho assíncrono para que a execução não seja bloqueada enquanto você estiver aguardando um grande conjunto de resultados ser retornado.Here, you return results in pages by using an async workflow so that execution is not blocked while you're waiting for a large set of results to return.


let tableQ = TableQuery<Customer>()

let asyncQuery = 
    let rec loop (cont: TableContinuationToken) = async {
        let! ct = Async.CancellationToken
        let! result = table.ExecuteQuerySegmentedAsync(tableQ, cont, ct) |> Async.AwaitTask

        // ...process the result here...
        
        // Continue to the next segment
        match result.ContinuationToken with
        | null -> ()
        | cont -> return! loop cont 
    }
    loop null

Agora você executa essa computação de forma síncrona:You now execute this computation synchronously:

let asyncResults = asyncQuery |> Async.RunSynchronously

Excluir uma entidadeDelete an entity

Você pode excluir uma entidade depois de recuperá-la.You can delete an entity after you have retrieved it. Assim como a atualização de uma entidade, isso falhará se a entidade tiver sido alterada desde que você a recuperou.As with updating an entity, this fails if the entity has changed since you retrieved it.

let deleteOp = TableOperation.Delete(customer)
table.Execute(deleteOp)

Excluir uma tabelaDelete a table

Você pode excluir uma tabela de uma conta de armazenamento.You can delete a table from a storage account. Uma tabela que foi excluída não estará disponível para ser recriada por um período de tempo após a exclusão.A table that has been deleted will be unavailable to be re-created for a period of time following the deletion.

table.DeleteIfExists()

Próximas etapasNext steps

Agora que você aprendeu os conceitos básicos do armazenamento de tabelas, siga estes links para saber mais sobre tarefas de armazenamento mais complexas e o Azure Cosmos DB API de Tabela.Now that you've learned the basics of Table storage, follow these links to learn about more complex storage tasks and the Azure Cosmos DB Table API.