Retour : Page Principale > sommaire aide > sommaire aide-mémos

Nettoyage des bases de données tb_cel et tb_del

Une collection de procédures pour nettoyer les tables dans différents cas.

À RÉÉCRIRE (2017) - cette page mĂ©rite d'ĂȘtre conservĂ©e, Ă  condition de la mettre Ă  jour


Supprimer les observations Pl@ntNet des non-inscrits


1. Compter ce qu'on peut supprimer


ATTENTION cette méthode retourne des faux-positifs, en raison de ce bug.

Compter les images éligibles
use tb_cel;
-- trouver les images telles que :
SELECT count(distinct ci.id_image) FROM cel_images ci
LEFT JOIN tb_del.del_observation do ON ci.ce_observation = do.id_observation
-- contient le mot-clé 'plantnet'
WHERE do.mots_cles_texte LIKE '%plantnet%'
-- a été postée par quelqu'un qui n'est pas inscrit à TB
AND do.ce_utilisateur = 0
-- n'a pas de proposition / commentaire
AND do.id_observation NOT IN (SELECT ce_observation FROM tb_del.del_commentaire)
-- n'a pas de vote, mĂȘme sur la proposition initiale
-- (traité au dessus, cf. matérialisation de la proposition initiale)
-- dont aucune des images n'a :
--     de vote sur aucun protocole
AND ci.id_image NOT IN (SELECT ce_image FROM tb_del.del_image_vote)
--     de tag
AND ci.id_image NOT IN (SELECT ce_image FROM tb_del.del_image_tag)
;


Compter les obs éligibles
use tb_cel;
-- trouver les obs telles que :
SELECT count(distinct co.id_observation) FROM cel_obs co
LEFT JOIN tb_del.del_image di ON di.ce_observation = co.id_observation
-- contient le mot-clé 'plantnet'
WHERE co.mots_cles_texte LIKE '%plantnet%'
AND co.transmission = 1
-- a été postée par quelqu'un qui n'est pas inscrit à TB
AND co.ce_utilisateur = 0
-- n'a pas de proposition / commentaire
AND co.id_observation NOT IN (SELECT ce_observation FROM tb_del.del_commentaire)
-- n'a pas de vote, mĂȘme sur la proposition initiale
-- (traité au dessus, cf. matérialisation de la proposition initiale)
-- dont aucune des images n'a :
--     de vote sur aucun protocole
AND di.id_image NOT IN (SELECT ce_image FROM tb_del.del_image_vote)
--     de tag
AND di.id_image NOT IN (SELECT ce_image FROM tb_del.del_image_tag)
;


2. Supprimer ce qu'on peut supprimer

On crée
ATTENTION les requĂȘtes de suppression en 2.2 peuvent ĂȘtre extrĂȘmement longues. De plus, si on les tue (KILL) avant qu'elles soient terminĂ©es, InnoDB fait un "rollback" qui prend encore plus de temps !
Si vous avez plus de 100 000 données à supprimer, il vaut mieux utiliser la méthode donnée en 2.3.

2.1 Stocker les IDs des données à supprimer

CREATE TABLE tmp_images_a_dezinguer (id integer primary key);

INSERT INTO tmp_images_a_dezinguer
SELECT distinct ci.id_image FROM cel_images ci
INNER JOIN tb_del.del_observation do ON ci.ce_observation = do.id_observation
WHERE do.mots_cles_texte LIKE '%plantnet%'
AND do.ce_utilisateur = 0
AND do.id_observation NOT IN (SELECT ce_observation FROM tb_del.del_commentaire)
AND ci.id_image NOT IN (SELECT ce_image FROM tb_del.del_image_vote)
AND ci.id_image NOT IN (SELECT ce_image FROM tb_del.del_image_tag);

CREATE TABLE tmp_obs_a_dezinguer (id integer primary key);

