2010-11-27 11 views
50

Tengo una tabla de registro que contendrá millones de escrituras por razones estadísticas. Todas las columnas son claves extranjeras int. También voy a agregar una columna de marca de tiempo para cada fila. Dado que DATETIME toma 8bits, usaré int(10) unsigned para reducir el espacio de almacenamiento (y el índice en esa columna) a la mitad.¿Cómo se deben almacenar las marcas de tiempo de unix en columnas int?

Sin embargo, me pregunto cuándo esta columna ya no funcionará. A las 3:14:07 AM del 19 de enero de 2038, el valor de 9.999.999.999 será un problema para las marcas de tiempo de UNIX, pero una int sin firmar en MySQL solo tiene una capacidad de 4.294.967.295 y la marca de tiempo 4294967295 muestra un número no válido en mi aplicación PHP.

¿Qué significa esto? ¿El final del almacenamiento de marcas de tiempo int en MySQL va a ser en algún momento en 2021 ya que no puede llegar al 9999999999?

Respuesta:

  1. 2147483647 es 2038 (no 9999999999) así que no hay problema.
  2. unsigned no es necesario ya que 2147483647 se ajusta bien en un int firmado de MySQL.
+1

Me preocuparé por eso entonces. ;) – Stephen

+3

Incluso si tuviera 10 millones de filas, usaría 9.5 MB adicionales ... Solo use el tipo DATETIME, realmente. –

+2

Debe tener en cuenta que el objetivo del tipo DateTime es protegerlo de tener que tratar este problema en absoluto. – Nick

Respuesta

81

Las marcas de tiempo UNIX estándar son un entero de 32 bits con signo, que en MySQL es una columna "int" regular. No hay forma de que pueda almacenar 9.999.999.999, ya que está fuera del rango de representación, la más alta de 32 bits de cualquier tipo puede ser 4.294.967.295. El más alto de 32 bits firmado va es 2.147.483.647.

Si/cuando las marcas de tiempo de UNIX van a un tipo de datos de 64 bits, entonces tendrá que usar un "bigint" de MySQL para almacenarlos.

En cuanto a int(10), la parte (10) es meramente indicativa. MySQL aún usará un total de 32 bits internamente para almacenar el número, pero solo mostrará 10 cada vez que selecciones la tabla.

+3

Me alegro de que hayas confirmado lo que dije, pero ¿qué pasa con la pregunta de qué significa esto para almacenar fechas? – Xeoncross

+1

Una marca de tiempo de Unix estándar irá a una columna 'int' firmada estándar en PHP sin ninguna conversión. No existe una marca de tiempo de Unix firmada, no está en la libc estándar, por lo que no tiene que preocuparse por las marcas de tiempo entre 2.147.483.648 -> 4.294.967.295.La compatibilidad con la marca de tiempo de PHP se basa directamente en la libc también, por lo que PHP tampoco aceptará una marca de tiempo sin firmar. –

+2

Significa que no puede almacenar fechas de esa manera que sea mayor que 2^31-1 (Eso es 2147483647, que puede representar el tiempo como segundos hasta 2038. 9.999.999.999 lo acercaría a 2287). Este es un problema conocido; http: //stackoverflow.com/questions/36239/what-should-we-do-to-prepare-for-2038 – nos

Cuestiones relacionadas