Cibersegurança aplicada a banco de dados e seus desafios

Segundo Fernando A. S. F. Junior, colunista do Portal ITForum365, o aumento da conectividade da internet e da economia digital, alimenta um crescimento exponencial de dados acumulados por organizações.


Image result for imagens bancos de dados
Com o aumento da conectividade da internet e da economia digital, alimenta-se um crescimento exponencial de dados acumulados por organizações. Segundo a Forbes, em 2015, o volume de dados criado nos dois anos anteriores foi maior que a quantidade produzida por em toda história da humanidade.

Esse crescimento, aumentou muito o interesse dos cibercriminosos por promoverem invasões – e o fato de haver grande quantidade de informações em um só lugar favorece isso – e também o números de ferramentas e recursos de proteção contra ataques. Como os dados se tornaram protagonistas nas empresas, o vazamento de informações estratégicas pode resultar em processos milionários e até mesmo na quebra do negócio.

Continue Lendo “Cibersegurança aplicada a banco de dados e seus desafios”

Dica do Mês – Identificando os números ausentes em uma sequência numérica


Olá pessoal, bom dia.

Tudo bem? Estamos no ultimo final de semana do mês de Setembro, a primavera chegou, já estamos vivendo a última estação do ano, 2019 voando, passando de forma extremamente rápida, o que muitas vezes não nos deixa perceber o quanto nossa vida é uma correria.

Mesmo com este correira, temos que tentar aproveitar todo tempo disponível dentro das 24 horas diárias para se dedicar também ao que gostamos de fazer, e por isso estou aqui novamente em mais um post do meu blog, que honra ter encontrar aqui neste sábado, sua presença é muito importante.

Ainda mais na sessão Dica do Mês, a qual foi criada á alguns anos com objetivo de compartilhar algo que possa ser considerada como uma dica ou melhores práticas para se trabalhar na área de banco de dados, mais especificamente com o Microsoft SQL Server.

A dica de hoje esta envolvida diretamente com os dados manipulados diariamente por empresas, instituições ou organizações públicas e privadas, me refiro a lançamento feitos através de um SIG – Sistema de Informação Gerencial ou ERP – Enterprise Resource Planning, que muitas vezes utilizamos para dar entrada em lançamento contábeis, movimentações fiscais e financeiras, ou “basicamente” cadastrar uma nota fiscal de recebimento de produto no almoxarifado da empresa.

Para facilitar o entendimento, e server como base de exemplo para nossa dica, dentre as mais diversas áreas, setores e departamentos que constituem uma empresa, selecione para esta dica, uma das mais tradicionais áreas conhecida por muitos como Controle de Estoque vinculado com os lançamentos contábeis.

Mais ainda não ficou claro o objetivo desta dica, não é mesmo? Tenho a certeza que não, mas tenha calma, você vai descobrir a seguir o que estou querendo te apresentar.

Continue Lendo “Dica do Mês – Identificando os números ausentes em uma sequência numérica”

Dica do Mês – Analisando o comportamento do comando DBCC CleanTable.


Olá, bom dia. Tudo bem?

O frio já chegou na sua região? Aqui em São Roque, interior de São Paulo, hoje esta manhã esta sendo considerada até o presente momento a mais fria do ano (eu particularmente adoro o frio).

Fico extremamente contente e honrado com a sua visita ao meu blog, mesmo com todo este frio ter a sua presença aqui é muito importante, ainda mais neste post da sessão Dica do Mês, a qual foi criada á alguns anos com objetivo de compartilhar algo que possa ser considerada como uma dica ou melhores práticas para se trabalhar na área de banco de dados, mais especificamente falando relacionadas ao Microsoft SQL Server.

Posso dizer que o post de hoje é algo bastante simples, vamos conhecer um pouco mais sobre um dos mais tradicioais comandos pertencentes a categoria DBCC – Database Command Console existente no Microsoft SQL Server desde suas versões iniciais.

Estou me referindo ao comando DBCC CleanTable, considerado por muitos DBAs o “Veja, aquele produto de limpeza que utilizamos para tirar a gordura dos fogões e panelas”, ele faz basicamente isso em nossas tabelas. No decorrer deste post vou tentar mostrar como Podemos fazer isso.

Sendo assim, sem mais delongas, vamos em frente, vou tentar mitigar a sua curiosidade e ao mesmo também satisfazer os meus objetivos. Seja bem-vindo ao post – Dica do Mês – Analisando o comportamento do comando DBCC Clean Table.


Introdução

O Microsoft SQL Server apresenta em sua galeria de comandos um conjunto muito particular e exclusivo denominado DBCC – Database Command Console em uma possível tradução para o Português “Comandos de Console de Banco de Dados“, pois bem, este conjunto com categoria de comandos é composta por uma relação bem interessante e diversificada que nos permite fazer uso em diversos cenários, dentre eles por exemplos os comandos: DBCC CheckDB ou DBCC ShrinkFile, ambos muito conhecidos pelos DBAs e Administradores de Banco de Dados, caso você ainda não conheça, com certeza em algum momento terá a oportunidade.

Como já destaquei nesta relação exclusiva de comandos, podemos se deparar com um deles que nos permite aplicar sem qualquer tipo de alteração de configuração, ou mudanças drásticas na estrutura de nosso banco de dados, o que chamamos de remover a gordura de nossas tabelas, talvez você não consiga ou não esteja entendendo o que eu estou definindo como “gordura”, na verdade me refiro por exemplo a aquelas colunas do tipo de dados VarChar, criadas inicialmente em nossas tabelas, mas que ao longo do tempo se tornam colunas praticamente consideradoras espúrias (algo sem sentido ou desnecessário), é ai que entra o nosso amigo DBCC CleanTable, ele tem um papel único e específico justamente para este tipo de cenário, que daqui a pouco eu vou demonstrar, mas antes vamos conhecer um pouquinho sobre este comando.

DBCC CleanTable

Adicionado ao Microsoft SQL Server a partir da edição 2008, o comando DBCC CleanTable possui como papel principal a capacidade de recuperar e liberar o espaço ocupado por colunas existentes em uma tabela consideradas colunas com comprimento variável quando utilizam os seguintes tipos de dados:

  • Varchar;
  • Nvarchar;
  • Varchar(max);
  • Nvarchar(max);
  • Varbinary;
  • Varbinary(max);
  • Text;
  • Ntext;
  • Image;
  • Sql_variant; e
  • XML.

Ele recupera espaço anteriormente ocupado por um destes tipos de dados, depois que uma coluna de comprimento variável é descartada, mas não recupera espaço depois que uma coluna de comprimento fixo é descartada.

Mesmo não tem a capacidade de recuperar o espaço ocupado em disco logo após este limpeza na estrutura da tabela, o comando DBCC CleanTable, pode ajudar a melhorar ou até mesmo zerar taxas de fragmentação que possam estar sendo apresentadas justamente em uma tabela devido a utilização destas colunas com comprimentos variáveis.

Considerações

  • As colunas descartadas forem armazenadas em linha, DBCC CLEANTABLE recuperará espaço da unidade de alocação IN_ROW_DATA da tabela.
  • Quando as colunas forem armazenadas fora de linha, o espaço será recuperado da unidade de alocação LOB_DATA ou ROW_OVERFLOW_DATA, dependendo do tipo de dados da coluna descartada.Se o espaço recuperado de uma página ROW_OVERFLOW_DATA ou LOB_DATA resultar em uma página vazia, DBCC CLEANTABLE removerá a página. DBCC CLEANTABLE executa como uma ou mais transações.
  • O espaço recuperado de uma página ROW_OVERFLOW_DATA ou LOB_DATA resultar em uma página vazia, DBCC CLEANTABLE removerá a página. DBCC CLEANTABLE executa como uma -ou mais transações.
  • Caso não especificado um tamanho de lote, o comando processará a tabela inteira em uma transação e a tabela será bloqueada exclusivamente durante a operação. Para algumas tabelas grandes, o comprimento da única transação e o espaço do log requeridos podem ser muito grandes. Se um tamanho de lote for especificado, o comando executará em uma série de transações, cada qual incluindo o número especificado de linhas.
  • O comando DBCC CLEANTABLE não pode ser executado como uma transação dentro de outra transação. Essa operação é totalmente registrada. Não há suporte para DBCC CLEANTABLE para uso em tabelas do sistema, tabelas temporárias ou a parte do índice columnstore xVelocity de memória otimizada de uma tabela.

Evite utilizar

O comando DBCC CLEANTABLE não deve ser executado como uma tarefa de manutenção de rotina. Ao invés disso, utilize o DBCC CLEANTABLE depois de fazer mudanças significativas em colunas de comprimento variável em uma tabela ou exibição indexada e necessita recuperar o espaço sem-uso (considerada como área não alocada) prontamente.

Alternativas para o uso do DBCC CleanTable

Uma das possíveis alternativas quando desejamos recuperar o espaço ocupado por colunas de comprimemto variável aplica-se a reconstrução de índices em tabelas ou visões indexadas, mas este recurso pode ser considerado custoso no que se relaciona ao tempo de processamento ou até mesmo alocação de recursos durante sua execução.

