Dica do Mês – Novidades – SQL Server 2016 – AT Time Zone


Mas que beleza, boa tarde, comunidade.

Após 17 dias acompanhando os 31º Jogos Olímpicos realizados em nosso Brasil, estou voltando a realidade, como sempre um grande emoção em poder conhecer um pouco da diversidade de esportes, culturas, atletas e principalmente dos mais variados países existentes neste mundão de Deus.

Foi justamente inspirado neste momento olímpico que pensei em compartilhar algo relacionado ao SQL Server mas que também esteja envolvido com os jogos, posso dizer que não foi fácil encontrar algo de bate pronto, mas pesquisando aqui, buscando ali acabei encontrando uma pequena novidade bem escondida implementada no Microsoft SQL Server 2016.

Estou me referindo a instrução AT TIME Zone ou melhor dizendo a Fuso Horário algo que tem tudo a ver com olimpíadas e esportes, ainda mais por neste período todos os países do mundo estavam direcionando seus olhares “satélites” na incansável missão de transmitir em tempo real tudo o que estava acontecendo. Imagine você na Austrália no última dia 21 de Agosto, louco para querer saber qual seria o horário de transmissão do Jogo da Seleção Brasileira de Vôlei, se fosse eu estava realmente aflito.

Muito bem, pensando neste e outros possíveis cenários que eu dedico o post de hoje. Seja bem vindo a mais uma dica do mês, começa aqui a Dica do Mês – Novidades – SQL Server 2016 – AT Time Zone.


Um pouco de história…..

Viver em um mundo tão dinâmico, diversificado, que apresenta a cada dia novas tecnologias, culturas e comportamento é algo bastante complexo e complicado, ainda mais quando no deparamos com compromissos realizados fora da nossa região, país ou continente. E para nos ajudar a tentar se organizar em nossa agenda de compromissos que foram criadas as zonas horárias ou fusos horários para cada uma das vinte e quatro áreas em que se divide a Terra e que seguem a mesma definição de tempo.

O termo fuso denomina a porção de superfície esférica compreendida entre dois semiplanos que partem de um diâmetro da esfera, assemelhando-se à superfície externa de um gomo de laranja. Anteriormente, por volta do ano 1300, ou já antes, usava-se o tempo solar aparente, passagem meridiana do Sol, de forma que a hora do meio-dia se diferenciava de uma cidade para outra.

Os fusos horários corrigiram em parte o problema ao colocar os relógios de cada região no mesmo tempo solar médio.

Principais siglas

Sigla Significado Tradução Descrição
GMT Greenwich Mean Time Tempo Médio de Greenwich Refere-se a Greenwich, onde ficou definido por convenção, a base para cálculo internacional de horário.
ST Standard Time Tempo Padrão Hora oficial em cada fuso horário.
DST Daylight Saving Time ou Summer Time Horário de verão Alteração do horário de uma região, designado apenas durante uma porção do ano, adiantando-se em geral uma hora no fuso horário oficial local.
UTC Coordinated Universal Time Tempo Universal Coordenado, tempo civil Os fusos horários são relativos a ele.
UT Universal Time Tempo Universal Usado em astronomia, tem por base a rotação da Terra.
IAT International Atomic Time Tempo Atômico Internacional Sua base são os relógios atômicos.
A.M./P.M. Ante Meridiem/Post Meridiem (do latim) Antes do meio dia/Após o meio dia Usados em povos que consideram um ciclo de 12 horas.
HL Hora Legal Hora oficial do país.

DateTimeOffSet

Pensando em uma maneira de facilitar e melhorar ainda mas a forma de se conseguir identificar os possíveis fusos horários, bem como, trabalhar com estas variações de horário a Microsoft introduziu a partir da versão 2008 um tipo de dados chamado DateTimeOffSet, que basicamente combinava a possibilidade de armazenar valores do tipo data e hora em conjunto com uma representação numérica de fuso horário, conforme o exemplo abaixo:

SELECT CAST(‘2007-05-08 12:35:29. 1234567 +12:15’ AS time(7)) AS ‘time’,

CAST(‘2007-05-08 12:35:29. 1234567 +12:15’ AS date) AS ‘date’,

CAST(‘2007-05-08 12:35:29.123’ AS smalldatetime) AS ‘smalldatetime’,

CAST(‘2007-05-08 12:35:29.123’ AS datetime) AS ‘datetime’,

CAST(‘2007-05-08 12:35:29.1234567+12:15’ AS datetime2(7)) AS ‘datetime2’,

CAST(‘2007-05-08 12:35:29.1234567 +12:15’ AS datetimeoffset(7)) AS ‘datetimeoffset’,

CAST(‘2007-05-08 12:35:29.1234567+12:15’ AS datetimeoffset(7)) AS ‘datetimeoffset IS08601’;

AT TIME ZONE

Chegamos em 2016 e muito ainda se fala das necessidades em converter e armazenar valores de fuso horário diretamente em nossas tabelas de banco de dados, sabendo das dificuldades e também de como seria possível apresentar uma nova maneira de manipular datas e fuso horários a Microsoft introduziu a partir da versão 2016 a nova instrução AT TIME ZONE.

Sendo este responsável em converter um data e hora para o correspondente valor datetimeoffset em conjunto com seu respectivo valor de fuso horário de destino. Sua forma de uso é bastante simples, levando-se em consideração dois parâmetros:

  • Inputdate: Valor que representa um dado no formatos – SmallDateTime, DateTime, DateTime2 ou DateTimeOffSet que pode referenciar de forma clara um valor correspondente uma data no mundo real; e

 

  • Time Zone: Nome da zona de tempo do destino. O SQL Server se baseia em fusos horários que são armazenados no registro do Windows. Todos os fusos instalados no computador são armazenados no seguinte hive do registro: KEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones. Uma lista de fusos horários instalados também é exposta através da exibição de sys.time_zone_info, sendo esta também uma novidade adicionado no SQL Server 2016.

Dentre alguns valores existentes na sys.time_zone_info destaco alguns relacionados ao Brasil:

  1. Atlantic Standard Time;
  2. Bahia Standard Time;
  3. E. South America Standard Time;
  4. Pacific SA Standard Time;
  5. Tocantins Standard Time; e
  6. Central Brazilian Standard Time.

Por padrão o valor retornado na execução da AT TIME ZONE corresponde a um valor data e hora no formato DateTimeOffSet. Seguindo em frente vamos agora ver alguns exemplos de como podemos trabalhar com o mesmo valor de data e hora e obter alguns possíveis valores através da zona de fuso horário, para tal vamos utilizar os blocos de códigos  apresentados abaixo:

— Bloco de Código 1 – Exemplos de uso – AT TIME ZONE – Mesma data com Time Zone distintos — 

Select CONVERT(DateTime, GetDate()) AT TIME ZONE ‘Alaskan Standard Time’ As ‘Alaskan Standard Time’,
CONVERT(DateTime, GetDate()) AT TIME ZONE ‘SA Western Standard Time’ As ‘SA Western Standard Time’,
CONVERT(DateTime, GetDate()) AT TIME ZONE ‘Morocco Standard Time’ As ‘Morocco Standard Time’,
CONVERT(DateTime, GetDate()) AT TIME ZONE ‘Kaliningrad Standard Time’ As ‘Kaliningrad Standard Time’,
CONVERT(DateTime, GetDate()) AT TIME ZONE ‘W. Mongolia Standard Time’ As ‘W. Mongolia Standard Time’
Go

Note que o mesmo valor foi retornado de maneira diferente em relação ao seu respetivo time zone de acordo com o fuso horário identificado pelo SQL Server.

 

— Bloco de Código 2 – Exemplos de uso – AT TIME ZONE – Mesma data com horas diferentes no mesmo Time Zone —

SELECT CONVERT(datetime, ’08/29/2016 10:59:00′)  AT TIME ZONE ‘Central European Standard Time’;
SELECT CONVERT(datetime, ’08/29/2016  12:01:00′)  AT TIME ZONE ‘Central European Standard Time’;
SELECT CONVERT(datetime, ’08/29/2016  11:59:00 PM’)  AT TIME ZONE ‘Central European Standard Time’;

 

— Bloco de Código 3 – Exemplos de uso – AT TIME ZONE – Utilizando tabelas e inserindo valores de dados e seus respectivos Time Zone —

Declare @Calendario Table
(IDDia Int Primary Key Identity(1,1),
Data_FusoHorario DateTimeOffSet,
TimeZone Varchar(100))
Insert Into @Calendario Values (GetDate()-30 AT TIME ZONE ‘Alaskan Standard Time’, ‘Alaskan Standard Time’),
(GetDate()-75 AT TIME ZONE ‘SA Western Standard Time’,’SA Western Standard Time’),
(GetDate()+26 AT TIME ZONE ‘Morocco Standard Time’,’Morocco Standard Time’),
(GetDate()+98 AT TIME ZONE ‘Kaliningrad Standard Time’,’Kaliningrad Standard Time’),
(GetDate()+15 AT TIME ZONE ‘W. Mongolia Standard Time’,’W. Mongolia Standard Time’)
Select IDDia, Data_FusoHorario, TimeZone Data From @Calendario
Go
Ufa, é isso ai simples, fácil e prático……

