Desmistificando o collation no SQL Server – Parte 2

Olá!

No último post eu comecei uma série sobre collations no SQL Server. Este post apresenta a segunda parte da série. Você pode conferir a agenda a seguir para se situar:

  • Introdução [Você está aqui]
  • O que são collations
  • Collations do Windows vs Collations do SQL
  • Precedência de Collations
  • Tertiary Weights
  • Query Optimizer e Collations!

Lembrando: Essa parte é muito importante para entender a necessidade do collation. Vamos nessa, fera!?

Como um breve resumo: no último post vimos o que são textos e como eles se diferenciam dos outros tipos de dados. Para resumir:

  • Textos dependem de regras culturais!
  • Textos são formados por elementos menores: O caractere
  • O caractere pode ser uma letra, um algarismo, um sinal de pontuação, um espaço, etc.
  • Computadores trabalham com números somente!
  • O seu monitor/impressora faz um desenho, com base no que algum software ordena… Eles não sabem a diferença entre um o ‘a’ de um texto em um site, e o ‘a’ de uma foto de um documento 😉
  • Em suma: O computador/software representa tudo internamente com números e ordena aos dispositivos que desenhem conforme nós entendemos!

Então, o que você vê na tela como sendo uma letra ‘a’ é na verdade um conjunto de pontinhos(pixels) no seu monitor acesos que formam isso que você chama de letra, ou de interrogação, ou de exclamação, ou a maiúsculo com acento…os softwares e o sistema operacional só trabalham com números, mas dão significados aos números dependendo do contexto em que estão usando eles. Imagine este caractere que está vendo na tela do seu computador: A. Olha o que ele é:

  • O seu navegador web/sistema operacional/computador: 65
  • Para o seu monitor/placa de vídeo: pintar o pixel que está na linha 1001 e coluna 5000, pintar o pixel que está na linha 1002, coluna 5002, etc…
  • Para você: letra A
Uma letra A desenhada no monitor, em um zoom!

Uma letra A desenhada no monitor, em um zoom!

Sacou!? Para o computador/software tudo são números e caracteres são números, e consequentemente, textos são números. Todo o texto que você digita e que você lê, está sendo na verdade representado por uma sequência de números (sequência de caracteres), e em qualquer lugar que ele for exibido, por um monitor e uma placa de vídeo, ou uma impressora, ele vai ser exibido conforme você entende: um conjunto de símbolos, de desenhos. Mas dentro do computador, eles são números, porque o computador é capaz de trabalhar somente com números!

Bom Rodrigo, então se caracteres são números, então qual número representa qual caractere?

E é aqui que você começa a se deparar com um dilema que começou lá no início da computação. Os primeiros computadores/softwares eram capazes de trabalhar somente com números de 256 valores diferentes: 0-255. Para entender melhor isso, precisaríamos de outro post, outra série e provavelmente ela despertaria muitas outras dúvidas… Existe um cara, muito foda extremamente expert neste assunto,  que escreveu uma série de artigos sobre como funciona um computador, mais especificamente, uma CPU, começando falando sobre o que são dados e informações até chegar em como o seu computador carrega o sistema operacional… É simplesmente sensacional, e ele aborda tudo o que você precisa saber para entender detalhes de como um computador consegue representar textos, imagens, fazer cálculos,o que quer dizer computador de 8-bits, de 32-bits, etc. Ele é o B. Piropo (http://www.bpiropo.com.br/). Lá tem muitos artigos excelentes, e eu ainda tenho muita fé que vou ler todos! A série de artigos que estou falando começa com o artigo “Mudança de Rumo” e depois com “Computadores I: Dados e Informações”, e estão na seção “Escritos”, “Colunas Fórum PC”. Você pode usar a busca para encontrar também. O B. Piropo sabe realmente como transformar assuntos complexos, com uma linguagem técnica difícil, em brincadeira de criança. Faça bom proveito!

Mas Rodrigo, espera um pouco… O que esse assunto tem a ver com SQL Server?

Bom, o SQL Server é um SGBD, isto é, um software que gerencia um banco de dados onde informações estão a todo tempo sendo armazenadas e recuperadas, e essas informações podem ser textos, ou melhor dizendo, caracteres :-).
Ele realmente não se preocupa em escrever nada na tela, ou imprimir algo… Porém, ele pode entregar e receber textos de outros softwares… Além disso, ele permite que você ordene, compare, conte caracteres, e muitas outras operações com textos…