Pois bem, agora que já conhecemos um pouco sobre este comando, suas considerações, o quando usar e não usar, vamos avançar um pouco este post, dando início a nosso cenário de estudos afim de analisarmos de uma forma bem simples e artificial como o DBCC CleanTable pode nos ser útil.


NOSSO AMBIENTE

Como de costume vamos utilizar um ambiente isolado dos demais bancos de dados que você possa conter, desta maneira nosso cenário será constituído dos seguintes elementos:

Observações

  1. Estaremos fazendo uso de um arquivo texto, o qual é parte importante para nossa análise. O mesmo possui os dados que serão importados para o Microsoft SQL Server, contendo com conjunto real de valores coletados através do portal do INPEInstituto Nacional de Pesquisas Especiais, através de seu Banco de Dados de análise de queimadas ocorridas no Brasil ao longo dos últimos 70 anos, sendo considerada uma das mais importantes fontes de dados abertos do Brasil, disponível para qualquer tipo de análise. Particularmente falando, sou um grande admirador do trabalho realizado pelo INPE, o qual eu comecei em 2017 a estudar para um dos meus projetos no mestrado e diretamente relacionados com a minha nova área de estudos: Data Warehouse, Data Mining e BI.
  2. A estrutura apresentada no arquivo texto, não tem por finalidade ou regra ser considerada uma estrutura padronizada, como também, algo que atenda as regras da Normalização, longe disso, todo conjunto de dados, tipos de dados, nomes das colunas e sua composição física e lógica foi definida e criada para atender as regras de negócio muito específicas de um trabalho de mestrado acadêmico, o qual não faz parte deste estudo ou análise.
  3. O objetivo deste post não se realiza a apresentar, demonstrar ou orientar como realizar o procedimento de importação de dados para o Microsoft SQL Server, sendo assim, caso você tenha dúvidas ou dificuldades para realizar este procedimento, acesse: Import and Export Data with the SQL Server Import and Export Wizard.
  4. Logo após a execução do processo de importação dos dados, você notará que nossa tabela e sua estrutura foi criada sem respeitar uma análise de uso de tipos de dados, criação de chaves primárias ou outras considerações que podemos definir como melhores práticas de modelagem de banco de dados. Não foi fique preocupado, pois estaremos realizando toda esta reestruturação logo na sequência.

Avançando mais um pouco, vamos criar nosso banco de dados e logo na sequência começaremos nossa análise, para tais procedimentos, utilizaremos o Bloco de Código 1 abaixo:

— Bloco de Código 1 – Criando nosso cenário —

— Criando o Banco de Dados —

Create Database TesteDBCCCleanTable
Go

— Acessando o Banco de Dados —

Use TesteDBCCCleanTable
Go

Presumo que neste momento você já tenha feito download do arquivo QueimadasTableCleanTable.txt, como também, já tenha realizado a importação dos dados e criação da tabela,.

Ótimo, espero que todo processo de importação de dados tenha ocorrido corretamente, agora com a estrutura criada e acessível, teremos a possibilidade de começar a realizar nossa análise, nosso próximo passo será reestrutura a tabela QueimadasCleanTable, definindo sua chave primária, alterando tipos de dados em determinadas colunas, removendo outras, enfim colocando um pouco de ordem na casa.

Desta forma, vamos utilizar o Bloco de Código 2 a seguir:

— Bloco de Código 2 – Reestruturando a Tabela QueimadasCleanTable —

— Remover a Anulabilidade da coluna CodigoQueimada —
Alter Table QueimadasCleanTable
Alter Column CodigoQueimada Int Not Null
Go
— Adicionar a coluna chave primária na Tabela QueimadasCleanTable —
Alter Table QueimadasCleanTable
Add Constraint [PK_QueimadasCleanTable_Codigo]
Primary Key (CodigoQueimada)
Go
— Alterando o Tamanho e Tipo de Dados da Coluna Pais —
Alter Table QueimadasCleanTable
Alter Column Pais Char(6) Not Null
Go
— Alterando os tipos de dados e tamanho da coluna Satelite —
Alter Table QueimadasCleanTable
Alter Column Satelite Varchar(10) Not Null
Go
— Alterando os tipos de dados e tamanho das colunas —
Alter Table QueimadasCleanTable
Alter Column Municipio Varchar(40) Not Null
Go
Alter Table QueimadasCleanTable
Alter Column Estado Varchar(20) Not Null
Go
Alter Table QueimadasCleanTable
Alter Column Bioma Varchar(15) Not Null
Go
— Alterando o formato do dado armazenado na coluna DataHora —
Update QueimadasCleanTable
Set DataHora=Convert(DateTime, DataHora, 102)
Go
— Alterando a Coluna DataHora —
Alter Table QueimadasCleanTable
Alter Column DataHora DateTime Not Null
Go
— Alterando a Coluna Longitude —
Alter Table QueimadasCleanTable
Alter Column Longitude Numeric(10,5) Not Null
Go
— Alterando a Coluna Latitude —
Alter Table QueimadasCleanTable
Alter Column Latitude Numeric(10,5) Not Null
Go

Ufa, após este longo caminho percorrido, nossa tabela QueimadasCleanTable, deve estar apresentando uma estrutura similar a Figura 1:


Figura 1 – Banco de Dados TesteDBCCCleanTable e Tabela QueimadasCleanTable criados.

Sensacional, agora a brincadeira vai começar, devemos ter basicamente 752.252 (Setecentas e cinquenta e duas mil, duzentas e cinquenta e duas) linhas de registros lógicos inseridas nesta tabela, uma massa de dados interessante e bem diversificada para nosso estudo, afim de confirmarmos nossas massa de dados, vamos executar o Bloco de Código 3 a seguir, para retornarmos em tela uma pequena porção de dados:

— Bloco de Código 3 – Validando uma porção de dados da Tabela QueimadasCleanTable —

Select Top 1000 DataHora,
Satelite,
Pais,
Estado,
Municipio
From QueimadasCleanTable
Go

Após a execução do Bloco de Código 3, você deverá ter obtido em tela, um resultado similar ao apresentado abaixo pelo Figura 2:

Figura 2 – Dados coletados e apresentados em tela após a execução do Bloco de código 3.

Por enquanto nenhuma novidade, nada em especial foi apresentado, não é mesmo? Eu acredito que sim. Agora que toda estrutura da tabela foi refeita, nossos dados foram validados, o que pode estar faltando para fazermos uso do comando DBCC CleanTable?

A resposta é simples, falta identificar quais são as colunas de comprimento variável existentes em nossa tabela que poderemos utilizar para entender o comportamento deste comando, sendo assim, nosso próximo passo será identificar quais seriam as colunas e seus respectivos tipos de dados que formam a estrutura da tabela QueimadasCleanTable, através da execução do Bloco de Código 4 apresentado abaixo:

— Bloco de Código 4 – Identificando as colunas de comprimento variável —

Select st.name As ‘TableName’,
sc.name As ‘ColumnName’,
sc.column_id As ‘ColumnID’,
sty.name As ‘DataType’,
sc.max_length As ‘MaxLength’
from sys.tables st Inner Join sys.columns sc
on st.object_id = sc.object_id
Inner Join sys.systypes sty
on sc.system_type_id = sty.xtype
Where st.name = ‘QueimadasCleanTable’
And sty.name = ‘VarChar’
Order By st.Name Asc, sc.column_id Asc
Go

Note que estamos fazendo uso das conhecidas e tradicionais tabelas de sistema:

  • sys.tables;
  • sys.columns; e
  • sys.systypes.

A execução do Bloco de Código 4 é simples e rápida, a Figura 3 abaixo, deve ilustrar o resultado obtido após sua execução:

Figura 3 – Relação de colunas que utilizam o tipo de dados Varchar() com tamanho variáveis.

Estamos quase lá, já sabemos da existência de 7(sete) colunas que neste momento fazem parte da estrutura da nossa tabela QueimadasCleanTable que nos possibilitam serem utilizadas.

Como eu destaquei anteriormente o comando DBCC CleanTable tem como papel principal recuperar o espaço ocupado por estas colunas, quando as mesmas venham a ser removidas ou sofram alterações em seus tamanhos.

Para que possamos entender de forma clara e didática como o DBCC CleanTable trabalha, temos a necessidade de identificar os espaços ocupados neste momento por nossa tabela, e obrigatoriamente as taxas de alocação e fragmentação de dados, vamos então executar o Bloco de Código 5, o qual vai nos ajudar a identificar o espaçamento ocupado por nossa tabela:

— Bloco de Código 5 – Identificando o espaço e áreas de alocação ocupadas pela Tabela QueimadasCleanTable —

