Introduction
L’équipe d’assistance a besoin d’une chronologie pour chaque ticket ainsi que d’un récapitulatif incluant les tickets sans événement. Vous allez relier les lignes d’activité aux tickets, écrire un rapport SQL réutilisable et ajouter un index justifié par un plan de requête. Une réponse qui semble rapide sur un petit jeu de données ne suffit pas à prouver l’efficacité du chemin d’accès.
Cet atelier indépendant fournit le schéma de base des tickets utilisé dans les leçons précédentes. Vous allez créer vous-même la relation, le rapport et l’index dans une seule base de données D1 temporaire.
Utilisez votre propre compte d’apprentissage et une VM neuve. La configuration prépare d’abord Node.js 22.22.0, puis exécute npm install pour installer Wrangler 4.131.1 au niveau du projet ainsi que les dépendances d’évaluation dans /home/labex/project/ticket-database. Les versions des dépendances directes sont figées et l’installation crée son propre fichier de verrouillage. La configuration n’effectue aucune connexion au cloud ni opération sur la base évaluée. Sur une machine personnelle, installez la même version de Wrangler avec npm install --save-dev wrangler@4.131.1 dans votre projet.
Cet exercice utilise de petits enregistrements synthétiques dans le cadre des quotas gratuits de D1. L’utilisation existante de votre compte est prise en compte dans ces quotas. Aucun domaine acheté n’est nécessaire. Conservez cette VM jusqu’à ce que la suppression des ressources et la déconnexion aient été vérifiées.
Autoriser cette VM et sélectionner le compte
Dans cette étape, vous connectez ce terminal neuf à votre propre compte d’apprentissage. Une simple connexion au Dashboard n’autorise pas la VM. Les autorisations D1 permettent de créer, modifier et supprimer des bases de données. Consultez la page de consentement réelle, notamment la section Background Access, avant d’autoriser l’accès.
Ouvrez le projet préparé et vérifiez la version de la CLI :
cd /home/labex/project/ticket-database
npx wrangler --version
La version attendue est 4.131.1. Lancez l’autorisation de l’appareil ; --device affiche un code à saisir dans le navigateur et --browser=false vous laisse choisir vous-même le navigateur :
npx wrangler login --device --browser=false --scopes account:read user:read d1:write
Ouvrez l’URL affichée dans votre navigateur, saisissez le code actuel, vérifiez votre compte d’apprentissage et les autorisations demandées, puis autorisez l’accès. Attendez que le terminal confirme la réussite. Ne collez jamais de mots de passe ni de jetons dans les fichiers du projet.
npx wrangler whoami --json
Vérifiez que loggedIn: true est présent, puis lisez le name et l’id du compte, même si un seul compte est répertorié. Copiez l’ID voulu dans la configuration ci-dessous. La variable Shell suivante utilise 6 octets aléatoires, soit 12 caractères hexadécimaux, afin d’éviter les collisions avec les autres participants. Un here-document écrit le JSON entre les lignes JSON ; $RUN est développé à l’intérieur.
La barre oblique inverse devant $schema conserve cette clé JSON littérale ; $RUN est toujours remplacé par le nom unique de cette exécution.
RUN=labex-c04-d04-$(openssl rand -hex 6)
cat > wrangler.jsonc <<JSON
{
"\$schema": "./node_modules/wrangler/config-schema.json",
"name": "$RUN",
"account_id": "YOUR_ACCOUNT_ID",
"main": "src/index.js",
"compatibility_date": "2026-09-15",
"workers_dev": true,
"preview_urls": false
}
JSON
Remplacez YOUR_ACCOUNT_ID avant d’exécuter le bloc. Gardez ce terminal ouvert afin que RUN reste disponible. name identifie cette exécution ; account_id sélectionne le compte utilisé pour les opérations cloud. Le fichier est un fichier JSON ordinaire, également valide en JSONC. Sa création ne déploie aucun Worker.
Relier l’activité aux tickets
Dans cette étape, vous ajoutez une table d’activité pour représenter plusieurs événements associés à un ticket. Une clé étrangère relie ticket_id d’une activité à un ticket réel et empêche ainsi un événement de pointer vers un parent inexistant. La configuration fournit le schéma habituel des tickets afin que vous puissiez vous concentrer sur les relations et les requêtes.
Créez une base de données cloud temporaire. --binding DB fournit au code de l’application un nom court, --update-config enregistre son nom réel et son UUID dans wrangler.jsonc, et --use-remote=false conserve le développement en local :
npx wrangler d1 create "$RUN-db" --binding DB --update-config --use-remote=false
Lisez le nom et l’ID créés, puis vérifiez la liaison enregistrée :
cat wrangler.jsonc
L’entrée DB doit désigner la base de données de cette exécution. Une liaison est une connexion configurée entre le code et une ressource. Son UUID identifie la base de données cloud, tandis que --local utilise une base SQLite distincte dans cette VM. Incluez toujours --local ou --remote dans les commandes SQL.
Lisez et appliquez localement le schéma fourni pour les tickets :
cat schema.sql
npx wrangler d1 execute DB --local --file schema.sql
Écrivez le schéma de l’activité ainsi que le jeu de données fixe. Les horodatages entiers utilisés ici sont des valeurs synthétiques servant à définir l’ordre, et non des heures actuelles :
cat > activity.sql <<'SQL'
CREATE TABLE activity (
id INTEGER PRIMARY KEY,
ticket_id INTEGER NOT NULL REFERENCES tickets(id),
action TEXT NOT NULL,
created_at INTEGER NOT NULL
);
INSERT INTO activity (id, ticket_id, action, created_at) VALUES
(1, 1, 'opened', 100),
(2, 1, 'assigned', 200),
(3, 2, 'opened', 110),
(4, 2, 'closed', 300);
INSERT INTO tickets (id, subject, source) VALUES (3, 'No activity yet', 'seed');
SQL
Appliquez-le localement :
npx wrangler d1 execute DB --local --file activity.sql
Les tickets 1 et 2 possèdent chacun deux événements ; le ticket 3 n’en possède aucun. L’étape suivante montrera comment inclure ce ticket sans événement dans un récapitulatif.
Écrire un rapport sur l’activité des tickets
Dans cette étape, vous combinez les lignes de deux tables. Une jointure met en correspondance des lignes à l’aide d’une relation. t et a sont des alias courts pour les noms des tables. LEFT JOIN conserve chaque ticket, même lorsqu’il n’a aucune activité ; COUNT(a.id) compte uniquement les identifiants d’activité correspondants. GROUP BY regroupe les événements par ticket et AS event_count donne un nom à la colonne calculée.
Écrivez une requête de rapport en lecture seule et réutilisable. Conserver une requête dans un fichier SQL permet d’exécuter le même rapport localement ou à distance :
cat > report.sql <<'SQL'
SELECT t.id, t.subject, COUNT(a.id) AS event_count
FROM tickets AS t
LEFT JOIN activity AS a ON a.ticket_id = t.id
GROUP BY t.id, t.subject
ORDER BY t.id;
SQL
Exécutez le rapport :
npx wrangler d1 execute DB --local --file report.sql
Les comptes attendus sont 2, 2 et 0 pour les tickets 1, 2 et 3. Une jointure interne supprimerait le ticket 3 ; compter * compterait sa ligne correspondante sans activité. Lisez les événements chronologiques d’un ticket :
npx wrangler d1 execute DB --local --command "SELECT action, created_at FROM activity WHERE ticket_id = 1 ORDER BY created_at;"
Vous devez obtenir opened à 100, puis assigned à 200. Le rapport répond à la question du nombre d’événements de chaque ticket ; la requête filtrée indique quels événements appartiennent à un ticket donné.
Utiliser un plan de requête pour justifier un index
Dans cette étape, vous ajoutez une structure de recherche pour la chronologie des activités. Un index stocke les valeurs recherchables dans un ordre qui peut éviter de parcourir des lignes sans rapport. Il utilise de l’espace de stockage et ajoute du travail lorsque les valeurs indexées changent ; ajoutez-le donc pour répondre à une requête précise.
Examinez le plan avant d’ajouter l’index. EXPLAIN QUERY PLAN décrit la stratégie d’accès de SQLite ; il ne mesure pas le temps écoulé :
npx wrangler d1 execute DB --local --command "EXPLAIN QUERY PLAN SELECT action, created_at FROM activity WHERE ticket_id = 1 ORDER BY created_at;"
Recherchez un parcours de activity et éventuellement une structure temporaire utilisée pour le tri. Créez un index combiné avec ticket_id en première position et created_at en deuxième :
cat > index.sql <<'SQL'
CREATE INDEX idx_activity_ticket_created ON activity(ticket_id, created_at);
SQL
npx wrangler d1 execute DB --local --file index.sql
npx wrangler d1 execute DB --local --command "EXPLAIN QUERY PLAN SELECT action, created_at FROM activity WHERE ticket_id = 1 ORDER BY created_at;"
Le plan doit maintenant mentionner idx_activity_ticket_created pour la recherche. Le format exact peut varier. Le jeu de données fixe est trop petit pour permettre des comparaisons de temps utiles ; le chemin d’accès sélectionné constitue ici la preuve.
Ajoutez un nouvel événement après la création de l’index, puis exécutez à nouveau le rapport :
npx wrangler d1 execute DB --local --command "INSERT INTO activity (id, ticket_id, action, created_at) VALUES (5, 1, 'replied', 400);"
npx wrangler d1 execute DB --local --file report.sql
Le ticket 1 possède maintenant trois événements. Un index doit préserver la validité des écritures tout en facilitant les lectures.
Exécuter le rapport et la requête indexée dans D1
Dans cette étape, vous installez le schéma et l’index vérifiés dans la base de données distante de l’atelier. Les fichiers locaux seuls ne créent pas de schéma distant.
npx wrangler d1 execute DB --remote --file schema.sql
npx wrangler d1 execute DB --remote --file activity.sql
npx wrangler d1 execute DB --remote --file index.sql
Lorsque vous y êtes invité, confirmez uniquement cette base de données de l’atelier. Ajoutez la même activité finale, examinez le rapport et le plan de requête distant :
npx wrangler d1 execute DB --remote --command "INSERT INTO activity (id, ticket_id, action, created_at) VALUES (5, 1, 'replied', 400);"
npx wrangler d1 execute DB --remote --command "$(cat report.sql)"
npx wrangler d1 execute DB --remote --command "EXPLAIN QUERY PLAN SELECT action, created_at FROM activity WHERE ticket_id = 1 ORDER BY created_at;"
$(cat report.sql) transmet le texte du rapport comme requête. À distance, --file utilise le processus d’importation et affiche les métadonnées de l’importation plutôt qu’un tableau de résultats SELECT. Les comptes distants sont 3, 2 et 0, et le plan nomme votre index. Cela prouve le résultat et le chemin d’accès dans D1, sans supposer une amélioration particulière du temps d’exécution. Si vous le souhaitez, ouvrez la base D1 de cette exécution dans le Dashboard pour effectuer une vérification en lecture seule des tables et du schéma ; conservez le plan de la CLI comme preuve de l’utilisation de l’index.

