Communitygithub.com

Especialista MySQL/MariaDB para Agentes de IA

Habilidade especializada em banco de dados MySQL/MariaDB para agentes de IA como Claude, Codex, Copilot e outros — tipos de dados corretos, índices, tuning de queries e boas práticas transacionais.

O que é MariaDB para Agentes de IA?

Esta habilidade fornece conhecimento profundo e específico sobre bancos MySQL e MariaDB para agentes de IA. Ela é projetada para ser usada quando um projeto declara o uso de MySQL/MariaDB (por exemplo, via pacotes `mysql2`/`mysql`, dialeto de ORM como `provider = "mysql"` no Prisma, ou string de conexão `mysql://`). O agente coberto por esta skill sabe como escolher o charset e collation corretos (como `utf8mb4`), definir tipos de dados precisos (como `DECIMAL` para valores monetários), projetar índices compostos eficientes, e otimizar consultas usando `EXPLAIN` e técnicas de paginação por keyset. Além disso, a skill aborda isolamento de transações, locking (incluindo gap locks no `REPEATABLE READ`), armadilhas comuns de MySQL, e diferenças importantes entre MySQL e MariaDB — garantindo que o código gerado seja correto, performático e portável. Ela não substitui habilidades de esquema de banco de dados ou backend de propósito geral, mas sim fornece a expertise MySQL que elas aplicam quando o motor é MySQL/MariaDB. Suporta agentes como Claude Code, Cursor, Codex, Copilot e similares desde que o contexto do projeto indique o uso de MySQL/MariaDB.

Funciona com✓Claude Code✓Codex CLI✓Cursor
npx skills add LDKTC/Agent-P-FullStack

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação


name: mysql description: Expertise específica em banco de dados MySQL/MariaDB — tipos de dados e charset/collation corretos (utf8mb4, DECIMAL para dinheiro, VARCHAR/INT no tamanho certo, trade-offs de ENUM), InnoDB vs MyISAM, design de índices e tuning de consultas guiado por EXPLAIN (ordem de índices compostos, índices covering, predicados sargáveis, paginação por keyset), isolamento de transações e locking (REPEATABLE READ, gap locks, deadlocks), e armadilhas específicas de MySQL. Use quando package.json listar mysql2 ou mysql, o dialeto/provider de um ORM estiver configurado como mysql (Prisma provider = "mysql", Sequelize dialect: 'mysql', TypeORM type: 'mysql'/'mariadb'), um serviço docker-compose executar imagem mysql/mariadb, ou uma string de conexão mysql:// estiver presente, inclusive quando for solicitado diretamente (em tailandês ou inglês) para escrever ou revisar schema/query MySQL de forma correta e eficiente. Não substitui o workflow de migração engine-agnóstico de database-schema-dev nem o código de camada de acesso de backend-dev — esta é a expertise MySQL que ambos utilizam quando o motor é MySQL/MariaDB.

MySQL

Camada de expertise específica MySQL para database-schema-dev e backend-dev: esses agentes são engine-agnósticos e se adaptam a qualquer ferramenta de migração/ORM que o projeto já tenha — esta habilidade é o conhecimento real de MySQL que eles utilizam quando o motor é MySQL, ou seu fork compatível MariaDB. Onde MariaDB se comporta de forma diferente, isso é destacado — não assuma paridade total em funcionalidades avançadas.

Passo 1 — Confirmar que o motor é realmente MySQL/MariaDB

Verifique package.json para mysql2/mysql, um dialeto/provider de ORM (provider = "mysql" no Prisma, dialect: 'mysql' no Sequelize, type: 'mysql'/'mariadb' no TypeORM), um serviço em docker-compose.yml executando uma imagem mysql/mariadb, ou uma string de conexão mysql://. Se nada disso for verdade, pare — use os padrões engine-agnósticos de database-schema-dev/backend-dev, ou a habilidade específica do motor correspondente.

Passo 2 — Charset, collation, storage engine

  • O charset padrão é utf8mb4, não utf8 — o utf8 do MySQL é um alias de no máximo 3 bytes que não consegue armazenar a maioria dos emojis/caracteres astrais — com uma collation explícita (utf8mb4_0900_ai_ci no MySQL 8+; MariaDB não tem collations 0900, use utf8mb4_unicode_ci para qualquer coisa que almeje ambos).
  • InnoDB a menos que haja uma razão específica para MyISAM (sem transações, sem locks de linha, sem FKs) — é o padrão desde MySQL 5.5/MariaDB 10.x, então isso geralmente é apenas confirmar que nada o substitui.
  • Collation _ci significa que '[email protected]' corresponde a '[email protected]' — use _bin/_cs (ou uma coluna com hash) para qualquer coisa que precise comparar com distinção de maiúsculas/minúsculas (tokens, segredos).

