Communitygithub.com

LDKTC/Agent-P-FullStack

Agent pour Claude AI, Codex, Copilot et autres IA

Qu'est-ce que Agent-P-FullStack ?

Compétence spécialisée MySQL/MariaDB pour assistants IA de développement. Fournit une expertise approfondie sur les types de données corrects (utf8mb4, DECIMAL pour les montants monétaires), la conception d'index et l'optimisation de requêtes via EXPLAIN, ainsi que la gestion des transactions et des verrous. Supporte les commandes en français et en anglais. Vérifie automatiquement la configuration MySQL/MariaDB (package.json, ORM, docker-compose) avant d'appliquer ses recommandations. Inclut des vérifications de cohérence avant validation finale et met en garde contre les pièges courants comme l'utilisation de FLOAT pour les montants ou le pagination OFFSET.

Compatible avec✓Claude Code✓Codex CLI✓Cursor
npx skills add LDKTC/Agent-P-FullStack

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation


name: mysql description: Expertise approfondie spécifique à MySQL/MariaDB — types de données et charset/collation corrects (utf8mb4, DECIMAL pour l'argent, VARCHAR/INT de taille appropriée, compromis ENUM), InnoDB vs MyISAM, conception d'index et réglage de requêtes piloté par EXPLAIN (ordre des index composites, index couvrants, prédicats sargables, pagination par jeu de clés), isolation des transactions et verrouillage (REPEATABLE READ, verrous d'écart, deadlocks), et pièges de correction spécifiques à MySQL. À utiliser lorsque package.json liste mysql2 ou mysql, le dialecte/fournisseur d'un ORM est défini sur mysql (Prisma provider = "mysql", Sequelize dialect: 'mysql', TypeORM type: 'mysql'/'mariadb'), un service docker-compose exécute une image mysql/mariadb, ou une chaîne de connexion mysql:// est présente, y compris lorsqu'on demande directement (en français ou en anglais) d'écrire ou vérifier un schéma/requête MySQL correct et performant. Ne remplace pas le workflow de migration indépendant du moteur de database-schema-dev ni le code de couche d'accès de backend-dev — c'est l'expertise MySQL spécifique que les deux utilisent lorsque le moteur est effectivement MySQL/MariaDB.

MySQL

Couche d'expertise spécifique à MySQL de database-schema-dev et backend-dev : ces agents sont indépendants du moteur et correspondent à l'outil de migration/ORM qu'un projet possède déjà — cette compétence est la connaissance réelle de MySQL qu'ils utilisent lorsque le moteur se trouve être MySQL, ou son fork proche-compatible MariaDB. Lorsque MariaDB se comporte différemment, cela est signalé — ne présumez pas d'une parité complète sur les fonctionnalités avancées.

Étape 1 — Confirmer que le moteur est effectivement MySQL/MariaDB

Vérifiez package.json pour mysql2/mysql, un dialecte/fournisseur d'ORM (provider = "mysql" dans Prisma, dialect: 'mysql' dans Sequelize, type: 'mysql'/'mariadb' dans TypeORM), un service docker-compose.yml exécutant une image mysql/mariadb, ou une chaîne de connexion mysql://. Si rien de tout cela n'est vérifié, arrêtez-vous — utilisez les valeurs par défaut indépendantes du moteur de database-schema-dev/backend-dev, ou la compétence spécifique au moteur correspondant à la place.

Étape 2 — Charset, collation, moteur de stockage

  • Le charset par défaut est utf8mb4, pas utf8 — le utf8 de MySQL est un alias de 3 octets maximum qui ne peut pas contenir la plupart des emojis/caractères astraux — avec une collation explicite (utf8mb4_0900_ai_ci sur MySQL 8+ ; MariaDB n'a pas de collations 0900, utilisez utf8mb4_unicode_ci pour tout ce qui cible les deux).
  • InnoDB sauf s'il y a une raison spécifique pour MyISAM (pas de transactions, pas de verrous de ligne, pas de clés étrangères) — c'est la valeur par défaut depuis MySQL 5.5/MariaDB 10.x, donc il s'agit généralement simplement de confirmer que rien ne le remplace.
  • La collation _ci signifie que '[email protected]' correspond à '[email protected]' — utilisez _bin/_cs (ou une colonne hachée) pour tout ce qui doit comparer de manière sensible à la casse (jetons, secrets).

Étape 3 — Types de données corrects

  • Argent/décimales exactes : DECIMAL(p,s), jamais FLOAT/DOUBLE — les nombres flottants binaires ne peuvent pas représenter la plupart des fractions en base 10 exactement.
  • Entiers de taille appropriée (TINYINT/SMALLINT/INT/BIGINT) en fonction des plages réelles, pas BIGINT partout par habitude — les types plus petits signifient des index plus petits. UNSIGNED est une marge de manœuvre gratuite sur une colonne d'identifiant, qui n'est jamais négative.
  • DATETIME pour une valeur d'horloge sans conversion de fuseau horaire prévue ; TIMESTAMP (normalisé UTC, se convertit automatiquement selon le fuseau horaire de la session, limite de plage 2038) uniquement pour un instant réel dans le temps — ne le définissez pas par défaut.
  • VARCHAR(n) dimensionné selon la contrainte réelle, pas VARCHAR(255) par eréflexe ; TEXT/BLOB pour un contenu véritablement illimité — aucun des deux ne prend de valeur par défaut ou d'index complet (non préfixé).
  • ENUM uniquement pour un ensemble fixe et rarement modifié — les valeurs se trient par ordre de définition, pas alphabétiquement (une surprise dans ORDER BY), et ajouter une valeur est uniquement métadonnée sur MySQL 8 mais peut réécrire la table sur MariaDB/MySQL plus ancien. Une table de référence évolue mieux lorsque l'ensemble s'agrandit ou a besoin de métadonnées.
  • JSON natif (MySQL 5.7.8+/MariaDB 10.2+ — le JSON de MariaDB est en fait LONGTEXT plus une CHECK, pas un type binaire, donc aucun des avantages de stockage binaire/mise à jour partielle de MySQL ne s'applique) uniquement pour des données véritablement sans schéma — tout ce qui est régulièrement filtré ou joint appartient à une colonne réelle.

Étape 4 — Conception d'index

  • Index composites : colonne(s) filtrée(s) par égalité d'abord, la colonne de tri/plage en dernier — (status, created_at) sert WHERE status = ? ORDER BY created_at ; l'ordre inverse ne le fait pas.
  • Règle du préfixe le plus à gauche : un index sur (a, b, c) sert également les recherches (a) et (a, b) — n'ajoutez pas un index (a) redondant à côté.
  • Un index couvrant (chaque colonne sélectionnée incluse) permet à MySQL de répondre à partir de l'index seul (Using index dans EXPLAIN) — utile pour une requête chaude et étroite, pas par défaut sur chaque requête.
  • Index de préfixe (col(20)) pour les VARCHAR/TEXT longs — vérifiez COUNT(DISTINCT LEFT(col, n)) par rapport à COUNT(DISTINCT col) pour dimensionner n.
  • Pagination profonde : LIMIT 20 OFFSET 100000 scanne et jette encore 100 000 lignes à chaque page. La pagination par jeu de clés (WHERE (created_at, id) < (:last_created, :last_id) ORDER BY created_at DESC, id DESC LIMIT 20) réutilise le même index composite et va directement au curseur — utilisez-la pour le défilement infini ou la pagination API profonde à la place de OFFSET.
  • Chaque index coûte du temps d'écriture et de l'espace disque — ajoutez des index pour des modèles de requêtes réels (database-schema-dev Étape 1), pas de manière spéculative par colonne.

Étape 5 — Réglage des requêtes piloté par EXPLAIN

  • Exécutez EXPLAIN (ou EXPLAIN ANALYZE, MySQL 8.0.18+/MariaDB 10.4+) avant de croire qu'une requête est rapide — ne jugez pas uniquement par la forme de la requête.
  • type: ALL est un scan de table complet ; ref/range/const signifient qu'un index est réellement utilisé — une requête valant la peine d'être optimisée ne devrait pas montrer ALL au-delà d'une taille de table triviale.
  • Extra: Using filesort/Using temporary signifie que MySQL a trié/matérialisé en dehors d'un index — généralement corrigé par un index correspondant au ORDER BY/ GROUP BY.
  • Une fonction d'encapsulation ou une conversion implicite sur une colonne indexée (WHERE YEAR(created_at) = ..., comparer une colonne de chaîne à un nombre) rend l'index inutilisable — réécrivez comme une plage de colonne nue à la place (created_at >= '2024-01-01' AND created_at < '2025-01-01').
  • SELECT * sur une table large rend les index couvrants inutiles et extrait des colonnes TEXT/BLOB que personne n'a demandées — sélectionnez uniquement ce qui est utilisé.

Étape 6 — Transactions et verrouillage

  • InnoDB verrouille les lignes, pas les tables, mais l'isolation par défaut REPEATABLE READ prend également des verrous d'écart sur les scans de plage dans UPDATE/DELETE/ SELECT verrouillant — une condition de plage peut bloquer plus que les lignes correspondantes. READ COMMITTED évite les verrous d'écart si les lectures répétables ne sont pas nécessaires.
  • Cet instantané ne couvre qu'un SELECT simple — une lecture verrouillante dans la même transaction (SELECT ... FOR UPDATE, UPDATE, DELETE) lit les données validées les plus récentes à la place, elle peut donc voir une ligne que l'instantané n'a jamais montrée. Ne présumez pas que l'isolation d'instantané protège également une lecture verrouillante.
  • Gardez les transactions courtes — une transaction ouverte conserve ses verrous et, sous REPEATABLE READ, bloque également la purge par InnoDB des anciennes versions de lignes.
  • SELECT ... FOR UPDATE pour verrouiller les lignes lues puis écrites dans une seule transaction (vérification du solde avant débit) ; acquérez les verrous dans un ordre de lignes cohérent dans toute la base de code pour éviter les deadlocks.
  • Un deadlock (ERROR 1213, SQLSTATE 40001) est attendu sous une contention réelle — InnoDB annule automatiquement un côté ; attrapez ce code et réessayez au lieu de le "réparer" avec une transaction plus longue. SHOW ENGINE INNODB STATUS → LATEST DETECTED DEADLOCK montre ce que chaque côté détenait/attendait.
  • Autocommit est activé par connexion par défaut — l'atomicité multi-déclarations nécessite une transaction explicite (ou l'encapsulation de l'ORM), pas seulement une adjacency dans le code.

Étape 7 — Pièges spécifiques à MySQL et divergence MariaDB

  • sql_mode devrait inclure STRICT_TRANS_TABLES (valeur par défaut depuis MySQL 5.7/MariaDB 10.2) — sans cela, les valeurs hors plage/de mauvais type sont silencieusement tronquées au lieu de générer une erreur ; confirmez qu'il n'a pas été assoupli.
  • Les valeurs AUTO_INCREMENT ne sont pas sans écart (une annulation en consomme toujours une) — ne comptez jamais sur des identifiants contigus.
  • Le time_zone de session affecte la conversion TIMESTAMP mais pas DATETIME — un pool avec des fuseaux horaires mixtes par connexion est un véritable bug "mauvaise heure" ; épinglez-le explicitement.
  • MariaDB a ses propres extensions sans équivalent MySQL (CREATE SEQUENCE, RETURNING sur les écritures) — ne les utilisez pas si MySQL est également une cible ; les fonctions de fenêtre/CTE nécessitent MySQL 8.0+/MariaDB 10.2+, vérifiez d'abord la version épinglée.
  • L'optimiseur et la sortie EXPLAIN de MariaDB ne sont pas le même moteur que ceux de MySQL — réexécutez EXPLAIN sur le moteur réellement utilisé plutôt que de vous fier à un plan réglé sur l'autre.

Étape 8 — Auto-vérification avant de signaler comme terminé

Confirmez que chaque colonne nouvelle/modifiée a un type intentionnel et que le charset par défaut est utf8mb4. Confirmez que tout nouvel index est soutenu par un modèle de requête réel avec une sortie EXPLAIN montrant qu'il est utilisé, et que tout point de terminaison de liste profonde/illimitée utilise keyset au lieu de OFFSET. Confirmez que les écritures multi-déclarations sont encapsulées dans une transaction explicite et que le comportement d'isolation d'une lecture verrouillante est délibéré, pas supposé. Si le fichier compose/CI épingle MariaDB, confirmez qu'aucun ajout ne suppose une fonctionnalité exclusive à MySQL-8.

Ce qu'il ne faut pas faire

  • N'utilisez pas le charset utf8 ni FLOAT/DOUBLE pour l'argent — utf8mb4 et DECIMAL sont les valeurs par défaut correctes.
  • N'ajoutez pas d'index sans modèle de requête derrière, ou ne qualifiez pas une requête de "rapide" sans vérifier EXPLAIN.
  • N'utilisez pas la pagination OFFSET sur une liste qui peut paginer profondément ou s'exécuter sans limite — utilisez keyset.
  • Ne laissez pas une transaction ouverte plus longtemps que le travail qu'elle protège, surtout sous les verrous d'écart de REPEATABLE READ.
  • Ne comptez pas sur la contiguïté de AUTO_INCREMENT ou la conversion de type implicite pour l'exactitude.
  • Ne présumez pas qu'une cible MariaDB possède des fonctionnalités exclusives à MySQL-8 (JSON natif, utf8mb4_0900_ai_ci) sans vérifier la version épinglée.
  • N'écrivez pas vous-même le code de migration/couche d'accès indépendant du moteur — c'est le rôle de database-schema-dev/backend-dev ; cette compétence est la connaissance de MySQL qu'ils appliquent par-dessus.

Skills associés