Capítulo 11. Tipos de columna
Anterior |  | Siguiente

## Capítulo 11. Tipos de columna

MySQL soporta un número de tipos de columnas divididos en varias categorías: tipos númericos, tipos de fecha y hora, y tipos de cadenas de carácteres. Este capítulo primero hace un repaso de estos tipos de columnas, y luego proporciona una descripción detallada de las propiedades de los tipos de cada categoría, y un resumen de sus requerimientos de almacenamiento. El repaso es intencionalmente breve. Las descripciones más detalladas deben consultarse para obtener más información acerca de los tipos de datos particulares, como los formatos permitidos para especificar los tipos.

MySQL 5.0 soporta extensiones para tratar datos espaciales. Información al respecto se proporciona en Capítulo 18, Extensiones espaciales de MySQL.

Varias descripciones de los tipos de columnas usan estas convenciones:

- ``M``

  Indica la máxima anchura al mostrar los datos. El máximo ancho de muestra es 255.

- ``D``

  Se aplica a tipos de coma flotante y de coma fija e indica el número de dígitos a continuación del punto decimal. El valor máximo posible es 30, pero no debe ser mayor que `M`-2.

- ``

  Los corchetes ('`[`' y '`]`') indican partes de especificadores de tipos que son opcionales.

## 11.1. Panorámica de tipos de columna

### 11.1.1. Panorámica de tipos numéricos

A continuación hay un resumen de los tipos de columnas numéricos. Para información adicional, consulte Sección 11.2, “Tipos numéricos”. Los requerimientos de almacenamiento de columna se dan en Sección 11.5, “Requisitos de almacenamiento según el tipo de columna”.

`M` indica la anchura máxima para mostrar. La anchura máxima es 255. La anchura de muestra no tiene nada que ver con el tamaño de almacenamiento o el rango de valores que el valor puede contener, como se describe en Sección 11.2, “Tipos numéricos”.

Si especifica `ZEROFILL` para columnas numéricas,, MySQL añade automáticamente el atributo `UNSIGNED` en la columna.

`SERIAL` es un alias para `BIGINT UNSIGNED NOT NULL AUTO_INCREMENT`.

`SERIAL DEFAULT VALUE` en la definición de una columna de tipo entero es un alias para `NOT NULL AUTO_INCREMENT UNIQUE`.

Atención: Debe tener en cuenta que cuando usa la resta entre valores enteros cuando uno de los operandos es de tipo `UNSIGNED`, el resultado no tiene signo. Consulte Sección 12.8, “Funciones y operadores de cast”.

- `BIT[(`M`)]`

  En un tipo de datos bit. `M` indica el número de bits por valor, de 1 a 64. El valor por defecto es 1 si se omite `M` .

  Este tipo de datos se añadió en MySQL 5.0.3 para `MyISAM`, una extensión en 5.0.5 para `MEMORY`, `InnoDB`, y `BDB`. Antes de 5.0.3, `BIT` es un sinónimo de `TINYINT(1)`.

- `TINYINT[(`M`)] [UNSIGNED] [ZEROFILL]`

  Un entero muy pequeño. El rango con signo es de `-128` a `127`. El rango sin signo es de `0` a `255`.

- `BOOL`, `BOOLEAN`

  Son sinónimos para `TINYINT(1)`. Un valor de cero se considera falso. Valores distintos a cero se consideran ciertos.

  En el futuro, se introducirá tratamiento completo de tipos booleanos según el estándard SQL.

- `SMALLINT[(`M`)] [UNSIGNED] [ZEROFILL]`

  Un entero pequeño. El rango con signo es de `-32768` a `32767`. El rango sin signo es de `0` a `65535`.

- `MEDIUMINT[(`M`)] [UNSIGNED] [ZEROFILL]`

  Entero de tamaño medio. El rango con signo es de `-8388608` a `8388607`. El rango sin singo es de `0` a `16777215`.

- `INT[(`M`)] [UNSIGNED] [ZEROFILL]`

  Un entero de tamaño normal. El rango con signo es de `-2147483648` a `2147483647`. El rango sin signo es de `0` a `4294967295`.

- `INTEGER[(`M`)] [UNSIGNED] [ZEROFILL]`

  Es un sinónimo de `INT`.

- `BIGINT[(`M`)] [UNSIGNED] [ZEROFILL]`

  Un entero grande. El rango con signo es de `-9223372036854775808` a `9223372036854775807`. El rango sin signo es de `0` a `18446744073709551615`.

  Algunos aspectos a considerar con respecto a las columnas `BIGINT` :

  - Toda la aritmética se hace usando valores `BIGINT` o `DOUBLE`, así que no debe usar enteros sin signos mayores que `9223372036854775807` (63 bits) except con funciones bit! Si lo hace, algunos de los últimos dígitos en el resultado pueden ser erróneos por culpa de errores de redondeo al convertir valores `BIGINT` a `DOUBLE`.

    MySQL 5.0 puede tratar `BIGINT` en los siguientes casos:

    - Cuando usa enteros para almacenar valores grandes sin signo en una columna `BIGINT` .

    - En `MIN(`col_name`)` o `MAX(`col_name`)`, donde `col_name` se refiere a una columna `BIGINT` .

    - Al usar operadores (`+`, `-`, `*`, y así) donde ambos operadores son enteros.

  - Siempre puede guardar un valor entero exacto en un columna `BIGINT` almacenándolo usando una cadena de carácteres. En este caso, MySQL realiza una conversión cadena de carácteres-número que no implica representación de doble precisión intermedia.

  - Los operadores `-`, `+`, y `*` usan `BIGINT` en operaciones aritméticas cuando ambos operandos son valores enteros. Esto significa que si multiplica dos enteros grandes (o resultados de funciones que devuelven enteros), puede obtener resultados inesperados cuando el resultado es mayor que `9223372036854775807`.

- `FLOAT(`p`) [UNSIGNED] [ZEROFILL]`

  Número con coma flotante. `p` representa la precisión. Puede ir de 0 a 24 para números de coma flotante de precisión sencilla y de 25 a 53 para números de coma flotante con doble precisión. Estos tipos son como los tipos `FLOAT` y `DOUBLE` descritos a continuación. `FLOAT(p)` tiene le mismo rango que los tipos correspondientes `FLOAT` y `DOUBLE`, pero la anchura de muestra y el número de decimales no están definidos.

  En MySQL 5.0, este es un valor de coma flotante auténtico.

  Esta sintaxis se proprociona para compatibilidad con ODBC.

  Usar `FLOAT` puede darle algunos problemas inesperados ya que todos los cálculos se en MySQL se hacen con doble precisión. Consulte Sección A.5.7, “Resolver problemas con registros que no salen”.

- `FLOAT[(`M`,`D`)] [UNSIGNED] [ZEROFILL]`

  Un número de coma flotante pequeño (de precisión simple). Los valores permitidos son de `-3.402823466E+38` a `-1.175494351E-38`, `0`, y de `1.175494351E-38` a `3.402823466E+38`. Si se especifica `UNSIGNED`, los valores negativos no se permiten. `M` es la anchura de muestra y `D` es el número de dígitos significativos. `FLOAT` sin argumentos o `FLOAT(`p`)` (donde `p` está en el rango de 0 a 24) es un número de coma flotante con precisión simple.

- `DOUBLE[(`M`,`B`)] [UNSIGNED] [ZEROFILL]`

  Número de coma flotante de tamaño normal (precisión doble). Los valores permitidos son de `-1.7976931348623157E+308` a `-2.2250738585072014E-308`, `0`, y de `2.2250738585072014E-308` a `1.7976931348623157E+308`. Si se especifica `UNSIGNED`, no se permiten valores negativos. `M` es la anchura de muestra y `B` es el número de bits de precisión. `DOUBLE` sin parámetros o `FLOAT(`p`)` (donde `p` está en el rango de 25 a 53) es un número de coma flotante con doble precisión. Un número de coma flotante con precision sencilla tiene una precisión de 7 decimales aproximadamente; un número con coma flotante de doble precisión tiene una precisión aproximada de 15 decimales.

- `DOUBLE PRECISION[(`M`,`D`)] [UNSIGNED] [ZEROFILL]`, `REAL[(`M`,`D`)] [UNSIGNED] [ZEROFILL]`

  Son sinónimos de `DOUBLE`. Excepción: Si el modo del servidor SQL incluye la opción `REAL_AS_FLOAT`, `REAL` es un sinónimo para `FLOAT` en lugar de `DOUBLE`.

- `DECIMAL[(`M`[,`D`])] [UNSIGNED] [ZEROFILL]`

  A partir de MySQL 5.0.3:

  Número de punto fijo exacto y empaquetado. `M` es el número total de dígitos y `D` es el número de decimales. El punto decimal y (para números negativos) el signo '`-`' no se tiene en cuenta en `M`. Si `D` es 0, los valores no tienen punto decimal o parte fraccional. El máximo número de dígitos (`M`) para `DECIMAL` es 64. El máximo número de decimales soportados (`D`) es 30. Si `UNSIGNED` se especifica, no se permiten valores negativos.

  Si se omite `D`, el valor por defecto es 0. Si se omite `M`, el valor por defecto es 10.

  Todos los cálculos básicos (`+, -, *, /`) con columnas `DECIMAL` se hacen con precisión de 64 dígitos decimales.

  Antes de MySQL 5.0.3:

  Número de punto decimal fijo sin empaquetar. Se comporta como una columna `CHAR` ; "sin empaquetar" significa que el número se alacena como una cadena de carácteres, usando un carácter para cada dígito del valor. `M` es el número total de dígitos y `D` es el número de decimales. El punto decimal y (para números negativos) el signo '`-`' no se cuenta en `M`, aunque se reserva espacio para él. Si `D` es 0, los valores no tienen punto decimal ni parte fraccional. El máximo rango de los valores `DECIMAL` es el mismo que para `DOUBLE`, pero el rango real para una columna `DECIMAL` dada puede estar restringido por la elección de `M` y `D`. Si se especifica `UNSIGNED` no se permiten números negativos.

  Si se omite `D`, el valor por defecto es 0. Si se omite `M`, el valor por defecto es 10.

- `DEC[(`M`[,`D`])] [UNSIGNED] [ZEROFILL]`, `NUMERIC[(`M`[,`D`])] [UNSIGNED] [ZEROFILL]`, `FIXED[(`M`[,`D`])] [UNSIGNED] [ZEROFILL]`

  Son sinónimos para `DECIMAL`. El sinónimo `FIXED` está disponible por compatibilidad con otros servidores.

### 11.1.2. Panorámica de tipos de fechas y hora

Un resumen de los tipos de columnas temporales se muestra a continuación. Para información adicional, consulte Sección 11.3, “Tipos de fecha y hora”. Los requerimientos de almacenamiento se dan en Sección 11.5, “Requisitos de almacenamiento según el tipo de columna”.

- `DATE`

  Una fecha. El rango soportado es de `'1000-01-01'` a `'9999-12-31'`. MySQL muestra valores `DATE` en formato `'YYYY-MM-DD'`, pero permite asignar valores a columnas `DATE` usando cadenas de carácteres o números.

- `DATETIME`

  Combinación de fecha y hora. El rango soportado es de `'1000-01-01 00:00:00'` a `'9999-12-31 23:59:59'`. MySQL muestra valores `DATETIME` en formato `'YYYY-MM-DD HH:MM:SS'`, pero permite asignar valores a las columnas `DATETIME` usando cadenas de carácteres o números.

