Skip to content

scanhex12/relvec-db

Repository files navigation

Relvec Database

RelvecDB - распределенная база данных, которая предоставляет пользователю SQL запросы, а возможность хранить в таблицах вектора и делать быстрый поиск ближайших соседей (также в SQL синтаксисе)

Архитектура

Pic

База данных состоит из клиента, мастер-сервера и чанк-серверов. Ниже будет описано как взаимодействуют отдельные компоненты (протокол - HTTP 2.0)

Взаимодействие клиент-мастер

Клиент может задавать SQL-like запросы. Изначально этот запрос парсится (на стороне клиента, как устроен парсинг будет рассмотрено ниже), из него достаются все необходимые имена таблиц. Затем клиент отправляет запрос на мастер сервер запрос с получением адресов чанк-серверов

Взаимодействие клиент-чанксервер

После получения всех адресов, клиент обходит все чанк-сервера, которые он получил от мастера и получает необходимые данные.

Взаимодействие чанксервер-мастер

Чтобы мастеру понимать какие чанксервера живы, в чанксерверах есть отдельный тред, который с периодом $T$ отправляет хартбиты к мастер-серверу. На мастере живет отдельный компонент, который называется балансер - он отвечает за ответы на хартбиты от чанк-серверов и распределяет на каких серверах должны жить таблицы. балансер представляет из себя персистентное KV-хранилище, которое жадно распределяет таблицы по серверам.

Пример использования

Как собрать

bash build.sh

#TODO - настроить docker-compose, чтобы не поднимать все руками

Далее будет описано как поднимать отдельные компоненты (поднимать их нужно именно в этом порядке)

Поднимем мастер-сервер

Мастер сервер принимает в качестве аргументов хост и порт, на которых он будет принимать HTTP-соединения

Пример

cd build/master
./master 127.0.0.1 1234

Поднимем чанк-сервер

Чанк сервер принимает в качестве аргументов сначала хост и порт мастер-сервера, затем свой хост и порт, а затем некоторое магическое число - максимальное число байт, которое может занять на диске чанк-сервер

Пример

cd build/chunk
./chunk 127.0.0.1 1234 127.0.0.1 5678 100000

Запускаем клиента

Клиент в качестве аргументов принимает на вход хост мастера и его порт

Пример

cd build/client
./client 127.0.0.1 1234

Далее запустится CLI, в которые можно задавать SQL запросы

Синтаксис SQL

SQL-синтаксис от RelVec DB может отличаться от стандартного, поэтому рассмотрим операции, которые поддерживает данная БД

Удаление таблицы

Пример:

DROP TABLE your_table

Создание таблицы

Пример:

CREATE TABLE your_table (id uint64, name string, data vec, flag boolean)

В скобках должна указываться схема таблицы в формате списка пар $[name, type]$. Имя должно задаваться строчкой, тип должен принадлежать множеству (int64, uint64, string, boolean, vec). Тип vec - тип для вектора

Просмотр содержимого таблицы

базовый SELECT-запрос

SELECT * FROM your_table

Можно выбирать не все колонки, а только некоторые:

SELECT id, data FROM your_table 

Также можно выбирать не все значения:

SELECT * FROM your_table LIMIT 1

Также можно упорядочивать колонки

SELECT * FROM your_table ORDER BY id

Упорядочивать можно и в обратном порядке

SELECT * FROM your_table ORDER BY id DESC

Добавление строк в таблицу

INSERT your_table VALUES (1, [1, 2], "Bob", 3<0)

Важно:

Задавать векторные типы можно через скобки [] Строки надо передавать через ""

Join таблиц

В RelvecDB поддержан автоматический join, то есть пользователю не нужно задавать по каким колонкам надо join-ить таблицы - движок сам их выбирает на основе колонок, по которым полностью совпадают значения в обеих таблицах. После этого строится декартово произведение остальных колонок и по ним делается join.

Пример использования

SELECT * FROM table_left, table_right

Векторные запросы

Построение индекса

Прежде чем задавать векторные запросы, необходимо построить индекс. Индекс не персистентный, то есть он хранится в RAM и при отказе чанк-сервера и его переподнятии индекс придется строить заново.

Чтобы построить индекс, нужно вбить запрос

CREATE INDEX your_table, column, type

type должен быть один из (simple, hnsw, lsh)

Поиск ближайших соседей

Чтобы выполнить поиск, нужно сделать

SEARCH NEAREST your_table TO [ 1, 2, 3 ] BY column LIMIT 123 

Поиск будет делаться на основе существующего индекса.

Примеры корректных запросов

robertj@LAPTOP-A4NVHTDH:~/relvecdb/relvec-db/build/client$ ./client 127.0.0.1 5065
>>> 
>>> 
>>> 
>>> Some incorrect query
Incorrect query Bad input: syntax error
>>> DROP TABLE test_table
executed
>>> CREATE TABLE test_table (id int64, name string)
executed
>>> INSERT test_table VALUES (0, "Ann")
executed
>>> INSERT test_table VALUES (4, "Bob")
executed
>>> INSERT test_table VALUES (2, "Trinity")
executed
>>> SELECT * FROM test_table
+----+---------+
| id |  name   |
+----+---------+
|  0 |   Ann   |
+----+---------+
|  4 |   Bob   |
+----+---------+
|  2 | Trinity |
+----+---------+

>>> 
>>> 
>>> 
>>> 
>>> 
>>> SELECT id FROM test_table
+----+
| id |
+----+
|  0 |
+----+
|  4 |
+----+
|  2 |
+----+

>>> SELECT * FROM test_table LIMIT 1
+----+------+
| id | name |
+----+------+
|  0 |  Ann |
+----+------+

>>> SELECT * FROM test_table ORDER BY id LIMIT 2
+----+---------+
| id |  name   |
+----+---------+
|  0 |   Ann   |
+----+---------+
|  2 | Trinity |
+----+---------+

>>> CREATE TABLE testik_table (id int64, value string)
executed
>>> INSERT testik_table VALUES (0, "Some")
executed
>>> INSERT testik_table VALUES (4, "Value")
executed
>>> SELECT * FROM test_table, testik_table
+----+------+-------+
| id | name | value |
+----+------+-------+
|  0 |  Ann | Some  |
+----+------+-------+
|  4 |  Bob | Value |
+----+------+-------+

>>> CREATE TABLE test_t (id int64, name string, data vec)
executed
>>> INSERT test_t VALUES (0, "Ann", [0.1, 0.2, 0.3])
executed
>>> INSERT test_t VALUES (4, "Bob", [0.4, 0.5, 0.6])
executed
>>> INSERT test_t VALUES (2, "Trinity", [0.7, 0.8, 0.9])
executed
>>> SELECT * FROM test_t
+----+---------+--------------------------------+
| id |  name   |              data              |
+----+---------+--------------------------------+
|  0 |   Ann   | [0.100000, 0.200000, 0.300000] |
+----+---------+--------------------------------+
|  4 |   Bob   | [0.400000, 0.500000, 0.600000] |
+----+---------+--------------------------------+
|  2 | Trinity | [0.700000, 0.800000, 0.900000] |
+----+---------+--------------------------------+

>>> CREATE INDEX test_t data hnsw
executed
>>> SEARCH NEAREST test_t TO [1.0, 1.1, 1.2] BY data LIMIT 1
+----+---------+--------------------------------+
| id |  name   |              data              |
+----+---------+--------------------------------+
|  2 | Trinity | [0.700000, 0.800000, 0.900000] |
+----+---------+--------------------------------+

Ссылка на видео с примером использования

TODO

About

Vector-relational database. HSE Coursework

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published