Passo 3 — Tipos de dados corretos

  • Dinheiro/decimais exatos: DECIMAL(p,s), nunca FLOAT/DOUBLE — ponto flutuante binário não consegue representar a maioria das frações base-10 exatamente.
  • Inteiros no tamanho certo (TINYINT/SMALLINT/INT/BIGINT) pelo intervalo real, não BIGINT em todo lugar por hábito — tipos menores significam índices menores. UNSIGNED é espaço livre adicional em uma coluna de id, que nunca é negativa.
  • DATETIME para um valor de relógio de parede sem conversão de fuso horário pretendida; TIMESTAMP (normalizado para UTC, converte automaticamente por fuso horário da sessão, limite de faixa em 2038) apenas para um instante real no tempo — não use como padrão.
  • VARCHAR(n) dimensionado pela restrição real, não VARCHAR(255) por reflexo; TEXT/BLOB para conteúdo genuinamente sem limites — nenhum dos dois aceita um valor padrão ou um índice completo (não prefixado).
  • ENUM apenas para um conjunto fixo e raramente mutável — valores são ordenados pela ordem de definição, não alfabeticamente (uma surpresa em ORDER BY), e anexar um valor é apenas metadados no MySQL 8, mas pode reescrever a tabela no MariaDB/MySQL mais antigo. Uma tabela de lookup escala melhor assim que o conjunto cresce ou precisa de metadados.
  • JSON nativo (MySQL 5.7.8+/MariaDB 10.2+ — o JSON do MariaDB é na verdade LONGTEXT mais um CHECK, não um tipo binário, então nenhum dos benefícios de armazenamento binário/atualização parcial do MySQL se aplicam) apenas para dados genuinamente sem schema — qualquer coisa filtrada ou com join regularmente pertence a uma coluna real.

Passo 4 — Design de índices

  • Índices compostos: coluna(s) filtradas por igualdade primeiro, a coluna de faixa/ordenação por último — (status, created_at) atende WHERE status = ? ORDER BY created_at; a ordem inversa não.
  • Regra do prefixo mais à esquerda: um índice em (a, b, c) também atende consultas (a) e (a, b) — não adicione um índice redundante (a) junto com ele.
  • Um índice covering (toda coluna selecionada incluída) permite que MySQL responda a partir apenas do índice (Using index no EXPLAIN) — vale a pena para uma consulta quente e estreita, não por padrão em toda consulta.
  • Índice prefixo (col(20)) para VARCHAR/TEXT longo — verifique COUNT(DISTINCT LEFT(col, n)) contra COUNT(DISTINCT col) para dimensionar n.
  • Paginação profunda: LIMIT 20 OFFSET 100000 ainda varre e descarta 100.000 linhas a cada página. Paginação por keyset (WHERE (created_at, id) < (:last_created, :last_id) ORDER BY created_at DESC, id DESC LIMIT 20) reutiliza o mesmo índice composto e busca diretamente pelo cursor — use-o para scroll infinito ou paginação profunda de API em vez de OFFSET.
  • Cada índice custa tempo de escrita e espaço em disco — adicione índices para padrões de consulta reais (database-schema-dev Passo 1), não especulativamente por coluna.

Passo 5 — Tuning de consultas guiado por EXPLAIN

  • Execute EXPLAIN (ou EXPLAIN ANALYZE, MySQL 8.0.18+/MariaDB 10.4+) antes de confiar que uma consulta é rápida — não julgue apenas pela forma da consulta.
  • type: ALL é uma varredura completa de tabela; ref/range/const significa que um índice é realmente usado — uma consulta que vale a pena otimizar não deve mostrar ALL além de tamanho de tabela trivial.
  • Extra: Using filesort/Using temporary significa que MySQL ordenou/materializou fora de um índice — geralmente corrigido por um índice que corresponda ao ORDER BY/ GROUP BY.
  • Uma função envolvendo ou cast implícito em uma coluna indexada (WHERE YEAR(created_at) = ..., comparando uma coluna string a um número) impede o uso do índice — reescreva como uma faixa de coluna nua (created_at >= '2024-01-01' AND created_at < '2025-01-01').
  • SELECT * em uma tabela larga impede índices covering e puxa colunas TEXT/BLOB que ninguém pediu — selecione apenas o que é usado.

