Devo usar o tipo de dados datetime ou timestamp no MySQL?

Respostas:

1830

Os registros de data e hora no MySQL são geralmente usados ​​para rastrear alterações nos registros e são atualizados sempre que o registro é alterado. Se você deseja armazenar um valor específico, use um campo de data e hora.

Se você quis dizer que deseja decidir entre usar um registro de data e hora do UNIX ou um campo de data e hora nativo do MySQL, vá com o formato nativo. Você pode fazer cálculos no MySQL dessa maneira ("SELECT DATE_ADD(my_datetime, INTERVAL 1 DAY)")e é simples alterar o formato do valor para um timestamp UNIX ("SELECT UNIX_TIMESTAMP(my_datetime)")quando você consultar o registro, se desejar operar nele com PHP.

blivet
fonte
981
Uma diferença importante é que DATETIMErepresenta uma data (como encontrada em um calendário) e uma hora (como pode ser observado em um relógio de parede), enquanto TIMESTAMPrepresenta um ponto no tempo bem definido. Isso pode ser muito importante se o seu aplicativo manipular fusos horários. Há quanto tempo foi '2010-09-01 16:31:00'? Depende do fuso horário em que você está. Para mim, apenas alguns segundos atrás, para você, pode representar um tempo no futuro. Se eu disser 1283351460 segundos desde '1970-01-01 00:00:00 UTC', você saberá exatamente de que ponto de tempo falo. (Veja a excelente resposta de Nir abaixo). [Desvantagem: faixa válida].
Matt Bianco
121
Outra diferença: consultas com data e hora "nativas" não serão armazenadas em cache, mas consultas com registro de data e hora - serão.
OZ_
39
"Os carimbos de data / hora no MySQL geralmente costumavam rastrear alterações nos registros" Não pense que seja uma boa resposta. O registro de data e hora é muito mais poderoso e complicado do que isso, como MattBianco e Nir disseram. Embora, a segunda parte da resposta seja muito boa. É verdade o que disse o blivet e é um bom conselho.
Santiagobasulto
10
Além disso, uma observação importante: DATETIME e TIMESTAMP podem usar CURRENT_TIMESTAMP, NOW () respeitosamente como seu valor padrão, mas DATE por exemplo não pode, porque usa '0000-00-00' por padrão, para resolver esse problema, você deve escrever Seu próprio gatilho para essa tabela, para inserir a data atual (sem hora) no campo / col com o tipo DATE mysql.
Arthur Kushman
14
@DavidHarkness: A documentação diz "Para especificar propriedades automáticas, use as cláusulas DEFAULT CURRENT_TIMESTAMP e ON UPDATE CURRENT_TIMESTAMP" dev.mysql.com/doc/refman/5.0/en/timestamp-initialization.html
Plap
917

No MySQL 5 e acima, os valores TIMESTAMP são convertidos do fuso horário atual para UTC para armazenamento e convertidos de volta do UTC para o fuso horário atual para recuperação. (Isso ocorre apenas para o tipo de dados TIMESTAMP e não para outros tipos, como DATETIME.)

Por padrão, o fuso horário atual de cada conexão é o horário do servidor. O fuso horário pode ser definido por conexão, conforme descrito no Suporte ao fuso horário do servidor MySQL .

Nir
fonte
11
esta apresentação da OReilly é muito boa para este tópico (PDF em inglês) cdn.oreillystatic.com/en/assets/1/event/36/…
gcb 27/10/2013
13
É também sobre a natureza do evento: - Uma videoconferência (TIMESTAMP). Todos os participantes devem ver uma referência a um instante absoluto de tempo ajustado ao seu fuso horário. - Um horário de tarefa local (DATETIME), eu devo executar essa tarefa em 31/03/2014 às 09:00, independentemente do dia em que estiver trabalhando em Nova York ou Paris. Começarei a trabalhar às 8:00 da hora local onde estarei naquele dia.
yucer
1
Então, se eu ALTERAR o fuso horário do servidor, o valor de TIMESTAMP permanecerá o mesmo ou será alterado também?
Andrew
3
@ Andrew, uma vez que é UTC, permanecerá UTC. A conversão para trás será alterada para o "novo" fuso horário do servidor.
Nembleton 5/07
@ yucer - eu não recomendo pensar dessa maneira. O uso mais consistente em uma economia global é converter todas as datas para UTC para armazenamento. Por convenção, trate Datetime como um campo UTC. Isso sobrecarrega todas as tarefas que inserem datas para fazer a conversão para o UTC, mas é um design mais limpo a longo prazo. Obviamente, apresente as informações ao usuário com base em suas configurações atuais. Se o usuário desejar digitar "09:00 em Paris", deixe que ele defina a hora de Paris e digite 09:00. Então qualquer um que está em Nova York pode facilmente encontrar o tempo que eles precisam ser acordado durante a seu tempo, a teleconferência no.
ToolmakerSteve
524

