Tablas de base de datos personalizadas Creación de la tabla

En esta serie veremos el uso de tablas de bases de datos personalizadas. Cubriremos cómo crear, mantener y eliminar la tabla, así como cómo agregar, eliminar y consultar datos de forma segura y eficiente. En este primer artículo veremos cuándo las tablas personalizadas pueden ser apropiadas, las ventajas y desventajas de usarlas y cómo crear la tabla..

Afortunadamente, WordPress proporciona una API bastante importante que simplifica un poco la creación e interacción con tablas personalizadas. En particular: el $ wpdb clase y la dbDelta () Función que veremos más durante la serie. Sin embargo, a pesar de eso, crear una tabla personalizada significa crear algo ajeno a WordPress, y perderá la mayoría del marco que rodea las tablas nativas. Por esa razón, usted como el autor del complemento es responsable de interactuar de manera segura y eficiente con él. Así que antes de saltar, debes considerar cuidadosamente si es más apropiado usar una tabla central existente..


Las desventajas de usar una tabla personalizada

Como se mencionó, las tablas personalizadas se ubican fuera del marco normal de WordPress y, en su mayor parte, esta es la causa subyacente de sus desventajas:

  • No hay funciones nativas de agregar, eliminar, actualizar o consultar con las que interactuar con la tabla.
  • La interfaz de usuario debe construirse desde (casi) cero.
  • La desinfección y el almacenamiento en caché depende de usted (aunque WordPress proporciona mucha ayuda a este respecto).
  • Otros complementos, y el propio WordPress, no "esperan" que su mesa esté allí. Por otro lado, si sus datos son un tipo de publicación personalizada, entonces la mayoría de los complementos de terceros bien integrados funcionarán junto a ellos..
  • WordPress, ni muchos otros complementos relacionados, realizará copias de seguridad o exportará su tabla. (En realidad, algunos complementos de copia de seguridad admiten tablas no centrales, pero exportar / importar no es tan sencillo)
  • Usted es responsable de configurar la estructura de sus tablas personalizadas de la manera más eficiente, incluida la elección del tipo de datos más apropiado para las columnas.
  • Eres responsable de escribir consultas SQL eficientes y sin errores..

Cuando es apropiado crear una tabla personalizada?

No hay una respuesta 'correcta' a esto, y se requiere un juicio sensato de los pros y los contras. Sin embargo, la sección anterior describe algunos inconvenientes serios para no usar el esquema de WordPress existente; por lo tanto, si no está seguro, generalmente es mejor evitar la creación de una tabla. Además, un enfoque de tabla personalizado requiere mucho trabajo y ofrece una gran oportunidad para que los errores se arrastren. Pero teniendo esto en cuenta, ¿cuándo podría ser adecuada una tabla personalizada??

La estructura de datos

Uno de los argumentos más importantes para las tablas personalizadas es cuando los datos deben estructurarse de manera que no sean apropiados para las tablas nativas. los * _posiciones La tabla está intrínsecamente orientada hacia publicaciones y páginas, que pueden ser totalmente inadecuadas para sus datos. De hecho, sus datos pueden distribuirse mejor en varias tablas, con relaciones entre ellos. Puede que ni siquiera sea tan complicado: el complemento Posts 2 Publicaciones usa una tabla personalizada para almacenar relaciones de muchos a muchos entre los tipos de publicaciones. Esta podría Se puede hacer usando la taxonomía API (y originalmente fue) o la meta API, pero ninguna de ellas es particularmente eficiente, y si bien puede estar bien para sitios más pequeños, no se escala bien. Scribu movió las Publicaciones 2 Publicaciones a una implementación de tabla personalizada para permitir que la información sobre una relación sea almacenada.

Mientras que la mayoría de los casos pueden ser 'comprimidos' en el * _posiciones En este caso, puede que no sea la ruta más eficiente: la tabla de metadatos utiliza una columna de valor no indexado para almacenar datos. Es increíblemente rápido para recuperar los metadatos de una publicación (WordPress emplea el almacenamiento en caché aquí también), pero las consultas complejas que utilizan la tabla meta pueden ser ineficientes o casi imposibles..

