Ontem eu estava mexendo no meu projeto de DV de estimação (um aconselhamento que presto a um amigo) e descobri uma coisa: o satélite dos dados dos empregados tinha centenas de registros por empregado. Eu fui olhar de perto e descobri que não eram centenas, mas sim um por dia desde o início da captura dos dados. Para um DV, isso significa que a cada refresh (que é diário neste caso) o ETL está versionando o satélite de empregados. Como isso só aconteceria se todo dia houvesse alguma diferença para a última versão, eu decidi analisar os registros, comparando as versões de satélites para um empregado qualquer.

Eu vou mostrar algumas imagens para ilustrar o que eu fiz, mas saibam que todos os nomes foram mudados para coisas mais óbvias, e campos particulares (que possuíam detalhes da arquitetura do sistema) foram removidos. São ilustrações, não são o caso real, ok? Exceto por esse detalhe, todo o restante é a narração fiel do que eu fiz.

O satélite Empregado, mostrado na figura abaixo junto ao hub Empregado, tem cerca de 13 campos do sistema de origem, mais 4 de controle do DV.

Satélite empregado original, com todos os campos em uma única tabela.
Satélite empregado original, com todos os campos em uma única tabela.

Todos esses campos estão em uma única tabela no sistema de origem, de modo que a carga desse pedaço do modelo é feito por duas transformações: uma de hub e uma de satélite.

Eu descobri, depois de analisar o conteúdo do satélite, que três campos eram atualizados sempre que o empregado chegava para trabalhar e depois ia embora:

  • emp_ultimo_acesso
  • emp_ultimo_ip
  • emp_ultima_sessao

Na verdade, sempre que o empregado fazia login (e depois logoff) em qualquer computador na empresa, esses detalhes são atualizados. Resultado: todo dia eles estavam diferentes do dia anterior, a menos que o empregado tivesse faltado, ou o dia anterior fosse um feriado/fim-de-semana. Portanto, todo dia um novo satélite era carregado, e isso estava correto. O ETL estava fazendo o que havia sido programado para fazer.

Satélites Separados

Temos aqui uma situação clássica para Data Vault: o sistema de origem tem taxas de atualização diferente entre os atributos. Alguns são atualizados uma vez na vida e outra na morte, e outros são alterados todos os dias, quando não várias vezes por dia. Se capturarmos todos os registros na mesma tabela estaremos desperdiçando tempo e espaço em disco, tratando e gravando coisas duplicadas, desnecessariamente.

Neste caso optamos por quebrar um satélite em dois ou mais, em função de sua taxa de atualização: um satélite conterá apenas os três campos que mudam todos os dias, e o outro satélite ficará com os campos mais estáveis. Cada um terá sua própria transformação para carga. No final, nosso DV vai ficar assim:

Satélite Empregado, agora quebrado em duas tabelas em função da taxa de atualização.
Satélite Empregado, agora quebrado em duas tabelas em função da taxa de atualização.

Aplicando a Mudança

Antes havia um satélite (=uma tabela), com todos os campos, carregada por uma transformação. Depois teremos duas tabelas, cada qual com seu conjunto de campos, e cada qual carregada por sua transformação. Eis o passo-a-passo que eu passei para meu amigo aplicar em produção:

  1. Renomear o satélite original para s_empregado_antigo;
  2. Criar as duas novas tabelas, s_empregado e s_empregado_1;
  3. Popular cada uma com o histórico atual;
  4. Apagar o satélite original;
  5. Subir as duas novas transformações.

As novas tabelas foram criadas e populadas de uma só vez com um SELECT INTO (o DV está em Postgres, o que facilita tudo.) As transformações foram criadas semi-automaticamente (basta entrar os nomes das tabelas, campos e da transformação e um script parametrizado gera tudo sozinho.)

Pronto! Quinze minutos depois de diagnosticar o problema eu tinha desenhado a solução. Meu amigo avisou que aplicou e deu tudo certo e agora vai propagar a solução para outros satélites (ele tem vários desses com status instantâneo.)

(Bom, vá lá, eu demorei um pouco mais que quinze minutos porque deu um trabalhinho até eu acertar o SELECT – ele precisava manter o histórico, o que significa dois SELECT DISTINCTs, com ORDER BY etc. Mas agora eu já sei o macete, e da próxima vez vai ser só 15min mesmo!)

Outras Quebras

Outras opções de quebras para satélites são por sistema de origem, que dá a vantagem de integrar os dados já no DV, e por particionamento. Neste último podemos deslocar satélites estáveis para outras mídias (outros tablespaces), e continuar a carregar os novos em uma tabela menor.

O Que Kimball Faria?

Meu grande amigo Gurgel que me perdoe, mas eu não vou nem considerar essa situação na 3NF. Agora, como ficaria essa situação em um Modelo Dimensional?