Chegamos ao final de mais uma dica do mês.

Espero que você tenha gostado deste post,  acredito que as informações e exemplo publicadas aqui possam de alguma maneira ajudar e colaborar em suas atividades diárias, profissionais e ou acadêmicas.

Desejo um forte abraço, agradeço mais uma vez a sua visita.

Até mais.

Microsoft SQL Server Management Studio 16.3


A Microsoft anunciou nesta semana no blog SQL Server Release Services a disponibilidade do SQL Server Management Studio 16.3.

O SQL Server Management Studio (SSMS) é um ambiente integrado para acessar, configurar, gerenciar, administrar e desenvolver todos os componentes do SQL Server.

O SSMS combina um amplo grupo de ferramentas gráficas com vários editores de script avançados para fornecer acesso para desenvolvedores e administradores de todos os níveis de conhecimento ao SQL Server.

Novidades no SQL Server Management Studio 16.3

De acordo com o anúncio da Microsoft, o SQL Server Management Studio 16.3 (build 13.0.15700.28) traz nova opção de autenticação no Active Directory e novos cmdlets do PowerShell para ajudar no gerenciamento de login.

Esta versão também traz suporte preliminar para telas com alta resolução (como monitores Ultra HD ou 4K), suporte para filtragem no nó “Databases” do Object explorer, correções de bugs e muitas outras novidades.

Outro detalhe é que a partir da versão 16.3, as atualizações do SMSS não levarão mais o mês no nome, como atualização de julho ou atualização de agosto, por exemplo.

A lista completa com as novidades pode ser vista no post com o anúncio da Microsoft.

Microsoft SQL Server Management Studio 16.3
O SQL Server Management Studio (SSMS) é um ambiente integrado para acessar, configurar, gerenciar, administrar e desenvolver todos os componentes do SQL Server

O Microsoft SQL Server Management Studio 16.3 está disponível para download aqui, suporta o SQL Server versão 2008 até 2016 e é compatível com o Windows 10, Windows 8, Windows 8.1, Windows 7 (SP1), Windows Server 2012 (64 bits), Windows Server 2012 R2 (64 bits) e Windows Server 2008 R2 (64 bits).

Mais detalhes sobre ele podem ser encontrados aqui.

Fontes e Direitos autorais: Microsoft – Developer Network – https://msdn.microsoft.com/en-us/library/mt238290.aspx

#07 – Para que serve


Boa tarde comunidade, boa tarde Brasil!!!!

Começando mais uma tarde de sábado, neste primeiro final de semana do mês de agosto, clima olímpico e muito feliz em ver que o Brasil foi capaz de fazer uma linda festa ontem na abertura dos Jogos Olímpicos Rio 2016, desejo muito sucesso para todos os participantes principalmente aos atletas brasileiros.

O post dedicado a sessão Para que serve deste mês, também esta no clima olímpico, você pode estar se perguntando o porque eu destaquei na minha abertura este clima. Quando estamos pensando em esporte muitas vezes pensamos que não existem possibilidades ou possíveis situações de um determinado time ou atleta ser superado por outro mais fraco, pode ser definido como algo “Hipotético”, sim “Hipotético” na sua definição com base em diversos dicionários: fictício, figurado, imaginário, suposto. Na área de banco de dados isso também pode ser aplicado, principalmente no SQL Server.

Mas de que maneira podemos pensar em algo hipotético, fictício ou imaginário quando estamos trabalhando com banco de dados? Pergunta que inicialmente pode ser difícil de ser respondida, complexa ou simplesmente hipotético(kkkkk).

Foi então que eu comecei a buscar mais informações em um conceito que pra mim era realmente imaginário de ser adotado, e recentemente em um dos posts publicados nos fóruns de SQL Server aqui no Brasil veio a tona o chamado Índices Hipotéticos.

Essa é uma possível resposta quando estamos trabalhando com banco de dados, fazer uso de índices hipotéticos pode nos ajudar a identificar ou similar possíveis situações de impacto na performance de uma query durante sua execução, ainda mais se estivermos trabalhando com um conjunto volumoso de dados.

Para tentar compartilhar com você um pouco sobre este mistorioso recurso que podemos adotar em nosso ambiente, o post de hoje o próximo da sessão para que serve serão dedicados justamente ao entendimento, criação e uso dos índices hipotéticos.

E como de costume aquelas perguntas já conhecidas dos posts anteriores desta sessão:

E ai, você conhece esta funcionalidade? Já utilizou? Sabe para que ela serve?

Pois bem, estas e outras possíveis perguntas serão respondidas a partir de agora em mais este post da sessão Para que Serve!


Começa agora o #07 – Para que serve – Índices Hipotéticos – Parte I.

Mais um final de semana esta chegando, hoje sexta – feira, você já esta começando a se preparar para desligar sua estação de trabalho, pegar suas coisas e voltar para casa feliz por mais um dia de trabalho duro e gratificante e por saber que fez o melhor possível para manter tudo em ordem em seu local de trabalho, eis que após alguns minutos o seu ramal de telefone toca e no display aparece 2801 – Fernanda Galvão, meu deus você pensa, respira e atende sabendo que ela é a gerente de produção da empresa e para estar ligando no final do dia não deve ser nada muito simples, mesmo assim sabendo dos seus deveres e obrigações realiza o atendimento a ligação e escuta:

Junior Galvão, boa tarde!!!

Aqui é a Fernanda, tudo bem? Estamos com um pequeno problema na emissão do relatório de produção diária, estou aqui com o analista de produção João Pedro, você pode falar com ele?

Junior responde sim, claro!!!

Neste momento, João Pedro apresenta o cenário: Junior, olá boa tarde.

Estou com dificuldades para emitir o relatório de produção diária, ao tentar filtrar os dados por clientes e categoria de clientes, o sistema aparentemente entra em loop de processamento e os dados não são apresentados em tela. 

O que será que pode estar acontecendo? Alguns segundos se passam…. Junior começa a pensar e observa que seu final de semana aparentemente foi por água, ou melhor dizendo o final de semana não vai ser tão tranquilo.

Você responde: João Pedro, boa tarde, vou verificar o que pode esta acontecendo, sei que hoje realizamos algumas mudanças na estrutura da tabela de clientes e categoria de clientes, parece-me que o time de suporte adicionou um novo índice, vou tentar verificar.

João Pedro responde dizendo.

Ok! Junior, fico no aguardo, assim que você tiver uma posição por favor me informe.

Junior responde: Certo, perfeito, deixa comigo, vou verificar o que esta acontecendo garanto que hoje não vou conseguir dar uma resposta mais concreta!

Sabendo justamente que a equipe de suporte esta trabalhando para realizar alguns testes de performance nas tabelas de clientes e categoria de clientes, onde milhares de registros estão sendo processados diariamente, Junior chama um dos seus analistas de suporte Eduardo Galvão e pergunta:

Edu por acaso vocês realizaram alguma alteração na estrutura das tabelas de clientes ou categoria de clientes?

A resposta é simples e direta, sim Junior, estamos fazendo uso de um recurso que até então novo ou supostamente desconhecido para nossa equipe,  pelo que pesquisei é uma funcionalidade conhecida como índices que possuem somente estatíticas mas não existem fisicamente.

Junior responde: Índices somente com estatísticas, índices que não existem, que raio de recurso é esse, por acaso vocês estão se referindo a índices hipotéticos?

Eduardo responde, sim, sim, acredito que seja isso a analista de suporte de banco de dados Maria Luíza, esta fazendo um estudo sobre isso em nosso ambiente de testes e identificou que se fizermos a adoção deste recurso poderemos ter mais facilidade em reconhecer a necessidade de um novo índice ou se o mesmo realmente é útil mesmo após ter sido criado anteriormente.

Junior responde, certo Eduardo, mas este tipo de teste ou implementação deve ser planejada, não podemos simplesmente pesquisar um recurso na internet ou livros e já sair aplicando em nossos ambientes de teste, muito menos em produção, devemos sempre por em prática nosso check-list de boas práticas e principalmente ter um ambiente de contigência caso algo aconteça de errado.

Quero saber qual será a forma para identificar o que esta acontecendo e como vamos resolver este problema até segunda – feira, questiona Junior!!!”

Muito bem, este é nosso cenário, com base, nesta pequena estória que acabamos de conhecer, será criado nosso ambiente de testes para colocar em prática o conceito de índices hipotéticos, antes disso iremos comecer um pouco mais sobre este conceito.

Índices

