⚠️ Эта страница автоматически переведена, и перевод может быть несовершенным.
blog-post

UUID в Manticore: единый ID для основной БД и Manticore

Допустим, у вашего товара в основной базе уже есть ID 550e8400-e29b-41d4-a716-446655440000. Он попадает в события, логи и ответы API. Но при загрузке того же товара в Manticore приложению приходится выдавать ему ещё один, числовой ID.

До Manticore Search 28.5.0 ID документа был беззнаковым 64-битным числом. UUID можно было сохранить в отдельном строковом атрибуте, однако идентификатором документа он от этого не становился. Для UPDATE, REPLACE и DELETE всё равно требовался числовой id.

В результате приходилось хранить соответствие между UUID из основной БД и числовым ID в таблице Manticore. Теперь без него можно обойтись: RT-таблица Manticore умеет использовать UUID как ID документа.

Почему второй ID мешает

Таблица соответствий между айдишниками - это конечно не то чтоб сильно сложно, но только пока приложение загружает данные и выполняет поиск. Сложности начинаются при изменении документов.

Воркер получает событие с UUID, находит соответствующий числовой ID и только после этого отправляет обновление в Manticore. Удаление проходит по той же схеме. Если запись о соответствии пропала или устарела, может обновиться не тот документ либо изменения вообще не попадут в Manticore.

Другой сценарий — превратить UUID в 64-битный хеш. Тогда приложение должно само учитывать возможность коллизии. Можно также завести отдельный последовательный счётчик, но его придётся согласовывать между всеми процессами, которые создают документы.

С числовым ID связана ещё одна тонкость — уже на уровне API. Внутри Manticore это uint64, а SQL показывает его как знаковый BIGINT. Поэтому SQL может вернуть значения больше 2^63-1 в виде отрицательных чисел, и клиенту приходится аккуратно их преобразовывать. UUID передаётся и возвращается строкой, поэтому о знаковом диапазоне и переполнении можно не беспокоиться.

id uuid решает проблему на корню: идентификатор объекта больше не нужно преобразовывать. Один и тот же UUID используется в основной БД, очереди, Manticore, логах и внешнем API.

Что такое UUID

UUID по сути своей - это 128-битный идентификатор, для создания которого не нужен центральный реестр. В текстовом виде он обычно состоит из 36 символов: 32 шестнадцатеричных цифр и четырёх дефисов.

550e8400-e29b-41d4-a716-446655440000

В UUID заложены версия и variant. Версия определяет способ формирования остальных битов. UUIDv4 строится на случайных или псевдослучайных данных. UUIDv7 включает временную составляющую и сохраняет хронологический порядок идентификаторов. В UUIDv8 расположение остальных битов определяет конкретная реализация.

Отсутствие центральной регистрации позволяет назначить ID ещё до записи в общую базу. Например, два независимых сервиса могут создавать объекты параллельно, а какой-нибудь мобильный клиент, который не ловит LTE — подготовить данные без подключения к серверу. После синхронизации объект сохранит тот же идентификатор.

Однако, UUID не стоит считать абсолютной гарантией уникальности. На практике она зависит от корректности выбранного генератора. Также имейте в виду, что UUID не является секретом и не заменяет пароль, токен или проверку прав.

Что появилось в Manticore 28.5.0

Для RT-таблицы теперь можно явно задать тип ID документа:

CREATE TABLE products_uuid (
    id uuid,
    title text,
    sku string,
    price int
);

INSERT INTO products_uuid (id, title, sku, price)
VALUES (
    '550e8400-e29b-41d4-a716-446655440000',
    'Mechanical keyboard',
    'KB-001',
    149
);

После вставки этот же UUID может использоваться в фильтрах по равенству и IN, а также в UPDATE, REPLACE и DELETE. SQL возвращает ID как строку. Передать явный UUID или попросить Manticore создать ID можно и через JSON API; подробные запросы и ответы разберём в следующей статье.

