Jak používat Azure Table Storage a Azure Cosmos DB pro tabulku s C++

PLATÍ PRO: Tabulka

Tip

Obsah v tomto článku se týká služby Azure Table Storage a Azure Cosmos DB for Table. Rozhraní API pro tabulku je prémiová nabídka pro úložiště tabulek, která nabízí tabulky optimalizované pro propustnost, globální distribuci a automatické sekundární indexy.

Tato příručka ukazuje běžné scénáře pomocí služby Azure Table Storage nebo Azure Cosmos DB for Table. Ukázky jsou napsané v C++ a využívají klientskou knihovnu služby Azure Storage pro C++. Tento článek pokrývá následující scénáře:

  • Vytvoření a odstranění tabulky
  • Práce s entitami tabulky

Poznámka:

Tato příručka je určená pro klientskou knihovnu služby Azure Storage pro C++ verze 1.0.0 nebo novější. Doporučená verze je Klientská knihovna služby Storage 2.2.0, která je dostupná pomocí NuGetu nebo GitHubu.

Vytvoření účtů

Vytvoření účtu služby Azure

S tabulkami můžete pracovat pomocí služby Azure Table Storage nebo Azure Cosmos DB. Další informace o rozdílech mezi nabídkami tabulek v těchto dvou službách najdete v přehledu rozhraní API pro tabulky. U služby, kterou budete používat, si budete muset vytvořit účet. Následující části ukazují, jak vytvořit úložiště Azure Table Storage i účet služby Azure Cosmos DB, ale můžete použít jenom jednu z nich.

Vytvoření účtu úložiště Azure

Nejjednodušší způsob, jak vytvořit účet úložiště Azure, je použití webu Azure Portal. Další informace naleznete v tématu Vytvoření účtu úložiště

Účet úložiště Azure můžete vytvořit také pomocí Azure PowerShellu nebo Azure CLI.

Pokud v tuto chvíli nechcete vytvořit účet úložiště, můžete také pomocí emulátoru úložiště Azure spustit a otestovat kód v místním prostředí. Další informace najdete v tématu Použití emulátoru úložiště Azure pro vývoj a testování.

Vytvoření účtu služby Azure Cosmos DB for Table

Pokyny k vytvoření účtu tabulky služby Azure Cosmos DB najdete v tématu Vytvoření databázového účtu.

Vytvoření aplikace C++

V této příručce použijete funkce úložiště z aplikace C++. Uděláte to tak, že nainstalujete klientskou knihovnu Azure Storage pro C++.

Pokud chcete nainstalovat klientskou knihovnu Azure Storage pro C++, použijte následující metody:

.\vcpkg.exe install azure-storage-cpp

Průvodce sestavením zdrojového kódu a exportem do Nugetu najdete v souboru README .

Konfigurace přístupu ke klientské knihovně služby Table Storage

Pokud chcete pro přístup k tabulkám použít rozhraní API služby Azure Storage, přidejte do horní části souboru C++ následující include příkazy:

#include <was/storage_account.h>
#include <was/table.h>

Klient služby Azure Storage nebo klient služby Azure Cosmos DB používá připojovací řetězec k ukládání koncových bodů a přihlašovacích údajů pro přístup ke službám pro správu dat. Při spuštění klientské aplikace musíte zadat připojovací řetězec úložiště nebo připojovací řetězec Azure Cosmos DB ve vhodném formátu.

Nastavení připojovacího řetězce služby Azure Storage

Tento příklad ukazuje, jak deklarovat statické pole pro uložení připojovací řetězec Azure Storage:

// 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>"));

Použijte název účtu úložiště pro <your_storage_account>. Pro <your_storage_account_key> použijte přístupový klíč pro účet úložiště uvedený na webu Azure Portal. Informace o účtech úložiště a přístupových klíčích najdete v tématu Vytvoření účtu úložiště.

Nastavení připojovacího řetězce služby Azure Cosmos DB

Tento příklad ukazuje, jak deklarovat statické pole pro uložení připojovací řetězec azure Cosmos DB:

// 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>"));

Použijte název účtu služby Azure Cosmos DB pro <your_cosmos_db_account>. Zadejte svůj primární klíč pro <your_cosmos_db_account_key>. Zadejte koncový bod uvedený na webu Azure Portal pro <your_cosmos_db_endpoint>.

