A updated
coluna foi criada como
| updated | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
um simples SELECT
dá
+---------------------+
| updated |
+---------------------+
| 2021-12-25 00:15:47 |
+---------------------+
Infelizmente, updated
não foi criado como timestamp(3)
.
Existe alguma maneira de extrair mais precisão de updated
? (o MySQL armazena mais precisão do que o segundo, mesmo que mostre apenas segundos?)
Não. Não é possÃvel selecionar os dados que estão ausentes na tabela e não podem ser calculados a partir dos dados presentes nas tabelas.
Não. Ele armazena exatamente o que você pediu. Ele pode armazenar até microssegundos - mas você não solicitou essa precisão.
Você liga
NOW()
- e obtém a data e hora sem milissegundos. LigueNOW(3)
ouNOW(6)
e obtenha um valor mais preciso.https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=ccaf9b2c25e372c7bf0ca82c66ded787
Nunca consulte a pessoa do campo MySQL que disse esse absurdo novamente.
<TL;DR>
Para responder a pergunta primeiro:
Minha pesquisa sugere fortemente que não há como recuperar mais dados do que os originalmente armazenados no campo - que era
TIMESTAMP(0)
- o valor padrão de (p
) se nenhuma precisão for especificada (veja a discussão abaixo).A razão pela qual isso pode ser afirmado com alguma certeza é que, se observarmos os requisitos de armazenamento para vários tipos aqui , você verá o seguinte:
e logo abaixo disso, você verá:
Então, o que estou tirando disso é que, se você optar por não armazenar
TIMESTAMP
s especificamente com uma precisão maior que 0, perderá toda a precisão mais alta porque nenhum espaço é reservado para essa precisão extra.Uma resposta completamente definitiva exigiria um editor hexadecimal e diversão para toda a famÃlia explorando os
.ibd
arquivos e/ou uma varredura no código-fonte do MySQL, ambos um pouco acima do meu salário! Eu acho que você pode considerar que sua precisão extra se foi, ou melhor, que nunca existiu em primeiro lugar!</TL;DR>
Tendo cometido alguns erros nos comentários (já excluÃdos), decidi realmente testar (como sugerido em seus comentários em sua própria resposta) minhas afirmações ( mea culpa, mea maxima culpa ).
Fico feliz em informar que estava correto sobre o problema de arredondamento - se alguém inserir um tempo com 6 segundos de precisão, o valor será arredondado e não truncado.
Todo o código abaixo (a menos que indicado de outra forma) está disponÃvel no violino aqui .
MySQL
TIMESTAMP
e fusos horários!Para MySQL, TIMESTAMPs são armazenados como segundos desde UTC - daqui :
Como um aparte, há outro violino aqui que mostra a diferença no MySQL entre
TIMESTAMP
eDATETIME
- o último tipo de dados não possui fusos horários.Eu recomendo fortemente que você (ou qualquer desenvolvedor) sempre use o UTC para armazenar os horários sempre que possÃvel - é mais simples, mais limpo e o horário de verão (DST) é cuidado para você pelo servidor.
Além disso, se você for obrigado a usar fusos horários locais, não use um deslocamento (+07:00 no violino) porque você perderá qualquer informação de horário de verão - a razão pela qual eu fiz isso é porque a implementação do MySQL do db<>fiddle não suporta fusos horários (veja aqui ), mas suporta deslocamentos.
Mais sobre MySQL
TIMESTAMP
:Enfim, a primeira coisa que me jogou foi o fato de que
TIMESTAMP
sem precisão éTIMESTAMP(0)
, mas isso está no manual :e daqui :
Justo o suficiente, mas eles pelo menos
[could | should]
têm uma configuração do Modo SQL do Servidor para substituir isso e alterá-lo para o comportamento do SQL Standard - eles fizeram isso antes para uma pilha de outros MySQL-ismos!Outro complicado (mas novamente documentado ) é que
ROUND
ing ocorre quando você tenta espremer uma fração de precisão mais alta em um campo de precisão mais baixa:Comportamento do MySQL:
Então, agora, vamos examinar o que o comportamento realmente é da seguinte forma:
e, em seguida, preencha-o:
e então examinamos nossos dados:
Resultado:
Assim, podemos ver que (conforme documentado)
TIMESTAMP
eTIMESTAMP(0)
(que são os mesmos de qualquer maneira) são arredondados de15.567899
para16
e que esse arredondamento continua na linha dependendo da precisão especificada - conforme o manual!Então, como remediar isso?
Existem duas possibilidades - a primeira é que você está fazendo medições TIMESTAMP(6) antigas de algum lugar e precisa truncar (e não arredondá -las - veja o violino principal ), e/ou possivelmente que, daqui para frente, você queira use
TIMESTAMP(3)
como seu tipo de campo eNOW(3)
como sua entrada ( violino diferente ).Isso exigirá truncar os valores no
TIMESTAMP(6)
campo. Isso se mostrou mais complicado do que pode parecer - veja o violino para os estágios, mas o melhor que consegui foi:Isso pode parecer um pouco como andar pelas casas, mas a
DATE_FORMAT
função MySQL tem uma granularidade de microssegundos, mas (estranhamente) não de milissegundos! Qualquer sugestão para uma solução mais simples e elegante é bem-vinda!Este valor pode então ser inserido em ap = 3
TIMESTAMP
(veja fiddle ).O ( manual ) diz:
Então, dias felizes. E verificando ( violino ):
Insira oito
NOW(p)
valores:E depois:
Resultado:
Podemos ver no exemplo acima que se o arredondamento estivesse ocorrendo, o
w
campo (NOW(3)
) seria arredondado para19:28:38.629
devido ao seguinte7
. Algumas execuções do violino podem ser necessárias para que isso se torne óbvio!Tamanho no disco:
Tentei encontrar uma consulta para obter os tamanhos individuais dos campos do MySQL no disco, mas o MySQL aparentemente não expõe essas informações - pelo menos não através de sua interface SQL. PostgreSQL tem a
pg_column_size()
função e também tem apageinspect
extensão contrib para quem gosta de mexer com dumps hexadecimais e bit-twiddling .O melhor que eu consegui, com exceção de obter um editor hexadecimal e/ou cavar o código-fonte do MySQL foi isso (veja o final do violino):
Resultado:
Então, 16kB para 8 registros. Uma pesquisa rápida revela ( manual ):
Na mesma página, há menção a innodb_page_size :
Resultado:
Portanto, tudo o que a
Data Length...
consulta acima está nos dizendo é que usamos 1 página de espaço em disco para uma pequena tabela - dificilmente surpreendente e não ajuda muito. Veja minha discussão na<TL;DR>
introdução sobre requisitos de armazenamento para ver por que (com toda a probabilidade) seus bits de precisão extras foram para aquele grande balde no céu... de profundis... .