Что такое динамическая схема?
Этот пост написан совместно Yujian Tang и Zhenshan Cao.
У каждой базы данных есть схема, но не все они динамические. Базы данных SQL имеют предопределённые схемы, которые обычно не меняются. Когда вы создаёте её, вы указываете базе данных, как должна выглядеть каждая таблица, и обеспечиваете, чтобы каждая запись соответствовала схеме этой таблицы. Базы данных NoSQL обычно имеют динамическую схему (или могут быть бессхемными). Атрибуты для каждого объекта не обязательно должны быть определены при создании ваших баз данных.
Для векторной базы данных Milvus динамическая схема — это схема, которая меняется по мере добавления данных. Например, поддержка динамической схемы означает, что вы можете обращаться с вводом данных так же, как в базе данных NoSQL, и добавлять данные в формате JSON. Ранее в Milvus была строго enforced схема. Мы выпустили опцию динамической схемы в Milvus 2.2.9 несколько месяцев назад и сделали её простой в реализации.
В этой статье мы рассмотрим:
- Что такое схема базы данных?
- Что такое схема векторной базы данных?
- Как использовать динамическую схему с векторной базой данных Milvus
- Как функция динамической схемы реализована в Milvus
Плюсы и минусы динамических схем
Краткое изложение динамических схем для векторных баз данных
Что такое схема базы данных?
Схемы структурируют то, как данные вставляются и хранятся в базе данных. Пример выше показывает, как можно создать нормализованную схему базы данных для реляционной базы данных. В примере выше центральная таблица имеет четыре столбца. У этой базы данных было бы четыре таблицы и схема для каждой таблицы.
Три таблицы имели бы схемы из двух столбцов, а центральная — схему из четырёх столбцов. Схемы столбцов также включали бы определения данных. Столбцы “Employee”, “Title” и “DeptName” все были бы строками, или VARCHAR. Скорее всего, “CourseID” тоже был бы таким. “EmpID” и “DeptID” были бы целыми числами, а “Date” также мог бы быть типом даты или типом VARCHAR.
Что такое схема векторной базы данных?
На изображении ниже показана запись в экземпляре Zilliz, полностью управляемого сервиса векторных баз данных Milvus, который я использую для своего проекта Chat Towards Data Science. Если бы мы определяли её как схему реляционной базы данных, у нас было бы 11 столбцов. Было бы шесть строковых столбцов или столбцов VARCHAR — “id”, “paragraph”, “subtitle”, “publication”, “article_url” и “title”. Три из оставшихся пяти столбцов были бы каким-либо типом данных INT — “reading_time”, “responses” и “claps”. Два оставшихся столбца были бы типа DATE, “date”, и того, что мы называем “FLOAT_VECTOR”, вектором embedding.
Как использовать динамическую схему с векторной базой данных Milvus?
Milvus — популярная векторная база данных с открытым исходным кодом, созданная для производительности, масштабируемости и надёжности. Мы выпустили опцию динамической схемы в Milvus 2.2.9 несколько месяцев назад и сделали её простой в реализации.
Следующий фрагмент кода демонстрирует, как включить и использовать функцию динамической схемы в Milvus, а также как вставлять данные в динамические поля и выполнять фильтрованный поиск.
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())
В созданной коллекции "books" мы определяем схему с тремя полями: id, title и embeddings. id — это первичный ключ, уникальный идентификатор каждой строки, в формате INT64. title представляет название книги с типом VARCHAR, а embedding — это 8-мерный векторный столбец. В этой статье векторные данные случайно задаются в коде для демонстрационных целей.
schema = CollectionSchema(fields=fields, enable_dynamic_field=True)
collection = Collection(name=COLLECTION_NAME, schema=schema)
Мы включаем динамическую схему, передавая поле в объект CollectionSchema при определении. Всё, что мы делаем, — добавляем схему enable_dynamic_field и устанавливаем для неё значение 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},
]
В приведённом выше коде мы вставляем три строки данных. Данные для id=1 включают динамическое поле isbn, id=2 включает author, а id=3 включает claps. Эти динамические поля имеют разные типы, включая строковые типы (isbn и author) и целочисленные типы (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")
В приведённом выше коде мы выполняем гибридный поиск, объединяющий поиск ANNS (Approximate Nearest Neighbors) с фильтрацией на основе динамических полей. Запрос направлен на получение данных из строк, которые удовлетворяют условиям, указанным в параметре expr. Вывод включает поля title, author, claps и isbn, если они присутствуют. Параметр expr позволяет фильтровать на основе полей схемы (title) и динамических полей (claps).
После выполнения кода результаты вывода выглядят следующим образом:
{'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}}
Как функция Dynamic Schema реализована в Milvus?
Ядро Milvus позволяет пользователям добавлять динамические поля с разными именами и типами данных в каждую строку данных с помощью скрытого метастолбца. Когда пользователи создают таблицу и включают динамические поля, вместе с таблицей создаётся скрытый столбец с именем $meta. Скрытый столбец использует JSON в качестве типа данных, поскольку это независимый от языка формат данных, широко поддерживаемый современными языками программирования для генерации и разбора данных в формате JSON.
Milvus организует данные в колоночной структуре. Во время вставки данные для динамических полей в каждой строке упаковываются в один фрагмент JSON-данных, а все строки JSON-данных вместе формируют скрытый столбец $meta.
Каковы плюсы и минусы Dynamic Schema?
Динамические схемы имеют преимущества и недостатки, отвечая различным потребностям в моделировании данных.
Плюсы
- Динамические схемы легко настраиваются, что делает их доступными для широкой аудитории пользователей без необходимости сложных конфигураций.
- Динамические схемы учитывают изменения в моделях данных с течением времени, позволяя разработчикам адаптироваться без существенной реструктуризации.
Минусы:
- Фильтрованный поиск с динамическими схемами намного медленнее, чем с фиксированными схемами.
- Массовая вставка в динамическую схему сложна.
Чтобы решить эти проблемы, Milvus интегрировал векторизованную модель выполнения для повышения эффективности фильтрованного поиска. В отличие от традиционной модели volcano, которая обрабатывает по одной строке данных за раз с помощью вызываемых операторов, векторизованная модель выполнения обрабатывает целые пакеты данных одновременно. Эта вычислительная парадигма оптимизирует локальность данных во время вычислений, что приводит к значительному повышению общей производительности системы.
Заглядывая вперед, мы продолжим расширять возможности скалярного индексирования в Milvus 2.4. Это улучшение направлено на ускорение фильтрованного поиска за счет инвертированного индексирования для статических и динамических полей и обещает повышенную производительность и эффективность при управлении динамическими схемами и выполнении запросов к ним.
Краткое описание динамических схем для векторных баз данных
В этой статье мы рассмотрели схемы баз данных. Мы использовали пример схемы реляционной базы данных, чтобы лучше понять схемы. Реляционные базы данных имеют строгие схемы, которые необходимо определять. В схемах должны быть определенные поля, а у полей должны быть определенные типы данных. Именно так раньше применялась схема Milvus.
Однако на самом деле Milvus нужно знать только, как определены два поля. Первое — ID записи, и второе — поле embedding. Остальные поля не обязательно определять, но это возможно. С появлением динамической схемы, передаваемой с помощью параметра enable_dynamic_field, Milvus больше не требует определения остальных полей.
Динамические схемы — это палка о двух концах: они предлагают простоту настройки, гибкость и эффективность, но не без компромиссов. Например, фильтрованный поиск с динамическими схемами медленнее, чем с фиксированными схемами, а массовая вставка в динамические схемы сложнее. Milvus использовал векторизованную модель выполнения, чтобы решить проблемы, возникающие с динамическими схемами, оптимизируя общую производительность системы. Мы также расширим возможности скалярного индексирования в Milvus 2.4, чтобы повысить производительность и эффективность при управлении динамическими схемами и выполнении запросов к ним.
Читать далее

Zilliz Skills Breakdown: How AI Agents Master Vector Databases
Zilliz's Milvus Skill (pymilvus, 7 files) and Zilliz Cloud Skill (zilliz-cli, 14 modules) bring vector-DB dev and ops into one Claude Code session.

Introducing DeepSearcher: A Local Open Source Deep Research
In contrast to OpenAI’s Deep Research, this example ran locally, using only open-source models and tools like Milvus and LangChain.

Vector Databases vs. Hierarchical Databases
Use a vector database for AI-powered similarity search; use a hierarchical database for organizing data in parent-child relationships with efficient top-down access patterns.



