Social Icons

Mostrando postagens com marcador Projeto/Modelagem de dados. Mostrar todas as postagens
Mostrando postagens com marcador Projeto/Modelagem de dados. Mostrar todas as postagens

18 de mai. de 2012

TCC com Datamart em Oracle Database


Olá pessoal,
 
     No artigo de hoje estou escrevendo para compartilhar o Trabalho de Conclusão de Curso (TCC) do amigo DBA Luciano Barros Pires, que propõe a criação de um ambiente de Data Mart para armazenar resumos sobre o Resultado das Eleições Gerais de 2006. Os parágrafos abaixo descrevem resumidamente o TCC e foram escritos pelo próprio Luciano. Eu participei fazendo apenas uma pequena revisão.
  
     Em todos os anos em que ocorrem Eleições, muitos pedidos são protocolados no Tribunal Regional Eleitoral do Estado de São Paulo (TRE-SP) requerendo-se os resultados das eleições. Tais pedidos têm, em sua maioria, como requerente, os candidatos aos pleitos das eleições de Deputado Federal, Deputado Estadual, Senador, Governador e Presidente. Cada um desses cargos têm seus vices ou suplentes, conforme o caso.

     Os requerentes sempre desejam saber quantos votos receberam em cada Zona Eleitoral (ZE), Seção Eleitoral (as salas) ou Local de Votação (as escolas). Com essas informações, o candidato pode montar uma mapa eleitoral com os seus resultados, para verificar onde obteve menos votos e saber onde terá que trabalhar para conseguir mais votos nas próximas eleições. É possível também, identificar eleitores por faixa etária, escolaridade etc.

     O volume de dados para obter todas essas informações é imenso e muito dificil de ser tratado, tanto que nesse TCC, a intenção era mostrar o resultado no Estado inteiro de SP, porém, para fins apenas didáticos, tive que mudá-lo para contemplar apenas uma ZE com muitos municípios.

     O trabalho aborda conceitos gerais sobre Bancos de Dados, Modelagem Entidade-Relacionamento, Modelagem Dimensional (ver imagem 1),  SQL, Data Warehouse, ETL e Datamart e seu objetivo era montar um  Datamart com informações, que até o momento de sua conclusão não estavam disponíveis, usando ferramentas livres desde o Sistema Operacional (SO) até a aplicação. Ele contempla a instalação e configuração dos seguintes softwares: SO Linux,  Banco de Dados Oracle Express Edition 10GR2 (com Oracle Apex) e o BROffice para manipulação dos dados.


Imagem 1: Tabelas fato e dimensões do Data Mart
   
    Para baixar o TCC clique no link TCC_oracle_resultados_eleicoes.zip. O arquivo está compactado e protegido com senha. Para recebê-la assine a newsletter que encontra-se no painel direito deste blog.
   
 
Boa leitura e até o próximo artigo!
  

8 de ago. de 2011

Qual tipo de dado devo usar: CHAR, VARCHAR ou VARCHAR2?


Olá pessoal,

     No artigo de hoje irei comentar sobre um assunto que representa uma dúvida muito comum para quem vai criar tabelas no Banco de Dados (BD) Oracle:  "Qual tipo de dado devo usar: CHAR, VARCHAR ou VARCHAR2?". Essa dúvida surge, normalmente, quando um Desenvolvedor precisa criar colunas para armazenar texto (caracteres alfanuméricos).  Para ter a resposta, precisamos entender primeiro as diferenças entre os tipos de dados CHARVARCHAR e VARCHAR2:

1- VARCHAR  
     Atualmente (até a versão 11G do Oracle Database), VARCHAR nada mais é do que um sinônimo para VARCHAR2 (desde o Oracle8), por isso a Oracle recomenda não utilizar este tipo de dado. Existe a possibilidade de VARCHAR ser utilizado em versões futuras para ter uma semântica ou característica diferente de VARCHAR2, mas mesmo, estando tudo igual atualmente, utilize VARCHAR2 ao invés de VARCHARpara evitar possíveis problemas futuros.
  
