Поделиться через


Запрос данных Azure Cosmos DB с помощью бессерверного пула SQL

Бессерверный пул SQL позволяет анализировать данные в контейнерах Azure Cosmos DB, включенных с помощью Azure Synapse Link, практически в реальном времени и без влияния на производительность транзакционных рабочих нагрузок. Он предлагает знакомый синтаксис Transact-SQL (T-SQL) для запроса данных из аналитического хранилища и интегрированного подключения к широкому спектру средств бизнес-аналитики (BI) и нерегламентированных средств запросов через интерфейс T-SQL.

For querying Azure Cosmos DB, the full SELECT surface area is supported through the OPENROWSET function, which includes most SQL functions and operators. Вы также можете сохранять результаты запроса, считывающего данные из Azure Cosmos DB, вместе с данными в Azure Blob Storage или Azure Data Lake Storage, с помощью команды create external table as select (CETAS). В настоящее время нельзя сохранять результаты запросов бессерверного пула SQL в Azure Cosmos DB с помощью CETAS.

В этой статье объясняется, как написать запрос с бессерверным пулом SQL, который запрашивает данные из контейнеров Azure Cosmos DB, включенных в Azure Synapse Link. Затем в этом учебнике вы можете просмотреть дополнительную информацию о создании представлений бессерверных пулов SQL в контейнерах Azure Cosmos DB и их подключении к моделям Power BI. В этом учебнике используется контейнер с четко определенной схемой Azure Cosmos DB. Вы также можете ознакомиться с модулем Learn о том, как запрашивать Azure Cosmos DB с помощью SQL Serverless для Azure Synapse Analytics.

Предварительные условия

  • Make sure that you prepare the analytical store:
  • Убедитесь, что вы применили все рекомендации, такие как:
    • Убедитесь, что аналитическое хранилище Azure Cosmos DB находится в том же регионе, что и бессерверный пул SQL.
    • Убедитесь, что клиентское приложение (Power BI, служба анализа) находится в том же регионе, что и бессерверный пул SQL.
    • Если вы возвращаете большой объем данных (более 80 ГБ), рассмотрите возможность использования слоя кэширования, например, используя службы Analysis Services, и загрузите партиции меньше 80 ГБ в модель служб Analysis Services.
    • Если вы фильтруете данные с помощью строковых столбцов, убедитесь, что используете функцию OPENROWSET с явным предложением WITH, у которого имеются наименьшие возможные типы. Например, не используйте VARCHAR(1000) , если вы знаете, что свойство имеет до пяти символов.

Обзор

Бессерверный пул SQL позволяет запрашивать аналитическое хранилище Azure Cosmos DB с помощью функции OPENROWSET.

OPENROWSET( 
       'CosmosDB',
       '<SQL connection string for Azure Cosmos DB>',
       <other parameters>
    )  [ < with clause > ] AS alias

The SQL connection string for Azure Cosmos DB includes the following components:

  • account - The name of the Azure Cosmos DB account you are targeting.
  • database - The container name, specified without quotation marks in the OPENROWSET syntax. If the container name contains special characters (for example, a dash -), it should be enclosed in square brackets ([]).
  • region (optional) - The region of your Cosmos DB analytical storage. Если этот параметр опущен, используется основной регион контейнера.
  • endpoint (optional) - required if your Cosmos DB account does not follow the standard *.documents.azure.com format.

Внимание

The endpoint parameter is needed for accounts that don't match the standard *.documents.azure.com format. For example, if your Azure Cosmos DB account ends with .documents.azure.us, make sure that you add endpoint=<account name>.documents.azure.us in the connection string.

These properties can be identified from the standard Cosmos DB connection string, for example:

AccountEndpoint=https://<database account name>.documents.azure.com:443/;AccountKey=<database account master key>;

The SQL connection string can be formatted as follows:

'account=<database account name>;database=<database name>;region=<region name>'

