Partage
  • Partager sur Facebook
  • Partager sur Twitter

Supprimer des doublons dans une SQL

Les doublons relatifs de la table postmeta de Wordpress

16 octobre 2018 à 20:57:42

Bonjour à tous,

J'ai actuellement une table wpfrv3_postmeta qui pèse plus de 1Go

Elle contient beaucoup de doublons comme sur l'image ci-jointe :

J'ai tenté la requête suivante, mais MySQL a retourné un résultat vide.

SELECT * FROM wpfrv3_postmeta
WHERE EXISTS (
              SELECT *
              FROM wpfrv3_postmeta
              WHERE meta_id <> meta_id
              AND   post_id = post_id
              AND   meta_key = meta_key
              AND   meta_value = meta_value )

Je voulais votre avis, et comprendre mon erreur

Merci

  • Partager sur Facebook
  • Partager sur Twitter
16 octobre 2018 à 23:07:01

Bonjour,

Dans la sous requête tu compares les données de chaque enregistrement à lui même...

Meta_id n'est donc jamais different ...

Il faut utiliser des alias idéalement avec une auto jointure. 

  • Partager sur Facebook
  • Partager sur Twitter
Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
16 octobre 2018 à 23:45:28

Hello,

Merci du coup de main, du coup j'utilise :

SELECT DISTINCT *
FROM   wpfrv3_postmeta T1
WHERE  EXISTS (SELECT *
               FROM   wpfrv3_postmeta T2
               WHERE  T1.`meta_id` <> T2.`meta_id`
                 AND  T1.`post_id`    = T2.`post_id`
                 AND  T1.`meta_key` = T2.`meta_key`
                 AND  T1.`meta_value` = T2.`meta_value`)

source : lien

ce qui me retourne 36 000 lignes environ : parfait :)

Maintenant le DELETE ....

  • Partager sur Facebook
  • Partager sur Twitter
17 octobre 2018 à 8:25:16

Je mettrai un < plutôt que <> ... pour éviter les doublons de doublon ...
  • Partager sur Facebook
  • Partager sur Twitter
Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
17 octobre 2018 à 17:42:22

