web-dev-qa-db-fra.com

Construire un plugin favoris Wordpress évolutif - un tableau de méta-valeurs sérialisées ou plusieurs méta-enregistrements

J'essaie de créer un plug-in de publication favori favori de Wordpress, qui soit évolutif et puisse gérer des milliers d'utilisateurs ou plus de 10000 utilisateurs.

J'ai observé différentes approches dans d'autres plugins et j'aimerais savoir quelle serait la meilleure pratique du point de vue de l'évolutivité, ce qui signifie que la taille de l'enregistrement ou le nombre d'enregistrements pourrait poser problème.

Problème: l’idée de base est qu’il existe un bouton sur un message sur lequel un utilisateur connecté peut cliquer pour le mettre en favori. Celui-ci doit ensuite être stocké dans la base de données de sorte que, lorsque l'utilisateur accède à ce message, il ne puisse plus le mettre en favori et il peut également afficher une liste de ses messages favoris.

Option 1: Stocker à la fois les méta-tables utilisateur et posta avec des tableaux sérialisés

C’est ce que fait le système de post de type Wordpress ( https://hofmannsven.com/2013/laboratory/wordpress-post-like-system/ ). Après le clic, le code récupère la clé méta _liked_posts de la table méta utilisateur qui stocke dans un tableau les ID de publication des publications que l'utilisateur a aimées et récupère la clé méta _user_likes de la table méta post qui stocke dans un tableau l'utilisateur identifiants des utilisateurs qui ont aimé le post.

Le code ajoute ensuite l'id de la publication actuelle aux _liked_posts et l'id de l'utilisateur actuel à _user_likes. Il incrémente également deux autres méta-enregistrements: post like like et un utilisateur like count.

Ce que j’aime dans ce système, c’est qu’il semble assez simple, avec un seul enregistrement dans la méta utilisateur et un autre dans le stockage post-méta qui a aimé quoi. Ce que je n’aime pas, c’est que si vous avez beaucoup d’utilisateurs qui aiment la publication ou un utilisateur qui aime beaucoup de publications, ces tableaux de méta-valeurs peuvent être très longs, ce qui, je suppose, pourrait causer des problèmes?

$meta_POSTS = get_user_meta( $user_id, "_liked_posts" ); // post ids from user meta
$meta_USERS = get_post_meta( $post_id, "_user_liked" ); // user ids from post meta
$meta_POSTS['post-'.$post_id] = $post_id; // Add post id to user meta array
$meta_USERS['user-'.$user_id] = $user_id; // add user id to post meta array
update_post_meta( $post_id, "_user_liked", $meta_USERS ); // Add user ID to post meta
update_user_meta( $user_id, "_liked_posts", $meta_POSTS ); // Add post ID to user meta

Option 2: Ajouter un enregistrement à la méta de l'utilisateur pour chaque publication préférée

Après le clic, le code vérifie si un enregistrement a déjà été inséré dans la méta de l'utilisateur. Sinon, il ajoute un nouvel enregistrement du favori. Si c'est le cas, cela ne fait rien.

Ce que j’aime dans ce système, c’est qu’il est facile d’interroger et de générer des statistiques car il n’est pas encombré de tableaux sérialisés. Ce que je n’aime pas, c’est que si l’utilisateur aime beaucoup de publications, il est possible d’augmenter considérablement le nombre d’enregistrements dans la table meta.

// Check if already favourited the post in User Meta
// Not sure how you would do this with WP_Query or WP_User_Query, any suggestions?

$favourited = WP_Query($args)

if ($favourited->post_count == 0) {
  // Add user meta with favourite
  add_user_meta($userid, '_favourite_episode', $postid);
}

Donc, pour conclure, je demande essentiellement quelle est la meilleure pratique dans ce domaine. Est-ce soit:

  • Avoir un grand tableau sérialisé dans une seule paire méta clé/valeur
  • Avoir beaucoup de paires méta/valeur de clé avec un entier dans la méta valeur
  • Y a-t-il une autre option que je n'ai pas envisagée?

EDIT: Suite aux réponses données, j'ai décidé que la création d'un tableau personnalisé était la meilleure voie à suivre. J'ai trouvé ce tutoriel qui fait à peu près ce que je veux faire et d'une manière beaucoup plus extensible afin que je puisse ajouter d'autres actions ainsi que simplement "favoriser".

http://code.tutsplus.com/series/custom-database-tables--wp-33839

3
Alex

Vous avez oublié l'option 3 - Ajoutez une table spéciale dans laquelle la paire (utilisateur, identifiant de publication) sera l'index. Ok Je ne suis pas un utilisateur de MySQL, donc c'est peut-être trop extrême, mais peut-être qu'avoir deux tables, l'une avec les utilisateurs comme index et l'autre avec les publications, sera encore meilleur.

Le problème des performances est qu’il existe rarement des solutions absolues pour tout le monde, à tout moment, et que la "meilleure" dépend de votre modèle d’utilisation, et non du modèle théorique. Ou en d'autres termes, vous faites une optimisation précoce ici.

Bien que l’option 2 semble plus rapide pour cette information spécifique, elle augmentera la taille des méta-tables et ralentira donc toutes les requêtes vers ces tables (à cet effet). la suggestion pour l’option 3 qui est très similaire mais n’affecte pas les autres requêtes).

Un autre problème que vous ignorez ici est le coût de l'insertion/mise à jour des données. Cette opération est beaucoup plus lente qu'une lecture et ne peut pas être mise en cache. Si vous allez avoir plusieurs goûts en même temps, avec l'option 2, vous verrouillez les tables et les demandes doivent attendre que les autres soient terminées et chaque insertion sera plus lente, tandis que l'option 1 risque de corrompre les données avec une implémentation naïve. (deux changements en même temps, au mieux un seul aura un impact).

Ensuite, vous devez prendre en compte le type de mise en cache que vous allez faire. Avec un bon schéma de mise en cache, le temps de lecture n’est pas un problème.

Pour conclure, je souhaite que vous constatiez qu'il s'agit d'un problème réel qui doit être résolu, en attendant, écrivez simplement la bonne API pour accéder/modifier les données afin de masquer les détails de la mise en œuvre. Si cela devenait un problème, vous pourrez le modifier. la mise en œuvre sans impact sur le reste de votre code.

3
Mark Kaplun

Option 1 n'est pas le meilleur choix car la sérialisation des données signifie que vous devez analyser votre résultat SQL pour qu'il soit lisible. Par conséquent, vous ne pouvez tirer aucun avantage des requêtes SQL.

Option 2 serait le moyen le plus simple, mais si vous avez beaucoup d’utilisateurs qui aiment beaucoup de publications, cela commence à polluer la table méta des utilisateurs.

Option 3 Ce que je ferais, c’est de créer une table relationnelle entre les publications et les utilisateurs. Utiliser la table de relation serait la solution la plus simple car vous pouvez utiliser SQL pour effectuer beaucoup de logique à votre place. Par exemple, vous n'avez pas besoin de compter le nombre de mentions de J'aime dans une publication dans PHP, mais d'exécuter une requête sur SQL qui le fait pour vous et renvoie le résultat. Cela signifie que les performances seront bonnes et que si vous désinstallez le plug-in, il ne vous reste plus qu'à supprimer le tableau, simplement et proprement.

0
Marttin Notta