Eu sempre uso campos DATETIME para qualquer coisa que não seja metadados de linha (data de criação ou modificação).

Conforme mencionado na documentação do MySQL:

O tipo DATETIME é usado quando você precisa de valores que contenham informações de data e hora. O MySQL recupera e exibe valores DATETIME no formato 'AAAA-MM-DD HH: MM: SS'. O intervalo suportado é '1000-01-01 00:00:00' a '9999-12-31 23:59:59'.

...

O tipo de dados TIMESTAMP tem um intervalo de '1970-01-01 00:00:01' UTC a '2038-01-09 03:14:07' UTC. Possui propriedades variadas, dependendo da versão do MySQL e do modo SQL em que o servidor está sendo executado.

É provável que você atinja o limite inferior do TIMESTAMPs em uso geral - por exemplo, armazenando a data de nascimento.

scronide
fonte
195
você também pode bater a parte superior limite facilmente se você está na operação bancária ou de imóveis ... de 30 anos hipotecas ir além de 2038 agora
Kip
16
Obviamente, use carimbos de data e hora Unix de 64 bits. Por exemplo, em Java, new Date().getTime()já fornece um valor de 64 bits.
Osa
5
+1 para DATETIME: em nosso fluxo de dados, do SQL Server da Loja Física para compra e fatura, transferido para o MySQL Server para a Loja Virtual na página da Web, DATETIME é melhor para Modificação Data / Hora, pois esse tipo de dados também existe no Transact -SQL. Mas TIMESTAMP significa outra coisa no Transact-SQL, é binário como ROWVERSION, embora o MySQL TIMESTAMP seja DateTime semelhante. Portanto, evitamos o uso do TIMESTAMP para a compatibilidade dos dois bancos de dados.
10133 Jacouh
10
Nenhuma idéia. É um problema muito maior do que apenas o MySQL e não existe uma solução simples: en.wikipedia.org/wiki/Year_2038_problem Não acredito que o MySQL possa apenas declarar que os carimbos de data e hora estão agora de 64 bits e suponha que tudo ficará bem. Eles não controlam o hardware.
scronide
5
Uma data de nascimento pode ser DATETIME, se você souber a hora do nascimento, como eu faço para a minha.
Kris Craig
322

Os exemplos abaixo mostram como o TIMESTAMPtipo de data alterou os valores após alterar o time-zone to 'america/new_york'local DATETIMEinalterado.

mysql> show variables like '%time_zone%';
+------------------+---------------------+
| Variable_name    | Value               |
+------------------+---------------------+
| system_time_zone | India Standard Time |
| time_zone        | Asia/Calcutta       |
+------------------+---------------------+

mysql> create table datedemo(
    -> mydatetime datetime,
    -> mytimestamp timestamp
    -> );

mysql> insert into datedemo values ((now()),(now()));

mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 14:11:09 |
+---------------------+---------------------+

mysql> set time_zone="america/new_york";

mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 04:41:09 |
+---------------------+---------------------+

Eu converti minha resposta em artigo para que mais pessoas possam achar isso útil, MySQL: tipos de dados Datetime Versus Timestamp .

mr_eclair
fonte
55
Bem, na verdade o DATETIMEtempo efetivo mudou com a mudança de fuso horário, TIMESTAMPnão mudou, mas a representação humana mudou.
flindeberg
3
Parece que este comando não funciona no MySQL 5.6 set time_zone="america/new_york";
precisa saber é o seguinte
Aqui está a resposta para o problema definido no time_zone. stackoverflow.com/questions/3451847/mysql-timezone-change
Manjunath Reddy
2
Concorde com @flindeberg. Timestamp representa o tempo correto, não de data e hora, após a mudança do fuso horário
Nitin Bansal
193

A principal diferença é que DATETIME é constante enquanto TIMESTAMP é afetado pela time_zoneconfiguração.

Portanto, só importa quando você tem - ou pode ter no futuro - clusters sincronizados entre fusos horários.

Em palavras mais simples: se eu tiver um banco de dados na Austrália e fizer um despejo desse banco de dados para sincronizar / preencher um banco de dados na América, o TIMESTAMP será atualizado para refletir o tempo real do evento no novo fuso horário, enquanto DATETIME ainda refletem a hora do evento no fuso horário au .

Um ótimo exemplo de DATETIME sendo usado onde o TIMESTAMP deveria ter sido usado é no Facebook, onde seus servidores nunca sabem ao certo o que aconteceu durante os fusos horários. Uma vez eu estava tendo uma conversa na qual o horário dizia que estava respondendo às mensagens antes que a mensagem fosse realmente enviada. (Isso, é claro, também poderia ter sido causado por uma tradução incorreta do fuso horário no software de mensagens se os horários estivessem sendo postados em vez de sincronizados.)