This connection string does not include the authentication information required to connect to Cosmos DB analytical storage. Additional information is needed depending on the type of authentication used:

  • If OPENROWSET uses workspace managed identity to access the analytical store, you should add the AuthType property.
  • If OPENROWSET uses an inline account key, you should add the key property. This allows you to query Azure Cosmos DB collections without needing to prepare credentials.
  • Instead of including authentication information in the connection string, OPENROWSET can reference a credential that contains the Azure Cosmos DB account key. This approach can be used to create views on Azure Cosmos DB collections.

These options are described below.

The serverless SQL pool enables you to query Cosmos DB Analytical storage and authenticate with the original Cosmos DB account key or to allow Synapse managed identity to access the Cosmos DB Analytical storage. You can use the following syntax in this scenario:

OPENROWSET( 
       'CosmosDB',
       '<SQL connection string for Azure Cosmos DB>',
       <Container name>
    )  [ < with clause > ] AS alias

In addition to the common properties in the SQL connection string that are described above (account, database, region, and endpoint), you need to add one of the following options:

  • AuthType - set this option to ManagedIdentity if accessing Cosmos DB using the Synapse workspace Managed Identity.
  • key - The master key for accessing Cosmos DB data, used if not utilizing the Synapse workspace managed identity.

The examples of connection strings are shown in the following table:

Тип аутентификации Connection string
Cosmos DB account master key account=<account name>;database=<db name>;region=<region name>;key=<account master key>
Synapse workspace managed identity account=<account name>;database=<db name>;region=<region name>;authtype=ManagedIdentity

Внимание

Убедитесь, что используются некоторые параметры сортировки базы данных UTF-8, например, Latin1_General_100_CI_AS_SC_UTF8, так как строковые значения в аналитическом хранилище Azure Cosmos DB представлены в кодировке UTF-8. Несоответствие кодировки текста в файле и параметров сортировки может привести к непредвиденным ошибкам преобразования текста. Параметры сортировки по умолчанию для текущей базы данных легко изменить с помощью инструкции T-SQL alter database current collate Latin1_General_100_CI_AI_SC_UTF8.

Примечание.

Бессерверный пул SQL не поддерживает запросы транзакционного хранилища Azure Cosmos DB.

Пример набора данных

The examples in this article are based on data from the European Center for Disease Prevention and Control (ECDC) COVID-19 Cases and COVID-19 Open Research Dataset (CORD-19).

На этих страницах можно увидеть лицензию и структуру данных. Вы также можете скачать примеры данных для наборов данных ECDC и CORD-19.

Для работы с этой статьей, показывающей, как выполнять запросы данных Azure Cosmos DB с помощью бессерверного пула SQL, вам потребуются следующие ресурсы:

  • Учетная запись базы данных Azure Cosmos DB, для которой включена поддержка Azure Synapse Link
  • База данных Azure Cosmos DB с именем covid
  • Два контейнера Azure Cosmos DB с именем Ecdc и Cord19 загружены с помощью предыдущих примеров наборов данных

Обратите внимание, что это подключение не гарантирует производительность, так как эта учетная запись может находиться в удаленном регионе по сравнению с конечной точкой Synapse SQL.

Исследование Azure Cosmos DB данных с помощью автоматического вывода схемы

Самый простой способ исследовать данные в Azure Cosmos DB — использовать функцию автоматического вывода схемы. By omitting the WITH clause from the OPENROWSET statement, you can instruct the serverless SQL pool to autodetect (infer) the schema of the analytical store of the Azure Cosmos DB container.

Внимание

В скрипте замените эти значения собственными значениями:

  • your-cosmosdb — имя учетной записи Cosmos DB
  • yourcosmosdbkey — ключ учетной записи Cosmos DB
SELECT TOP 10 *
FROM OPENROWSET( 
       'CosmosDB',
       'Account=your-cosmosdb;Database=covid;Key=yourcosmosdbkey',
       Ecdc) as documents