Falando de uma maneira simples quando criamos um novo índice no SQL Server ou em qualquer outro banco de dados, estamos criando uma estrutura que basicamente servirá como caminho na busca e identificação de um ou mais dados solicitados pelos mecanismos de banco de dados durante o processamento de uma determinada query.

Ao realizar a criação deste elemento normalmente os índices físicos apresentam em sua estrutura os dados, distribuídos de maneira demográfica confome as manipulações são realizadas, além disso, apresentam densidade, granularidade e seletividade de acordo com seu conjunto de valores, com isso, temos um conjunto de informações técnicas conhecidas como estatísticas do índice o que permite servir como elemente auxiliar no obtenção mais ágil e simples dos dados solicitados.

Índices Hipotéticos

Ao se falar de índices hipotéticos, estamos se referindo a uma estrutura completamente oposta, sem qualquer tipo estrutura física, muito menos dados, um índice hipotético é conhecido como algo imaginário que não possue estrutura física, somente estrutura lógica ou seja, somente estatísticas que podem servir como recurso para tentar criar o mecanismo de banco de dados e também o plano de execução por parte do SQL Server na busca de um ou mais dados.

Como podemos criar um índice hipotético?

A partir do SQL Server 2008 R2 a Microsoft adicionou uma opção no comando Create Index conhecido como With Statistics_Only, traduzindo ao pé da letra para o português vamos encontrar ao similar à somente estatísticas. É com base nesta opção não documentada que temos a possibilidade de fazer uso de índices hipotéticos em nossos bancos de dados.

O uso desta opção é muito simples, basta ao final da linha de comando que referencia a criação de um novo índice adicionar a instrução With Statistics_Only = 0, onde o mecanismo de banco de dados vai entender que esta novo índice deverá ser criado possuindo somente uma estrutura lógica controlada e direcionada através dos dados estatísticos coletados durante as manipulações de dados ou execução de querys que fazem uso do mesmo. Quando criamos um novo índice e não informamos esta opção por padrão o mecanismo de banco de dados repassa internamente para processador de querys que este índice deve ser criado da maneira padrão ou seja, um índice que conterá estrutura física e lógica, e o valor correspondente a instrução With Statistics_Only será igual á -1, ou seja:

  • With Statistics_Only = 0 — Indica que o índice deve ser criado de maneira hipotética, índice forma somente por estrutura lógica, conhecida como estatíticas; e
  • With Statistics_Only = -1 — Indica que o índice deve ser criada da maneira clássica, índice formado por estrutura física e lógica.

Uma forma simples é fácil para saber se um ou mais índices apresentam esta diferença pode ser encontrada na visão de sistema sys.indexes através da coluna is_hypothetical, onde a mesma deverá apresentar os valores: 0(zero) ou 1(hum), sendo estes valores que identificam e diferenciam a ocorrência da existência de um ou mais índices clássicos e hipotéticos.

Mas não tudo sem flores como diria meu irmão, a criação de um índice hipotético é fácil, tranquila, sem muitos segredos. Agora, imagine se você deseja orientar otimizador de consultados existentes no SQL Server no uso deste tipo de índice durante o processamento de uma query, ou então se você deseja omitir o seu uso, situação que pode parecer muito comum de ser realizada ou automática, mas não é bem assim.

Temos a necessidade de dirigir isso mesmo, mostrar o caminho que deve ser seguido pelo Database Engine em conjunto com o Query Optimizer e posteriormente o Execution Plan, como deve ser feito o uso de um índice hipotético. Isso parece ser algo bastante complicado, não é bem assim, como sempre existe uma solução que a Microsoft muitas vezes também não reconhece como recurso documentado ou simplesmente não documento, e ai mais uma vez “Mister M de SQL Server” surge para nos ajudar e apresentar ao mundo como uma possível solução pode ser adotada maneira mais suave, mostrando como podemos  resolver este problema e sair desta sinuca de bico.

Pra variar surge para muitos um novo  DBCC – Database Command Console não documentado conhecido como DBCC AutoPilot e uma nova diretiva Set AutoPilot, onde:

  • Set AutoPilot – Orienta o query optimizer a considerar ou não o uso do índice hipotético no momento da criação do plano de execução da query; e
  • DBCC AutoPilot – Orienta o query optimizer fazer uso do índice hipotético de acordo com o conjunto de parâmetros a ser utilizado e posteriormente repassado para o plano de execução.

Preste atenção o nome dele não tem nada haver com piloto de Fórmula 1 (kkkk), vou repetir o seu nome DBCC AutoPilot e ele vai justamente nos ajudar e saber mais sobre os dados que estão relacionados com um determinado índice hipotético.

DBCC AUTOPILOT

Este comando DBCC é mais um dos diversos comandos de console de banco de dados que a Microsoft não reconhece como comando documentado ou suportado nativamente, através do conjunto de instruções “parâmetros” que compõem sua sintaxe o query optimizer vai se comportar de uma determinado maneira ou de outra.

Abaixo apresento a relação de parãmetros que formam o DBCC AutoPilot:

Parâmetro

Descrição
typeid Existem alguns valores, os mais utilizados basicamente são:
Type ID = 5: Iniciar a sessão ou comandos anteriores limpos;
Type ID = 0: Fazer uso de índices não clusterizados; e
Type ID = 6: Usar apenas índices clusterizados.
dbid Id do banco de dados habilitado para executar o comando.
maxQueryCost Supostamente definir um possível custo em relação ao processamento da query. “Sinceramente não entendi bem como usar (kkkk)”
tabid Id da Tabela a ser utilizada.
indid Id do índice a ser utilizado.
pages Ao executar o DBCC AutoPilot simular o comportamento e uso de páginas de dados.
flag Parâmetro desconhecido, não encontrei informações sobre ele….
rowcounts Parâmetro utilizado para definir o número de linhas de execução e processamento para alguns comandos.

Bom vou deixar você agora com um gostinho de quero mais, como destaco anteriormente este é a primeira parte deste Para que serve…. Na segunda parte vamos fazer uso dos índices hipotéticos de maneira prática utilizando a não documentada DBCC AutoPilot.


É isso ai galera, chegamos ao final desta primeira parte de mais um post da sessão Para que serve! Espero que você tenha gostado, que as informações compartilhadas aqui possam lhe ajudar a se tornar cada vez um profisisonal de banco de dados mais reconhecido e valorizado, algo que atualmente as empresas estão deixando muito de reconhecer o verdadeiro papel de um DBA que muitas vezes passa despercebido, mas é de grande e extremo valor para qual instituição, empresa ou corporação.

Caso deseje acessar os posts anteriores desta sessão, utilize os links postados abaixo:

Dica do Mês – Identificando pressão de memória interna e externa no Microsoft SQL Server


Olá comunidade, muito boa tarde.

Tudo bem? Mais um mês que chega ao final, graças a deus este mês de Julho foi complicado, espero que toda a correria que passei mesmo em período de férias não se repita por um longo tempo. Estamos no sétimo post desta nova sessão lançada no início de 2016, muito legal, já temos um pouco de história para contar em relação a aceitação dos visitantes do meu blog em relação a esta sessão.

Como você já deve estar acostumado quando visita o meu blog, todo final de mês é dedicado a post exclusivos das sessões Dica do Mês e Para que Serve. No último post publicado no mês de Junho, apresentei um conteúdo mais focado para área acadêmica, destaquei um dos conceitos mais importantes quando estamos falando de Modelagem de Banco de Dados, a tão temida e misteriosa Normalização(kkkkk), algo que para muitos é um bicho de sete cabeças, mas na verdade não se passa de um gatinho lindo e manhoço.

Como diria aquela boa e velha “Amanheceu pequeno a viola botei na sacola e fui viajar”, no meu caso seria mais ou menos assim: “Amanheceu entrei no meu carro peguei minha mochila e fui trabalhar, anoiteceu entre no meu carro peguei minha apostila e fui lecionar……”.

Deixando a brincadeira de lado no post de hoje vou falar um pouco sobre como podemos identificar o consumo de memória por parte do SQL Server ou Windows através do Management Studio ou Scripts, estou me referindo a chamada pressão de memória interna ou externa.

Então, seja bem vindo a mais uma dica do mês, começa aqui a Dica do Mês – Identificando pressão de memória interna e externa no SQL Server.


Introdução

Uma das maiores preocupação de qualquer profissional de infraestrutura ou administrador de banco de dados é saber se seus recursos de hardware estão atendendo as demandas solicitadas por suas aplicações e usuários.

Quando se referimos a consumo de memória por parte de um servidor de banco de dados, existem pontos que podem nos direcionar a uma pequena confusão, dentre elas destaco:

  • Identificar o quanto uma sessão ou transação esta consumindo de memória;
  • Identificar o quanto um ou mais bancos de dados estão consumindo de memória; ou
  • Identificar o quanto um servidor ou instância de sql server esta consumindo de memória.