K otestování aplikace v místním počítači s Windows můžete použít emulátor úložiště Azure, který je nainstalovaný se sadou Azure SDK. Emulátor úložiště je nástroj, který simuluje služby Azure Blob, Queue a Table, které jsou k dispozici na místním vývojovém počítači. Následující příklad ukazuje, jak deklarovat statické pole pro uložení připojovací řetězec do emulátoru místního úložiště:

// Define the connection string with Azure Storage Emulator.
const utility::string_t storage_connection_string(U("UseDevelopmentStorage=true;"));  

Pokud chcete spustit emulátor služby Azure Storage, vyberte na ploše Windows tlačítko Start nebo klíč Windows. Zadejte a spusťte emulátor úložiště Microsoft Azure. Další informace najdete v tématu Použití emulátoru úložiště Azure pro vývoj a testování.

Načtení připojovacího řetězce

Třídu můžete použít cloud_storage_account k reprezentaci informací o účtu úložiště. K načtení informací o účtu úložiště z připojovací řetězec úložiště použijte metoduparse.

// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

V dalším kroku získáte odkaz na cloud_table_client třídu. Tato třída umožňuje získat referenční objekty pro tabulky a entity uložené ve službě Table Storage. Následující kód vytvoří cloud_table_client objekt pomocí objektu účtu úložiště, který jste získali dříve:

// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();

Vytvoření a přidání entit do tabulky

Vytvoření tabulky

Objekt cloud_table_client umožňuje získat referenční objekty pro tabulky a entity. Následující kód vytvoří cloud_table_client objekt a použije ho k vytvoření nové tabulky.

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

Přidání entity do tabulky

Pokud chcete přidat entitu do tabulky, vytvořte nový table_entity objekt a předejte ji .table_operation::insert_entity Následující kód používá jméno zákazníka jako klíč řádku a jeho příjmení jako klíč oddílu. Společně pak klíč oddílu a řádku entity jednoznačně identifikují entitu v tabulce. Entity se stejným klíčem oddílu je možné dotazovat rychleji než entity s různými klíči oddílu. Použití různorodých klíčů oddílů umožňuje větší škálovatelnost paralelních operací. Další informace najdete v tématu Kontrolní seznam výkonu a škálovatelnosti služby Microsoft Azure Storage.

Následující kód vytvoří novou instanci table_entity s některými zákaznickými daty, která se mají uložit. Kód dále volá table_operation::insert_entity vytvoření objektu table_operation pro vložení entity do tabulky a přidruží k ní novou entitu tabulky. Nakonec kód volá metodu execute objektu cloud_table . Nová table_operation odešle požadavek službě Table Service, aby do tabulky vložil novou entitu people zákazníka.

// 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);

Vložení dávky entit

V rámci jedné operace zápisu můžete do služby Table Storage vložit dávku entit. Následující kód vytvoří table_batch_operation objekt a pak do něj přidá tři operace vložení. Každá operace vložení se přidá vytvořením nového objektu entity, nastavením jeho hodnot a následným voláním insert metody objektu table_batch_operation pro přidružení entity k nové operaci vložení. Potom volání cloud_table.execute kódu ke spuštění operace.

// 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);

O dávkových operacích byste měli vědět několik věcí:

  • V jedné dávce můžete provádět až 100 insert, delete, replacemerge, insert-or-merge, a insert-or-replace operace v libovolné kombinaci.
  • Dávková operace může mít operaci načtení, pokud se jedná o jedinou operaci v dávce.
  • Všechny entity v jedné dávkové operaci musí mít stejný klíč oddílu.
  • Velikost datové části dávkové operace je omezená na 4 MB.

Dotazování a úpravy entit

Načtení všech entit v oddílu

Pokud chcete dotazovat tabulku pro všechny entity v oddílu, použijte table_query objekt. Následující příklad kódu určuje filtr pro entity, kde Smith je klíč oddílu. Tento příklad zobrazí pole každé entity z výsledků dotazu z konzoly.

Poznámka:

Tyto metody se ve službě Azure Cosmos DB v současné době nepodporují pro C++.

// 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;
}  

Dotaz v tomto příkladu vrátí všechny entity, které splňují kritéria filtru. Pokud máte velké tabulky a potřebujete často stahovat entity tabulky, doporučujeme místo toho ukládat data v objektech blob v úložišti Azure.

Načtení rozsahu entit v oddílu