ekerner
fonte
83
Eu não acho que essa seja uma boa maneira de pensar. Gostaria de armazenar e processar todas as datas no UTC e garantir que o front-end as exibisse de acordo com o fuso horário especificado. Essa abordagem é simples e previsível.
Kos
8
@ Kos: não está armazenando e processando todas as datas no UTC exatamente o que o TIMESTAMP está fazendo internamente? (Em seguida, convertê-lo para mostrar o seu fuso horário local?)
carbocation
10
meu fuso horário local? Como seu DB saberia meu fuso horário? ;-) Normalmente, existe algum processamento entre o banco de dados e a interface do usuário. Eu faço a localização somente após todo o processamento.
Kos
3
@Koz: meu banco de dados não conhece o fuso horário dos seus bancos de dados:! Mas sabe o timestamp. Seu banco de dados conhece sua própria configuração de fuso horário e aplica-a ao interpretar / representar o carimbo de data / hora. 01:01 em 11 de dezembro de 2013 em Pequim A China não é o mesmo momento que 01:01 em 11 de dezembro de 2013 em Sydney, Austrália. Google: 'fusos horários' e 'meridiano de primeira linha'.
ekerner
2
O MySQL converte valores TIMESTAMP do fuso horário atual para UTC para armazenamento e de volta do UTC para o fuso horário atual para recuperação. (Isto não ocorre para outros tipos, tais como a data e hora.) Dev.mysql.com/doc/refman/5.5/en/datetime.html
Mahdyfo
125

Eu tomo essa decisão em uma base semântica.

Uso um carimbo de data / hora quando preciso registrar um ponto (mais ou menos) fixo no tempo. Por exemplo, quando um registro foi inserido no banco de dados ou quando alguma ação do usuário ocorreu.

Eu uso um campo datetime quando a data / hora pode ser definida e alterada arbitrariamente. Por exemplo, quando um usuário pode salvar mais tarde alterar compromissos.

MaxVT
fonte
timestamp - ponto fixo no tempo, data e hora universal coordenada - em relação a um ponto de vista, a uma referência de hora (ej fuso horário local), poderia ser .. Hora local coordenada?
yucer
110

Eu recomendo usar nem um DATETIME ou um campo TIMESTAMP. Se você deseja representar um dia específico como um todo (como um aniversário), use um tipo DATE, mas se estiver sendo mais específico do que isso, provavelmente está interessado em registrar um momento real em oposição a uma unidade de hora (dia, semana, mês, ano). Em vez de usar um DATETIME ou TIMESTAMP, use um BIGINT e simplesmente armazene o número de milissegundos desde a época (System.currentTimeMillis () se você estiver usando Java). Isso tem várias vantagens:

  1. Você evita o bloqueio do fornecedor. Praticamente todo banco de dados suporta números inteiros de maneira relativamente semelhante. Suponha que você queira mudar para outro banco de dados. Deseja se preocupar com as diferenças entre os valores DATETIME do MySQL e como a Oracle os define? Mesmo entre diferentes versões do MySQL, o TIMESTAMPS tem um nível diferente de precisão. Apenas recentemente, o MySQL suportou milissegundos nos registros de data e hora.
  2. Sem problemas de fuso horário. Houve alguns comentários interessantes aqui sobre o que acontece com os fusos horários com os diferentes tipos de dados. Mas esse conhecimento é comum e todos os seus colegas de trabalho terão tempo para aprender? Por outro lado, é muito difícil mudar o BigINT para java.util.Date. O uso de um BIGINT faz com que muitos problemas com os fusos horários caiam no caminho.
  3. Não se preocupe com faixas ou precisão. Você não precisa se preocupar com o que será cortado por períodos futuros (o TIMESTAMP só vai para 2038).
  4. Integração de ferramentas de terceiros. Ao usar um número inteiro, é trivial que ferramentas de terceiros (por exemplo, EclipseLink) façam interface com o banco de dados. Nem todas as ferramentas de terceiros terão o mesmo entendimento de um "datetime" que o MySQL. Deseja tentar descobrir no Hibernate se você deve usar um objeto java.sql.TimeStamp ou java.util.Date se estiver usando esses tipos de dados personalizados? O uso dos tipos de dados básicos é fácil com ferramentas de terceiros.

Esse problema está intimamente relacionado à forma como você deve armazenar um valor monetário (ou seja, US $ 1,99) em um banco de dados. Você deve usar um decimal ou o tipo de dinheiro do banco de dados ou, pior ainda, um duplo? Todas as três opções são terríveis, por muitos dos mesmos motivos listados acima. A solução é armazenar o valor do dinheiro em centavos usando BIGINT e, em seguida, converter centavos em dólares quando você exibir o valor ao usuário. O trabalho do banco de dados é armazenar dados, e NÃO interpretar esses dados. Todos esses tipos de dados sofisticados que você vê nos bancos de dados (especialmente o Oracle) adicionam pouco e ajudam você a trancar o fornecedor.

