Podemos armazenar informações de data e hora de duas maneiras. Qual é a melhor abordagem para armazenar informações DateTime?
Armazenando Data e Hora em 2 colunas separadas ou uma coluna usando DateTime ?
Você pode explicar por que essa abordagem é melhor?
(Link para os documentos do MySQL para referência, a pergunta é geral, não específica ao MySQL)
Tipos de data e hora : Data e hora
database-design
datetime
Julian
fonte
fonte
date,time
comgroup by date
, mas não por um índice emdatetime
comgroup by cast(datetime as date)
ainda que forneceria o fim desejado.Respostas:
Armazenar os dados em uma única coluna é a maneira preferida, pois eles estão inextricavelmente vinculados. Um ponto no tempo é uma única informação, não duas.
Uma maneira comum de armazenar dados de data / hora, empregados "nos bastidores" por muitos produtos, é convertendo-os em um valor decimal em que a "data" é a parte inteira do valor decimal e a "hora" é o fracionário valor. Portanto, 1900-01-01 00:00:00 é armazenado como 0.0 e 20 de setembro de 2016 9:34:00 é armazenado como 42631.39861. 42631 é o número de dias desde 1900-01-01. .39861 é a parte do tempo decorrido desde a meia-noite. Não use um tipo decimal diretamente para fazer isso, use um tipo explícito de data / hora; meu ponto aqui é apenas uma ilustração.
Armazenar os dados em duas colunas separadas significa que você precisará combinar os dois valores da coluna sempre que quiser ver se um determinado momento é anterior ou posterior ao valor armazenado.
Se você armazenar os valores separadamente, invariavelmente encontrará "bugs" difíceis de detectar. Tome, por exemplo, o seguinte:
No código acima, estamos criando uma tabela de teste, preenchendo-a com dois valores e, em seguida, realizando uma consulta simples nesses dados. O primeiro
SELECT
retorna as duas linhas; no entanto, o segundoSELECT
retorna apenas uma única linha, que pode não ser o resultado desejado:A maneira correta de filtrar um intervalo de data / hora em que os valores estão em colunas discretas, conforme apontado por @ypercube nos comentários, é:
Se você precisar separar o componente de tempo para fins de análise , considere adicionar uma coluna calculada e persistente para a parte de tempo do valor:
A coluna persistida pode então ser indexada, permitindo classificações rápidas, etc., por hora do dia.
Se você estiver pensando em dividir a data e a hora em dois campos para fins de exibição, deve perceber que a formatação deve ser feita no cliente, não no servidor.
fonte
Vou fornecer uma opinião divergente para as outras respostas.
Se os componentes de data e hora forem necessários juntos, ou seja, uma entrada é inválida se contiver um, mas não o outro (ou for NULL em um, mas não no outro), o armazenamento em uma única coluna fará sentido pelas razões indicadas em outros respostas.
No entanto, pode ser que um ou ambos os componentes sejam individualmente opcionais. Nesse caso, seria incorreto armazená-lo em uma única coluna. Fazer isso forçaria você a representar valores NULL de maneira arbitrária, por exemplo, armazenando o horário como 00:00:00.
Aqui estão alguns exemplos:
Você está gravando viagens de veículo para deduções de imposto de quilometragem. Saber a hora exata da jornada seria útil, mas se um funcionário não a anotasse e a esquecesse, a data ainda deve ser registrada por si mesma (data obrigatória, hora opcional).
Você está conduzindo uma pesquisa para descobrir a que horas as pessoas almoçam e solicita aos participantes que preencham um formulário com uma amostra de seus horários de almoço, incluindo datas. Alguns não se incomodam em preencher a data e você não deseja descartar os dados, pois são os horários que realmente interessam (data opcional, tempo necessário).
Veja esta pergunta relacionada para abordagens alternativas.
fonte
Eu sempre prefiro armazenar isso como uma única coluna, a menos que haja alguma demanda específica de negócios / aplicativos. Abaixo estão meus pontos -
fonte
No SQL Server, é melhor armazenar o DataTime como um campo. Se você criar um índice na coluna DataTime, ele poderá ser usado como pesquisa por Data e pesquisa por Data e Hora. Portanto, se você precisar limitar todos os registros existentes para a data específica, ainda poderá usar o índice sem precisar fazer nada de especial. Se você precisar consultar a parte do tempo, não poderá usar o mesmo índice e, portanto, se tiver um caso de negócios em que se preocupe mais com a hora do dia do que com o DateTime, armazene-o separadamente, pois precisará criar um índice e melhorar o desempenho.
fonte
De fato, é uma pena que não haja um tipo de DBMS cruzado padrão para isso (como INT e VARCHAR são para números inteiros e valores de sequência). As duas abordagens entre bancos de dados que conheci até agora estão usando as colunas VARCHAR / CHAR para armazenar valores DataTime como seqüências de caracteres formatadas de acordo com o padrão ISO 8601 (mais conveniente, legível por humanos) e usando o BIGINT para armazená-los como registros de data e hora POSIX (armazenados mais eficiente, mais rápido, mais fácil de manipular matematicamente).
fonte
timestamp
isso que o padrão SQL define. Armazenar timestamps como strings é um péssimo conselhoDepois de ler várias coisas, o horário UTC do Unix no BIGINT parece ser a solução ideal. ID de horário TZDB em VARCHAR para armazenamento de fuso horário, se necessário. Alguns argumentos:
TIMESTAMP e DATETIME realizam várias conversões enganosas em segundo plano que parecem complexas e não claras. O servidor alterna do horário local para o UTC ou para o horário do servidor e vice-versa, às vezes ou não. Um monte de sobrecarga oculta para todas as funções.
O BIGINT (8kb) é pelo menos tão leve ou mais leve que o DECIMAL necessário para o armazenamento no formato xxxxxx.xxxxxx, que é praticamente armazenado como dois INTs + algo pelo MySQL . E basta armazenar séculos à frente.
Praticamente todas as principais linguagens de programação possuem bibliotecas de funções padrão para trabalhar com o tempo Unix.
As operações matemáticas com o BIGINT devem ser mais rápidas ou rápidas do que qualquer outra coisa em qualquer hardware.
É claro que tudo isso é relevante para grandes projetos internacionais. Para algo pequeno, seguir o formato padrão da estrutura escolhida parece ser bom o suficiente.
fonte
timestamp
coluna, nenhuma "conversão enganosa" acontece (na camada do banco de dados) etimestamp with time zone
isso é bem documentado e explicado nos manuais (pelo menos para Oracle e Postgres)