Persistencia avanzada con wpdb: tablas propias y migraciones sin perder datos

Aprendes cuándo salir de `options/postmeta`, cómo crear tablas propias con `dbDelta`, versionar esquema y ejecutar migraciones idempotentes con consultas seguras.

No todo cabe bien en `wp_options` o `postmeta`. Cuando necesitas consultas específicas, volumen alto o relaciones claras, una tabla propia suele ser la mejor decisión.

En esta lección diseñarás persistencia para eventos de avisos contextuales con `wpdb` y migraciones de esquema controladas.

El foco es evitar dos problemas clásicos: consultas inseguras y cambios de esquema que rompen instalaciones existentes.

Al terminar tendrás una base para evolucionar estructura de datos sin perder información de clientes.

  • La elección de almacenamiento impacta rendimiento, mantenibilidad y coste de evolución.
  • Si guardas pocos valores globales, `options` es perfecto. Si el dato cuelga de un post, `postmeta` puede ser suficiente.
  • Pero si necesitas filtrar por fecha, tipo de evento o estado con volumen alto, una tabla propia evita consultas lentas y estructuras forzadas.
  • Caso real: guardar logs de avisos en `options` generó un blob enorme difícil de consultar; pasar a tabla propia redujo tiempos y simplificó reporting.
  • Datos globales simples: `options`.

Cuándo usar tabla propia en lugar de options o meta

La elección de almacenamiento impacta rendimiento, mantenibilidad y coste de evolución.

Si guardas pocos valores globales, `options` es perfecto. Si el dato cuelga de un post, `postmeta` puede ser suficiente.

Pero si necesitas filtrar por fecha, tipo de evento o estado con volumen alto, una tabla propia evita consultas lentas y estructuras forzadas.

Caso real: guardar logs de avisos en `options` generó un blob enorme difícil de consultar; pasar a tabla propia redujo tiempos y simplificó reporting.

  • Datos globales simples: `options`.
  • Datos por post/usuario: metadatos.
  • Datos relacionales y voluminosos: tabla propia.

Crear y versionar esquema con dbDelta

Tu esquema debe poder evolucionar sin romper instalaciones ya activas.

En activación crea tabla inicial con `dbDelta` y guarda versión de esquema (`wpac_db_version`) en opciones.

En cada carga de plugin (o hook controlado) compara versión actual vs esperada y ejecuta migraciones pendientes.

Importante: las migraciones deben ser idempotentes; si se ejecutan dos veces, no deben duplicar ni corromper datos.

Consultas seguras: `prepare`, formato y límites

Nunca construyas SQL con concatenación de entradas de usuario.

Usa `$wpdb->prepare` en consultas con parámetros dinámicos y tipos correctos (`%d`, `%s`, `%f`).

Para inserciones sencillas, `$wpdb->insert` con formato explícito reduce errores y mejora legibilidad.

En lecturas de listas, añade límites y orden explícito para evitar consultas costosas inesperadas.

Caso real: añadir columna sin romper instalaciones antiguas

Una migración bien hecha respeta datos existentes y evita downtime.

Supón que en v1 guardabas solo `event_type` y `payload`, pero en v1.1 necesitas `source` para diferenciar admin/frontend.

En vez de forzar reset de tabla, ejecutas `ALTER TABLE` controlado durante migración y actualizas versión de esquema.

Después, tu código debe tolerar temporalmente instalaciones en versión anterior hasta completar migración.

WordPress Plugin
09

Persistencia avanzada con wpdb: tablas propias y migraciones sin perder datos

Aprendes cuándo salir de `options/postmeta`, cómo crear tablas propias con `dbDelta`, versionar esquema y ejecutar migraciones idempotentes con consultas seguras.

Código del tema: dbDelta

📘 Teoría

Cuándo usar tabla propia en lugar de options o meta

La elección de almacenamiento impacta rendimiento, mantenibilidad y coste de evolución.

