Dans cette série, nous examinerons l'utilisation de tables de base de données personnalisées. Nous verrons comment créer, maintenir et supprimer la table, ainsi que comment ajouter, supprimer et interroger des données en toute sécurité et efficacement. Dans ce premier article, nous examinons à quel moment les tableaux personnalisés peuvent être appropriés, les avantages et les inconvénients de leur utilisation et comment créer le tableau..
Heureusement, WordPress fournit une API assez importante qui simplifie un peu la création et l’interaction avec des tables personnalisées. Plus particulièrement: le $ wpdb
la classe et la dbDelta ()
fonction que nous verrons plus de au cours de la série. Malgré cela, toutefois, créer une table personnalisée signifie créer quelque chose d'extraordinaire à WordPress - et vous perdrez l'essentiel de la structure qui entoure les tables natives. Pour cette raison, en tant qu’auteur du plug-in, vous êtes responsable d’une interaction sûre et efficace avec ce dernier. Donc, avant de vous lancer, vous devez examiner avec soin s'il est plus approprié d'utiliser une table de base existante..
Comme mentionné précédemment, les tables personnalisées ne font pas partie du cadre normal de WordPress - et c’est en grande partie la cause sous-jacente de ses inconvénients:
Il n’ya pas de «bonne» réponse à cette question et un jugement sensé des avantages et des inconvénients est nécessaire. Cependant, la section précédente décrit certains inconvénients graves liés à la non-utilisation du schéma WordPress existant. En tant que tel, en cas de doute, il est généralement préférable d'éviter de créer un tableau. En outre, une approche de table personnalisée nécessite beaucoup de travail et offre aux bogues une bonne opportunité pour s’y glisser. Mais gardez cela à l’esprit, quand une table personnalisée pourrait-elle être appropriée??
L'un des arguments les plus importants pour les tables personnalisées est le moment où les données doivent être structurées de manière inappropriée pour les tables natives. le *_des postes
table est intrinsèquement orienté vers les publications et les pages, ce qui peut être totalement inapproprié pour vos données. En fait, il est préférable que vos données soient réparties sur plusieurs tables, avec des relations entre elles. Cela n’est peut-être même pas si compliqué: le plug-in Posts 2 Posts utilise un tableau personnalisé pour stocker les relations plusieurs à plusieurs entre les types de publication. Ce pourrait Cela peut être fait en utilisant l’API de taxonomie (et était à l’origine) ou la méta API - mais aucune de celles-ci n’est particulièrement efficace - et bien que cela puisse convenir aux sites plus petits, elle n’est pas bien adaptée. Scribu a déplacé Posts 2 Posts vers une implémentation de table personnalisée pour permettre le stockage d'informations sur une relation..
Alors que la plupart des cas peuvent être «pressés» dans la *_des postes
mould utilisant post meta, cela peut ne pas fournir la route la plus efficace: La table post meta utilise une colonne de valeur non indexée pour stocker les données. Il est incroyablement rapide de récupérer les métadonnées d'une publication (WordPress utilise également la mise en cache ici), mais des requêtes complexes utilisant la table méta peuvent s'avérer inefficaces ou presque impossibles..
Ce qui précède est lié aux requêtes complexes que les tables natives ne sont peut-être pas conçues pour répondre efficacement. Dans l'organisateur d'événements, par exemple, un événement est une publication avec des dates d'événements stockées dans une table séparée. Bien qu'il soit possible de stocker ces dates en tant que méta-post, le faire lorsque des événements ont plusieurs dates rendrait les requêtes basées sur la date extrêmement difficiles et inefficaces, en particulier du fait que la colonne de la méta-valeur n'est pas indexée..
Si tu utilises wp_posts
et vos données sont suffisamment volumineuses (plus de 100 000 messages), puis peut nuire aux performances, en fonction des requêtes que vous exécutez. Cet argument en soi est plutôt faible, car il y a beaucoup d'inconnues qui affecteront sa validité. En général, les bases de données sont rapides à la tâche - et le cadre WordPress qui l’entoure permet d’optimiser au maximum les requêtes. En combinaison avec les deux autres facteurs, vous constaterez peut-être qu’un tableau personnalisé présente l’option la plus judicieuse..
Une fois que vous avez décidé qu'une table personnalisée est nécessaire, nous devons la créer. Avant de le faire, nous allons stocker le nom de notre table personnalisée dans $ wpdb
. Cette liste globale contient toutes les informations relatives à la base de données du blog actuel (elles changeront d’un site à l’autre si vous utilisez plusieurs sites). Nous allons ajouter le nom de notre table à ce global. Ce n'est pas du tout nécessaire, mais rend le reste de notre code légèrement plus net:
add_action ('init', 'wptuts_register_activity_log_table', 1); add_action ('switch_blog', 'wptuts_register_activity_log_table'); function wptuts_register_activity_log_table () global $ wpdb; $ wpdb-> wptuts_activity_log = "$ wpdb-> préfixe wptuts_activity_log";
Le code ci-dessus utilise $ wpdb-> préfixe
ajouter un préfixe au nom de la table. Le préfixe est par défaut wp_
mais peut être modifié par l'utilisateur dans wp-config.php
. Cela est nécessaire lorsque plusieurs installations de WordPress utilisant la même base de données sont possibles, mais que vous pouvez également les modifier pour d'autres raisons. En tant que tel, vous ne pouvez pas supposer que le préfixe est wp_
. Comme pour les fonctions, les classes et les paramètres, etc., vous devez vous assurer que le nom de votre table est unique..
Tout au long de cette série, nous reviendrons à l'exemple suivant. Nous imaginons que nous créons un tableau pour consigner l'activité de l'utilisateur (mise à jour ou suppression de messages, modification des paramètres, téléchargement d'une image, etc.)..
Il existe différentes conventions pour nommer vos colonnes (et vos tables d'ailleurs) - mais quelle que soit la façon dont vous les nommez, il est important d'être cohérent. Je vous recommande d'utiliser uniquement des caractères minuscules car, dans certaines situations, les noms de colonne peuvent être sensibles à la casse. L'imposition de cette règle rend les erreurs moins probables et améliore la lisibilité. Comme nous le verrons plus tard dans la série, c'est également utile lorsque vous avez besoin de liste blanche de colonnes. Vous devez séparer les mots dans les noms de colonne (par exemple,. post_data
, Publier un contenu
) pour plus de lisibilité - mais vous devriez le faire avec des traits de soulignement, et jamais les espaces.
Vous devriez également éviter les mots réservés. Si la colonne fait référence à une table étrangère, il est recommandé d’utiliser le nom de cette colonne étrangère (tel que identifiant d'utilisateur
, notre exemple).
Dans notre exemple, nous allons nommer nos colonnes:
log_id
- l'identifiant du journal.identifiant d'utilisateur
- l'identifiant de l'utilisateur pour lequel le journal correspond.activité
- l'activité qui s'est produite.object_id
- l'identifiant de l'objet (par exemple, post ID, ID utilisateur, ID de commentaire, etc.) ayant fait l'objet de l'activité de l'utilisateur.type d'objet
- le type d'objet (par exemple, "post", "utilisateur", "commentaire", etc.).date_activité
- la date / heure de l'activité.Avant d'aller plus loin, vous aurez besoin de décider des types de données des colonnes de votre table. Les types de colonnes peuvent être divisés en trois catégories: chaînes, valeurs numériques et dates / heures. Pour chacune d’elles, il existe de nombreuses variantes. Vous pouvez trouver une référence complète ici.
Il est important de choisir le type de données approprié pour votre table, car cela affectera l'efficacité de vos requêtes. Certains types de données vous permettent de définir une limite (par exemple,. varchar (40)
- qui vous permet de stocker jusqu'à 40 caractères). La limite est facultative, mais elle est recommandée car elle peut améliorer les performances. Vous devez donc choisir pour chaque colonne le nombre maximal de caractères requis par la colonne. Remarque Pour les types de données numériques, la longueur fait référence au nombre de chiffres - pas au maximum (par exemple. INT (10)
autorise des nombres entiers non négatifs de 10 chiffres au maximum - donc 4 294 967 295 au maximum).
Lorsque vous stockez des dates, vous devez presque toujours utiliser le DATETIME
type de données (stocké sous le numéro 2012-11-05 14:55:10) - et certainement pas une représentation humaine de la date (par exemple, le 5 novembre 2012 à 14h55). DATETIME
les valeurs peuvent être facilement formatées sous une forme lisible par l'homme à l'aide de fonctions telles que mysql2date ()
. Vous devez stocker les dates dans le fuseau horaire UTC et, si nécessaire, le changer pour un fuseau horaire différent en sortie..
Dans notre exemple nous aurons:
log_id
- bigint (20)identifiant d'utilisateur
- bigint (20)activité
- varchar (20)object_id
- bigint (20)type d'objet
- varchar (20)rendez-vous amoureux
- date / heureEnsuite, vous devrez décider quelles colonnes indexer - elles seront déclarées comme CLÉ
s, dont l’un sera le CLÉ PRIMAIRE
. La clé primaire est une colonne où chaque ligne a un unique entrée - habituellement, il s'agit simplement d'un entier auto-incrémenté, essentiellement le "numéro de ligne".
Les valeurs des autres colonnes indexées ne doivent pas nécessairement être uniques, mais elles doivent déterminer un ensemble d'enregistrements relativement petit. L’idée de l’indexation est d’améliorer les requêtes de lecture. Sans index, une recherche devrait parcourir toute la table pour trouver les lignes correspondantes. Si une colonne est indexée et fait partie de la requête, elle peut alors trouver rapidement les lignes qui correspondent à cette colonne, puis ce petit sous-ensemble de lignes correspondantes peut être comparé à la requête (l'analogie est un index pour un livre)..
En tant que tel, si vous n'interrogez pas sur cette colonne, l'indexation de cette colonne ne vous aidera pas (si vous ne recherchez jamais un mot dans l'index du livre, il se peut également qu'il n'en soit pas là). Ni si beaucoup d'enregistrements partagent la même valeur, telle qu'une colonne "genre", cela n'améliorera pas beaucoup l'analyse d'un tableau complet (imaginez un index de livre répertoriant un mot figurant sur une autre page)..
L’indexation n’est pas gratuite non plus: les colonnes déclarées comme CLÉ
s réduisent les performances en écriture (pour continuer l'analogie, il vous faudrait mettre à jour l'index du livre lorsqu'un mot indexé est ajouté ou supprimé) - et vous devrez donc décider quel est le bon équilibre pour votre configuration. Plus d'informations peuvent être trouvées ici.
Comme il est probable que nous voudrons interroger par utilisateur (pour voir son activité récente), nous indexerons cette colonne et utiliserons log_id
comme clé primaire.
Nous placerons le code de création de la table personnalisée dans la fonction suivante:
function wptuts_create_tables () // Le code pour la création d'une table va ici // Créer des tables à l'activation du plugin register_activation_hook (__FILE__, 'wptuts_create_tables');
Cette fonction devra être appelée sur le hook d'activation du plug-in, ainsi que chaque fois que nous souhaitons apporter des modifications à la table - par exemple, l'ajout de colonnes ou la modification de leur type de données (nous expliquerons pourquoi plus tard dans la série)..
Le fait qu'en utilisant le crochet d'activation, wptuts_create_tables ()
pourrait être appelé lorsqu'une table existe déjà, n'est pas un oubli - et encore, nous allons expliquer pourquoi plus tard dans la série.
Dans cette fonction, nous incluons wp-admin / includes / upgrade.php mettre en place quelques constantes et charger la fonction dbDelta ()
. Notez que lorsqu'un plugin est activé, il manque le init
crochet, donc wptuts_register_activity_log_table ()
doit être appelé manuellement.
require_once (ABSPATH. 'wp-admin / includes / upgrade.php'); $ wpdb global; global $ charset_collate; // Appelez ceci manuellement car nous avons peut-être manqué l'init hook wptuts_register_activity_log_table ();
Le Global $ charset_collate
contient le jeu de caractères et le classement utilisés par les tables WordPress natives. En gros, ils définissent le codage des caractères et leur comparaison - dans la mesure où WordPress est utilisé dans de nombreuses langues, il est important d'utiliser le classement approprié pour votre tableau..
Outre le classement, l’instruction SQL doit déclarer le nom de la table, ainsi que chaque colonne, son type, sa valeur par défaut et CLÉ
colonnes, y compris un CLÉ PRIMAIRE
colonne. Typiquement ce sera de la forme:
CREATE TABLE [nom de la table] ([colonne de clé primaire] bigint (20) non signé NOT NULL auto_increment, [nom de colonne] [type de données] [valeur par défaut], PRIMARY KEY ([nom de colonne]), KEY nom_ clé ([nom de colonne]) ) [collation];
Pour créer cette table, nous ajoutons ce qui suit à notre wptuts_create_tables ()
une fonction:
$ sql_create_table = "CREATE TABLE $ wpdb-> wptuts_activity_log (log_id bigint (20) non signé NOT NULL auto_increment, utilisateur_id bigint (20) non signé NON NULL par défaut '0', activité varchar (20) NON par défaut, NULL mis à jour ', object_id bigint (20) unsigned NOT NULL par défaut '0', type d'objet varchar (20) NOT NULL par défaut 'post', date_activité datetime NON NULL par défaut '0000-00-00 00:00:00', PRIMARY KEY (id_log), KEY identifiant_utilisateur (user_id)) $ charset_collate; "; dbDelta ($ sql_create_table);
le dbDelta ()
fonction effectue notre CREER LA TABLE
commander. Il peut être assez strict quant à l’instruction SQL qui lui est donnée. Par exemple, il doit deux espaces entre CLÉ PRIMAIRE
et la colonne de clé primaire. et les clés doivent avoir un nom.
Si lors de l'activation, vous trouvez que vous obtenez le 'Vous avez le caractère X d'une sortie inattendue… 'message d'erreur - il est probable qu'il y ait une erreur dans votre instruction SQL. Parfois c'est dû à dbDelta ()
est la rigueur. Si vous ajoutez wp_die ();
après dbDelta ()
, cela annule le traitement et (avec 'WP_DEBUG' défini sur true) révélera tous les messages d'erreur.
Dans cet article, nous avons examiné les raisons pour lesquelles vous devriez et ne devriez pas utiliser de tables personnalisées, ainsi que les détails que vous devez prendre en compte et, enfin, comment créer une table. La prochaine partie de cette série portera sur la désinfection, sur l’injection SQL et sur la façon de vous en protéger. Le code dans cet article est disponible sur ce référentiel GitHub et sera mis à jour à mesure que la série se poursuivra..
$ wpdb
classe