— Identificando os espaços ocupados —
sp_spaceused ‘QueimadasCleanTable’
Go
— Identificando as taxas de alocação, fragmentação e distribuição de registros —
Select object_name(ddips.object_id) As ‘Tabela’,
si.name As ‘Índice’,
convert(decimal(5,2),isnull(ddips.avg_fragmentation_in_percent,0)) As ‘% Média de Fragmentação’,
convert(decimal(5,2),isnull(ddips.avg_page_space_used_in_percent,0)) As ‘% Média de Espaço utilizado’,
ddips.page_count As ‘Páginas’,
ddips.compressed_page_count As ‘Páginas compactadas’,
ddips.record_count As ‘Registros’,
ddips.ghost_record_count As ‘Registros Fantasmas’
From sys.dm_db_index_physical_stats(db_id(), object_id(‘QueimadasCleanTable’),null, null, ‘detailed’) ddips Inner Join sys.indexes si
on si.object_id = ddips.object_id
Go
Acredito que você deve ter observado que o Bloco de Código 5 foi dividido em duas partes, a primeira fazendo uso da System Stored Procedure: SP_SpaceUsed, e a segunda, através da DMF – Dynamic Management Function – sys.dm_db_index_physical_stats.
Como uma forma de ajudar a identificar e entender os dados coletados após a execução deste bloco de código, apresenta abaixo a Tabela 1 com os dados coletados através SP_SpaceUsed e Tabela 2 com os dados coletados através sys.dm_db_index_physical_stats.
Tabela 1 – SP_SpaceUsed – Espaços Ocupados
name rows reserved data index_size unused
QueimadasCleanTable 752252 81736 KB 81272 KB 312 KB 152 KB
Ao realizarmos uma breve análise, podemos observar através dos resultados apresentados na Tabela 1, que nosso tabela QueimadasCleanTable, neste momento esta ocupando uma área em disco de quase 82Mbs (Megabytes), sendo 81.2Mbs para dados e 312Kbs (Kilobytes) para índices, com uma área não alocada de 152Kbs.
Tabela 2 – Sys.dm_db_index_physical_stats – Taxas de Fragmentação, Distribuição de Páginas de Dados e Registros
Tabela Índice % Média de Fragmentação % Média de Espaço utilizado Páginas Páginas compactadas Registros Registros Fantasmas
QueimadasCleanTable PK_CodigoQueimada_Queimadas2018_CleanTable 0.01 99.34 10159 0 752252 0
QueimadasCleanTable PK_CodigoQueimada_Queimadas2018_CleanTable 0.00 44.07 37 0 10159 0
QueimadasCleanTable PK_CodigoQueimada_Queimadas2018_CleanTable 0.00 5.92 1 0 37 0
Já os dados apresentados pela Tabela 2, mostram uma pequena taxa de fragmentação de 0,01 % para nosso índice chave primária: PK_CodigoQueimada_Queimadas2018_CleanTable, em sua área de alocação de dados, composta por 10.159 páginas de dados.
Estamos próximos da hora da verdade, com todo esta conjunto de dados coletados, poderemos comprovar como o DBCC CleanTable pode nos ajudar, através do Bloco de Codigo 6, realizaremos a exclusão de 4 (Municipio, Bioma, AreaIndu e FRP) das 7 colunas listadas anteriormente, logo na sequência vamos repetir a execução do Bloco de Código 5 para comprovar que as áreas e espaços ocupados continuam apresentando os mesmos valores, e nosso ultimo passo será executar o DBCC Clean Table.
— Bloco de Código 6 – Removendo as colunas Municipio, Bioma, AreaIndu e FRP —
Alter Table QueimadasCleanTable
Drop Column Municipio, Bioma, AreaIndu, FRP
Go
As colunas foram removidas corretamente, agora vamos repetidar a execução do Bloco de Código 5 na sequência.
— Executar novamente o Bloco de Código 5 —
— Identificando os espaços ocupados —
sp_spaceused ‘QueimadasCleanTable’
Go
— Identificando as taxas de alocação, fragmentação e distribuição de registros —
Select object_name(ddips.object_id) As ‘Tabela’,
si.name As ‘Índice’,
convert(decimal(5,2),isnull(ddips.avg_fragmentation_in_percent,0)) As ‘% Média de Fragmentação’,
convert(decimal(5,2),isnull(ddips.avg_page_space_used_in_percent,0)) As ‘% Média de Espaço utilizado’,
ddips.page_count As ‘Páginas’,
ddips.compressed_page_count As ‘Páginas compactadas’,
ddips.record_count As ‘Registros’,
ddips.ghost_record_count As ‘Registros Fantasmas’
From sys.dm_db_index_physical_stats(db_id(), object_id(‘QueimadasCleanTable’),null, null, ‘detailed’) ddips Inner Join sys.indexes si
on si.object_id = ddips.object_id
Go
A Figura 4, vai ilustrar e comprovar que os valores apresentados após a nova execução do Bloco de Código 5, são os mesmos obtidos em sua primeira execução:
Figura 4 – Valores obtidos após a segunda execução do Bloco de Código 5.
E agora chegou o grande momento, vamos executar o Bloco de Código 7, o qual terá a responsabilidade de executar o comando DBCC CleanTable, logo na sequência vamos executar novamente o Bloco de Código 5, e ai sim teremos uma surpresa:
— Bloco de Código 7 – Executando o comando DBCC CleanTable —
Dbcc CleanTable(TesteDBCCCleanTable,’dbo.QueimadasCleanTable’)
Go
Por padrão como boa parte dos comandos DBCCs, o CleanTable, vai retornar na guia de mensagens a seguinte frase:
DBCC execution completed. If DBCC printed error messages, contact your system administrator.”
Agora repita novamente a execução do Bloco de Código 5, e observe que teremos um novo conjunto de valores apresentados.
— Executar novamente o Bloco de Código 5 —
— Identificando os espaços ocupados —
sp_spaceused ‘QueimadasCleanTable’
Go
— Identificando as taxas de alocação, fragmentação e distribuição de registros —
Select object_name(ddips.object_id) As ‘Tabela’,
si.name As ‘Índice’,
convert(decimal(5,2),isnull(ddips.avg_fragmentation_in_percent,0)) As ‘% Média de Fragmentação’,
convert(decimal(5,2),isnull(ddips.avg_page_space_used_in_percent,0)) As ‘% Média de Espaço utilizado’,
ddips.page_count As ‘Páginas’,
ddips.compressed_page_count As ‘Páginas compactadas’,
ddips.record_count As ‘Registros’,
ddips.ghost_record_count As ‘Registros Fantasmas’
From sys.dm_db_index_physical_stats(db_id(), object_id(‘QueimadasCleanTable’),null, null, ‘detailed’) ddips Inner Join sys.indexes si
on si.object_id = ddips.object_id
Go
As tabelas 3 e 4 apresentadas na sequência, vamos nos ajudar a identificar estes novos valores apresentados após a execução do Bloco de Código 7:
Tabela 3 – SP_SpaceUsed – Espaços Ocupados
name rows reserved data index_size unused
QueimadasCleanTable 752252 81736 KB 81272 KB 312 KB 152 KB
Ao analisarmos os valores apresentados na Tabela 3, inicialmente podemos ficar surpresos por não ocorreram mudanças, na verdade não vai ocorrer mesmo, pois como destacado no início deste post o DBCC CleanTable não tem a função de liberar o espaço físico e lógico ocupado pela tabela e suas estruturas.
Tabela 4 – Sys.dm_db_index_physical_stats – Taxas de Fragmentação, Distribuição de Páginas de Dados e Registros
Tabela Índice % Média de Fragmentação % Média de Espaço utilizado Páginas Páginas compactadas Registros Registros Fantasmas
QueimadasCleanTable PK_CodigoQueimada_Queimadas2018_CleanTable 0.01 80.99 10159 0 752252 0
QueimadasCleanTable PK_CodigoQueimada_Queimadas2018_CleanTable 0.00 44.07 37 0 10159 0
QueimadasCleanTable PK_CodigoQueimada_Queimadas2018_CleanTable 0.00 5.92 1 0 37 0
Por outro lado, a Tabela 4 nos apresenta uma pequena mudança na coluna % Média de Espaço Utilizado que agora é de 80,99 % e antes era de 99,34%, ou seja, ao realizarmos a execução das colunas: Municipio, Bioma, AreaIndu e FRP o DBCC CleanTable realizou uma pequena recuperação de espaço que estava sendo ocupados por estas colunas em suas respectivas linhas de registro lógicos.
Isso não é algo fora do comum, conseguir reaproveitar as áreas que estavam sendo ocupadas anteriormente sem precisar realizar qualquer tipo de reconstrução ou mudanças de configuração. Eu acredito que sim.
Seguindo a tradição dos posts desta sessão, antes de encerrarmos, gostaria de contar com a sua participação neste post, respondendo a enquete abaixo:
Quero propor um desafio
Elabore um cenário similar ao apresentado aqui, e utilize os comandos Delete e Truncate Table em conjunto com o DBCC CleanTable, faça uma análise comparativa, tenho a certeza que este desafio vai lhe ajudar a entender de forma simples e objetiva as diferenças entre o Delete e o Truncate, sendo esta, uma das dúvidas mais recorrentes que podemos encontrar na internet.
Com isso chegamos ao final de mais um post da sessão Dica do Mês, espero que você tenha gostado, eu como de costume gostei muito. 

REFERÊNCIAS

https://docs.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-cleantable-transact-sql

