使用 Synapse SQL 查询 Cosmos DB

已完成

除了使用 Spark 池,还可以使用 Azure Synapse Analytics 中的内置无服务器 SQL 池查询 Azure Cosmos DB 分析容器。 为此,可以使用 OPENROWSET SQL 函数连接到 Azure Cosmos DB 数据库的链接服务。

将 OPENROWSET 与身份验证密钥配合使用

默认情况下,对 Azure Cosmos DB 帐户的访问通过身份验证密钥进行身份验证。 可以将此密钥用作 OPENROWSET 语句中连接字符串的一部分,通过 SQL 池的链接服务进行连接,如以下示例所示:

SELECT *
FROM OPENROWSET(​
    'CosmosDB',
    'Account=my-cosmos-db;Database=my-db;Key=abcd1234....==',
    [my-container]) AS products_data

提示

可以在 Azure 门户中的“密钥”页上找到 Cosmos DB 帐户的主密钥和辅助密钥。

此查询的结果可能如下所示,包括来自 Azure Cosmos DB 容器中的项的元数据和应用程序定义的字段:

_rid _ts productID productName id _etag
mjMaAL...== 1655414791 123 小组件 7248f072-11c3-42b1-a368-... 54004b09-0000-2300-...
mjMaAL...== 1655414829 124 Wotsit dc33131c-65c7-421a-a0f7-... 5400ca09-0000-2300-...
mjMaAL...== 1655414835 125 Thingumy ce22351d-78c7-428a-a1h5-... 5400ca09-0000-2300-...
... ... ... ... ... ...

数据从分析存储中检索,查询不会影响操作存储。

将 OPENROWSET 与凭据配合使用

可以定义封装 Cosmos DB 帐户的身份验证信息的凭据,并在后续查询中使用该凭据,而不是在每次调用 OPENROWSET 时包括身份验证密钥。 若要创建凭据,请使用 CREATE CREDENTIAL 语句,如以下示例所示:

 CREATE CREDENTIAL my_credential
 WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
 SECRET = 'abcd1234....==';

凭据准备就绪后,可以在 OPENROWSET 函数中使用它,如下所示:

SELECT *
FROM OPENROWSET(​PROVIDER = 'CosmosDB',
                CONNECTION = 'Account=my-cosmos-db;Database=my-db',
                OBJECT = 'my-container',
                SERVER_CREDENTIAL = 'my_credential'
) AS products_data

结果再次包括分析存储中的元数据和应用程序定义的字段:

_rid _ts productID productName id _etag
mjMaAL...== 1655414791 123 小组件 7248f072-11c3-42b1-a368-... 54004b09-0000-2300-...
mjMaAL...== 1655414829 124 Wotsit dc33131c-65c7-421a-a0f7-... 5400ca09-0000-2300-...
mjMaAL...== 1655414835 125 Thingumy ce22351d-78c7-428a-a1h5-... 5400ca09-0000-2300-...
... ... ... ... ... ...

指定架构

OPENROWSET 语法包含一个 WITH 子句,可用于为生成的行集定义架构。 可以使用此语法指定各个字段并分配数据类型,如以下示例所示:

 SELECT *
 FROM OPENROWSET(​PROVIDER = 'CosmosDB',
                 CONNECTION = 'Account=my-cosmos-db;Database=my-db',
                 OBJECT = 'my-container',
                 SERVER_CREDENTIAL = 'my_credential'
 )
 WITH (
    productID INT,
    productName VARCHAR(20)
 ) AS products_data

在这种情况下,假设分析存储中的字段包括 productID 和 productName,生成的行集将类似于下表:

productID productName
123 小组件
124 Wotsit
125 Thingumy
... ...

当然,可以在 SELECT 子句中指定单个列名(例如 SELECT productID, productName ...),因此这种指定单个列的功能可能看起来使用受限。 但是,请考虑存储在操作存储中的源 JSON 文档包含多级字段的情况,如以下示例所示:

{
    "productID": 126,
    "productName": "Sprocket",
    "supplier": {
        "supplierName": "Contoso",
        "supplierPhone": "555-123-4567"
    }
    "id": "62588f072-11c3-42b1-a738-...",
    "_rid": "mjMaAL...==",
    ...
}

WITH 子句支持包含显式 JSON 路径,使你能够处理嵌套字段并将别名分配给字段名称,如以下示例所示:

 SELECT *
 FROM OPENROWSET(​PROVIDER = 'CosmosDB',
                 CONNECTION = 'Account=my-cosmos-db;Database=my-db',
                 OBJECT = 'my-container',
                 SERVER_CREDENTIAL = 'my_credential'
 )
 WITH (
    ProductNo INT '$.productID',
    ProductName VARCHAR(20) '$.productName',
    Supplier VARCHAR(20) '$.supplier.supplierName',
    SupplierPhoneNo VARCHAR(15) '$.supplier.supplierPhone'
 ) AS products_data

此查询的结果将包括产品 126 的以下行:

ProductNo ProductName 供应商 SupplierPhoneNo
126 Sprocket Contoso 555-123-4567

在数据库中创建视图

如果需要频繁查询相同的数据,或者需要使用依赖于不包含 OPENROWSET 函数的 SELECT 语句的报表和可视化工具,可以使用视图来抽象数据。 若要创建视图,应创建一个新数据库来定义它(不支持 master 数据库中用户定义的视图),如以下示例所示:

CREATE DATABASE sales_db
   COLLATE Latin1_General_100_BIN2_UTF8;
 GO;

 USE sales_db;
 GO;

 CREATE VIEW products
 AS
 SELECT *
 FROM OPENROWSET(​PROVIDER = 'CosmosDB',
                 CONNECTION = 'Account=my-cosmos-db;Database=my-db',
                 OBJECT = 'my-container',
                 SERVER_CREDENTIAL = 'my_credential'
 )
 WITH (
    ProductNo INT '$.productID',
    ProductName VARCHAR(20) '$.productName',
    Supplier VARCHAR(20) '$.supplier.supplierName',
    SupplierPhoneNo VARCHAR(15) '$.supplier.supplierPhone'
 ) AS products_data
 GO

提示

创建将访问 Cosmos DB 中的数据的数据库时,最好使用基于 UTF-8 的排序规则来确保与 Cosmos DB 中的字符串兼容。

创建视图后,用户和客户端应用程序可以像查询任何其他 SQL 视图或表一样对其进行查询:

SELECT * FROM products;

无服务器 SQL 池和 Azure Cosmos DB 的注意事项

在计划使用无服务器 SQL 池查询 Azure Cosmos DB 分析存储中的数据时,请考虑以下最佳做法:

  • 在与无服务器 SQL 池相同的区域中预配 Azure Cosmos DB 分析存储和任何客户端应用程序(例如 Microsoft Power BI)。

    Azure Cosmos DB 容器可以复制到多个区域。 如果有多区域容器,则可以在 OPENROWSET 连接字符串中指定 region 参数,以确保将查询发送到该容器的特定区域副本。

  • 使用字符串列时,将 OPENROWSET 函数与显式 WITH 子句一起使用,并为字符串数据指定适当的数据长度。