Skip to main content

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples in this guide work on VillageSQL. Install Now →
Vector embeddings represent text as arrays of numbers that capture semantic meaning. Two pieces of text about the same topic have similar vectors even if they share no words. MySQL has no built-in way to generate embeddings. VillageSQL’s vsql_ai extension adds ai_embedding(), which calls an embedding model and returns the vector as a JSON array you can store and query.

What Embeddings Are For

An embedding model converts text to a fixed-length vector of floats. The distance between two vectors reflects semantic similarity:
  • "dog" and "puppy" → similar vectors
  • "dog" and "database index" → distant vectors
This enables semantic search (find rows that mean the same thing as a query), clustering, and recommendation — none of which keyword search handles well.

With VillageSQL: ai_embedding()

ai_embedding(provider, model, api_key, text) calls an embedding model and returns a JSON array string.

Storing embeddings

Store the JSON array in a JSON column:

Backfilling embeddings on existing rows

Choosing a Model

Use the same model for all embeddings in a table. Embeddings from different models are not comparable — mixing them produces meaningless similarity scores. Anthropic does not currently provide an embedding API. Neither MySQL nor VillageSQL provides a native vector distance function. Full similarity search — finding the nearest vectors in a large table — runs in application code. The typical architecture: store embeddings in MySQL, fetch them, compute cosine similarity in your application, and return the top matches.
Pass the results to a vector similarity library (NumPy, scikit-learn, Faiss) to find nearest neighbors. For production-scale search, consider a dedicated vector database alongside MySQL.

What to Embed

The quality of your embeddings depends on what you embed. Some patterns:
Keep the text you embed under a few thousand tokens. Longer text gets truncated by the embedding model.

Frequently Asked Questions

Can I compare embeddings from different models?

No. Embeddings from text-embedding-3-small and gemini-embedding-001 live in different vector spaces — their similarity scores are meaningless when compared against each other. Standardize on one model per column.

How much storage do embeddings take?

A JSON array of 1536 floats is roughly 10–15 KB per row as a text string. For large tables, this adds up. Consider whether you need all embeddings stored or just the ones you’ll query against.

Does ai_embedding() support batch input?

No — each call processes one text input. For bulk embedding, loop through rows in your application and call UPDATE in batches.

What happens if the text is too long?

The embedding model truncates input at its token limit (typically 8191 tokens for OpenAI models). The embedding is computed on the truncated text. For long documents, embed a summary or the first few paragraphs rather than the full text.

Troubleshooting

See also