Estratégia para montagem de Data Warehouse

Fala galera, uma área que é extremamente importante quando estamos falando em BI (Business Intelligence), é a área do DW (Data Warehouse). Estudos apontam que a criação do DW, através do processo de ETL (Extraction, Transformation and Loading – Extração, Transformação e Carga), consome, em média, 70% do tempo total do projeto. Isso se dá ao fato de, em grande parte das vezes, precisarmos buscar as informações necessárias para responder as perguntas que a área de negócio faz, mas que nem sempre estão dentro do nosso ambiente relacional. É preciso, através dos processos de ETL, buscar estas informações em outras origens.

Uma questão que em aulas/palestras sempre me perguntam é: “COMO MONTAR O DW“? Sempre respondo para pensar no DW se adequando às necessidades da modelagem que vamos utilizar dentro do SSAS (SQL Server Analysis Services). Essa adequação é um exercício que deve ser feito juntamente com a área de negócios. Isso é um ponto importante. BI é pra área de negócios, a área de TI só falicita que a área de negócios consiga encontrar a informação mais rapido. Porém, é a área de negócios que dita a regra do BI… Pode parecer estranho, mas é isso que defendo! Ninguém melhor que a área de negócios para saber as perguntas que precisam das respostas… A nossa área será esse facilitador, entregando uma plataforma que irá responder estas perguntas!

Quando pensamos na arquitetura do DW, existem duas modelagens que são amplamente estudadas e utilizadas, Snowflake Schema e Star Schema… Elas se diferem pela modelagem da estrutura do ambiente e desempenho no processamento. Eu particularmente tento usar sempre a modelagem Star Schema, pelo desempenho ser melhor.

A grosso modo, no modelo Star Schema, as dimensões se relacionam diretamente com a tabela Fato, sem nenhuma sub-dimensão. A ligação é direta. Já no modelo Snowflake Schema, possuimos sub-dimensões ligadas às dimensões, que por sua vez estão ligadas à tabela fato. Isso bem resumidamente, lembrando que preciso montar um post específico sobre cada uma das modelagens!

Voltando à estratégia inicial do DW, nem tudo que está na tabela do OLTP precisa de fato estar dentro do DW. Por exemplo, na tabela de cadastro de clientes tem o campo telefone, mas a necessidade da área de negócios é responder quantos cadastros de solteiros foram realizados em Janeiro/2012. Os dados de telefone não são importantes para esta análise, já os dados de Estado Civil sim. Neste caso, precisamos enviar os dados de Estado Civil da tabela online (transacional) para a tabela analítica do DW e não precisamos enviar os dados de telefone.

Os dados existentes na tabela fato já dizem o que eles são por sí só. Os dados da tabela fato são, única e exclusivamente, fatos reais e verdadeiros, sobre a análise que precisa ser feita. A tabela fato deve receber somente os campos chaves das tabelas dimensões, criando o relacionamento entre elas. Bem no formato PK e FK que já estamos acostumados a encontrar no ambiente OLTP. Estes dados inseridos dentro da fato podem ser detalhados, fazendo uma busca na tabela dimensão correspondente àquela informação. Lembrando que os dados na tabela fato estão desnormalizados, sendo duplicados diversas vezes para responder todas as variações que geram um fato no cruzamento das dimensões.

A tabela Dimensão armazena os dados detalhados sobre aquele grupo específico. Seria algo do tipo, a tabela dimensão de cliente possui os dados relacionados à clientes. A dimensão de pagamentos, possui os dados referentes à pagamentos. A dimensão de pedidos, possui dados referentes à pedidos. Elas não se relacionam entre sí, a única ligação que me responde qual cliente comprou tal produto na data x, são as chaves que estão na tabela fato. Também são representações detalhadas das informações na qual os dados agrupados das Measures (medidas) serão cortados (quebrados / filtrados).

As medidas normalmente são baseadas nas informações contidas na tabela fato. Sendo os consolidadores – agregações – baseado em um campo que recebe uma operação. Estas agregações podem ser de SOMA, MÉDIA, MAXIMO, MÍNIMO, CONTAGEM, PRIMEIRO VALOR, ULTIMO VALOR…

Para exemplificar esses conceitos, vamos imaginar um cenário pequeno que representa um sistema de mercadinho (relembrando da época do colégio técnico em Processamento de Dados).

image

Este diagrama acima representa uma parte do sistema do mercadinho. E o script T-SQL abaixo gera o banco… Eu sei, eu sei… Faltam os índices e outros objetos. Mas não é esse o objetivo aqui. rss

CREATE DATABASE mercadinhoOLTP
GO

USE mercadinhoOLTP
GO

/************************/
/* CRIAÇÃO DAS TABELAS  */
/************************/

CREATE TABLE tbCliente
( ClienteID INT IDENTITY(1,1) PRIMARY KEY
, ClienteNome VARCHAR(50)
, ClienteTelefone VARCHAR(15)
, ClienteDataCadastro DATE)
GO

CREATE TABLE tbPagamento
( PagamentoID INT IDENTITY(1,1) PRIMARY KEY
, ClienteID INT
, PedidoID INT
, PagamentoValor DECIMAL(8,2)
, PagamentoData DATE)
GO