user64141
fonte
12
Eu gosto desta solução. O TIMESTAMP que expira em 2038 é um grande problema. Isso não é realmente tão longe!
Charlie Dalsass
4
@CharlieDalsass Você acha que software atual vai estar lá esse tempo :-P
Habeeb Perwad
13
Torna-se difícil para consulta de dados por data, se a sua armazenado como um número de milissegundos
Ali Saeed
4
Essa é realmente a melhor solução se você se preocupa com portabilidade e manipulação de usuários em vários fusos horários ou banco de dados em fusos horários diferentes dos usuários. O TIMESTAMP pode ser o caminho a percorrer se não houver falhas de design. Pena que as soluções quebradas receberam mais votos porque foram postadas mais cedo (anos!).
alemão
4
Excelente solução! E você está exatamente certo em estar "preso". Quando você adquire o hábito de deixar os outros "fazerem o trabalho por você", começa a perder os pedaços que o tornam o programador.
fmc 22/02
98

TIMESTAMP é de 4 bytes vs. 8 bytes para DATETIME.

http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html

Mas, como o scronide disse que tem um limite inferior do ano de 1970. É ótimo para qualquer coisa que possa acontecer no futuro;)

Alex
fonte
186
O futuro termina às 2038-01-19 03:14:07 UTC.
Matt Bianco
5
Isso é estupido. Eu pensei que o tipo TIMESTAMP estaria "preparado para o futuro" porque é relativamente novo. Você não pode se preocupar em converter data e hora para UTC e voltar sempre que trabalhar com fusos horários diferentes. Eles deveriam ter aumentado o TIMESTAMP .. pelo menos 1 byte maior. adicionará 68 * 255 = 17340 mais anos ... embora não esteja alinhado em 32 bits.
27412 NickSoft
10
Você sabe por que o TIMESTAMP termina em 2038? Porque é um número inteiro, e os números inteiros têm um limite que é 2147483647. Acho que esse é o motivo. Pode ser que, se eles mudarem de tipo para varchar e mudarem a maneira de manipulá-lo, estará "pronto para o futuro".
VINSA
6
@vinsa, acho que não estará pronto para o futuro até então. Ainda se lembra do bug do Y2K? 2038 está chegando.
Pacerier
2
Por 2038, MySQL (se ele ainda existe) simplesmente atualizar o campo TIMESTAMP usar mais de 4 bytes e permitir uma gama mais ampla
the_nuts
95
  1. TIMESTAMP tem quatro bytes ou oito bytes para DATETIME.

  2. Os carimbos de hora também são mais claros no banco de dados e indexados mais rapidamente.

  3. O tipo DATETIME é usado quando você precisa de valores que contenham informações de data e hora. O MySQL recupera e exibe valores DATETIME no formato 'AAAA-MM-DD HH: MM: SS'. O intervalo suportado é '1000-01-01 00:00:00' a '9999-12-31 23:59:59'.

O tipo de dados TIMESTAMP tem um intervalo de '1970-01-01 00:00:01 ′ UTC a' 2038-01-09 03:14:07 ′ UTC. Possui propriedades variadas, dependendo da versão do MySQL e do modo SQL em que o servidor está sendo executado.

  1. DATETIME é constante enquanto TIMESTAMP é efetuado pela configuração time_zone.
Vivek S
fonte
6
Você precisa esclarecer # 4: o carimbo de data / hora, conforme armazenado, é constante e não relativo (completamente independente) ao fuso horário, enquanto a saída exibida na recuperação é afetada pelo fuso horário da sessão solicitante. DATETIME é sempre relativo ao fuso horário em que foi registrado e deve sempre ser considerado nesse contexto, uma responsabilidade que agora cabe ao aplicativo.
Christopher McGowan
1
Ótima resposta. Para adicionar a essa resposta, se tentarmos armazenar valores além desse '2038-01-09 03:14:07', obteremos um erro ou ele será armazenado como '0000-00-00 00:00:00'. Eu estava recebendo esse erro no meu banco de dados, pois tinha valores com desvio de horário (para fins de criptografia).
KarthikS
Além disso, há um problema com DATETIME com valor DEFAULT nas versões do mysql abaixo de 5.5. dba.stackexchange.com/questions/132951/…
Velaro
47

Depende da aplicação, realmente.

Considere definir um carimbo de data e hora de um usuário para um servidor em Nova York, para um compromisso em Sanghai. Agora, quando o usuário se conecta em Sanghai, ele acessa o mesmo registro de data e hora de compromisso em um servidor espelhado em Tóquio. Ele verá o compromisso no horário de Tóquio, compensado com o horário original de Nova York.

Portanto, para valores que representam a hora do usuário, como um compromisso ou uma agenda, o horário e o horário são melhores. Ele permite que o usuário controle a data e a hora exata desejadas, independentemente das configurações do servidor. O horário definido é o horário definido, não afetado pelo fuso horário do servidor, pelo fuso horário do usuário ou por alterações na maneira como o horário de verão é calculado (sim, ele muda).