Consultas complejas

En relación con lo anterior, se encuentran consultas complejas, que las tablas nativas podrían no estar diseñadas para completarse de manera eficiente. En Event Organizer, por ejemplo, un evento es una publicación con fechas de eventos almacenadas en una tabla separada. Aunque sería posible almacenar esas fechas como meta posterior, hacerlo cuando los eventos tienen más de una fecha haría que cualquier consulta basada en la fecha sea extremadamente difícil e ineficiente, especialmente porque la columna de valor meta no está indexada.

Escala

Si utiliza wp_posts y sus datos son lo suficientemente grandes (más de 100.000 publicaciones), entonces mayo obstaculizar el rendimiento, dependiendo de qué consultas está ejecutando. Este argumento por sí solo es bastante débil, ya que hay muchas incógnitas que afectarán su validez. Sin embargo, en general, las bases de datos son rápidas en lo que hacen, y el marco de WordPress circundante sirve para optimizar las consultas tanto como sea posible. Sin embargo, en combinación con los otros dos factores, es posible que una tabla personalizada presente la opción más sensata..


Creando la mesa

Una vez que haya decidido que una tabla personalizada es necesaria, debemos crear la tabla. Antes de hacerlo, almacenaremos el nombre de nuestra tabla personalizada en $ wpdb. Este global contiene toda la información correspondiente a la base de datos del blog actual (cambiará de un sitio a otro cuando se use un sitio múltiple). Agregaremos nuestro nombre de tabla a este global. Esto no es en absoluto necesario, pero hace que el resto de nuestro código sea un poco más limpio:

 add_action ('init', 'wptuts_register_activity_log_table', 1); add_action ('switch_blog', 'wptuts_register_activity_log_table'); función wptuts_register_activity_log_table () global $ wpdb; $ wpdb-> wptuts_activity_log = "$ wpdb-> prefijo wptuts_activity_log"; 

El código anterior utiliza $ wpdb-> prefijo para agregar un prefijo al nombre de la tabla. El prefijo es por defecto wp_ pero puede ser alterado por el usuario en wp-config.php. Esto es necesario cuando puede tener más de una instalación de WordPress utilizando la misma base de datos, pero también puede cambiarse por otros motivos. Como tal no se puede asumir que el prefijo es wp_. Al igual que con las funciones, clases y configuraciones, etc., debe asegurarse de que el nombre de su tabla sea único.

A lo largo de esta serie volveremos al siguiente ejemplo. Imaginaremos que estamos creando una tabla para registrar la actividad del usuario (actualizar o eliminar publicaciones, cambiar la configuración, cargar una imagen, etc.).

Convenciones de nomenclatura de columnas

Existen varias convenciones sobre cómo nombrar sus columnas (y sus tablas para esa materia), pero independientemente de cómo las nombre, es importante ser consistente. Recomiendo usar solo caracteres en minúscula, ya que en algunas situaciones los nombres de columna pueden distinguir entre mayúsculas y minúsculas, e imponer esa regla hace que los errores sean menos probables y mejora la legibilidad. Como veremos más adelante en la serie, también es útil para cuando se necesitan listas blancas de columnas. Debe separar las palabras en los nombres de las columnas (por ejemplo,. post_data, Publicar Contenido) para facilitar la lectura, pero debe hacerlo con guiones bajos, y Nunca espacios.

También debe evitar palabras reservadas. Si la columna hace referencia a una tabla externa, se recomienda usar el nombre de esa columna externa (como user_id, nuestro ejemplo).