- `TIMESTAMP[(`M`)]`

  Una marca temporal. El rango es de `'1970-01-01 00:00:00'` hasta el año `2037`.

  Una columna `TIMESTAMP` es útil para registrar la fecha y hora de una operación `INSERT` o `UPDATE` . La primera columna `TIMESTAMP` en una tabla se rellena automáticamente con la fecha y hora de la operación más reciente si no le asigna un valor. Puede asignar a cualquier columna `TIMESTAMP` la fecha y hora actual asignándole un valor `NULL` .

  En MySQL 5.0, `TIMESTAMP` se retorna como una cadena de carácteres en el formato `'YYYY-MM-DD HH:MM:SS'` cuya anchura de muestra son 19 carácteres. Si quiere obtener el valor como un número, debe añadir `+0` a la columa timestamp .

- `TIME`

  Una hora. El rango es de `'-838:59:59'` a `'838:59:59'`. MySQL muestra los valores `TIME` en formato `'HH:MM:SS'`, pero permite asingar valores a columnas `TIME` usando números o cadenas de carácteres.

- `YEAR[(2|4)]`

  Un año en formato de dos o cuatro dígitos. El valor por defecto está en formato de cuatro dígitos. En formato de cuatro dígitos, los valores permitidos son de `1901` a `2155`, y `0000`. En formato de dos dígitos, los valores permitidos son de `70` a `69`, representando los años de 1970 a 2069. MySQL muestra los valores `YEAR` en formato `YYYY` pero permite asignar valores a columnas `YEAR` usando cadenas de carácteres o números.

### 11.1.3. Panorámica de tipos de cadenas de caracteres

Un resumen de los tipos de columnas de cadenas de carácteres se muestra a continuación. Para información adicional, consulte Sección 11.4, “Tipos de cadenas de caracteres”. Los requerimientos de almacenamiento de estas columnas se dan en Sección 11.5, “Requisitos de almacenamiento según el tipo de columna”.

En algunos casos, MySQL puede cambiar una columna de cadena de carácteres a un tipo diferente para un comando `CREATE TABLE` o `ALTER TABLE` . Consulte Sección 13.1.5.1, “Cambios tácitos en la especificación de columnas”.

Los tipos de cadenas de carácteres MySQL 5.0 incluyen algunas características que puede que no haya encontrado trabajando con versiones anteriores de MySQL anteriores a la 4.1:

- Las definiciones de columnas para varios tipos de datos de cadenas de carácteres incluyen un atributo `CHARACTER SET` para especificar el conjunto de carácteres y, ocasionalmente, una colación. (`CHARSET` es sinónimo de `CHARACTER SET`.) Estos atributos se aplican a los tipos `CHAR`, `VARCHAR`, `TEXT`, `ENUM`, y `SET`. Por ejemplo:

      CREATE TABLE t
      (
          c1 CHAR(20) CHARACTER SET utf8,
          c2 CHAR(20) CHARACTER SET latin1 COLLATE latin1_bin
      );

  Esta definición de tabla crea una columna llamada `c1` que tiene un conjunto de carácteres `utf8` con la colación por defecto para ese conjunto de carácteres, y una columna llamada `c2` que tiene el conjunto de carácteres `latin1` y la colación binaria para el conjunto de carácteres. La colación binaria no es sensible a mayúsculas.

- MySQL 5.0 interpreta las especificaciones de longitud en las definiciones de las columnas en unidades de carácteres . (En algunas versiones anteriores de MySQL la longitud se interpreta en bytes.)

- Para los tipos `CHAR`, `VARCHAR`, y the `TEXT`, el atributo `BINARY` hace que se asigne a la columna la colación binaria del conjunto de carácteres.

- Las ordenaciones y comparaciones de las columnas de tipo carácter se basan en el conjunto de carácteres asignado a la columna. Para versiones anteriores, la comparación y ordenación se basan en la colación del conjunto de carácteres del servidor. Para columnas `CHAR` y `VARCHAR`, puede declarar que la columna con el atributo `BINARY` realice la ordenación y la comparación usando los códigos de los valores subyacentes en lugar del orden léxico.

Para más información acerca del soporte de conjuntos de carácteres en MySQL 5.0, consulte Capítulo 10, Soporte de conjuntos de caracteres.

- `[NATIONAL] CHAR(`M`) [BINARY | ASCII | UNICODE]`

  Una cadena de carácteres de longitud fija que siempre tiene el número necesario de espacios a la derecha para ajustarla a la longitud especificada al almacenarla. `M` representa la longitud de la columna. El rango de `M` en MySQL 5.0 es de 0 a 255 carácteres.

  Nota: Los espacios a la derecha se borran cuando se obtiene los valores `CHAR` .

  Antes de MySQL 5.0.3, una columna `CHAR` con una longitud especificada mayor que 255 se convierte al tipo `TEXT` más pequeño que pueda tener los valores de la longitud dada. Por ejemplo, `CHAR(500)` se convierte a `TEXT`, y `CHAR(200000)` se convierte en `MEDIUMTEXT`. Esta es una característica de compatibilidad. Sin embargo, esta conversión causa que la columna tenga longitud variable, y también afecta a la eliminación de espacios.

  `CHAR` es una abreviatura para `CHARACTER`. `NATIONAL CHAR` (o su forma equivalente de, `NCHAR`) es la forma estándard de SQL de definir que una columna `CHAR` debe usar el conjunto de carácteres por defecto. Este es el comportamiento por defecto en MySQL.

  El atributo `BINARY` es una abreviatura para especificar la colación binaria del conjunto de carácteres de la columna. La ordenación y comparación se basa en los valores numéricos de los carácteres.

  El tipo de columna `CHAR BYTE` es un alias para `CHAR BINARY`. Esta es una característica de compatibilidad.

  El atributo `ASCII` puede especificarse para `CHAR`. Asigna el conjunto de carácteres `latin1`.

  El atributo `UNICODE` puede especificarse en MySQL 5.0 para `CHAR`. Asigna el conjunto de carácteres `ucs2` .

  MySQL le permite crear un tipo de columna `CHAR(0)`. Esto es útil cuando tiene que cumplir con las especificaciones de alguna aplicación vieja que dependa de la existencia de una columna pero que no usa realmente el valor. Esto es también útil cuando necesita una columna que sólo pueda tener dos valores: Una columna `CHAR(0)` que no esté definido como `NOT NULL` ocupa sólo un bit y sólo puede tener dos valores `NULL` y `''` (la cadena de carácteres vacía).

- `CHAR`

  Es un sinónimo de `CHAR(1)`.

- `[NATIONAL] VARCHAR(`M`) [BINARY]`

  Cadena de carácteres de longitud variable. `M` representa la longitud de columna máxima. En MySQL 5.0, el rango de `M` es de 0 a 255 antes de MySQL 5.0.3, y de 0 a 65,535 en MySQL 5.0.3 y posterior. (La longitud máxima real de un `VARCHAR` en MySQL 5.0 se determina por el tamaño de registro máximo y el conjunto de carácteres que use. La longitud máxima efectiva desde MySQL 5.0.3 es de 65,532 bytes.)

  Nota: Antes de 5.0.3, los espacios finales se eliminaban cuando se almacenaban los valores `VARCHAR`, lo que difiere de le especificación estándard de SQL.

  Previo a MySQL 5.0.3, una columna `VARCHAR` con una longitud especificada mayor a 255 se convertía al valor de tipo `TEXT` más pequeño que podía soportar el valor de la longitu dada. Por ejemplo, `VARCHAR(500)` se convertía a `TEXT`, y `VARCHAR(200000)` se convertía a `MEDIUMTEXT`. Esto era una cuestión de compatibilidad. Sin embargo, esta conversión afectaba la eliminación de espacios finales.

  `VARCHAR` es la abreviación de `CHARACTER VARYING`.

  En MySQL 5.0, el atributo `BINARY` es abreviatura para especificar la colación binaria del conjunto de carácteres de la columna. La ordenación y la comparación se basa en los valores numéricos de los carácteres.

  Desde MySQL 5.0.3, `VARCHAR` se guarda con un prefijo de longitud de uno o dos bytes + datos. La longitud del prefijo es de dos bytes si la columna `VARCHAR` se declara con una longitud mayor a 255.

- `BINARY(`M`)`

  El tipo `BINARY` es similar al tipo `CHAR`, pero almacena cadenas de datos binarios en lugar de cadenas de carácteres no binarias.

- `VARBINARY(`M`)`

  El tipo `VARBINARY` es similar al tipo `VARCHAR`, pero almacena cadenas de carácteres binarias en lugar de cadenas de carácteres no binarias.

- `TINYBLOB`

  Una columna `BLOB` con una longitud máxima de 255 (2^8 - 1) bytes.

- `TINYTEXT`

  Una columna `TEXT` con longitud máxima de 255 (2^8 - 1) carácteres.

- `BLOB[(`M`)]`

  Una columna `BLOB` con longitud máxima de 65,535 (2^16 - 1) bytes.

  Una longitud opcional `M` puede darse para este tipo en MySQL 5.0. Si se hace, MySQL creará las columnas como el tipo `BLOB` de tamaño mínimo para tratar los valores de `M` bytes.

- `TEXT[(`M`)]`

  Una columna `TEXT` con longitud máxima de 65,535 (2^16 - 1) carácteres.

  En MySQL 5.0, se puede dar una longitud opcional `M` . En ese caso MySQL creará las columnas con el tipo `TEXT` de longitud mínima para almacenar los valors de longitud `M` .

- `MEDIUMBLOB`

  Una columna `BLOB` con longitud de 16,777,215 (2^24 - 1) bytes.

- `MEDIUMTEXT`

  Una columna `TEXT` con longitud máxima de 16,777,215 (2^24 - 1) carácteres.

- `LONGBLOB`

  Una columna `BLOB` con longitud máxima de 4,294,967,295 o 4GB (2^32 - 1) bytes. La longitud máxima efectiva (permitida) de las columnas `LONGBLOB` depende del tamaño máximo configurado para los paquetes en el protocolo cliente/servidor y la memoria disponible.

- `LONGTEXT`

  Una columna `TEXT` con longitud máxima de 4,294,967,295 or 4GB (2^32 - 1) carácteres. La longitud máxima efectiva (permitida) de columnas `LONGTEXT` depende del tamaño máximo de paquete configurado en el protocolo cliente/servidor y la memoria disponible.

- `ENUM('`value1`','`value2`',...)`

  Una enumeración. Un objeto de cadena de carácteres que sólo puede tener un valor, elegido de una lista de valores `'`value1`'`, `'`value2`'`, `...`, `NULL` o el valor de error especial `''` . Una columna `ENUM` puede tener un máximo de 65,535 valores distintos. Los valores `ENUM` se representan internamente como enteros.

- `SET('`value1`','`value2`',...)`

  Un conjunto. Un objeto de cadena de carácteres que puede tener cero o más valores que deben pertencer a la lista de valores `'`value1`'`, `'`value2`'`, `...` Una columna `SET` puede tener un máximo de 64 miembros. Los valores `SET` se representan internamente como enteros.

## 11.2. Tipos numéricos

MySQL soporta todos los tipos de datos SQL numéricos estándard. Estos tipos incluyen los tipos numéricos exactos (`INTEGER`, `SMALLINT`, `DECIMAL`, y `NUMERIC`), así como los tipos de datos aproximados (`FLOAT`, `REAL`, y `DOUBLE PRECISION`). La palabra clave `INT` es sinónimo de `INTEGER`, y la palabra clave `DEC` es sinónimo de `DECIMAL`.

