Desvendando a SQL – Parte 2

Neste artigo serão abordadas as junções entre tabelas do tipo cross join, que resulta em um produto cartesiano, e também as junções do tipo self join, onde é feita a junção de uma tabela com ela mesma.

Demais posts desta série:
Desvendando a SQL – Parte 1
Artigo do tipo Exemplos Práticos
Recursos especiais neste artigo:
Artigo no estilo Curso Online.

Desvendando a SQL – Parte 2
Existe uma grande necessidade em bancos de dados relacionais de efetuar junções entre tabelas, seja para recuperar informações que estão “espalhadas” devido à normalização de dados, ou para sumarizar informações para posterior geração de relatórios, mas o fato é que a junção entre tabelas é necessária e poderíamos dizer até mesmo fundamental.

No entanto, este assunto causa um certo desconforto na maioria dos desenvolvedores de aplicativos que acessam bancos de dados relacionais.

O perfeito entendimento da sintaxe e semântica da cláusula JOIN em instruções SQL é fundamental para que se obtenha o melhor desempenho possível ao recuperar dados de um bando de dados relacional.

Particularmente nesta segunda e última parte deste artigo, serão abordadas as junções entre tabelas do tipo cross join, que resulta em um produto cartesiano, e também as junções do tipo self join, onde é feita a junção de uma tabela com ela mesma. Ao final apresento um pequeno estudo de caso onde utilizamos a junção entre tabelas para resolver um problema cotidiano.

A correta utilização desta técnica, além de facilitar muito a leitura e interpretação da semântica da consulta sendo executada, em vários casos pode oferecer um ganho de performance dependendo do grau de maturidade e inteligência do sistema de gerenciamento de banco de dados relacional que se executa a consulta.

Em que situação o tema é útil
Em muitos momentos é necessário efetuar junções entre tabelas para buscar dados relativos a determinada informação. Em bancos de dados relacionais, a utilização da metodologia de normalização de dados é uma prática comum, amplamente difundida e muito correta porém, devido à normalização de dados, em muitos momentos é necessário efetuar junções entre tabelas para que se possa reconstruir uma informação completa. É neste tipo de situação que a correta utilização da junção entre tabelas na SQL se mostra bastante útil.

No primeiro artigo desta série apresentamos questões importantes com relação à utilização da cláusula WHERE para efetuar junções entre tabelas (muitas vezes necessárias por conta do uso de práticas de normalização na definição da base de dado (ler Box 1)). Sem dúvida nenhuma é a maneira mais utilizada entre os desenvolvedores de aplicações.

A grande maioria dos sistemas de gerenciamento de bancos de dados relacionais já adquiriram “inteligência” suficiente para interpretar este tipo de implementação e “converter” implicitamente em junções para poder elaborar os planos de execução de maneira a obter o melhor desempenho possível.

Mas infelizmente não podemos garantir que cem por cento dos sistemas de gerenciamento de bancos de dados relacionais possuem esta “inteligência”, o que pode ocasionar em consultas com desempenho muito aquém do desejado.

A utilização da cláusula JOIN resolve completamente este problema, pois ela foi criada exatamente para a finalidade de efetuar junções.

Outro fator que também se apresenta como muito importante para que utilizemos a cláusula JOIN é a facilidade de visualização do código da consulta. Entenda esta facilidade no tocante a manutenção, pois é muito mais fácil analisar uma consulta com cada componente no seu devido lugar (junções na cláusula JOIN e predicados na cláusula WHERE) do que uma consulta onde tudo está na cláusula WHERE e será necessário uma análise mais detalhada para “separar o joio do trigo”.

E vamos combinar: a utilização da cláusula JOIN deixa a consulta muito mais elegante.

As junçõs apresentadas no primeiro artigo foram:

· Inner join:

o Equi-join e Non Equi-join;

o Natural join;

· Outer join:

o Left outer joins;

o Right outer join;

o Full outer join.

Porém, esta não são as únicas maneiras de efetuar junções entre tabelas. Há também:

· Cross Joins: (ou junções cruzadas) são junções onde a condição de junção é omitida, ou seja, cada linha de uma tabela é combinada com cada linha de uma outra tabela. O resultado deste tipo de junção é conhedico como produto cartesiano;

· Self Joins: (ou auto-junção) são junções de uma tabela com ela mesma.

E para tornar esta artigo mais completo, abordarei também os algorítmos de junção:

· Nested Loop Join (ou junção de loop aninhado): é um algoritmo que une dois conjuntos usando dois loops aninhados;