https://docs.microsoft.com/pt-br/sql/relational-databases/system-stored-procedures/sp-spaceused-transact-sql

https://docs.microsoft.com/pt-br/sql/relational-databases/system-stored-procedures/sp-columns-transact-sql

https://docs.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-db-index-physical-stats-transact-sql

https://docs.microsoft.com/en-us/sql/relational-databases/system-compatibility-views/sys-systypes-transact-sql

https://docs.microsoft.com/en-us/sql/t-sql/data-types/data-types-transact-sql

POSTS ANTERIORES

CONCLUSÃO

Como de costume, tenho um imenso prazer em poder compartilhar um pouco das minhas experiências, estudos e conhecimentos que estou diariamente formando sobre este fantástico Sistema Gerenciador de Banco de Dados chamado Microsoft SQL Server.

Neste post, tivemos a possibilidade de relembrar um pouco sobre os comandos DBCCs, mais especificamente o DBCC CleanTable, conhecido como o “Veja, desengordurante, das estruturas de tabelas e visões índexadas” existente no Microsoft SQL Server.

O uso desta comando pode ser aplicado, como uma ferramenta de apoio quando temos a necessidade de reaproveitar o espaço antes ocupado por áreas que pertenciam a uma ou mais colunas que venham a utilizar tipos de dados com tamanhos variáveis.

O comando DBCC CLEANTABLE não deve ser executado como uma tarefa de manutenção de rotina, mas sim, como um recurso aplicado em momento específicos e não de uso contínuo.

Através do cenário aqui apresentado, foi possível observar, como este comando é capaz de resdistribuir e aproveitar o espaço ocupado internamente, sem nos forçar a realizar alterações drásticas em nossas tabelas, bem como, mudanças nas configurações do nosso banco de dados ou SQL Server.

Este é o fantástico Microsoft SQL Server, produto tão fascinante que a cada dia eu não consigo deixar de querer estudar e conhecer mais ainda.

Agradecimentos

Agradeço a você por sua atenção e visita ao meu blog. Fique à vontade para enviar suas críticas, sugestões, observações e comentários.

Nos encontramos no próximo post da sessão Dica do Mês a ser publicado em breve.

Um forte abraço.

Até mais.

Dica do Mês – Como ficar “quase louco” utilizando análise combinatória no Microsoft SQL Server


Olá, boa noite.

Estamos no mês de março, carnaval já passou, o primeiro trimestre de 2019 está acabando, e para minha alegria te encontro mais uma vez no meu blog, caso esta seja a sua primeira visita ou acesso, fico mais feliz ainda, seja muito bem-vindo.

Este é mais um post da sessão Dica do Mês, sessão dedicada a compartilhar bimestralmente dicas, novidades, curiosidades e demais assuntos, conteúdos e informações relacionadas ao Microsoft SQL Server, Banco de Dados e Tecnologias de Banco de Dados.

No post de hoje, quero compartilhar com vocês a minha mais nova “loucura” criada em meus ambientes de estudos acadêmicos para ser utilizada no Microsoft SQL Server através do uso da Análise Combinatória, isso mesmo mais uma vez a matemática esta presente em nossas vidas e desta vez foi justamente para permitir a criação de um script que permite criar todas as sequência de combinações de letras e números afim de construir um gerador de placas de carros para todos os estados brasileiros.

 

Não parece realmente coisa de louco, minha esposa disse que sim, eu também acho (kkkkk).

Pois bem, ficou curioso para saber como eu criei mais esta “loucura”? Calma, daqui a pouco eu conto mais sobre isso para você.

Sendo assim, sem mais delongas, vamos em frente, vou tentar mitigar a sua curiosidade e ao mesmo também satisfazer os meus objetivos. Seja bem-vindo ao post – Dica do Mês – Como ficar “quase louco” utilizando análise combinatória no Microsoft SQL Server.


Introdução

Muito se fala que a área de banco de dados, e posteriormente os Sistemas Gerenciadores de Bancos de Dados (SGBDs) nasceram dos métodos, técnicas e também das teorias existentes na Matemática.

A cada dia eu tenho mais certeza que esta analogia é verdadeira, e neste post, eu pretendo justamente mostrar como mais uma vez esta fantástica e grandiosa área de estudos e conhecimentos pode nos ajudar a transformar algo que parece ter um nível de raciocínio tão complexo ou talvez impossível, em algo na verdade simples, fácil e de rápida compreensão.

Para ser mais direto, estou me referindo a análise combinatória, uma das mais variadas áreas de conhecimento e aprendizado existentes na Matemática e que este mero ser humano demorou um bom tempo para conseguir entender de verdade e aplicar de forma bem racional.

ANÁLISE COMBINATÓRIA

Podemos determinar a análise combinatória como sendo um conjunto de possibilidades constituídos por elementos finitos, a mesma baseia-se em critérios que possibilitam a contagem. Realizamos o seu estudo na lógica matemática, analisando possibilidades e combinações.

Por exemplo: Descubra quantos números com 3 algarismos conseguimos formar com o conjunto numérico {1, 2, 3}, olha a teoria de conjuntos aí gente….

  • Conjunto de elementos finito: {1, 2, 3}.
  • Conjunto de possibilidades de números com 3 algarismos: {123, 132, 213, 231, 312, 321}.

A análise combinatória estuda os seguintes conteúdos:

  • Princípio fundamental da contagem;
  • Fatorial;
  • Permutação simples;
  • Permutação com repetição;
  • Arranjo simples; e
  • Combinação simples.

Não vou abortar todos estes conteúdos de estudo utilizado pela análise combinatória neste post, mas sim o que mais entendo como importante e de extrema necessidade para o cenário que estaremos utilizando a posterior, sendo estes:

  • Permutação Simples; e
  • Permutação com repetição.

Permutação simples

Na permutação os elementos que compõem o agrupamento mudam de ordem, ou seja, de posição. Determinamos a quantidade possível de permutação dos elementos de um conjunto, com a seguinte expressão:

Pn = n!
Pn = n . (n-1) . (n-2) . (n-3)…..1!

Exemplo: Em uma eleição para representante de sala de aula, 3 alunos candidataram-se: Fernanda, Eduardo e Malú. Quais são os possíveis resultados dessa eleição?

  • Fernanda (F);
  • Eduardo (E); e
  • Malú (M).

Os possíveis resultados dessa eleição podem ser dados com uma permutação simples, acompanhe:

n = 3 (Quantidade de candidatos concorrendo a representante)

Pn = n!

Pn = 3 . 2 . 1!
Pn = 6

Para a eleição de representante, temos 6 possibilidades de resultado, em relação a posição dos candidatos, ou seja, 1º, 2º e 3º lugar.

Veja a seguir os possíveis resultados dessa eleição:

Resultado 1

Resultado 2 Resultado 3 Resultado 4 Resultado 5 Resultado 6
FEM FME EFM EMF MEF

MFE

 

Permutação com repetição

Nessa permutação alguns elementos que compõem o evento experimental são repetidos, quando isso ocorrer devemos aplicar a seguinte fórmula:

Pn(n1,n2,n3…nk)=n!n1!⋅n2!⋅n3!…nk!

  • Pn(n1,n2,n3…nk) = permutação com repetição
  • n! = total de elemetos do evento
  • n1!⋅n2!⋅n3!…nk! = Elementos repetidos do evento

Exemplo: Quantos anagramas são possíveis formar com a palavra CASA. A palavra CASA possui:
4 letras (n) e duas vogais que se repetem (n1).

  • n! = 4!
  • n1! = 2!

Pn(n1)=n!n1!

Pn(n1)=4!2!

Pn(n1)=4⋅3⋅2⋅1!2⋅1!

Pn(n1)=242=12

Anagramas da palavra CASA sem repetição

CASA

ACSA ASCA ASAC SCAA

CSAA

AASC AACS CAAS SAAC SACA

ACAS

Bom, agora que conhecemos um pouco destes conceitos, você pode estar se perguntando:

“O que o Microsoft SQL Server tem haver com isso?”.

Então, tudo, pois ele faz justamente uso destes elementos e dos demais quando queremos realizar as combinações das mais variadas possíveis que envolvem letras, letras e números, ou somente números.

E aí, até aqui tudo tranquilo? Espero que sim, pois daqui em diante começaremos a preparar nosso ambiente e aplicaremos a análise combinatória e as permutações para colocarmos em funcionamento a minha “loucura”.

Para você ter a ideia do nível de loucura que estaremos trabalhando, ao realizar o uso das vinte e seis letras do alfabeto em nosso idioma da língua portuguesa teremos basicamente a seguinte permutação com repetição:

  • n! = 3!
  • n1! = 26!

Ou seja, de forma mais simples, vamos permutar: 26 letras * 26 letras * 26 letras, o que não apresentara um total de: 17.756 (Dezessete Mil, Setecentos e Cinquenta e Seis) combinações de letras distintas.

Mas não terminamos isso nossa caminhada, depois de realizar estas combinações de letras (17.756), vamos fazer uso dos arranjos (este conteúdo eu não abordei), que nos permitirá criar em tempo real todos os agrupamentos entre letras e números (de 0 até 9999), estabelecendo a seguinte fórmula:

