O que é um esquema dinâmico?
Este post foi escrito em conjunto por Yujian Tang e Zhenshan Cao.
Todo banco de dados tem um schema, mas nem todos são dinâmicos. Bancos de dados SQL têm schemas predefinidos, que normalmente não mudam. Quando você o cria, informa ao banco de dados como deseja que cada tabela seja e impõe que cada entrada se ajuste ao schema dessa tabela. Bancos de dados NoSQL normalmente têm um schema dinâmico (ou podem não ter schema). Os atributos de cada objeto não precisam ser definidos quando você cria seus bancos de dados.
Para o banco de dados vetorial Milvus, o schema dinâmico é aquele que muda conforme você adiciona dados. Por exemplo, o suporte a schema dinâmico significa que você pode tratar a entrada de dados como faria com um banco de dados NoSQL e adicionar dados em formato JSON. Anteriormente, o Milvus tinha um schema rigorosamente imposto. Lançamos uma opção de schema dinâmico no Milvus 2.2.9 há alguns meses e a tornamos fácil de implementar.
Neste artigo, abordaremos:
- O que é um Schema de Banco de Dados?
- O que é um Schema de Banco de Dados Vetorial?
- Como Usar Schema Dinâmico com o Banco de Dados Vetorial Milvus
- Como o Recurso de Schema Dinâmico É Implementado no Milvus
Prós e contras dos Schemas Dinâmicos
Resumo dos Schemas Dinâmicos para Bancos de Dados Vetoriais
O que é um Schema de Banco de Dados?
Schemas estruturam como os dados são inseridos e armazenados em um banco de dados. O exemplo acima mostra como você poderia criar um schema de banco de dados normalizado para um banco de dados relacional. No exemplo acima, a tabela central tem quatro colunas. Esse banco de dados teria quatro tabelas e um schema para cada tabela.
Três tabelas teriam schemas de duas colunas, e a central teria um schema de quatro colunas. Os schemas das colunas também incluiriam definições de dados. As colunas “Employee”, “Title” e “DeptName” seriam todas strings, ou VARCHARs. Muito provavelmente, “CourseID” também seria. “EmpID” e “DeptID” seriam inteiros, e “Date” poderia ser do tipo date ou do tipo VARCHAR também.
O que é um Schema de Banco de Dados Vetorial?
A imagem abaixo mostra uma entrada em uma instância do Zilliz, o serviço de banco de dados vetorial totalmente gerenciado do Milvus, que uso no meu projeto Chat Towards Data Science. Se fôssemos defini-la como um schema de banco de dados relacional, teríamos 11 colunas. Haveria seis colunas de string ou VARCHAR - “id”, “paragraph”, “subtitle”, “publication”, “article_url” e “title”. Três das outras cinco colunas seriam algum tipo de dado INT - “reading_time”, “responses” e “claps”. As duas colunas restantes seriam um tipo DATE, “date”, e o que chamamos de “FLOAT_VECTOR”, o vetor de embedding.
Como usar Schema Dinâmico com o banco de dados vetorial Milvus?
Milvus é um popular banco de dados vetorial de código aberto criado para desempenho, escalabilidade e confiabilidade. Lançamos uma opção de schema dinâmico no Milvus 2.2.9 há alguns meses e a tornamos fácil de implementar.
O trecho de código a seguir demonstra como habilitar e utilizar o recurso de schema dinâmico no Milvus e como inserir dados em campos dinâmicos e realizar buscas filtradas.
from pymilvus import (
connections,
FieldSchema, CollectionSchema, DataType,
Collection,
)
DIMENSION = 8
COLLECTION_NAME = "books"
connections.connect("default", host="localhost", port="19530")
fields = [
FieldSchema(name='id', dtype=DataType.INT64, is_primary=True),
FieldSchema(name='title', dtype=DataType.VARCHAR, max_length=200),
FieldSchema(name='embeddings', dtype=DataType.FLOAT_VECTOR, dim=DIMENSION)
]
schema = CollectionSchema(fields=fields, enable_dynamic_field=True)
collection = Collection(name=COLLECTION_NAME, schema=schema)
data_rows = [
{"id": 1, "title": "Lord of the Flies",
"embeddings": [0.64, 0.44, 0.13, 0.47, 0.74, 0.03, 0.32, 0.6],
"isbn": "978-0399501487"},
{"id": 2, "title": "The Great Gatsby",
"embeddings": [0.9, 0.45, 0.18, 0.43, 0.4, 0.4, 0.7, 0.24],
"author": "F. Scott Fitzgerald"},
{"id": 3, "title": "The Catcher in the Rye",
"embeddings": [0.43, 0.57, 0.43, 0.88, 0.84, 0.69, 0.27, 0.98],
"claps": 100},
]
collection.insert(data_rows)
collection.create_index("embeddings", {"index_type": "FLAT", "metric_type": "L2"})
collection.load()
vector_to_search = [0.57, 0.94, 0.19, 0.38, 0.32, 0.28, 0.61, 0.07]
result = collection.search(
data=[vector_to_search],
anns_field="embeddings",
param={},
limit=3,
expr="claps > 30 || title =='The Great Gatsby'",
output_fields=["title", "author", "claps", "isbn"],
consistency_level="Strong")
for hits in result:
for hit in hits:
print(hit.to_dict())
Na coleção criada "books," definimos um esquema com três campos: id, title e embeddings. O id é a chave primária, um identificador único de cada linha, e no formato INT64. O title representa o nome do livro com o tipo VARCHAR, e o embedding é uma coluna vetorial de 8 dimensões. Neste post, os dados vetoriais são definidos aleatoriamente no código para fins de demonstração.
schema = CollectionSchema(fields=fields, enable_dynamic_field=True)
collection = Collection(name=COLLECTION_NAME, schema=schema)
Habilitamos o esquema dinâmico passando um campo para o objeto CollectionSchema na definição. Tudo o que fazemos é adicionar o esquema enable_dynamic_field e defini-lo como True.
data_rows = [
{"id": 1, "title": "Lord of the Flies",
"embeddings": [0.64, 0.44, 0.13, 0.47, 0.74, 0.03, 0.32, 0.6],
"isbn": "978-0399501487"},
{"id": 2, "title": "The Great Gatsby",
"embeddings": [0.9, 0.45, 0.18, 0.43, 0.4, 0.4, 0.7, 0.24],
"author": "F. Scott Fitzgerald"},
{"id": 3, "title": "The Catcher in the Rye",
"embeddings": [0.43, 0.57, 0.43, 0.88, 0.84, 0.69, 0.27, 0.98],
"claps": 100},
]
No código acima, inserimos três linhas de dados. Os dados para id=1 incluem o campo dinâmico isbn, id=2 inclui author, e id=3 inclui claps. Esses campos dinâmicos têm tipos diferentes, incluindo tipos de string (isbn e author) e tipos inteiros (claps).
result = collection.search(
data=[vector_to_search],
anns_field="embeddings",
param={},
limit=3,
expr="claps > 30 || title =='The Great Gatsby'",
output_fields=["title", "author", "claps", "isbn"],
consistency_level="Strong")
No código acima, realizamos uma busca híbrida combinando busca ANNS (Vizinhos Mais Próximos Aproximados) com filtragem baseada em campos dinâmicos. A consulta visa recuperar dados de linhas que satisfazem as condições especificadas no parâmetro expr. A saída inclui os campos title, author, claps e isbn, se presentes. O parâmetro expr permite a filtragem baseada em campos do esquema (title) e campos dinâmicos (claps).
Após executar o código, os resultados de saída são os seguintes:
{'id': 2, 'distance': 0.40939998626708984, 'entity': {'title': 'The Great Gatsby', 'author': 'F. Scott Fitzgerald'}}
{'id': 3, 'distance': 1.8463000059127808, 'entity': {'title': 'The Catcher in the Rye', 'claps': 100}}
Como o recurso de Esquema Dinâmico é implementado no Milvus?
O kernel do Milvus permite que os usuários adicionem campos dinâmicos com nomes e tipos de dados diferentes a cada linha de dados usando uma metacoluna oculta. Quando os usuários criam uma tabela e habilitam campos dinâmicos, uma coluna oculta chamada $meta é criada junto com a tabela. A coluna oculta usa JSON como tipo de dados porque é um formato de dados independente de linguagem amplamente suportado por linguagens de programação modernas para gerar e analisar dados em formato JSON.
O Milvus organiza os dados em uma estrutura colunar. Durante a inserção, os dados dos campos dinâmicos em cada linha são empacotados em um único dado JSON, e todas as linhas de dados JSON juntas formam a coluna oculta $meta.
Quais são os prós e contras do Dynamic Schema?
Schemas dinâmicos oferecem vantagens e desvantagens, atendendo a diferentes necessidades na modelagem de dados.
Prós
- Schemas dinâmicos são fáceis de configurar, tornando-os acessíveis a uma ampla base de usuários sem exigir configurações complexas.
- Schemas dinâmicos acomodam mudanças nos modelos de dados ao longo do tempo, permitindo que desenvolvedores façam ajustes sem reestruturações significativas.
Contras:
- A busca filtrada com schemas dinâmicos é muito mais lenta do que com schemas fixos.
- A inserção em massa em schema dinâmico é complicada.
Para enfrentar esses desafios, o Milvus integrou um modelo de execução vetorizado para aumentar a eficiência da busca filtrada. Em contraste com o modelo volcano convencional, que processa uma linha de dados por vez por meio de operadores invocados, o modelo de execução vetorizado lida com lotes inteiros de dados simultaneamente. Esse paradigma de computação otimiza a localidade dos dados durante a computação, resultando em uma melhoria significativa no desempenho geral do sistema.
Olhando para o futuro, continuaremos a aprimorar os recursos de indexação escalar no Milvus 2.4. Esse aprimoramento visa acelerar a busca filtrada por meio de indexação invertida para campos estáticos e dinâmicos, prometendo melhor desempenho e eficiência no gerenciamento e na consulta de schemas dinâmicos.
Resumo de Dynamic Schemas para Vector Databases
Neste artigo, analisamos schemas de banco de dados. Usamos um exemplo de schema de um banco de dados relacional para entender melhor os schemas. Bancos de dados relacionais têm schemas rígidos que precisam ser definidos. Schemas precisam ter campos definidos, e os campos precisam ter tipos de dados definidos. Era assim que o schema do Milvus costumava ser imposto.
No entanto, o Milvus na verdade só precisa saber como dois campos são definidos. Primeiro, o ID da entrada e, segundo, o campo de embedding. O restante dos campos não precisa ser definido, mas pode ser. Com a introdução do schema dinâmico, passado usando o parâmetro enable_dynamic_field, o Milvus não precisa mais ter os outros campos definidos.
Schemas dinâmicos são uma faca de dois gumes, oferecendo facilidade de configuração, flexibilidade e eficiência, mas não sem concessões. Por exemplo, a busca filtrada com schemas dinâmicos é mais lenta do que com schemas fixos, e a inserção em massa em schemas dinâmicos é mais complicada. O Milvus utilizou um modelo de execução vetorizado para enfrentar os desafios que vêm com schemas dinâmicos, otimizando o desempenho geral do sistema. Também aprimoraremos os recursos de indexação escalar no Milvus 2.4 para melhorar o desempenho e a eficiência no gerenciamento e na consulta de schemas dinâmicos.
Continue lendo

Introducing Zilliz CLI and Agent Skills for Zilliz Cloud
Manage your vector database from your terminal or AI coding agent. Zilliz CLI and Agent Skills work with Claude Code, Cursor, Codex, and Copilot.

A Developer's Guide to Exploring Milvus 2.6 Features on Zilliz Cloud
Milvus 2.6 marks a shift from “vector search + glue code” to a more advanced retrieval engine, and it is now Generally Available (GA) on Zilliz Cloud (a managed Milvus service).

Legal Document Analysis: Harnessing Zilliz Cloud's Semantic Search and RAG for Legal Insights
Enhance legal document analysis with Zilliz Cloud’s Semantic Search and RAG. Improve accuracy, efficiency, and scalability for contracts, case law, and compliance.