En MySQL 5.0.3, un tipo de datos `BIT` está disponible para almacenar valores de un bit. (Antes de 5.0.3, MySQL interpreta `BIT` como `TINYINT(1)`.) En MySQL 5.0.3, `BIT` lo soporta sólo tablas `MyISAM`. MySQL 5.0.5 extiende soporte de `BIT` para `MEMORY`, `InnoDB`, y `BDB`.

Como extensión de los estándards SQL, MySQL soporta los tipos enteros `TINYINT`, `MEDIUMINT`, y `BIGINT`. La siguiente tablas muestra el almacenamiento requerido y el rango para cada uno de los tipos enteros.

Tipo | Bytes | Valor Mínimo | Valor Máximo
|  | (Con signo/Sin signo) | (Con signo/Sin signo)
`TINYINT` | 1 | `-128` | `127`
|  | `0` | `255`
`SMALLINT` | 2 | `-32768` | `32767`
|  | `0` | `65535`
`MEDIUMINT` | 3 | `-8388608` | `8388607`
|  | `0` | `16777215`
`INT` | 4 | `-2147483648` | `2147483647`
|  | `0` | `4294967295`
`BIGINT` | 8 | `-9223372036854775808` | `9223372036854775807`
|  | `0` | `18446744073709551615`

MySQL soporta otra extensión para especificar de forma óptima el ancho a mostrar de un tipo entero en paréntesis después de la palabra clave para el tipo (por ejemplo, `INT(4)`). Esta especificación opcional del ancho de muestra se usa para alinear a la izquierda la muestra de los valores con ancho menor que el ancho especificado para la columna.

El ancho de muestra no restringe el rango de valores que pueden almacenarse en la columna, no el número de dígitos que se muestran para valores con ancho que exceda el especificado para la columna.

Cuando se usa en conjunción con el atributo de extensión opcional `ZEROFILL`, el relleno por defecto de espacios se replaza por ceros. Por ejmplo, para una columna declarada como `INT(5) ZEROFILL`, un valor de `4` se muestra como `00004`. Tenga en cuenta que si almacena valores mayores que el ancho de muestra en una columna entera, puede tener problemas cuando MySQL genera tablas temporales para algunos joins complicados, ya que en estos casos MySQL cree que los datos encajan en el ancho original de la columna.

Todos los tipos enteros pueden tener un atributo opcional (no estándard) `UNSIGNED`. Los valores sin signo pueden usarse cuando quiere permitir sólo números no negativos en una columna y necesita un rango numérico mayor para la columna.

Tipos de coma flotante y de coma fija pueden ser `UNSIGNED`. Como con los tipos enteros, este atributo evita que los valores negativos se almacenen en la columna. Sin embargo, a diferencia de los tipos enteros, el rango superior de los valores de la columna sigue siendo el mismo.

Si especifica `ZEROFILL` para una columna numérica, MySQL añade automáticamente el atributo `UNSIGNED` a la columna.

Para columnas de tipo coma flotante, MySQL usa cuatro bytes para valores de precisión simple y ocho bytes para valores de doble precisión.

El tipo `FLOAT` se usa para representar tipos numéricos aproximados. El estándard SQL permite una especificación opcional de la precisión (pero no del rango del exponente) en bits a continación de la palabra clave `FLOAT` entre paréntesis. La implementación de MySQL soporta esta especificación opcional de precisión, pero el valor de precisión se usa sólo para determinar el tamaño de almacenamiento. Una precisión de 0 a 23 resulta en una columna de precisión simple de cuatro bytes de tamaño `FLOAT` . Una precisión de 24 a 53 resulta en una columna de doble precisión de ocho bytes de tamaño `DOUBLE` .

Cuando se especifica la palaba clave `FLOAT` para tipos de columnas sin especificar la precisión, MySQSL usa cuatro bytes para almacenar los valors.MySQL también soporta una sintaxis alternativa con dos números entre paréntesis a continación de la palabra clave `FLOAT` . El primer número representa el ancho a mostrar y el segundo número especifica el número de dígitos a almacenar a continuación del punto decimal ( como con `DECIMAL` y `NUMERIC`). Cuando se pide a MySQL que almacene un número para tales columnas con más dígitos decimales a continuación del punto decimal del especificado para la columna, el valor se redondea para elminar los dígitos extras cuando se almacena el valor.

En SQL estándard, los tipos `REAL` y `DOUBLE PRECISION` no aceptan especificaciones de precisión. MySQL soporta una sintaxis alternativa con dos números dados entre paréntesis a continuación del nombre del tipo. El primer número representa el ancho a mostrar y el segundo número especifica el número de dígitos a almacenar y mostrar a continuación del punto decimal. Como una extensión al estándard SQL, MySQL reconoce `DOUBLE` como sinónimo del tipo `DOUBLE PRECISION` . En contraste con el requerimiento estándard que la precisión para `REAL` sea menor que la usada para `DOUBLE PRECISION`, MySQL implementa ambas como valores de punto flotante de doble precisión con tamaño de ocho bytes (a no ser que el modo SQL del servidor incluya la opción `REAL_AS_FLOAT` ).

Para portabilidad máxima, el código que requiera almacenamiento de datos numéricos aproximados debe usar `FLOAT` o `DOUBLE PRECISION` sin especificar la precisión ni el número de dígitos decimales.

Los tipos `DECIMAL` y `NUMERIC` se implementan como el mismo tipo en MySQL. Se usan para guardar valores para los que es importante preservar una precisión exacta, por ejemplo con datos monetarios. Cuando se declara una columna de alguno de estos tipos, la precisión y la escala puede especificarse (y usualmente se hace), por ejemplo:

    salary DECIMAL(5,2)

En este ejemplo, `5` es la precisión y `2` es la escala. La precisión representa el número de dígitos decimales significativos que se almacenan para los valores, y la escala representa el número de dígitos que pueden almacenarse a continuación del punto decimal.

Desde MySQL 5.0.3, los valores `DECIMAL` y `NUMERIC` se almacenan en formato binario. Antes de 5.0.3, MySQL almacena los valores `DECIMAL` y `NUMERIC` como cadenas de carácteres, en lugar de binario. .Un carácter se usa para cada dígito del valor, el punto decimal (si la escala es mayor que 0), y el signo '`-`' (para números negativos). Si la escala es 0, los valores `DECIMAL` y `NUMERIC` no contienen punto decimal o parte fraccional.

SQL estándard requiere que la columna `salary` sea capaz de almacenar cualquier valor con cinco dígitos y dos decimales. En este caso, por lo tanto, el rango de valores que puede almacenarse en la columna `salary` es desde `-999.99` a `999.99`. MySQL fuerza este límite desde MySQL 5.0.3. Antes de 5.0.3, MySQL 5.0 variaba este límite de forma que, en el límite positivo del rango, la columna podía almacenar números hasta `9999.99`. (Para números positivos, MySQL 5.0.2 y anteriores usaba el byte reservado para el signo para extender el límite superior del rango.)

En SQL estándard, la sintaxis `DECIMAL(`M`)` es equivalente a `DECIMAL(`M`,0)`. Similarmente, la sintaxis `DECIMAL` es equivalente a `DECIMAL(`M`,0)`, donde la implementación se permite para decidir el valor de `M`. Ambas formas de los tipos `DECIMAL` y `NUMERIC` se soportan en MySQL 5.0. El valor por defecto de `M` es 10.

El máximo rango de los valores `DECIMAL` y `NUMERIC` es el mismo para `DOUBLE`, pero el rango real para un valor dado en una columna `DECIMAL` o `NUMERIC` puede restringirse con la precisión o escala para una columna dada. Cuando en tal columna se asigna un valor con más dígitos siguiendo el punto decimal de los permitidos por la escala específica, el valor se convierte a tal escala. (El comportamiento preciso depende del sistema operativo, pero generalmente el efecto es que se trunca al número de dígitos permitidos.)

Desde MySQL 5.0.3, el tipo de datos `BIT` puede usarse para guardar valores de un bit. Un tipo `BIT(`M`)` permite el almacenamiento de valores de `M`-bit . `M` tiene un rango de 1 a 64.

Para especificar valores bit, puede usar la notación `b'`value`'` . `value` es un valor binario escrito usando ceros y unos. Por ejemplo, `b'111'` y `b'100000000'` representan 7 y 128, respectivamente. Consulte Sección 9.1.5, “Valores de bits”.

Si asigna un valor a una columna `BIT(`M`)` con menos de `M` bits , el valor se alinea a la izquierda con ceros. Por ejemplo, asignar un valor `b'101'` a una columna `BIT(6)` es, en efecto, lo mismo que asignar `b'000101'`.

Cuando se intenta almacenar un valor en una columna numérica que está fuera del rango permitido por la columna, MySQL corta el valor en el final del rango permitido y guarda el valor resultante.

Por ejemplo, el ranto de una coluna `INT` es de `-2147483648` a `2147483647`. Si intenta insertar `-9999999999` en una columna `INT`, MySQL reemplaza el valor con el mínimo valor del rango y almacena `-2147483648` en su lugar. De forma similar, si trata de insertar `9999999999`, MySQL reemplaza el valor con el valor máximo del rango y almacena `2147483647` en su lugar.

Si la columna `INT` es `UNSIGNED`, el tamaño del rango de la columna es el mismo, pero los límites cambian a `0` y `4294967295`. Si intenta almacenar `-9999999999` y `9999999999`, los valores almacenados en la columna son `0` y `4294967296`.

Cuando se asigna un valor fuera de rango especificado (o por defecto) a una columna de coma flotante o fija, MySQL almacena el valor representado por el valor correspondiente al límite de rango correspondiente.

Las conversiones debidas a valores fuera de rango se reportan como advertencias para los comandos `ALTER TABLE`, `LOAD DATA INFILE`, `UPDATE`, y `INSERT` de múltiples registros.

## 11.3. Tipos de fecha y hora

Los tipos de fecha y hora para representar valores temporales son `DATETIME`, `DATE`, `TIMESTAMP`, `TIME`, y `YEAR`. Cada tipo temporal tiene un rango de valores legales, así como un valor “zero” que se usa cuando se especifica un valor ilegal que MySQL no puede representar. El tipo `TIMESTAMP` tiene un comportamiento automático especial, descrito posteriormente.

Desde MySQL 5.0.2, MySQL da advertencias/errores si trata de insertar una fecha ilegal. Puede hacer que MySQL acepte ciertas fechas, tales como `'1999-11-31'`, usando el modo SQL `ALLOW_INVALID_DATES` . (Antes de 5.0.2, este modo era el comportamiento por defecto de MySQL). Esto es útil cuando quiere almacenar el valor “posiblemente erróneo” que el usuario especifica (por ejemplo, en un formulario web) en la base de datos para un posterior procesamiento. En este modo, MySQL sólo verifica que el mes esté en el rango de 0 a 12 y que el día esté en el rango de 0 a 31. Estos rangos incluyen cero ya que MySQL permite almacenar fechas cuando el día o el mes son cero en columnas `DATE` o `DATETIME` . Esto es muy útil para aplicaciones que necesiten almacenar una fecha de nacimiento para la que no sepa la fecha exacta. En este caso, símplemente almacena la fecha como `'1999-00-00'` o `'1999-01-00'`. Si almacena valores similares a estos, no debe esperar obtener resultados correctos para funciones tales como `DATE_SUB()` or `DATE_ADD` que necesitan fechas completas. (Si no quiere permitir ceros en las fechas, puede usar el modo SQL `NO_ZERO_IN_DATE` ).

