Banco de Dados - SQL Server

Novos datatypes para Data e Hora – SQL Server 2008

Continuando com as novidades do SQL Server 2008, este artigo apresentará os novos tipos de dados para controlar Datas e Horas.

por Diego Nogare



Continuando com as novidades do SQL Server 2008, este artigo apresentará os novos tipos de dados para controlar Datas e Horas. Estes novos tipos integram as novidades do SQL Server 2008 e trazem um ganho de performance, já que quanto menos dados desnecessários forem armazenados, mais rápidos os dados retornam para quem os solicitou.

Para se ter uma idéia de onde se pode utilizar estes novos tipos de dados, imagine o seguinte cenário em que é necessário armazenar o tempo de uma determinada quantidade de ações em seu sistema. Na versão 2005 não é possível armazenar um datatype de Hora, o mais próximo seria Smalldatetime que armazena a data e a hora sem os milisegundos. Neste cenário a Data seria desnecessária, porque o objetivo é o armazenamento das horas. Outro cenário, agora armazenando somente a Data, seria na Data de Nascimento de um cliente no qual a hora é desnecessária e estaria ocupando espaço nas páginas do banco de dados.

Fazendo um breve comparativo entre os datatypes existentes na versão 2005 e 2008, pode-se ver que surgiram 4 novos tipos na nova versão: Datetime2, Datetimeoffset, Date e por fim Time. E foram mantidos os tipos já existentes na versão 2005 como Smalldatetime, Datetime e Timestamp.

Consultando o Books On-Line, é possível chegar a estas descrições para cada ítem:

Datetime2: É parecido com o Datetime existente, e pode ser utilizado como um complemento a ele.

Datetimeoffset: Representa uma data e hora completa (24Hs) e os dados de fuso-horário.

Date: Define a representação de uma data.

Time: Representa as horas no formato de 24Hs e sem utilizar fuso-horário.

Abrindo o SQL Server Management Studio é possível consultar o Database Engine e ver os resultados dos datatypes existentes para Data e Hora. Veja na listagem 1 a consulta e os resultados na versão 2005, e na listagem 2 a mesma consulta e os novos resultados quando é executado na versão 2008.

Listagem 1. Consulta e resultado na versão 2005.

SELECT name FROM sys.systypes WHERE name like "%date%" or name like "%time%"

name

--------------

datetime

smalldatetime

timestamp

Listagem 2. Consulta e resultado na versão 2008.

SELECT name FROM sys.systypes WHERE name like "%date%" or name like "%time%"

name

--------------

date

datetime

datetime2

datetimeoffset

smalldatetime

time

timestamp

Esta busca consulta todos os DataTypes existentes no SQL Server, veja que na Listagem 2 (2008) aparecem todos os tipos existentes no 2005 e mais os novos tipos do 2008.

Agora que já temos os novos tipos de dados do SQL Server 2008, podemos criar uma tabela com esses dados e inserir uma linha e ver como estes dados são armazenados. Acompanhe na Listagem 3 esta criação.

Listagem 3. Criação da tabela, inserção de dados e resultado.

CREATE TABLE tbNovosTipos(campoDate Date, campoTime Time,

campoOffSet Datetimeoffset, campoDatetime2 Datetime2)

INSERT INTO tbNovosTipos VALUES (getDate(),getDate(),getDate(),getDate())

campoDate   campoTime         campoOffSet                         campoDatetime2

----------  ----------------  ----------------------------------  ----------------------

2008-07-09  09:58:28.5700000  2008-07-09 09:58:28.5700000 +00:00  2008-07-09 09:58:28.57

Veja que neste exemplo de código em SQL Server 2008, os novos tipos de dados são armazenados conforme descritos anteriormente. A primeira coluna armazena somente a data, a segunda somente a hora, a terceira e quarta armazenam respectivamente a data e hora completa com e sem fuso-horário.

Para provar o desempenho, vamos analisar o resultado utilizando o DBCC ShowContig, já apresentado anteriormente em outro artigo.

Primeiro será criado todo o processo no SQL Server 2005 e depois no 2008. A listagem 4 contém os códigos para a versão 2005.

Listagem 4. Criação de tabela, inserção de dados e resultado.

create table tbData (data datetime)

create table tbhora (hora datetime)

insert into tbData values ("2008-01-01")

insert into tbHora values ("19:00:00")

go 450

select top 1 * from tbData

select top 1 * from tbHora

dbcc showcontig

data

-----------------------

2008-08-07 00:00:00.000

hora

-----------------------

1900-01-01 12:28:00.000

DBCC SHOWCONTIG scanning "tbData" table...