INSERT INTO tmp_obs_a_dezinguer
SELECT distinct co.id_observation FROM cel_obs co
INNER JOIN tb_del.del_image di ON di.ce_observation = co.id_observation
WHERE co.mots_cles_texte LIKE '%plantnet%'
AND co.transmission = 1
AND co.ce_utilisateur = 0
AND co.id_observation NOT IN (SELECT ce_observation FROM tb_del.del_commentaire)
AND di.id_image NOT IN (SELECT ce_image FROM tb_del.del_image_vote)
AND di.id_image NOT IN (SELECT ce_image FROM tb_del.del_image_tag);


2.2 Supprimer bourrinement - déconseillé !

SUPPRIMER les images éligibles
DELETE FROM cel_images WHERE id_image IN (SELECT id FROM tmp_images_a_dezinguer);


SUPPRIMER les obs éligibles
DELETE FROM cel_obs WHERE id_observation IN (SELECT id FROM tmp_obs_a_dezinguer);


2.3 Supprimer progressivement

Utiliser ce script
<?php
$db = new PDO('mysql:dbname=tb_cel;host=127.0.0.1;port=3306', 'apitela', 'bennes-y-donc-ton-mot-de-passe-la-bas-d-dans');

$req_ids_images = $db->query("SELECT id FROM tmp_images_a_dezinguer");
$ids_images = $req_ids_images->fetchAll(PDO::FETCH_COLUMN);
dezing_tranchette($ids_images, 'cel_images', 'id_image', 'images', 50000);

echo "\n";

$req_ids_obs = $db->query("SELECT id FROM tmp_obs_a_dezinguer");
$ids_obs = $req_ids_obs->fetchAll(PDO::FETCH_COLUMN);
dezing_tranchette($ids_obs, 'cel_obs', 'id_observation', 'observations', 50000);

echo "\n";
echo "À bientît sur nos lignes :)\n";

function dezing_tranchette(&$ids, $table, $colonne, $truc_qu_on_dezingue="machins", $taille_tranche=10000) {
    global $db;
    echo "NB " . $truc_qu_on_dezingue . " à dézinguer: " . count($ids) . "\n";
    while (!empty($ids)) {
        $tranche = array_slice($ids, 0, $taille_tranche);
        array_splice($ids, 0, $taille_tranche);
        echo "- tranche : " . count($tranche) . " IDs; " . $truc_qu_on_dezingue . " restant Ă  traiter : " . count($ids) . "\n";
        $ids_imploses = implode(',', $tranche);
        $req_del = "DELETE FROM $table WHERE $colonne IN(" . $ids_imploses . ")";
        echo "- dézingage de la tranche...\n";
        $db->query($req_del);
        echo "> tranche dézinguée !\n";
    }
}


3. Nettoyer les tables liées

Si le génie qui a conçu cette base avait mis des clés et des ON DELETE CASCADE comme quelqu'un de normal, on ne serait pas obligés de faire tout ça à la main !
-- champs étendus
DELETE FROM cel_obs_etendues WHERE id_observation NOT IN (SELECT id_observation FROM cel_obs);
-- mots-clés obs
DELETE FROM  cel_mots_cles_obs_liaison WHERE id_element_lie NOT IN (SELECT id_observation FROM cel_obs);
-- mots-clés images
DELETE FROM  cel_mots_cles_images_liaison WHERE id_element_lie NOT IN (SELECT id_image FROM cel_images);

Et tant qu'on y est, nettoyer les tables temporaires.
DROP TABLE tmp_images_a_dezinguer;
DROP TABLE tmp_obs_a_dezinguer;


Autres ?


  • champs rĂ©fĂ©rentiels : n'indiquer que le code du rĂ©fĂ©rentiel (ex: "bdtfx") et ne pas y adjoindre la version (ex: "bdtfx:1_01")
  • champs notes : supprimer les antislashes ("\") multiples
  • vĂ©rifier les types de colonnes et les index par rapport aux requĂȘtes posant problĂšme (pt_query_digest => slow_queries)
  • ... (y a des tas de choses Ă  voir !)