MySQL permite almacenar `'0000-00-00'` como “fecha de pruebas” (si no está usando el modo SQL `NO_ZERO_DATE` ). Esto es mejor que usar (y usa menos espacio de datos e índice) que usar valores `NULL` .

Modificando la variable de sistema `sql_mode` al modo apropiado, puede especificar exactamente qué tipos de datos quiere soportar con MySQL. Consulte Sección 5.3.2, “El modo SQL del servidor”.

Aquí hay algunas consideraciones generales a tener en cuenta cuando se trabaja con tipos de fecha y hora:

- MySQL muestra los valores para una fecha o hora en un formato de salida estándard, pero trata de intepretar una variedad de formatos para los valores de entrada que se proporcionan (por ejemplo, cuando especifica un valor para asignar o comparar con un tipo fecha o hora). Sólo los formatos descritos en las siguientes secciones son soportados. Se espera la entrada de valores legales. Si se usan otros formatos pueden ocurrir resultados imprevisibles.

- Las fechas con años de dos dígitos son ambituas, ya que no se sabe el siglo. MySQL interpreta los años de dos dígitos usando las siguientes reglas:

  - Los años del rango `70-99` se convierten en `1970-1999`.

  - Los años del rango `00-69` se convierten en `2000-2069`.

- Aunque MySQL trata de interpretar los valores con varios formatos, las fechas siempre deben darse en el orden año-mes-día (por ejemplo, `'98-09-04'`), en lugar del formato mes-día-año o día-mes-año usados comunmente (por ejemplo, `'09-04-98'`, `'04-09-98'`).

- MySQL convierte automáticamente una fecha o hora a un número si el valor se usa en un contexto numérico y viceversa.

- Cuando MySQL encuentra un valor para fecha o hora que está fuera de rango o es ilegal para el tipo (como se describe al inicio de la sección), lo convierte al valor “cero” para ese tipo. La excepción es que los valores fuera de rango del tipo `TIME` se reemplazan por el valor límite de rango apropiado para el tipo `TIME` .

  La siguiente tabla muestra el formato del valor “cero” para cada tipo. Tenga en cuenta que el uso de estos valores produce mensajes de advertencia si el modo SQL `NO_ZERO_DATE` está activado.

  Tipo de Columna | “Cero” Valor
  `DATETIME` | `'0000-00-00 00:00:00'`
  `DATE` | `'0000-00-00'`
  `TIMESTAMP` | `00000000000000`
  `TIME` | `'00:00:00'`
  `YEAR` | `0000`

- Los valores “cero” son especiales, pero puede almacenarlos o referirse a ellos explícitamente usando los valores mostrados en la tabla. También puede hacerlo usando los valores `'0'` o `0`, que son más sencillos de escribir.

- Los valores de fecha o hora “cero” usados a través de MyODBC se convierten automáticamente a `NULL` en MyODBC 2.50.12 y posterior, ya que ODBC no puede tratar estos valores.

### 11.3.1. Los tipos de datos `DATETIME`, `DATE` y `TIMESTAMP`

Los tipos `DATETIME`, `DATE`, and `TIMESTAMP` están relacionados. Esta sección describe sus características, en que se parecen y en que difieren.

El tipo `DATETIME` se usa cuando necesita valores que contienen información de fecha y hora. MySQL recibe y muestra los valores `DATETIME` en formato `'YYYY-MM-DD HH:MM:SS'` . El rango soportado es de `'1000-01-01 00:00:00'` a `'9999-12-31 23:59:59'`. (“Soportado” significa que aunque valores anteriores pueden funcionar, no hay garantías)

El tipo `DATE` se usa cuando necesita sólo un valor de fecha, sin una parte de hora. MySQL recibe y muestra los valores `DATE` en formato `'YYYY-MM-DD'` . El rango soportado es de `'1000-01-01'` a `'9999-12-31'`.

El tipo `TIMESTAMP` tiene varias propiedades, en función de la versión de MySQSL y el modo SQL que esté ejecutando el servidor. Estas propiedades se describen posteriormente en esta sección.

Puede especificar valores `DATETIME`, `DATE`, y `TIMESTAMP` usando cualquier de los siguientes formatos:

- Como cadena de carácteres en formato `'YYYY-MM-DD HH:MM:SS'` o `'YY-MM-DD HH:MM:SS'` . Una sintaxis “relajada” se permite: Cualquier carácter de puntuación puede usarse como delimitador entre partes de fecha o de hora. Por ejemplo, `'98-12-31 11:30:45'`, `'98.12.31 11+30+45'`, `'98/12/31 11*30*45'`, y `'98@12@31 11^30^45'` son equivalentes.

- Como cadena de carácteres en formato `'YYYY-MM-DD'` or `'YY-MM-DD'` . Se permite una sintaxis “relajada” . Por ejemplo, `'98-12-31'`, `'98.12.31'`, `'98/12/31'`, y `'98@12@31'` son equivalentes.

- Como cadena de carácteres sin delimitadores en formato `'YYYYMMDDHHMMSS'` o `'YYMMDDHHMMSS'`, mientras que la cadena de carácteres tenga sentido como fecha. Por ejemmplo, `'19970523091528'` y `'970523091528'` se interpretan como `'1997-05-23 09:15:28'`, pero `'971122129015'` es ilegal (tiene una parte de minutos sin sentido) y se convierte en `'0000-00-00 00:00:00'`.

- Como cadena de carácteres sin delimitadores en formato `'YYYYMMDD'` o `'YYMMDD'` , mientras que el cadena de carácteres tenga sentido como fecha. Por ejemplo, `'19970523'` y `'970523'` se interpretan como `'1997-05-23'`, pero `'971332'` es ilegal (tiene una parte de mes y día sin sentido) y se convierte en `'0000-00-00'`.

- Como número en formato `YYYYMMDDHHMMSS` o `YYMMDDHHMMSS`, mientras que el número tenga sentido como fecha. Por ejemplo, `19830905132800` y `830905132800` se interpretan como `'1983-09-05 13:28:00'`.

- Como número en formato `YYYYMMDD` o `YYMMDD`, mientras que el número tenga sentido como fecha. Por ejemplo, `19830905` y `830905` se interpretan como `'1983-09-05'`.

- Como resultado de una función que retorne un valor acceptable en un contexto `DATETIME`, `DATE`, o `TIMESTAMP` , como `NOW()` o `CURRENT_DATE`.

Los valores ilegales de `DATETIME`, `DATE`, o `TIMESTAMP` se convierten al valor “cero” del tipo apropiado (`'0000-00-00 00:00:00'`, `'0000-00-00'`, o `00000000000000`).

Para valores especificados como cadenas de carácteres que incluyan partes de fecha delimitadas, no es necesario especificar dos dígitos para valores de mes o día menores que `10`. `'1979-6-9'` es lo mismo que `'1979-06-09'`. Similarmente, para valores especificados como cadenas de carácteres que incluyan delimitadores para la parte de hora, no es necesario especificar dos dígitos para horas, minutos o segundos menores que `10`. `'1979-10-30 1:2:3'` es lo mismo que `'1979-10-30 01:02:03'`.

Los valores especificados como números deben tener una longitud de 6, 8, 12, o 14 dígitos. Si un número tiene una longitud de 8 o 14 dígitos, se asume que está en formato `YYYYMMDD` o `YYYYMMDDHHMMSS` y que el año lo dan los primeros 4 dígitos. Si el número tiene 6 o 12 dígitos de longitud, se asume que está en formato `YYMMDD` o `YYMMDDHHMMSS` y que el año lo dan los primeros 2 dígitos. Los números que no tengan estas longitudes se interpretan como si tuvieran ceros a la izquierda y fueran de la longitud permitida más cercana.

Los valores especificados como cadenas de carácteres no delimitadas se interpretan usando su longitud. Si la cadena de carácteres tiene longitud 8 o 14, el año se asume como dado por los primeros 4 carácteres. En el resto de caso, se supone que el año lo dan los primeros 2 carácteres. La cadena de carácteres se interpreta de izquierda a derecha para encontrar el año, mes, día, hora, minuto y segundo, para tantas partes como representa la cadena de carácteres. Esto significa que no debe usar cadenas de carácteres con menos de 6 carácteres. Por ejemplo, si especifica `'9903'`, pensando que representa Marzo, 1999, MySQL inserta un valor “cero” en la tabla. Esto es porque el valor de año y mes son `99` y `03`, pero la parte de día no se encuentra, así que el valor no es una fecha legal. Sin embargo, puede especificar explícitamente un valor de cero para representar partes de día y mes. Por ejemplo, puede usar `'990300'` para insertar el valor `'1999-03-00'`.

Puede asignar valores de un tipo a un objeto de un tipo diferente hasta un límite. Sin embargo, hay algunas alteraciones del valor o pérdidas de información:

- Si asigna un valor `DATE` a un objeto `DATETIME` o `TIMESTAMP`, la parte de hora del valor resultante se cambia a `'00:00:00'` ya que el valor `DATE` no contiene información temporal.

- Si asigna un valor `DATETIME` o `TIMESTAMP` a un objeto `DATE`, la parte temporal del valor resultante se borra porque el tipo `DATE` no tiene información temporal.

- Tenga en cuenta que aunque `DATETIME`, `DATE`, y `TIMESTAMP` pueden especificarse usando el mismo conjunto de formatos, los tipos no tienen el mismo rango de valores. Por ejemplo, `TIMESTAMP` no pueden ser anteriores a `1970` o posteriores a `2037`. Esto significa que una fecha como `'1968-01-01'`, que sería legal como `DATETIME` o `DATE` no es un valor válido `TIMESTAMP` y se convierte a `0` si se asigna a un objeto de este tipo.

Tenga en cuenta ciertas cosas al especificar valores temporales:

- El formato relajado para valores especificados como cadenas de carácteres puede ser problemático. Por ejemplo, un valor como `'10:11:12'` puede parecer una hora por el delimitador '`:`' , pero si se usa en un contexto de fecha se interpreta como `'2010-11-12'`. El valor `'10:45:15'` se convierte a `'0000-00-00'` ya que `'45'` no es un mes legal.

- El servidor MySQL realiza sólo chequeo básico de la validez de las fechas: Los rangos para año, mes y día son de 1000 a 9999, 00 a 12, y 00 a 31, respectivamente. Cualquier fecha que contenga partes fuera de estos rangos está sujeta a conversión a `'0000-00-00'`. Tenga en cuenta que esto permite almacenar fechas inválidas como `'2002-04-31'`. Para asegurar que una fecha es válida, haga una comprobación en su aplicación.

- Fechas con valores de año de dos dígitos son ambíguas porque no se conoce el siglo. MySQL interpreta los años de dos dígitos usando las siguientes reglas:

  - Los valores de años en el rango `00-69` se convierten a `2000-2069`.

  - Los valores de años en el rango `70-99` se convierten a `1970-1999`.

#### 11.3.1.1. Propiedades de `TIMESTAMP` desde MySQL 4.1

Nota: En antiguas versiones de MySQL (antes de la 4.1), las propiedades de las columnas `TIMESTAMP` difieren significativamente en muchas cosas de lo que se describe en esta sección. Si necesita convertir datos `TIMESTAMP` antiguos para que funcionen con MySQL 5.0, asegúrese de consultar Manual de referencia de MySQL 4.1 para más detalles.