Encore une victime de la non normalisation :(

Pour bien faire les chose,s il faudrait deux tables :

- une table avec la liste des metakey

CREATE TABLE METAKEY (
  ID INTEGER PRIMARY KEY, -- AUTO_INCREMENT,
  KEY CHARACETER VARYING(64) UNIQUE
);

- Et la table avec les valeurs, qui n'est en fait rien d'autre qu'une table de jointure entre les post et les metakey

CREATE TABLE POSTMETA (
  POST_ID INTEGER NOT NULL,
  META_ID INTEGER NOT NULL,
  VALUE TEXT NOT NULL,
  PRIMARY KEY(ID_POST, ID_META),
  FOREIGN KEY(POST_ID) REFERENCES post(id),
  FOREIGN KEY(META_ID) REFERENCES METAKEY(ID)
);



Ensuite, il suffit de remplir ces tables avec les données issues de ta table actuelle (avec ta table ne sélectionnant pas les doublons).

Enfin, on DROP carrément l'ancienne table :p Ca facilite vraiment le DELETE ;)

Et pour rester compatible avec le code applicatif existant, il suffit de créer une VUE qui va reprendre les colonnes de ta table actuelle

CREATE VIEW wpfrv3_postmeta AS
SELECT POST_ID as post_id, KEY as meta_key, VALUE as meta_value
FROM POSTMETA
  INNER JOIN METAKEY
    ON METAKEY.ID = POSTMETA.META_ID;


On pourra aussi rajouter des trigger sur les actions INSERT / UPDATE et DELETE de la vue pour effectuer les vraies opérations (avec INSTEAD OF) sur les vraies tables.


  • Partager sur Facebook
  • Partager sur Twitter
17 octobre 2018 à 18:02:46

Sebajuste a écrit:

Encore une victime de la non normalisation :(

Ah ... sacré WordPress ... On ne change pas une équipe qui gagne ...

Sebajuste a écrit:

pour effectuer les vraies opérations (avec INSTEAD OF) sur les vraies tables.

Et non ... pas de INSTEAD OF avec MySQL ... pas taper pas taper ...

Sebajuste a écrit:

une table avec la liste des metakey

Ce n'est pas possible dans le contexte WordPress, car les meta_key sont variables et peuvent être créées par de multiples biais non maîtrisés ... cool !

Cela dit un changement de modèle serait bienvenu sur ce CMS ...

Enfin, pour ton problème, je te propose :

DELETE M2
FROM
	wpfrv3_postmeta M1
		INNER JOIN wpfrv3_postmeta M2
			ON M1.`meta_id` < M2.`meta_id`
			AND M1.`post_id` = M2.`post_id`
			AND M1.`meta_key` = M2.`meta_key`
			AND M1.`meta_value` = M2.`meta_value`

Bien évidemment fais un dump de ta table avant de faire quoi que ce soit ... Avec plusieurs millions de lignes cela peut prendre en certain temps en plus ... pour faire le dump, et pour exécuter le DELETE ...

Par ailleurs ce script ne supprime pas tous les doublons, car dans ce cas un doublon (comme souligné par Sebajuste) c'est un même couple meta_key et post_id. Si tu as pour le même post de fois la même meta_key mais avec des valeurs différentes, ce script n'y touchera pas ...

Enfin je me demande bien ce qui a pu induire un tel bordel dans ta base ... normalement il n'y a aucune raison pour une multiplication des meta_key ...



-
Edité par Benzouye 17 octobre 2018 à 18:06:06

  • Partager sur Facebook
  • Partager sur Twitter
Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
17 octobre 2018 à 21:56:35

Bonsoir,

Milles merci pour votre aide, j'ai compris maintenant :)

A l'origine de ce bordel ? une sale migration...

Mais bon, à savoir que le wp contient plus de 7 000 articles

D'ailleurs on me parle de PostgreSQL à la place de MySQL

Dois-je m'inquiéter maintenant ? :o

-
Edité par ArnaudMoine 17 octobre 2018 à 22:33:01

  • Partager sur Facebook
  • Partager sur Twitter
18 octobre 2018 à 9:46:32

A ce jour WordPress ne fonctionne qu'avec MySQL (et MariaDB bien sûr). Des projets de portabilité vers PostGreSQL existent, mais c'est un vrai sac de noeuds pour les développeurs tellement l'intrication avec MySQL est forte ... Je te déconseille de t'y aventurer ...

Par contre tu peux "bricoler" ta base de données pour améliorer la gestion de l'intégrité. Par exemple, pour reprendre le cas de ce sujet, en mettant :

  • une contrainte UNIQUE( meta_key, post_id ) sur la table wp_postmeta
  • une contrainte de clé étrangère sur post_id vers la table wp_posts

Cela pourra générer des erreurs applicatives non maîtrisées (puisque MySQL renverra des erreurs non prévues par WordPress), mais tu pourras assurer l'intégrité de ta base ...

Après, si ce "bordel" vient d'une "sale migration", alors prend le temps de nettoyer correctement la base. Les problèmes sont généralement sur les meta-données ( postmeta, commentmeta, usermeta ) et sur les révisions dans la table posts ...

  • Partager sur Facebook
  • Partager sur Twitter
Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
18 octobre 2018 à 11:47:18

oO

OMFG, C'est WordPress qui est aussi mal codé ??!! Je n'ai jamais travaillé avec ce CMS (ni avec aucun d'ailleurs ^^) mais ça fait vraiment peur....

Evidement, je ne recommande donc plus mes recommandations :p C'est le problème quand on ne maitrise pas l'applicatif, on en devient dépendant :(

Bon courage.

  • Partager sur Facebook
  • Partager sur Twitter