Por outro lado, para valores que representam a hora do sistema, como transações de pagamento, modificações de tabela ou log, sempre use carimbos de data e hora. O sistema não será afetado movendo o servidor para outro fuso horário ou ao comparar entre servidores em fusos horários diferentes.

Os carimbos de hora também são mais claros no banco de dados e indexados mais rapidamente.

ianaré
fonte
Seu aplicativo não deve depender do fuso horário do servidor. Um aplicativo SEMPRE deve selecionar o fuso horário na sessão da conexão com o banco de dados que ele usa antes de emitir qualquer consulta. Se uma conexão for compartilhada entre vários usuários (por exemplo, webapp), use o UTC e faça a conversão de fuso horário no lado da renderização.
Dolmen
42

2016 + : o que eu aconselho é definir o fuso horário do Mysql para UTC e usar DATETIME:

Qualquer estrutura recente de front-end (Angular 1/2, react, Vue, ...) pode converter de forma fácil e automática a sua data e hora UTC para a hora local.

Além disso:

(A menos que você mude o fuso horário dos seus servidores)


Exemplo com AngularJs

// back-end: format for angular within the sql query
SELECT DATE_FORMAT(my_datetime, "%Y-%m-%dT%TZ")...

// font-end Output the localised time
{{item.my_datetime | date :'medium' }}

Todo o formato de hora localizado disponível aqui: https://docs.angularjs.org/api/ng/filter/date

Sebastien Horin
fonte
8
Seus dados não devem ser anexados às configurações de fuso horário dos seus servidores. Talvez, ele está trabalhando para o seu se você tem caixa de MySql único sob sua mesa
Jin
@Jin UTC significa que não há fuso horário como o TIMESTAMP. Se todos os seus servidores estiverem no UTC, não haverá problemas. Talvez não esteja funcionando para você se você tiver uma configuração de 2000.
Sebastien Horin
O TIMESTAMP pode ser atualizado para um valor de 64 bits no futuro. Então não há mais problema.
precisa saber é o seguinte
Carregar bibliotecas de terceiros inteiras para capturar algo assim também não pode ser ótimo para desempenho, pode? Dado que é do lado do cliente e não afeta seu banco de dados ... Ainda assim, qualquer coisa que você faça no front-end exigirá verificações no servidor. Então, pensando na imagem completa , isso realmente ajuda com a questão da velocidade? A propósito, esses benchmarks são um pouco estranhos. Usar uma sequência de caracteres em uma consulta para comparar campos de carimbo de data e hora também parece bastante estranho. Isso também deve prejudicar o desempenho, certo?
NoobishPro
1
Não confie no seu aplicativo no time_zone do servidor. Em vez disso, defina o time_zone a ser usado em cada conexão com o banco de dados: SET time_zone = '+0:00';para UTC.
Dolmen
37

Um timestampcampo é um caso especial do datetimecampo. Você pode criar timestampcolunas para ter propriedades especiais; ele pode ser configurado para se atualizar ao criar e / ou atualizar.

Em termos de banco de dados "maiores", timestamphá alguns gatilhos de casos especiais.

O que é certo depende inteiramente do que você deseja fazer.

Jeff Warnica
fonte
6
Não, a diferença não é apenas "um caso especial". Como os fusos horários da sessão que define / consulta os valores estão envolvidos de maneira diferente.
dólmen
Estou feliz que você colocou "O que é certo depende inteiramente do que você quer fazer". Existem muitas respostas no SE que afirmam, sem justificativa suficiente, "Você nunca deve fazer X" ou "Você deve sempre fazer Y".
Agi Hammerthief 23/08/18
37

O TIMESTAMP está sempre no UTC (ou seja, segundos decorridos desde 01-01-2009, no UTC), e o servidor MySQL o converte automaticamente na data / hora do fuso horário da conexão. A longo prazo, o TIMESTAMP é o caminho a percorrer, porque você sabe que seus dados temporais sempre estarão no UTC. Por exemplo, você não estragará suas datas se migrar para um servidor diferente ou se alterar as configurações de fuso horário no servidor.

Nota: o fuso horário da conexão padrão é o fuso horário do servidor, mas isso pode (deve) ser alterado por sessão (consulte SET time_zone = ...).

Sobes
fonte
29

Comparação entre DATETIME, TIMESTAMP e DATE

insira a descrição da imagem aqui

O que é isso [.fração]?

  • Um valor DATETIME ou TIMESTAMP pode incluir uma parte fracionária de segundos à direita com precisão de até microssegundos (6 dígitos). Em particular, qualquer parte fracionária em um valor inserido em uma coluna DATETIME ou TIMESTAMP é armazenada em vez de descartada. Claro que isso é opcional.

Fontes:

Dehan de Croos
fonte
24

Eu sempre usaria um timestamp Unix ao trabalhar com MySQL e PHP. A principal razão para isso ser o método de data padrão no PHP usa um carimbo de data / hora como parâmetro, portanto, não seria necessário analisar.