En MySQL 5.0, `TIMESTAMP` se muestran en el mismo formato que las columnas `DATETIME`. En otras palabras, el ancho de muestra se limita a 19 carácteres, y el formato es `YYYY-MM-DD HH:MM:SS`.

El servidor MySQL puede ejecutarse en modo `MAXDB` . Cuando el servidor corre en este modo, `TIMESTAMP` es idéntico a `DATETIME`. Esto es, si el servidor está ejecutándose en modo `MAXDB` cuando se crea una tabla, las columnas `TIMESTAMP` se crean como columnas `DATETIME` . Como resultado, tales columnas usan el formato de salida de `DATETIME`, tienen el mismo rango de valores, y no hay inicialización automática o actualización de la fecha y hora actual.

Para activar el modo `MAXDB`, cambie el modo SQL del servido a`MAXDB` cuando arranque usando la opción `--sql-mode=MAXDB` o cambiando en tiempo de ejecución la variable global `sql_mode`:

    mysql> SET GLOBAL sql_mode=MAXDB;

Un cliente puede hacer que el servidor se ejecute en modo `MAXDB` para sus propias conexiones como se muestra:

    mysql> SET SESSION sql_mode=MAXDB;

Desde MySQL 5.0.2, MySQL no acepta valores timestamp que incluyan cero en la columna de día o hora o valores que no sean fechas válidas. La única excepción es el valor especial `'0000-00-00 00:00:00'`.

En MYSQL 5.0, tiene considerable flexibilidad para determinar cuando se actualiza e inicializa automáticamente `TIMESTAMP` y qué columna debe tener ese comportamiento:

- Puede asignar la fecha y hora actual como el valor por defecto y el valor de actualización automático, como se hacía anteriormente. Pero es posible tener sólo uno u otro comportamiento automático, o ninguno de ellos. (No es posible tener un comportamiento para una columna y el otro para la otra columna.)

- Puede especificar qué columna `TIMESTAMP` inicializar o actualizar con la fecha y hora actuales. Ya no hace falta que sea la primera columna `TIMESTAMP` .

Tenga en cuenta que la información en la siguiente discusión se aplica a columnas `TIMESTAMP` sólo para tablas no creadas con el modo `MAXDB` activado. (Como se menciona anteriormente, el modo `MAXDB` hace que las columnas se creen como columnas `DATETIME` .) Las reglas que gobiernan la inicialización y actualización de columnas `TIMESTAMP` en MySQL 5.0 son las siguientes:

- Si un valor `DEFAULT` se especifica para la primera columna `TIMESTAMP` en una tabla, no se ignora. El valor por defecto puede ser `CURRENT_TIMESTAMP` o una fecha y hora constante.

- `DEFAULT NULL` es lo mismo que `DEFAULT CURRENT_TIMESTAMP` para la primera columna `TIMESTAMP`. Para cualquier otra columna `TIMESTAMP`, `DEFAULT NULL` se trata como `DEFAULT 0`.

- Cualquier columna `TIMESTAMP` individual en una tabla puede actualizarse e inicializarse con la fecha y hora actual automáticamente.

- En un comando `CREATE TABLE`, la primera columna `TIMESTAMP` puede declararse de cualquiera de las siguientes formas:

  - Con las cláusulas `DEFAULT CURRENT_TIMESTAMP` y `ON UPDATE CURRENT_TIMESTAMP`, la columna tiene la fecha y hora actual como su valor por defecto, y se actualiza automáticamente.

  - Sin las cláusulas `DEFAULT` ni `ON UPDATE`, es lo mismo que `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`.

  - Con la cláusula `DEFAULT CURRENT_TIMESTAMP` y sin `ON UPDATE`, la columna tiene la fecha y hora actual como valor por defecto pero no se actualiza automáticamente.

  - Sin cláusula `DEFAULT` y con cláusula `ON UPDATE CURRENT_TIMESTAMP`, la columna tiene por defecto 0 y se actualiza automáticamente.

  - Con un valor constante `DEFAULT`, la columna tiene el valor dado por defecto. Si la columna tiene una cláusula `ON UPDATE CURRENT_TIMESTAMP` se actualiza automáticamente, de otro modo no lo hace.

  En otras palabras, puede usar la fecha y hora actuales para el valor inicial y el valor de actualización automática, o uno de ellos o ninguno. (Por ejemplo, puede especificar `ON UPDATE` para activar actualización automática sin tener la columna inicializada .)

- Cualquiera de `CURRENT_TIMESTAMP`, `CURRENT_TIMESTAMP()`, o `NOW()` puede usarse en las cláusulas `DEFAULT` y `ON UPDATE` . Todas tienen el mismo efecto.

  El orden de los dos atributos no importa. Si se especifican `DEFAULT` y `ON UPDATE` para una columna `TIMESTAMP`, cualquiera puede preceder al otro.

  Ejemplo. Estos comandos son equivalentes:

      CREATE TABLE t (ts TIMESTAMP);
      CREATE TABLE t (ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP
      ON UPDATE CURRENT_TIMESTAMP);
      CREATE TABLE t (ts TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
      DEFAULT CURRENT_TIMESTAMP);

- Para especificar el valor por defecto o actualización automática para una columna `TIMESTAMP` distinta a la primera, debe suprimir la actualización e inicialización automática de la primera columna `TIMESTAMP` asignándole explícitamente una valor constante `DEFAULT` (por ejemplo, `DEFAULT 0` o `DEFAULT '2003-01-01 00:00:00'`). Luego, para la otra columna `TIMESTAMP`, las reglas son las mismas que para la misma columna `TIMESTAMP`, excepto que no puede omitir ambas cláusulas `DEFAULT` y `ON UPDATE` . Si lo hace, no habrá inicialización ni actualización automática.

  Ejemplo, estos comandos son equivalentes:

      CREATE TABLE t (
          ts1 TIMESTAMP DEFAULT 0,
          ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                        ON UPDATE CURRENT_TIMESTAMP);
      CREATE TABLE t (
          ts1 TIMESTAMP DEFAULT 0,
          ts2 TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
                        DEFAULT CURRENT_TIMESTAMP);

En MySQL 5.0, puede asignar la zona horaria actual para cada conexión, como se describe en Sección 5.9.8, “Soporte de zonas horarias en el servidor MySQL”. Los valores `TIMESTAMP` se almacenan en UTC, convirtiéndose desde la zona horaria actual para almacenamiento, y volviéndose a convertir a la zona horaria actual al mostrarse. Mientras la zona horaria permanezca constante, puede obtener el mismo valor que hay almacenado. Si almacena un valor `TIMESTAMP`, cambia la zona horaria y luego rescata el valor, es diferente que el valor almacenado. Esto ocurre porque no se usa la misma zona horaria para la conversión en ambas direcciones. La zona horaria actual está disponible en la variable de sistema `time_zone`.

Puede incluir el atributo `NULL` en la definición de una columna `TIMESTAMP` para permitir que la columna contenga valores `NULL` . Por ejemplo:

    CREATE TABLE t
    (
      ts1 TIMESTAMP NULL DEFAULT NULL,
      ts2 TIMESTAMP NULL DEFAULT 0,
      ts3 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP
    );

Si el atributo `NULL` no se especifica, asignar el valor `NULL` a la columna resulta en que se almacena la hora y fecha actuales. Tenga en cuenta que una columna `TIMESTAMP` que permita valores `NULL` no no almacenará la fecha y hora actual a no ser que su valor por defecto se defina como `CURRENT_TIMESTAMP`, o `NOW()` o `CURRENT_TIMESTAMP` se inserte en la columna. En otras palabras, una columna `TIMESTAMP` definida como `NULL` se actualizará automáticamente sólo si se crea usando una definición como las siguientes:

    CREATE TABLE t (ts NULL DEFAULT CURRENT_TIMESTAMP);

De otro modo - esto es, si la columna `TIMESTAMP` se define usando `NULL` pero no usando `DEFAULT TIMESTAMP`, como se muestra aquí...

    CREATE TABLE t1 (ts NULL DEFAULT NULL);
    CREATE TABLE t2 (ts NULL DEFAULT '0000-00-00 00:00:00');

...entonces debe insertar el valor explícitamente correspondiente a la fecha y hora actuales. Por ejemplo:

    INSERT INTO t1 VALUES (NOW());
    INSERT INTO t2 VALUES (CURRENT_TIMESTAMP);

### 11.3.2. El tipo `TIME`

MySQL devuelve y muestra los valores `TIME` en formato `'HH:MM:SS'` (o formato `'HHH:MM:SS'` para valores de hora grandes). `TIME` tiene rango de `'-838:59:59'` a `'838:59:59'`. La razón por la que la parte de hora puede ser tan grande es que el tipo `TIME` puede usarse no sólo para representar una hora del día (que debe ser menor a 24 horas), pero también el tiempo transcurrido o un intervalo de tiempo entre dos eventos (que puede ser mucho mayor a 24 horas, o incluso negativo).

Puede especificar valores `TIME` en una variedad de formatos:

- Como cadena de carácteres en formato `'D HH:MM:SS.fracción'`. También puede usar una de las siguientes sintaxis “relajadas” : `'HH:MM:SS.fracción'`, `'HH:MM:SS'`, `'HH:MM'`, `'D HH:MM:SS'`, `'D HH:MM'`, `'D HH'`, o `'SS'`. Aquí `D` representa días y puede tener un valor de 0 a 34. Tenga en cuenta que MySQL no almacena la fracción (todavía).

- Como cadena de carácteres sin delimitadores en formato `'HHMMSS'`, mientras que tenga sentido como hora. Por ejemplo, `'101112'` se entiende como `'10:11:12'`, pero `'109712'` es ilegal (no tiene una parte de minutos correcta) y pasa a ser `'00:00:00'`.

- Como número en formato `HHMMSS`, mientras tenga sentido como hora. Por ejemplo, `101112` se entiende como `'10:11:12'`. Los siguientes formatos alternativos también se entienden: `SS`, `MMSS`, `HHMMSS`, `HHMMSS.fracción`. Tenga en cuenta que MySQL no almacena la fracción (todavía).

- Como resultado de una función que retorna un valor que es aceptable en un contexto `TIME`, tal como `CURRENT_TIME`.

Para valores `TIME` especificados como cadenas de carácteres que incluyan un delimitador de las partes de hora, no es necesario especificar dos dígitos para horas, minutos o segundos que tengan un valor inferior a `10`. `'8:3:2'` es lo mismo que `'08:03:02'`.

Tenga cuidado con asignar valores abreviados a una columna `TIME` . Sin comas, MySQL interpreta los valores asumiendo que los dos dígitos más a la derecha representan segundos. (MySQL interpreta valores `TIME` como tiempo transcurrido en lugar de horas del día.) Por ejemplo puede pensar que `'1112'` y `1112` significan `'11:12:00'` (12 minutos tras las 11 en punto), pero MySQL los interpreta como `'00:11:12'` (11 minutos, 12 segundos). Similarmente, `'12'` y `12` se interpretan como `'00:00:12'`. Los valores `TIME` con comas, por contrario, se tratan siempre como hora del día. Esto es, `'11:12'` significa `'11:12:00'`, no `'00:11:12'`.

Los valores fuera del rango de `TIME` pero que son legales se cambian por el valor límite de rango más cercano. Por ejemplo `'-850:00:00'` y `'850:00:00'` se convierten en `'-838:59:59'` y `'838:59:59'`.

