Post meta vs tables de base de données séparées

25

Lors du développement de plug-ins nécessitant un stockage de données, quels sont les avantages et les inconvénients d'utiliser une méthode ou une autre?

L'explication fournie dans le codex n'est pas détaillée:

  

Avant de sauter avec un tout nouveau   table, cependant, envisager si le stockage   les données de votre plugin dans WordPress 'Post   Meta (a.k.a. Champs personnalisés) serait   travail. Post Meta est le préféré   méthode; l'utiliser quand   possible / pratique.

    
posée Nassif Bourguig 03.12.2010 - 20:04

5 réponses

26

Bien, si je prends le chapeau d'un script WP kiddie, ma réponse serait: utilisez post_meta, toujours.

Cependant, je sais quelque chose au sujet des bases de données, ma réponse est: n'utilisez jamais, jamais, jamais, un EAV (ou table post_meta) pour stocker des données que vous pourriez avoir besoin d'interroger.

En ce qui concerne les index, il n’en est pratiquement aucun intérêt à en utiliser dans les méta-tables. Donc, si vous stockez le type de données XYZ et espérez que vous interrogez toutes les publications qui ont XYZ avec une valeur de 'abc' , eh bien ... bonne chance. (Voir tous les billets relatifs aux utilisateurs / rôles / majuscules dans le WP trac pour vous donner une idée de son horreur.)

Sur le plan de la jointure, vous écrasez rapidement la limite à laquelle l'optimiseur décide d'utiliser un algorithme générique au lieu d'analyser la requête lorsqu'il existe plusieurs critères de jointure.

Ainsi, non, non, non, non. Ne jamais, jamais, jamais utiliser un méta. Sauf si ce que vous stockez est esthétique et ne fera jamais partie d'un critère de requête.

Cela se décompose en votre application. Si vous enregistrez, par exemple, la date de naissance d'un directeur de film, ce n'est pas grave. Utilisez une méta tout ce que vous voulez. Mais si vous stockez, par exemple, la date de sortie d'un film, vous auriez tort de ne pas utiliser une table séparée (ou d'ajouter des colonnes à la table des publications) et d'ajouter un index à cette colonne.

    
réponse donnée Denis de Bernardy 03.12.2010 - 22:13
3

Si votre plugin doit contenir BEAUCOUP de données, utiliser wp_postmeta n'est PAS une bonne idée, comme illustré ci-dessous:

En prenant Woocommerce comme exemple,

Dans un magasin avec environ 30 000 produits, supposons qu’il y aura en moyenne environ 40 post-méta (attributs et tout) par produit, 5 images de produit par produit, ce qui signifie qu’il y aura environ 4 méta-image pour chaque image:

30 000 produits x 40 méta chacun = 1 200 000 lignes dans wp_postmeta

+

30 000 produits x 5 images chacun x 4 méta d'image pour chacun = 600 000 lignes dans wp_postmeta

Ainsi, avec seulement 30 000 produits, vous envisagez de créer 1 800 000 lignes dans wp_postmeta.

Si vous ajoutez d'autres propriétés à vos produits ou à vos images de produit, ce nombre se multipliera.

Le problème est double:

  • Les jointures sont très chères avec MySQL
  • La table wp_postmeta n'est pas indexée sauf si vous utilisez des versions ultérieures de mysql (c'est-à-dire pas d'index FULLTEXT pour meta_value)

Pour donner un exemple tiré d'un cas réel:

SELECT meta_value FROM wp_postmeta WHERE meta_key LIKE '_shipping_city'

La

requête, qui sélectionne la ville d'expédition parmi tous les détails de la commande , prend environ 3 secondes sur un serveur d'entrée de gamme même s'il y a 5 à 10 commandes . En effet, la requête est exécutée à partir d’une table wp_postmeta contenant environ 3 millions de lignes dans une installation dynamique.

Même la page d’accueil est assez lente, car le thème tire divers éléments de wp_postmeta - curseurs, quelques encarts de revue, quelques autres méta. En général, la liste de produits est très lente, de même que les recherches lorsque vous répertoriez des produits.

Vous ne pouvez pas résoudre ce problème par aucun moyen normal. Vous pouvez mettre Elastic Search sur votre serveur et utiliser un plugin Elastic Search dans Wordpress, vous pouvez utiliser redis / memcached, vous pouvez utiliser un bon plugin de cache de page, mais à la fin, le problème fondamental restera - extraire toute quantité de données à partir d'une mémoire gonflée. La table wp_postmeta sera lente chaque fois que cela sera fait. Sur le serveur où j’ai testé la solution mise en œuvre ci-dessous, toutes ces applications ont été installées, configurées correctement et optimisées, et le site a fonctionné de manière satisfaisante pour les utilisateurs non connectés ou les requêtes fréquemment effectuées depuis l’installation des plugins de mise en cache.

Mais au moment où un utilisateur connecté essaie de faire quelque chose d’inhabituel ou que les plugins, caches, plugins ou tout autre utilitaire veulent extraire les données réelles de la base de données pour les mettre en cache ou faire autre chose, les choses se compliquent. / p>

J'ai donc essayé autre chose:

J'ai codé un petit plugin pour transférer toutes les méta du produit (postmeta pour le type de produit post) dans une table personnalisée générée par le code. Ce plugin a pris toutes les méta pour chaque publication et a créé une table en ajoutant chaque méta sous forme de colonnes et en insérant les valeurs dans chaque ligne. J'ai donc transformé le format EAV en un format relationnel horizontal et plat. J'ai également eu le plugin pour supprimer postmeta de tous les produits déplacés de la table wp_postmeta.

