Introdução
A equipe de suporte precisa de uma linha do tempo para cada ticket e de um resumo que também inclua os tickets sem eventos. Você vai relacionar as linhas de atividade aos tickets, escrever um relatório SQL reutilizável e adicionar um índice respaldado por um plano de consulta. Uma resposta que parece rápida em um conjunto de dados pequeno não é evidência suficiente de um caminho de acesso eficiente.
Este laboratório independente fornece o esquema básico de tickets usado no ensino anterior. Você vai criar a relação, o relatório e o índice por conta própria, usando um único banco de dados D1 descartável.
Use sua própria conta de aprendizado e uma VM nova. A configuração prepara o Node.js 22.22.0 e depois executa npm install para instalar o Wrangler 4.131.1 localmente no projeto e quaisquer dependências da avaliação em /home/labex/project/ticket-database. As versões das dependências diretas estão fixadas; a instalação cria seu próprio lockfile. A configuração não faz login na nuvem nem executa operações avaliadas no banco de dados. Em uma máquina pessoal, instale a mesma versão do Wrangler com npm install --save-dev wrangler@4.131.1 no seu projeto.
Este exercício usa registros sintéticos pequenos dentro dos limites gratuitos do D1. O uso existente da conta também conta para esses limites. Não é necessário ter um domínio comprado. Mantenha esta VM até verificar a exclusão dos recursos e o logout.
Autorizar esta VM e selecionar a conta
Nesta etapa, você conecta este terminal novo à sua própria conta de aprendizado. Fazer login no Dashboard, por si só, não autoriza a VM. A permissão do D1 permite criar, alterar e excluir bancos de dados. Revise a página de consentimento real, incluindo o acesso em segundo plano, antes de autorizar.
Abra o projeto preparado e verifique a versão fixada da CLI:
cd /home/labex/project/ticket-database
npx wrangler --version
O resultado esperado é 4.131.1. Inicie a autorização por dispositivo; --device exibe um código para o navegador, e --browser=false deixa a escolha do navegador por sua conta:
npx wrangler login --device --browser=false --scopes account:read user:read d1:write
Abra a URL exibida no navegador, informe o código atual, confirme sua conta de aprendizado e as permissões e autorize o acesso. Aguarde a confirmação de sucesso no terminal. Nunca cole senhas ou tokens nos arquivos do projeto.
npx wrangler whoami --json
Verifique loggedIn: true e leia o name e o id da conta, mesmo que apenas uma conta esteja listada. Copie o ID correto para a configuração abaixo. A variável de shell a seguir usa 6 bytes aleatórios, ou 12 caracteres hexadecimais, para evitar conflitos com outros alunos. Um here-document grava o JSON entre as linhas JSON; $RUN é expandido dentro dele.
A barra invertida antes de $schema mantém essa chave JSON literal; $RUN continua sendo expandido para o nome único desta execução.
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
Substitua YOUR_ACCOUNT_ID antes de executar o bloco. Mantenha este terminal aberto para que RUN continue disponível. name identifica esta execução; account_id seleciona a conta usada nas operações na nuvem. O arquivo é JSON comum, que também é válido como JSONC. Gravá-lo não faz o deploy de nenhum Worker.
Relacionar atividades a tickets
Nesta etapa, você adiciona uma tabela de atividades para representar vários eventos de um ticket. Uma chave estrangeira vincula o ticket_id de uma atividade a um ticket real, impedindo que um evento aponte para um registro pai inexistente. A configuração fornece o esquema conhecido de tickets para que você possa se concentrar nas relações e nas consultas.
Crie um banco de dados descartável na nuvem. --binding DB fornece um nome curto para o código da aplicação, --update-config registra o nome real e o UUID em wrangler.jsonc, e --use-remote=false mantém o desenvolvimento local:
npx wrangler d1 create "$RUN-db" --binding DB --update-config --use-remote=false
Leia o nome e o ID criados e inspecione a vinculação salva:
cat wrangler.jsonc
A entrada DB deve indicar o banco de dados desta execução. Uma vinculação é uma conexão configurada entre o código e um recurso. O UUID identifica o banco de dados na nuvem, enquanto --local usa um banco de dados SQLite separado nesta VM. Sempre inclua --local ou --remote nos comandos SQL.
Leia e aplique localmente os tickets fornecidos:
cat schema.sql
npx wrangler d1 execute DB --local --file schema.sql
Grave o esquema de atividades e o conjunto de dados fixo. Os timestamps inteiros usados aqui são valores sintéticos de ordenação, não horários atuais:
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
Aplique o arquivo localmente:
npx wrangler d1 execute DB --local --file activity.sql
Os tickets 1 e 2 têm dois eventos cada; o ticket 3 não tem nenhum. A próxima etapa mostrará como incluir esse ticket com zero eventos em um resumo.
Escrever um relatório de atividades dos tickets
Nesta etapa, você combina linhas de duas tabelas. Um join associa linhas usando uma relação. t e a são aliases curtos para os nomes das tabelas. LEFT JOIN mantém cada ticket mesmo quando ele não tem atividades; COUNT(a.id) conta apenas os IDs de atividades correspondentes. GROUP BY agrupa os eventos por ticket, e AS event_count dá nome à coluna calculada.
Escreva uma consulta de relatório reutilizável e somente para leitura. Manter a consulta em um arquivo SQL permite executar o mesmo relatório localmente e remotamente:
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
Execute o relatório:
npx wrangler d1 execute DB --local --file report.sql
Os valores esperados são 2, 2 e 0 para os tickets 1, 2 e 3. Usar um inner join excluiria o ticket 3; contar * contaria a linha substituta sem correspondência. Leia os eventos cronológicos de um ticket:
npx wrangler d1 execute DB --local --command "SELECT action, created_at FROM activity WHERE ticket_id = 1 ORDER BY created_at;"
O resultado esperado é opened em 100 e depois assigned em 200. O relatório responde quantos eventos cada ticket tem; a consulta filtrada responde quais eventos pertencem a um ticket específico.
Usar um plano de consulta para justificar um índice
Nesta etapa, você adiciona uma estrutura de pesquisa para a linha do tempo das atividades. Um índice armazena valores pesquisáveis em uma ordem que pode evitar a varredura de linhas não relacionadas. Ele usa armazenamento e adiciona trabalho quando os valores indexados mudam; por isso, adicione-o para uma consulta concreta.
Inspecione o plano antes de adicionar o índice. EXPLAIN QUERY PLAN descreve a estratégia de acesso do SQLite; ele não mede o tempo decorrido:
npx wrangler d1 execute DB --local --command "EXPLAIN QUERY PLAN SELECT action, created_at FROM activity WHERE ticket_id = 1 ORDER BY created_at;"
Procure uma varredura de activity e, possivelmente, uma estrutura temporária para a ordenação. Crie um índice combinado com ticket_id primeiro e created_at depois:
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;"
Agora o plano deve mencionar idx_activity_ticket_created na pesquisa. A formatação exata pode variar. O conjunto de dados fixo é pequeno demais para comparações de tempo úteis; o caminho de acesso escolhido é a evidência neste caso.
Adicione um novo evento depois de criar o índice e execute o relatório novamente:
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
O ticket 1 agora tem três eventos. Um índice deve preservar a correção das gravações e também dar suporte às leituras.
Executar o relatório e a consulta indexada no D1
Nesta etapa, você instala o esquema e o índice revisados no banco de dados remoto do laboratório. Os arquivos locais, sozinhos, não estabelecem um esquema remoto.
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
Quando solicitado, confirme somente o banco de dados deste laboratório. Adicione a mesma atividade final, inspecione o relatório e o plano de consulta remoto:
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) passa o texto do relatório como uma consulta. O --file remoto usa o fluxo de importação e informa metadados da importação, em vez de uma tabela de resultados de SELECT. As contagens remotas são 3, 2 e 0, e o plano informa o nome do seu índice. Isso comprova o resultado e o caminho de acesso no D1, sem presumir uma melhoria específica de tempo. Se quiser, abra o banco de dados D1 desta execução no Dashboard para conferir as tabelas e o esquema em modo somente leitura; mantenha o plano da CLI como evidência do índice.

