Você recomendaria o uso de um campo datetime ou timestamp e por quê (usando o MySQL)?
Estou trabalhando com PHP no lado do servidor.
Você recomendaria o uso de um campo datetime ou timestamp e por quê (usando o MySQL)?
Estou trabalhando com PHP no lado do servidor.
Respostas:
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.
DATETIME
representa uma data (como encontrada em um calendário) e uma hora (como pode ser observado em um relógio de parede), enquanto TIMESTAMP
representa 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].
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 .
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.
new Date().getTime()
já fornece um valor de 64 bits.
Os exemplos abaixo mostram como o TIMESTAMP
tipo de data alterou os valores após alterar o time-zone to 'america/new_york'
local DATETIME
inalterado.
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 .
DATETIME
tempo efetivo mudou com a mudança de fuso horário, TIMESTAMP
não mudou, mas a representação humana mudou.
set time_zone="america/new_york"
;
A principal diferença é que DATETIME é constante enquanto TIMESTAMP é afetado pela time_zone
configuraçã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.)
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.
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:
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.
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;)
TIMESTAMP tem quatro bytes ou oito bytes para DATETIME.
Os carimbos de hora também são mais claros no banco de dados e indexados mais rapidamente.
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.
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.
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
SET time_zone = '+0:00';
para UTC.
Um timestamp
campo é um caso especial do datetime
campo. Você pode criar timestamp
colunas para ter propriedades especiais; ele pode ser configurado para se atualizar ao criar e / ou atualizar.
Em termos de banco de dados "maiores", timestamp
há alguns gatilhos de casos especiais.
O que é certo depende inteiramente do que você deseja fazer.
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 = ...
).
Comparação entre DATETIME, TIMESTAMP e DATE
O que é isso [.fração]?
Fontes:
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();
.
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.
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 user
tabela com um campo DATA DE INSCRIÇÃO . Nessa user
tabela, 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;
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 .
SET time_zone = '+0:00';
(UTC aqui) para garantir o que você obtém / define dos TIMESTAMP
valores e evitar dependendo do padrão de time_zone do servidor que pode ser alterado.
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.
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:
Por todos esses motivos, escolho os campos UTC e de carimbo de data / hora, quando possível. E evito dores de cabeça;)
warranties.expires_at
não poderia ser um timestamp do MySQL hoje.
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.
ON UPDATE CURRENT_TIMESTAMP
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 ′
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
| 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. |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
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.
CREATE TABLE t2 ( ts1 TIMESTAMP NULL, ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
A primeira coluna pode aceitar um valor NULL.
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.
A principal diferença é
veja esta postagem para ver problemas com a indexação do Datetime
Parei de usar datetime
em meus aplicativos depois de enfrentar muitos problemas e bugs relacionados a fusos horários. IMHO usando timestamp
é melhor do que datetime
na 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 datetime
mais 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 datetime
e desejará que você armazene seus dados em timestamps.
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';
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).
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 .
date
e outros campos timestamp
em uma tabela. Eu acho que causará um novo problema porque os dados filtrados por where
não estão de acordo com as alterações do fuso horário.
date
coluna antes de enviar a consulta.
A TIMESTAMP
requer 4 bytes, enquanto a DATETIME
requer 8 bytes.
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);