2- VARCHAR2
     VARCHAR2 armazena caracteres alfanuméricos de tamanho variável, entre 1 e 4000 bytes ou caracteres. O tamanho padrão desta coluna é especificado em bytes. Agora vem a pergunta, qual a diferença entre armazenar bytes ou caracteres? Bom... quando utilizamos caracteres multibyte, como por exemplo UTF-8 (para representar caracteres específicos em múltiplas linguagens), 1 único caractere pode ser armazenado em até 3 bytes. Nestes casos, uma palavra contendo caracteres especiais, como por exemplo, FÁBIO, poderá ter mais bytes do que caracteres (a letra Á, internamente será armazenada em 2 ou 3 bytes), por isso, recomenda-se, nestes casos, especificar o armazenamento da coluna em caracteres, ao invés de bytes.

3- CHAR
     A única diferença entre CHAR e VARCHAR2 é que CHAR armazena caracteres alfanuméricos de tamanho fixo, entre 1 e 2000 bytes ou caracteres. Se você armazenar o sobrenome PRADO em uma coluna CHAR(50), a coluna conterá a string PRADO + 45 espaços em branco que são adicionados automaticamente para preencher o tamanho total da coluna.      

     Agora que já sabemos as diferenças e particularidades de cada tipo de dados, vamos à pergunta que é o título deste artigo: Qual tipo de dado devo usar: CHAR, VARCHAR ou VARCHAR2?
     Resposta: Sabendo que VARCHAR é um sinônimo para VARCHAR2 e que a própria Oracle não recomenda utilizar este tipo de dados, esqueça que ele existe, utilize VARCHAR2 ao invés de VARCHAR. Agora que já sabemos que não devemos utilizar VARCHAR, sobraram apenas 2 tipos de dados para comparar: CHAR e VARCHAR2. Thomas Kyte, um dos maiores especialistas em Oracle do mundo, recomenda evitar CHAR em seu site ASK TOM (ver referências). Resumindo o que ele explica, em termos de armazenamento CHAR nada mais é do que um VARCHAR2 com espaços em branco adicionais. Neste caso, se você cria uma coluna com CHAR ou VARCHAR2 de tamanho 50 e armazena uma palavra que tenha somente 40 caracteres, utilizando VARCHAR2 você poderá economizar espaço em disco e você ainda terá consultas mais rápidas.
    
    Diante de todos estes dados e informações, podemos chegar à conclusão de que devemos evitar CHAR e VARCHAR, utilizando sempre  VARCHAR2 para armazenar valores alfanuméricos de até 4000 caracteres (limite de tamanho do Oracle Database 11G).

     Segue abaixo um conjunto de scripts para serem executados no SQL Developer (ou em sua ferramenta preferida), para permitir a comparação de performance de INSERTs e SELECTs entre uma tabela com 1 coluna VARCHAR2 e outra tabela idêntica com 1 coluna CHAR. O script do Passo 4 permite comparar a performance de inserções nas 2 tabelas. Os scripts dos Passos 6 e 7 permitem comparar a performance de consultas e os scripts dos Passos 8 e 9 permitem verificar a qtde. de bytes que foram armazenados em cada coluna:

Passo 1: Criando as tabelas de origem de dados:
     CREATE TABLE CLIENTE_CHAR (ID_CLIENTE NUMBER, NM_CLIENTE CHAR(50), NM_ENDERECO CHAR(100));
     CREATE TABLE CLIENTE_VARCHAR2 (ID_CLIENTE NUMBER, NM_CLIENTE VARCHAR2(50), NM_ENDERECO VARCHAR2(100));

Passo 2: Populando as tabelas de origem de dados:
SET SERVEROUTPUT ON
DECLARE  
  V_COUNT         NUMBER; 
BEGIN 
  FOR V_COUNT IN 1..99999
  LOOP 
          -- executa insert c/ loop em cursor
          INSERT  INTO CLIENTE_CHAR (ID_CLIENTE, NM_CLIENTE, NM_ENDERECO)
          VALUES  (V_COUNT, 'NOME ' || TO_CHAR(V_COUNT), 'ENDERECO ' || TO_CHAR(V_COUNT));
         
          INSERT  INTO CLIENTE_VARCHAR2 (ID_CLIENTE, NM_CLIENTE, NM_ENDERECO)
          VALUES  (V_COUNT, 'NOME ' || TO_CHAR(V_COUNT), 'ENDERECO ' || TO_CHAR(V_COUNT));
  END LOOP; 
 
  COMMIT;