Valores `TIME` ilegales se convierten a `'00:00:00'`. Tenga en cuenta que como `'00:00:00'` es un valor `TIME` legal, no hay forma de decir si un valor `'00:00:00'` almacenado en una tabla, se insertó como `'00:00:00'` o como valor ilegal.

### 11.3.3. El tipo de datos `YEAR`

El tipo `YEAR` es un tipo de un byte usado para representar años.

MySQL devuelve y muestra los valores `YEAR` en formato `YYYY` . El rango es de `1901` a `2155`.

Puede especificar los valores `YEAR` en una variedad de formatos:

- Como cadena de carácteres de cuatro dígitos en el rango de `'1901'` a `'2155'`.

- Como número de cuatro dígitos en el rango de `1901` a `2155`.

- Como cadena de carácteres de dos dígitos en el rango de `'00'` a `'99'`. Los valores en los rangos de `'00'` a `'69'` y de `'70'` a `'99'` se convierten en valores `YEAR` en el rango de `2000` a `2069` y de `1970` a `1999`.

- Como número de dos dígitos en el rango de `1` a `99`. Los valores en los rangos de `1` a `69` y de `70` a `99` se convierten en valores `YEAR` en los rangos de `2001` a `2069` y de `1970` a `1999`. Tenga en cuenta que el rango para números de dos dígitos es ligeramente distinto del rango para cadenas de carácteres de dos dígitos, ya que no especifica el cero directamente como número y tiene que ser interpretado como `2000`. Debe especificarlo como cadena de carácteres `'0'` o `'00'` o se interpreta como `0000`.

- Como resultado de una función que retorne un valor que se acepte en un contexto `YEAR`, como `NOW()`.

Valores `YEAR` ilegales se convierten en `0000`.

### 11.3.4. Efecto 2000 (Y2K) y tipos de datos

MySQL no tiene problemas con el año 2000 (Y2K) (consulte Sección 1.4.5, “Conformidad con el efecto 2000”), pero los valores de entrada presentados a MySQL pueden tenerlos. Cualquier entrada con valores de años de dos dígitos es ambigua, ya que no se conoce el siglo. Tales valores deben interpretarse en forma de cuatro dígitos, ya que MySQL los almacena internamente usando cuatro dígitos.

Para tipos `DATETIME`, `DATE`, `TIMESTAMP`, y `YEAR`, MySQL interpreta las fechas con valores de año ambíguos usando las siguientes reglas:

- Años en el rango `00-69` se convierten a `2000-2069`.

- Años en el rango `70-99` se convierten a `1970-1999`.

Recuerde que estas reglas proporcionan sólo suposiciones razonables sobre lo que significan los valores. Si el heurístico usado por MySQL no produce los valores correctos, debe proporcionar entrada no ambígua con años de cuatro dígitos.

`ORDER BY` ordena valores `TIMESTAMP` o `YEAR` correctamente que tengan años de dos digitos.

Algunas funciones como `MIN()` y `MAX()` convierten un `TIMESTAMP` o `YEAR` a número. Esto significa que un valor con un año de dos dígitos no funciona correctamente con estas funciones. En este caso la solución es convertir `TIMESTAMP` o `YEAR` a formato de cuatro dígitos o usar algo como `MIN(DATE_ADD(timestamp,INTERVAL 0 DAYS))`.

## 11.4. Tipos de cadenas de caracteres

Los tipos de cadenas de carácteres son `CHAR`, `VARCHAR`, `BINARY`, `VARBINARY`, `BLOB`, `TEXT`, `ENUM`, y `SET`. Esta sección describe cómo funcionan estos tipos y cómo usarlo en sus consultas.

### 11.4.1. Los tipos `CHAR` y `VARCHAR`

Los tipos `CHAR` y `VARCHAR` son similares, pero difieren en cómo se almacenan y recuperan. Desde MySQL 5.0.3, también difieren en la longitud máxima y en cómo se tratan los espacios finales.

Los tipos `CHAR` y `VARCHAR` se declaran con una longitud que indica el máximo número de carácteres que quiere almacenar. Por ejemplo, `CHAR(30)` puede almacenar hasta 30 carácteres.

La longitud de una columna `CHAR` se fija a la longitud que se declara al crear la tabla. La longitud puede ser cualquier valor de 0 a 255. Cuando los valores `CHAR` se almacenan, se añaden espacios a la derecha hasta las longitud específica. Cuando los valores `CHAR` se recuperan, estos espacios se borran.

Los valores en columnas `VARCHAR` son cadenas de carácteres de longitud variable. En MySQL 5.0, la longitud puede especficarse de 0 a 255 antes de MySQL 5.0.3, y de 0 a 65,535 en 5.0.3 y versiones posteriores. (La máxima longitud efectiva de un `VARCHAR` en MySQL 5.0 se determina por el tamaño de registro máximo y el conjunto de carácteres usados. La longitud máxima total es de 65,532 bytes.)

En contraste con `CHAR`, `VARCHAR` almacena los valores usando sólo los carácteres necesarios, más un byte adicional para la longitud (dos bytes para columnas que se declaran con una longitud superior a 255).

Los valores `VARCHAR` no se cortan al almacenarse. El tratamiento de espacios al final depende de la versión. Desde MySQL 5.0.3, los espacios finales se almacenan con el valor y se retornan, según el estándard SQL. Antes de MySQL 5.0.3, los espacios finales se eliminan de los valores cuando se almacenan en una columna `VARCHAR`, esto significa que los espacios también están ausentes de los valores retornados.

Durante el almacenamiento y la recuperación de valores no hace ninguna conversión de mayúsculas y minúsculas.

Si asigna un valor a una columna `CHAR` o `VARCHAR` que exceda la longitud máxima de la columna, el valor se trunca. Si los carácteres truncados no son espacios, se genera una advertencia. Puede hacer que aparezca un error en lugar de una advertencia usando modo SQL estricto. Consulte Sección 5.3.2, “El modo SQL del servidor”.

Antes de MySQL 5.0.3, si necesita un tipo de datos para el que no se borren los espacios finales, considere usar un tipo `BLOB` o `TEXT` . También, si quiere almacenar valores binarios como resultados de encriptación o compresión que puedan contener valores byte arbitrarios, use una columna `BLOB` en lugar de `CHAR` o `VARCHAR`, para evitar problemas potenciales con eliminación de espacios finales que puedan cambiar los valores de los datos.

La siguiente tabla ilustra las diferencias entre los dos tipos de columnas mostrando el resultado de almacenar varios valores de cadenas de carácteres en columnas `CHAR(4)` y `VARCHAR(4)` :

Valor | `CHAR(4)` | Almacenamiento necesario | `VARCHAR(4)` | Almacenamiento necesario
`''` | `' '` | 4 bytes | `''` | 1 byte
`'ab'` | `'ab '` | 4 bytes | `'ab'` | 3 bytes
`'abcd'` | `'abcd'` | 4 bytes | `'abcd'` | 5 bytes
`'abcdefgh'` | `'abcd'` | 4 bytes | `'abcd'` | 5 bytes

Los valores retornados de las columnas `CHAR(4)` y `VARCHAR(4)` son los mismos en cada caso, ya que los espacios finales se eliminan en la recuperación de valores `CHAR`.

En MySQL 5.0, los valores en columnas `CHAR` y `VARCHAR` se almacenan y comparan según la colación del conjunto de carácteres asignado a la columna.

`CHAR BYTE` es un alias para `CHAR BINARY`. Existe por cuestión de compatibilidad.

El atributo `ASCII` asigna el conjunto de carácteres `latin1` a una columna `CHAR` . El atributo `UNICODE` asigna el conjunto de carácteres `ucs2` .

MySQL puede cambiar silenciosamente el tipo de una columna `CHAR` o `VARCHAR` en tiempo de creación. Consulte Sección 13.1.5.1, “Cambios tácitos en la especificación de columnas”.

### 11.4.2. Los tipos `BINARY` y `VARBINARY`

Los tipos `BINARY` y `VARBINARY` son similares a `CHAR` y `VARCHAR`, excepto que contienen cadenas de carácteres binarias en lugar de cadenas de carácteres no binarias. Esto es, contienen cadenas de bytes en lugar de cadenas de carácteres. Esto significa que no tienen conjunto de carácteres asignado, y la comparación y ordenación se basa en los valores numéricos de los valores de los bytes.

La longitud máxima disponible es la máxima para `BINARY` t `VARBINARY` como para `CHAR` y `VARCHAR`, excepto que la longitud para `BINARY` y `VARBINARY` es una longitud en bytes en lugar de en carácteres.

El tratamiento de los espacios finales es el mismo para `BINARY` y `VARBINARY` como lo es para `CHAR` y `VARCHAR`. Cuando se almacenan los valores `BINARY`, se rellenan con espacios a la derecha hasta la longitud especificada. Cuando los valores `BINARY` se recuperan, los espacios finales se eliminan. Para `VARBINARY`, los espacios finales se eliminan cuando los valores se almacenan. Desde MySQL 5.0.3, los espacios finales se mantienen. Debe considerar estas características si planea usar estos tipos de datos para almacenar datos binarios que deban acabar con espacios.

En MySQL 5.0, `BINARY` y `VARBINARY` son tipos de datos distintos. Para `CHAR(`M`) BINARY` y `VARCHAR(`M`) BINARY`, el atributo `BINARY` hace que se use la colación binaria para la columna, pero la columna no contiene cadenas de carácteres no binarios en lugar de cadenas binarias de bytes. Por ejemplo `CHAR(5) BINARY` se trata como `CHAR(5) CHARACTER SET latin1 COLLATE latin1_bin`, asumiendo que el conjunto de carácteres por defecto es `latin1`.

### 11.4.3. Los tipos `BLOB` y `TEXT`

Un `BLOB` es un objeto binario que puede tratar una cantidad de datos variables. Los cuatro tipos `BLOB` son `TINYBLOB`, `BLOB`, `MEDIUMBLOB`, y `LONGBLOB`. Difieren sólo en la longitud máxima de los valores que pueden tratar.

Los cuatro tipos `TEXT` son `TINYTEXT`, `TEXT`, `MEDIUMTEXT`, y `LONGTEXT`. Se corresponden a los cuatro tipos `BLOB` y tienen las mismas longitudes y requerimientos de almacenamiento.

Consulte Sección 11.5, “Requisitos de almacenamiento según el tipo de columna”.

Las columnas `BLOB` se tratan como cadenas de carácteres binarias (de bytes). Las columnas `TEXT` se tratan como cadenas de carácteres no binarias (de carácateres). Las columnas `BLOB` no tienen conjunto de carácteres, y la ordenación y la comparación se basan en los valores numéricos de los bytes. Las columnas `TEXT` tienen un conjunto de carácteres y se ordenan y comparan en base de la colación del conjunto de carácteres asignada a la columna desde MySQL 4.1.

No hay conversión de mayúsculas/minúsculas para columnas `TEXT` o `BLOB` durante el almacenamiento o la recuperación.

Si asiguna un valor a una columna `BLOB` o `TEXT` que exceda la longitud máxima del tipo de la columna, el valor se trunca. Si los carácteres truncados no son espacios, aparece una advertencia. Puede hacer que aparezca un error en lugar de una advertencia usando el modo SQL estricto. Consulte Sección 5.3.2, “El modo SQL del servidor”.