Para o computador, um ‘a’ e um ‘A’ são representados por números diferentes, mas para nós, significam a mesma letra, porém uma é maiúscula e outra é minúscula. O mesmo vale quando temos um ‘á’ (para o computador é outro número diferente, mas para nós é um ‘a com acento agudo’). Dependendo como você quer trabalhar com texto, você irá querer ignorar essas diferenças, e mesmo sendo números diferentes, o software deverá ser capaz de lidar com isso. E todas essas operações podem ser afetadas conforme as regras culturais. No japão, por exemplo, os caracteres não são iguais ao que usamos aqui. Então é de suma importância entender toda essa base sobre textos! Os conceitos que irá aprender nessa parte, não vale apenas para o SQL Server, mas para qualquer software que necessite trabalhar com texto.

No próximo post, vamos continuar este assunto e descobrir como os caracteres são representandos por números!

Até lá!

[]’s

Advertisements

Desmistificando o Collation no SQL Server – Parte 1

Oi! Tudo certo!?

Já faz um bom tempo desde o último post, e estou devendo algumas coisas à vocês. Mas estou revendo alguns pontos e tem muita coisa e muito assunto que desejo postar aqui, então em breve creio que irei conseguir me desculpar! 🙂

Recentemente tive a oportunidade de falar de um assunto que parece não ser muito grande… Mas que pode causar muita dor de cabeça: COLLATIONS!

Pensando nisso, vou iniciar mais uma série “Desmitificando”, agora sobre collations. Espero que possa ser útil. A série “Desmitificando o SELECT” também será incrementada com posts novos!

Qual o meu objetivo com essa série?

Vocês já deve ter se deparado com aqueles erros de incompatibilidade de collations… Pois bem geralmente a ação é usar um comando “COLLATE” e está tudo certo.

  • Mas você sabia que existe uma precedência de collations?
  • Sabia que nem sempre collations diferentes vão resultar erros?
  • Sabia que você pode perder dados ao converter um collation para outro?
  • Sabia que o plano de execução gerado para sua query pode ser bem ruim, por conta do collation?

Muitas perguntas né!? E ainda tem  mais… Mas vamos direto ao ponto:

O objetivo desta série é que você domine o collation e saiba exatamente o que está fazendo e o que o SQL Server está fazendo por debaixo dos panos…

Mas, até lá, vamos precisar alinhar umas coisas antes sobre textos e computadores, pois se não fosse por isso, não havia necessidade de collations, ok!? Então senta aí, e vamos conversar um pouco…

Agenda da série (pode ser alterada a cada post)

  • Introdução [Você está aqui]
  • O que são collations
  • Collations do Windows vs Collations do SQL
  • Precedência de Collations
  • Tertiary Weights
  • Query Optimizer e Collations!

TEXTOS E COMPUTADORES

Um número em qualquer lugar do mundo significa a mesma coisa. O número 5 significa a mesma coisa, tanto no Brasil como no Japão, etc. O que pode mudar é a representação. O símbolo ‘5’ pra gente já é suficiente. Com datas, também não é diferente: Se você adicionar 1 dia à data ‘1 de janeiro de 2014’, você sempre vai ter ‘2 de janeiro de 2014’, independente do lugar em que você se encontra! Com textos isso já não é assim, tão simples…

Textos são como nós identificamos e representamos as coisas. As palavras e as letras são usadas por uma determinada cultura, povo, sociedade (chame do que quiser), mas o fato é que dependendo do lugar em que você se encontra no mundo, as regras de escrita podem mudar: Os símbolos para representar as letras (já ouviu falar em acento no S?) são o exemplo mais prático que você pode ter para ilustrar isso…

Computadores são capazes de representar textos e também lidar com essas diferenças. Mas precisam ser informados onde estão, qual o idioma, a região, etc. Sozinhos eles não conseguem sair do outro lado…

Mas os computadores não entendem textos. Apenas números. Um computador, em sua simplicidade é capaz de fazer somente algumas operações básicas, que envolvem números somente! Somar, multiplicar, subtrair… Também podem ler e gravar “dados” na memória… Mas tudo isso usando números somente! Tudo construído em volta de regras matemáticas e com ajuda da eletrônica, que fazem as coisas darem certo.