Pendant ce temps, j'ai également déplacé l'attachement postmeta et la méta de tous les autres types de post sur leurs propres tables.

Ensuite, je me suis connecté au filtre get_ (post_type) _meta pour remplacer la récupération des métadonnées afin de les servir à partir de nouvelles tables personnalisées.

Maintenant, la même requête que précédemment, qui nécessitait environ 3 secondes pour extraire de wp_postmeta, prend environ 0,006 seconde. Le site se comporte désormais comme s’il s’agissait d’une nouvelle installation de WP.

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

Naturellement, faire les choses à la manière Wordpress est préférable. C’est la norme.

Toutefois , il est également évident que la table EAV est très inefficace en termes de mise à l'échelle. Il est infiniment flexible et vous permet de stocker toutes les données, mais le prix que vous payez pour cela est la performance. C'est un compromis fondamental.

Dans ce contexte, il est difficile de dire à quelqu'un qui a l'intention de disposer de beaucoup de données et - ce qui est interdit - d'interroger / rechercher ces données pour utiliser la table wp_postmeta à coup sûr. La performance sera grande.

L'utilisation de vos tableaux personnalisés permettra à vos données de s'accumuler tout en restant suffisamment rapides.

Comme Pippin Williams, le créateur du plug-in Easy Digital Downloads, a mentionné qu'il utiliserait des tables personnalisées s'il commençait tout juste à coder son plug-in, si vous allez créer quelque chose qui sera utilisé pendant une longue période ou qui s'accumulera beaucoup. de données, il est plus efficace d’utiliser vos tables personnalisées si vous les concevez bien.

Vous devez vous assurer que tout autre développeur de plug-in / addon a le moyen de se connecter à votre plug-in pour manipuler vos données avant et après la récupération des données. Si vous faites cela, alors vous êtes assez solide.

    
réponse donnée unity100 20.02.2017 - 10:55
2

Cela dépend de ce que vous faites. La méthode WP consiste à utiliser les tables existantes, car elles ont été conçues pour être suffisamment souples. Cependant, vous atteignez parfois une nouvelle classe de données qui ne peut pas être placée dans une table existante, par exemple. si vous voulez des métadonnées de catégorie, vous pouvez choisir de créer une table wp_termsmeta.

Cependant, vous pouvez généralement stocker vos données assez facilement dans les différentes tables existantes. Le lieu où vous stockez vos données dépend de ce que fait votre plug-in.

  • Pour les paramètres généraux du plug-in, utilisez l’appel get_option () - il sera également mis en cache.
  • Pour les paramètres de plug-in qui correspondent à une publication particulière, utilisez les métadonnées personnalisées pour chaque publication avec get_post_meta () . . C’est généralement suffisant pour ce dont vous avez besoin.

La mise en cache est implémentée dans WordPress pour accélérer également le temps de réponse.

    
réponse donnée Dan Smart 03.12.2010 - 22:21
1

d'accord avec denis 100%. Mais il y a un moyen de le contourner.

Le problème lié à l'utilisation de la méta de publication pour les valeurs à interroger est lié au fait que les valeurs sont celles d'un tableau, par exemple:

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

Ceci est stocké dans la base de données en tant que chaîne sérialisée, qui ressemble à ceci:

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

Ainsi, lorsque vous souhaitez interroger toutes les publications avec array['key2'] = 'val 2' , wp doit extraire chaque méta entrée appelée array, la décompresser, la tester, puis passer à la suivante. Cela supprimera définitivement votre serveur si votre site est performant et contient de nombreux messages, pages, messages personnalisés, etc.

La solution dépend du projet et vous verrez pourquoi. Si vous deviez stocker les données sous forme de var = val , alors wp sera en mesure d'effectuer une recherche sans que PHP ait à décompresser chaque test. Pour ce faire, dans le scénario ci-dessus, utilisez un espacement de nom et stockez les clés méta:

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

alors wp recherchant la clé 2 avec val 2 pourra la tirer tout de suite. Ce projet dépend cependant. Mon projet actuel repose sur environ 20 types de données différents à stocker avec chaque poste personnalisé, de sorte que ce qui précède ne fait que créer un énorme tableau dans lequel effectuer des recherches, vu que nous attendons des centaines de milliers de messages. Donc, dans ce scénario, une table personnalisée est le seul moyen.

J'espère que cela aide quelqu'un

    
réponse donnée Daithí 03.12.2011 - 12:25
0

Pour mon site FarmVille :) J'ai fait les deux mais je ne l'ai jamais fini car je l'ai vendu:

  1. J'ai lu le fichier Farmville xml et vidé les données dans un tableau personnalisé
  2. Dans WordPress, des champs personnalisés étaient automatiquement créés pour chaque champ de cette table (et quelques-uns de plus)
  3. Maintenant, ne vous inquiétez pas de ce qui se passe si une valeur change dans la table ou de l'autre côté: dans le champ personnalisé, car elles doivent être synchronisées en permanence

Je l’ai fait parce que je voulais, d’une part, faire modifier le site wordpress par les utilisateurs en saisissant de nouvelles données de farmville, par exemple. "une vache coûte 10 pièces" MAIS du côté de l'intégration: SI un changement dans le xml ment, la vache coûte maintenant "20 pièces" (via le plug-in d'édition front-end) qui serait donné en option après celle-ci: XML OU l’utilisateur avait raison (sorte de système wiki).

Voici donc un exemple d'utilisation des deux.

    
réponse donnée edelwater 04.12.2010 - 17:58

Lire d'autres questions sur les étiquettes