Когда речь идёт о базах данных для ИИ-приложений, обычно подразумевается специализированный инструмент, созданный исключительно для работы с векторами. Однако Alibaba выбрала иной путь: они интегрировали поддержку векторного поиска прямо в AliSQL – свою реляционную базу данных. Это решение кажется просто технической деталью, но за ним стоит принципиальный подход. Разберём, что это означает на практике и как это устроено.
Что такое векторы и зачем они нужны базе данных?
Если вы когда-нибудь использовали семантический поиск, рекомендации «похожих товаров» или голосового помощника, то знайте: всё это функционирует с помощью векторов. Проще говоря, вектор – это набор чисел, описывающий объект: текст, изображение, звук. Два схожих по смыслу объекта будут иметь близкие векторы.
Задача базы данных в таком случае – не просто хранить эти числа, но и быстро находить ближайшие к заданному запросу. Зачем менять привычную реляционную базу для этого? Ответ прост: большинство приложений уже работают с реляционными базами данных. Если добавить туда векторный поиск, разработчику не придется создавать и обслуживать отдельную векторную систему, синхронизировать данные между двумя хранилищами и беспокоиться о согласованности. Всё будет в одном месте.
Как числа превращаются в структуру на диске?
Первый вопрос, который возникает при работе с векторами в базе данных: как их хранить? Вектор – это, по сути, массив чисел с плавающей точкой. В AliSQL для этого введён специальный тип данных, который сериализуется (то есть упаковывается) в бинарный формат перед записью на диск.
Формат устроен следующим образом: сначала идёт заголовок с метаданными – размерность вектора (сколько чисел он содержит) и тип данных (например, 32-битные числа с плавающей точкой). Затем следуют сами числовые значения, записанные последовательно. Такой подход позволяет точно определять границы векторов и не тратить лишнее место на разделители.
Важный аспект – размерность. Современные ИИ-модели часто генерируют векторы размерностью от нескольких сотен до нескольких тысяч чисел. AliSQL поддерживает до 16 000 измерений, что покрывает потребности большинства актуальных задач.
Почему перебирать всё подряд – неэффективно?
Представьте, что у вас в базе миллион векторов. Вам нужно найти 10 самых похожих на запрос. Самый прямолинейный способ – сравнить запрос с каждым из миллиона векторов. Математически это называется точным поиском ближайших соседей.
Проблема в том, что такой подход катастрофически медленный при больших объёмах данных. Миллион сравнений – еще терпимо. Но если данных десятки или сотни миллионов, время отклика становится неприемлемым для реальных приложений.
Именно поэтому в векторных базах данных используют приближённый поиск – алгоритмы, которые находят не гарантированно точный, но статистически очень близкий результат, причём делают это значительно быстрее. AliSQL использует для этого алгоритм HNSW.
HNSW: граф, обеспечивающий быстрый поиск
HNSW расшифровывается как Hierarchical Navigable Small World – иерархический навигируемый граф малого мира. Название звучит сложно, но идея довольно элегантна.
Представьте карту города. Есть скоростные магистрали – они соединяют далёкие районы, но не заходят в каждый двор. Есть районные дороги – они охватывают конкретные кварталы. И есть пешеходные тропинки – для точного перемещения внутри небольшого участка.
HNSW строит примерно такую же структуру, но из векторов. Верхние слои графа – это «магистрали»: грубые, но быстрые связи между далёкими точками. Нижние слои – детальные связи между соседними векторами. Поиск начинается сверху: мы быстро перемещаемся в нужный район, затем спускаемся ниже и уточняем результат.
Такой подход обеспечивает очень хорошее соотношение скорости и точности. Именно поэтому HNSW стал фактическим стандартом в большинстве векторных баз данных.
Как HNSW реализован в AliSQL?
Реализация в AliSQL соответствует общей логике HNSW, но адаптирована под особенности реляционной базы данных. Разберём ключевые моменты.
Построение графа
Когда новый вектор добавляется в таблицу, AliSQL встраивает его в граф. Сначала определяется, на каком уровне иерархии он будет присутствовать – это происходит случайно, по вероятностному правилу: большинство векторов попадают только на нижний уровень, и лишь немногие «поднимаются» выше. Это обеспечивает правильную структуру графа.
Затем для каждого уровня находятся ближайшие соседи нового вектора, и устанавливаются связи. Количество связей ограничено параметром – по умолчанию каждый узел соединён не более чем с определённым числом соседей. Это ограничение не только экономит память, но и поддерживает эффективность поиска: слишком «перегруженный» граф замедляет навигацию.
Поиск
Поиск работает в обратную сторону: начинается с верхнего слоя, где векторы связаны редко, но на большие расстояния. Происходит перемещение к ближайшему узлу, затем спуск на уровень ниже и повторение процесса. На нижнем, самом детальном слое проводится финальный локальный поиск, и возвращается результат.
Дополнительно используется список «кандидатов» – в процессе навигации алгоритм отслеживает несколько перспективных узлов одновременно, чтобы не застрять в локальном оптимуме. Размер этого списка – один из настраиваемых параметров: чем он больше, тем точнее результат, но тем медленнее поиск.
Метрики расстояния
AliSQL поддерживает несколько способов измерения «похожести» векторов:
- Евклидово расстояние – обычное геометрическое расстояние между двумя точками в многомерном пространстве;
- Косинусное сходство – измеряет угол между векторами, а не расстояние; хорошо работает с текстами;
- Скалярное произведение – ещё один вариант, часто используемый в задачах рекомендаций.
Выбор метрики зависит от задачи и от того, как была обучена модель, которая генерирует векторы.
Интеграция с хранилищем: не просто индекс
Один из нетривиальных аспектов реализации – то, как граф HNSW сохраняется на диске. В отдельных векторных базах данных индекс обычно целиком размещается в оперативной памяти. В реляционной базе это невозможно, так как данных может быть слишком много, и они должны сохраняться после перезапуска сервера.
AliSQL сохраняет граф как часть своего механизма хранения. Узлы графа и связи между ними сериализуются и записываются на диск наравне с обычными данными. При загрузке граф восстанавливается в памяти для работы. Это требует аккуратной работы с управлением памятью – держать весь граф в памяти дорого, поэтому реализован механизм частичной загрузки.
Кроме того, поскольку данные в реляционной базе постоянно меняются – строки добавляются, обновляются, удаляются – граф должен корректно отражать эти изменения. Удалённые строки не должны возвращаться в результатах поиска, даже если они ещё физически присутствуют в графе до очередной переиндексации.
Для кого это актуально?
Если вы разрабатываете приложение, которое уже использует MySQL или совместимую с ней базу данных – а AliSQL совместима с MySQL – и хотите добавить семантический поиск, поиск похожих изображений или рекомендательную систему, это решение позволяет сделать это без введения отдельного компонента в инфраструктуру.
Для небольших и средних проектов это особенно ценно: чем меньше движущихся частей в системе, тем меньше точек отказа и операционной нагрузки.
Для крупных высоконагруженных систем вопрос сложнее – специализированные векторные базы данных по-прежнему могут давать более высокую производительность именно в векторных задачах. Но возможность работать с векторами в рамках привычного SQL-окружения – это уже не экзотика, а реальный инструмент.
Это первая часть технического разбора AliSQL с фокусом на векторные возможности. В ней заложена основа: как данные хранятся и как работает поиск на уровне алгоритма. Следующие части, судя по всему, будут посвящены другим аспектам – например, производительности и настройке под реальные сценарии.