Pregunta 1En la consola de este curso, haces INSERT de la cadena '123' en una columna declarada INTEGER. ¿Qué afirmación es correcta?
Cadenas, números, booleanos y conversión implícita de tipos
Con la tabla typed_demo, observa cómo los tipos declarados difieren de las clases de almacenamiento, mira cómo '10' y 123 se convierten de ida y vuelta con typeof(), descubre cómo los booleanos se representan con 0 / 1 y compara todo esto con los tipos estrictos CHAR / VARCHAR / INT / DECIMAL de MySQL ejecutando consultas reales.
Los datos que usaremos — la tabla typed_demo
Cuando creas una columna declaras un tipo como INTEGER / TEXT / REAL, y eso decide cómo la columna trata los valores que contiene.
En este artículo recorrerás cómo se almacenan y comparan cadenas, números y booleanos en SQL, y en qué se diferencia la forma en que la consola de este curso maneja los tipos (también conocido como type affinity (afinidad de tipos) en la documentación de SQLite) de los tipos estrictos de MySQL.
Tipo declarado frente a clase de almacenamiento — cada valor lleva su propio tipo
El tipo que un valor realmente tiene en tiempo de ejecución se llama su clase de almacenamiento, y hay cinco: NULL / INTEGER (números enteros) / REAL (decimales) / TEXT (cadenas) / BLOB (binario).
Puedes comprobar qué clase de almacenamiento tiene un valor en este momento con la función typeof(value).
Si pones una cadena con apariencia numérica en una columna declarada TEXT, la política de la columna es "trata esto como texto", así que se queda como cadena.
Pero si pones una cadena con apariencia numérica como '123' en una columna declarada INTEGER, entra en acción la política de la columna y la convierte en el entero 123 antes de almacenarla.
'123' entrando en una columna INTEGER se convierte en entero, mientras que '10' entrando en una columna TEXT se queda como cadena. El tipo real por valor siempre se puede comprobar con typeof().-- Ejemplo rápido e independiente que muestra que "el tipo declarado de la columna decide el tipo almacenado"
-- Una cadena con apariencia numérica en una columna INTEGER se convierte en un entero
CREATE TABLE IF NOT EXISTS aff_probe(num INTEGER, txt TEXT);
INSERT OR IGNORE INTO aff_probe VALUES ('123','123'), ('hello','hello');
-- Usa typeof para inspeccionar la clase de almacenamiento real
SELECT num, typeof(num) AS num_class,
txt, typeof(txt) AS txt_class
FROM aff_probe;
-- columna num: '123' se convierte en entero, 'hello' no se puede convertir y se queda como texto
-- columna txt: ambos se quedan como texto
Las cadenas y los números se convierten de ida y vuelta — '123' y 123
Cuando se necesita un número, una cadena se convierte automáticamente en número; cuando se necesita una cadena, un número se convierte en cadena.
Por ejemplo, '123' + 0 convierte la cadena '123' en el número 123 y devuelve 123, por lo que las cadenas con apariencia numérica se pueden incluir directamente en operaciones aritméticas.
En el sentido contrario, 123 || '' (|| es concatenación de cadenas) convierte el número en cadena.
Los operadores de comparación funcionan de la misma manera: si un lado es una columna INTEGER, el otro lado se alinea como número; si un lado es una columna TEXT, el otro lado se alinea como cadena.
Pero con dos literales en bruto como '1' = 1 no hay columna que fije la política, así que los valores permanecen con tipos distintos y el resultado es 0 (sin coincidencia).
-- Observa la conversión cadena <-> número (ejemplo de solo lectura)
SELECT '123' + 0 AS str_to_num, -- la cadena pasa a número 123
'abc' + 0 AS not_a_num, -- no se puede convertir, pasa a 0
123 || '' AS num_to_str, -- el número pasa a cadena '123'
typeof('123' + 0) AS class_after_add,
'1' = 1 AS literal_cmp, -- literales en bruto: 0 (sin coincidencia)
7 / 2 AS int_div, -- entero / entero = entero 3
7.0 / 2 AS real_div; -- un decimal en la mezcla da 3.5
Booleanos — TRUE / FALSE se almacenan como 1 / 0
SQL no tiene un tipo booleano independiente — los valores de verdad se representan con los enteros 1 (verdadero) y 0 (falso).
Las expresiones de comparación como 1 = 1 o 3 > 2 devuelven 1 para verdadero y 0 para falso.
En cualquier lugar donde puedas escribir una condición, como CASE WHEN column THEN ..., cualquier cosa distinta de 0 (normalmente 1) se trata como verdadero y 0 se trata como falso.
NULL es un tercer estado que no es ni verdadero ni falso ("desconocido"), y en condiciones WHERE o CASE se comporta como falso en el sentido de que la fila "no se selecciona".
-- Las expresiones de comparación devuelven 1 / 0 (ejemplo de solo lectura)
SELECT (1 = 1) AS is_true, -- 1
(1 = 2) AS is_false, -- 0
(3 > 2) AS gt, -- 1
TRUE AS true_kw, -- equivalente a 1
FALSE AS false_kw; -- equivalente a 0
-- Usa una columna flag directamente como condición
SELECT a, flag,
CASE WHEN flag THEN 'enabled' ELSE 'disabled' END AS state
FROM typed_demo;
Comparado con los tipos estrictos de MySQL
Lo que has visto hasta ahora es conversión implícita de tipos — los valores se reformulan flexiblemente según el contexto.
Por el contrario, MySQL y Oracle tienen tipos estrictos: cuando declaras CHAR(10) / VARCHAR(255) / TEXT para cadenas o INT / DECIMAL(10,2) para números, solo entran valores de ese tipo y la longitud y la precisión se imponen exactamente como están declaradas.
Un número normalmente no se cuela en una columna de cadena por conversión implícita y los valores que superan la longitud declarada o bien dan error o se truncan.
El código de abajo es la forma de MySQL de declarar tipos.
La consola de este curso no impone comprobaciones de longitud por diseño, así que cuando estudies restricciones de longitud como VARCHAR(10), simplemente recuerda que "así es como lo escribe MySQL" — esa sintaxis se traslada cuando pases a otras bases de datos.
-- Declaraciones de tipos estrictos en MySQL (solo lectura — no lo ejecutes en esta consola)
CREATE TABLE product (
id INT PRIMARY KEY, -- solo enteros
code CHAR(8), -- longitud fija, 8 caracteres
name VARCHAR(100) NOT NULL, -- hasta 100 caracteres
note TEXT, -- cadena larga
price DECIMAL(10,2) NOT NULL, -- 8 dígitos + 2 decimales
in_stock TINYINT(1) DEFAULT 0 -- bandera 0/1 para booleanos
);
-- En MySQL, poner 101 caracteres en VARCHAR(100)
-- dará error o se truncará según la configuración.
-- Poner 'abc' en una columna INT dará error.
-- La consola de este curso ejecuta todo gracias a la conversión implícita de tipos.
Tips — CHAR frente a VARCHAR y cuándo usar cada uno
`CHAR(n)` es de longitud fija: si el valor es más corto que n caracteres, se rellena con espacios al final hasta completar los n caracteres.
`VARCHAR(n)` es de longitud variable: mantiene el valor con su longitud real (n es la cota superior).
Usa `CHAR` cuando: el valor siempre tiene una longitud fija, como un código de país ('JP' / 'US'), un código de género o una sección de longitud fija de un hash. La disposición fija puede ser marginalmente más rápida para comparaciones y cálculos de posición de registro.
Usa `VARCHAR` cuando: las longitudes varían — nombres, direcciones de correo, títulos, descripciones, etc. Solo ocupa el espacio que realmente necesita, por lo que el almacenamiento queda más pequeño.
En caso de duda, `VARCHAR` es la opción más segura por defecto. Usar CHAR para datos de longitud variable puede provocar desajustes sutiles en las comparaciones por el relleno de espacios finales (por ejemplo, 'JP' frente a 'JP ' manejados de forma inconsistente).
Verificación de conocimientos
Responde cada pregunta una a una.
Pregunta 2¿Qué afirmación describe correctamente cómo se representan los booleanos en SQL?
Pregunta 3¿Qué afirmación describe correctamente la diferencia entre la consola de este curso (conversión implícita de tipos) y los tipos estrictos de MySQL?