Para obter o timestamp atual do Unix no PHP, basta fazer time();
e no MySQL SELECT UNIX_TIMESTAMP();.

Mark Davidson
fonte
6
-1 Na ​​verdade, acho que a resposta abaixo é melhor - usar datetime permite que você introduza mais lógica no processamento de datas no próprio MySQL, o que pode ser muito útil.
Toby Hede
Não existem benchmarks mostrando que a classificação no MySQL é mais lenta que no php?
Sdkfasldf 17/05
bem, depende, às vezes é bom usá-lo quando gostamos de não usar o strtotime. (php5.3 dep)
Adam Ramadhan
você pode empurrar a lógica em mysql usando apenas FROM_UNIXTIME se necessário
inarilo
Eu costumava usar todos os carimbos de data e hora do Unix em meus aplicativos PHP e no MySQL, no entanto, achei muito mais conveniente armazenar datas e horas no MySQL como tipos de data / hora nativas. Isso é especialmente útil para fins de relatório e apenas para navegar nos conjuntos de dados. Com o tempo, quando fiquei frustrado por ter que copiar / passar os carimbos de data e hora do Unix, comecei a mudar. Estou certo de que há desempenho e outros prós / contras, mas dependendo do seu caso de uso, a conveniência pode ser mais importante do que micro otimizações.
DavidScherer
24

Vale a pena notar no MySQL que você pode usar algo ao longo das linhas abaixo ao criar suas colunas da tabela:

on update CURRENT_TIMESTAMP

Isso atualizará o horário em cada instância em que você modificar uma linha e, às vezes, é muito útil para as informações de última edição armazenadas. Isso funciona apenas com carimbo de data e hora, mas não com data e hora.

leejmurphy
fonte
17

De acordo com minhas experiências, se você deseja um campo de data no qual a inserção ocorre apenas uma vez e não deseja nenhuma atualização ou qualquer outra ação nesse campo específico, vá com a data e hora .

Por exemplo, considere uma usertabela com um campo DATA DE INSCRIÇÃO . Nessa usertabela, se você quiser saber a última hora de logon de um usuário específico, escolha um campo do tipo de carimbo de data / hora para que o campo seja atualizado.

Se você estiver criando a tabela a partir do phpMyAdmin, a configuração padrão atualizará o campo de carimbo de data / hora quando ocorrer uma atualização de linha. Se o registro de data e hora arquivado não estiver sendo atualizado com a atualização de linha, você poderá usar a consulta a seguir para fazer com que um campo de registro de data e hora seja atualizado automaticamente.

ALTER TABLE your_table
      MODIFY COLUMN ts_activity TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
Kannan Prasad
fonte
15

O tipo de dados do registro de data e hora armazena data e hora, mas no formato UTC, não no formato de fuso horário atual como datetime. E quando você busca dados, o registro de data e hora converte isso novamente no fuso horário atual.

Então, suponha que você esteja nos EUA e obtenha dados de um servidor com fuso horário nos EUA. Você receberá a data e a hora de acordo com o fuso horário dos EUA. A coluna do tipo de dados de data e hora sempre é atualizada automaticamente quando sua linha é atualizada. Portanto, pode ser útil rastrear quando uma linha específica foi atualizada da última vez.

Para mais detalhes, você pode ler a postagem do blog Timestamp Vs Datetime .

Arvind
fonte
Você pode (deve) sempre definir o fuso horário no nível da sessão com SET time_zone = '+0:00';(UTC aqui) para garantir o que você obtém / define dos TIMESTAMPvalores e evitar dependendo do padrão de time_zone do servidor que pode ser alterado.
Dolmen
14

Eu sempre uso um carimbo de data e hora do Unix, simplesmente para manter a sanidade ao lidar com muitas informações de data e hora, especialmente ao realizar ajustes para fusos horários, adicionar / subtrair datas e assim por diante. Ao comparar registros de data e hora, isso exclui os fatores complicadores do fuso horário e permite poupar recursos no processamento no servidor (seja código do aplicativo ou consultas ao banco de dados), na medida em que você usa aritmética leve e não subtrai / subtrai data e hora mais pesadas funções.

Outra coisa que vale a pena considerar:

Se você está criando um aplicativo, nunca sabe como os dados podem ser usados ​​na linha. Se você precisar, digamos, comparar um monte de registros em seu conjunto de dados, digamos, com vários itens de uma API de terceiros e dizer, colocá-los em ordem cronológica, ficará feliz em ter Carimbos de data e hora Unix para suas linhas. Mesmo se você decidir usar os carimbos de data / hora do MySQL, armazene um carimbo de data / hora do Unix como seguro.

Oliver Holmberg
fonte
14

No meu caso, defino o UTC como um fuso horário para tudo: o sistema, o servidor de banco de dados etc. sempre que posso. Se meu cliente precisar de outro fuso horário, eu o configurarei no aplicativo.

