La sentencia SQL CREATE TABLE es la base del diseño de bases de datos. Cada vez que construyes una aplicación que almacena datos, usarás CREATE TABLE para definir la estructura de las tablas de tu base de datos.
A lo largo de esta guía, encontrarás ejercicios SQL interactivos que te permiten practicar CREATE TABLE en tu navegador, sin necesidad de configurar ninguna base de datos. Escribe consultas, obtén retroalimentación instantánea y verifica si tus resultados coinciden con la salida esperada.
Entender CREATE TABLE es esencial ya sea que estés construyendo una nueva aplicación, aprendiendo SQL o manteniendo bases de datos existentes. Define no solo qué datos puedes almacenar, sino cómo esos datos son validados y protegidos.
Sintaxis Básica de CREATE TABLE
La sentencia CREATE TABLE define una nueva tabla con columnas y sus tipos de datos:
CREATE TABLE nombre_tabla (
columna1 tipo_dato,
columna2 tipo_dato,
columna3 tipo_dato
);
Cada columna necesita un nombre y un tipo de dato. El tipo de dato le indica a la base de datos qué clase de valores puede contener la columna.
Aquí hay un ejemplo simple creando una tabla para almacenar información de libros:
CREATE TABLE books (
id INTEGER,
title TEXT,
author TEXT,
price DECIMAL(10,2),
published_date DATE
);
Esto crea una tabla con cinco columnas, cada una con un tipo de dato apropiado para los datos que almacenará.
Pruébalo tú mismo:
[[ testData.title ]]
Escribe dos sentencias SQL:
-
CREATE TABLEpara crear una tabla llamadabookscon tres columnas:id(INTEGER),title(TEXT) yprice(DECIMAL) -
INSERT INTOpara agregar una fila con los valores (1, ‘SQL Basics’, 29.99)
Consejo: Separa múltiples sentencias con un punto y coma (;).
[[ col ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
[[ i18n.your_results ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
[[ i18n.expected_results ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
[[ error ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
[[ testData.solution ]]
Tablas Disponibles
[[ table.name ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
Tipos de Datos SQL Comunes
Elegir el tipo de dato correcto es importante para la integridad de los datos y la eficiencia del almacenamiento. Estos son los tipos más utilizados:
Tipos Numéricos
- INTEGER (o INT) - Números enteros: 1, 42, -100
- DECIMAL(p,s) - Números decimales exactos con precisión p y escala s
- FLOAT/REAL - Números decimales aproximados para cálculos científicos
Tipos de Texto
- TEXT - Cadenas de longitud variable de cualquier tamaño
- VARCHAR(n) - Cadena de longitud variable con longitud máxima n
- CHAR(n) - Cadena de longitud fija, rellenada con espacios
Tipos de Fecha y Hora
- DATE - Fecha del calendario (año, mes, día)
- TIME - Hora del día
- TIMESTAMP - Fecha y hora combinadas
- DATETIME - Fecha y hora (usado en algunas bases de datos en lugar de TIMESTAMP)
Otros Tipos
- BOOLEAN - Valores verdadero/falso
- BLOB - Datos binarios (imágenes, archivos)
Nota: Los nombres de tipos de datos y sus características varían ligeramente entre sistemas de bases de datos. SQLite es particularmente flexible con los tipos, mientras que PostgreSQL y MySQL los aplican más estrictamente.
Claves Primarias
Una clave primaria identifica de forma única cada fila en una tabla. Es un concepto fundamental en el diseño de bases de datos:
CREATE TABLE customers (
customer_id INTEGER PRIMARY KEY,
name TEXT,
email TEXT
);
Características de la clave primaria:
- Única: Dos filas no pueden tener el mismo valor de clave primaria
- No NULL: Las columnas de clave primaria no pueden contener valores NULL
- Propósito único: Identifica exactamente una fila
Muchas bases de datos soportan claves primarias auto-incrementales:
-- PostgreSQL
customer_id SERIAL PRIMARY KEY
-- MySQL
customer_id INT AUTO_INCREMENT PRIMARY KEY
-- SQLite
customer_id INTEGER PRIMARY KEY -- Se auto-incrementa automáticamente
Pruébalo tú mismo:
[[ testData.title ]]
Escribe sentencias SQL para:
-
CREATE TABLEllamadastudentsconstudent_id(INTEGER PRIMARY KEY),name(TEXT) yenrolled(BOOLEAN) -
INSERT INTOdos estudiantes: (1, ‘Alice’, true) y (2, ‘Bob’, false)
Consejo: Separa múltiples sentencias con un punto y coma (;).
[[ col ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
[[ i18n.your_results ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
[[ i18n.expected_results ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
[[ error ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
[[ testData.solution ]]
Tablas Disponibles
[[ table.name ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
Restricciones de Columna
Las restricciones son reglas que aseguran la integridad de los datos. Previenen que datos inválidos sean insertados en tus tablas.
NOT NULL
Requiere un valor, NULL no está permitido:
CREATE TABLE users (
user_id INTEGER PRIMARY KEY,
username TEXT NOT NULL,
email TEXT NOT NULL
);
DEFAULT
Proporciona un valor cuando no se especifica ninguno:
CREATE TABLE orders (
order_id INTEGER PRIMARY KEY,
status TEXT DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
UNIQUE
Previene valores duplicados en una columna:
CREATE TABLE accounts (
account_id INTEGER PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
username TEXT UNIQUE
);
CHECK
Valida que los valores cumplan una condición:
CREATE TABLE products (
product_id INTEGER PRIMARY KEY,
price DECIMAL CHECK(price > 0),
quantity INTEGER CHECK(quantity >= 0)
);
Pruébalo tú mismo:
[[ testData.title ]]
Escribe sentencias SQL para:
-
CREATE TABLEllamadaproductsconproduct_id(INTEGER PRIMARY KEY),name(TEXT NOT NULL) ystock(INTEGER DEFAULT 0) -
INSERT INTOdos productos: (1, ‘Laptop’, 50) y (2, ‘Mouse’) - nota que el segundo producto usa el valor de stock por defecto
Consejo: Separa múltiples sentencias con un punto y coma (;).
[[ col ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
[[ i18n.your_results ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
[[ i18n.expected_results ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
[[ error ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
[[ testData.solution ]]
Tablas Disponibles
[[ table.name ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
Combinando Múltiples Restricciones
Puedes aplicar múltiples restricciones a una sola columna:
CREATE TABLE employees (
emp_id INTEGER PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
salary DECIMAL NOT NULL CHECK(salary > 0),
hire_date DATE DEFAULT CURRENT_DATE
);
El orden de las restricciones no importa, todas se aplican por igual. Esta tabla de empleados asegura:
- Cada empleado tiene un ID único
- Las direcciones de correo electrónico son requeridas y únicas
- Los salarios deben ser números positivos
- La fecha de contratación es hoy por defecto si no se especifica
Pruébalo tú mismo:
[[ testData.title ]]
Escribe sentencias SQL para:
-
CREATE TABLEllamadaemployeescon:emp_id(INTEGER PRIMARY KEY),email(TEXT UNIQUE NOT NULL),department(TEXT) ysalary(DECIMAL CHECK(salary > 0)) -
INSERT INTOun empleado: (1, ‘alice@company.com’, ‘Engineering’, 75000)
Consejo: Separa múltiples sentencias con un punto y coma (;).
[[ col ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
[[ i18n.your_results ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
[[ i18n.expected_results ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
[[ error ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
[[ testData.solution ]]
Tablas Disponibles
[[ table.name ]]
| [[ col ]] |
|---|
| [[ formatCell(cell) ]] |
Claves Foráneas
Las claves foráneas crean relaciones entre tablas referenciando la clave primaria de otra tabla:
CREATE TABLE orders (
order_id INTEGER PRIMARY KEY,
customer_id INTEGER,
order_date DATE,
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);
Las claves foráneas aseguran la integridad referencial:
- No puedes insertar un pedido con un customer_id que no exista en la tabla customers
- No puedes eliminar un cliente que tenga pedidos (a menos que uses CASCADE)
Acciones de Clave Foránea
Especifica qué sucede cuando los datos referenciados cambian:
CREATE TABLE order_items (
item_id INTEGER PRIMARY KEY,
order_id INTEGER,
product_id INTEGER,
quantity INTEGER,
FOREIGN KEY (order_id) REFERENCES orders(order_id) ON DELETE CASCADE,
FOREIGN KEY (product_id) REFERENCES products(product_id) ON DELETE RESTRICT
);
- CASCADE - Elimina/actualiza filas relacionadas automáticamente
- RESTRICT - Previene la eliminación si existen filas relacionadas
- SET NULL - Establece la clave foránea a NULL cuando el padre se elimina
- SET DEFAULT - Establece el valor por defecto cuando el padre se elimina
Restricciones a Nivel de Tabla
Algunas restricciones se aplican a toda la tabla en lugar de columnas individuales:
Clave Primaria Compuesta
Cuando una sola columna no es suficiente para identificar filas de forma única:
CREATE TABLE enrollments (
student_id INTEGER,
course_id INTEGER,
enrollment_date DATE,
grade TEXT,
PRIMARY KEY (student_id, course_id)
);
Restricciones con Nombre
Nombrar las restricciones hace los mensajes de error más claros y permite modificarlas después:
CREATE TABLE products (
product_id INTEGER,
name TEXT NOT NULL,
price DECIMAL,
CONSTRAINT pk_products PRIMARY KEY (product_id),
CONSTRAINT chk_price CHECK (price > 0),
CONSTRAINT uq_name UNIQUE (name)
);
CREATE TABLE IF NOT EXISTS
Previene errores cuando una tabla podría ya existir:
CREATE TABLE IF NOT EXISTS logs (
log_id INTEGER PRIMARY KEY,
message TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Esto es especialmente útil en:
- Scripts de migración de bases de datos
- Código de inicialización de aplicaciones
- Entornos de desarrollo
CREATE TABLE AS SELECT
Crea una nueva tabla a partir de los resultados de una consulta:
CREATE TABLE active_customers AS
SELECT customer_id, name, email
FROM customers
WHERE last_order_date > '2024-01-01';
Esto copia tanto la estructura como los datos. La nueva tabla es independiente, los cambios en la original no la afectan.
Nota: Las restricciones de la tabla original no se copian. Necesitarás agregarlas por separado si es necesario.
Tablas Temporales
Crea tablas que existen solo durante la sesión actual:
CREATE TEMPORARY TABLE cart_items (
item_id INTEGER PRIMARY KEY,
product_id INTEGER,
quantity INTEGER
);
Las tablas temporales son útiles para:
- Almacenar resultados intermedios en consultas complejas
- Datos específicos de sesión en aplicaciones web
- Pruebas y desarrollo
Mejores Prácticas para CREATE TABLE
Elige Nombres Descriptivos
Usa nombres claros y consistentes:
-- Bueno
CREATE TABLE customer_orders (...)
CREATE TABLE product_categories (...)
-- Evitar
CREATE TABLE tbl1 (...)
CREATE TABLE data (...)
Usa Tipos de Datos Apropiados
No uses TEXT para todo:
-- Bueno
price DECIMAL(10,2)
quantity INTEGER
is_active BOOLEAN
-- Menos eficiente
price TEXT
quantity TEXT
is_active TEXT
Agrega Restricciones Temprano
Define las restricciones al crear la tabla, no después:
-- Mejor: Restricciones definidas desde el inicio
CREATE TABLE users (
user_id INTEGER PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Documenta con Comentarios
Muchas bases de datos soportan comentarios en tablas y columnas:
-- PostgreSQL
COMMENT ON TABLE customers IS 'Almacena información de contacto de clientes';
COMMENT ON COLUMN customers.email IS 'Dirección de correo de contacto principal';
Trabajando con CREATE TABLE en Beekeeper Studio
Crear y gestionar tablas es mucho más fácil con una herramienta visual. Beekeeper Studio proporciona gestión intuitiva de tablas:
Características que ayudan con la creación de tablas:
- Diseñador visual de tablas: Crea tablas sin escribir SQL
- Editor de columnas: Define tipos de datos y restricciones visualmente
- Visor de relaciones: Ve las conexiones de claves foráneas entre tablas
- Vista previa de SQL: Revisa la sentencia CREATE TABLE generada antes de ejecutar
- Navegador de esquemas: Navega las tablas existentes como referencia
La versión gratuita incluye herramientas de creación de tablas para PostgreSQL, MySQL, SQLite, SQL Server y muchas más bases de datos.
Errores Comunes y Soluciones
La Columna Ya Existe
Error: duplicate column name
Revisa tu sentencia CREATE TABLE para encontrar nombres de columnas repetidos.
La Tabla Ya Existe
Error: table already exists
Usa CREATE TABLE IF NOT EXISTS o DROP TABLE IF EXISTS primero.
Fallo en Restricción de Clave Foránea
Error: FOREIGN KEY constraint failed
Asegúrate de que la tabla y columna referenciadas existan, y que estés insertando valores de referencia válidos.
Valor por Defecto Inválido
Error: Invalid default value for column
Asegúrate de que el valor por defecto coincida con el tipo de dato de la columna.
Puntos Clave
La sentencia CREATE TABLE es fundamental para SQL y el diseño de bases de datos:
- Define la estructura: Especifica columnas y sus tipos de datos para organizar tus datos
- Asegura la integridad: Usa restricciones (PRIMARY KEY, NOT NULL, UNIQUE, CHECK) para validar datos
- Construye relaciones: Las claves foráneas conectan tablas y mantienen la integridad referencial
- Elige tipos apropiados: Haz coincidir los tipos de datos con los datos reales que almacenarás
- Planifica con anticipación: Agrega restricciones al crear las tablas, no como algo posterior
Entender CREATE TABLE a fondo te ayudará a diseñar bases de datos que sean confiables, eficientes y mantenibles. Practica con los ejemplos interactivos de arriba para ganar confianza.
¿Listo para aprender más? Explora nuestras guías sobre SQL GROUP BY y SQL ORDER BY para continuar desarrollando tus habilidades en SQL.
Beekeeper Studio Es Una GUI de Base de Datos Gratuita y de Código Abierto
La mejor herramienta de consultas y editor SQL que he usado. Proporciona todo lo que necesito para gestionar mi base de datos. - ⭐⭐⭐⭐⭐ Mit
Beekeeper Studio es rápido, intuitivo y fácil de usar. Beekeeper soporta muchas bases de datos y funciona muy bien en Windows, Mac y Linux.
Lo Que Dicen Los Usuarios Sobre Beekeeper Studio
"Beekeeper Studio reemplazó por completo mi antiguo flujo de trabajo con SQL. Es rápido, intuitivo y hace que trabajar con bases de datos sea agradable de nuevo."
"He probado muchas GUIs de bases de datos, pero Beekeeper logra el equilibrio perfecto entre características y simplicidad. Simplemente funciona."