Arranjos = LetrasCombinadas(17756) * Numeracao(0…9999) = 177.542.244

os anagramas que vimos apouco, como por exemplo: AAA-0001, o qual vai nos permitir obter um total de: 177.542.244 (Cento e Setenta e Sete Milhões, Quinhentos e Quarente e Dois Mil, Duzentas e Quarenta e Quatro) agrupamentos ou arranjos únicos e distintos que teremos a disposição para serem armazenados.

Não é algo de louco mesmo?

NOSSO AMBIENTE

Como de costume vamos utilizar um ambiente isolado dos demais bancos de dados que você possa conter, desta maneira nosso cenário será constituído dos seguintes elementos:

  • Banco de Dados: GeradorDePlacas;
  • Tabelas: LetrasCombinadas, Numeracao, Placas e FaixasDePlacasPorEstado;
  • CTEs: CTEMeuAlfabeto; e
  • Stored Procedure: P_PesquisarPlacas.

Criando o ambiente

Através do Bloco de Código 1 apresentado abaixo, vamos realizar a criação dos respectivos elementos destacados anteriormente:

 

— Bloco de Código 1 —

 

— Criando o Banco de Dados —

Create Database GeradorDePlacas

Go

 

— Acessando o Banco de Dados —

Use GeradorDePlacas

Go

 

— Desativando a contagem de linhas —

Set NoCount On

Go

 

— Criando a Tabela LetrasCombinadas para armazenar todas as combinações de Letras —

Create Table LetrasCombinadas

(CodigoSequencialLetrasCombinadas SmallInt Primary Key Identity(1,1) Not Null,

SequencialDeLetrasCombinadas Char(3) Not Null)

Go

 

— Criando a Tabela Numeracao para armazenar a faixa numérica de 1 até 9999 —

Create Table Numeracao

(CodigoNumeracao SmallInt Primary Key Identity(1,1) Not Null)

Go

 

— Criando a Tabela Placas para armazenar o CodigoSequencialLetrasCombinadas e o número da Placa —

Create Table Placas

(CodigoSequencialPlacas Int Primary Key Identity(1,1) Not Null,

CodigoSequencialLetrasCombinadas SmallInt Not Null,

CodigoSequencialNumeroPlacas SmallInt Not Null)

Go

 

— Criando a Tabela FaixasDeFaixasDePlacasPorEstado para armazenar as faixas de placas por Estado —

Create Table FaixasDePlacasPorEstado

(CodigoSequencialFaixasDePlacasPoEstado TinyInt Primary Key Identity(1,1) Not Null,

CodigoSequencialFaixasDeLetrasNumerosInicial Char(7) Not Null,

CodigoSequencialFaixasDeLetrasNumerosFinal Char(7) Not Null,

FaixasDePlacasPorEstadoNomeDoEstado Varchar(30) Not Null)

Go

 

— Inserindo a distribuição de Faixas de Placas Por Estado —

Insert Into FaixasDePlacasPorEstado Values (‘AAA0001′,’BEZ9999′,’Paraná’)

Insert Into FaixasDePlacasPorEstado Values (‘BFA0001′,’GKI9999′,’São Paulo’)

Insert Into FaixasDePlacasPorEstado Values (‘GKJ0001′,’HOK9999′,’Minas Gerais’)

Insert Into FaixasDePlacasPorEstado Values (‘HOL0001′,’HQE9999′,’Maranhão’)

Insert Into FaixasDePlacasPorEstado Values (‘HQF0001′,’HTW9999′,’Mato Grosso do Sul’)

Insert Into FaixasDePlacasPorEstado Values (‘HTX0001′,’HZA9999′,’Ceará’)

Insert Into FaixasDePlacasPorEstado Values (‘HZB0001′,’IAP9999′,’Sergipe’)

Insert Into FaixasDePlacasPorEstado Values (‘IAQ0001′,’JDO9999′,’Rio Grande do Sul’)

Insert Into FaixasDePlacasPorEstado Values (‘JDP0001′,’JKR9999′,’Distrito Federal’)

Insert Into FaixasDePlacasPorEstado Values (‘JKS0001′,’JSZ9999′,’Bahia’)

Insert Into FaixasDePlacasPorEstado Values (‘JTA0001′,’JWE9999′,’Pará’)

Insert Into FaixasDePlacasPorEstado Values (‘JWF0001′,’JXY9999′,’Amazonas’)

Insert Into FaixasDePlacasPorEstado Values (‘JXZ0001′,’KAU9999′,’Mato Grosso’)

Insert Into FaixasDePlacasPorEstado Values (‘KAV0001′,’KFC9999′,’Goiás’)

Insert Into FaixasDePlacasPorEstado Values (‘KFD0001′,’KME9999′,’Pernambuco’)

Insert Into FaixasDePlacasPorEstado Values (‘KMF0001′,’LVE9999′,’Rio de Janeiro’)

Insert Into FaixasDePlacasPorEstado Values (‘LVF0001′,’LWQ9999′,’Piauí’)

Insert Into FaixasDePlacasPorEstado Values (‘LWR0001′,’MMM9999′,’Santa Catarina’)

Insert Into FaixasDePlacasPorEstado Values (‘MMN0001′,’MOW9999′,’Paraíba’)

Insert Into FaixasDePlacasPorEstado Values (‘MOX0001′,’MTZ9999′,’Espírito Santo’)

Insert Into FaixasDePlacasPorEstado Values (‘MUA0001′,’MVK9999′,’Alagoas’)

Insert Into FaixasDePlacasPorEstado Values (‘MVL0001′,’MXG9999′,’Tocantins’)

Insert Into FaixasDePlacasPorEstado Values (‘MXH0001′,’MZM9999′,’Rio Grande do Norte’)

Insert Into FaixasDePlacasPorEstado Values (‘MZN0001′,’NAG9999′,’Acre’)

Insert Into FaixasDePlacasPorEstado Values (‘NAH0001′,’NBA9999′,’Roraima’)

Insert Into FaixasDePlacasPorEstado Values (‘NBB0001′,’NEH9999′,’Rondônia’)

Insert Into FaixasDePlacasPorEstado Values (‘NEI0001′,’NFB9999′,’Amapá’)

Insert Into FaixasDePlacasPorEstado Values (‘NFC0001′,’NGZ9999′,’Goiás’)

Insert Into FaixasDePlacasPorEstado Values (‘NHA0001′,’NHT9999′,’Maranhão’)

Insert Into FaixasDePlacasPorEstado Values (‘NHU0001′,’NIX9999′,’Piauí’)

Insert Into FaixasDePlacasPorEstado Values (‘NIY0001′,’NJW9999′,’Mato Grosso’)

Insert Into FaixasDePlacasPorEstado Values (‘NJX0001′,’NLU9999′,’Goiás’)

Insert Into FaixasDePlacasPorEstado Values (‘NLV0001′,’NMO9999′,’Alagoas’)

Insert Into FaixasDePlacasPorEstado Values (‘NMP0001′,’NNI9999′,’Maranhão’)

Insert Into FaixasDePlacasPorEstado Values (‘NNJ0001′,’NOH9999′,’Rio Grande do Norte’)

Insert Into FaixasDePlacasPorEstado Values (‘NOI0001′,’NPB9999′,’Amazonas’)

Insert Into FaixasDePlacasPorEstado Values (‘NPC0001′,’NPQ9999′,’Mato Grosso’)

Insert Into FaixasDePlacasPorEstado Values (‘NPR0001′,’NQK9999′,’Paraíba’)

Insert Into FaixasDePlacasPorEstado Values (‘NQL0001′,’NRE9999′,’Ceará’)

Insert Into FaixasDePlacasPorEstado Values (‘NRF0001′,’NSD9999′,’Mato Grosso do Sul’)

Insert Into FaixasDePlacasPorEstado Values (‘NSE0001′,’NTC9999′,’Pará’)

Insert Into FaixasDePlacasPorEstado Values (‘NTD0001′,’NTW9999′,’Bahia’)

Insert Into FaixasDePlacasPorEstado Values (‘NTX0001′,’NUG9999′,’Mato Grosso’)

Insert Into FaixasDePlacasPorEstado Values (‘NUH0001′,’NUL9999′,’Roraima’)

Insert Into FaixasDePlacasPorEstado Values (‘NUM0001′,’NVF9999′,’Ceará’)

Insert Into FaixasDePlacasPorEstado Values (‘NVG0001′,’NVN9999′,’Sergipe’)

Insert Into FaixasDePlacasPorEstado Values (‘NVO0001′,’NWR9999′,’Goiás’)

Insert Into FaixasDePlacasPorEstado Values (‘NWS0001′,’NXQ9999′,’Maranhão’)

Insert Into FaixasDePlacasPorEstado Values (‘NXR0001′,’NXT9999′,’Acre’)

Insert Into FaixasDePlacasPorEstado Values (‘NXU0001′,’NXW9999′,’Pernambuco’)

Insert Into FaixasDePlacasPorEstado Values (‘NXX0001′,’NYG9999′,’Minas Gerais’)

