Com a explosão de aplicações que usam embeddings de IA para busca semântica e recomendação, guardar vetores em bancos relacionais virou uma necessidade comum. A partir do MySQL 9.0, isso deixou de exigir gambiarras com JSON ou BLOB: o banco ganhou um tipo de coluna nativo, o VECTOR, junto com funções para armazenar, converter e comparar esses valores.
O problema antes do VECTOR
Sem um tipo dedicado, a saída comum era serializar o vetor como uma string JSON e calcular a similaridade na aplicação, trazendo linhas inteiras do banco só para descartar a maioria delas depois:
CREATE TABLE produtos (
id INT PRIMARY KEY,
nome VARCHAR(255),
embedding JSON
);
INSERT INTO produtos (id, nome, embedding)
VALUES (1, 'Tênis de corrida', '[0.12, -0.03, 0.98, ...]');
Funciona, mas não há como comparar vetores dentro do banco, indexar por proximidade ou economizar espaço: um JSON com centenas de números em texto puro é muito mais pesado do que precisa ser.
Criando uma coluna VECTOR
O tipo VECTOR(N) armazena até N números de ponto flutuante de precisão simples (4 bytes cada), em um formato binário compacto:
CREATE TABLE produtos (
id INT PRIMARY KEY,
nome VARCHAR(255),
embedding VECTOR(4)
);
Os valores podem ser inseridos a partir de uma string com a função STRING_TO_VECTOR(), e lidos de volta como texto legível com VECTOR_TO_STRING():
INSERT INTO produtos (id, nome, embedding)
VALUES (1, 'Tênis de corrida', STRING_TO_VECTOR('[0.12, -0.03, 0.98, 0.44]'));
SELECT id, nome, VECTOR_TO_STRING(embedding) AS embedding_legivel
FROM produtos;
Buscando os mais parecidos com VECTOR_DISTANCE()
A função VECTOR_DISTANCE() calcula a distância entre dois vetores, permitindo montar uma busca por similaridade (k-nearest-neighbour) usando SQL puro, ordenando pelos vetores mais próximos de uma consulta:
SET @busca = STRING_TO_VECTOR('[0.10, -0.02, 0.95, 0.40]');
SELECT id, nome, VECTOR_DISTANCE(embedding, @busca) AS distancia
FROM produtos
ORDER BY distancia ASC
LIMIT 5;
Por padrão a distância usada é euclidiana, mas a função aceita um terceiro argumento para escolher outra métrica, como COSINE:
SELECT id, nome, VECTOR_DISTANCE(embedding, @busca, 'COSINE') AS distancia
FROM produtos
ORDER BY distancia ASC
LIMIT 5;
Combinando com filtros relacionais
A vantagem de ter o vetor como coluna nativa é poder misturar busca por similaridade com filtros comuns, algo que bancos de vetores dedicados às vezes tornam mais complicado:
SELECT id, nome, preco, VECTOR_DISTANCE(embedding, @busca) AS distancia
FROM produtos
WHERE categoria = 'calçados' AND preco <= 300
ORDER BY distancia ASC
LIMIT 10;
Quando usar
- Guardar embeddings gerados por modelos de IA (OpenAI, modelos locais, etc.) diretamente junto dos dados relacionais.
- Busca semântica: encontrar produtos, documentos ou imagens parecidos com uma consulta.
- Sistemas de recomendação simples, sem precisar operar um banco de vetores separado.
- Protótipos e aplicações de porte pequeno a médio, onde manter tudo em um único banco reduz a complexidade da infraestrutura.
Limitações da primeira versão
É importante ter em mente que essa é a primeira geração do recurso. Colunas VECTOR não podem ser usadas como chave (primária ou índice único), o conjunto de funções ainda é enxuto e não existe (ainda) um índice especializado tipo HNSW para acelerar buscas em milhões de vetores. Para volumes muito grandes ou exigência de latência muito baixa, um banco de vetores dedicado ainda costuma performar melhor.
Compatibilidade
O tipo VECTOR e as funções relacionadas estão disponíveis a partir do MySQL 9.0 (lançado em julho de 2024), fazendo parte do ciclo de "innovation releases" do MySQL, e não do MySQL 8.4 LTS. Antes de usar em produção, confira se a versão do servidor e a distribuição em uso (Community, Enterprise ou serviços gerenciados) já oferecem suporte a esse tipo.
Conclusão
O tipo VECTOR traz busca por similaridade para dentro do MySQL, evitando a complexidade de sincronizar os dados com um banco de vetores separado só para casos de uso mais simples. Ainda é um recurso novo e com limitações, mas já resolve bem cenários onde IA e dados relacionais precisam conviver na mesma consulta.
0 Comentário
Deixe seu Comentário!