Full-Text Search no MySQL
Criando índice FULLTEXT no MySQL
CREATE FULLTEXT INDEX, colunas candidatas e cuidados com charset/collation.
Nesta aula você vai
- Criar índices FULLTEXT em colunas adequadas no MySQL
- Escolher charset/collation compatíveis com busca em português
- Evitar erros comuns de engine, tamanho de token e colunas excluídas
Criando índice FULLTEXT no MySQL
Objetivos
Nesta aula você vai:
- Escrever
CREATE FULLTEXT INDEX(e a forma inline noCREATE TABLE) - Selecionar colunas candidatas em um catálogo realista
- Conferir charset, collation, engine e parâmetros que afetam a tokenização
Introdução
No MySQL, full-text deixa de ser só conceito quando o índice existe. Sem FULLTEXT, não há MATCH ... AGAINST legítimo sobre aquelas colunas. Vamos indexar o catálogo do OficinaHub: nome do anúncio, descrição curta e, opcionalmente, tags textuais concatenadas.
Conteúdo
Pré-requisitos de tabela
FULLTEXT no MySQL clássico exige InnoDB (ou MyISAM em legado). Prefira InnoDB.
CREATE TABLE produtos (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
sku VARCHAR(32) NOT NULL,
nome VARCHAR(180) NOT NULL,
descricao TEXT NOT NULL,
tags_texto VARCHAR(255) NULL,
categoria VARCHAR(80) NOT NULL,
criado_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY uq_produtos_sku (sku)
) ENGINE=InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
utf8mb4 evita surpresas com caracteres fora do BMP; collation _ci (case-insensitive) costuma combinar com busca orientada a usuário final.
Criando o índice
CREATE FULLTEXT INDEX ft_produtos_busca
ON produtos (nome, descricao, tags_texto);
Ou na criação da tabela:
-- trecho
FULLTEXT KEY ft_produtos_busca (nome, descricao, tags_texto)
| Coluna | Por que indexar? | Cuidado |
|---|---|---|
nome |
Alta intenção de busca | Títulos curtos; stopwords importam |
descricao |
Cobertura temática | Textos longos; ruído de marketing |
tags_texto |
Sinônimos operacionais | Mantenha tokens limpos, separados por espaço |
sku |
Às vezes | Códigos curtos podem ficar abaixo de ft_min_token_size |
SKUs curtos (T12) frequentemente precisam de caminho à parte (= ou prefixo), não só FULLTEXT.
Parâmetros que mudam o jogo
SHOW VARIABLES LIKE 'ft_min_token_size';
SHOW VARIABLES LIKE 'innodb_ft_min_token_size';
SHOW VARIABLES LIKE 'innodb_ft_enable_stopword';
- Tokens menores que o mínimo não entram no índice
- Stopwords do servidor removem termos da lista padrão
- Alterar esses valores exige reinício e, em geral, reconstruir o índice FULLTEXT
-- Após mudar mínimo de token (em ambiente controlado)
ALTER TABLE produtos DROP INDEX ft_produtos_busca;
ALTER TABLE produtos ADD FULLTEXT INDEX ft_produtos_busca (nome, descricao, tags_texto);
Charset e collation na prática
Se a conexão envia utf8mb4 mas a coluna ficou em latin1 legado, tokens e comparações sofrem. Padronize:
ALTER TABLE produtos
CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Faça isso em janela de manutenção: a conversão pode reescrever a tabela.
Problema comum e solução
Problema: ERROR ao usar MATCH em colunas que não participam juntas do mesmo índice FULLTEXT, ou misturar colunas de índices diferentes na mesma cláusula MATCH.
Solução: a lista de colunas em MATCH(col1, col2, ...) deve corresponder a um índice FULLTEXT existente com exatamente esse conjunto (ordem pode importar conforme versão — alinhe com o índice criado). Crie índices separados se precisar de combinações distintas.
Como analisar
SHOW INDEX FROM produtos WHERE Index_type = 'FULLTEXT';
EXPLAIN
SELECT id, nome
FROM produtos
WHERE MATCH(nome, descricao, tags_texto)
AGAINST ('torquimetro bancada' IN NATURAL LANGUAGE MODE)
LIMIT 20;
Confirme que o plano referencia o fulltext e que rows candidatas fazem sentido frente ao tamanho da tabela.
Resumo
CREATE FULLTEXT INDEXmaterializa o índice invertido no MySQL- Escolha colunas de busca real; trate SKUs curtos à parte se necessário
utf8mb4+ collation_cie InnoDB são a base segura- Mínimo de token e stopwords exigem alinhamento operacional e possível rebuild