Insert Into FaixasDePlacasPorEstado Values (‘NYH0001′,’NZZ9999′,’Bahia’)

Insert Into FaixasDePlacasPorEstado Values (‘OAA0001′,’OAO9999′,’Amazonas’)

Insert Into FaixasDePlacasPorEstado Values (‘OAP0001′,’OBS9999′,’Mato Grosso’)

Insert Into FaixasDePlacasPorEstado Values (‘OBT0001′,’OCA9999′,’Pará’)

Insert Into FaixasDePlacasPorEstado Values (‘OCB0001′,’OCU9999′,’Ceará’)

Insert Into FaixasDePlacasPorEstado Values (‘OCV0001′,’ODT9999′,’Espírito Santo’)

Insert Into FaixasDePlacasPorEstado Values (‘ODU0001′,’OEI9999′,’Piauí’)

Insert Into FaixasDePlacasPorEstado Values (‘OEJ0001′,’OES9999′,’Sergipe’)

Insert Into FaixasDePlacasPorEstado Values (‘OET0001′,’OFH9999′,’Paraíba’)

Insert Into FaixasDePlacasPorEstado Values (‘OFI0001′,’OFW9999′,’Pará’)

Insert Into FaixasDePlacasPorEstado Values (‘OFX0001′,’OGG9999′,’Paraíba’)

Insert Into FaixasDePlacasPorEstado Values (‘OGH0001′,’OHA9999′,’Goiás’)

Insert Into FaixasDePlacasPorEstado Values (‘OHB0001′,’OHK9999′,’Alagoas’)

Insert Into FaixasDePlacasPorEstado Values (‘OHL0001′,’OHW9999′,’Rondônia’)

Insert Into FaixasDePlacasPorEstado Values (‘OHX0001′,’OIQ9999′,’Ceará’)

Insert Into FaixasDePlacasPorEstado Values (‘OIR0001′,’OJK9999′,’Maranhão’)

Insert Into FaixasDePlacasPorEstado Values (‘OJR0001′,’OKC9999′,’Rio Grande do Norte’)

Insert Into FaixasDePlacasPorEstado Values (‘OKI0001′,’OLG9999′,’Bahia’)

Insert Into FaixasDePlacasPorEstado Values (‘OLH0001′,’OLN9999′,’Tocantins’)

Insert Into FaixasDePlacasPorEstado Values (‘OLO0001′,’OMH9999′,’Minas Gerais’)

Insert Into FaixasDePlacasPorEstado Values (‘OMI0001′,’OOF9999′,’Goiás’)

Insert Into FaixasDePlacasPorEstado Values (‘OOG0001′,’OOU9999′,’Mato Grosso do Sul’)

Insert Into FaixasDePlacasPorEstado Values (‘OOV0001′,’ORC9999′,’Minas Gerais’)

Insert Into FaixasDePlacasPorEstado Values (‘ORD0001′,’ORM9999′,’Alagoas’)

Insert Into FaixasDePlacasPorEstado Values (‘ORN0001′,’OSV9999′,’Ceará’)

Insert Into FaixasDePlacasPorEstado Values (‘OSW0001′,’OTZ9999′,’Pará’)

Insert Into FaixasDePlacasPorEstado Values (‘OUA0001′,’OUE9999′,’Piauí’)

Insert Into FaixasDePlacasPorEstado Values (‘OUF0001′,’OVD9999′,’Bahia’)

Insert Into FaixasDePlacasPorEstado Values (‘OVE0001′,’OWC9999′,’Espírito Santo’)

Insert Into FaixasDePlacasPorEstado Values (‘OWD0001′,’OYG9999′,’Santa Catarina’)

Insert Into FaixasDePlacasPorEstado Values (‘PEE0001′,’PFQ9999′,’Pernambuco’)

Insert Into FaixasDePlacasPorEstado Values (‘PFR0001′,’PGK9999′,’Pernambuco’)

Insert Into FaixasDePlacasPorEstado Values (‘PGL0001′,’PHE9999′,’Pernambuco’)

Insert Into FaixasDePlacasPorEstado Values (‘SAV0001′,’SAV9999′,’São Paulo’)

Go

 

— Validando os dados inseridos na Tabela FaixasDePlacasPorEstado —

Select * From FaixasDePlacasPorEstado
Go

 

— Inserindo 9999 linhas de registros lógicos na Tabela Numeracao —

Insert Into Numeracao Default Values

Go 9999

 

— Validando os dados inseridos na Tabela Numeracao —

Select * From Numeracao

Go

Muito bem, agora que temos nossa estrutura quase toda montada, vamos avançar mais um pouco e fazer uso da análise combinatória, conforme o Bloco de Código 2 declarado abaixo:

 

— Bloco de Código 2 —

 

— Montando a CTE Recursiva para Gerar todas as combinações de Letras —

;With CTEMeuAlfabeto

As

(Select * From (Values (‘A’),(‘B’),(‘C’),(‘D’),(‘E’),(‘F’),(‘G’),(‘H’),(‘I’),(‘J’),(‘K’),

(‘L’),(‘M’),(‘N’),(‘O’),(‘P’),(‘Q’),(‘R’),(‘S’),(‘T’),(‘U’),(‘V’),

(‘W’),(‘X’),(‘Y’),(‘Z’)) As Alfabeto (LetrasDoAlfabeto)

)

— Inserindo as combinações de letras na Tabela LetrasCombinadas —

Insert Into LetrasCombinadas

Select Distinct Concat(A1.LetrasDoAlfabeto, A2.LetrasDoAlfabeto, A3.LetrasDoAlfabeto) As ConcatenacaoLetrasCombinadas

From CTEMeuAlfabeto A1

Cross Join CTEMeuAlfabeto A2 — Aqui que a mágia acontece —

Cross Join CTEMeuAlfabeto A3 — O cross join vai cruzar e combinar todas as letras —

Order By ConcatenacaoLetrasCombinadas Asc

Go

 

— Validando os dados inseridos na Tabela LetrasCombinadas —

Select * From LetrasCombinadas

Go

Nosso Bloco de Código 2 já deve ter sido processado, pois ele é especificamente o centro das atenções para conseguirmos criar todas as combinações possíveis de letras do nosso alfabeto, que estará criando em poucos segundos um total de: 17.756 (Dezessete Mil, Setecentos e Cinquenta e Seis) combinações de letras distintas.

Ufa, estamos avançando, você vai poder notar neste post, que estou fazendo uso de diversos comandos e técnicas existentes no SQL Server desde as primeiras versões como também outros implementados nas versões mais atuais, dentre eles destaco o uso de Tabela Derivada conforme o comando Select From (Values()) existente desde a versão 2000, e também da CTE – Common Table Expression adicionado ao Microsoft SQL Server a partir da versão 2005.

Vamos avançar mais ainda, pois o objetivo deste post não é mostrar somente o uso da análise combinatória, ao contrário, o estudo aqui criado, me permitiu elaborar alguns cenários que me permitiram adotar formas e técnicas diferentes de realizar todas as combinações entre letras e números afim de processar, criar e armazenar todas as placas criadas justamente na tabela denominada placas.

Destaco que foram criados 3 (três) cenários de estudo de acordo com percepções e análises que realizei, fazendo uso de recursos e técnicas distintas visando identificar o que poderia ser melhor utilizada:

  • Cenário 1 – Inserindo dados na Tabela de Placas através de Loop Condicional;
  • Cenário 2 – Inserindo dados na Tabela de Placas através de CTE Recursiva com Junção Cruzada; e
  • Cenário 3 – Inserindo dados na Tabela de Placas através de Junção Cruzada.

Nota: Tenho a certeza que você vai poder criar outros cenários e novas análises, como também, utilizar os mais variados recursos e funcionalidades existentes no Microsoft SQL Server, reforço mais uma vez que estes cenários são meras amostras de estudo e comparações do meu entendimento.

O objetivo de ter criado estes cenários, possibilitou realizarmos comparações de tempo de processamento no que relaciona ao uso da CPU e consumo de memória RAM para cada um dos cenários.

A Tabela 1 declarada abaixo apresenta um resumo dos valores obtidos durante 5 rodadas de processamento executadas em meu ambiente:

Cenário

Média de Uso de CPU Média do Uso de Memória em GBs Média de Uso de Disco Rígido Tempo Mínimo de processamento

Tempo Máximo de processamento

01 57% 3.5 Gbs 65% 19 Hrs e 23 segundos 21Hrs e 18 segundos
02 34% 2.8 Gbs 42% 33 minutos e 6 segundos 42 minutos e 27 segundos
03 18% 2.0 Gbs 24% 6 minutos e 13 segundos 10 minutos e 25 segundos

Tabela 1 – Resumo comparativo do uso de CPU, Memória e Disco, em conjunto com os tempos de processamento demandados para cada cenário.

Show, agora que temos este pequeno resumo dos tempos de processamento e uso dos principais recursos de hardware, já podemos conhecer cada um dos cenários elaborados abaixo, conforme apresenta o Bloco de Código 3 a seguir:

— Bloco de Código 3 —

 

— Cenário 1 –

 

