Peut CURRENT_TIMESTAMP
être utilisé comme un PRIMARY KEY
?
Y a-t-il une possibilité que deux ou plusieurs INSERTS différents obtiennent la même chose CURRENT_TIMESTAMP
?
postgresql
database-design
primary-key
timestamp
John Puskin
la source
la source
Réponses:
Selon la documentation , la précision des
CURRENT_TIMESTAMP
microsecondes est. Ainsi, la probabilité d'une collision est faible, mais possible.Imaginez maintenant un bogue qui se produit très rarement et provoque des erreurs de base de données. Est-il difficile de le déboguer? C'est un bug bien pire que celui qui est au moins déterministe.
Le contexte plus large: vous voulez probablement éviter ces petites nuances avec les séquences, ce qui est particulièrement gênant si vous êtes habitué à MySQL.
De plus, si vous utilisez des transactions (la plupart des frameworks Web, en particulier Java, le font!), Les horodatages seront les mêmes à l'intérieur d'une transaction! Une démonstration:
À plus? Deux sélections, exactement le même résultat. Je ne tape pas si vite. ;-)
-
Si vous voulez facilement des identifiants, en évitant l'utilisation des séquences, générez une valeur de hachage à partir des vrais identifiants des enregistrements. Par exemple, si votre base de données contient des humains et que vous savez que leur date de naissance, le nom de jeune fille de leur mère et leur vrai nom les identifient de manière unique, utilisez un
comme id. À côté de cela, vous pouvez utiliser une
CreationDate
colonne, après ce que vous indexez la table, mais ce n'est pas une clé (qui est l'id).Ps En général, c'est une très bonne pratique de rendre votre base de données aussi déterministe que possible. C'est-à-dire que la même opération devrait créer exactement le même changement dans la base de données . Tout ID basé sur l'horodatage ne parvient pas à cette fonctionnalité importante. Et si vous voulez déboguer ou simuler quelque chose? Vous rejouez une opération et le même objet sera créé avec un identifiant différent ... ce n'est vraiment pas difficile à suivre, et cela épargne beaucoup d'heures de travail.
Ps2 Quiconque vérifiera votre code à l'avenir, n'aura pas la meilleure opinion des identifiants générés par l'horodatage, pour les raisons ci-dessus.
la source
INSERT
plusieurs lignes, elles obtiennent toutes la même chosecurrent_timestamp
. Et puis vous avez des déclencheurs ...Pas vraiment parce qu'il est possible pour CURRENT_TIMESTAMP de fournir deux valeurs identiques pour deux INSERTs suivants (ou un INSERT unique avec plusieurs lignes).
Utilisez plutôt un UUID basé sur le temps: uuid_generate_v1mc () .
la source
Strictement parlant: non . Parce que
CURRENT_TIMESTAMP
c'est une fonction et qu'une ou plusieurs colonnes de table peuvent former unePRIMARY KEY
contrainte.Si vous voulez créer une
PRIMARY KEY
contrainte sur une colonne avec la valeur par défautCURRENT_TIMESTAMP
, la réponse est: oui, vous le pouvez . Rien ne vous empêche de le faire, comme rien ne vous empêche de tirer des pommes de la tête de votre fils. La question n'aurait toujours pas de sens tant que vous n'en définiriez pas le but. Quels types de données les colonnes et les tables sont-elles censées contenir? Quelles règles essayez-vous de mettre en œuvre?En règle générale, l'idée est liée à des erreurs de clé en double, car il
CURRENT_TIMESTAMP
s'agit d'uneSTABLE
fonction renvoyant la même valeur pour la même transaction (l'heure de début de la transaction). Plusieurs INSERT dans la même transaction sont susceptibles de se heurter - comme d'autres réponses déjà illustrées. Le manuel:Les horodatages PostgreSQL sont implémentés sous forme d'entiers de 8 octets représentant jusqu'à 6 chiffres fractionnaires (résolution en microsecondes).
Si vous créez une table qui ne doit pas contenir plus d'une ligne par microseconde et que cette condition ne changera pas (quelque chose nommé
sensor_reading_per_microsecond
), alors cela pourrait avoir du sens. Les lignes en double sont censées déclencher une erreur de violation de clé en double. C'est une exception exotique, cependant. Et le type de donnéestimestamptz
(nontimestamp
) serait probablement préférable. Voir:Je préfère toujours utiliser une clé primaire série de substitution à la place. Et ajoutez une
UNIQUE
contrainte sur la colonne d'horodatage. Moins de complications possibles, sans compter sur les détails de mise en œuvre du SGBDR.la source
sensor_reading_per_microsecond
peut entrer en collision si vous ne pouvez pas absolument garantir que la synchronisation de chaque lecture est parfaitement synchronisée par rapport à la précédente; une déviation inférieure à la microseconde (ce qui n'est souvent pas impossible) rompt le schéma. En général, j'éviterais tout à fait cela. (Attention, comme vous l'avez indiqué, dans un tel cas, la collision résultante peut être souhaitable!)