Cet exemple montre les cinq lignes d’activité distantes et leurs liens ticket_id. Le nom généré de la base identifie cette exécution d’exemple ; le vôtre sera différent. Les nombres created_at sont des valeurs synthétiques de tri, pas des horodatages actuels. Ce tableau sert de repère visuel pour les lignes ; la sortie CLI EXPLAIN QUERY PLAN ci-dessus confirme l’utilisation de l’index, pas une amélioration du temps d’exécution.
Supprimer les ressources temporaires
Dans cette étape, vous supprimez uniquement les ressources de cet atelier alors que la VM est encore autorisée. Terminez d’abord toutes les vérifications fonctionnelles. Conservez la configuration jusqu’à la fin de la vérification de la suppression.
npx wrangler d1 delete DB
Examinez l’invite et confirmez qu’il s’agit uniquement de la base de données de cette exécution. Listez ensuite les bases de données :
npx wrangler d1 list --json
Le nom et l’UUID de la base de données que vous avez enregistrés doivent être absents d’une réponse réussie. D’autres ressources peuvent rester présentes. Une erreur d’authentification ou de réseau ne permet pas de conclure : rétablissez l’accès et répétez la lecture avant de continuer. Effectuez la vérification de cette étape tant que vous êtes encore connecté.
Mettre fin à l’autorisation de cette VM
Dans cette étape, vous mettez fin à l’autorisation uniquement après la réussite de la vérification indépendante de la suppression. La déconnexion supprime l’autorisation Wrangler enregistrée sur cette VM ; fermer une VM ne constitue pas un nettoyage cloud.
npx wrangler logout
npx wrangler whoami --json
Vous devez obtenir loggedIn: false. Cette requête non authentifiée peut se terminer avec un code différent de zéro ; cela est attendu uniquement lorsque la réponse structurée indique explicitement que vous êtes déconnecté. Terminez la vérification, puis fermez l’environnement de l’atelier.
Résumé
Vous avez appris à interroger et à indexer l’activité des tickets. Vous avez vérifié les résultats observables dans la base de données, gardé explicites le compte sélectionné et l’état local, puis supprimé les ressources temporaires avant de vous déconnecter.