En nuestro ejemplo estaremos nombrando nuestras columnas:

  • log_id - el ID de registro.
  • user_id - el ID de usuario para quien corresponde el registro.
  • actividad - la actividad que se produjo.
  • object_id - el ID del objeto (por ejemplo, ID de publicación, ID de usuario, ID de comentario, etc.) que fue el sujeto de la actividad del usuario.
  • tipo de objeto - el tipo de objeto (por ejemplo, 'publicar', 'usuario', 'comentario', etc.).
  • fecha_actividad - la fecha y hora de la actividad.

Decidir los tipos de columna

Antes de continuar, deberá decidir los tipos de datos de las columnas que tendrá su tabla. Los tipos de columnas se pueden dividir en tres categorías: cadenas, números y tiempos de datos. Para cada uno de estos hay muchas variantes. Puedes encontrar una referencia completa aquí.

Es importante elegir el tipo de datos apropiado para su tabla ya que esto afectará la eficiencia de sus consultas. Algunos tipos de datos le permiten establecer un límite (por ejemplo,. varchar (40) - lo que le permite almacenar hasta 40 caracteres). El límite es opcional, pero se recomienda ya que puede mejorar el rendimiento, por lo que deberá decidir para cada columna cuál es la cantidad máxima de caracteres que requerirá la columna. Nota para los tipos de datos numéricos, la longitud se refiere al número de dígitos, no al máximo (por ejemplo,. INT (10) permite enteros no negativos de hasta 10 dígitos (hasta 4,294,967,295).

Cuando almacene fechas, casi siempre debe usar el FECHA Y HORA tipo de datos (almacenado como 2012-11-05 14:55:10) - y ciertamente no es una representación amigable para la fecha (por ejemplo, 5 de noviembre de 2012, 2:55 pm). FECHA Y HORA Los valores pueden ser fácilmente formateados en forma legible por humanos usando funciones como mysql2date (). Debe almacenar las fechas en la zona horaria UTC y, si es necesario, cambiarlo a una zona horaria diferente en la salida.

En nuestro ejemplo tendremos:

  • log_id - bigint (20)
  • user_id - bigint (20)
  • actividad - varchar (20)
  • object_id - bigint (20)
  • tipo de objeto - varchar (20)
  • fecha - fecha y hora

Columnas de indexación

A continuación, deberá decidir qué columnas indexar. Estas se declararán como LLAVEs, uno de los cuales será el CLAVE PRIMARIA. La clave principal es una columna donde cada fila tiene una único entrada - normalmente es solo un entero auto-incremental, esencialmente el 'número de fila'.

Los valores de las otras columnas indexadas no necesitan ser únicos, pero el valor debe determinar un conjunto relativamente pequeño de registros. La idea de la indexación es mejorar las consultas de lectura. Sin un índice, una búsqueda tendría que leer toda la tabla para encontrar filas coincidentes. Si una columna está indexada y forma parte de la consulta, puede encontrar rápidamente filas que coincidan con esa columna y luego ese subconjunto más pequeño de filas coincidentes puede compararse con la consulta (la analogía es un índice para un libro).

Como tal, si no consulta por esa columna, entonces la indexación de esa columna no ayudará (si nunca busca una palabra en el índice del libro, es posible que no esté allí). Tampoco si muchos registros comparten el mismo valor, como una columna de 'género', ya que esto no ofrecerá una gran mejora en una exploración de la tabla completa (imagine un índice de libros que incluya una palabra que aparece en todas las demás páginas).

La indexación tampoco es libre: columnas declaradas como LLAVEs reduzca el rendimiento de escritura (para continuar con la analogía, deberá actualizar el índice del libro cuando se agregue o elimine una palabra indexada), por lo que deberá decidir cuál es el balance correcto para su configuración. Más información se puede encontrar aquí..

Como es probable que queramos consultar por usuario (para ver su actividad reciente) estaremos indexando esta columna y usando la log_id como la clave principal.

Creando la mesa

Colocaremos el código para crear la tabla personalizada dentro de la siguiente función:

 la función wptuts_create_tables () // El código para crear una tabla va aquí // Crear tablas en la activación del complemento register_activation_hook (__FILE__, 'wptuts_create_tables');

Deberá activarse esta función en el gancho de activación del complemento, así como en cualquier momento en que deseemos realizar modificaciones en la tabla, por ejemplo, agregando columnas o cambiando su tipo de datos (veremos por qué más adelante en la serie).

El hecho de que al usar el gancho de activación, wptuts_create_tables () podría llamarse cuando ya existe una tabla, no es un descuido, y una vez más, cubriremos por qué más adelante en la serie.

Dentro de esa función, incluimos wp-admin / includes / upgrade.php para configurar algunas constantes y cargar la función dbDelta (). Tenga en cuenta que cuando se activa un plugin se pierde el en eso gancho, entonces wptuts_register_activity_log_table () debe ser llamado manualmente.

 require_once (ABSPATH. 'wp-admin / includes / upgrade.php'); $ wpdb global; global $ charset_collate; // Llame a esto manualmente ya que podemos haber perdido el gancho de inicio wptuts_register_activity_log_table ();

Lo global $ charset_collate contiene el conjunto de caracteres y la intercalación utilizados por las tablas nativas de WordPress. En términos generales, estos definen las codificaciones de los caracteres y cómo se comparan, dado que WordPress se usa en muchos idiomas diferentes, es importante usar la intercalación correcta para su tabla..

Aparte de la intercalación, la declaración SQL debe declarar el nombre de la tabla, junto con cada columna, su tipo y valor predeterminado y cualquier LLAVE columnas, incluyendo una CLAVE PRIMARIA columna. Típicamente será de la forma:

 CREAR TABLA [nombre de la tabla] ([columna de clave principal] bigint (20) sin signo NOT NULL auto_increment, [nombre de columna] [tipo de datos] [predeterminado], CLAVE PRIMARIA ([nombre de columna]), nombre de clave CLAVE ([nombre de columna]) ) [colación];

Para crear esta tabla agregamos lo siguiente a nuestro wptuts_create_tables () función:

 $ sql_create_table = "CREATE TABLE $ wpdb-> wptuts_activity_log (log_id bigint (20) sin firma NOT NULL auto_increment, user_id bigint (20) unsigned NOT NULL default '0', actividad varchar (20) NOT NULL default 'updated', object_id bigint (20) unsigned NOT NULL predeterminado '0', object_type varchar (20) NOT NULL predeterminado 'post', activity_date datetime NOT NULL predeterminado '0000-00-00 00:00:00', KEY PRINCIPAL (log_id), KEY user_id (user_id)) $ charset_collate; "; dbDelta ($ sql_create_table);

los dbDelta () función realiza nuestra CREAR MESA mando. Puede ser bastante estricto sobre la declaración SQL que se le ha dado. Por ejemplo, hay debe dos espacios entre CLAVE PRIMARIA y la columna de clave primaria. y las llaves deben tener un nombre.

Depuración

Si en la activación encuentras que obtienes el 'Tienes un carácter X de salida inesperada ... 'mensaje de error: es probable que haya un error en su declaración SQL. A veces se debe a dbDelta ()el rigor Si añades wp_die (); después dbDelta (), esto elimina el procesamiento y (con 'WP_DEBUG' establecido en verdadero) revelará cualquier mensaje de error.

Resumen

En este artículo hemos examinado las razones por las que no debería usar tablas personalizadas, los detalles que deberá considerar y, finalmente, cómo crear una tabla. La siguiente parte de esta serie cubrirá la desinfección, el análisis de la inyección SQL y cómo protegerse de ella. El código en este artículo está disponible en este repositorio de GitHub y se actualizará a medida que la serie continúe..


Recursos

  • MYSQL: Tipos de datos
  • MYSQL: Términos reservados para columnas y talbes
  • MYSQL: Índices
  • Introducción a MySQL
  • Codex: Creación de tablas con complementos
  • Códice: $ wpdb clase