Publicar meta vs tablas de bases de datos separadas

29

Al desarrollar complementos que requieren almacenamiento de datos, ¿cuáles son las ventajas y desventajas de usar un método u otro?

La explicación dada en el códice no es detallada:

Sin embargo, antes de saltar con una tabla completamente nueva, considere si el almacenamiento de los datos de su complemento en WordPress 'Post Meta (también conocido como Campos personalizados) funcionaría. Post Meta es el método preferido; Úselo cuando sea posible / práctico.

Nassif Bourguig
fuente
FYI: MB Custom Table es un complemento que puede almacenar metadatos en tablas personalizadas en lugar de la metatabla posterior de WP.
Anh Tran

Respuestas:

30

Bueno, si tomo el sombrero de un niño de script WP, mi respuesta sería: use post_meta, siempre.

Sin embargo, sé una o dos cosas acerca de las bases de datos, por lo que mi respuesta es: nunca, nunca, jamás, use un EAV (también conocido como la tabla post_meta) para almacenar datos que pueda necesitar consultar.

En el frente del índice, básicamente no hay ninguno que valga la pena usar en las tablas meta. Entonces, si está almacenando el tipo de datos XYZ y espera consultar todas las publicaciones que tienen XYZ con un valor de 'abc', bueno ... buena suerte. (Vea todos los tickets relacionados con usuarios / roles / caps en el WP trac para darle una idea de lo sangriento que puede ser).

En el frente de la unión, rápidamente choca con el límite en el que el optimizador decide usar un algoritmo genérico en lugar de analizar la consulta cuando hay múltiples criterios de unión.

Por lo tanto, no, no, no, no. Nunca, nunca, nunca uses un meta. A menos que lo que esté almacenando sea cosmético y nunca sea parte de un criterio de consulta.

Se desglosa en tu aplicación. Si está almacenando, digamos, la fecha de nacimiento de un director de cine, que gran cosa. Usa un meta todo lo que quieras. Pero si está almacenando, digamos, la fecha de lanzamiento de una película, sería una locura no usar una tabla separada (o agregar columnas a la tabla de publicaciones) y agregar un índice a esa columna.

Denis de Bernardy
fuente
1
Sí, los complementos que estoy desarrollando manejan datos personalizados como eventos, noticias, comunicados de prensa, ofertas de trabajo ... Desde fuera de "WordPress World", el uso de tablas no es realmente una opción. Pero el consejo del Codex de WordPress es un poco confuso. ¿Cómo se pueden preferir fragmentos de datos serializados a datos normalizados / estructurados / indexados?
Nassif Bourguig
1
Si le preguntas al desarrollador promedio de WP, probablemente responderá "usa una meta" o "usa una taxonomía". Y estoy de acuerdo, hasta el punto en que necesita consultar en su contra. Si es así, y creo que es su caso, mi única respuesta es agregar los campos a la tabla de publicaciones o crear una tabla separada por completo. De lo contrario, se encontrará con enormes problemas de rendimiento cuando se trata de consultas y, lo que es aún más importante para las listas de nodos, la clasificación top-n.
Denis de Bernardy
1
Denis, ¿podría explicar un poco más esto? Me parece muy informativo, pero me encantaría tener más datos, ¿alguien ha hecho pruebas ?, ¿cuáles son exactamente los principales inconvenientes y limitaciones? Gracias.
Wyck
66
@Denis - Toda la apasionada defensa contra la postmeta, ¿eh? Sabes que vas firmemente en contra de la ortodoxia y caerás de las gracias de los sumos sacerdotes de la iglesia de la poesía codificada si persistes en hablar así, ¿no? :-) Pero en serio, ¿no crees que exageras un poco? Realmente depende de si habrá decenas de miles de meta registros o no. En muchos casos, simplemente no hay suficientes registros de los que preocuparse. Un sitio complejo que estoy desplegando tiene alrededor de 10,000 meta registros con pocos registros nuevos planeados, y está bien (para su información, no es un blog)
MikeSchinkel
1
@Denis - Gracias por los comentarios. Y no me malinterpreten, probablemente me inclino mucho más hacia su perspectiva, pero la combinación de 1.) un debate de una hora con Matt en WordCamp Birmingham sobre los méritos de los campos tipo Pods y 2.) la simplicidad del meta ha renunciado a centrar mis atenciones en otros temas que podría cambiar. En WCB me di cuenta de que mientras Matt esté a cargo, no cambiará porque (supongo) Matt está tan enamorado de la idea de tener menos tablas que no se permitirá reconocer los inconvenientes de la indexación en un byte de 768 llave. <
sigh
5

