Så här använder du Azure Table Storage och Azure Cosmos DB för table med C++
GÄLLER FÖR: Bord
Dricks
Innehållet i den här artikeln gäller för Azure Table Storage och Azure Cosmos DB for Table. API för tabell är ett premiumerbjudande för tabelllagring som erbjuder dataflödesoptimerade tabeller, global distribution och automatiska sekundära index.
Den här guiden visar vanliga scenarier med hjälp av Azure Table Storage-tjänsten eller Azure Cosmos DB for Table. Exemplen är skrivna i C++ och använder Azure Storage-klientbiblioteket för C++. I denna artikel beskrivs följande scenarier:
- Skapa och ta bort en tabell
- Arbeta med tabellentiteter
Kommentar
För den här guiden krävs Azure Storage-klientbiblioteket för C++ version 1.0.0 eller senare. Den rekommenderade versionen är Storage Client Library 2.2.0, som är tillgängligt med hjälp av NuGet eller GitHub.
Skapa konton
Skapa ett Azure-tjänstkonto
Du kan arbeta med tabeller med hjälp av Azure Table Storage eller Azure Cosmos DB. Mer information om skillnaderna mellan tabellerbjudanden i dessa två tjänster finns i API:et för tabellöversikt. Du måste skapa ett konto för den tjänst som du ska använda. Följande avsnitt visar hur du skapar både Azure Table Storage och Azure Cosmos DB-kontot, men du kan bara använda en av dem.
Skapa ett Azure Storage-konto
Det enklaste sättet att skapa ett Azure-lagringskonto är att använda Azure-portalen. För mer information, se Skapa ett lagringskonto.
Du kan även skapa ett Azure-lagringskonto med hjälp av Azure PowerShell eller Azure CLI.
Om du föredrar att inte skapa ett lagringskonto just nu kan du även använda Azure Storage-emulatorn för att köra och testa koden i en lokal miljö. Mer information finns i Använda Azure Storage-emulatorn för utveckling och testning.
Skapa ett Azure Cosmos DB för tabellkonto
Anvisningar om hur du skapar ett Azure Cosmos DB för tabellkonto finns i Skapa ett databaskonto.
Skapa ett C++-program
I den här guiden använder du lagringsfunktioner från ett C++-program. Det gör du genom att installera Azure Storage-klientbiblioteket för C++.
Om du vill installera Azure Storage-klientbiblioteket för C++använder du följande metoder:
- Linux: Följ anvisningarna i Azure Storage-klientbiblioteket för C++ README: Komma igång på Linux-sidan .
- Windows: I Windows använder du vcpkg som beroendehanterare. Följ snabbstarten för att initiera vcpkg. Använd sedan följande kommando för att installera biblioteket:
.\vcpkg.exe install azure-storage-cpp
Du hittar en guide för hur du skapar källkoden och exporterar till Nuget i README-filen .
Konfigurera åtkomst till klientbiblioteket för Table Storage
Om du vill använda Azure Storage-API:erna för att komma åt tabeller lägger du till följande include
instruktioner överst i C++-filen:
#include <was/storage_account.h>
#include <was/table.h>
En Azure Storage-klient eller Azure Cosmos DB-klient använder en niska veze för att lagra slutpunkter och autentiseringsuppgifter för åtkomst till datahanteringstjänster. När du kör ett klientprogram måste du ange lagrings-niska veze eller Azure Cosmos DB-niska veze i lämpligt format.
Konfigurera en Azure Storage-anslutningssträng
Det här exemplet visar hur du deklarerar ett statiskt fält som ska innehålla Azure Storage-niska veze:
// Define the Storage connection string with your values.
const utility::string_t storage_connection_string(U("DefaultEndpointsProtocol=https;AccountName=<your_storage_account>;AccountKey=<your_storage_account_key>"));
Använd namnet på lagringskontot för <your_storage_account>
. För <your_storage_account_key> använder du åtkomstnyckeln för lagringskontot som anges i Azure-portalen. Information om lagringskonton och åtkomstnycklar finns i Skapa ett lagringskonto.
Konfigurera en Azure Cosmos DB-anslutningssträng
Det här exemplet visar hur du deklarerar ett statiskt fält som ska innehålla Azure Cosmos DB-niska veze:
// Define the Azure Cosmos DB connection string with your values.
const utility::string_t storage_connection_string(U("DefaultEndpointsProtocol=https;AccountName=<your_cosmos_db_account>;AccountKey=<your_cosmos_db_account_key>;TableEndpoint=<your_cosmos_db_endpoint>"));
Använd namnet på ditt Azure Cosmos DB-konto för <your_cosmos_db_account>
. Ange primärnyckeln för <your_cosmos_db_account_key>
. Ange slutpunkten som anges i Azure-portalen för <your_cosmos_db_endpoint>
.
Om du vill testa ditt program på din lokala Windows-baserade dator kan du använda Azure Storage-emulatorn som är installerad med Azure SDK. Lagringsemulatorn är ett verktyg som simulerar de Azure Blob-, Queue- och Table-tjänster som är tillgängliga på din lokala utvecklingsdator. I följande exempel visas hur du deklarerar ett statiskt fält för att lagra niska veze till din lokala lagringsemulator:
// Define the connection string with Azure Storage Emulator.
const utility::string_t storage_connection_string(U("UseDevelopmentStorage=true;"));
Starta Azure Storage-emulatorn genom att välja startknappen eller Windows-nyckeln från Skrivbordet i Windows. Ange och kör Microsoft Azure Storage-emulatorn. Mer information finns i Använda Azure Storage-emulatorn för utveckling och testning.
Hämta anslutningssträngen
Du kan använda cloud_storage_account
klassen för att representera din lagringskontoinformation. Om du vill hämta lagringskontoinformationen från lagrings-niska veze använder du parse
metoden .
// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);
Hämta sedan en referens till en cloud_table_client
klass. Med den här klassen kan du hämta referensobjekt för tabeller och entiteter som lagras i Table Storage-tjänsten. Följande kod skapar ett cloud_table_client
objekt med hjälp av lagringskontoobjektet som du hämtade tidigare:
// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();
Skapa och lägga till entiteter i en tabell
Skapa en tabell
Med ett cloud_table_client
objekt kan du hämta referensobjekt för tabeller och entiteter. Följande kod skapar ett cloud_table_client
objekt och använder det för att skapa en ny tabell.
// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);
// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();
// Retrieve a reference to a table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));
// Create the table if it doesn't exist.
table.create_if_not_exists();
Lägga till en entitet i en tabell
Om du vill lägga till en entitet i en tabell skapar du ett nytt table_entity
objekt och skickar det till table_operation::insert_entity
. I följande kod används kundens förnamn som radnyckel och efternamnet som partitionsnyckel. Tillsammans identifierar en entitets partition och radnyckel entiteten i tabellen unikt. Entiteter med samma partitionsnyckel kan efterfrågas snabbare än entiteter med olika partitionsnycklar. Om du använder olika partitionsnycklar kan du använda mer parallell skalbarhet. Mer information finns i checklistan för prestanda och skalbarhet i Microsoft Azure Storage.
Följande kod skapar en ny instans av table_entity
med vissa kunddata att lagra. Koden anropar table_operation::insert_entity
sedan för att skapa ett table_operation
objekt för att infoga en entitet i en tabell och associerar den nya tabellentiteten med den. Slutligen anropar execute
koden -metoden för cloud_table
objektet. Den nya table_operation
skickar en begäran till tabelltjänsten om att infoga den nya kundentiteten i people
tabellen.
// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);
// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();
// Retrieve a reference to a table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));
// Create the table if it doesn't exist.
table.create_if_not_exists();
// Create a new customer entity.
azure::storage::table_entity customer1(U("Harp"), U("Walter"));
azure::storage::table_entity::properties_type& properties = customer1.properties();
properties.reserve(2);
properties[U("Email")] = azure::storage::entity_property(U("Walter@contoso.com"));
properties[U("Phone")] = azure::storage::entity_property(U("425-555-0101"));
// Create the table operation that inserts the customer entity.
azure::storage::table_operation insert_operation = azure::storage::table_operation::insert_entity(customer1);
// Execute the insert operation.
azure::storage::table_result insert_result = table.execute(insert_operation);
Infoga en batch med entiteter
Du kan infoga en batch med entiteter i Table Storage i samma skrivåtgärd. Följande kod skapar ett table_batch_operation
objekt och lägger sedan till tre infogningsåtgärder i det. Varje infogningsåtgärd läggs till genom att ett nytt entitetsobjekt skapas, dess värden anges och sedan anropas insert
metoden för table_batch_operation
objektet för att associera entiteten med en ny infogningsåtgärd. Sedan anropar cloud_table.execute
koden för att köra åtgärden.
// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);
// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();
// Create a cloud table object for the table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));
// Define a batch operation.
azure::storage::table_batch_operation batch_operation;
// Create a customer entity and add it to the table.
azure::storage::table_entity customer1(U("Smith"), U("Jeff"));
azure::storage::table_entity::properties_type& properties1 = customer1.properties();
properties1.reserve(2);
properties1[U("Email")] = azure::storage::entity_property(U("Jeff@contoso.com"));
properties1[U("Phone")] = azure::storage::entity_property(U("425-555-0104"));
// Create another customer entity and add it to the table.
azure::storage::table_entity customer2(U("Smith"), U("Ben"));
azure::storage::table_entity::properties_type& properties2 = customer2.properties();
properties2.reserve(2);
properties2[U("Email")] = azure::storage::entity_property(U("Ben@contoso.com"));
properties2[U("Phone")] = azure::storage::entity_property(U("425-555-0102"));
// Create a third customer entity to add to the table.
azure::storage::table_entity customer3(U("Smith"), U("Denise"));
azure::storage::table_entity::properties_type& properties3 = customer3.properties();
properties3.reserve(2);
properties3[U("Email")] = azure::storage::entity_property(U("Denise@contoso.com"));
properties3[U("Phone")] = azure::storage::entity_property(U("425-555-0103"));
// Add customer entities to the batch insert operation.
batch_operation.insert_or_replace_entity(customer1);
batch_operation.insert_or_replace_entity(customer2);
batch_operation.insert_or_replace_entity(customer3);
// Execute the batch operation.
std::vector<azure::storage::table_result> results = table.execute_batch(batch_operation);
Några saker att tänka på när du använder batchåtgärder:
- Du kan utföra upp till 100
insert
,delete
,merge
,replace
,insert-or-merge
ochinsert-or-replace
åtgärder i valfri kombination i en enda batch. - En batchåtgärd kan ha en hämtningsåtgärd, om det är den enda åtgärden i batchen.
- Alla entiteter i samma batchåtgärd måste ha samma partitionsnyckel.
- Batchåtgärder är begränsade till en nyttolast på 4 MB.
Fråga efter och ändra entiteter
Hämta alla entiteter i en partition
Om du vill köra frågor mot en tabell för alla entiteter i en partition använder du ett table_query
objekt. I följande kodexempel anges ett filter för entiteter där Smith
är partitionsnyckeln. Det här exemplet skriver ut fälten för varje entitet i frågeresultatet till konsolen.
Kommentar
Dessa metoder stöds inte för närvarande för C++ i Azure Cosmos DB.
// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);
// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();
// Create a cloud table object for the table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));
// Construct the query operation for all customer entities where PartitionKey="Smith".
azure::storage::table_query query;
query.set_filter_string(azure::storage::table_query::generate_filter_condition(U("PartitionKey"), azure::storage::query_comparison_operator::equal, U("Smith")));
// Execute the query.
azure::storage::table_query_iterator it = table.execute_query(query);
// Print the fields for each customer.
azure::storage::table_query_iterator end_of_results;
for (; it != end_of_results; ++it)
{
const azure::storage::table_entity::properties_type& properties = it->properties();
std::wcout << U("PartitionKey: ") << it->partition_key() << U(", RowKey: ") << it->row_key()
<< U(", Property1: ") << properties.at(U("Email")).string_value()
<< U(", Property2: ") << properties.at(U("Phone")).string_value() << std::endl;
}
Frågan i det här exemplet returnerar alla entiteter som matchar filtervillkoren. Om du har stora tabeller och ofta behöver hämta tabellentiteterna rekommenderar vi att du lagrar dina data i Azure Storage-blobbar i stället.
Hämta ett intervall med enheter i en partition
Om du inte vill köra frågor mot alla entiteter i en partition kan du ange ett intervall. Kombinera partitionsnyckelfiltret med ett radnyckelfilter. I följande kodexempel används två filter för att hämta alla entiteter i partitionen Smith
där radnyckeln (förnamnet) börjar med en bokstav tidigare än E
i alfabetet och skriver sedan ut frågeresultatet.
Kommentar
Dessa metoder stöds inte för närvarande för C++ i Azure Cosmos DB.
// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);
// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();
// Create a cloud table object for the table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));
// Create the table query.
azure::storage::table_query query;
query.set_filter_string(azure::storage::table_query::combine_filter_conditions(
azure::storage::table_query::generate_filter_condition(U("PartitionKey"),
azure::storage::query_comparison_operator::equal, U("Smith")),
azure::storage::query_logical_operator::op_and,
azure::storage::table_query::generate_filter_condition(U("RowKey"), azure::storage::query_comparison_operator::less_than, U("E"))));
// Execute the query.
azure::storage::table_query_iterator it = table.execute_query(query);
// Loop through the results, displaying information about the entity.
azure::storage::table_query_iterator end_of_results;
for (; it != end_of_results; ++it)
{
const azure::storage::table_entity::properties_type& properties = it->properties();
std::wcout << U("PartitionKey: ") << it->partition_key() << U(", RowKey: ") << it->row_key()
<< U(", Property1: ") << properties.at(U("Email")).string_value()
<< U(", Property2: ") << properties.at(U("Phone")).string_value() << std::endl;
}
Hämta en enda entitet
Du kan skriva en fråga för att hämta en enda, specifik entitet. Följande kod använder table_operation::retrieve_entity
för att ange kunden Jeff Smith
. Den här metoden returnerar bara en entitet i stället för en samling, och det returnerade värdet finns i table_result
. Det snabbaste sättet att hämta en enskild entitet från tabelltjänsten är att ange både partitions- och radnycklar i en fråga.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);
// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();
// Create a cloud table object for the table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));
// Retrieve the entity with partition key of "Smith" and row key of "Jeff".
azure::storage::table_operation retrieve_operation = azure::storage::table_operation::retrieve_entity(U("Smith"), U("Jeff"));
azure::storage::table_result retrieve_result = table.execute(retrieve_operation);
// Output the entity.
azure::storage::table_entity entity = retrieve_result.entity();
const azure::storage::table_entity::properties_type& properties = entity.properties();
std::wcout << U("PartitionKey: ") << entity.partition_key() << U(", RowKey: ") << entity.row_key()
<< U(", Property1: ") << properties.at(U("Email")).string_value()
<< U(", Property2: ") << properties.at(U("Phone")).string_value() << std::endl;
Ersätta en entitet
Om du vill ersätta en entitet hämtar du den från Table Storage, ändrar entitetsobjektet och sparar sedan ändringarna till Table Storage igen. Följande kod ändrar en befintlig kunds telefonnummer och e-postadress. I stället för att anropa table_operation::insert_entity
använder table_operation::replace_entity
den här koden . Den här metoden gör att entiteten ersätts helt på servern, såvida inte entiteten på servern har ändrats sedan den hämtades. Om den har ändrats misslyckas åtgärden. Det här felet hindrar ditt program från att skriva över en ändring som gjorts mellan hämtningen och uppdateringen av en annan komponent. Rätt hantering av det här felet är att hämta entiteten igen, göra dina ändringar, om de fortfarande är giltiga och sedan utföra en annan table_operation::replace_entity
åtgärd.
// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);
// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();
// Create a cloud table object for the table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));
// Replace an entity.
azure::storage::table_entity entity_to_replace(U("Smith"), U("Jeff"));
azure::storage::table_entity::properties_type& properties_to_replace = entity_to_replace.properties();
properties_to_replace.reserve(2);
// Specify a new phone number.
properties_to_replace[U("Phone")] = azure::storage::entity_property(U("425-555-0106"));
// Specify a new email address.
properties_to_replace[U("Email")] = azure::storage::entity_property(U("JeffS@contoso.com"));
// Create an operation to replace the entity.
azure::storage::table_operation replace_operation = azure::storage::table_operation::replace_entity(entity_to_replace);
// Submit the operation to the Table service.
azure::storage::table_result replace_result = table.execute(replace_operation);
Infoga eller ersätta en entitet
table_operation::replace_entity
åtgärder misslyckas om entiteten har ändrats sedan den hämtades från servern. Dessutom måste du hämta entiteten från servern först för table_operation::replace_entity
att lyckas. Ibland vet du inte om entiteten finns på servern. De aktuella värden som lagras i den är irrelevanta eftersom uppdateringen bör skriva över dem alla. Använd en table_operation::insert_or_replace_entity
åtgärd för att uppnå det här resultatet. Den här åtgärden infogar entiteten om den inte finns. Åtgärden ersätter entiteten om den finns. I följande kodexempel hämtas kundentiteten för Jeff Smith
fortfarande, men den sparas sedan tillbaka till servern med hjälp table_operation::insert_or_replace_entity
av . Eventuella entitetsuppdateringar som görs mellan hämtnings- och uppdateringsåtgärden skrivs över.
// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);
// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();
// Create a cloud table object for the table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));
// Insert or replace an entity.
azure::storage::table_entity entity_to_insert_or_replace(U("Smith"), U("Jeff"));
azure::storage::table_entity::properties_type& properties_to_insert_or_replace = entity_to_insert_or_replace.properties();
properties_to_insert_or_replace.reserve(2);
// Specify a phone number.
properties_to_insert_or_replace[U("Phone")] = azure::storage::entity_property(U("425-555-0107"));
// Specify an email address.
properties_to_insert_or_replace[U("Email")] = azure::storage::entity_property(U("Jeffsm@contoso.com"));
// Create an operation to insert or replace the entity.
azure::storage::table_operation insert_or_replace_operation = azure::storage::table_operation::insert_or_replace_entity(entity_to_insert_or_replace);
// Submit the operation to the Table service.
azure::storage::table_result insert_or_replace_result = table.execute(insert_or_replace_operation);
Fråga en deluppsättning entitetsegenskaper
En fråga till en tabell kan hämta några få egenskaper från en entitet. Frågan i följande kod använder table_query::set_select_columns
metoden för att endast returnera e-postadresserna för entiteter i tabellen.
// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);
// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();
// Create a cloud table object for the table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));
// Define the query, and select only the Email property.
azure::storage::table_query query;
std::vector<utility::string_t> columns;
columns.push_back(U("Email"));
query.set_select_columns(columns);
// Execute the query.
azure::storage::table_query_iterator it = table.execute_query(query);
// Display the results.
azure::storage::table_query_iterator end_of_results;
for (; it != end_of_results; ++it)
{
std::wcout << U("PartitionKey: ") << it->partition_key() << U(", RowKey: ") << it->row_key();
const azure::storage::table_entity::properties_type& properties = it->properties();
for (auto prop_it = properties.begin(); prop_it != properties.end(); ++prop_it)
{
std::wcout << ", " << prop_it->first << ": " << prop_it->second.str();
}
std::wcout << std::endl;
}
Kommentar
Det är effektivare att köra frågor mot några få egenskaper från en entitet än att hämta alla egenskaper.
Ta bort innehåll
Ta bort en entitet
Du kan ta bort en entitet när du har hämtat den. När du har hämtat en entitet anropar table_operation::delete_entity
du med entiteten för att ta bort. Anropa cloud_table.execute
sedan metoden. Följande kod hämtar och tar bort en entitet med en partitionsnyckel Smith
och en radnyckel på Jeff
.
// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);
// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();
// Create a cloud table object for the table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));
// Create an operation to retrieve the entity with partition key of "Smith" and row key of "Jeff".
azure::storage::table_operation retrieve_operation = azure::storage::table_operation::retrieve_entity(U("Smith"), U("Jeff"));
azure::storage::table_result retrieve_result = table.execute(retrieve_operation);
// Create an operation to delete the entity.
azure::storage::table_operation delete_operation = azure::storage::table_operation::delete_entity(retrieve_result.entity());
// Submit the delete operation to the Table service.
azure::storage::table_result delete_result = table.execute(delete_operation);
Ta bort en tabell
I det sista kodexemplet tas en tabell bort från ett lagringskonto. En tabell som har tagits bort är inte tillgänglig för att återskapas under en tid efter borttagningen.
// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);
// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();
// Create a cloud table object for the table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));
// Delete the table if it exists
if (table.delete_table_if_exists())
{
std::cout << "Table deleted!";
}
else
{
std::cout << "Table didn't exist";
}
Felsökning
Om projektet får byggfel på grund av inkluderingsfilerna storage_account.h och table.h för Visual Studio Community Edition tar du bort växeln /permissive- compiler:
- Högerklicka på projektet i Solution Explorer och välj Egenskaper.
- Expandera Konfigurationsegenskaper i dialogrutan Egenskapssidor, expandera C/C++ och välj Språk.
- Ändra Conformance mode (Konformitetsläge) till Nej.
Nästa steg
Microsoft Azure Storage Explorer är en kostnadsfri, fristående app från Microsoft som gör det möjligt att arbeta visuellt med Azure Storage-data i Windows, macOS och Linux.
Följ de här länkarna om du vill veta mer om Azure Storage och API:et för tabell i Azure Cosmos DB: