Che cos'è uno schema dinamico?
Questo post è scritto congiuntamente da Yujian Tang e Zhenshan Cao.
Ogni database ha uno schema, ma non tutti sono dinamici. I database SQL hanno schemi predefiniti, che in genere non cambiano. Quando lo crei, indichi al database come vuoi che appaia ogni tabella e imponi che ogni voce si conformi allo schema di quella tabella. I database NoSQL in genere hanno uno schema dinamico (o possono essere senza schema). Gli attributi di ciascun oggetto non devono essere definiti quando crei i tuoi database.
Per il database vettoriale Milvus, lo schema dinamico è uno che cambia man mano che aggiungi dati. Ad esempio, il supporto dello schema dinamico significa che puoi trattare l’inserimento dei dati come faresti con un database NoSQL e aggiungere dati in formato JSON. In precedenza, Milvus aveva uno schema applicato rigidamente. Abbiamo rilasciato un’opzione di schema dinamico in Milvus 2.2.9 alcuni mesi fa e l’abbiamo resa facile da implementare.
In questo articolo tratteremo:
- Che cos’è uno schema di database?
- Che cos’è uno schema di database vettoriale?
- Come usare lo schema dinamico con il database vettoriale Milvus
- Come viene implementata la funzionalità di schema dinamico in Milvus
Pro e contro degli schemi dinamici
Riepilogo degli schemi dinamici per i database vettoriali
Che cos’è uno schema di database?
Gli schemi strutturano il modo in cui i dati vengono inseriti e conservati in un database. L’esempio sopra mostra come potresti creare uno schema di database normalizzato per un database relazionale. Nell’esempio sopra, la tabella centrale ha quattro colonne. Questo database avrebbe quattro tabelle e uno schema per ciascuna tabella.
Tre tabelle avrebbero schemi a due colonne, e quella centrale avrebbe uno schema a quattro colonne. Gli schemi per le colonne includerebbero anche definizioni dei dati. Le colonne “Employee”, “Title” e “DeptName” sarebbero tutte stringhe, o VARCHAR. Molto probabilmente, anche “CourseID” lo sarebbe. “EmpID” e “DeptID” sarebbero interi, e “Date” potrebbe essere anch’esso un tipo data o un tipo VARCHAR.
Che cos’è uno schema di database vettoriale?
L’immagine qui sotto mostra una voce in un’istanza di Zilliz, il servizio di database vettoriale completamente gestito di Milvus, che uso per il mio progetto Chat Towards Data Science. Se dovessimo definirlo come uno schema di database relazionale, avremmo 11 colonne. Ci sarebbero sei colonne stringa o VARCHAR - “id”, “paragraph”, “subtitle”, “publication”, “article_url” e “title”. Tre delle altre cinque colonne sarebbero un qualche tipo di dato INT - “reading_time”, “responses” e “claps”. Le due colonne rimanenti sarebbero un tipo DATE, “date”, e quello che chiamiamo un “FLOAT_VECTOR”, il vettore di embedding.
Come usare lo schema dinamico con il database vettoriale Milvus?
Milvus è un popolare database vettoriale open-source creato per prestazioni, scalabilità e affidabilità. Abbiamo rilasciato un’opzione di schema dinamico in Milvus 2.2.9 alcuni mesi fa e l’abbiamo resa facile da implementare.
Il seguente frammento di codice dimostra come abilitare e utilizzare la funzionalità di schema dinamico in Milvus e come inserire dati nei campi dinamici ed eseguire ricerche filtrate.
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())
Nella collection creata "books", definiamo uno schema con tre campi: id, title ed embeddings. L'id è la chiave primaria, un identificatore univoco di ogni riga, e nel formato INT64. Il title rappresenta il nome del libro con il tipo VARCHAR, e l'embedding è una colonna vettoriale a 8 dimensioni. In questo post, i dati vettoriali sono impostati casualmente nel codice a scopo dimostrativo.
schema = CollectionSchema(fields=fields, enable_dynamic_field=True)
collection = Collection(name=COLLECTION_NAME, schema=schema)
Abilitiamo lo schema dinamico passando un campo all'oggetto CollectionSchema nella definizione. Tutto ciò che facciamo è aggiungere lo schema enable_dynamic_field e impostarlo su 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},
]
Nel codice sopra, inseriamo tre righe di dati. I dati per id=1 includono il campo dinamico isbn, id=2 include author e id=3 include claps. Questi campi dinamici hanno tipi diversi, inclusi tipi stringa (isbn e author) e tipi interi (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")
Nel codice sopra, eseguiamo una ricerca ibrida che combina la ricerca ANNS (Approximate Nearest Neighbors) con il filtraggio basato su campi dinamici. La query mira a recuperare dati dalle righe che soddisfano le condizioni specificate nel parametro expr. L'output include i campi title, author, claps e isbn se presenti. Il parametro expr consente il filtraggio basato su campi dello schema (title) e campi dinamici (claps).
Dopo aver eseguito il codice, i risultati dell'output sono i seguenti:
{'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}}
Come viene implementata la funzionalità Dynamic Schema in Milvus?
Il kernel di Milvus consente agli utenti di aggiungere campi dinamici con nomi e tipi di dati diversi a ogni riga di dati utilizzando una metacolonna nascosta. Quando gli utenti creano una tabella e abilitano i campi dinamici, una colonna nascosta denominata $meta viene creata insieme alla tabella. La colonna nascosta utilizza JSON come tipo di dato perché è un formato di dati indipendente dal linguaggio ampiamente supportato dai moderni linguaggi di programmazione per generare e analizzare dati in formato JSON.
Milvus organizza i dati in una struttura colonnare. Durante l’inserimento, i dati per i campi dinamici in ogni riga vengono impacchettati in un unico dato JSON, e tutte le righe di dati JSON insieme formano la colonna nascosta $meta.
Quali sono i pro e i contro dello Schema Dinamico?
Gli schemi dinamici offrono vantaggi e svantaggi, rispondendo a esigenze diverse nella modellazione dei dati.
Pro
- Gli schemi dinamici sono facili da configurare, rendendoli accessibili a un’ampia base di utenti senza richiedere configurazioni complesse.
- Gli schemi dinamici accomodano i cambiamenti nei modelli di dati nel tempo, consentendo agli sviluppatori di adattarsi senza ristrutturazioni significative.
Contro:
- La ricerca filtrata con schemi dinamici è molto più lenta rispetto agli schemi fissi.
- L’inserimento in blocco su schema dinamico è complicato.
Per affrontare queste sfide, Milvus ha integrato un modello di esecuzione vettorializzato per aumentare l’efficienza della ricerca filtrata. A differenza del modello volcano convenzionale, che elabora una riga di dati alla volta tramite operatori invocati, il modello di esecuzione vettorializzato gestisce interi batch di dati contemporaneamente. Questo paradigma di calcolo ottimizza la località dei dati durante la computazione, risultando in un miglioramento significativo delle prestazioni complessive del sistema.
Guardando al futuro, continueremo a migliorare le capacità di indicizzazione scalare in Milvus 2.4. Questo miglioramento mira ad accelerare la ricerca filtrata tramite indicizzazione invertita per campi statici e dinamici, promettendo migliori prestazioni ed efficienza nella gestione e nell’interrogazione degli schemi dinamici.
Riepilogo degli Schemi Dinamici per Database Vettoriali
In questo articolo, abbiamo dato un’occhiata agli schemi di database. Abbiamo usato uno schema di esempio di un database relazionale per comprendere meglio gli schemi. I database relazionali hanno schemi rigidi che devono essere definiti. Gli schemi devono avere campi definiti, e i campi devono avere tipi di dati definiti. È così che lo schema di Milvus veniva applicato in passato.
Tuttavia, Milvus in realtà ha bisogno di sapere solo come sono definiti due campi. Uno, l’ID della voce, e due, il campo embedding. Il resto dei campi non deve essere definito, ma può esserlo. Con l’introduzione dello schema dinamico, passato usando il parametro enable_dynamic_field, Milvus non ha più bisogno che gli altri campi siano definiti.
Gli schemi dinamici rappresentano un’arma a doppio taglio, offrendo facilità di configurazione, flessibilità ed efficienza, ma non senza compromessi. Ad esempio, la ricerca filtrata con schemi dinamici è più lenta rispetto agli schemi fissi, e l’inserimento in blocco su schemi dinamici è più complicato. Milvus ha utilizzato un modello di esecuzione vettorializzato per affrontare le sfide che accompagnano gli schemi dinamici, ottimizzando le prestazioni complessive del sistema. Miglioreremo inoltre le capacità di indicizzazione scalare in Milvus 2.4 per migliorare le prestazioni e l’efficienza nella gestione e nell’interrogazione degli schemi dinamici.
Continua a leggere

Introducing Zilliz MCP Server: Natural Language Access to Your Vector Database
Developers can easily manage and query vector databases with natural language via Zilliz MCP Server in AI-native environments.

Cosmos World Foundation Model Platform for Physical AI
NVIDIA's Cosmos platform enables safe, digital twin training of GenAI models for physical applications, overcoming data scarcity and safety challenges.

Vector Databases vs. Time Series Databases
Use a vector database for similarity search and semantic relationships; use a time series database for tracking value changes over time.