Si su complemento va a tener MUCHOS datos, entonces wp_postmetaNO es una buena idea como se muestra a continuación:

Tomando WooCommerce como ejemplo, en una tienda con ~ 30,000 productos, habrá un promedio de, por ejemplo, ~ 40 publicaciones meta (atributos y todo) por producto, 5 imágenes de producto por producto, lo que significa que habrá ~ 4 imágenes meta para cada imagen:

30,000 productos x 40 meta cada uno = 1,200,000 filas en wp_postmeta

+

30,000 productos x 5 imágenes cada uno x 4 imágenes meta por cada = 600,000 filas en wp_postmeta

Entonces, con solo 30,000 productos, está buscando tener 1,800,000 filas wp_postmeta.

Si agrega más propiedades a sus productos o imágenes de sus productos, este número se multiplicará.

El problema con eso es doble:

  • Las autouniones son muy caras con MySQL
  • wp_postmetala tabla no está indexada a menos que esté utilizando versiones posteriores de mysql (es decir, no hay índice FULLTEXT para meta_value)

Para dar un ejemplo de un caso real:

SELECT meta_value FROM wp_postmeta WHERE meta_key LIKE '_shipping_city'

Esto selecciona la ciudad de envío de todos los detalles de la orden, viene en unos 3 segundos en un servidor dedicado de nivel de entrada, incluso si hay 5-10 órdenes . Esto se debe a que la consulta se ejecuta desde una wp_postmetatabla que tiene ~ 3 millones de filas en la instalación en vivo.

Incluso la página de inicio es bastante lenta, porque el tema extrae varios elementos de wp_postmeta: controles deslizantes, algunas inserciones de revisión, algunos otros meta. En general, la lista de productos es muy lenta, las búsquedas son igualmente lentas cuando se enumeran productos.

No puede solucionar esto por ningún medio normal. Puede poner Elastic Search en su servidor y usar un plugin de Elastic Search en Wordpress, puede usar redis / memcached, puede usar un buen plugin de caché de página, pero al final el problema fundamental seguirá siendo: recuperar cualquier cantidad de datos de un archivo hinchado wp_postmetaLa tabla será lenta, siempre que se haga. En el servidor donde probé la solución que implementé a continuación, todo esto se instaló y configuró correctamente y se optimizó, y el sitio funcionó de manera aceptable para usuarios no registrados o consultas realizadas comúnmente desde que se iniciaron los complementos de almacenamiento en caché.

Pero en el momento en que un usuario conectado intentó hacer algo que no se hacía comúnmente o los crons, los complementos de almacenamiento en caché o cualquier otra utilidad querían obtener datos reales de la base de datos para almacenarlos en caché o hacer cualquier otra cosa, las cosas se volvieron lentas.

Entonces intenté algo más:

Codifiqué un pequeño complemento para llevar todos los meta del producto (postmeta para producto de tipo post ) a una tabla personalizada generada por código. Este complemento tomó todos los metadatos para cada publicación y creó una tabla agregando cada meta como columnas e insertando los valores en cada fila. Convertí el formato EAV en un formato relacional horizontal y plano. También tenía el complemento para eliminar postmeta de todos los productos movidos de la wp_postmetatabla.

Mientras lo hacía, moví los postmeta de adjuntos y todos los meta tipos de publicaciones a sus propias tablas.

Luego me conecté al get_(post_type)_metafiltro para anular la recuperación de metadatos para servirlos desde nuevas tablas personalizadas.

Ahora la misma consulta de antes, que tardó ~ 3 segundos en recuperarse, wp_postmetatoma ~ 0.006 segundos. El sitio ahora se comporta como si fuera una nueva instalación de WP.

....................

Naturalmente, hacer las cosas a la manera de Wordpress es mejor. En realidad es la norma.

Sin embargo , también es obvio que la tabla EAV es muy ineficiente en el escalado. Es infinitamente flexible y le permite almacenar cualquier información, pero el precio que paga por eso es el rendimiento. Es una compensación fundamental.

En ese contexto, es difícil decirle a alguien que tiene la intención de tener una gran cantidad de datos y, Dios no lo quiera, consultar / buscar en esos datos para usar la wp_postmetatabla con seguridad. El éxito en el rendimiento será excelente.

El uso de sus tablas personalizadas permitirá que sus datos se acumulen y sigan siendo lo suficientemente rápidos.