Passo 6 — Transações e locking

  • InnoDB bloqueia linhas, não tabelas, mas o isolamento padrão REPEATABLE READ também coloca gap locks em varreduras de faixa em UPDATE/DELETE/ SELECT com lock — uma condição de faixa pode bloquear mais do que as linhas correspondentes. READ COMMITTED evita gap locks se leituras repetíveis não forem necessárias.
  • Esse snapshot cobre apenas um SELECT simples — uma leitura com lock na mesma transação (SELECT ... FOR UPDATE, UPDATE, DELETE) lê os dados mais recentes commitados, então pode ver uma linha que o snapshot nunca mostrou. Não assuma que o isolamento de snapshot também protege uma leitura com lock.
  • Mantenha transações curtas — uma transação aberta mantém seus locks e, sob REPEATABLE READ, também bloqueia a purga de versões antigas de linhas pelo InnoDB.
  • SELECT ... FOR UPDATE para bloquear linhas lidas e depois escritas em uma transação (verificação de saldo antes do débito); adquira locks em uma ordem de linha consistente em todo o código para evitar deadlocks.
  • Um deadlock (ERROR 1213, SQLSTATE 40001) é esperado sob contenção real — InnoDB automaticamente desfaz um dos lados; capture esse código e tente novamente em vez de "consertar" com uma transação mais longa. SHOW ENGINE INNODB STATUS → LATEST DETECTED DEADLOCK mostra o que cada lado mantinha/esperava.
  • Autocommit está ligado por conexão por padrão — atomicidade de múltiplas instruções precisa de uma transação explícita (ou do wrapper do ORM), não apenas adjacência no código.

Passo 7 — Armadilhas específicas de MySQL e divergências do MariaDB

  • sql_mode deve incluir STRICT_TRANS_TABLES (padrão desde MySQL 5.7/MariaDB 10.2) — sem ele, valores fora de faixa/tipo errado são truncados silenciosamente em vez de gerar erro; confirme que não foi relaxado.
  • Valores AUTO_INCREMENT não são livres de lacunas (um rollback ainda consome um) — nunca confie que ids são contínuos.
  • time_zone da sessão afeta a conversão de TIMESTAMP mas não de DATETIME — um pool com fusos horários mistos por conexão é um bug real de "hora errada"; fixe-o explicitamente.
  • MariaDB tem suas próprias extensões sem equivalente no MySQL (CREATE SEQUENCE, RETURNING em escritas) — não as use se MySQL também for um alvo; funções de janela/CTEs precisam de MySQL 8.0+/MariaDB 10.2+, verifique a versão fixada primeiro.
  • O otimizador e a saída EXPLAIN do MariaDB não são o mesmo motor que os do MySQL — reexecute EXPLAIN no motor real em uso em vez de confiar em um plano ajustado no outro.

Passo 8 — Autoverificação antes de relatar como concluído

Confirme que toda coluna nova/alterada tem um tipo intencional e o charset padrão é utf8mb4. Confirme que qualquer novo índice é baseado em um padrão de consulta real com saída EXPLAIN mostrando que é usado, e qualquer endpoint de lista profunda/sem limites usa keyset em vez de OFFSET. Confirme que escritas com múltiplas instruções estão envolvidas em uma transação explícita e o comportamento de isolamento de uma leitura com lock é deliberado, não assumido. Se o arquivo de compose/CI fixar MariaDB, confirme que nada adicionado assume uma funcionalidade exclusiva do MySQL 8.

O que não fazer

  • Não use charset utf8 ou FLOAT/DOUBLE para dinheiro — utf8mb4 e DECIMAL são os padrões corretos.
  • Não adicione um índice sem um padrão de consulta por trás dele, nem chame uma consulta de "rápida" sem verificar EXPLAIN.
  • Não use paginação OFFSET em uma lista que pode paginar profundamente ou ser ilimitada — use keyset.
  • Não deixe uma transação aberta por mais tempo do que o trabalho que ela protege, especialmente sob REPEATABLE READ com seus gap locks.
  • Não confie na contiguidade de AUTO_INCREMENT ou em coerção implícita de tipo para correção.
  • Não assuma que um alvo MariaDB tem funcionalidades exclusivas do MySQL 8 (JSON nativo, utf8mb4_0900_ai_ci) sem verificar a versão fixada.
  • Não escreva o código de migração/camada de acesso engine-agnóstico você mesmo — isso é papel de database-schema-dev/backend-dev; esta habilidade é o conhecimento MySQL que eles aplicam sobre ele.

Habilidades Relacionadas