Was ist ein dynamisches Schema?
Dieser Beitrag wurde gemeinsam von Yujian Tang und Zhenshan Cao verfasst.
Jede Datenbank hat ein Schema, aber nicht alle sind dynamisch. SQL-Datenbanken haben vordefinierte Schemas, die sich normalerweise nicht ändern. Wenn du sie erstellst, teilst du der Datenbank mit, wie jede Tabelle aussehen soll, und erzwingst, dass jeder Eintrag zum Schema dieser Tabelle passt. NoSQL-Datenbanken haben typischerweise ein dynamisches Schema (oder können schemalos sein). Die Attribute für jedes Objekt müssen nicht definiert werden, wenn du deine Datenbanken erstellst.
Für die Milvus-Vektordatenbank ist das dynamische Schema eines, das sich ändert, wenn du Daten hinzufügst. Unterstützung für dynamische Schemas bedeutet zum Beispiel, dass du die Dateneingabe so behandeln kannst wie bei einer NoSQL-Datenbank und Daten in einem JSON-Format hinzufügen kannst. Zuvor hatte Milvus ein strikt erzwungenes Schema. Wir haben vor einigen Monaten in Milvus 2.2.9 eine Option für dynamische Schemas veröffentlicht und deren Implementierung einfach gemacht.
In diesem Artikel behandeln wir:
- Was ist ein Datenbankschema?
- Was ist ein Vektordatenbankschema?
- Wie man ein dynamisches Schema mit der Milvus-Vektordatenbank verwendet
- Wie die Funktion für dynamische Schemas in Milvus implementiert ist
Vor- und Nachteile dynamischer Schemas
Zusammenfassung dynamischer Schemas für Vektordatenbanken
Was ist ein Datenbankschema?
Schemas strukturieren, wie Daten in eine Datenbank eingefügt und darin gespeichert werden. Das obige Beispiel zeigt, wie du ein normalisiertes Datenbankschema für eine relationale Datenbank erstellen könntest. Im obigen Beispiel hat die mittlere Tabelle vier Spalten. Diese Datenbank hätte vier Tabellen und ein Schema für jede Tabelle.
Drei Tabellen hätten zweispaltige Schemas, und die mittlere hätte ein vierspaltiges Schema. Die Schemas für die Spalten würden auch Datendefinitionen enthalten. Die Spalten „Employee“, „Title“ und „DeptName“ wären alle Strings oder VARCHARs. Höchstwahrscheinlich wäre „CourseID“ das ebenfalls. „EmpID“ und „DeptID“ wären Ganzzahlen, und „Date“ könnte ebenfalls ein Datumstyp oder ein VARCHAR-Typ sein.
Was ist ein Vektordatenbankschema?
Das folgende Bild zeigt einen Eintrag in eine Instanz von Zilliz, dem vollständig verwalteten Vektordatenbankdienst von Milvus, den ich für mein Projekt Chat Towards Data Science verwende. Wenn wir ihn wie ein relationales Datenbankschema definieren würden, hätten wir 11 Spalten. Es gäbe sechs String- oder VARCHAR-Spalten - „id“, „paragraph“, „subtitle“, „publication“, „article_url“ und „title“. Drei der anderen fünf Spalten wären eine Art INT-Datentyp - „reading_time“, „responses“ und „claps“. Die zwei verbleibenden Spalten wären ein DATE-Typ, „date“, und das, was wir einen „FLOAT_VECTOR“ nennen, der Einbettungsvektor.
Wie verwendet man ein dynamisches Schema mit der Milvus-Vektordatenbank?
Milvus ist eine beliebte Open-Source-Vektordatenbank, die für Performance, Skalierbarkeit und Zuverlässigkeit entwickelt wurde. Wir haben vor einigen Monaten in Milvus 2.2.9 eine Option für dynamische Schemas veröffentlicht und deren Implementierung einfach gemacht.
Der folgende Codeausschnitt zeigt, wie man die Funktion für dynamische Schemas in Milvus aktiviert und nutzt und wie man Daten in dynamische Felder einfügt und gefilterte Suchen durchführt.
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())
In der erstellten Collection "books" definieren wir ein Schema mit drei Feldern: id, title und embeddings. Die id ist der Primärschlüssel, ein eindeutiger Bezeichner jeder Zeile, und im Format INT64. Der title stellt den Namen des Buches mit dem Typ VARCHAR dar, und das Embedding ist eine 8-dimensionale Vektorspalte. In diesem Beitrag werden Vektordaten zu Demonstrationszwecken zufällig im Code festgelegt.
schema = CollectionSchema(fields=fields, enable_dynamic_field=True)
collection = Collection(name=COLLECTION_NAME, schema=schema)
Wir aktivieren das dynamische Schema, indem wir bei der Definition ein Feld an das CollectionSchema-Objekt übergeben. Wir fügen lediglich das Schema enable_dynamic_field hinzu und setzen es auf 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},
]
Im obigen Code fügen wir drei Datenzeilen ein. Die Daten für id=1 enthalten das dynamische Feld isbn, id=2 enthält author, und id=3 enthält claps. Diese dynamischen Felder haben unterschiedliche Typen, darunter String-Typen (isbn und author) und Integer-Typen (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")
Im obigen Code führen wir eine hybride Suche durch, die eine ANNS-Suche (Approximate Nearest Neighbors) mit Filterung auf Basis dynamischer Felder kombiniert. Die Abfrage zielt darauf ab, Daten aus Zeilen abzurufen, die die im Parameter expr angegebenen Bedingungen erfüllen. Die Ausgabe enthält die Felder title, author, claps und isbn, sofern vorhanden. Der Parameter expr ermöglicht das Filtern auf Basis von Schemafeldern (title) und dynamischen Feldern (claps).
Nach dem Ausführen des Codes lauten die Ausgabeergebnisse wie folgt:
{'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}}
Wie ist die Funktion des dynamischen Schemas in Milvus implementiert?
Der Milvus-Kernel ermöglicht es Benutzern, mithilfe einer ausgeblendeten Metaspalte dynamische Felder mit unterschiedlichen Namen und Datentypen zu jeder Datenzeile hinzuzufügen. Wenn Benutzer eine Tabelle erstellen und dynamische Felder aktivieren, wird neben der Tabelle eine ausgeblendete Spalte namens $meta erstellt. Die ausgeblendete Spalte verwendet JSON als Datentyp, da es sich um ein sprachunabhängiges Datenformat handelt, das von modernen Programmiersprachen zum Erzeugen und Parsen von Daten im JSON-Format breit unterstützt wird.
Milvus organisiert Daten in einer spaltenorientierten Struktur. Während der Einfügung werden die Daten für dynamische Felder in jeder Zeile in ein JSON-Datenobjekt verpackt, und alle Zeilen mit JSON-Daten bilden zusammen die verborgene Spalte $meta.
Was sind die Vor- und Nachteile von Dynamic Schema?
Dynamische Schemas bieten Vorteile und Nachteile und eignen sich für unterschiedliche Anforderungen in der Datenmodellierung.
Vorteile
- Dynamische Schemas sind einfach einzurichten und damit für eine breite Nutzerbasis zugänglich, ohne komplexe Konfigurationen zu erfordern.
- Dynamische Schemas ermöglichen Änderungen an Datenmodellen im Laufe der Zeit, sodass Entwickler Anpassungen ohne erhebliche Umstrukturierungen vornehmen können.
Nachteile:
- Gefilterte Suche mit dynamischen Schemas ist deutlich langsamer als mit festen Schemas.
- Bulk Insert bei dynamischem Schema ist kompliziert.
Um diese Herausforderungen zu bewältigen, hat Milvus ein vektorisiertes Ausführungsmodell integriert, um die Effizienz der gefilterten Suche zu steigern. Im Gegensatz zum herkömmlichen Volcano-Modell, das jeweils eine Datenzeile durch aufgerufene Operatoren verarbeitet, verarbeitet das vektorisierte Ausführungsmodell ganze Datenbatches gleichzeitig. Dieses Rechenparadigma optimiert die Datenlokalität während der Berechnung, was zu einer erheblichen Verbesserung der gesamten Systemleistung führt.
Mit Blick auf die Zukunft werden wir die skalaren Indexierungsfunktionen in Milvus 2.4 weiter verbessern. Diese Verbesserung zielt darauf ab, die gefilterte Suche durch invertierte Indexierung für statische und dynamische Felder zu beschleunigen und eine verbesserte Leistung und Effizienz beim Verwalten und Abfragen dynamischer Schemas zu versprechen.
Zusammenfassung dynamischer Schemas für Vektordatenbanken
In diesem Artikel haben wir uns Datenbankschemas angesehen. Wir haben ein Beispielschema einer relationalen Datenbank verwendet, um Schemas besser zu verstehen. Relationale Datenbanken haben strikte Schemas, die definiert werden müssen. Schemas müssen definierte Felder haben, und Felder müssen definierte Datentypen haben. So wurde das Schema von Milvus früher erzwungen.
Allerdings muss Milvus tatsächlich nur wissen, wie zwei Felder definiert sind. Erstens die ID des Eintrags und zweitens das Embedding-Feld. Die übrigen Felder müssen nicht definiert werden, können es aber. Mit der Einführung des dynamischen Schemas, das über den Parameter enable_dynamic_field übergeben wird, muss Milvus die anderen Felder nicht mehr definiert haben.
Dynamische Schemas sind ein zweischneidiges Schwert: Sie bieten einfache Einrichtung, Flexibilität und Effizienz, jedoch nicht ohne Kompromisse. Beispielsweise ist die gefilterte Suche mit dynamischen Schemas langsamer als mit festen Schemas, und das Bulk Inserting bei dynamischen Schemas ist komplizierter. Milvus nutzte ein vektorisiertes Ausführungsmodell, um die Herausforderungen zu bewältigen, die mit dynamischen Schemas einhergehen, und optimierte so die gesamte Systemleistung. Wir werden außerdem die skalaren Indexierungsfunktionen in Milvus 2.4 verbessern, um die Leistung und Effizienz beim Verwalten und Abfragen dynamischer Schemas zu steigern.
Weiterlesen
Milvus/Zilliz + Surveillance: How Vector Databases Transform Multi-Camera Tracking
See how Milvus vector database enhances multi-camera tracking with similarity-based matching for better surveillance in retail, warehouses and transport hubs.

Similarity Metrics for Vector Search
Exploring five similarity metrics for vector search: L2 or Euclidean distance, cosine distance, inner product, and hamming distance.

Proactive Monitoring for Vector Database: Zilliz Cloud Integrates with Datadog
we're excited to announce Zilliz Cloud's integration with Datadog, enabling comprehensive monitoring and observability for your vectorDB deployments.