Al igual que Pippin Williams, el creador del complemento Easy Digital Downloads, mencionó que usaría tablas personalizadas si recién comenzara a codificar su complemento, si va a crear algo que se utilizará durante mucho tiempo o acumulará muchos datos, es más eficiente usar sus tablas personalizadas si las diseña bien.

Debe asegurarse de que cualquier otro desarrollador de complementos / complementos tenga medios para conectarse a su complemento para manipular sus datos antes y después de recuperarlos. Si haces eso, entonces eres bastante sólido.

unidad100
fuente
1
¡Cosas interesantes! Una cosa para aclarar es que el filtro mencionado "get_ (post_type) _meta" en realidad se llama "get_ (meta-type) _metadata", donde meta-type es post, comment o user. Entonces get_post_meta () pasará por el filtro get_post_metadata, independientemente del tipo de publicación. El valor de retorno del filtro es lo que desea que sea el metavalor final.
Berend
get_ (meta-type) _metadata -> de hecho funciona con todos los tipos de publicación, y de hecho la función final que se visita es get_post_metadata. Sin embargo, el filtro funciona cuando lo usas.
unity100
2

Depende de lo que estés haciendo. La forma WP es usar las tablas existentes, ya que han sido diseñadas para ser lo suficientemente flexibles, sin embargo, ocasionalmente alcanzará una nueva clase de datos que no se pueden colocar en una tabla existente, por ejemplo, si desea metadatos de categoría , puede optar por crear una tabla wp_termsmeta.

Sin embargo, generalmente puede almacenar sus datos con bastante comodidad en las diferentes tablas que existen, y el lugar donde almacena sus datos depende de lo que haga su complemento.

  • Para la configuración general del complemento, use la llamada a la API get_option () ; esto también se almacenará en caché.
  • Para configuraciones de complementos que sean particulares para una publicación individual, use los metadatos personalizados por publicación con get_post_meta () . Esto suele ser suficiente para lo que necesita.

El almacenamiento en caché se implementa dentro de WordPress para acelerar su tiempo de respuesta también.

Dan Smart
fuente
1

de acuerdo con denis 100%. Pero hay una forma de evitarlo.

El problema con el uso de la meta meta para los valores a consultar es cuando los valores son matrices, etc., como este:

array(
'key1' => 'val 1',
'key2' => 'val 2'
);

Esto se almacena en la base de datos como una cadena serializada, que se verá así:

{array["key1"]...{}...}

Entonces, cuando desee consultar todas las publicaciones con array['key2'] = 'val 2'wp, debe extraer cada entrada meta llamada matriz, descomprimirla, luego probarla y luego pasar a la siguiente. Esto definitivamente derribará su servidor si su sitio es exitoso y tiene muchas publicaciones, páginas, publicaciones personalizadas, etc.

La solución depende del proyecto, y verá por qué. Si var = valtuviera que almacenar los datos como wp, entonces podrá buscar sin tener php para desempaquetar cada prueba. Para hacer esto en el escenario anterior, usaría algunos espacios de nombres y almacenaría las meta claves:

_array_key1 = 'val 1';
_array_key2 = 'val 2';

entonces wp buscando la clave 2 con val 2 podrá sacarla de inmediato. Sin embargo, esto depende del proyecto. Mi proyecto actual se basa en unos 20 tipos de datos diferentes que se almacenarán con cada publicación personalizada, por lo que lo anterior solo crearía una tabla masiva para buscar, ya que esperamos cientos de miles de publicaciones. Entonces, en ese escenario, una tabla personalizada es la única forma.

Espero que esto ayude a alguien

Daithí
fuente
0

Para mi sitio FarmVille :) Hice ambas cosas pero nunca lo terminé porque lo vendí:

  1. Leí el xml farmville y volqué los datos en una tabla personalizada
  2. En WordPress, hice campos personalizados automáticamente para cada campo en esa tabla (y algunos adicionales)
  3. Ahora preocúpese por lo que sucede si un valor cambia en la tabla o en el otro lado: el campo personalizado, ya que deben estar continuamente sincronizados

Hice esto porque quería, por un lado, que los usuarios editaran el sitio de wordpress ingresando nuevos datos de farmville, por ejemplo, "una vaca cuesta 10 monedas" PERO desde el lado de la integración: SI un cambio en el XML, la vaca ahora cuesta "20 monedas" (a través del complemento de edición front-end) que se le daría como opción después: para que el XML O el usuario tuviera razón (una especie de sistema wiki).

Así que aquí hay un ejemplo al usar ambos.

Edelwater
fuente