CREATE TABLE tbPedido
( PedidoID INT IDENTITY(1,1) PRIMARY KEY
, PedidoData DATE
, ClienteID INT)
GO

CREATE TABLE tbProduto
( ProdutoID INT IDENTITY(1,1) PRIMARY KEY
, ProdutoNome VARCHAR(50)
, ProdutoValor DECIMAL(5,2))
GO

CREATE TABLE tbPedidoItem
( PedidoItemID INT IDENTITY(1,1) PRIMARY KEY
, PedidoID INT
, ProdutoID INT)
GO

ALTER TABLE tbPagamento  WITH CHECK ADD  CONSTRAINT FK_tbPagamento_tbCliente
FOREIGN KEY(ClienteID) REFERENCES tbCliente (ClienteID)
GO

ALTER TABLE tbPagamento  WITH CHECK ADD  CONSTRAINT FK_tbPagamento_tbPedido
FOREIGN KEY(PedidoID) REFERENCES tbPedido (PedidoID)
GO

ALTER TABLE tbPedido  WITH CHECK ADD  CONSTRAINT FK_tbPedido_tbCliente
FOREIGN KEY(ClienteID) REFERENCES tbCliente (ClienteID)
GO

ALTER TABLE tbPedidoItem  WITH CHECK ADD  CONSTRAINT FK_tbPedidoItem_tbPedido
FOREIGN KEY(PedidoID) REFERENCES tbPedido (PedidoID)
GO

ALTER TABLE tbPedidoItem  WITH CHECK ADD  CONSTRAINT FK_tbPedidoItem_tbProduto
FOREIGN KEY(ProdutoID) REFERENCES tbProduto (ProdutoID)
GO

/**********************************/
/*  INSERT DE DADOS ALEATÓRIOS    */
/**********************************/

-- 10.000 Clientes
INSERT INTO tbCliente (ClienteNome, ClienteTelefone, ClienteDataCadastro)
VALUES (NEWID(), '(XX) 1234-5678'
      , CONVERT(DATE,CONVERT(DATETIME, CONVERT(INT,(RAND()*356)+40710))))
GO 10000

-- 100 Produtos
INSERT INTO tbProduto(ProdutoNome, ProdutoValor)
VALUES ( NEWID(), CONVERT(DECIMAL(5,2),(RAND()*100)+1,2)  )
GO 100

-- 1.000 Pedidos
WITH Clientes AS
( SELECT ClienteID
, CONVERT(DATE, DATEADD(DAY,RAND()*100,
        CONVERT(DATETIME,ClienteDataCadastro))) [ClienteDataCadastro]
FROM tbCliente
WHERE ClienteID = CONVERT(INT,(RAND()*10000)+1) )
INSERT INTO tbPedido(ClienteID,PedidoData)
SELECT ClienteID, ClienteDataCadastro FROM Clientes
GO 1000

-- 2.500 Itens nos Pedidos
INSERT INTO tbPedidoItem(PedidoID, ProdutoID)
SELECT (SELECT CONVERT(INT,RAND()*MAX(PedidoID)-1) FROM tbPedido)
      ,(SELECT CONVERT(INT,RAND()*MAX(ProdutoID)-1) FROM tbProduto)
GO 2500

-- Itens de Pagamento
INSERT INTO tbPagamento (ClienteID, PedidoID, PagamentoValor, PagamentoData)
SELECT PE.ClienteID, PE.PedidoID, SUM(PR.ProdutoValor)
 , CONVERT(DATE, DATEADD(DAY,RAND()*5
 , CONVERT(DATETIME,PE.PedidoData))) FROM tbPedido PE
INNER JOIN tbPedidoItem PI ON PE.PedidoID = PI.PedidoID
INNER JOIN tbProduto PR ON PR.ProdutoID = PI.ProdutoID
GROUP BY PE.ClienteID, PE.PedidoID
 , CONVERT(DATE, DATEADD(DAY,RAND()*5, CONVERT(DATETIME,PE.PedidoData)))
ORDER BY ClienteID, PedidoID

 

Depois de criado o banco de dados de exemplo, para o padrão de ambientes transacionais. Vamos remodelar estas mesmas tabelas para o ambiente analítico, montando o Data Warehouse com uma idéia de tabela Fato e algumas tabelas Dimensões. Veja o diagrama e o códito T-SQL abaixo, para gerar esse ambiente de DW.

image

Com essa idéia, é possível comparar a modelagem dos ambientes preparados para OLTP (transacional) e OLAP (analítico). Lembrando que ambos estão rodando em cima do engine relacional do SQL Server. Somente depois de criar o projeto do SSAS e processar/publicar o cubo, que ele será criado de fato no ambiente Tabular/Multidimensional.

Para um próximo post, vou mostrar como criar, processar e publicar o cubo com base nestas informações do DW. Também escreverei sobre as diferenças da modelagem Star Schema e Snowflake Schema.

Sobre Diego Nogare 350 Artigos
Diego Nogare é Gerente Técnico de Engenharia de Machine Learning no Itaú-Unibanco. Também é professor em programas de pós graduação no Mackenzie e na FIAP, em São Paulo. Foi nomeado como Microsoft MVP por 11 anos seguidos, e hoje faz parte do programa Microsoft Regional Director.