— Inserindo dados na Tabela de Placas através de Loop Condicional – 19Hrs e 33s de processamento —

 

— Limpando a Tabela de Placas —

Truncate Table Placas

Go

 

— Declarando as variáveis de controle —

Declare @ContadorSequencialTotalPlacasInseridas Int = 1,

@ContadorSequencialParcialPlacasInseridas Int = 1,

@CodigoSequencialLetrasCombinadas Int = 1

 

— Abrindo o Loop de Inserção —

While @ContadorSequencialTotalPlacasInseridas <=(Select Max(CodigoSequencialLetrasCombinadas) From LetrasCombinadas)

Begin

 

Set @CodigoSequencialLetrasCombinadas=(Select CodigoSequencialLetrasCombinadas From LetrasCombinadas

Where CodigoSequencialLetrasCombinadas = @ContadorSequencialTotalPlacasInseridas)

 

While @ContadorSequencialParcialPlacasInseridas <=9999 — Contador a cada 9999 incrementa a variável @ContadorSequencialTotalPlacasInseridas

Begin

Insert Into Placas (CodigoSequencialLetrasCombinadas, CodigoSequencialNumeroPlacas)

Values (@CodigoSequencialLetrasCombinadas, @ContadorSequencialParcialPlacasInseridas)

Set @ContadorSequencialParcialPlacasInseridas         +=1

End

 

Set @ContadorSequencialParcialPlacasInseridas = 1

Set @CodigoSequencialLetrasCombinadas +=1

Set @ContadorSequencialTotalPlacasInseridas +=1

 

End

 

— Cenário 2 –

 

— Inserindo dados na Tabela de Placas através de CTE Recursiva com Junção Cruzada — 33 minutos e 40s de processamento —

 

— Limpando a Tabela de Placas —

Truncate Table Placas

Go

 

— Declarando as variáveis de controle —

Declare @ContadorSequencialTotalPlacasInseridas Int = 1,

@CodigoSequencialLetrasCombinadas SmallInt = 1

 

While @ContadorSequencialTotalPlacasInseridas <=(Select Max(CodigoSequencialLetrasCombinadas) From LetrasCombinadas)

Begin

 

— Realizando a Junção Cruzada entre as Tabelas LetrasCombinadas x CTENumeracao —

;With CTENumeracao

As

(Select 1 As Numero

Union All

Select Numero + 1 From CTENumeracao

Where Numero <=9998

)

Insert Into Placas (CodigoSequencialLetrasCombinadas, CodigoSequencialNumeroPlacas)

Select LC.CodigoSequencialLetrasCombinadas, N.Numero

From LetrasCombinadas LC Cross Join — Aqui acontece a mágia

CTENumeracao N — Cross Joi vai combinar todas as Letras com 9999 números —

Where CodigoSequencialLetrasCombinadas = @CodigoSequencialLetrasCombinadas

Option (MaxRecursion 0)

 

Set @CodigoSequencialLetrasCombinadas +=1

Set @ContadorSequencialTotalPlacasInseridas +=1

End

Go

 

— Cenário 3 –

 

— Inserindo dados na Tabela de Placas através de Junção Cruzada – 10 minutos e 27s de processamento —

 

— Limpando a Tabela de Placas —

Truncate Table Placas

Go

 

— Declarando as variáveis de controle —

Declare @ContadorSequencialTotalPlacasInseridas Int = 1,

@CodigoSequencialLetrasCombinadas SmallInt = 1

 

While @ContadorSequencialTotalPlacasInseridas <=(Select Max(CodigoSequencialLetrasCombinadas) From LetrasCombinadas)

Begin

 

— Realizando a Junção Cruzada entre as Tabelas LetrasCombinadas x Numeracao —

Insert Into Placas (CodigoSequencialLetrasCombinadas, CodigoSequencialNumeroPlacas)

Select LC.CodigoSequencialLetrasCombinadas, N.CodigoNumeracao

From LetrasCombinadas LC Cross Join — Aqui acontece a mágia

Numeracao N — Cross Joi vai combinar todas as Letras com 9999 números —

Where CodigoSequencialLetrasCombinadas = @CodigoSequencialLetrasCombinadas

 

Set @CodigoSequencialLetrasCombinadas +=1

Set @ContadorSequencialTotalPlacasInseridas +=1

End

Go

 

Show, show, e show, nossos três cenários de estudo e testes já estão apresentados, basta você escolher qual deseja brincar, executar, encontrar as melhorias e possíveis falhas que podem existir.

Pra finalizar nossa longa caminhada, apresento o Bloco de Código 4, o qual vai ilustrar como podemos consultar nossas tabelas e obter os dados já inseridos após o processamento de um dos cenários, e por fim o Bloco de Código 5 que apresenta o código utilizado no Bloco de Código 4 transformado em uma Stored Procedure denominada: P_PesquisarPlacas.

— Bloco de Código 4 —

— Apresentando as 100 primeiras Placas Geradas —

Select Top 100 Concat(LC.SequencialDeLetrasCombinadas,’-‘,

Convert(Char(4),Case

When P.CodigoSequencialNumeroPlacas BetWeen 1 And 9 Then Concat(‘000’,P.CodigoSequencialNumeroPlacas)

When P.CodigoSequencialNumeroPlacas BetWeen 10 And 99 Then Concat(’00’,P.CodigoSequencialNumeroPlacas)

When P.CodigoSequencialNumeroPlacas BetWeen 100 And 999 Then Concat(‘0’,P.CodigoSequencialNumeroPlacas)

When P.CodigoSequencialNumeroPlacas BetWeen 1000 And 9999 Then Convert(Char(4),P.CodigoSequencialNumeroPlacas)

End)) As ‘Placa’,

IsNull(F.FaixasDePlacasPorEstadoNomeDoEstado,’Sequência não atribuída…’) As ‘Nome do Estado’

From LetrasCombinadas LC Inner Join Placas P

On LC.CodigoSequencialLetrasCombinadas = P.CodigoSequencialLetrasCombinadas

Left Join FaixasDePlacasPorEstado F

On LC.SequencialDeLetrasCombinadas Between SubString(F.CodigoSequencialFaixasDeLetrasNumerosInicial,1,3)

And SubString(F.CodigoSequencialFaixasDeLetrasNumerosFinal,1,3)

Go

A Figura 1 apresentada abaixo, ilustra o possível resultado obtido após a execução do Bloco de Código 4:

Figura 1 – Relação das 100 primeiras placas de carros criadas e inseridas na tabela Placas.

— Bloco de Código 5 —

 

— Criando uma Stored Procedure para pesquisa de placas —

Create or Alter Procedure P_PesquisarPlacas @LetrasCombinadas Char(3), @SequenciaNumerica SmallInt = Null

As

Begin

 

Set NoCount On

 

Select Concat(LC.SequencialDeLetrasCombinadas,’-‘,

Convert(Char(4),Case

When P.CodigoSequencialNumeroPlacas BetWeen 1 And 9 Then Concat(‘000′,P.CodigoSequencialNumeroPlacas)

When P.CodigoSequencialNumeroPlacas BetWeen 10 And 99 Then Concat(’00’,P.CodigoSequencialNumeroPlacas)

When P.CodigoSequencialNumeroPlacas BetWeen 100 And 999 Then Concat(‘0’,P.CodigoSequencialNumeroPlacas)

When P.CodigoSequencialNumeroPlacas BetWeen 1000 And 9999 Then Convert(Char(4),P.CodigoSequencialNumeroPlacas)

End)) As ‘Placa’,

IsNull(F.FaixasDePlacasPorEstadoNomeDoEstado,’Sequência não atribuída…’) As ‘Nome do Estado’

From LetrasCombinadas LC Inner Join Placas P

On LC.CodigoSequencialLetrasCombinadas = P.CodigoSequencialLetrasCombinadas

Left Join FaixasDePlacasPorEstado F

On LC.SequencialDeLetrasCombinadas Between SubString(F.CodigoSequencialFaixasDeLetrasNumerosInicial,1,3)

And SubString(F.CodigoSequencialFaixasDeLetrasNumerosFinal,1,3)

Where LC.SequencialDeLetrasCombinadas = @LetrasCombinadas

And P.CodigoSequencialNumeroPlacas = @SequenciaNumerica

End

Após a Stored Procedure estar criada, basta realizar sua execução conforme o exemplo apresentado abaixo, passando a sequência de letras e números que você deseja consultar.

Importante: Destaco que algumas combinações de placas de carro ainda não estão sendo utilizadas em nosso território, dentre elas as que começam com as letras: W, X, Y e Z.

 

— Executando a Stored Procedure P_PesquisarPlacas —

Exec P_PesquisarPlacas ‘FBD’,3127

Go

Sensacional, chegamos ao final, missão cumprida e entregue, acredito que este foi um dos estudos mais prazerosos e de grande obtenção de conhecimento que eu realizei nos últimos meses.

Antes de encerrarmos, gostaria de contar com a sua participação neste post, respondendo a enquete abaixo:

 

REFERÊNCIAS

https://www.infoescola.com/matematica/analise-combinatoria/

https://mundoeducacao.bol.uol.com.br/matematica/analise-combinatoria.htm