END;

Passo 3: Criando as tabelas teste para comparar performance:
CREATE TABLE CLIENTE_VARCHAR2_B AS SELECT * FROM CLIENTE_VARCHAR2 WHERE 1=2;
CREATE TABLE CLIENTE_CHAR_B AS SELECT * FROM CLIENTE_CHAR WHERE 1=2;

Passo 4: Calculando o tempo de INSERT nas tabelas teste a partir da leitura das tabelas de origens de dados:
SET SERVEROUTPUT ON
DECLARE
  L_START         NUMBER;  
BEGIN
  L_START := DBMS_UTILITY.GET_TIME;     
  -- executa insert c/ loop em cursor
  INSERT  INTO CLIENTE_CHAR_B
  SELECT * FROM CLIENTE_CHAR;
  DBMS_OUTPUT.PUT_LINE('Tempo total de INSERT na tabela CLIENTE_CHAR2 : ' || ROUND((DBMS_UTILITY.GET_TIME - L_START)/100,2) || 's');   
 
  L_START := DBMS_UTILITY.GET_TIME; 
  INSERT  INTO CLIENTE_VARCHAR2_B
  SELECT * FROM CLIENTE_VARCHAR2; 
  DBMS_OUTPUT.PUT_LINE('Tempo total de INSERT na tabela CLIENTE_VARCHAR2 : ' || ROUND((DBMS_UTILITY.GET_TIME - L_START)/100,2) || 's');   
END;

Passo 5: Coletando estatísticas das tabelas teste para gerar plano de execução otimizado:
     ANALYZE TABLE CLIENTE_VARCHAR2_B COMPUTE STATISTICS;
     ANALYZE TABLE CLIENTE_CHAR_B COMPUTE STATISTICS;

Passo 6: Verificando tempo de consulta na tabela teste que tem colunas CHAR:
     EXPLAIN PLAN FOR
          SELECT * FROM  CLIENTE_CHAR_B WHERE NM_CLIENTE = 'NOME 1'; --
     SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

Passo 7: Verificando tempo de consulta na tabela teste que tem colunas VARCHAR2:
     EXPLAIN PLAN FOR
          SELECT * FROM  CLIENTE_VARCHAR2_B WHERE NM_CLIENTE = 'NOME 1'; --
     select * from table(DBMS_XPLAN.DISPLAY);

Passo 8: Verificando qtde de bytes armazenados na coluna nm_cliente da tabela teste com CHAR:
     SELECT DUMP(NM_CLIENTE) FROM CLIENTE_CHAR_B;

Passo 9: Verificando qtde. de bytes armazenados na coluna nm_cliente da tabela teste com VARCHAR2:
     SELECT DUMP(NM_CLIENTE) FROM CLIENTE_VARCHAR2_B;

   
Obs.: Após efetuar os testes de comparação, execute os comandos abaixo para apagar as tabelas criadas nos passos anteriores:
     DROP TABLE CLIENTE_VARCHAR2 PURGE;
     DROP TABLE CLIENTE_VARCHAR2_B PURGE;
     DROP TABLE CLIENTE_CHAR PURGE;
     DROP TABLE CLIENTE_CHAR_B PURGE;
     
 
COMENTÁRIOS FINAIS:
     Em testes que eu fiz, o tempo de consulta na tabela que tem a coluna VARCHAR2 foi 4.6 vezes mais rápido e o tempo de inserção na tabela que tem a coluna VARCHAR2 foi 3.5 vezes mais rápido.
           
CONCLUSÃO:
     Evite CHAR ou VARCHAR. Não utilize CHAR nem para criar colunas que armazenarão apenas 1 caractere de tamanho fixo. Atualmente não há vantagens em utilizar este tipo de dado. Utilize sempre VARCHAR2. Este sim poderá oferecer vantagens de performance e armazenamento quando a definição do tamanho da coluna for maior que o valor armazenado.
 

LINKS ÚTEIS

Total de visualizações de página

Seguidores

Meu One Drive (antigo Sky Drive)