· Block Nested Loop (ou loop de bloco aninhado): é uma variação do algoritmo nested loop;

· Sort-Merge Join: (ou junção do tipo fusão): a ideia principal deste algoritmo é primeiro classificar as relações pelo atributo de junção e, desta forma, as varreduras lineares intercaladas encontrarão os registros ao mesmo tempo;

· Hash Join (ou junção hash): este algoritmo necessita que haja um predicado de equi-join, ou seja, um predicado usado para comparar os valores de uma tabela com os valores da outra tabela usando o operador igual ‘=’.

Box 1. Normalização de Dados

Normalização de Dados é o processo de organização dos campos e tabelas de um banco de dados relacional para minimizar a redundância e dependência. Normalização normalmente envolve a divisão tabelas grandes em tabelas menores (e menos redundantes) e definindo as relações entre elas. O objetivo é isolar os dados de modo que as inserções, exclusões e alterações de campos possam ser feitas em apenas uma tabela e então propagadas através da base de dados utilizando os relacionamentos definidos.

Edgar F. Codd, o inventor do modelo relacional, introduziu o conceito de normalização que hoje conhecemos como a Primeira Forma Normal (1FN, ou 1NF – First Normal Form) em 1970. Codd então definiu a Segunda Forma Normal (2FN, ou 2NF – Second Normal Form) e a Terceira Forma Normal (3FN, ou 3NF – Third Normal Form) em 1971, e Codd e Raymond F. Boyce definiram a Forma Normal de Boyce-Codd (BCNF – Boyce-Codd Normal Form), em 1974.

Informalmente, uma tabela de banco de dados relacional é frequentemente descrita como "normalizada" se está na Terceira Forma Normal e a grande maioria das tabelas na 3FN são livres de anomalias tanto para inserção quanto para atualização ou exclusão.

A orientação padrão de projeto de banco de dados é que o Arquiteto de Dados deve criar um modelo totalmente normalizado. Uma eventual desnormalização seletiva pode, posteriormente, ser realizada por motivos de desempenho.

Um objetivo básico da Primeira Forma Normal, definida por Codd, em 1970, foi o de permitir que os dados sejam consultados e manipulados usando uma "sub-linguagem universal de dados", fundamentada na lógica de primeira ordem (SQL é um exemplo deste tipo de sub-linguagem universal de dados, ainda que Codd a considerava como falha).

Os objetivos da normalização além Primeira Forma Normal foram definidos por Codd da seguinte forma:

1) Para libertar a coleção de relacionamentos de indesejáveis dependências de inserções, atualizações e exclusões;

2) Para reduzir a necessidade de reestruturar a coleção de relacionamentos, por serem introduzidos novos tipos de dados e, assim, aumentar a vida útil dos programas aplicativos;

3) Para tornar o modelo relacional mais informativo para os usuários;

4) Para fazer a coleção de relacionamentos neutra com as estatísticas de consulta, onde estas estatísticas são suscetíveis de mudança à medida que o tempo passa.

Cross Join / Produto Cartesiano

Caso não seja especificada a condição de junção na união de duas tabelas, o SGBDR combina cada linha da primeira tabela com cada linha da segunda tabela. Este tipo de junção é chamada de cross join ou produto cartesiano, ambos os termos estão corretos. O número de linhas de uma cross join é o produto do número de linhas em cada tabela. A Listagem 1 apresenta um exemplo de uma cross join.