Você pode fazer isso, bom identificar o quanto o SQL Server esta consumindo de memória é fácil, basta eu utilizar as ferramentas Task Manager ou Resource Monitor para obter estes dados, na verdade não é bem assim, ambas as ferramentas podem ajudar a encontra vestígios deste possível consumo, o que particularmente não pode ser considerada uma tarefa complexa nem tão simples.

Mas quando se referimos a pressão de memória, o cenário muda totalmente, trata-se de uma situação onde nosso servidor pode por diversos motivos estar sofrendo uma sobrecarga de processamento interno ou externo que gera um consumo elevado ou até mesmo falta de memória para atender todas as requisições que estão sendo disparadas para ele. Seguindo nesta linha de raciocínio a Microsoft disponibilizou a partir da versão do Microsoft SQL Server 2008 e 2008 R2 duas DMVs – Dynamic Management Views (Visões de Gerenciamento Dinâmico):

  • sys_dm_os_ring_buffers: Retorna um conjunto de rings “anéis” de dados que nos permitem relacionar com outras dmv afim de identificarmos problemas de erros de conectividade, faixa exceções, além disso, utilizada também como mecanismo para identificar a saúde de nosso ambiente de banco de dados, sem proporcionar qualquer tipo de pressão de memória, deadlocked ou mudança no comportamento dos agendadores de tarefas em execução.
  • sys_dm_os_sys_info: Retorna um conjunto de informações relacionadas as recursos de hardware utilizados pelo SQL Server, como por exemplo:
    • CPU_TICKS;
    • CPU_COUNT; e
    • Physical_Memory_KB.

Você pode estar pensando, bom já que a sys_dm_os__sys_info apresenta um conjunto de informações relacionadas a hardware que esta em uso pelo SQL Server, é através dela que eu poderei identificar o consumo de memória. Bom se você me pergunta-se isso neste momento a minha resposta seria NÃO.

Porque não, porque estes dados do que esta sendo consumido de maneira interna pelo SQL Server ou até mesmo externamente pelo Windows que possui relação são para muitos conhecidos como ring_buffers ou melhor dizendo ring “anéis”, e são através destes anéis ou basicamente falando com base nestes neles que temos como através da DMV sys.dm_os_ring_buffers coletar os ring_buffers que estão consumindo recursos de memória.

Então se você me perguntar se através da dmv sys.dm_os_ring_buffers podemos obter informações sobre pressão interna ou externa de memória a resposta será SIM. Pois bem, o segredo foi revelado o pulo do gato para saber detalhes escondidos de como o SQL Server coleta e armazena estes anéis é relavado pela sys.dm_os_ring_buffers.

Agora que sabemos os recuros que vamos utilizar para coletar estes dados e identificar os recursos  que estão consumindo memória em nosso ambiente, para tal utilizaremos o bloco de código 1 apresentado a seguir:

— Bloco de Código 1 – Identificando pressão de memória interna e externa —