En la mayoría de aspectos, puede tratar una columna `BLOB` como `VARBINARY` que puede ser tan grande como desee. Similarmente, puede tratar columnas `TEXT` como `VARCHAR`. `BLOB` y `TEXT` difieren de `VARBINARY` y `VARCHAR` en los siguientes aspectos::

- No se eliminan espacios al final para columnas `BLOB` y `TEXT` cuando los valores se almacenan o recuperan. Antes de MySQL 5.0.3, esto difiere de `VARBINARY` y `VARCHAR`, para los que se eliminaban los epacios al final cuando se almacenaban.

  Tenga en cuenta que `TEXT` realiza comparación espacial extendida para coincidir con el objeto comparado, exactamente como `CHAR` y `VARCHAR`.

- Para índices en columnas `BLOB` y `TEXT`, debe especificar una longitud de prefijo para el índice. Para `CHAR` y `VARCHAR`, la longitud de prefijo es opciona. Consulte Sección 7.4.3, “Índices de columna”.

- `BLOB` y `TEXT` no pueden tener valores `DEFAULT` .

En MySQL 5.0, `LONG` y `LONG VARCHAR` se mapean con el tipo de datos `MEDIUMTEXT`. Esto existe por compatibilidad. Si usa el atributo `BINARY` con el tipo de columna `TEXT`, se asigna la colación binaria del conjunto de carácteres a la columna.

MySQL Connector/ODBC define los valores `BLOB` como `LONGVARBINARY` y valores `TEXT` como `LONGVARCHAR`.

Como los valores `BLOB` y `TEXT` pueden ser extremadamente grandes, puede encontrar algunas restricciones al usarlos:

- Sólo los primeros `max_sort_length` bytes de la columna se usan al ordenar. El valor por defecto de `max_sort_length` es 1024; este valor puede cambiarse usando la opción `--max_sort_length` al arrancar el servidor mysqld . Consulte Sección 5.3.3, “Variables de sistema del servidor”.

  Puede hacer que haya más bytes significativos al ordenar o agrupar incrementando el valor de `max_sort_length` en tiempo de ejecución. Cualquier cliente puede cambiar el valor de su variable de sesión `max_sort_length` :

      mysql> SET max_sort_length = 2000;
      mysql> SELECT id, comment FROM tbl_name
          -> ORDER BY comment;

  Otra forma de usar `GROUP BY` o `ORDER BY` en una columna `BLOB` o `TEXT` conteniendo valores grandes cuando quiere que más de `max_sort_length` bytes sean significativos es convertir el valor de la columna en un objeto de longitud fija. La forma estándard de hacerlo es con la función `SUBSTRING` . Por ejemplo, el siguiente comando causa que 2000 bytes de la columna `comment` se tengan en cuenta para ordenación:

      mysql> SELECT id, SUBSTRING(comment,1,2000) FROM tbl_name
          -> ORDER BY SUBSTRING(comment,1,2000);

- El tamaño máximo de un objeto `BLOB` o `TEXT` se determina por su tipo, pero el valor máximo que puede transmitir entre el cliente y el servidor viene determinado por la cantidad de memoria disponible y el tamaño de los buffers de comunicación. Puede cambiar el tamaño de los buffers de comunicación cambiando el valor de la variable `max_allowed_packet`, pero debe hacerlo para el servidor y los clientes . Por ejemplo, mysql y mysqldump le permite cambiar el valor de la variable del cliente `max_allowed_packet` . Consulte Sección 7.5.2, “Afinar parámetros del servidor”, Sección 8.3, “La herramienta intérprete de comandos mysql”, y Sección 8.7, “El programa de copia de seguridad de base de datos mysqldump”.

Cada valor `BLOB` o `TEXT` se representa internamente como un objeto a parte. Esto se hace en contraste con todos los otros tipos de columnas, para los que el almacenamiento se hace una vez por columna cuando se abre la tabla.

### 11.4.4. El tipo de columna `ENUM`

Un `ENUM` es un objeto de cadenas de carácteres con un valor elegido de una lista de valores permitidos que se enumeran explícitamente en la especificación de columna en tiempo de creación de la tabla.

El valor puede ser la cadena vacía (`''`) o `NULL` bajo ciertas circunstancias:

- Si inserta un valor inválido en un `ENUM` (esto es, una cadena de carácteres no presente en la lista de valores permitidos), la cadena vacía se inserta en lugar de un valor especial de error. Esta cadena puede distinguirse de una cadena vacía “normal” por el hecho que esta cadena tiene un valor numérico 0. Más información posteriormente.

- Si se declara una columna `ENUM` para permitir `NULL`, el valor `NULL` es un valor legal para la columna, y el valor por defecto es `NULL`. Si una columna `ENUM` se declara `NOT NULL`, su valor por defecto es el primer elemento de la lista de valores permitidos.

Cada valor de la enumeración tiene un índice:

- Los valores de la lista de elementos permitidos en la especificación de la columna se numeran empezando por 1.

- El valor de índice de la cadena errónea es 0. Esto significa que puede usar el siguiente comando `SELECT` para encontrar registros con el valor inválido `ENUM` asignado:

      mysql> SELECT * FROM tbl_name WHERE enum_col=0;

- El índice del valor `NULL` es `NULL`.

Por ejemplo, una columna especificada como `ENUM('one', 'two', 'three')` puede tener cualquiera de los valores mostrados aquí. El índice de cada valor se muestra:

Valor | Índice
`NULL` | `NULL`
`''` | 0
`'one'` | 1
`'two'` | 2
`'three'` | 3

Una enumeración puede tener un máximo de 65,535 elementos.

Los espacios finales se borran automáticamente para valores `ENUM` miembros cuando se crea la tabla.

Cuando se reciben, los valores almacenados en una columna `ENUM` se muestran usando el formato de mayúsculas/minúsculas usado en la definición de la columna. En MySQL 4.1.1, las columnas `ENUM` pueden recibir un conjunto de carácteres y colación. Para colaciones binarias o sensibles a mayúsculas/minúsculas, el formato se tiene en cuenta al asignar valores a la columna.

Si recibe un valor `ENUM` en contexto numérico, se retorna el índice del valor. Por ejemplo, puede recibir valores numéricos de una columna `ENUM` así:

    mysql> SELECT enum_col+0 FROM tbl_name;

Si almacena un número en una columna `ENUM`, el número se trata como índice, y el valor almacenado es el miembro de la enumeración con ese índice. (Sin embargo, esto no funciona con `LOAD DATA`, que trata toda la entrada como cadenas de carácteres.) No es recomendable definir una columna `ENUM` con valores de enumeración que parezcan números, ya que esto puede causar confusión. Por ejemplo, la siguiente columna tiene miembros de enumeración con valores de `'0'`, `'1'`, y `'2'`, pero valores de índice `1`, `2`, y `3`:

    numbers ENUM('0','1','2')

Los valores `ENUM` se ordenan según el order en que se enumeran los mienbros en la especificación de la columna. (En otras palabras, los valores `ENUM` se ordenan según sus números de índice.) Por ejemplo, `'a'` se ordena antes que `'b'` para `ENUM('a', 'b')`, pero `'b'` se ordena antes de `'a'` para `ENUM('b', 'a')`. La cadena vacía se ordena antes de las cadenas no vacías, y los valores `NULL` se ordenan antes de todos los otros valores de la enumeración. Para evitar resultados inesperados, especifique la lista `ENUM` en orden alfabético. También puede usar `GROUP BY CAST(col AS VARCHAR)` o `GROUP BY CONCAT(col)` para asegurarse que la columna se ordena léxicamente en lugar de por número de índice.

Si quiere determinar todos los valores posibles para una columna `ENUM`, use `SHOW COLUMNS FROM `tbl_name` LIKE `enum_col`` y parsee la definición de `ENUM` en la segunda columna de la salida.

### 11.4.5. El tipo `SET`

Un `SET` es un objeto de cadenas de carácteres que tiene cero o más valores, cada uno de ellos debe elegirse de una lista de valores posibles especificada cuando se crea la tabla. Los valores de columnas `SET` que consisten de múltiples miembros del conjunto se especifican con los miembros separados por comas ('`,`'). Una consecuencia de esto es que los miembros de `SET` no pueden contener comas ellos mismos.

Por ejemplo, una columna especificada como `SET('one', 'two') NOT NULL` puede tener cualquiera de estos valores:

    ''
    'one'
    'two'
    'one,two'

Un `SET` puede tener un máximo de 64 miembros distintos.

Los espacios finales se borran automáticamente de los miembros de un `SET` cuando se crea la tabla.

Cuando se recuperan, los valors almacenados en una columna `SET` se muestran usando la sensibilidad de mayúsculas/minúsculas usando en la definición de la columna. En MySQL 5.0, las columnas `SET` pueden tener un conjunto de carácteres y colación. Para colaciones binarias o sensibles a mayúsculas/minúsculas, esta sensibilidad se tiene en cuenta al asignar valores a la columna.

MySQL almacena valores `SET` numéricamente, con el bit de menos peso del valor almacenado correspondiente al primer miembro del conjunto. Si recibe un valor `SET` en un contexto numérico, el valor recibido tiene los bits asignados correspondientes a los miembros que coinciden con el valor de la columna. Por ejemplo, puede recuperar los valores numéricos de una columna `SET` así:

    mysql> SELECT set_col+0 FROM tbl_name;

Si se almacena un número en una columna `SET`, los bits que se asignan en la representación binaria del número determinan los miembros del conjunto en el valor de la columna. Para una columna especificada como `SET('a','b','c','d')`, los miembros tienen los siguientes valores decimales y binarios:

`SET` Miembro | Valor decimal | Valor binario
`'a'` | `1` | `0001`
`'b'` | `2` | `0010`
`'c'` | `4` | `0100`
`'d'` | `8` | `1000`

Si asigna un valor de `9` a esta columna, esto es `1001` en binario, de forma que el primer y cuarto miembro del`SET` `'a'` y `'d'` se seleccionan y el valor resultante es `'a,d'`.

Para un valor que contenga más de un elemento `SET`, no importa el orden en que se listen los elementos cuando inserte el valor. Tampoco no importa cuántas veces se lista un elemento dado para el valor. Cuando el valor se recupera posteriormente, cada elemento en el valor aparece una vez, con los elementos listados según el orden en que se especificaron al crear la tabla. Si una columna se especifica como `SET('a','b','c','d')`, `'a,d'`, `'d,a'`, y `'d,a,a,d,d'` aparecen como `'a,d'` al recuperarse.

Si asigna un valor no soportado a una columna `SET`, el valor se ignora.

Los valores `SET` se ordenan numéricamente. Los valores `NULL` se ordenan antes de los no `NULL`.

Normalmente, busca valores `SET` usando la función `FIND_IN_SET()` o el operador `LIKE` :

    mysql> SELECT * FROM tbl_name WHERE FIND_IN_SET('value',set_col)>0;
    mysql> SELECT * FROM tbl_name WHERE set_col LIKE '%value%';

El primer comando encuentra registros cuando `set_col` contiene el miembro `value` del conjunto. El segundo es similar, pero no igual: encuentra registros cuando `set_col` contengan el valor `value` en cualquier sitio, incluso cuando es una subcadena de otro miembro del conjunto.

Los siguientes comandos también son legales:

    mysql> SELECT * FROM tbl_name WHERE set_col & 1;
    mysql> SELECT * FROM tbl_name WHERE set_col = 'val1,val2';