Listagem 1. Cross join entre as tabelas FUNCIONARIOS e DEPARTAMENTOS. 01. SQL> SELECT F.NOME||' '||F.SOBRENOME FUNCIONARIO, D.NOME_DEPTO 02. 2 FROM FUNCIONARIOS F 03. 3 CROSS JOIN DEPARTAMENTOS D; 04. 05. FUNCIONARIO NOME_DEPTO 06. ----------------------------------------- ------------------------- 07. Ricardo Rezende Vendas 08. Joao da Silva Vendas 09. Leonardo Souza Vendas 10. Rafaela Bastos Vendas 11. Felipe Carvalho Vendas 12. Olavo Santos Vendas 13. Samantha Xavier Vendas 14. Paulo Ferreira Vendas 15. Manoel Vargas Vendas 16. USjpT USjpT Vendas 17. L L Vendas 18. yevi yevi Vendas 19. kGuOBF kGuOBF Vendas 20. ... 21. ... 22. Ricardo Rezende Recursos Humanos 23. Joao da Silva Recursos Humanos 24. Leonardo Souza Recursos Humanos 25. Rafaela Bastos Recursos Humanos 26. Felipe Carvalho Recursos Humanos 27. Olavo Santos Recursos Humanos 28. Samantha Xavier Recursos Humanos 29. Paulo Ferreira Recursos Humanos 30. Manoel Vargas Recursos Humanos 31. USjpT USjpT Recursos Humanos 32. L L Recursos Humanos 33. yevi yevi Recursos Humanos 34. kGuOBF kGuOBF Recursos Humanos 35. ... 36. ... 37. Ricardo Rezende Engenharia 38. Joao da Silva Engenharia 39. Leonardo Souza Engenharia 40. Rafaela Bastos Engenharia 41. Felipe Carvalho Engenharia 42. Olavo Santos Engenharia 43. Samantha Xavier Engenharia 44. Paulo Ferreira Engenharia 45. Manoel Vargas Engenharia 46. USjpT USjpT Engenharia 47. L L Engenharia 48. yevi yevi Engenharia 49. kGuOBF kGuOBF Engenharia 50. ... 51. ... 52. Ricardo Rezende Tecnologia de Informacao 53. Joao da Silva Tecnologia de Informacao 54. Leonardo Souza Tecnologia de Informacao 55. Rafaela Bastos Tecnologia de Informacao 56. Felipe Carvalho Tecnologia de Informacao 57. Olavo Santos Tecnologia de Informacao 58. Samantha Xavier Tecnologia de Informacao 59. Paulo Ferreira Tecnologia de Informacao 60. Manoel Vargas Tecnologia de Informacao 61. USjpT USjpT Tecnologia de Informacao 62. L L Tecnologia de Informacao 63. yevi yevi Tecnologia de Informacao 64. kGuOBF kGuOBF Tecnologia de Informacao 65. ... 66. ... 67. Ricardo Rezende Compras 68. Joao da Silva Compras 69. Leonardo Souza Compras 70. Rafaela Bastos Compras 71. Felipe Carvalho Compras 72. Olavo Santos Compras 73. Samantha Xavier Compras 74. Paulo Ferreira Compras 75. Manoel Vargas Compras 76. USjpT USjpT Compras 77. L L Compras 78. yevi yevi Compras 79. kGuOBF kGuOBF Compras 80. ... 81. ... 82. Ricardo Rezende Estoque 83. Joao da Silva Estoque 84. Leonardo Souza Estoque 85. Rafaela Bastos Estoque 86. Felipe Carvalho Estoque 87. Olavo Santos Estoque 88. Samantha Xavier Estoque 89. Paulo Ferreira Estoque 90. Manoel Vargas Estoque 91. USjpT USjpT Estoque 92. L L Estoque 93. yevi yevi Estoque 94. kGuOBF kGuOBF Estoque 95. ... 96. ... 97. Ricardo Rezende XAgXTHmlAwVnDyS 98. Joao da Silva XAgXTHmlAwVnDyS 99. Leonardo Souza XAgXTHmlAwVnDyS 100. Rafaela Bastos XAgXTHmlAwVnDyS 101. Felipe Carvalho XAgXTHmlAwVnDyS 102. Olavo Santos XAgXTHmlAwVnDyS 103. Samantha Xavier XAgXTHmlAwVnDyS 104. Paulo Ferreira XAgXTHmlAwVnDyS 105. Manoel Vargas XAgXTHmlAwVnDyS 106. USjpT USjpT XAgXTHmlAwVnDyS 107. L L XAgXTHmlAwVnDyS 108. yevi yevi XAgXTHmlAwVnDyS 109. kGuOBF kGuOBF XAgXTHmlAwVnDyS 110. ... 111. ... 112. buusBIVQCauztX buusBIVQCauztX HkMmQjyagGhWVzReRFdloD 113. IKfvhGpWW IKfvhGpWW HkMmQjyagGhWVzReRFdloD 114. eiOXs eiOXs HkMmQjyagGhWVzReRFdloD 115. Q Q HkMmQjyagGhWVzReRFdloD 116. jbYJVRMVhUI jbYJVRMVhUI HkMmQjyagGhWVzReRFdloD 117. bFL bFL HkMmQjyagGhWVzReRFdloD 118. AOu AOu HkMmQjyagGhWVzReRFdloD 119. KwveCIxJpDWxMpsdF KwveCIxJpDWxMpsdF HkMmQjyagGhWVzReRFdloD 120. 121. 2144754 rows selected. 122. 123. Elapsed: 00:03:22.79"

[...] continue lendo...

Artigos relacionados