Este exemplo mostra as cinco linhas de atividade remotas e suas relações por ticket_id. O nome gerado do banco de dados identifica esta execução de exemplo; o seu será diferente. Os números de created_at são valores sintéticos de ordenação, não registros de tempo atuais. Esta tabela é uma referência visual das linhas; a saída de EXPLAIN QUERY PLAN da CLI acima confirma o uso do índice, não uma melhoria no tempo de execução.
Excluir os recursos descartáveis
Nesta etapa, você remove somente os recursos deste laboratório enquanto a VM ainda está autorizada. Primeiro conclua todas as verificações funcionais. Mantenha a configuração até concluir a verificação da exclusão.
npx wrangler d1 delete DB
Leia o prompt e confirme somente o banco de dados desta execução. Depois, liste os bancos de dados:
npx wrangler d1 list --json
O nome e o UUID registrados do banco de dados devem estar ausentes em uma resposta bem-sucedida. Outros recursos podem permanecer. Um erro de autenticação ou de rede não é conclusivo: resolva o problema de acesso e repita a leitura antes de continuar. Faça a verificação desta etapa enquanto ainda estiver conectado.
Encerrar a autorização desta VM
Nesta etapa, você encerra a autorização somente depois que a verificação independente da exclusão for aprovada. O logout remove a autorização armazenada do Wrangler nesta VM; fechar uma VM, por si só, não faz a limpeza na nuvem.
npx wrangler logout
npx wrangler whoami --json
O resultado esperado é loggedIn: false. Essa consulta sem autenticação pode terminar com código diferente de zero; isso só é esperado quando a resposta estruturada informa explicitamente que você saiu da conta. Conclua a verificação e depois feche o ambiente do laboratório.
Resumo
Você praticou consultas e indexação de atividades de tickets. Verificou resultados observáveis no banco de dados, manteve explícitos a conta selecionada e o estado local e removeu os recursos descartáveis antes de fazer logout.