Quase sempre prefiro carimbos de data e hora em vez de campos de data e hora, porque os carimbos de hora incluem o fuso horário implicitamente. Portanto, desde o momento em que o aplicativo será acessado por usuários de diferentes fusos horários e você desejar que eles vejam datas e horas no fuso horário local, esse tipo de campo facilita bastante a execução, do que se os dados fossem salvos em campos de data e hora .

Além disso, no caso de uma migração do banco de dados para um sistema com outro fuso horário, eu me sentiria mais confiante usando carimbos de data e hora. Isso sem falar nos possíveis problemas ao calcular as diferenças entre dois momentos, com uma mudança de tempo menor entre eles e precisando de uma precisão de 1 hora ou menos.

Então, para resumir, eu valorizo ​​essas vantagens do timestamp:

  • Pronto para uso em aplicativos internacionais (fuso horário)
  • Migrações fáceis entre fusos horários
  • bastante fácil de calcular diferenças (basta subtrair os dois registros de data e hora)
  • não se preocupe com datas dentro / fora de um período de verão

Por todos esses motivos, escolho os campos UTC e de carimbo de data / hora, quando possível. E evito dores de cabeça;)

Roger Campanera
fonte
os dados de carimbo de data e hora serão divertidos para a pessoa que oferece suporte ao seu aplicativo quando chegar 20 de janeiro de 2038. tick tock tick tock
Wilson Hauck
O tipo de carimbo de data e hora pode ser aumentado um pouco e dobrar os valores possíveis.
Roger Campanera
Teste sua teoria para 'aumentar um pouco' e veja se você pode armazenar com êxito em 1º de fevereiro de 2038 e recuperá-la com o MySQL. Vamos ver sua definição de tabela quando terminar, por favor. Você provavelmente vai ter um monte de conhecidos passado infeliz em fevereiro de 2038.
Wilson Hauck
1
@WilsonHauck Você terá que atualizar a versão do MySQL muito antes de 2038 de qualquer maneira. E esse TIMESTAMP estendido será tratado pela migração. Além disso, poucas aplicações além de lidar com hipotecas realmente precisam se preocupar com 2038 no momento.
Dolmen
@dolmen Muitas ferramentas e materiais de nível profissional têm uma garantia de mais de 20 anos. Então, algo como warranties.expires_atnão poderia ser um timestamp do MySQL hoje.
alexw
13

Cuidado com a alteração do carimbo de data e hora quando você faz uma instrução UPDATE em uma tabela. Se você possui uma tabela com as colunas 'Nome' (varchar), 'Idade' (int) e 'Date_Added' (carimbo de data e hora) e executa a seguinte instrução DML

UPDATE table
SET age = 30

todos os valores da coluna "Data_Adicionados" serão alterados para o carimbo de data / hora atual.

Lloyd Banks
fonte
3
com base em como você configura sua tabela, você pode controlar esse comportamento. olhar para dev.mysql.com/doc/refman/5.5/en/timestamp-initialization.html
Charles Faiga
5
@CharlesFaiga O comportamento padrão é que o registro de data e hora seja atualizado quando qualquer outra coluna for atualizada. Você tem que virar explicitamente esta situação se você deseja que o timestamp para reter seu valor original
Lloyd Banks
O que é isso ?! você deve definir a coluna de carimbo de data / hora comoON UPDATE CURRENT_TIMESTAMP
Accountant
Esse é um recurso que você deve habilitar explicitamente ao criar a tabela.
Dolmen
13

Referência retirada deste artigo:

As principais diferenças:

TIMESTAMP usado para rastrear alterações nos registros e atualizar sempre que o registro é alterado. DATETIME usado para armazenar valores estáticos e específicos que não são afetados por nenhuma alteração nos registros.

O TIMESTAMP também é afetado por diferentes configurações relacionadas ao Fuso Horário. DATETIME é constante.

O TIMESTAMP converteu o fuso horário atual internamente em UTC para armazenamento e, durante a recuperação, converteu novamente no fuso horário atual. DATETIME não pode fazer isso.

Intervalo suportado TIMESTAMP: '1970-01-01 00:00:01' UTC para '2038-01-19 03:14:07' UTC DATETIME intervalo suportado: '1000-01-01 00:00:00' para '9999 -12-31 23:59:59 ′

Anvesh
fonte
11
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
|                                       TIMESTAMP                                       |                                 DATETIME                                 |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
| TIMESTAMP requires 4 bytes.                                                           | DATETIME requires 8 bytes.                                               |
| Timestamp is the number of seconds that have elapsed since January 1, 1970 00:00 UTC. | DATETIME is a text displays 'YYYY-MM-DD HH:MM:SS' format.                |
| TIMESTAMP supported range: 1970-01-01 00:00:01 UTC to 2038-01-19 03:14:07 UTC.    | DATETIME supported range: 1000-01-01 00:00:00 to 9999-12-31 23:59:59 |
| TIMESTAMP during retrieval converted back to the current time zone.                   | DATETIME can not do this.                                                |
| TIMESTAMP is used mostly for metadata i.e. row created/modified and audit purpose.    | DATETIME is used mostly for user-data.                                   |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
Premraj
fonte
10