Si guardas pocos valores globales, `options` es perfecto. Si el dato cuelga de un post, `postmeta` puede ser suficiente.

Pero si necesitas filtrar por fecha, tipo de evento o estado con volumen alto, una tabla propia evita consultas lentas y estructuras forzadas.

Caso real: guardar logs de avisos en `options` generó un blob enorme difícil de consultar; pasar a tabla propia redujo tiempos y simplificó reporting.

  • Datos globales simples: `options`.
  • Datos por post/usuario: metadatos.
  • Datos relacionales y voluminosos: tabla propia.

Crear y versionar esquema con dbDelta

Tu esquema debe poder evolucionar sin romper instalaciones ya activas.

1

En activación crea tabla inicial con `dbDelta` y guarda versión de esquema (`wpac_db_version`) en opciones.

2

En cada carga de plugin (o hook controlado) compara versión actual vs esperada y ejecuta migraciones pendientes.

3

Importante: las migraciones deben ser idempotentes; si se ejecutan dos veces, no deben duplicar ni corromper datos.

Creación de tabla y control de versión
global $wpdb;
$table = $wpdb->prefix . 'wpac_events';
$charset = $wpdb->get_charset_collate();

$sql = "CREATE TABLE $table (
  id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  event_type VARCHAR(64) NOT NULL,
  payload LONGTEXT NOT NULL,
  created_at DATETIME NOT NULL,
  PRIMARY KEY (id),
  KEY event_type (event_type)
) $charset;";

require_once ABSPATH . 'wp-admin/includes/upgrade.php';
dbDelta($sql);
update_option('wpac_db_version', '1.0.0');

Consultas seguras: `prepare`, formato y límites

Nunca construyas SQL con concatenación de entradas de usuario.

Usa `$wpdb->prepare` en consultas con parámetros dinámicos y tipos correctos (`%d`, `%s`, `%f`).

Para inserciones sencillas, `$wpdb->insert` con formato explícito reduce errores y mejora legibilidad.

En lecturas de listas, añade límites y orden explícito para evitar consultas costosas inesperadas.

1

Riesgo común

Query construida con strings concatenados.

  • Riesgo de SQL injection.
  • Errores por escapes manuales incompletos.
  • Código difícil de auditar.
2

Patrón recomendado

`prepare` / `insert` con formato.

  • Consultas más seguras.
  • Código más claro.
  • Mantenimiento más sencillo.

Caso real: añadir columna sin romper instalaciones antiguas

Una migración bien hecha respeta datos existentes y evita downtime.

1

Supón que en v1 guardabas solo `event_type` y `payload`, pero en v1.1 necesitas `source` para diferenciar admin/frontend.

2

En vez de forzar reset de tabla, ejecutas `ALTER TABLE` controlado durante migración y actualizas versión de esquema.

3

Después, tu código debe tolerar temporalmente instalaciones en versión anterior hasta completar migración.

🧪 Aprende probando

Ejemplo Ejemplo guiado: repositorio de eventos con wpdb seguro Creamos inserción y lectura con `wpdb` y consultas preparadas para uso real en plugin.

🏁 Retos

Reto Reto real: migración de esquema de v1.0.0 a v1.1.0 Añade columna `source` de forma segura e idempotente, y actualiza versión.

¿Qué es esto?

Soy Cristian Eslava y a veces hago webs para procrastinar yo y vosotros 😉.

Esta la hice en febrero de 2026 para facilitar el aprendizaje de mis alumnxs. Aprender desarrollo web practicando. La idea es que crezca semanalmente con nuevos temas, tests y retos.

Inspirado en MDN, en W3Schools, en Codepen, en el crack de Manz y en mil sitios de documentación sobre desarrollo web. Quería aportar además de bloques teóricos con ejemplos, la gamificación de los retos y el sistema de test que ya tenía en culTest .

Si te gustó, si no te gustó, si quieres saludarme, o invitarme a 🍻 no dudes en escribirme en cristianeslava@gmail.com .