В случае повторного INSERT с уже существующим UUID, Manticore отклонит его, как и раньше с числовым id. Для перезаписи документа по ID используется REPLACE.

Стоит заметить, что тип uuid относится только к ID документа. Объявить обычный пользовательский атрибут с типом uuid нельзя.

Кто создаёт UUID

Есть два варианта:

Как записан документКто создаёт IDЧто делает Manticore
Поле id переданоОсновная БД, клиентская библиотека или другой компонент системыПроверяет формат, версию и variant, затем сохраняет UUID в нижнем регистре
Поле id отсутствуетManticoreСоздаёт UUIDv8 и кодирует в нём внутренний числовой auto-ID

Если UUID уже создаёт приложение, подстраивать его под Manticore не нужно. Формат обычный: пять групп 8-4-4-4-12. Версия может быть любой от v1 до v8, а в позиции variant должна стоять 8, 9, a или b. Регистр не важен: UUID можно прислать заглавными буквами, но Manticore сохранит его строчными.

На этом проверка заканчивается: Manticore проверяет формат UUID, но не качество генерации. За случайность UUIDv4 и корректную временную часть UUIDv7 отвечает клиентская библиотека.

Генерация на стороне сервера устроена иначе. Если поле id не передано, Manticore создаёт UUIDv8 собственной структуры и кодирует в нём штатный числовой auto-ID. Это не случайный UUIDv4 и не секретное значение.

UUIDv8, созданный приложением, Manticore проверит и сохранит как есть; сервер не будет перестраивать его по собственной схеме.

Техническая деталь. Внешним идентификатором остаётся полный UUID: Manticore не заменяет его 64-битным хешем и не требует от приложения хранить таблицу соответствий. Как UUID устроен внутри движка — деталь реализации, на внешний контракт она никак не влияет.

Где это работает

UUID можно использовать как ID документа в обычных RT-таблицах, RT-таблицах с engine='columnar' и таблицах в кластере репликации. С такими ID доступны точный поиск, фильтр IN и привычные операции над документами: INSERT, REPLACE, UPDATE и DELETE.

Нужно учитывать ограничения:

  • тип uuid не подходит для обычных атрибутов: Manticore отклонит объявление вроде guid uuid;
  • в plain , percolate/PQ и shard-таблицах UUID нельзя использовать как ID документа;
  • существующую таблицу нельзя переключить с числового ID на UUID или обратно через ALTER TABLE;
  • диапазонные условия <, <=, > и >=, а также арифметические операции с ID такого типа не поддерживаются;
  • ID документа нельзя изменить через UPDATE — это относится и к UUID, и к числовым ID;
  • для автоматической генерации поле id нужно опустить: значение 0 здесь не работает как специальный маркер.

Об этом легко забыть при переносе старого кода. Для числовой RT-таблицы 0 может означать «создать ID автоматически». В UUID-таблице поле id нужно просто не передавать.

UUIDv7 тоже не делает id пригодным для фильтров по времени. Его можно использовать как внешний идентификатор, но запросы вида id > ... Manticore пока не поддерживает.

Подведём итоги

Если UUID уже есть в основной БД, можете теперь передавать его в Manticore вместе с документом. Если документ сначала появляется в Manticore, не указывайте id и заберите сгенерированный UUID из ответа.

Дальше этот же UUID используйте в UPDATE, REPLACE и DELETE. Выдавать документу отдельный числовой ID и хранить соответствие между двумя идентификаторами больше не нужно.

Полный контракт и актуальные ограничения собраны в документации: UUID document IDs . Поддержка UUID как ID документа появилась в Manticore Search 28.5.0 .

В следующем материале — практическом руководстве по работе с UUID как ID документа — пошагово покажем, как через SQL и JSON задавать и генерировать ID, искать, обновлять, заменять и удалять документы, а также обрабатывать ошибки.

Установить Manticore Search

Установите Manticore Search одной командой в Linux или macOS:

curl https://manticoresearch.com | sh

Для расширенных вариантов установки см. полное руководство по установке и документацию .

Установить Manticore Search