Outra diferença entre carimbo de data e hora e data e hora está no carimbo de data e hora que você não pode usar como valor padrão NULL.

ecleel
fonte
8
Está obviamente errado. Aqui está um exemplo: CREATE TABLE t2 ( ts1 TIMESTAMP NULL, ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP); A primeira coluna pode aceitar um valor NULL.
Ormoz #
10

Encontrei utilidade insuperável na capacidade do TIMESTAMP de se atualizar automaticamente com base no tempo atual sem o uso de gatilhos desnecessários. Mas sou apenas eu, embora o TIMESTAMP seja UTC como foi dito.

Ele pode acompanhar diferentes fusos horários, portanto, se você precisar exibir um tempo relativo, por exemplo, o horário UTC é o que você deseja.

Marc DiMillo
fonte
9

A principal diferença é

  • um ÍNDICE no carimbo de data / hora - funciona
  • um ÍNDICE no Datetime - Não Funciona

veja esta postagem para ver problemas com a indexação do Datetime

Charles Faiga
fonte
6
Ambos têm o mesmo problema se você estiver selecionando uma função com base no valor da coluna e ambos puderem ser indexados.
Marcus Adams
4
O índice funciona no carimbo de data e hora e não na data e hora? Você tirou conclusões erradas dessas postagens.
Salman A
9

Parei de usar datetimeem meus aplicativos depois de enfrentar muitos problemas e bugs relacionados a fusos horários. IMHO usando timestampé melhor do que datetimena maioria dos casos .

Quando você pergunta que horas são? e a resposta vem como algo como '2019-02-05 21:18:30', que não está completo, resposta não definida porque falta outra parte, em que fuso horário? Washington? Moscow? Pequim?

Usar datetime sem o fuso horário significa que seu aplicativo está lidando com apenas 1 fuso horário, no entanto, os timestamps oferecem os benefícios de datetimemais a flexibilidade de mostrar o mesmo ponto exato do tempo em diferentes fusos horários.

Aqui estão alguns casos que farão você se arrepender de usar datetimee desejará que você armazene seus dados em timestamps.

  1. Para o conforto de seus clientes, você deseja mostrar a eles os horários com base em seus fusos horários preferidos sem precisar fazer as contas e converter o horário em seu fuso horário significativo. tudo o que você precisa é alterar o fuso horário e todo o código do seu aplicativo será o mesmo. (Na verdade, você sempre deve definir o fuso horário no início do aplicativo ou solicitar o processamento no caso de aplicativos PHP)

    SET time_zone = '+2:00';
  2. você mudou o país em que fica e continua seu trabalho de manter os dados enquanto os vê em um fuso horário diferente (sem alterar os dados reais).

  3. você aceita dados de diferentes clientes em todo o mundo, cada um deles insere a hora no fuso horário.

Em resumo

datetime = o aplicativo suporta 1 fuso horário (para inserir e selecionar)

timestamp = o aplicativo suporta qualquer fuso horário (para inserir e selecionar)


Esta resposta é apenas para destacar a flexibilidade e a facilidade dos carimbos de data / hora quando se trata de fusos horários, mas não cobre outras diferenças, como o tamanho da coluna, o intervalo ou a fração .

Contador م
fonte
e se houver campos que usem datee outros campos timestampem uma tabela. Eu acho que causará um novo problema porque os dados filtrados por wherenão estão de acordo com as alterações do fuso horário.
Erlang P
@ ErlangP Nesse caso, seu aplicativo deve corrigir o problema de fuso horário na datecoluna antes de enviar a consulta.
Accountant em 11/02
7

Eu prefiro usar o carimbo de data / hora para manter tudo em um formato bruto comum e formatar os dados no código PHP ou na sua consulta SQL. Há casos em que é útil no seu código manter tudo em segundos simples.

Hans
fonte
7

A TIMESTAMPrequer 4 bytes, enquanto a DATETIMErequer 8 bytes.

Mwangi Thiga
fonte
6

Eu gosto de um carimbo de data / hora do Unix, porque você pode converter para números e apenas se preocupar com o número. Além disso, você adiciona / subtrai e obtém durações, etc. Em seguida, converte o resultado em Data em qualquer formato. Esse código descobre quanto tempo, em minutos, passou entre um registro de data e hora de um documento e o horário atual.

$date  = $item['pubdate']; (etc ...)
$unix_now = time();
$result = strtotime($date, $unix_now);
$unix_diff_min = (($unix_now  - $result) / 60);
$min = round($unix_diff_min);
user723220
fonte
4
Ou use um datetime do MySQL legível por humanos e nativo e use funções nativas do MySQL para adicionar / subtrair datetime.
Julien Palard