Na verdade, ficaria muito bem, obrigado! Veja, Modelagem Dimensional é uma técnica resiliente e robusta, com muita flexibilidade. Teríamos praticamente a mesma abordagem: quebrar uma tabela (de dimensão) em duas, criar dois novos processos de cargas (duas novas transformações), e recriar a fato, agora com duas chaves no lugar de uma só.

Factível, viável e simples, sim. Interessante? Não tenho certeza: hoje esses dados não possuem nenhum interesse para o negócio do meu amigo. São dados que ele descartaria sem pensar duas vezes – e foi essa a primeira sugestão dele. Saber qual é a hora do último logoff de cada empregado não tem o menor impacto no rendimento da empresa, nem a menor relação com a produtividade desse empregado. É um dado pura e simplesmente inútil, e só entrou no satélite porque simplificamos o levantamento de requisitos ao mínimo essencial – o também clássico carrega tudo!.

O Que Linstedt Faria?

Tá bom, saber quando o empregado fez o último logoff do dia é inútil. Mas e saber o histórico completo de todos os logins e logoffs, interessa?

Veja, estamos falando de capturar todas as mudanças, até mesmo em tempo real se for necessário. Para conseguir isso, sem gastar muito, basta rodar apenas a transformação que carrega esse satélite (com um ajuste para a variável de tempo – detalhes que não vêm ao caso agora…) a cada hora ou minuto. Com algumas centenas de empregados esse processo seria muito leve.

No caso mais extremo, dá para agendar uma PROC no banco que faça isso, e descartar o PDI completamente, reduzindo ainda mais o impacto da captura de histórico.

Com esses dados, novas perguntas são possíveis:

  • Será que um empregado que entra e sai do sistema várias vezes produz menos?
  • Preciso me preocupar com isso?

Um modelo dimensional permite capturar isso se você quiser. Basta montar uma estrela só para isso, já que esse vai ser o processo de negócio em análise.

Agora, e aqui vem uma das coisas legais do DV, um Data Vault te permite capturar isso já integrado com os outros satélites, o hub e tudo o mais. Um bom desenhista dimensional sabe que a técnica do Kimball também te dá essa possibilidade. Mas quanto mais você extende seu DW Dimensional com esse tipo de recurso, mais chega perto de um modelo Data Vault! A quantidade de dimensões e inter-relações (o Bus Matriz) começa a crescer, e a gestão vai ficando cada vez mais difícil. Apesar de flexível, a Modelagem Dimensional não é pensada para acumular dados, mas para análisá-los e por isso, cedo ou tarde, se seu DW muda com frequẽncia, um DV vai se tornar uma alternativa interessante.

E então você vai testar, só para ver como seria. E, então, já será tarde demais. Você será fisgado, como eu fui.

Até a próxima! Fui! :-)

Anúncios

5 comentários sobre “Como um Data Vault Evolui

  1. Faltou um tópico (com um toque de maldade, lógico) “O que o Apolo faria”: De cara eu tento criar o DV nos menores pedaços possíveis e os Satelites quebrados por assuntos. Teria quebrado em dois ou mais Satelites por serem assuntos diferentes e não por terem momentos de atualizações diferentes. Se minha origem é uma tabela ou um arquivo, meu primeiro passo seria quebrar essa origem mais ou menos nos pedaços que preciso (mamão com açúcar pra fazer isso via PDI). E colocaria todas as cargas em paralelo (hubs em paralelo com hubs e por ai vai).

    Quanto ao modelo dimensional ser super flexível… Concordo com os pontos que você colocou.. mas veja, se você cria cubos de forma correta (e não como uma certa empresa faz colocando sempre o menor grão em qualquer coisa) você teria que fazer um monte de reprocessamento. E isso não seria simples (tão pouco seria rápido) quanto o SELECT INTO que você fez. Bom, esse ponto é bem mais filosófico e só quis dar uma alfinetada mesmo :D

    1. Obrigado pelo comentário, ó maldoso deus-sol :-). Quem fez o lance não fui eu, mas como eu sou preguiçoso eu teria feito a mesma coisa: vai tudo pelo mais fácil. Depois, se precisar, revemos. Eu procuro mesmo viver pela máxima do Scrum (maximizar o trabalho não-feito), e como um DV permite isso – de tratar depois, se e somente se precisar – eu abusaria.

      E eu concordo contigo: não é porque é viável que é a melhor escolha. O retrabalho e o gerenciamento do barramento dimensional tornaria o projeto todo mais custoso. Não consigo deixar de pensar que ficaria inviável em algum ponto. Pode ser que não, mas não consigo me livrar da sensação.

  2. Obrigado Fábio de Salles pelo compartilhamento do seu vasto conhecimento, tal fato agrega valor incomensurável ao conhecimento! Sucesso, saúde e paz.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s