Comprendre la base de données WordPress
Tout ce qui se passe sur votre site WordPress est stocké dans une base de données MySQL (ou MariaDB). Vos articles, pages, commentaires, réglages, utilisateurs, et même la configuration de vos plugins — tout est là. Comprendre cette base vous permet de déboguer des problèmes, optimiser les performances, et effectuer des modifications en masse impossibles depuis le dashboard.
Les 12 tables WordPress par défaut
Une installation WordPress fraîche crée 12 tables (préfixe wp_ par défaut) :
Tables principales du contenu
- wp_posts : Contient TOUS les contenus — articles, pages, médias, révisions, menus, et les Custom Post Types. C’est la table la plus importante
- wp_postmeta : Métadonnées associées aux posts. Chaque champ personnalisé (custom field), chaque réglage de plugin par post est stocké ici en paires clé/valeur
- wp_terms : Les termes de taxonomie (noms des catégories, tags, et taxonomies custom)
- wp_term_taxonomy : Définit la taxonomie de chaque terme (est-ce une catégorie ? un tag ? une taxonomie custom ?)
- wp_term_relationships : Lie les posts à leurs termes (quel article est dans quelle catégorie)
Tables des utilisateurs
- wp_users : Les comptes utilisateurs (login, email, mot de passe hashé, date d’inscription)
- wp_usermeta : Métadonnées utilisateur (nom, prénom, rôle, préférences, données de plugins)
Tables système
- wp_options : TOUS les réglages du site — nom du site, URL, structure des permaliens, réglages de chaque plugin. C’est la table la plus consultée
- wp_comments : Les commentaires
- wp_commentmeta : Métadonnées des commentaires (votes, flags Akismet, etc.)
- wp_links : Ancienne fonctionnalité de blogroll, rarement utilisée aujourd’hui
Accéder à votre base de données
phpMyAdmin
L’outil le plus courant, disponible chez la plupart des hébergeurs :
- Connectez-vous à votre cPanel ou panel d’hébergement
- Cliquez « phpMyAdmin » dans la section Bases de données
- Sélectionnez votre base WordPress dans la colonne de gauche
WP-CLI
# Exécuter une requête SQL directement
wp db query "SELECT COUNT(*) FROM wp_posts WHERE post_status='publish'"
# Ouvrir un shell MySQL interactif
wp db cli
Adminer (alternative légère à phpMyAdmin)
Un seul fichier PHP de 400 Ko. Uploadez adminer.php à la racine de votre site, accédez-y via le navigateur, et connectez-vous avec les identifiants de wp-config.php. N’oubliez pas de le supprimer après utilisation (risque de sécurité).
La table wp_posts en détail
C’est la table la plus importante. Voici ses colonnes clés :
wp_posts
├── ID → Identifiant unique du post
├── post_author → ID de l'auteur (lié à wp_users)
├── post_date → Date de publication
├── post_content → Le contenu complet (HTML)
├── post_title → Le titre
├── post_excerpt → L'extrait
├── post_status → publish, draft, pending, trash, private
├── post_type → post, page, attachment, revision, nav_menu_item, ou CPT
├── post_name → Le slug (URL)
├── post_parent → ID du parent (pour les pages enfants, révisions)
├── menu_order → Ordre d'affichage (pages)
└── guid → URL permanente unique
Requêtes utiles sur wp_posts
-- Compter les articles publiés par type
SELECT post_type, COUNT(*) as total
FROM wp_posts
WHERE post_status = 'publish'
GROUP BY post_type
ORDER BY total DESC;
-- Trouver les articles les plus anciens jamais modifiés
SELECT ID, post_title, post_date, post_modified
FROM wp_posts
WHERE post_type = 'post' AND post_status = 'publish'
ORDER BY post_modified ASC
LIMIT 10;
-- Compter les révisions (souvent très nombreuses)
SELECT COUNT(*) FROM wp_posts WHERE post_type = 'revision';
La table wp_options en détail
Cette table contient les réglages du site et des plugins. Structure simple :
wp_options
├── option_id → ID auto-incrémenté
├── option_name → Nom unique du réglage
├── option_value → Valeur (peut être sérialisée pour les tableaux/objets)
└── autoload → 'yes' ou 'no' (chargé automatiquement à chaque page ?)
Options importantes
-- URL du site (NE MODIFIEZ PAS directement sans savoir ce que vous faites)
SELECT option_value FROM wp_options WHERE option_name = 'siteurl';
SELECT option_value FROM wp_options WHERE option_name = 'home';
-- Nom et description du site
SELECT option_value FROM wp_options WHERE option_name = 'blogname';
SELECT option_value FROM wp_options WHERE option_name = 'blogdescription';
-- Structure des permaliens
SELECT option_value FROM wp_options WHERE option_name = 'permalink_structure';
-- Thème actif
SELECT option_value FROM wp_options WHERE option_name = 'template';
SELECT option_value FROM wp_options WHERE option_name = 'stylesheet';
-- Plugins actifs (données sérialisées)
SELECT option_value FROM wp_options WHERE option_name = 'active_plugins';
Problème de performance : l’autoload
Toutes les options avec autoload='yes' sont chargées en mémoire à CHAQUE page vue. Les plugins mal codés ajoutent des centaines d’options en autoload, ralentissant le site.
-- Voir la taille totale des options autoloadées
SELECT SUM(LENGTH(option_value)) / 1024 / 1024 AS taille_mo
FROM wp_options
WHERE autoload = 'yes';
-- Si > 1 Mo, c'est trop. Trouvez les coupables :
SELECT option_name, LENGTH(option_value) / 1024 AS taille_ko
FROM wp_options
WHERE autoload = 'yes'
ORDER BY LENGTH(option_value) DESC
LIMIT 20;
-- Désactiver l'autoload d'une option non critique
UPDATE wp_options SET autoload = 'no' WHERE option_name = 'option_volumineuse';
La table wp_postmeta
Stocke les métadonnées des posts en paires clé/valeur :
wp_postmeta
├── meta_id → ID unique
├── post_id → Lié à wp_posts.ID
├── meta_key → Nom de la métadonnée
└── meta_value → Valeur
Exemples de meta courantes
_thumbnail_id: ID de l’image mise en avant_edit_lock: Verrou d’édition (qui édite actuellement)_wp_page_template: Template de page utilisé_yoast_wpseo_title: Titre SEO (Yoast)_price,_stock: Données WooCommerce
Les meta préfixées par _ (underscore) sont « protégées » — elles n’apparaissent pas dans l’éditeur de champs personnalisés par défaut.
Optimiser votre base de données
1. Supprimer les révisions
WordPress stocke chaque sauvegarde de brouillon comme une révision. Un article modifié 50 fois a 50 révisions dans wp_posts + 50 entrées de métadonnées dans wp_postmeta.
-- Compter les révisions
SELECT COUNT(*) FROM wp_posts WHERE post_type = 'revision';
-- Supprimer TOUTES les révisions
DELETE FROM wp_posts WHERE post_type = 'revision';
-- Limiter les révisions futures (dans wp-config.php)
define('WP_POST_REVISIONS', 3); // Garder seulement 3 révisions
-- ou
define('WP_POST_REVISIONS', false); // Désactiver complètement
2. Supprimer les transients expirés
Les transients sont des caches temporaires stockés dans wp_options. Ils s’accumulent :
-- Compter les transients
SELECT COUNT(*) FROM wp_options WHERE option_name LIKE '%_transient_%';
-- Supprimer les transients expirés (via WP-CLI, plus sûr)
-- wp transient delete --expired
3. Supprimer les meta orphelines
-- Métadonnées de posts qui n'existent plus
DELETE pm FROM wp_postmeta pm
LEFT JOIN wp_posts p ON pm.post_id = p.ID
WHERE p.ID IS NULL;
-- Métadonnées de commentaires orphelines
DELETE cm FROM wp_commentmeta cm
LEFT JOIN wp_comments c ON cm.comment_id = c.comment_ID
WHERE c.comment_ID IS NULL;
4. Optimiser les tables
-- Optimiser toutes les tables (récupère l'espace des lignes supprimées)
-- Via WP-CLI :
-- wp db optimize
-- Via SQL :
OPTIMIZE TABLE wp_posts, wp_postmeta, wp_options, wp_comments;
Plugin recommandé : WP-Optimize
Si vous n’êtes pas à l’aise avec SQL, le plugin WP-Optimize (gratuit) fait tout cela en quelques clics :
- Supprime les révisions, brouillons auto, trash
- Supprime les commentaires spam et trash
- Supprime les transients expirés
- Optimise les tables
- Planifie le nettoyage automatique (hebdomadaire recommandé)
Sauvegarder votre base de données
Avec WP-CLI
# Sauvegarde complète
wp db export backup-$(date +%Y%m%d).sql
# Sauvegarde compressée
wp db export - | gzip > backup-$(date +%Y%m%d).sql.gz
Avec phpMyAdmin
- Sélectionnez votre base
- Onglet « Exporter »
- Méthode : « Personnalisé » → Format : SQL
- Cochez « Ajouter CREATE TABLE / DROP TABLE »
- Cliquez « Exécuter »
Plugin : UpdraftPlus
Pour des sauvegardes automatiques :
- Installez UpdraftPlus (gratuit)
- Configurez : sauvegarde automatique hebdomadaire
- Destination : Google Drive, Dropbox, ou email
- Il sauvegarde la base ET les fichiers (uploads, thèmes, plugins)
Sécurité de la base de données
Changer le préfixe de table
Le préfixe par défaut wp_ est connu de tous les attaquants. Sur une nouvelle installation, changez-le dans wp-config.php AVANT l’installation :
$table_prefix = 'itsc_'; // Préfixe personnalisé
Sur un site existant, c’est plus complexe — il faut renommer toutes les tables et modifier les références dans wp_options et wp_usermeta. Utilisez un plugin comme « Brozzme DB Prefix » pour le faire en sécurité.
Protéger wp-config.php
Ce fichier contient vos identifiants de base de données en clair. Protégez-le :
# Dans .htaccess
<files wp-config.php>
order allow,deny
deny from all
</files>
Limiter l’accès à phpMyAdmin
Si phpMyAdmin est accessible publiquement, un attaquant qui trouve vos identifiants a accès à toute votre base. Protégez-le par :
- Restriction IP dans .htaccess
- Authentification HTTP supplémentaire (double mot de passe)
- Ou simplement utilisez WP-CLI via SSH au lieu de phpMyAdmin
Requêtes SQL utiles au quotidien
-- Changer l'URL du site (migration)
UPDATE wp_options SET option_value = 'https://nouveau.com' WHERE option_name = 'siteurl';
UPDATE wp_options SET option_value = 'https://nouveau.com' WHERE option_name = 'home';
-- ATTENTION : utilisez plutôt wp search-replace qui gère les données sérialisées
-- Réinitialiser le mot de passe admin
UPDATE wp_users SET user_pass = MD5('nouveau_mot_de_passe') WHERE user_login = 'admin';
-- Trouver et remplacer dans le contenu
UPDATE wp_posts SET post_content = REPLACE(post_content, 'ancien-texte', 'nouveau-texte')
WHERE post_content LIKE '%ancien-texte%';
-- Fermer les commentaires sur tous les articles
UPDATE wp_posts SET comment_status = 'closed' WHERE post_type = 'post';
-- Trouver les articles sans image mise en avant
SELECT p.ID, p.post_title
FROM wp_posts p
LEFT JOIN wp_postmeta pm ON p.ID = pm.post_id AND pm.meta_key = '_thumbnail_id'
WHERE p.post_type = 'post' AND p.post_status = 'publish' AND pm.meta_value IS NULL;
Règle d’or : toujours sauvegarder avant
Avant TOUTE modification directe de la base de données, faites un export. Une mauvaise requête SQL peut casser votre site en une seconde — et contrairement à un fichier, il n’y a pas de Ctrl+Z. Exportez d’abord, modifiez ensuite, vérifiez, et gardez la sauvegarde pendant au moins une semaine.