Tech / Dev

Generador de SQL para tabla

Generá un CREATE TABLE con tipos, llaves, índices y constraints listos para copiar a tu migración.

Instantáneo🔒En tu navegadorSin registro
En vivo

Anatomía de un CREATE TABLE

Un buen CREATE TABLE define columnas con tipos precisos, una primary key clara, foreign keys con sus acciones de cascada, índices sobre columnas que se filtran o se ordenan, y constraints que protegen la integridad. Lo que parece overhead al inicio paga en confiabilidad después.

Primary key: BIGSERIAL vs UUID

Para tablas internas que crecen rápido, BIGSERIAL (Postgres) o BIGINT IDENTITY (SQL Server) siguen siendo lo más eficiente: 8 bytes, ordenable. Para IDs visibles al usuario o compartidos entre servicios, UUID (v7 si querés ordenamiento temporal) evita revelar cardinalidad y permite generar IDs sin coordinar.

Tipos de timestamp

Usá TIMESTAMPTZ en Postgres (timestamp with time zone): guarda en UTC y convierte al timezone del cliente. TIMESTAMP sin TZ es una trampa: parece funcionar hasta que cruzás husos horarios. En MySQL, usá DATETIME con la regla "guardá UTC en la app, formateá en el cliente".

NOT NULL y defaults

Toda columna que pueda ser NULL debería ser una decisión consciente. Si un campo siempre tiene valor, marcalo NOT NULL desde el principio. created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() es la configuración por defecto de cualquier tabla nueva.

CHECK constraints

CHECK (price >= 0), CHECK (status IN ('pending', 'paid')), CHECK (start_date < end_date). Lo que tu app debería validar, validalo también en la base. Es la última línea de defensa contra datos corruptos.

Foreign keys: CASCADE, RESTRICT, SET NULL

ON DELETE CASCADE borra los hijos cuando se borra el padre; útil para relaciones de composición (orden → items). RESTRICT prohíbe el borrado si hay hijos; lo más conservador. SET NULL deja el hijo huérfano; útil para autores y posts si querés mantener el post.

Índices: cuándo y cuáles

Indexá columnas usadas en WHERE, JOIN, ORDER BY. Para igualdad y rangos, B-tree (default). Para búsquedas full-text, GIN en Postgres. Para arrays y JSON, también GIN. Demasiados índices ralentizan los INSERT y ocupan espacio: monitoreá con pg_stat_user_indexes cuáles no se usan y borralos.

Soft delete

Si vas a "borrar" registros pero querés conservarlos, agregá deleted_at TIMESTAMPTZ nullable. Tu app filtra WHERE deleted_at IS NULL en lecturas. El trade-off: todas las queries necesitan ese filtro y los índices únicos requieren parciales.

Preguntas frecuentes

¿BIGSERIAL o UUID?

BIGSERIAL para tablas internas; UUID cuando el ID es público o cross-service.

¿Índice compuesto?

Cuando varias columnas se filtran juntas. La primera columna debe ser la más selectiva.

¿VARCHAR o TEXT?

En Postgres es lo mismo. En MySQL, VARCHAR(N) si tenés un límite claro.

¿Te sirvió este generador?