Se CURRENT_TIMESTAMP
puede utilizar como PRIMARY KEY
?
¿Existe la posibilidad de que dos o más INSERTs diferentes obtengan lo mismo CURRENT_TIMESTAMP
?
postgresql
database-design
primary-key
timestamp
John Puskin
fuente
fuente
Respuestas:
Según la documentación , la precisión de los
CURRENT_TIMESTAMP
microsegundos. Por lo tanto, la probabilidad de una colisión es baja, pero posible.Ahora imagine un error que ocurre muy raramente y causa errores en la base de datos. ¿Qué tan difícil es depurarlo? Es un error mucho peor que uno que es al menos determinista.
El contexto más amplio: probablemente desee evitar estos pequeños matices con las secuencias, lo cual es particularmente molesto si está acostumbrado a MySQL.
Además, si está utilizando transacciones (¡la mayoría de los marcos web, particularmente los Java, sí!), ¡Las marcas de tiempo serán las mismas dentro de una transacción! Una demostración:
¿Nos vemos? Dos selecciones, exactamente el mismo resultado. No escribo tan rápido. ;-)
-
Si desea identificar fácilmente, evitando el uso de las secuencias, genere un valor hash a partir de los identificadores reales de los registros. Por ejemplo, si su base de datos tiene humanos, y sabe que su fecha de nacimiento, el apellido de soltera de la madre y el nombre real los identifica de manera única, entonces use un
como id. Además de eso, puede usar una
CreationDate
columna, después de lo que indexa la tabla, pero no es una clave (que es la identificación).Ps En general, es una muy buena práctica hacer que su DB sea tan determinista, como sea posible. Es decir, la misma operación debería crear exactamente el mismo cambio en la base de datos . Cualquier ID basado en la marca de tiempo falla esta importante característica. ¿Qué pasa si quieres depurar o simular algo? Vuelve a reproducir una operación y se creará el mismo objeto con una identificación diferente ... realmente no es difícil de seguir y ahorra muchas horas de trabajo.
Ps2 Cualquiera que verifique su código en el futuro, no tendrá la mejor opinión al ver los identificadores generados por la marca de tiempo, por los motivos anteriores.
fuente
INSERT
de varias filas, todas obtienen lo mismocurrent_timestamp
. Y luego tienes disparadores ...No realmente porque es posible que CURRENT_TIMESTAMP proporcione dos valores idénticos para dos INSERTs posteriores (o un solo INSERT con varias filas).
Utilice un UUID basado en el tiempo en su lugar: uuid_generate_v1mc () .
fuente
Estrictamente hablando: No. Porque
CURRENT_TIMESTAMP
es una función y solo una o más columnas de la tabla pueden formar unaPRIMARY KEY
restricción.Si quiere crear una
PRIMARY KEY
restricción en una columna con el valor predeterminadoCURRENT_TIMESTAMP
, la respuesta es: Sí, puede hacerlo . Nada le impide hacerlo, como nada le impide disparar manzanas de la cabeza de su hijo. La pregunta aún no tendría sentido mientras no definas el propósito de la misma. ¿Qué tipo de datos deben contener la columna y la tabla? ¿Qué reglas estás tratando de implementar?Por lo general, la idea está destinada a errores de clave duplicados, ya que
CURRENT_TIMESTAMP
es unaSTABLE
función que devuelve el mismo valor para la misma transacción (la hora de inicio de la transacción). Múltiples INSERTs en la misma transacción están obligados a colisionar, como otras respuestas ya ilustradas. El manual:Las marcas de tiempo de Postgres se implementan como enteros de 8 bytes que representan hasta 6 dígitos fraccionarios (resolución de microsegundos).
Si está creando una tabla que se supone que no debe contener más de una fila por microsegundo y esa condición no va a cambiar (algo llamado
sensor_reading_per_microsecond
), entonces podría tener sentido. Se supone que las filas duplicadas generan un error de violación de clave duplicada. Sin embargo, esa es una excepción exótica. Y el tipo de datostimestamptz
(notimestamp
) probablemente sería preferible. Ver:Todavía preferiría usar una clave primaria serial sustituta en su lugar. Y agregue una
UNIQUE
restricción en la columna de marca de tiempo. Menos complicaciones posibles, sin depender de los detalles de implementación del RDBMS.fuente
sensor_reading_per_microsecond
puede colisionar si no puede garantizar absolutamente que el tiempo de cada lectura esté perfectamente sincronizado con respecto al anterior; una desviación de menos de microsegundos (que a menudo no es imposible) rompe el esquema. En general, todavía evitaría esto por completo. (¡Ojo, como has indicado, en tal caso, la colisión resultante puede ser deseable!)