Pode CURRENT_TIMESTAMP
ser usado como um PRIMARY KEY
?
Existe a possibilidade de dois ou mais INSERTs diferentes obterem o mesmo CURRENT_TIMESTAMP
?
postgresql
database-design
primary-key
timestamp
John Puskin
fonte
fonte
Respostas:
Conforme a documentação , a precisão do
CURRENT_TIMESTAMP
é microssegundos. Assim, a probabilidade de uma colisão é baixa, mas possível.Agora imagine um bug que acontece muito raramente e causa erros no banco de dados. Quão difícil é depurá-lo? É um bug muito pior do que um que é pelo menos determinístico.
O contexto mais amplo: você provavelmente deseja evitar essas pequenas nuances com as seqüências, o que é particularmente irritante se você está acostumado ao MySQL.
Além disso, se você estiver usando transações (a maioria das estruturas da Web, principalmente as de Java, fazem!), Os carimbos de data e hora serão os mesmos dentro de uma transação! Uma demonstração:
Até logo? Duas seleções, exatamente o mesmo resultado. Eu não digito tão rápido. ;-)
-
Se você quiser IDs com facilidade, evitando o uso das seqüências, gere algum valor de hash a partir dos identificadores reais dos registros. Por exemplo, se seu banco de dados possui seres humanos e você sabe que a data de nascimento, o nome de solteira da mãe e o nome real os identificam exclusivamente, use um
como id. Além disso, você pode usar uma
CreationDate
coluna, depois do que indexa a tabela, mas não é uma chave (que é o ID).Ps Em geral, é uma prática muito boa tornar seu banco de dados tão determinístico quanto possível. Ou seja, a mesma operação deve criar exatamente a mesma alteração no banco de dados . Qualquer identificação baseada em carimbo de data e hora falha neste recurso importante. E se você quiser depurar ou simular alguma coisa? Você reproduz uma operação e o mesmo objeto será criado com um ID diferente ... não é realmente difícil de seguir e poupa muitas horas de trabalho.
Ps2 Qualquer pessoa que verifique seu código no futuro não terá a melhor opinião para ver os IDs gerados por carimbo de data / hora, pelos motivos acima.
fonte
INSERT
de várias linhas, todas elas serão iguaiscurrent_timestamp
. E então você tem gatilhos ...Na verdade, não é porque é possível que CURRENT_TIMESTAMP forneça dois valores idênticos para dois INSERTs subsequentes (ou um único INSERT com várias linhas).
Use um UUID baseado em tempo: uuid_generate_v1mc () .
fonte
Estritamente falando: Não. Porque
CURRENT_TIMESTAMP
é uma função e apenas uma ou mais colunas da tabela podem formar umaPRIMARY KEY
restrição.Se você deseja criar uma
PRIMARY KEY
restrição em uma coluna com o valor padrãoCURRENT_TIMESTAMP
, a resposta é: Sim, você pode . Nada o impede de fazê-lo, como nada o impede de atirar maçãs da cabeça do seu filho. A questão ainda não faria sentido enquanto você não definir seu objetivo. Que tipo de dados a coluna e a tabela devem conter? Quais regras você está tentando implementar?Normalmente, a ideia é executada com erros de chave duplicados, pois
CURRENT_TIMESTAMP
é umaSTABLE
função que retorna o mesmo valor para a mesma transação (a hora de início da transação). Vários INSERTs na mesma transação são obrigados a colidir - como outras respostas já ilustradas. O manual:Os carimbos de data e hora do Postgres são implementados como números inteiros de 8 bytes, representando até 6 dígitos fracionários (resolução de microssegundos).
Se você está construindo uma tabela que é suposto não detêm mais de uma linha por microssegundo e essa condição não vai mudar (algo chamado
sensor_reading_per_microsecond
), então pode fazer sentido. Linhas duplicadas devem gerar um erro de violação de chave duplicada. Essa é uma exceção exótica, no entanto. E o tipo de dadostimestamptz
(nãotimestamp
) provavelmente seria preferível. Vejo:Eu ainda preferiria usar uma chave primária serial substituta. E adicione uma
UNIQUE
restrição na coluna de carimbo de data / hora. Menos complicações possíveis, sem depender dos detalhes de implementação do RDBMS.fonte
sensor_reading_per_microsecond
pode colidir se você não puder garantir absolutamente que o tempo de cada leitura esteja perfeitamente sincronizado em relação à anterior; um desvio de microssegundo (que geralmente não é impossível) interrompe o esquema. Em geral, eu ainda evitaria isso totalmente. (Lembre-se, como você indicou, nesse caso, a colisão resultante pode ser desejável!)