В предыдущем примере мы дали бессерверному пулу SQL указание подключиться к базе данных covid в учетной записи Azure Cosmos DB MyCosmosDbAccount, прошедшей проверку подлинности с помощью ключа Azure Cosmos DB (фиктивного в предыдущем примере). Затем мы обратились к аналитическому хранилищу контейнера Ecdc в регионе West US 2. Так как нет проекции определенных свойств, OPENROWSET функция возвращает все свойства из элементов Azure Cosmos DB.

Если исходить из предположения, что элементы в контейнере Azure Cosmos DB имеют свойства date_rep, cases и geo_id, то результаты запроса будут следующие.

date_rep случаи гео_идентификатор
2020-08-13 254 RS
2020-08-12 235 RS
2020-08-11 163 RS

Если нужно исследовать данные из другого контейнера в той же базе данных Azure Cosmos DB, то можно использовать ту же строку подключения и сослаться на необходимый контейнер в третьем параметре:

SELECT TOP 10 *
FROM OPENROWSET( 
       'CosmosDB',
       'Account=your-cosmosdb;Database=covid;Key=yourcosmosdbkey',
       Cord19) as cord19

Явное указание схемы

While automatic schema inference capability in OPENROWSET provides a simple, easy-to-use experience, your business scenarios might require you to explicitly specify the schema to read-only relevant properties from the Azure Cosmos DB data.

Функция OPENROWSET позволяет явно указать свойства, которые необходимо прочитать из данных в контейнере и указать их типы данных.

Предположим, что мы импортировали в Azure Cosmos DB некоторые данные из набора данных ECDC COVID со следующей структурой:

{"date_rep":"2020-08-13","cases":254,"countries_and_territories":"Serbia","geo_id":"RS"}
{"date_rep":"2020-08-12","cases":235,"countries_and_territories":"Serbia","geo_id":"RS"}
{"date_rep":"2020-08-11","cases":163,"countries_and_territories":"Serbia","geo_id":"RS"}

Эти плоские документы JSON в Azure Cosmos DB могут быть представлены в виде набора строк и столбцов в Synapse SQL. Функция OPENROWSET позволяет указать подмножество свойств, которые требуется прочитать, и точные типы столбцов в предложении WITH :

SELECT TOP 10 *
FROM OPENROWSET(
      'CosmosDB',
      'Account=your-cosmosdb;Database=covid;Key=yourcosmosdbkey',
       Ecdc
    ) with ( date_rep varchar(20), cases bigint, geo_id varchar(6) ) as rows

Результат этого запроса может выглядеть, как показано в следующей таблице:

date_rep случаи гео_идентификатор
2020-08-13 254 RS
2020-08-12 235 RS
2020-08-11 163 RS

Дополнительные сведения о типах SQL, которые должны использоваться для значений Azure Cosmos DB, см. в статье Azure Cosmos DB с сопоставлениями типов SQL в конце этой статьи.

Создать представление

Creating views in the master or default databases isn't recommended or supported. Поэтому вам необходимо создать пользовательскую базу данных для ваших представлений.

Once you identify the schema, you can prepare a view on top of your Azure Cosmos DB data. You should place your Azure Cosmos DB account key in a separate credential and reference this credential from OPENROWSET function. Don't keep your account key in the view definition.

CREATE CREDENTIAL MyCosmosDbAccountCredential
WITH IDENTITY = 'SHARED ACCESS SIGNATURE', SECRET = 'yourcosmosdbkey';
GO
CREATE OR ALTER VIEW Ecdc
AS SELECT *
FROM OPENROWSET(
      PROVIDER = 'CosmosDB',
      CONNECTION = 'Account=your-cosmosdb;Database=covid',
      OBJECT = 'Ecdc',
      SERVER_CREDENTIAL = 'MyCosmosDbAccountCredential'
    ) with ( date_rep varchar(20), cases bigint, geo_id varchar(6) ) as rows