https://docs.microsoft.com/en-us/sql/t-sql/queries/from-transact-sql

https://docs.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expression-transact-sql

https://www.mssqltips.com/sqlservertip/1042/using-derived-tables-to-simplify-the-sql-server-query-process/

https://docs.microsoft.com/pt-br/sql/t-sql/language-elements/select-local-variable-transact-sql

 

Posts Anteriores

 

CONCLUSÃO

Como de costume, tenho um imenso prazer em poder compartilhar um pouco das minhas experiências, estudos e conhecimentos que estou diariamente formando sobre este fantástico Sistema Gerenciador de Banco de Dados chamado Microsoft SQL Server.

Hoje não seria diferente, mais uma vez você pode notar o quanto ele é capaz de nos surpreender com sua inteligência, sabedoria, e principalmente sua capacidade de conseguir aplicar as mais variadas técnicas existentes da Matemática para solucionar algo que pode parecer tão complexo para o raciocínio humano.

Neste post, utilizei algumas das mais variadas técnicas para se trabalhar com combinações de dados, utilização de dados em memória através de um Select From (Values()), em conjunto com tabelas criadas fisicamente ou tabelas declaradas como expressões em um CTE.

Por fim, fizemos usado mais uma vez da Matemática aplicando a análise condicional em conjunto com seus elementos de permutação e arranjo de valores.

Através dos cenários apresentados, em conjunto com a gama de recursos que ele nos permite utilizar, conseguimos aplicar as mais variadas preposições de análises de dados que nos possibilita identificar qual cenário pode ser a melhor maneira de se tomar uma decisão.

Este é o fantástico Microsoft SQL Server, produto tão fascinante que a cada dia eu não consigo deixar de querer estudar e conhecer mais ainda.

 

Agradecimentos

Agradeço a você por sua atenção e visita ao meu blog. Fique à vontade para enviar suas críticas, sugestões, observações e comentários.

Nos encontramos no próximo post da sessão Dica do Mês a ser publicado em breve.

Um forte abraço, curta esta nova estação do ano que começou a alguns dias atrás, eu adoro o outono.

Até mais.

Microsoft SQL Server 2016 SP1 – Atualização Cumulativa 9 disponível


A Microsoft disponibilizou para download hoje dia 30/05/2018 a Atualização Cumulativa 9 para SQL Server 2016 SP1.

As informações obtidas através do artigo KB4100997 publicado no site de suporte da Microsoft, esta atualização traz correções decorrentes dos problemas apresentados e identificados após o lançamento do SP1 e das atualizações cumulativas anteriores.

Relação de Atualizações Cumulativas disponíveis para o Microsoft SQL Server 2016 Service Pack 1:

SQL Server 2016 SP1 CU8
SQL Server 2016 SP1 CU7
SQL Server 2016 SP1 CU6
SQL Server 2016 SP1 CU5
SQL Server 2016 SP1 CU4
SQL Server 2016 SP1 CU3
SQL Server 2016 SP1 CU2
SQL Server 2016 SP1 CU1
SQL Server 2016 SP1
SQL Server 2016 all builds

Hotfixes que estão incluídos neste pacote de atualização cumulativa


Número de bug do VSTS Número de artigo do KB Descrição Corrigir a área
11814294 4099472 PFS página melhoria de algoritmo round robin no SQL Server 2016 Serviço do SQL
11231756 4133164 CORREÇÃO: Erro quando um trabalho do SQL Server Agent executa um comando do PowerShell para enumerar as permissões do banco de dados Ferramentas de gerenciamento
11701139 4086173 CORREÇÃO: Violação de acesso ocorre ao executar uma consulta DAX em um modelo tabular no SQL Server Analysis Services Serviços de análise
11814333 4131193 Problemas de desempenho ocorrem sob a forma de PAGELATCH_EX e PAGELATCH_SH espera em TempDB quando você usar o SQL Server 2016 Serviço do SQL
11829791 3028216 CORREÇÃO: Ocorre uma falha quando o cache pró-ativo é desencadeada por uma dimensão no SSAS Serviços de análise
11829056 4135113 CORREÇÃO: Registro de controle de alterações é inconsistente durante uma atualização em uma tabela que tem um índice cluster/exclusivo no SQL Server Serviço do SQL
11918578 4293839 CORREÇÃO: Banco de dados TDE fica offline durante operações de descarga de log quando problemas de conectividade com o provedor EKM tornar-se inacessível no SQL Server Segurança do SQL
11810404 4230730 CORREÇÃO: Uma condição de morto trava ocorre quando você executar uma reconstrução de índice online ou executa um comando de mesclagem no SQL Server Serviço do SQL
11793118 4163478 CORREÇÃO: Uma violação de acesso ocorre quando incrementais estatísticas são atualizadas automaticamente em uma tabela no SQL Server Desempenho de SQL
11923632 4230306 CORREÇÃO: Restauração de um backup compactado TDE é vencida quando usando o cliente VDI Serviço do SQL
11924460 4163087 CORREÇÃO: Desempenho é lento para um sempre na AG quando você processa uma leitura consulta no SQL Server Serviço do SQL
11684528 4164562 CORREÇÃO: Nome de usuário errado aparece quando dois usuários acesse a MDS em momentos diferentes no SQL Server Serviços de qualidade de dados (DQS)
11634113 4094893 CORREÇÃO: Banco de dados não pode ser descartado após seu armazenamento é desconectado e reconectado no SQL Server Serviço do SQL
11708639 4162814 CORREÇÃO: Ocorre uma violação de acesso de exceção interna e o servidor SSAS para de responder Serviços de análise
11801446 4134541 CORREÇÃO: Erro do MDS Add-in para o Excel quando você usar a versão alemã do Excel no SQL Server Serviços de qualidade de dados (DQS)
11637501 4132267 CORREÇÃO: Implantar um projeto SSAS em SSDT é frequentemente mal sucedido no SQL Server Analysis Services no modo Tabular Serviços de análise
11797887 4101554 CORREÇÃO: Paralelo refazer em uma réplica do secundária de um grupo de disponibilidade que contém tabelas heap gera um despejo de declaração de tempo de execução ou o servidor de SQL falha com um erro de violação de acesso Alta disponibilidade
11750742 4098762 CORREÇÃO: Parâmetros ocultos são incluídos nos relatórios quando o papel do navegador é usado em 2016 SSRS O Reporting Services
11830380 4134175 FIX: Um cubo com várias partições de processamento gera muitas conexões de fonte de dados simultâneos no SSAS Serviços de análise
11591371 4091245 CORREÇÃO: Violação de acesso ocorre quando você consulta uma tabela com uma coluna de inteiro em 2017 de SQL Server e SQL Server 2016 Desempenho de SQL
11714686 4094706 FIX: Um thread de trabalho parece ficar depois que outro thread de trabalho é abortado quando você executa uma consulta paralela no SQL Server Serviço do SQL
11953725 4058175 CORREÇÃO: Backup banco de dados habilitado para TDE e as operações de restauração são lentas quando a chave de criptografia é armazenada em um provedor de EKM no SQL Server Serviço do SQL
11833599 4131960 CORREÇÃO: Uma violação de acesso ocorre quando você executar uma consulta select aninhada contra um índice de columnstore no SQL Server Mecanismo do SQL
11676935 4094858 CORREÇÃO: “ocorreu um erro inesperado” quando você usa o DAX medidas em visualizações de mesa poder BI no SQL Server Serviços de análise
11791348 4101502 CORREÇÃO: Backup de banco de dados habilitada a TDE com a compactação causa corrupção de banco de dados no SQL Server 2016 Serviço do SQL

Dentre os mais diversos bugs identificados e corrigidos destaco um relacionado ao bug de número: 11923632, artigo KB: 4230306, que corresponde um erro apresentado durante a restauração de um backup de banco de dados compactado que utiliza criptografia transparente de dados TDE.

Vale ressaltar que após a atualização desta nova atualização cumulativa, o número do build utilizado pelo Microsoft SQL Server 2016 SP1 será alterado para compilação: 13.0.4502.0.

Para realizar o download clique na imagem abaixo:

Fontes e Direitos Autorais: Suporte da Microsoft – https://support.microsoft.com/pt-br/help/4100997/cumulative-update-9-for-sql-server-2016-sp1 – 30/05/2018.

O SQL Server codinome “Denali” Express CTP3 já está disponível

Dica – SQL Server codinome “Denali” Express CTP3 já está disponível.


sql banner

O SQL Server codinome “Denali” Express Community Technology Preview 3 (CTP3) já está disponível para download gratuito.

» Baixe o SQL Server codinome “Denali” Express CTP3 

O SQL Server codinome “Denali” Express CTP3 apresenta uma nova opção disponível com a instalação – o SQL Server Express LocalDB.  O LocalDB é uma nova versão simples do Express que tem todos os recursos de programação, é executado no modo de usuário, tem uma instalação rápida sem configuração e uma lista curta de pré-requisitos. Para experimentar, basta marcar a caixa quando solicitado durante a instalação do Express.

» Obtenha mais informações sobre o SQL Server Express LocalDB