Pokud nechcete dotazovat všechny entity v oddílu, můžete zadat rozsah. Zkombinujte filtr klíče oddílu s filtrem klíče řádku. Následující příklad kódu používá dva filtry k získání všech entit v oddílu Smith , kde klíč řádku (jméno) začíná písmenem dřívějším než E v abecedě, a pak vytiskne výsledky dotazu.

Poznámka:

Tyto metody se ve službě Azure Cosmos DB v současné době nepodporují pro C++.

// 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;
}  

Načtení jedné entity

Můžete napsat dotaz pro načtení jedné konkrétní entity. Následující kód používá table_operation::retrieve_entity k určení zákazníka Jeff Smith. Tato metoda vrátí pouze jednu entitu, nikoli kolekci, a vrácená hodnota je v table_result. Určení jak klíčů oddílu, tak klíčů řádků v dotazu představuje nejrychlejší způsob, jak načíst jednu entitu ze služby Table service.

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;

Nahrazení entity

Pokud chcete entitu nahradit, načtěte ji ze služby Table Storage, upravte objekt entity a pak uložte změny zpět do služby Table Storage. Následující kód změní telefonní číslo a e-mailovou adresu stávajícího zákazníka. Místo volání table_operation::insert_entitytento kód používá table_operation::replace_entity. Tento přístup způsobí, že se entita na serveru plně nahradí, pokud se entita na serveru od načtení nezměnila. Pokud došlo ke změně, operace selže. Toto selhání brání vaší aplikaci v přepsání změny provedené mezi načtením a aktualizací jinou komponentou. Správné zpracování tohoto selhání spočívá v opětovném načtení entity, provedení změn, pokud je stále platné, a následné provedení jiné table_operation::replace_entity operace.

// 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);

Vložení nebo nahrazení entity

table_operation::replace_entity operace selžou, pokud se entita od načtení ze serveru změnila. Kromě toho musíte nejprve načíst entitu ze serveru, aby table_operation::replace_entity byla úspěšná. Někdy nevíte, jestli entita existuje na serveru. Aktuální hodnoty uložené v ní jsou irelevantní, protože vaše aktualizace by je měla přepsat všechny. K dosažení tohoto výsledku table_operation::insert_or_replace_entity použijte operaci. Tato operace vloží entitu, pokud neexistuje. Operace nahradí entitu, pokud existuje. V následujícím příkladu kódu je entita zákazníka stále Jeff Smith načtena, ale pak je uložena zpět na server pomocí table_operation::insert_or_replace_entity. Jakékoli aktualizace provedené v entitě mezi operací načtení a aktualizace se přepíšou.

// 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);

Dotaz na podmnožinu vlastností entity

Dotaz na tabulku dokáže z entity načíst pouze několik vlastností. Dotaz v následujícím kódu používá metodu table_query::set_select_columns k vrácení pouze e-mailových adres entit v tabulce.

// 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;
}

Poznámka:

Dotazování několika vlastností entity je efektivnější operace než načítání všech vlastností.

Odstranit obsah

Odstranění entity

Entitu můžete po načtení odstranit. Po načtení entity zavolejte table_operation::delete_entity s entitou, která se má odstranit. Pak zavolejte metodu cloud_table.execute . Následující kód načte a odstraní entitu s klíčem Smith oddílu a klíčem Jeffřádku .

// 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);  

Odstraní tabulku

Následující příklad kódu nakonec odstraní tabulku z účtu úložiště. Po odstranění není k dispozici tabulka, která byla odstraněna, se po odstranění znovu vytvoří.

// 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";
}

Řešení problému

Pokud v sadě Visual Studio Community Edition dojde k chybám sestavení z důvodu zahrnutí souborů storage_account.h a table.h, odeberte přepínač kompilátoru /permissive- :

  1. V Průzkumníku řešení klikněte pravým tlačítkem na váš projekt a vyberte Vlastnosti.
  2. V dialogovém okně Stránky vlastností rozbalte Vlastnosti konfigurace, pak rozbalte C/C++ a vyberte Jazyk.
  3. Nastavte Režim přizpůsobení na hodnotu Ne.

Další kroky

Microsoft Azure Storage Explorer je bezplatná samostatná aplikace od Microsoftu, která umožňuje vizuálně pracovat s daty Azure Storage ve Windows, macOS a Linuxu.

Další informace o službě Azure Storage a rozhraní API pro tabulky ve službě Azure Cosmos DB najdete na těchto odkazech: