Chapitre 4.6 — La base de données & ses outils
⏱️ TL;DR — WordPress stocke tout son contenu dans une douzaine de tables MySQL. Les incontournables :
wp_posts(articles, pages, médias, révisions, CPT…),wp_postmeta(leurs métadonnées),wp_options(réglages du site),wp_users/wp_usermeta, et le trio des taxonomies (terms,term_taxonomy,term_relationships). Savoir explorer cette base avec phpMyAdmin/Adminer (ouwp db query) démystifie WordPress. On y reviendra en profondeur (côté code,$wpdb) en Partie 5.
🎯 Objectifs
- Connaître les tables clés et ce qu’elles contiennent.
- Comprendre le modèle objet + méta (posts/postmeta, users/usermeta…).
- Explorer la base avec un outil graphique et en CLI.
- Repérer les pièges (préfixe,
autoloaddes options).
1. Le schéma d’ensemble
Une installation standard compte ~12 tables (préfixées, wp_ par défaut) :
| Table | Contient |
|---|---|
wp_posts | Tous les contenus : articles, pages, médias (attachments), révisions, éléments de menu, et vos CPT. Une colonne post_type les distingue. |
wp_postmeta | Métadonnées clé/valeur rattachées à un post (post_id, meta_key, meta_value). |
wp_options | Réglages globaux du site (titre, URL, options de plugins/thèmes). |
wp_users / wp_usermeta | Comptes + leurs métadonnées (dont rôles/capabilities). |
wp_terms, wp_term_taxonomy, wp_term_relationships | Le système de taxonomies (catégories, étiquettes, taxonomies custom) et leur liaison aux contenus. |
wp_comments / wp_commentmeta | Commentaires. |
2. Le modèle « objet + table de méta »
Un schéma récurrent : un objet (post, user, comment, term) a une table principale + une table de métadonnées clé/valeur. Cela rend le modèle extensible sans migration : ajouter une donnée à un article, c’est insérer une ligne dans wp_postmeta (meta_key = 'prix', meta_value = '19.90'), pas modifier le schéma.
wp_posts (ID=42, post_title="T-shirt", post_type="product")
└── wp_postmeta (post_id=42, meta_key="_prix", meta_value="19.90")
wp_postmeta (post_id=42, meta_key="_stock", meta_value="12")💡 Pour un dev React — C’est un modèle EAV (Entity-Attribute-Value) : très flexible (on ajoute des champs sans toucher au schéma), au prix de la performance sur les requêtes complexes (jointures sur
meta). En développement, vous lirez/écrirez ces métadonnées via des fonctions dédiées —get_post_meta(),update_post_meta()(Partie 7) — sans SQL brut. C’est l’équivalent d’un « champ JSON extensible » attaché à chaque entité, mais stocké en lignes.
3. La table wp_options (et le piège autoload)
wp_options stocke les réglages sous forme clé/valeur (option_name, option_value, autoload). La colonne autoload est cruciale : les options en autoload = yes sont toutes chargées à chaque requête (en une seule requête, mises en cache mémoire).
⚠️ Piège — l’
autoloadqui gonfle. Des plugins mal écrits stockent de grosses données en option autoloadée, chargées à chaque page → mémoire et temps gaspillés. Unwp_optionsde plusieurs Mo autoloadés est une cause classique de lenteur. On l’audite (wp option list --autoload=on --format=count, requêtes sur la taille) en Partie 11. Retenez : une option volumineuse ou rarement lue ne doit pas être autoloadée.
4. Explorer la base
- Outils graphiques : phpMyAdmin, Adminer (souvent fourni par l’env local), ou un client SQL (TablePlus, DBeaver). On y parcourt les tables, on lance des requêtes, on exporte.
- En CLI :
wp db query "SELECT ID, post_title FROM wp_posts WHERE post_type='page'", ouwp db clipour un shell MySQL.wp db exportpour un dump. - Quelques requêtes utiles :
-- Compter les contenus par type
SELECT post_type, COUNT(*) FROM wp_posts GROUP BY post_type;
-- Les options autoloadées les plus lourdes
SELECT option_name, LENGTH(option_value) AS taille
FROM wp_options WHERE autoload='yes' ORDER BY taille DESC LIMIT 10;⚠️ Piège — le préfixe. N’écrivez jamais
wp_en dur : le préfixe de tables peut différer d’un site à l’autre (wp_,wp_a1b2_…). En SQL brut d’exploration, c’est acceptable localement, mais dans du code vous utiliserez toujours$wpdb->posts,$wpdb->prefix(Partie 5), jamais un nom de table en dur.
5. Ne pas écrire de SQL brut… en général
Explorer la base à la main est formateur, mais en code, on passe par les API de WordPress (WP_Query, get_posts(), get_post_meta(), get_option() — Parties 5 et 7). Elles gèrent le préfixe, la sécurité (requêtes préparées), le cache et la compatibilité. Le SQL direct ($wpdb->get_results()) est réservé aux cas que les API ne couvrent pas — toujours préparé ($wpdb->prepare()), jamais concaténé (Partie 7 : sécurité).
✏️ Exercices
- Dans quelle table trouve-t-on un article, une page, une image et un produit WooCommerce ? Qu’est-ce qui les distingue ?
- Expliquez le modèle « objet + méta » et son avantage principal.
- Pourquoi une option volumineuse en
autoload=yespeut-elle ralentir tout le site ?
✅ Solution
- Tous dans
wp_posts; la colonnepost_typeles distingue (post,page,attachment,product). WordPress unifie les contenus dans une même table, typée parpost_type. - Un objet (post) a une table principale (
wp_posts) + une table de métadonnées clé/valeur (wp_postmeta). Avantage : on ajoute des données sans modifier le schéma (flexibilité, extensibilité). - Parce que toutes les options
autoload=yessont chargées à chaque requête ; une option volumineuse gonfle la mémoire et le temps de chaque page, même si elle n’est presque jamais utilisée.
🧠 Quiz de révision
1. Quelle table contient articles, pages, médias et CPT ?
wp_posts, la colonne post_type distinguant les types.
2. Où sont stockées les métadonnées d’un article ?
Dans wp_postmeta (paires clé/valeur reliées par post_id).
3. Quelles tables gèrent les taxonomies ?
wp_terms, wp_term_taxonomy et wp_term_relationships.
4. Que fait la colonne autoload de wp_options ?
Elle indique si l’option est chargée automatiquement à chaque requête ; mal utilisée, elle dégrade la performance.
5. En code, comment référence-t-on une table sans coder le préfixe en dur ?
Via $wpdb : $wpdb->posts, $wpdb->prefix, etc. (Partie 5).
Partie suivante : Partie 5 — Architecture du cœur de WordPress.