Carregar dados de revenda da Contoso para conjuntos de SQL dedicados no Azure Synapse Analytics
Neste tutorial, vai aprender a utilizar comandos PolyBase e T-SQL para carregar duas tabelas dos dados de revenda da Contoso para conjuntos de SQL dedicados.
Neste tutorial, irá:
- Configurar o PolyBase para carregar a partir do armazenamento de blobs do Azure
- Carregar dados públicos para a base de dados
- Efetue otimizações após a conclusão da carga.
Antes de começar
Para executar este tutorial, precisa de uma conta do Azure que já tenha um conjunto de SQL dedicado. Se não tiver um armazém de dados aprovisionado, veja Criar um armazém de dados e definir a regra de firewall ao nível do servidor.
Configurar a origem de dados
O PolyBase utiliza objetos externos T-SQL para definir a localização e os atributos dos dados externos. As definições de objetos externos são armazenadas em conjuntos de SQL dedicados. Os dados são armazenados externamente.
Criar uma credencial
Ignore este passo se estiver a carregar os dados públicos da Contoso. Não precisa de acesso seguro aos dados públicos, uma vez que já está acessível a qualquer pessoa.
Não ignore este passo se estiver a utilizar este tutorial como modelo para carregar os seus próprios dados. Para aceder aos dados através de uma credencial, utilize o seguinte script para criar uma credencial com âmbito de base de dados. Em seguida, utilize-a ao definir a localização da origem de dados.
-- A: Create a master key.
-- Only necessary if one does not already exist.
-- Required to encrypt the credential secret in the next step.
CREATE MASTER KEY;
-- B: Create a database scoped credential
-- IDENTITY: Provide any string, it is not used for authentication to Azure storage.
-- SECRET: Provide your Azure storage account key.
CREATE DATABASE SCOPED CREDENTIAL AzureStorageCredential
WITH
IDENTITY = 'user',
SECRET = '<azure_storage_account_key>'
;
-- C: Create an external data source
-- TYPE: HADOOP - PolyBase uses Hadoop APIs to access data in Azure blob storage.
-- LOCATION: Provide Azure storage account name and blob container name.
-- CREDENTIAL: Provide the credential created in the previous step.
CREATE EXTERNAL DATA SOURCE AzureStorage
WITH (
TYPE = HADOOP,
LOCATION = 'wasbs://<blob_container_name>@<azure_storage_account_name>.blob.core.windows.net',
CREDENTIAL = AzureStorageCredential
);
Criar a origem de dados externa
Utilize este comando CREATE EXTERNAL DATA SOURCE para armazenar a localização dos dados e o tipo de dados.
CREATE EXTERNAL DATA SOURCE AzureStorage_west_public
WITH
(
TYPE = Hadoop
, LOCATION = 'wasbs://contosoretaildw-tables@contosoretaildw.blob.core.windows.net/'
);
Importante
Se optar por tornar os contentores de armazenamento de blobs do Azure públicos, lembre-se de que, como proprietário dos dados, será cobrado pelos custos de saída de dados quando os dados deixarem o datacenter.
Configurar o formato de dados
Os dados são armazenados em ficheiros de texto no armazenamento de blobs do Azure e cada campo é separado por um delimitador. No SSMS, execute o seguinte comando CREATE EXTERNAL FILE FORMAT para especificar o formato dos dados nos ficheiros de texto. Os dados da Contoso são descomprimidos e delimitados por pipes.
CREATE EXTERNAL FILE FORMAT TextFileFormat
WITH
( FORMAT_TYPE = DELIMITEDTEXT
, FORMAT_OPTIONS ( FIELD_TERMINATOR = '|'
, STRING_DELIMITER = ''
, DATE_FORMAT = 'yyyy-MM-dd HH:mm:ss.fff'
, USE_TYPE_DEFAULT = FALSE
)
);
Criar o esquema para as tabelas externas
Agora que especificou a origem de dados e o formato de ficheiro, está pronto para criar o esquema para as tabelas externas.
Para criar um local para armazenar os dados da Contoso na base de dados, crie um esquema.
CREATE SCHEMA [asb]
GO
Criar as tabelas externas
Execute o seguinte script para criar as tabelas externas DimProduct e FactOnlineSales. Tudo o que está a fazer aqui é definir nomes de colunas e tipos de dados e enlace-os à localização e formato dos ficheiros de armazenamento de blobs do Azure. A definição é armazenada no armazém de dados e os dados ainda estão no Blob de Armazenamento do Azure.
O parâmetro LOCALIZAÇÃO é a pasta na pasta raiz no Blob de Armazenamento do Azure. Cada tabela está numa pasta diferente.
--DimProduct
CREATE EXTERNAL TABLE [asb].DimProduct (
[ProductKey] [int] NOT NULL,
[ProductLabel] [nvarchar](255) NULL,
[ProductName] [nvarchar](500) NULL,
[ProductDescription] [nvarchar](400) NULL,
[ProductSubcategoryKey] [int] NULL,
[Manufacturer] [nvarchar](50) NULL,
[BrandName] [nvarchar](50) NULL,
[ClassID] [nvarchar](10) NULL,
[ClassName] [nvarchar](20) NULL,
[StyleID] [nvarchar](10) NULL,
[StyleName] [nvarchar](20) NULL,
[ColorID] [nvarchar](10) NULL,
[ColorName] [nvarchar](20) NOT NULL,
[Size] [nvarchar](50) NULL,
[SizeRange] [nvarchar](50) NULL,
[SizeUnitMeasureID] [nvarchar](20) NULL,
[Weight] [float] NULL,
[WeightUnitMeasureID] [nvarchar](20) NULL,
[UnitOfMeasureID] [nvarchar](10) NULL,
[UnitOfMeasureName] [nvarchar](40) NULL,
[StockTypeID] [nvarchar](10) NULL,
[StockTypeName] [nvarchar](40) NULL,
[UnitCost] [money] NULL,
[UnitPrice] [money] NULL,
[AvailableForSaleDate] [datetime] NULL,
[StopSaleDate] [datetime] NULL,
[Status] [nvarchar](7) NULL,
[ImageURL] [nvarchar](150) NULL,
[ProductURL] [nvarchar](150) NULL,
[ETLLoadID] [int] NULL,
[LoadDate] [datetime] NULL,
[UpdateDate] [datetime] NULL
)
WITH
(
LOCATION='/DimProduct/'
, DATA_SOURCE = AzureStorage_west_public
, FILE_FORMAT = TextFileFormat
, REJECT_TYPE = VALUE
, REJECT_VALUE = 0
)
;
--FactOnlineSales
CREATE EXTERNAL TABLE [asb].FactOnlineSales
(
[OnlineSalesKey] [int] NOT NULL,
[DateKey] [datetime] NOT NULL,
[StoreKey] [int] NOT NULL,
[ProductKey] [int] NOT NULL,
[PromotionKey] [int] NOT NULL,
[CurrencyKey] [int] NOT NULL,
[CustomerKey] [int] NOT NULL,
[SalesOrderNumber] [nvarchar](20) NOT NULL,
[SalesOrderLineNumber] [int] NULL,
[SalesQuantity] [int] NOT NULL,
[SalesAmount] [money] NOT NULL,
[ReturnQuantity] [int] NOT NULL,
[ReturnAmount] [money] NULL,
[DiscountQuantity] [int] NULL,
[DiscountAmount] [money] NULL,
[TotalCost] [money] NOT NULL,
[UnitCost] [money] NULL,
[UnitPrice] [money] NULL,
[ETLLoadID] [int] NULL,
[LoadDate] [datetime] NULL,
[UpdateDate] [datetime] NULL
)
WITH
(
LOCATION='/FactOnlineSales/'
, DATA_SOURCE = AzureStorage_west_public
, FILE_FORMAT = TextFileFormat
, REJECT_TYPE = VALUE
, REJECT_VALUE = 0
)
;
Carregar os dados
Existem diferentes formas de aceder a dados externos. Pode consultar dados diretamente a partir das tabelas externas, carregar os dados para novas tabelas no armazém de dados ou adicionar dados externos a tabelas existentes do armazém de dados.
Criar um novo esquema
O CTAS cria uma nova tabela que contém dados. Primeiro, crie um esquema para os dados contoso.
CREATE SCHEMA [cso]
GO
Carregar os dados para novas tabelas
Para carregar dados do armazenamento de blobs do Azure para a tabela do armazém de dados, utilize a instrução CREATE TABLE AS SELECT (Transact-SQL ). O carregamento com CTAS tira partido das tabelas externas fortemente digitadas que criou. Para carregar os dados para novas tabelas, utilize uma instrução CTAS por tabela.
O CTAS cria uma nova tabela e preenche-a com os resultados de uma instrução selecionada. O CTAS define a nova tabela para ter as mesmas colunas e tipos de dados que os resultados da instrução select. Se selecionar todas as colunas de uma tabela externa, a nova tabela será uma réplica das colunas e tipos de dados na tabela externa.
Neste exemplo, criamos a dimensão e a tabela de factos como tabelas hash distribuídas.
SELECT GETDATE();
GO
CREATE TABLE [cso].[DimProduct] WITH (DISTRIBUTION = HASH([ProductKey] ) ) AS SELECT * FROM [asb].[DimProduct] OPTION (LABEL = 'CTAS : Load [cso].[DimProduct] ');
CREATE TABLE [cso].[FactOnlineSales] WITH (DISTRIBUTION = HASH([ProductKey] ) ) AS SELECT * FROM [asb].[FactOnlineSales] OPTION (LABEL = 'CTAS : Load [cso].[FactOnlineSales] ');
Controlar o progresso da carga
Pode controlar o progresso da carga com vistas de gestão dinâmicas (DMVs).
-- To see all requests
SELECT * FROM sys.dm_pdw_exec_requests;
-- To see a particular request identified by its label
SELECT * FROM sys.dm_pdw_exec_requests as r
WHERE r.[label] = 'CTAS : Load [cso].[DimProduct] '
OR r.[label] = 'CTAS : Load [cso].[FactOnlineSales] '
;
-- To track bytes and files
SELECT
r.command,
s.request_id,
r.status,
count(distinct input_name) as nbr_files,
sum(s.bytes_processed)/1024/1024/1024 as gb_processed
FROM
sys.dm_pdw_exec_requests r
inner join sys.dm_pdw_dms_external_work s
on r.request_id = s.request_id
WHERE
r.[label] = 'CTAS : Load [cso].[DimProduct] '
OR r.[label] = 'CTAS : Load [cso].[FactOnlineSales] '
GROUP BY
r.command,
s.request_id,
r.status
ORDER BY
nbr_files desc,
gb_processed desc;
Otimizar a compressão columnstore
Por predefinição, os conjuntos de SQL dedicados armazenam a tabela como um índice columnstore em cluster. Após a conclusão de uma carga, algumas das linhas de dados poderão não ser comprimidas no columnstore. Existem diferentes razões pelas quais isto pode acontecer. Para saber mais, veja Gerir índices columnstore.
Para otimizar o desempenho das consultas e a compressão columnstore após uma carga, recompile a tabela para forçar o índice columnstore a comprimir todas as linhas.
SELECT GETDATE();
GO
ALTER INDEX ALL ON [cso].[DimProduct] REBUILD;
ALTER INDEX ALL ON [cso].[FactOnlineSales] REBUILD;
Para obter mais informações sobre a manutenção de índices columnstore, veja o artigo Gerir índices columnstore .
Otimizar estatísticas
É melhor criar estatísticas de coluna única imediatamente após uma carga. Se souber que determinadas colunas não estarão em predicados de consulta, pode ignorar a criação de estatísticas nessas colunas. Se criar estatísticas de coluna única em cada coluna, poderá demorar muito tempo a reconstruir todas as estatísticas.
Se decidir criar estatísticas de coluna única em todas as colunas de cada tabela, pode utilizar o exemplo de código prc_sqldw_create_stats
de procedimento armazenado no artigo de estatísticas .
O exemplo seguinte é um bom ponto de partida para criar estatísticas. Cria estatísticas de coluna única em cada coluna na tabela de dimensões e em cada coluna de associação nas tabelas de factos. Pode sempre adicionar estatísticas individuais ou de várias colunas a outras colunas de tabela de factos mais tarde.
CREATE STATISTICS [stat_cso_DimProduct_AvailableForSaleDate] ON [cso].[DimProduct]([AvailableForSaleDate]);
CREATE STATISTICS [stat_cso_DimProduct_BrandName] ON [cso].[DimProduct]([BrandName]);
CREATE STATISTICS [stat_cso_DimProduct_ClassID] ON [cso].[DimProduct]([ClassID]);
CREATE STATISTICS [stat_cso_DimProduct_ClassName] ON [cso].[DimProduct]([ClassName]);
CREATE STATISTICS [stat_cso_DimProduct_ColorID] ON [cso].[DimProduct]([ColorID]);
CREATE STATISTICS [stat_cso_DimProduct_ColorName] ON [cso].[DimProduct]([ColorName]);
CREATE STATISTICS [stat_cso_DimProduct_ETLLoadID] ON [cso].[DimProduct]([ETLLoadID]);
CREATE STATISTICS [stat_cso_DimProduct_ImageURL] ON [cso].[DimProduct]([ImageURL]);
CREATE STATISTICS [stat_cso_DimProduct_LoadDate] ON [cso].[DimProduct]([LoadDate]);
CREATE STATISTICS [stat_cso_DimProduct_Manufacturer] ON [cso].[DimProduct]([Manufacturer]);
CREATE STATISTICS [stat_cso_DimProduct_ProductDescription] ON [cso].[DimProduct]([ProductDescription]);
CREATE STATISTICS [stat_cso_DimProduct_ProductKey] ON [cso].[DimProduct]([ProductKey]);
CREATE STATISTICS [stat_cso_DimProduct_ProductLabel] ON [cso].[DimProduct]([ProductLabel]);
CREATE STATISTICS [stat_cso_DimProduct_ProductName] ON [cso].[DimProduct]([ProductName]);
CREATE STATISTICS [stat_cso_DimProduct_ProductSubcategoryKey] ON [cso].[DimProduct]([ProductSubcategoryKey]);
CREATE STATISTICS [stat_cso_DimProduct_ProductURL] ON [cso].[DimProduct]([ProductURL]);
CREATE STATISTICS [stat_cso_DimProduct_Size] ON [cso].[DimProduct]([Size]);
CREATE STATISTICS [stat_cso_DimProduct_SizeRange] ON [cso].[DimProduct]([SizeRange]);
CREATE STATISTICS [stat_cso_DimProduct_SizeUnitMeasureID] ON [cso].[DimProduct]([SizeUnitMeasureID]);
CREATE STATISTICS [stat_cso_DimProduct_Status] ON [cso].[DimProduct]([Status]);
CREATE STATISTICS [stat_cso_DimProduct_StockTypeID] ON [cso].[DimProduct]([StockTypeID]);
CREATE STATISTICS [stat_cso_DimProduct_StockTypeName] ON [cso].[DimProduct]([StockTypeName]);
CREATE STATISTICS [stat_cso_DimProduct_StopSaleDate] ON [cso].[DimProduct]([StopSaleDate]);
CREATE STATISTICS [stat_cso_DimProduct_StyleID] ON [cso].[DimProduct]([StyleID]);
CREATE STATISTICS [stat_cso_DimProduct_StyleName] ON [cso].[DimProduct]([StyleName]);
CREATE STATISTICS [stat_cso_DimProduct_UnitCost] ON [cso].[DimProduct]([UnitCost]);
CREATE STATISTICS [stat_cso_DimProduct_UnitOfMeasureID] ON [cso].[DimProduct]([UnitOfMeasureID]);
CREATE STATISTICS [stat_cso_DimProduct_UnitOfMeasureName] ON [cso].[DimProduct]([UnitOfMeasureName]);
CREATE STATISTICS [stat_cso_DimProduct_UnitPrice] ON [cso].[DimProduct]([UnitPrice]);
CREATE STATISTICS [stat_cso_DimProduct_UpdateDate] ON [cso].[DimProduct]([UpdateDate]);
CREATE STATISTICS [stat_cso_DimProduct_Weight] ON [cso].[DimProduct]([Weight]);
CREATE STATISTICS [stat_cso_DimProduct_WeightUnitMeasureID] ON [cso].[DimProduct]([WeightUnitMeasureID]);
CREATE STATISTICS [stat_cso_FactOnlineSales_CurrencyKey] ON [cso].[FactOnlineSales]([CurrencyKey]);
CREATE STATISTICS [stat_cso_FactOnlineSales_CustomerKey] ON [cso].[FactOnlineSales]([CustomerKey]);
CREATE STATISTICS [stat_cso_FactOnlineSales_DateKey] ON [cso].[FactOnlineSales]([DateKey]);
CREATE STATISTICS [stat_cso_FactOnlineSales_OnlineSalesKey] ON [cso].[FactOnlineSales]([OnlineSalesKey]);
CREATE STATISTICS [stat_cso_FactOnlineSales_ProductKey] ON [cso].[FactOnlineSales]([ProductKey]);
CREATE STATISTICS [stat_cso_FactOnlineSales_PromotionKey] ON [cso].[FactOnlineSales]([PromotionKey]);
CREATE STATISTICS [stat_cso_FactOnlineSales_StoreKey] ON [cso].[FactOnlineSales]([StoreKey]);
Conquista desbloqueada!
Carregou com êxito dados públicos para o seu armazém de dados. Parabéns!
Agora pode começar a consultar as tabelas para explorar os seus dados. Execute a seguinte consulta para descobrir o total de vendas por marca:
SELECT SUM(f.[SalesAmount]) AS [sales_by_brand_amount]
, p.[BrandName]
FROM [cso].[FactOnlineSales] AS f
JOIN [cso].[DimProduct] AS p ON f.[ProductKey] = p.[ProductKey]
GROUP BY p.[BrandName]
Passos seguintes
Para carregar o conjunto de dados completo, execute o exemplo para carregar o armazém de dados de revenda completo da Contoso a partir do repositório de exemplos da Microsoft SQL Server. Para obter mais sugestões de desenvolvimento, veja Decisões de estruturação e técnicas de codificação para armazéns de dados.