Também, os computadores são capazes de fazer algo interessante com uma pequena ajuda: Desenhar na tela! Na verdade, quem faz isso é um dispositivo ultra-moderno chamado “Monitor”. Esse cara recebe sinais de uma coisa chamada “placa de vídeo” e sai ativando pontos na tela que exibem a luz em uma determinada cor, conforme lhe é orientado. Mas, o monitor e a placa de vídeo não sabem que estão desenhando letra ‘a’ ou ‘b’… Eles sabem que estão ativando e desativando pixels (os pontinhos, que tem um monte deles)… Esses pixels juntos para nós tem algum significado… Para eles são meros pontinhos que podem ser ativados com uma determinada cor… Para eles, o ponteiro do mouse a letra ‘a’ não passam de pontos na tela!

Textos são compostos por elementos menores; Coisinhas chamadas “caractere”. Um caractere é a menor unidade que forma um texto:

  • A letra ‘A’
  • A letra ‘z’
  • O algarismo 6, o algarismo 1
  • Cada letra do alfabeto é um caractere diferente
  • Um “A” é um caractere, um “a” é outro caractere, um “á” outro, e um “Á” outro: Cada variação de uma mesma letra é um caractere diferente.
  • Os sinais de pontuação (! . , ” @ #, etc.)
  • O espaço (sim! o espaço é um caractere), a tabulação

Entendeu!? Cada coisinha dessa é um caractere e um conjunto de 0 ou mais caracteres formam o que chamamos de STRING, que é a mesma coisa que texto.

Uffaaa!!! Muito assunto né!? Mas se você chegou até aqui é porque acha esse assunto tão legal quanto eu! Vai ver que é de suma importância entender bem a introdução para dominar COLLATIONS! No próximo post vamos continuar a introdução… Até lá!

Relâmpago: Como usar sp_helptext

Essa procedure permite você trazer informações das definições (codigo-fonte) de vários módulos, como triggers, procedures , views, funções, etc.

A sintaxe é:

EXEC sp_helptext ‘schema.NomeObjeto’

O objeto deve estar no mesmo banco onde se está executando o comando acima. Lembre-se que se a definição do objeto estiver criptografado, você não conseguirá ver. Por padrão, a procedure vai exibir no máximo 255 caracteres por linha. (Caso tenha uma linha com mais que isso, podem ocorrer problemas na execução pois ela vai quebrar a continuação da linha).

DICAS:

  • Você pode configurar query shortcuts (veja meu post sobre isso) para facilitar o uso. Em suma, você pode atribuir um atalho a chamada da procedure.
  • Se você optar por exibir no modo “Grid” a formatação do GRID acaba danificando a formatação original..Uma boa técnica é escolher exibir o resultado em texto. Atalho para isso é “CTRL + T”.

Rodrigo Ribeiro Gomes
[]’s

DESMISTIFICANDO O SELECT no SQL SERVER: O FROM – Parte 1

 

E após mais um longo tempo sem postar nada,  vou dando continuidade a nossa série do processamento lógico de um SELECT.

Hoje vamos falar sobre o FROM. No último post eu tentei uma breve explicação sobre o que é o processamento lógico, e a comparação dele com o processamento físico. O objetivo desta série é saber como o SQL Server “entende” uma query e como ele vai manipular as informações para produzir o resultado codificado pelo seu comando de SELECT. De posse desta informação, você pode começar a manipular suas queries e entender porque determinada consulta não está trazendo um resultado que você espera, ou rapidamente poder montar uma solução para um determinado problema.

Assim, vamos falar do processamento lógico como se fosse realmente o que SQL Server faz, e por mais que seja absurdo, não pense em performance agora. Concentre-se em entender qual a semântica por trás de um simples SELECT.

Para recapitular, um simples SELECT: (Utilize os scripts deste post para criar as tabelas)

SELECT
    C.clienteID
    ,C.cidade
FROM
    dbo.Cliente C

Se eu estivesse aprendendo banco de dados agora, e te perguntasse o que esse código faz, provavelmente você diria: “Retorna o ID e cidade de todos os registros da tabela ‘Cliente’ ”. E está certo! Você sabe o que vai ser retornado. Agora se eu te perguntasse, como o SQL Server está fazendo para acessar estes dados você poderia me responder: “Ele está lendo a tabela inteira diretamente”, ou “Ele está usando o índice da tabela”. Não importa como o SQL Server está fazendo, mas você sabe que o que ele está tentando fazer é ler a tabela inteira, e retornar 2 colunas. Independente de como ele vai fazer isso, porque é isto que a query está pedindo.

Agora, imagine que você quisesse saber o seguinte:

Trazer todas as cidades da tabela cliente, junto com o total de pedidos feitos por clientes cujo ID é < 3.

Em uma primeira tentativa, a query abaixo poderia ser uma solução:

SELECT
    C.cidade
    ,COUNT(P.PedidoID) as TotalPedidos
FROM
    dbo.Cliente C
    LEFT JOIN
    dbo.Pedido P
        ON P.ClienteID = C.ClienteID
WHERE
    P.ClienteID < 3
GROUP BY
    C.cidade
cidade               TotalPedidos
-------------------- ------------
Brasilia             5

 

Percebam que a cidade “Goiânia” não aparece no resultado, e a nossa regra de negócio exige que ela apareça. Mas porque ? Onde está o problema ? A coisa fica mais interessante quando você apenas muda um filtro de lugar …

SELECT
    C.cidade
    ,COUNT(P.PedidoID) as TotalPedidos
FROM
    dbo.Cliente C
    LEFT JOIN
    dbo.Pedido P
        ON P.ClienteID = C.ClienteID    
        AND P.ClienteID < 3
GROUP BY
    C.cidade
cidade               TotalPedidos
-------------------- ------------
Brasilia             5
Goiania              0

Agora sim o resultado retornado foi o que queríamos. Porque apenas ao mudarmos o filtro de lugar o resultado produzido foi diferente ? Repostas a estas perguntas serão respondidas quando você entender o processamento lógico.

Neste ponto, você não deve se preocupar em COMO o SQL Server irá fazer determinar operação, mas sim O QUE ele entenderá que deve ser feito. Isso é o processamento lógico!!!!

Conforme vistos no primeiro post, vamos falar agora fase por fase, explicando suas entradas e saídas. Hoje o nosso foco é a primeira fase, a parte do FROM.

 

Tabelas Virtuais

No processamento lógico cada fase produz um resultado, e esse resultado é passado para a próxima fase. Para facilitar, imagine que cada fase produz uma tabela virtual. Eu não vou chamar de “temporária” para você não confundir com as tabelas temporárias que existem na linguagem. Essas “tabelas virtuais” são passadas de fase por fase, e a próxima fase só enxerga a tabela que foi passada a ela, inclusive somente as suas colunas (tem algumas exceções, mas esqueça por agora). Por questões de nomenclatura, eu vou atribuir nomes a essas tabelas para ir facilitando nossa compreensão, mas lembre-se que essas tabelas só são “enxergadas” pelo SQL Server.

A cláusula FROM

A cláusula FROM é a primeira a ser processada. Lá é onde ficam as nossas tabelas e as operações que fazemos com elas.Você pode fazer JOINS, APPLYs e PIVOTs com as tabelas. A fase de processamento do FROM é divido em sub-fases. Cada sub-fase também produz uma tabela virtual que é passada para a próxima sub-fase e por ai em diante. No final, a tabela virtual resultante é retornada do FROM e passada para a próxima fase,que é o WHERE (que veremos em outro post).

A sintaxe do FROM é a seguinte:

FROM
   input OPERAÇÃO input OPERAÇÃO input OPERAÇÃO input [etc…]

Percebam que eu usei o nome “input”. Vou chamar assim porquê esse input pode ser qualquer coisa que retorne uma estrutura de tabela:

  • Uma tabela
  • Uma view
  • Uma tabela derivada
  • Uma CTE
  • Uma Table-Valued Function

NOTA: Se você não conhece essas coisas ainda, não se preocupe. Se concentre que um input é algo que representa uma estrutura de tabela.

A OPERACAO é o que será feito entre os dois inputs. Ela pode ser:

  • JOINS (CROSS,INNER, LEFT, RIGHT,FULL)
  • APPLY (CROSS, OUTER)
  • PIVOT (PIVOT, UNPIVOT)

        As sub-fases da cláusula FROM variam de acordo com cada uma dessas oparações. A sub-fases para um “INNER JOIN” são diferentes para um CROSS JOIN que são diferentes para um “CROSS APPLY” ou um “UNPIVOT”.
    Para simplificar, vamos inicialmente falar somente sobre as sub-fases para todos os tipos de JOINS, pois estes são mais fáceis de se compreender e são usados mais frequentemente.
    Em outro post entraremos em mais detalhes sobre as sub-fases dos outros operadores.

Operadores de Tabela

As operações realizada com as tabelas são feitas através de operadores de tabela. Por exemplo, um “INNER JOIN”. Os operadores de tabela seguem algumas regras já conhecida por nós lá na matemática…Por exemplo, você tem a operação de SOMA. O que é preciso para fazer uma soma acontecer? Você precisa de 2 números para fazer a SOMA. Neste caso, os 2 números chamamos de “operando” e a “soma” é o operador, o qual é representado pelo sinal “+”.

Aqui é a mesma coisa. Por exemplo, para fazer um CROSS JOIN, você precisa de dois inputs. O operador é representado pelo seu próprio nome. Os dois inputs são os nossos operandos. Em versões futuras do SQL Server, podem ser lançados operadores que requeiram somente um input, ou três, ou nenhum …

Ainda, na matemática, se você tem a expressão “1 + 1 + 2”, Você pode fazer “1 + 1”, e do resultado, somar com 2. Ou seja o operador só trabalha com 2 operandos por vez.
Igualmente com os operadores de tabela, se existir mais de 1 operando, é feito a operação entre os 2 primeiros operandos, e o resultado é usado como input para o próximo operador, juntamente com o o outro input, e por ai vai até acabar:

input_A OPERADOR input_B OPERADOR input_C OPERADOR input_D:

    input_A OPERADOR input_B  = input_AB

    input_AB OPERADOR input_C = input_ABC

    input_ABC OPERADOR input_D = input_ABCD

Como acabou as operações, o resultado seria o “input_ABCD”.

As tabelas virtuais retornadas por cada sub-fase serão passadas para a próxima fase, ou serão usadas como inputs para próximas operações, se houver, até acabar todas as cláusulas no FROM. No final, a tabela virtual resultante é passada para a fase de processamento do WHERE. Lembre-se que podemos misturar operadores de diferentes operações: 

A JOIN B APPLY C PIVOT D.

Simplesmente, o resultado do JOIN de A com B é usado para fazer o APPLY com C, e este último resultado é usado para fazer o PIVOT com D.

Mas, de novo, ressalto que iremos apenas falar de JOINs.

AS SUB-FASES

1ª SUB-FASE: Produto Cartesiano

Nesta fase, é feito um produto Cartesiano entre os inputs. Para quem não lembra o produto cartesiano vem lá da teoria de conjuntos. Ele é uma operação onde todos os elementos de um conjunto são combinados com todos os elementos de um outro conjunto. Isto gera um conjunto com TODAS AS COMBINAÇÕES POSSÍVEIS.

Trazendo para o nosso mundo, nesta sub-fase, será gerado uma tabela virtual contendo todas as combinações possíveis de linhas entre os dois inputs.
Se o input da esquerda contém 5 linhas, e o input da direita contém 2 linhas, a tabela virtual gerada aqui vai conter 5 x 2 = 10 linhas. Cada linha da esquerda será associada com cada linha da direita.

E é exatamente isso o que um CROSS JOIN faz. Ele serve para combinar TODAS AS LINHAS dos dois inputs. Quando a operação que está sendo executada é um CROSS JOIN, esta é a única sub-fase que executada para o operador que está sendo processado.

Aqui será retornado a tabela virtual “TVF1”.

JOINS RECAP:

Joins são operações que usamos para combinar linhas de dois inputs. O resultado de uma operação de JOIN é uma tabela que contém as colunas dos dois inputs. Dependendo do JOIN, você pode especificar uma condição, isto é, uma lógica, para determinar as combinações de linhas que vão ser geradas. Podemos combinar linhas usando APPLY. Existe também operadores que podemos combinar dois inputs. Eles diferem um pouco dos JOINS porque combinam colunas, isto é, juntam colunas de diferentes inputs. São: UNION, INTERSECT E EXCEPT. Mas isso é assunto pra outro post, outra série!

 

Bom, por hoje é só. No próximo post irei falar sobre as outras fases.  Até lá, vá revendo os tipos de JOINS. Para este momento entender e vê exemplos de JOINs irão facilitar ainda mais sua compreensão.

E como sempre, desculpem os erros de português. A cada post estou tentando melhorar e ser mais claro. Qualquer dúvida, sugestão, crítica, ou elogios, utilize os comentários! Seu feedback sempre é bem vindo!

[]’s
Rodrigo Ribeiro Gomes
MCTS | MCITP