SELECT CONVERT (varchar(30), GETDATE(), 121) as [RunTime],
dateadd (ms, (rbf.[timestamp] – tme.ms_ticks), GETDATE()) as [Notification_Time],
cast(record as xml).value(‘(//Record/ResourceMonitor/Notification)[1]’, ‘varchar(30)’) AS [Notification_type],
cast(record as xml).value(‘(//Record/MemoryRecord/MemoryUtilization)[1]’, ‘bigint’) AS [MemoryUtilization %],
cast(record as xml).value(‘(//Record/MemoryNode/@id)[1]’, ‘bigint’) AS [Node Id],
cast(record as xml).value(‘(//Record/ResourceMonitor/IndicatorsProcess)[1]’, ‘int’) AS [Process_Indicator],
cast(record as xml).value(‘(//Record/ResourceMonitor/IndicatorsSystem)[1]’, ‘int’) AS [System_Indicator],
cast(record as xml).value(‘(//Record/ResourceMonitor/Effect/@type)[1]’, ‘varchar(30)’) AS [type],
cast(record as xml).value(‘(//Record/ResourceMonitor/Effect/@state)[1]’, ‘varchar(30)’) AS [state],
cast(record as xml).value(‘(//Record/ResourceMonitor/Effect/@reversed)[1]’, ‘int’) AS [reserved],
cast(record as xml).value(‘(//Record/ResourceMonitor/Effect)[1]’, ‘bigint’) AS [Effect],
cast(record as xml).value(‘(//Record/ResourceMonitor/Effect[2]/@type)[1]’, ‘varchar(30)’) AS [type],
cast(record as xml).value(‘(//Record/ResourceMonitor/Effect[2]/@state)[1]’, ‘varchar(30)’) AS [state],
cast(record as xml).value(‘(//Record/ResourceMonitor/Effect[2]/@reversed)[1]’, ‘int’) AS [reserved],
cast(record as xml).value(‘(//Record/ResourceMonitor/Effect)[2]’, ‘bigint’) AS [Effect],
cast(record as xml).value(‘(//Record/ResourceMonitor/Effect[3]/@type)[1]’, ‘varchar(30)’) AS [type],
cast(record as xml).value(‘(//Record/ResourceMonitor/Effect[3]/@state)[1]’, ‘varchar(30)’) AS [state],
cast(record as xml).value(‘(//Record/ResourceMonitor/Effect[3]/@reversed)[1]’, ‘int’) AS [reserved],
cast(record as xml).value(‘(//Record/ResourceMonitor/Effect)[3]’, ‘bigint’) AS [Effect],
cast(record as xml).value(‘(//Record/MemoryNode/ReservedMemory)[1]’, ‘bigint’) AS [SQL_ReservedMemory_KB],
cast(record as xml).value(‘(//Record/MemoryNode/CommittedMemory)[1]’, ‘bigint’) AS [SQL_CommittedMemory_KB],
cast(record as xml).value(‘(//Record/MemoryNode/AWEMemory)[1]’, ‘bigint’) AS [SQL_AWEMemory],
cast(record as xml).value(‘(//Record/MemoryNode/SinglePagesMemory)[1]’, ‘bigint’) AS [SinglePagesMemory],
cast(record as xml).value(‘(//Record/MemoryNode/MultiplePagesMemory)[1]’, ‘bigint’) AS [MultiplePagesMemory],
cast(record as xml).value(‘(//Record/MemoryRecord/TotalPhysicalMemory)[1]’, ‘bigint’) AS [TotalPhysicalMemory_KB],
cast(record as xml).value(‘(//Record/MemoryRecord/AvailablePhysicalMemory)[1]’, ‘bigint’) AS [AvailablePhysicalMemory_KB],
cast(record as xml).value(‘(//Record/MemoryRecord/TotalPageFile)[1]’, ‘bigint’) AS [TotalPageFile_KB],
cast(record as xml).value(‘(//Record/MemoryRecord/AvailablePageFile)[1]’, ‘bigint’) AS [AvailablePageFile_KB],
cast(record as xml).value(‘(//Record/MemoryRecord/TotalVirtualAddressSpace)[1]’, ‘bigint’) AS [TotalVirtualAddressSpace_KB],
cast(record as xml).value(‘(//Record/MemoryRecord/AvailableVirtualAddressSpace)[1]’, ‘bigint’) AS [AvailableVirtualAddressSpace_KB],
cast(record as xml).value(‘(//Record/@id)[1]’, ‘bigint’) AS [Record Id],
cast(record as xml).value(‘(//Record/@type)[1]’, ‘varchar(30)’) AS [Type],
cast(record as xml).value(‘(//Record/@time)[1]’, ‘bigint’) AS [Record Time],
tme.ms_ticks as [Current Time]
FROM sys.dm_os_ring_buffers rbf
cross join sys.dm_os_sys_info tme
where rbf.ring_buffer_type = ‘RING_BUFFER_RESOURCE_MONITOR’
ORDER BY rbf.timestamp ASC

 

Perfeito, após executar este bloco de código o Management Studio vai retornar as linhas de recursos internos e externos que podem estar gerando uma possível pressão de memória para seu servidor ou instância SQL Server, isso vai variar e depender muito de cada ambiente, hardware, versão de sistema operacional e principalmente versão do SQL Server e service pack instalado.


Sendo assim chegamos ao final de mais uma dica do mês.

Espero que você tenha gostado deste post,  acredito que as informações e exemplo publicadas aqui possam de alguma maneira ajudar e colaborar em suas atividades diárias, profissionais e ou acadêmicas.

Fique ligado nos próximos meses, novas dicas relacionadas a sys.dm_os_ring_buffers serão postadas, todas voltadas para ajudar identificar como solucionar problemas que o SQL Server pode estar apresentando e você ainda não percebeu dentre eles erros de segurança.

Desejo um forte abraço, agradeço mais uma vez a sua visita.

Até mais.

Atualização Cumulativa 1 para SQL Server 2016


De acordo com a Microsoft, a Atualização Cumulativa 1 para SQL Server 2016 contém correções para problemas encontrados depois do lançamento do SQL Server 2016.

Entre os bugs corrigidos estão um que causa um problema com as permissões no upgrade para o SQL Server 2016 Master Data Services e um que faz com que o SQL Server 2016 apresente erros quando um atarefa de backup é cancelada.

A lista completa com os bugs corrigidos pode ser encontrada no artigo KB3164674 publicado no site de suporte da Microsoft.

A Atualização Cumulativa 1 para SQL Server 2016 está disponível para download aqui.

Fontes e Direitos Autorais: Microsoft.

Atualização Cumulativa 4 para SQL Server 2012 SP3


A Microsoft disponibilizou para download nesta semana sua Atualização Cumulativa 4 para SQL Server 2012 SP3. O Service Pack 3 (ou SP3) foi lançado em novembro de 2015.

O SP3 trouxe novidades como:

• Aprimoramentos de escalabilidade e desempenho para o mecanismo de armazenamento.

• Melhorias no desempenho da verificação de consistência.

• Dicas de consulta para fornecer controle granular enquanto estiver usando o Resource Governor.

• Adicionais recursos por meio de melhorias na DMV, Extended Events e planos de consulta de monitoramento.

• Melhorar o desempenho ao abrir e ler arquivos XEL usando leitor XEvent Linq.

De acordo com a Microsoft, a Atualização Cumulativa 4 contém as correções para problemas encontrados depois do lançamento do SP3.

A lista com os bugs corrigidos por esta atualização pode ser encontrada no artigo KB3165264 publicado no site de suporte da Microsoft.

Entre os bugs corrigidos estão um que faz com que caracteres Unicode não sejam exibidos corretamente quando eles são copiados de um relatório do SQL Server Reporting Services e um que faz com que o erro “The process cannot access the file” seja exibido quando uma tarefa XML falha no SQL Server.

Atualização Cumulativa 4 para SQL Server 2012 SP3
A Microsoft disponibilizou para download nesta semana sua Atualização Cumulativa 4 para SQL Server 2012 SP3. O Service Pack 3 (ou SP3) foi lançado em novembro de 2015

Baixe a Atualização Cumulativa 4 para SQL Server 2012 SP3

A Atualização Cumulativa 4 para SQL Server 2012 SP3 está disponível para download aqui. Ela é compatível com o Windows 10, Windows 7 SP1, Windows 8, Windows 8.1, Windows Server 2008 R2, Windows Server 2008 R2 SP1, Windows Server 2012 e Windows Server 2012 R2.

Fontes e Direitos Autorais: Baboo. com – 19/07/2016 – 8:53 am.

Material de Apoio – Julho 2016


Hoje é sexta – feira, sexta – feira….. Graças a deus.

Salve galera, bom dia, Tudo bem?

E ai, mês de Julho, férias para boa parte dos estudantes, professores e demais profissionais relacionados a área de educação, assim como eu também. Espero que todos estejam aproveitando este justo e necessário período de descanso, pois muitos pensam que a vida acadêmica é fácil, tranquila e estável, mas posso dizer que não é bem assim.

Pois bem, como você deve ter percebido este é mais um post da sessão Material de Apoio, que a partir deste ano esta sendo publicada a cada três meses. Para você que ainda não conhece esta sessão, ela é uma das mais antigas do meu blog, tendo atualmente mais de 140 posts exclusivos, tendo como objetivo principal compartilhar os códigos de exemplo e scripts existentes em minha biblioteca pessoal de scripts dedicados ao SQL Server desde a versão 7 isso lá nos anos 2000.

Caso você queira acessar os últimos posts, utilize os links apresentados abaixo:

https://pedrogalvaojunior.wordpress.com/2016/04/20/material-de-apoio-abril-2016

https://pedrogalvaojunior.wordpress.com/2016/01/18/material-de-apoio-janeiro-2016/

Seguindo em frente, no post de hoje vou compartilhar com vocês alguns scripts que utilizei recentemente com os meus alunos da Fatec São Roque na Disciplina de Banco de Dados II, dentre os quais destaco:

  • Comando Merge;
  • Comando Begin Catch;
  • Comando Begin Try;
  • Comando Begin Transaction;
  • Comando Commit;
  • Comando Rollback;
  • Comando Print;
  • Common Table Expression;
  • Função de Ranking – Dense_Rank();
  • Função de Ranking – NTile()
  • Função de Ranking – Rank();
  • Função de Ranking – Row_Number();
  • Ordenação de Dados;
  • Operador And;
  • Operador Between; e
  • Operador Is Not Null.

Como de costume gosto sempre de destacar que todos estes arquivos são fruto do meu trabalho realizado como DBA desde 2000 e principalmente da pesquisa e coleta de informações através da internet, onde grande parte do conhecimento aqui compartilhado também obtido através da dedicação e colaboração de seus autores grande profissionais nacionais e internacionais que atuam como profissionais reconhecidos e especialistas nas áreas de:

  • Modelagem de Dados;
  • Engenharia de Banco de Dados;
  • Engenharia de Softwares e Processos;
  • Banco de Dados;
  • Servidores;
  • Alta Disponibilidade;
  • Desenvolvimento;
  • Migração e Contingência de Dados.

Obseravação: Toda e qualquer informação, código, exemplo e lógica utilizada nestes scripts foi aplicada em um determinado cenário, situação ou necessidade, o que em muitos casos talvez não se aplica a sua necessidade mas pode ser útil como material de consulta ou aprendizado.

Além disso, todos os arquivos estão renomeados tendo ao final do seu nome a extensão .doc como forma de compatibilidade com a plataforma do WordPress.com, vale sempre ressaltar que após o seu download será necessário remover esta extensão mantendo a extensão .sql padrão para arquivos do script do SQL Server.

A seguir a relação de scripts:

Exemplo 1 – Utilizando a função Raiserror.sql

Exemplo 2 – Utilizando o Comando Merge.sql

Exemplo 3 – Utilizando o comando Merge + Insert + Update.sql

Exemplo 4 – Utilizando o comando Begin Try.. Begin Catch + Transaction + Print para apresentar mensagem.sql

Exemplo 5 – Trabalhando com função de Ranking.sql

Exemplo 6 – Trabalhando com função de Ranking-2.sql


Legal, chegamos ao final de mais um post, fique a vontade para compartilhar com seus contatos, não deixe de enviar seus comentários, críticas, dicas ou sugestões.

Mais uma vez obrigado por sua visita, por seu interesse e participação.

Uma ótima sexta – feira e bom final de semana.

Abraços.

#06 – Para que serve


Muito boa tarde pessoal……

Mais um dia lindo de muito sol e um pouco de calor para alegrar este sábado! Estou retornando com mais um post dedicado a sessão Para que Serve, sendo este o sexto post desta sessão criada no início de 2016, já passamos da metade do ano.

Pois bem, no post de hoje quero compartilhar com vocês um desafio que passei esta semana realizando a migração de alguns bancos de dados que estavam hospedados em um servidor com o Microsoft SQL Server 2008 R2 Enterprise para um outro servidor rodando o Microsoft SQL Server 2014 Standard.

A princípio algo que parece ser bastante tranquilo pois estamos falando de um upgrade de versão, mas na verdade seria um downgrade de edição, isso mesmo estaria evoluíndo no número da versão mas baixando o nível em relação ao tipo da edição. Foi justamente ai que surgiu o desafio identificar quais recursos meus atuais bancos de dados armazenados na edição Enterprise poderiam ser migrados diretamente para a edição Standard sem correr riscos ou se possível tentar limitar o máximo possível de impactos.

Neste momento, comecei a pensar como poderia realizar este tipo de procedimento de uma maneira fácil, ágil e simples, por alguns instantes pensei que poderia fazer uso do Upgrade Advisor, mas precisa de algo que como eu destaquei acima mais rápido e simples, além disso, uma funcionalidade existente dentro do Management Studio.

Por alguns instantes minha cabeça começou a processamento, me senti um Tom Hanks em um dos seus filmes da série O código da Vinci (nossa quem ve parece que isso seria possível kkkkk) foi como tivesse ocorrido um estálo, um momento de pura nostalgia me fazendo lembrar dos treinamentos de SQL Server 2008 e R2 que ministrei anos atrás(kkkk isso já faz tempo).

Voltando a realidade deixando de lado o momento de ator,  para minha alegria acabei rememorando uma das mais interessantes DMVs – Dynamic Management Views (Visão de Gerenciamento Dinâmica), estou me referindo a: sys.dm_db_persisted_sku_features implementada pela equipe de desenvolvedores e engenheiros do SQL Server a partir da versão 2008 e mantida até as atuais versões incluíndo a nova 2016.

E ai, você conhece esta funcionalidade? Já utilizou? Sabe para que ela serve?

Pois bem, estas e outras possíveis perguntas serão respondidas a partir de agora em mais este post da sessão Para que Serve!


Começa agora o #06 – Para que serve.

Quando pensamos em realizar a migração de um ou mais bancos de dados normalmente temos a necessidade de identificar os possíveis riscos e impactos que esta atividade pode apresentar, para muitos profissionais de banco de dados, administradores, gestores, enfim aqueles que de alguma maneira estão envolvidos neste tipo de cenário querer tentar fazer este procedimento no menor tempo possível, visando gerar o tão temido downtime!!! Isso mesmo tempo de parada que os sistemas podem ficar fora do ar.

Normalmente quando estamos se referindo ao Microsoft SQL Server existem alguns pontos de muito atenção que devemos se atentar um deles é a versão e edição que estamos atualmente utilizando mapeando seus recursos e funcionalidades através de um check-list gerando como resultado um mapeamento de compatilidade para estabelecer o nível de aderencia para a futura versão que vamos utilizar, ainda mais se estiverem planejando realizar o downgrade de edição em conjunto com o upgrade de versão.

Pensando nestes riscos e principalmente no mapeamento a Microsoft introduziu a partir da versão 2008 a DMV sys.dm_db_persisted_sku_features que nos permite de maneira rápida e fácil através do management studio ou via script identificar quais as funcionalidades exclusivas da edição Enterprise que podem estar sendo utilizadas. Como você a edição enterprise apresenta um lista de recursos e funcionalidades exclusivos que tornam esta a edição mais completa e poderosa de todas as edições disponíveis para se utilizar em relação ao SQL Server, dentre estas funcionalidades destaco as mais conhecidas:

Seguindo em frente, agora que já conhecemos algumas das funcionalidades exclusivas da edição Enterprise tendo como base as versões do SQL Server 2008 R2 até a versão 2016, vamos então fazer uso da sys.dm_db_persisted_sku_features, para isso vamos conecte em seu servidor SQL Server, abra uma nova query em seguida execute o bloco de código 1 apresentado abaixo:

— Código 1 — Consultando a lista de recursos habilitados —

Use Master

Go

Select * from sys.dm_db_persisted_sku_features

Go

Pronto, simples e prático, é possível notar que nosso Management Studio retornou um select contendo as colunas:

  1. feature_name = Nome da funcionalidade; e
  2. feature_id = Id ou código da funcionalidade.

Mas nenhum dado foi apresentado em ambas as colunas, isso representa que o banco de dados Master não esta fazendo uso de nenhum recurso exclusivo da edição Enterprise. Então vamos similar o uso de uma funcionalidade exclusiva, para isso vou utilizar como exemplo a CDC ou Change Data Capture, introduzida a partir da versão 2008 SQL Server posteriormente se tornou um recurso nativo do SQL Server. Desta forma, vamos utilizar o bloco de código 2 apresentado abaixo:

— Código 2 — Simulando o uso de uma funcionalidade exclusiva da edição Enterprise

— Criando o Banco de Dados CDC —
Create Database CDC
Go
— Habilitando o CDC para o Banco de Dados —
Use CDC
Go
Exec sys.sp_cdc_enable_db
Go
— Criando a Tabela de Exemplo —
Create Table Produtos
(Codigo Int Identity(1,1) Primary Key,
Descricao VarChar(20))
Go
— Habilitando o Change Data Capture para trabalhar sobre a table Produtos —
EXECUTE sys.sp_cdc_enable_table
@source_schema = N’dbo’,
@source_name = N’Produtos’,
@role_name = N’cdc_Admin’;
GO
Ufa estamos quase lá, agora vamos executar novamente o select na dmv sys.dm_db_persisted_sku_features 1 e observar o retorno de dados apresentados pelo Management Studio:

Select * from sys.dm_db_persisted_sku_features

Go

Muito bem, agora sim, observando o resultado do nosso select podemos notar claramente que estamos fazendo uso de uma funcionalidade exclusiva da edição Enterprise, neste caso será apresentado os seguintes valores:

  1. feature_name = ChangeCapture; e
  2. feature_id = 400.
Legal, muito legal mesmo, que fantástico, como o SQL Server é surpreende, sinceramente esse produto esta sempre me supreendendo com sua capacidade de recursos e funcionalidades, com base, neste simples select fica bem mais fácil obter a lista de funcionalidade exclusivas que estamos utilizando e com isso definir toda a estratégia para migração, upgrade ou qualquer outra técnica que podemos adotar para evitar o máximo possível de riscos e impactos para
nosso ambiente, como também, não proporcionar algum tipo de downtime.
Vale ressaltar que este tipo de recurso pode ser muito útil em ambientes considerados pequenos, mas que pode também ser analisado para cenários mais complexos e críticos.
Sucessooooooo, chegamos ao final de mais um post, tenho a certeza que agora vai ser mais fácil planejar qualquer migração de banco de dados ou versão de SQL Server antes mesmo de realizar esta tão misteriosa, intrigante e talvez complexa atividade.

Valeu galera!

Espero que você tenha gostado, que as informações compartilhadas aqui possam lhe ajudar a se tornar cada vez um profisisonal de banco de dados mais reconhecido e valorizado, algo que atualmente as empresas estão deixando muito de reconhecer o verdadeiro papel de um DBA que muitas vezes passa despercebido, mas é de grande e extremo valor para qual instituição, empresa ou corporação.

Dica do Mês – Você sabe o que é Normalização de Banco de Dados?


Olá galera, bom dia, bom dia comunidade!!!

Estou de volta com mais um post da sessão Dica do Mês, nossa como o tempo esta passando, este é o sexto post desta nova sessão criada este ano no meu blog e que lentamente começa a apresentar alguns resultados. Como você já deve estar acostumado quando visita o meu blog, todo final de mês é dedicado a post exclusivos das sessões Dica do Mês e Para que Serve.

No último post publicado no mês de Maio, apresentei um conteúdo mais focado para área acadêmica e hoje não será diferente, vou falar sobre um dos conceitos mais importantes quando falamos sobre banco de dados, estou me referindo a Normalização de Dados ou para muitos Normalização.

 Acredito que você já deve ter ouvir falar sobre este conceito, para muitos algo bastante complexo, mas na verdade não é bem assim, por isso eu decidi compartilhar com vocês um pouco do meu conhecimento nesta área.

Então, seja bem vindo a mais uma dica do mês, começa aqui a Dica do Mês – Você sabe o que é Normalização de Banco de Dados?


Introdução

Conhecida como técnicas de racionalização das estruturas de dados de um sistema, eliminando redundâncias, problemas de manipulação e armazenamento, basicamente a normalização é um processo através do qual esquemas de relação, que não sejam satisfatórios às características do modelo relacional, são decompostos em esquemas menores que satisfaçam as propriedades desejáveis.

Inicialmente proposta como uma ferramenta de auxílio no projeto físico para a definição de relações, porém na prática tornou-se uma ferramenta de verificação, pois serve para verificar se os esquemas do projeto físico satisfazem algumas características básicas. Estas características são conhecidas como medidas de qualidade que devem obrigatóriamente estar alinhadas as necessidades do projeto de banco de dados e seu modelagem conceitual.

Medidas de Qualidade

Na normalização, são analisadas algumas medidas de qualidade para o projeto de um esquema de relação. Estas medidas de qualidade visam, por exemplo, evitar um mau uso da memória. As medidas são as seguintes:

1 – Correta representação semântica – os dados devem ser projetados de forma a terem seus significados bem definidos e coerentes com o que realmente querem representar;

2 – Redução de valores redundantes – sempre que possível deve-se reduzir ao máximo os valores redundantes desnecessários, ou seja, valores que muitas vezes aparecem repetidos quando isto não seria preciso;

3 – Redução de valores nulos – sempre que possível deve-se reduzir o número de atributos que por alguma razão receberão muitos valores nulos;

4 – Não geração de tuplas espúrias (sem sentido) – durante o processo de normalização deve-se atentar para evitar que sejam geradas tuplas que não façam sentido diante da realidade, isto pode ocorrer devido a alguma decomposição.

Estas medidas de qualidade nos ajudam a estabelecer uma estrutura organizacional para nosso modelo de banco de dados, onde podemos tentar afirmar que estamos criando um cenário para armazenar com coerência.

Outro elemento muito importante quando estamos trabalhando com Normalização é a chamada dependência funcional, conhecida como propriedade da semântica ou do significado dos atributos. Você pode estar se perguntando poxa vida o que seria isso, calma vou tentar se ajudar neste respostas.

Dependência Funcional

As decomposições da normalização ocorrem seguindo os conceitos de dependências funcionais. A seguir estes conceitos serão apresentados, juntamente com as três principais e mais utilizadas formas normais.

Uma dependência funcional (DF) é uma propriedade da semântica ou do significado dos atributos. Formalmente, uma dependência funcional entre dois conjuntos de atributos, x e y, que são subconjuntos de um esquema de relação R, denotada por x® y é uma restrição que estabelece que para quaisquer tuplas t1 e t2 de uma instância r de R, tal que, se temos t1[x] = t2[x], então também devemos ter que t1[y] = t2[y].

Em outras palavras, os valores do componente y em uma tupla de r dependem de (ou são determinados por) valores do componente x.

Por exemplo:  Seja x = {Matrícula} e y = {Nome, Endereço, Telefone, CodCurso}, então {Matrícula} {Nome, Endereço, Telefone, CodCurso}, ou seja, a depender do valor da Matrícula, serão determinados os valores do Nome, Endereço, Telefone, e CodCurso.

Quando se define uma dependência funcional, esta regra deve valer para todas as instâncias da relação, é como se fosse uma restrição de integridade, onde em muitos casos não se pode deduzir a existência de uma dependência, conforme a Figura 1 apresentada abaixo demonstra:

Normalização

Figura 1 – Exemplo de como podemos identificar a existência ou não de dependência funcional.

Seguindo em frente, agora que conhecemos um pouco sobre a normalização, suas medidas de qualidade e seu principal elemento de decomposição chamado dependência funcional, o próximo passo é justamente conhecer e entender um pouco mais sobre esta técnica de decomposição de estrutura, para tal será necessário se aprofundar um pouco mais, vamos então começar a desmistificar as tão temidas Formas Normais (kkkkkk), tenho a certeza que você vai gostar.

Formas Normais Baseadas em Chaves Primárias

O processo de normalização é realizado gradativamente através de formas normais, definidas a partir do conceito de DF. As três principais formas normais são a Primeira Forma Normal (1FN), a Segunda Forma Normal (2FN) e a Terceira Forma Normal (3FN).

1FN  2FN  3FN……

Este processo de normalização é composto por algumas propriedades:

  1. Junções sem perda – uma vez definida uma decomposição, caso esta seja recomposta através de uma operação de junção, no resultado gerado não pode haver perdas;  e
  2. Preservação de dependências – assegura que cada DF seja representada em algumas relações individuais resultantes após a decomposição.

A Figura 2 apresentada a seguir ilustra como as formas normais trabalham, sua forma de uso e finalidade:

Normalização1
Figura 2 – Resumo formas normais.

Primeira Forma Normal (1FN)

Um esquema de relação R está na 1FN se todos os seus atributos forem atômicos e monovalorados, ou seja, não possuem valores que formam atributos compostos.

1 – Exemplo:
ESTUDANTES = {MATRÍCULA + NOME + ENDEREÇO + CODCURSO} e
ENDEREÇO é um atributo composto, ENDEREÇO = {RUA + NUMERO + BAIRRO + CIDADE + UF}.

Para colocar na 1FN faz:
ESTUDANTES={MATRÍCULA+NOME+RUA+NUMERO+BAIRRO+CIDADE+UF+CODCURSO}

Um esquema de relação R está na 1FN se todos os seus atributos forem atômicos e monovalorados, ou seja, não possuem valores que formam atributos compostos.

2 – Exemplo:

FUNCIONÁRIOS = {CODFUNC + NOME + CARGO + {PROJETO + DATAINI + DATAFIM}}

Para colocar na 1FN faz:

– FUNCIONÁRIOS = {CODFUNC + NOME + CARGO}

– FUNC_PROJ = {CODFUNC + PROJETO + DATAINI + DATAFIM}

Observação: todas as tabelas são relações na 1FN.

 

Segunda Forma Normal (2FN)

Dependência funcional total ou completa: Uma DF x® y é total, se não existir nenhum atributo A em x, tal que (x – {A})® y, para qualquer AÎ x, ou seja, se retirarmos este atributo A da relação x a DF deixa de existir. Caso contrário, x® y é parcial.

Definição da 2FN: Um esquema de relação está na 2FN se: estiver na 1FN e, além disso, todo atributo que não pertença a alguma de suas chaves for totalmente dependente da sua chave primária.

Em outras palavras, para que uma relação esteja na 2FN é preciso que esteja na 1FN e que, havendo uma chave primária composta, todos os dados que não são chaves dependem de toda a chave primária (a chave primária completa).

Seja o exemplo de uma relação que represente o estoque de um estabelecimento comercial, da seguinte forma:

ESTOQUE = {PRODUTO + ALMOX + END_ALMOX + UNID_EST + QTD + PRECO}

Não está na 2FN porque alguns dados não chave dependem somente de parte da chave, como END_ALMOX depende só de ALMOX, e UNID_EST depende só de PRODUTO.

Com a normalizando ficaria:
– Estoque = {PRODUTO + UNID_EST}
– Almoxarifado = {ALMOX + END_ALMOX}
– Produto= {PRODUTO + ALMOX + QTD + PRECO}

 

Terceira Forma Normal (3FN)

Dependência funcional transitiva: Uma DF x® y é transitiva em um esquema de relação R se existir um conjunto de atributos z, que não seja um subconjunto de alguma chave de R, e as DFs x® z e z® y forem válidas em R.

Um esquema de relação está na 3FN se: estiver na 2FN e, além disso, nenhum atributo que não pertença a alguma das suas chaves for transitivamente dependente da sua chave primária.

Em outras palavras, para que uma relação esteja na 3FN é preciso que esteja na 2FN e todo atributo, que não pertença a alguma chave for não dependente de algum outro atributo, que também não pertença a alguma chave.

Seja o exemplo de uma relação que represente os dados referentes às músicas, da seguinte forma:

Exemplo: MÚSICA = {CÓDIGO + TÍTULO + GÊNERO + PAÍS_ORIGEM}, supondo que neste exemplo, o PAÍS_ORIGEM refere-se ao GÊNERO musical e não a música, sendo assim, apesar de estar na 2FN, a relação não está na 3FN, pois existe  dependência entre GÊNERO e PAÍS_ORIGEM.

Com a normalizando ficaria:
MÚS_1 = {CÓDIGO + TÍTULO + GÊNERO}
MÚS_2 = {GÊNERO + PAÍS_ORIGEM}

Acredito que você pode ter entendido como inicialmente a normalização de dados vai influenciar na estrutura da sua modelagem de dados, como a mesma vai ser elaborada, estruturada e elaborada.

Para tentar ajudar o seu entendimento e tentar praticar o que estamos vendo neste post, vou deixar algumas perguntas que podem ser de extrema importância para o esclarecimento de dúvidas, como também, um exercício prático de normalização.


Questionário

1.O que é uma dependência funcional?

2.Quem especifica as dependências funcionais que se mantêm (são válidas) entre os atributos de um esquema de relação?

3.A que se refere a expressão “relação desnormalizada”?

4.Defina primeira, segunda e terceira formas normais quando somente chaves primárias são consideradas. Como as definições da 2FN e 3FN, que consideram todas as chaves de uma relação, diferem daquelas que consideram somente chaves primárias?

Exercício

Sejam os seguintes dados de uma locadora de automóveis:

A locadora aluga automóveis de uma determinada marca apenas para clientes pessoa jurídica (empresas). Estes clientes credenciam motoristas para utilizarem os veículos, o preço diário de aluguel e a potência do carro dependem de seu modelo. Considerando que a locadora necessite, para seu controle, dos dados descritos na seguinte relação:

  • REGISTRO_ALUGUEL = {NumCNH + NomeMotorista + DataNasc + CGCCliente + NomeCliente + EndCliente + {PlacaCarro + Modelo + Cor + Potência + QTDDiárias + PreçoDiária}}

Sendo assim chegamos ao final de mais uma dica do mês.

O conhecimento técnico é muito importante para qualquer profissional, mas o conceito é algo que sempre devemos valorizar e conhecer, a diferença entre um bom profissional e um profissional reconhecido e respeitado no mercado de trabalho é saber aliar o conhecimento teórico com o conhecimento prática, como muitos costumam dizer aliar a téoria a prática, sendo este o objetivo deste post.

Espero que você tenha gostado, que as informações e exemplos publicadas possam de alguma maneira ajudar e colaborar com suas atividades diárias, profissionais e ou acadêmicas.

Desejo um forte abraço, agradeço mais uma vez a sua visita.

Até mais.

 

Short Scripts – Junho 2016


Salve, salve minha gente, boa tarde!!!

Mais uma segunda – feira começando e mais uma semana se iniciando, já passamos da metade do mês de Junho tão aguardado devido ao lançamento do novo Microsoft SQL Server 2016. Caso você tenha perdido alguma informação sobre este lançamento, aproveito para compartilhar aqui um dos diversos posts publicados no meu blog sobre esta nova versão:

Voltando a falar sobre o Short Scripts, esta é uma das sessões mas visitadas do meu blog, onde o objetivo  é compartilhar os scripts existentes em minha biblioteca de códigos  dedicados exclusivamente para o SQL Server. Muitos destes scripts são resultado de pesquisas, posts publicados nos fóruns MSDN e também de respostas encontradas em outros websites de profissionais, administradores de banco de dados, professores e comunidades.

Boa parte de material é fruto de um trabalho dedicado exclusivamente a colaboração com a comunidade, visando sempre encontrar algo que possa ser a solução de um determinado problema, bem como, a demonstração de como se pode fazer uso de um determinado recurso. Todos os scripts publicados nesta sessão são devidamente testados antes de serem publicados, mas isso não significa que você pode fazer uso dos mesmo em seu ambiente de produção, vale sim todo cuidado possível para evitar maiores problemas.

Caso você não tenha acessado os últimos posts, não perca tempo, utilize os links publicados a seguir:

https://pedrogalvaojunior.wordpress.com/2016/03/22/short-scripts-marco-2016/

https://pedrogalvaojunior.wordpress.com/2015/12/14/short-script-dezembro-2015/

https://pedrogalvaojunior.wordpress.com/2015/10/21/short-scripts-outubro-2015/

https://pedrogalvaojunior.wordpress.com/2015/08/26/short-scripts-agosto-2015/

https://pedrogalvaojunior.wordpress.com/2015/06/03/short-script-junho-2015/

Para esta relação você vai encontrar scripts relacionados aos seguintes assuntos, conceitos, recursos ou funcionalidades:

  • Acesso a banco de dados;
  • Collation;
  • Comando Exec;
  • Comando Union;
  • Comando Union All;
  • Comando Create Table;
  • Comando Alter Table;
  • Common Table Expression;
  • DBCC CheckPrimaryFile;
  • DMV sys.dm_db_index_usage_stats;
  • DMV sys.dm_os_buffer_descriptors;
  • Índices Clustered e NonClustered;
  • Option MaxRecursion;
  • Plano de Execução;
  • Querys consideradas pesadas;
  • Tabela de sistema sys.allocation_units;
  • Tabela de sistema sys.partitions;
  • Tabela de sistema sys.indexes;
  • Tabela e caracteres Unicode; e
  • Recursividade.
A seguir, apresento a relação de short scripts:

— Short Script 1 – DBCC CheckPrimaryFile Verificando se o arquivo realmente é um Primary File —
DBCC CheckPrimaryFile (‘C:\Bancos\Laboratorio.MDF’,0)
Go

 

— Short Script 2 – DBCC CheckPrimaryFile – Retornando o conjunto completo de informações associados ao Primary File que formam a estrutura do respectivo Banco de Dados —
DBCC CheckPrimaryFile (‘C:\Bancos\Laboratorio.MDF’,1)
Go

 

— Short Script 3 – DBCC CheckPrimaryFile – Retornando o nome do banco de dados, versão e collation relacionados ao Primary File —
DBCC CheckPrimaryFile (‘C:\Bancos\Laboratorio.MDF’,2)
Go

— Short Script 4 – DBCC CheckPrimaryFile – Retornando o status, fileid, name e filename associados ao Primary File que formam a estrutura do respectivo Banco de Dados —
DBCC CheckPrimaryFile (‘C:\Bancos\Laboratorio.MDF’,3)
Go
— Short Script 5 – Informações sobre acesso ao Banco de Dados —
WITH agg AS
(SELECT last_user_seek,
                  last_user_scan,
                  last_user_lookup,
last_user_update
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID()
)
SELECT last_read = MAX(last_read),
                 last_write = MAX(last_write)
FROM
(SELECT last_user_seek, NULL FROM agg
UNION ALL
SELECT last_user_scan, NULL FROM agg
UNION ALL
SELECT last_user_lookup, NULL FROM agg
UNION ALL
SELECT NULL, last_user_update FROM agg
) AS x (last_read, last_write);
Go

 

— Short Script 6 – Observando a mudança de comportamento após a troca de Collation —

CREATE TABLE [dbo].[Authors]
([id] [INT] NULL,
   [author] [VARCHAR](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
   [dateposted] [DATE] NULL) ON [PRIMARY]
GO
INSERT Authors  VALUES (1, ‘Steve’, ‘20160101’),
                                                   (2, ‘STEVE’, ‘20160201’),
                                                   (3, ‘Andy’, ‘20160301’),
                                                   (4, ‘andy’, ‘20160401’)
GO
CREATE PROCEDURE GetAuthors @author VARCHAR(50)
AS
BEGIN
SELECT a.id, a.author FROM dbo.Authors a
WHERE a.author = @author
END
GO
— If I run the procedure with a parameter of ‘Steve’, it returns two rows. I then run this code:
Exec GetAuthors ‘Steve’
Go
ALTER TABLE dbo.Authors
ALTER COLUMN author VARCHAR(50) COLLATE SQL_Latin1_General_CP437_BIN2 NULL
— If I were to execute the stored procedure, what would happen?
Exec GetAuthors ‘Steve’
Go

 

— Short Script 7 – Descobrindo o código Unicode de um caracter ou String —

— Exemplo 1 —
DECLARE @n CHAR(10);
SET @n = N’Abc’;
SELECT UNICODE(@n);
Go
— Exemplo 2 —
DECLARE @n NCHAR(10);
SET @n = N’??????????’;
SELECT UNICODE(@n);
Go

 

— Short Script 8 – Criando CTEs —

— Exemplo 1 – Criando uma simples CTE —
;With Exemplo1(Valor, Nome)
As
(
Select 1, ‘Pedro Galvão’ As Nome
)
Select * from Exemplo1
Go
— Exemplo 2 – Criando uma CTE com Union de Selects —
;With Exemplo2(Valor)
As
( Select 10
Union
Select 50
Union
Select 8
Union
Select 10 + 2
)
Select Valor = (Select Max(valor) From Exemplo2) + (Select Sum(Valor) From Exemplo2)
Go
– Short Script 9 – Criando CTEs com Recursividade —
— Exemplo – Criando uma nova CTE Recursiva concatenando dados —
;With ConcatenarNomes(nome)
AS
( SELECT Nome = CONVERT(Varchar(4000),’Pedro Antonio’)
UNION ALL
SELECT CONVERT(Varchar(4000),nome + ‘ Galvão Junior’) FROM ConcatenarNomes
WHERE LEN(nome) < 30
)
SELECT Nome FROM ConcatenarNomes
Go
— Exemplo 2 – Criando uma CTE com Union + Recursividade – Simulando uma sequência de números pares —
;With CTENumerosPares(Numero)
As
( Select 0 As Numero
Union All
Select Numero + 2 As Numero From CTENumerosPares
Where Numero < 100
)
Select Numero From CTENumerosPares
Go
— Exemplo 3 – Criando uma CTE com Union + Recursividade – Simulando uma sequência de números —
;With CTENumerosSequenciais(Numero)
AS
(   SELECT 1 AS Numero
UNION ALL
SELECT Numero + 1 AS num FROM CTENumerosSequenciais
WHERE Numero < 1000
)
SELECT * FROM CTENumerosSequenciais
OPTION (MAXRECURSION 0)
Go
— Short Script 10 – Obtendo o tamanho de índices Clustered e NonClustered —
SELECT COUNT(*) AS cached_pages_count,
COUNT(*)/128.0000 MB,
name AS BaseTableName,
IndexName,
IndexTypeDesc
FROM sys.dm_os_buffer_descriptors AS bd
INNER JOIN (SELECT s_obj.name,
s_obj.index_id,
s_obj.allocation_unit_id,
s_obj.OBJECT_ID,
i.name IndexName,
i.type_desc IndexTypeDesc
FROM
(SELECT OBJECT_NAME(OBJECT_ID) AS name,
index_id,
allocation_unit_id,
OBJECT_ID
FROM sys.allocation_units AS au INNER JOIN sys.partitions AS p
ON au.container_id = p.hobt_id
AND (au.TYPE = 1 OR au.TYPE = 3)
UNION ALL
SELECT OBJECT_NAME(OBJECT_ID) AS name,
index_id,
allocation_unit_id,
OBJECT_ID
FROM sys.allocation_units AS au INNER JOIN sys.partitions AS p
ON au.container_id = p.partition_id
AND au.TYPE = 2
) AS s_obj LEFT JOIN sys.indexes i
ON i.index_id = s_obj.index_id
AND i.OBJECT_ID = s_obj.OBJECT_ID
) AS obj ON bd.allocation_unit_id = obj.allocation_unit_id
WHERE database_id = DB_ID()
and name not like ‘sys%’
and IndexName <> ‘null’
GROUP BY name, index_id, IndexName, IndexTypeDesc
ORDER BY cached_pages_count DESC;
Muito bem, mais uma relação de short scripts acaba de ser compartilhada, mesmo sendo denominados short entre aspas pequenos, posso garantir que todos estes exemplos são de grande importância e apresentam um valor e conhecimento do mais alto nível.

Chegamos ao final de mais um post, fique a vontade para compartilhar este conteúdo com seus contatos e redes sociais, contribua também enviando dicas, sugestões, dúvidas, críticas, enfim participe e ajude a melhorar cada vez mais esta sessão.

Mais uma vez obrigado por sua visita, nos encontramos em breve em mais um post da sessão Short Scripts.

Uma ótima semana, abraços.