El primero de estos comandos busca valores que contengan el primer miembro del conjunto. El segundo busca una coincidencia exacta. Tenga cuidado con las comparaciones del segundo tipo. Comparar valores del conjunto `'`val1`,`val2`'` retorna distintos resultados que comparar valores de `'`val2`,`val1`'`. Debe especificar los valores en el mismo orden en que se listan en la definición de la columna.

Si desea determinar todos los valores posibles para una columna `SET`, use `SHOW COLUMNS FROM `tbl_name` LIKE `set_col`` y parsee la definición de `SET` en la segunda columna de la salida.

## 11.5. Requisitos de almacenamiento según el tipo de columna

Los requerimientos de almacenamiento para cada uno de los tipos de columnas soportados por MySQL se listan por categoría.

El máximo tamaño de un registro en una tabla `MyISAM` es 65,534 bytes. Cada columna `BLOB` y `TEXT` cuenta sólo de cinco a nueve bytes más alla de su tamaño.

Si una tabla `MyISAM` incluye cualquier tipo de columna de tamaño variable, el formato de rebistro también tiene longitud variable. Cuando se crea una tabla. MySQL puede, bajo ciertas condiciones, cambiar una columna de tamaño variable a fijo o viceversa. Consulte Sección 13.1.5.1, “Cambios tácitos en la especificación de columnas” para más información.

Requerimientos de almacenamiento para tipos numéricos

Tipo de columna | Almacenamiento requerido
`TINYINT` | 1 byte
`SMALLINT` | 2 bytes
`MEDIUMINT` | 3 bytes
`INT`, `INTEGER` | 4 bytes
`BIGINT` | 8 bytes
`FLOAT(`p`)` | 4 bytes si 0 <= `p` <= 24, 8 bytes si 25 <= `p` <= 53
`FLOAT` | 4 bytes
`DOUBLE [PRECISION]`, objeto `REAL` | 8 bytes
`DECIMAL(`M`,`D`)`, `NUMERIC(`M`,`D`)` | Varía; consulte la siguiente explicación
`BIT(`M`)` | aproximadamente (`M`+7)/8 bytes

Los requerimientos de almacenamiento para `DECIMAL` (y `NUMERIC`) son específicos para cada versión:

Desde MySQL 5.0.3, los valores para columnas `DECIMAL` más largos se representan usando un formato binario que empaqueta nueve dígitos decimales en cuatro bytes. El almacenamiento para la parte entera y fraccional se determinan separadamente. Cada múltiplo de nueve dígitos requiere cuatro bytes, y el dígito "de resto" requiere alguna fracción de cuatro bytes. El almacenamiento requerido para los dígitos "de resto" se da en la siguiente tabla:

Resto | Número
Dítigos | de bytes
0 | 0
1 | 1
2 | 1
3 | 2
4 | 2
5 | 3
6 | 3
7 | 4
8 | 4
9 | 4

Antes de MySQL 5.0.3, las columnas `DECIMAL` se representan como cadenas y el requerimiento de almacenamiento es: `M`+2 bytes si `D` > 0, ``M`+1` bytes si `D` = 0 (`D`+2, si ``M` < `D``)

Requerimientos de almacenamiento para tipos de fecha y hora

Tipo de columna | Almacenamiento requerido
`DATE` | 3 bytes
`DATETIME` | 8 bytes
`TIMESTAMP` | 4 bytes
`TIME` | 3 bytes
`YEAR` | 1 byte

Requerimientos de almacenamiento para tipos de cadenas de carácteres

Tipo de columna | Almacenamiento requerido
`CHAR(`M`)` | ``M`` bytes, 0 `<= `M` <=` 255
`VARCHAR(`M`)` | `L`+1 bytes, donde ``L` <= `M`` y 0 `<= `M` <=` 255
`BINARY(`M`)` | ``M`` bytes, 0 `<= `M` <=` 255
`VARBINARY(`M`)` | `L`+1 bytes, donde ``L` <= `M`` y 0 `<= `M` <=` 255
`TINYBLOB`, `TINYTEXT` | `L`+1 byte, donde `L` < 2^8
`BLOB`, `TEXT` | `L`+2 bytes, donde `L` < 2^16
`MEDIUMBLOB`, `MEDIUMTEXT` | `L`+3 bytes, donde `L` < 2^24
`LONGBLOB`, `LONGTEXT` | `L`+4 bytes, donde `L` < 2^32
`ENUM('`value1`','`value2`',...)` | 1 o 2 bytes, dependiendo del número de valores de la enumeración (65,535 valores como máximo)
`SET('`value1`','`value2`',...)` | 1, 2, 3, 4, o 8 bytes, dependiendo del número de miembros del conjunto (64 miembros como máximo)

Los tipos `VARCHAR` y `BLOB` y `TEXT` son de longitud variable. Para cada uno, los requerimientos de almacenamiento depende de la longitud de los valores de la (representados por `L` en la tabla precedente), en lugar que el tamaño máximo del tipo. Por ejemplo, una columna `VARCHAR(10)` puede tratar una cadena con una lengitud máxima de 10. El almacenamiento requerido real es la longitud de la cadena (`L`), más 1 byte para registrar la longitud de la cadena. Para la cadena `'abcd'`, `L` es 4 y el requerimiento de almacenamiento son 5 bytes.

Para los tipos `CHAR`, `VARCHAR`, y `TEXT`, los valores `L` y `M` en la tabla precedente debe interpretarse como números de carácteres en MySQL 5.0, y las longitudes para estos tipos en las especificaciones de la colmna indican el número de carácteres. Por ejemplo, para almacenar un valor `TINYTEXT` necesita `L` carácteres + 1 byte.

Desde MySQL 5.0.3, el motor `NDBCLUSTER` soporta sólo columnas de longitud fija. Esto significa que una columna `VARCHAR` de una tabla en MySQL Cluster se comportará casi como si fuera de tipo `CHAR` (excepto que cada registro todavía tiene un byte extra). Por ejemplo, en una tabla Cluster, cada registro en una columna declarada como `VARCHAR(100)` necesitará 101 bytes para almacenamiento, sin tener en cuenta la longitud de la columna almacenada en cualquier registro.

Los tipos `BLOB` y `TEXT` requieren 1, 2, 3, o 4 bytes para almacenar la longitud de la columna, dependiendo de la longitud máxima posible del tipo. Consulte Sección 11.4.3, “Los tipos `BLOB` y `TEXT`”.

Las columnas `TEXT` y `BLOB` se implementan de forma distinta en el motor de almacenamiento NDB Cluster , donde cada registro en una columna `TEXT` se compone de dos partes separadas. Una de estas es de longitud fija (256 bytes), y se almacena realmente en la tabla original. La otra consiste de cualquier dato de más de 256 bytes, que se almacena en una tabla oculta. Los registros en esta segunda tabla siempre tienen una longitud de 2,000 bytes . Esto significa que el tamaño de una columna `TEXT` es 256 si `size` <= 256 (donde `size` representa el tamaño del registro); de otro modo, el tamaño es 256 + `size` + (2000 - (`size` - 256) % 2000).

El tamaño de un objeto `ENUM` lo determina el número de diferentes valores de la enumeración. Un byte se usa para enumeraciones de hasta 255 valores posibles. Dos bytes se usan para enumeraciones teniendo entre 256 y 65,535 valores posibles. Consulte Sección 11.4.4, “El tipo de columna `ENUM`”.

El tamaño de un objeto `SET` se determina por el número de diferentes mienbros del conjunto. Si el tamaño del conjunto es `N`, el objeto ocupa `(`N`+7)/8` bytes, redondeado a 1, 2, 3, 4, o 8 bytes. Un `SET` puede tener como máximo 64 miembros. Consulte Sección 11.4.5, “El tipo `SET`”.

## 11.6. Escoger el tipo de columna correcto

Para almacenamiento óptimo, debe tratar de usar el tipo más preciso en todos los casos. Por ejemplo, si una columna entera se usa para valores en el rango de `1` a `99999`, entonces `MEDIUMINT UNSIGNED` es el mejor tipo. De los tipos que representan todos los valores requeridos, este tipo usa la menor cantidad de espacio.

Las tablas creadas en MySQL 5.0.3 y versiones posteriores usan un nuevo formato de almacenamiento para columnas `DECIMAL` . Todos los cálculos básicos (`+,-,*,/`) con columnas `DECIMAL` se realizan con precisión de 64 dígitos decimales. Consulte Sección 11.1.1, “Panorámica de tipos numéricos”.

Los cálculos con valores `DECIMAL` se realizan usando operaciones de doble precisioón. Si la precisión no es muy importante, o si la velocidad es la máxima prioridad, el tipo `DOUBLE` puede ser lo bastante bueno. Para alta precisión, siempre puede convertirlo a un tipo de punto fijo como `BIGINT`. Esto le permite hacer todos los cálculos con enteros de 64-bit, luego convertir los resultados de nuevo a valores de coma flotante.

## 11.7. Usar tipos de columnas de otros motores de bases de datos

Para facilitar el uso de código escrito por implementadores de SQL de otros vendedores, MySQL mapea los tipos de columnas como se muestra en la siguiente tabla. Estos mapeos hacen más fácil importar las definiciones de tablas de otros motores de bases de datos a MySQL:

Tipos de otros vendedores | Tipos MySQL
`BOOL`, | `TINYINT`
`BOOLEAN` | `TINYINT`
`CHAR VARYING(`M`)` | `VARCHAR(`M`)`
`DEC` | `DECIMAL`
`FIXED` | `DECIMAL`
`FLOAT4` | `FLOAT`
`FLOAT8` | `DOUBLE`
`INT1` | `TINYINT`
`INT2` | `SMALLINT`
`INT3` | `MEDIUMINT`
`INT4` | `INT`
`INT8` | `BIGINT`
`LONG VARBINARY` | `MEDIUMBLOB`
`LONG VARCHAR` | `MEDIUMTEXT`
`LONG` | `MEDIUMTEXT`
`MIDDLEINT` | `MEDIUMINT`
`NUMERIC` | `DECIMAL`

El mapeo de tipos de columnas se realiza en tiempo de creación de la tabla, tras el cual se descartan las especificaciones originales de tipos. Si crea una tabla con tipos usados por otros vendedores y luego realiza un comando `DESCRIBE `tbl_name``, MySQL muestra la estructura de tabla usando los tipos MySQL equivalentes. Por ejemplo:

    mysql> CREATE TABLE t (a BOOL, b FLOAT8, c LONG, d NUMERIC);
    Query OK, 0 rows affected (0.08 sec)

    mysql> DESCRIBE t;
    +-------+---------------+------+-----+---------+-------+
    | Field | Type          | Null | Key | Default | Extra |
    +-------+---------------+------+-----+---------+-------+
    | a     | tinyint(1)    | YES  |     | NULL    |       |
    | b     | double        | YES  |     | NULL    |       |
    | c     | mediumtext    | YES  |     | NULL    |       |
    | d     | decimal(10,0) | YES  |     | NULL    |       |
    +-------+---------------+------+-----+---------+-------+
    4 rows in set (0.00 sec)

Ésta es una traducción del manual de referencia de MySQL, que puede encontrarse en dev.mysql.com. El manual de referencia original de MySQL está escrito en inglés, y esta traducción no necesariamente está tan actualizada como la versión original. Para cualquier sugerencia sobre la traducción y para señalar errores de cualquier tipo, no dude en dirigirse a mysql-es@vespito.com.

Anterior |  | Siguiente
Capítulo 10. Soporte de conjuntos de caracteres | Inicio | Capítulo 12. Funciones y operadores