Table: "tbData" (2089058478); index ID: 0, database ID: 6

TABLE level scan performed.

- Pages Scanned................................: 1

- Extents Scanned..............................: 1

- Extent Switches..............................: 0

- Avg. Pages per Extent........................: 1.0

- Scan Density [Best Count:Actual Count].......: 100.00% [1:1]

- Extent Scan Fragmentation ...................: 0.00%

- Avg. Bytes Free per Page.....................: 446.0

- Avg. Page Density (full).....................: 94.49%

DBCC SHOWCONTIG scanning "tbhora" table...

Table: "tbhora" (2105058535); index ID: 0, database ID: 6

TABLE level scan performed.

- Pages Scanned................................: 1

- Extents Scanned..............................: 1

- Extent Switches..............................: 0

- Avg. Pages per Extent........................: 1.0

- Scan Density [Best Count:Actual Count].......: 100.00% [1:1]

- Extent Scan Fragmentation ...................: 0.00%

- Avg. Bytes Free per Page.....................: 446.0

- Avg. Page Density (full).....................: 94.49%

Na listagem 4 foram criadas duas tabelas, uma chamada tbData e outra tbHora, ambas com um único campo do tipo Datetime. Após a criação foram inseridas 450 linhas em cada tabela, na tabela tbData foi inserida a data 01/01/2008 e na tabela tbHora foi inserida a hora 19h00. Veja que em ambas tabelas o resultado apresenta data e hora no campo, e não é esse nosso objetivo, em cada tabela deveria ter sido armazenado um tipo de dado específico.

Agora, trabalhando com o SQL Server 2008, vamos ver o quanto é possível ganhar de espaço com a utilização dos dados específicos para cada tipo de armazenamento. Acompanhe o código na listagem 5.

Listagem 5. Criação de tabela, inserção de dados e resultado.

create table tbData (data date)

create table tbhora (hora time)

insert into tbData values ("2008-01-01")

insert into tbHora values ("19:00:00")

go 450

select top 1 * from tbData

select top 1 * from tbHora

dbcc showcontig

data

----------

2008-01-01

hora

----------------

19:00:00.0000000

DBCC SHOWCONTIG scanning "tbhora" table...

Table: "tbhora" (5575058); index ID: 0, database ID: 6

TABLE level scan performed.

- Pages Scanned................................: 1

- Extents Scanned..............................: 1

- Extent Switches..............................: 0

- Avg. Pages per Extent........................: 1.0

- Scan Density [Best Count:Actual Count].......: 100.00% [1:1]

- Extent Scan Fragmentation ...................: 0.00%

- Avg. Bytes Free per Page.....................: 1796.0

- Avg. Page Density (full).....................: 77.81%

DBCC SHOWCONTIG scanning "tbData" table...

Table: "tbData" (2137058649); index ID: 0, database ID: 6

TABLE level scan performed.

- Pages Scanned................................: 1

- Extents Scanned..............................: 1

- Extent Switches..............................: 0

- Avg. Pages per Extent........................: 1.0

- Scan Density [Best Count:Actual Count].......: 100.00% [1:1]

- Extent Scan Fragmentation ...................: 0.00%

- Avg. Bytes Free per Page.....................: 2696.0

- Avg. Page Density (full).....................: 66.69%

É possível concluir que, quando utilizamos o tipo de dado correto, diminuímos aproximadamente 17% na tabela tbHora e na tabela tbHora 28%, analisando a densidade média de cada página. E como sabemos que no SQL Server o custo é calculado com base na quantidade de páginas retornadas, utilizar o tipo de dado correto nos faz ganhar dinheiro. rs

Até o próximo artigo.

Referências:

Books On-Line

Time – http://msdn.microsoft.com/en-us/library/bb677243(SQL.100).aspx

Date – http://msdn.microsoft.com/en-us/library/bb630352(SQL.100).aspx

Datetime2 – http://msdn.microsoft.com/en-us/library/bb677335(SQL.100).aspx

Datetimeoffset – http://msdn.microsoft.com/en-us/library/bb630289(SQL.100).aspx

Diego Nogare

Diego Nogare - Graduado em Ciência da Computação e Pós-Graduado em Engenharia de Computação com ênfase em Desenvolvimento Web com .NET, Colaborador do Portal Linha de Código, co-Líder do grupo de usuários Codificando .NET, co-Líder dos Microsoft Student Partners [MSP] de São Paulo e Microsoft Most Valuable Professional [MVP] em SQL Server, possui certificações MCP e MCTS em SQL Server 2005, é palestrante em eventos da Microsoft, Codificando .NET e INETA BR, mantém o site: www.diegonogare.net.