Не используйте OPENROWSET без явно определенной схемы, так как это может повлиять на производительность. Убедитесь, что для столбцов используются наименьшие возможные размеры (например VARCHAR(100) , вместо по умолчанию VARCHAR(8000)). You should use some UTF-8 collation as default database collation or set it as explicit column collation to avoid a UTF-8 conversion issue. Параметры сортировки Latin1_General_100_BIN2_UTF8 обеспечивают лучшую производительность при фильтрации данных с использованием нескольких строковых столбцов.

При выполнении запроса представления вы можете столкнуться с ошибками или неожиданными результатами. The view references columns or objects were probably modified or no longer exists. Необходимо вручную настроить определение представления, чтобы выровнять изменения базовой схемы. Помните, что это может произойти как при использовании автоматического вывода схемы в представлении, так и при явном указании схемы.

Query nested objects

С помощью Azure Cosmos DB можно представлять более сложные модели данных, составляя их как вложенные объекты или массивы. Функция автосинхронизации Azure Synapse Link для Azure Cosmos DB управляет представлением схемы в готовом аналитическом хранилище, что включает обработку вложенных типов данных, обеспечивающую выполнение расширенных запросов из бессерверного пула SQL.

Например, набор данных CORD-19 содержит документы JSON, имеющие следующую структуру:

{
    "paper_id": <str>,                   # 40-character sha1 of the PDF
    "metadata": {
        "title": <str>,
        "authors": <array of objects>    # list of author dicts, in order
        ...
     }
     ...
}

Вложенные объекты и массивы в Azure Cosmos DB представлены в результатах запроса в виде строк JSON, когда функция OPENROWSET считывает их. При использовании предложения WITH можно указать пути к вложенным значениям в объектах:

SELECT TOP 10 *
FROM OPENROWSET( 
       'CosmosDB',
       'Account=your-cosmosdb;Database=covid;Key=yourcosmosdbkey',
       Cord19)
WITH (  paper_id    varchar(8000),
        title        varchar(1000) '$.metadata.title',
        metadata     varchar(max),
        authors      varchar(max) '$.metadata.authors'
) AS docs;

Результат этого запроса может выглядеть, как показано в следующей таблице:

идентификатор_документа название метаданные авторы
bb11206963e831f… Supplementary Information An eco-epidemi… {"title":"Supplementary Informati… [{"first":"Julien","last":"Mélade","suffix":"","af…
bb1206963e831f1… The Use of Convalescent Sera in Immune-E… {"title":"The Use of Convalescent… [{"first":"Antonio","last":"Lavazza","suffix":"", …
bb378eca9aac649… Tylosema esculentum (Marama) Tuber and B… {"title":"Tylosema esculentum (Ma… [{"first":"Walter","last":"Chingwaru","suffix":"",…

Дополнительные сведения см. в статье "Анализ сложных типов данных в Azure Synapse Analytics" или "Запрос вложенных типов в файлах Parquet и JSON с помощью бессерверного пула SQL".

Внимание

Если вы видите в тексте неожиданные символы, например, MÃÂ&copy;lade вместо Mélade, это означает, что в вашей базе данных не установлена сортировка UTF-8. Параметры сортировки базы данных можно изменить на параметры сортировки UTF-8 с помощью инструкции SQL, напримерALTER DATABASE MyLdw COLLATE LATIN1_GENERAL_100_CI_AS_SC_UTF8.

Преобразование вложенных массивов в плоскую структуру

Azure Cosmos DB data might have nested subarrays like the author's array from a CORD-19 dataset:

{
    "paper_id": <str>,                      # 40-character sha1 of the PDF
    "metadata": {
        "title": <str>,
        "authors": [                        # list of author dicts, in order
            {
                "first": <str>,
                "middle": <list of str>,
                "last": <str>,
                "suffix": <str>,
                "affiliation": <dict>,
                "email": <str>
            },
            ...
        ],
        ...
}

В некоторых случаях может потребоваться присоединить свойства из верхнего элемента (метаданных) ко всем элементам массива (авторов). Бессерверный пул SQL позволяет распрямить вложенные структуры, применяя функцию OPENJSON к вложенному массиву.

SELECT
    *
FROM
    OPENROWSET(
      'CosmosDB',
      'Account=your-cosmosdb;Database=covid;Key=yourcosmosdbkey',
       Cord19
    ) WITH ( title varchar(1000) '$.metadata.title',
             authors varchar(max) '$.metadata.authors' ) AS docs
      CROSS APPLY OPENJSON ( authors )
                  WITH (
                       first varchar(50),
                       last varchar(50),
                       affiliation nvarchar(max) as json
                  ) AS a

Результат этого запроса может выглядеть, как показано в следующей таблице:

название авторы first last принадлежность
Supplementary Information An eco-epidemi… [{"first":"Julien","last":"Mélade","suffix":"","affiliation":{"laboratory":"Centre de Recher… Жюльен Mélade {"laboratory":"Centre de Recher…
Supplementary Information An eco-epidemi… [{"first":"Nicolas","last":"4#","suffix":"","affiliation":{"laboratory":"","institution":"U… Nicolas #4 {"laboratory":"","institution":"U…
Supplementary Information An eco-epidemi… [{"first":"Beza","last":"Ramazindrazana","suffix":"","affiliation":{"laboratory":"Centre de Recher… Beza Ramazindrazana {"laboratory":"Centre de Recher…
Supplementary Information An eco-epidemi… [{"first":"Olivier","last":"Flores","suffix":"","affiliation":{"laboratory":"UMR C53 CIRAD, … Olivier Flores {"laboratory":"UMR C53 CIRAD, …

Внимание

Если вы видите в тексте неожиданные символы, например, MÃÂ&copy;lade вместо Mélade, это означает, что в вашей базе данных не установлена сортировка UTF-8. Параметры сортировки базы данных можно изменить на параметры сортировки UTF-8 с помощью инструкции SQL, напримерALTER DATABASE MyLdw COLLATE LATIN1_GENERAL_100_CI_AS_SC_UTF8.

Azure Cosmos DB to SQL type mappings

Транзакционное хранилище Azure Cosmos DB не зависит от схемы, однако аналитическое хранилище схематизировано для оптимизации производительности аналитических запросов. Благодаря возможности автосинхронизации Azure Synapse Link Azure Cosmos DB управляет представлением схемы в готовом аналитическом хранилище, в том числе обработкой вложенных типов данных. Бессерверный пул SQL запрашивает аналитическое хранилище, поэтому важно понимать, как сопоставить типы входных данных Azure Cosmos DB с типами данных SQL.

Azure Cosmos DB accounts of SQL (Core) API support JSON property types of number, string, Boolean, null, nested object, or array. Нужно выбрать типы SQL, соответствующие этим типам JSON, если вы используете предложение WITH в функции OPENROWSET. В следующей таблице показаны типы столбцов SQL, которые следует использовать для различных типов свойств в Azure Cosmos DB.

Azure Cosmos DB property type Тип столбца SQL
Boolean bit
Integer bigint
Десятичное число float
String varchar (сопоставление базы данных UTF-8)
Дата и время (строка в формате ISO) varchar(30)
Дата и время (метка времени UNIX) bigint
Null any SQL type
Вложенный объект или массив varchar(max) (сравнение базы данных UTF-8), сериализован как текст JSON

Схема полной точности

Схема полной точности Azure Cosmos DB записывает как значения, так и их типы наилучшего соответствия для каждого свойства в контейнере. Функция OPENROWSET в контейнере со схемой полной точности предоставляет как тип, так и фактическое значение в каждой ячейке. Let's assume that the following query reads the items from a container with full fidelity schema:

SELECT *
FROM OPENROWSET(
      'CosmosDB',
      'account=MyCosmosDbAccount;database=covid;region=westus2;key=C0Sm0sDbKey==',
       Ecdc
    ) as rows

Результат этого запроса возвращает типы и значения, отформатированные как текст JSON:

date_rep случаи гео_идентификатор
{"date":"2020-08-13"} {"int32":"254"} {"string":"RS"}
{"date":"2020-08-12"} {"int32":"235"} {"string":"RS"}
{"date":"2020-08-11"} {"int32":"316"} {"string":"RS"}
{"date":"2020-08-10"} {"int32":"281"} {"string":"RS"}
{"date":"2020-08-09"} {"int32":"295"} {"string":"RS"}
{"string":"2020/08/08"} {"int32":"312"} {"string":"RS"}
{"date":"2020-08-07"} {"float64":"339.0"} {"string":"RS"}

Для каждого значения можно увидеть тип, определенный в элементе контейнера Azure Cosmos DB. Большинство значений для свойства date_rep содержат значения date, но некоторые из них неправильно сохранены как строки в Azure Cosmos DB. Полная схема точности возвращает как правильно типизированные date значения, так и неправильно отформатированные string значения.

Число случаев хранится в виде int32 значения, но есть одно значение, введенное как десятичное число. Это значение имеет тип float64. При наличии некоторых значений, превышающих максимальное число int32, они будут храниться как значения с типом int64. Все значения geo_id в этом примере хранятся в виде типов string.

Внимание

Функция OPENROWSET без предложения WITH предоставляет и значения с ожидаемыми типами, и значения с неправильно указанными типами. Эта функция предназначена для просмотра данных, а не для создания отчетов. Не следует анализировать значения JSON, возвращаемые этой функцией, для построения отчетов. Для создания отчетов используйте явный оператор WITH. Следует удалить значения, имеющие неверные типы в контейнере Azure Cosmos DB, чтобы применить исправления в аналитическом хранилище полной точности.

To query Azure Cosmos DB for MongoDB accounts, you can learn more about the full fidelity schema representation in the analytical store and the extended property names to be used in What is Azure Cosmos DB Analytical Store?.

Query items with full fidelity schema

При запросе схемы полной точности необходимо явно указать тип SQL и ожидаемый тип свойств Azure Cosmos DB в предложении WITH.

В следующем примере предполагается, что string это правильный тип для geo_id свойства и int32 является правильным типом для cases свойства:

SELECT geo_id, cases = SUM(cases)
FROM OPENROWSET(
      'CosmosDB'
      'account=MyCosmosDbAccount;database=covid;region=westus2;key=C0Sm0sDbKey==',
       Ecdc
    ) WITH ( geo_id VARCHAR(50) '$.geo_id.string',
             cases INT '$.cases.int32'
    ) as rows
GROUP BY geo_id

Значения для geo_id и cases с другими типами возвращаются как значения NULL. Этот запрос ссылается только на cases с указанным типом в выражении (cases.int32).

Если имеются значения с другими типами (cases.int64, cases.float64), которые нельзя очистить в контейнере Azure Cosmos DB, то нужно явно указать их в предложении WITH и объединить результаты. В следующем запросе суммируются значения int32, int64 и float64, хранящиеся в столбце cases:

SELECT geo_id, cases = SUM(cases_int) + SUM(cases_bigint) + SUM(cases_float)
FROM OPENROWSET(
      'CosmosDB',
      'account=MyCosmosDbAccount;database=covid;region=westus2;key=C0Sm0sDbKey==',
       Ecdc
    ) WITH ( geo_id VARCHAR(50) '$.geo_id.string', 
             cases_int INT '$.cases.int32',
             cases_bigint BIGINT '$.cases.int64',
             cases_float FLOAT '$.cases.float64'
    ) as rows
GROUP BY geo_id

В этом примере количество случаев сохраняется как значения int32, int64 или float64. Все значения должны быть извлечены для вычисления количества случаев в каждой стране или регионе.

Устранение неполадок

Просмотрите страницу самопомощи, чтобы найти известные проблемы или шаги по устранению неполадок, которые могут помочь решить потенциальные проблемы с запросами Azure Cosmos DB.