Full-Text Search no MySQL

Criando índice FULLTEXT no MySQL

CREATE FULLTEXT INDEX, colunas candidatas e cuidados com charset/collation.

Intermediário 40 min 32 pontos Leitura 0%

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 no CREATE 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 INDEX materializa o índice invertido no MySQL
  • Escolha colunas de busca real; trate SKUs curtos à parte se necessário
  • utf8mb4 + collation _ci e InnoDB são a base segura
  • Mínimo de token e stopwords exigem alinhamento operacional e possível rebuild