В процессе проектирования систем интеграции, разработки обменов данными и администрирования баз данных «1С:Предприятие» разработчики часто сталкиваются с фундаментальным вопросом: гарантирует ли платформа абсолютную уникальность GUID (UUID) для всех объектов информационной базы, или же эта уникальность ограничена конкретным типом метаданных?
В этой статье мы подробно разберем внутреннее устройство механизмов генерации уникальных идентификаторов в 1С, выясним, могут ли совпадать GUID у разных документов (например, у «Перемещения товаров» и «Реализации товаров и услуг»), проанализируем низкоуровневую структуру хранения ссылок в СУБД и рассмотрим новые возможности платформы для работы с UUID.
Для начала проанализируем, как контролируется уникальность записей на уровне системы управления базами данных (СУБД). Платформа 1С хранит данные различных типов объектов (справочников, документов) в отдельных физических таблицах СУБД (например, таблицы вида _Document150 или _Reference85). Ссылка на объект базы данных записывается в системное поле _IDRRef, которое имеет тип данных binary(16).
Контроль уникальности (первичный ключ, или Primary Key) накладывается СУБД только в пределах одной конкретной таблицы. Это означает, что:
Таким образом, совпадение UUID у объектов разных типов — это не просто теоретическая вероятность, а полностью допустимое и запланированное поведение платформы.
Разберем ситуацию, когда разработчику требуется намеренно связать два разных объекта базы данных одинаковыми идентификаторами. На практике это часто используется в механизмах распределенных баз данных (РИБ) или при интеграции «один-к-одному» между разными конфигурациями (например, при синхронизации «Поступления товаров и услуг» в одной базе и «Реализации товаров и услуг» в другой).
Для программной установки предопределенного GUID в 1С используется метод УстановитьСсылкуНового() менеджера объекта. Рассмотрим практический пример кода:
// Шаг 1. Получаем необходимый уникальный идентификатор (например, из другого документа)
НужныйGUID = Новый УникальныйИдентификатор("d3b07384-d113-11e0-9124-0015e9b9b9bf");
// Шаг 2. Формируем ссылку для нового документа "ПоступлениеТоваровУслуг" с этим GUID
СсылкаНового = Документы.ПоступлениеТоваровУслуг.ПолучитьСсылку(НужныйGUID);
// Шаг 3. Создаем новый документ и жестко привязываем к нему подготовленную ссылку
НовыйДокумент = Документы.ПоступлениеТоваровУслуг.СоздатьДокумент();
НовыйДокумент.УстановитьСсылкуНового(СсылкаНового);
// Шаг 4. Заполняем реквизиты и записываем объект в базу данных
НовыйДокумент.Дата = ТекущаяДата();
НовыйДокумент.Организация = Справочники.Организации.ПустаяСсылка();
НовыйДокумент.Записать();
Если в системе уже существовал документ другого типа (например, «Реализация товаров и услуг») с идентификатором d3b07384-d113-11e0-9124-0015e9b9b9bf, то после выполнения данного кода в базе данных будут находиться два совершенно разных документа разных типов, но с абсолютно одинаковыми GUID. Платформа без проблем запишет этот объект, так как СУБД проверяет уникальность поля _IDRRef только внутри таблицы поступлений.
Что происходит, если мы не устанавливаем GUID вручную, а полагаемся на стандартные механизмы платформы? При интерактивном создании документов или вызове метода Записать() платформа автоматически генерирует GUID для новых объектов.
В соответствии со стандартом RFC 4122, платформа 1С использует две разные версии UUID в зависимости от контекста создания:
Новый УникальныйИдентификатор() без параметров, а также для предопределенных элементов метаданных.Рассмотрим подробнее сценарий, при котором возможна автогенерация дублирующегося GUID в штатном режиме без ручного вмешательства программиста. Генерация UUID версии 1 жестко привязана к системному времени сервера приложений и сетевому адресу (MAC-адресу) сетевой карты хоста.
Проанализируем следующую цепочку событий:
Вероятность такого совпадения в стабильной серверной инфраструктуре крайне мала (менее 0.01%), однако в крупных корпоративных системах с высокой интенсивностью транзакций и частыми изменениями сетевой конфигурации или виртуального окружения такие ситуации периодически фиксируются.
При выполнении прямых SQL-запросов к базе данных 1С разработчики часто сталкиваются с тем, что строковое представление GUID в коде 1С не совпадает с бинарным представлением в поле _IDRRef. Выясним причину этого феномена.
Стандартный UUID состоит из 16 байт (128 бит) и условно делится на 4 группы:
Data1 (4 байта) - Data2 (2 байта) - Data3 (2 байта) - Data4 (8 байт)
Например, строковый GUID в 1С выглядит так: d3b07384-d113-11e0-9124-0015e9b9b9bf.
При записи этого значения в базу данных СУБД платформа 1С выполняет побайтовую перестановку (Byte Swap):
Data4 (8 байт) записывается в начало бинарного поля без изменений: 91240015e9b9b9bf.Data3, Data2, Data1) разворачиваются (переставляются байты от конца к началу) и дописываются следом.В результате в СУБД в поле _IDRRef запишется совершенно другая последовательность байт. Для прямого сопоставления GUID из внешних систем с базой данных 1С на уровне SQL приходится применять специальные функции декодирования, восстанавливающие оригинальный порядок байт.
Долгое время получение строкового представления уникального идентификатора непосредственно в языке запросов 1С было нерешаемой задачей. Разработчикам приходилось выгружать результат запроса в память и использовать XML-сериализацию, либо писать сложные SQL-представления.
Начиная с версии платформы 8.3.22, разработчикам доступна встроенная функция языка запросов УникальныйИдентификатор(). Рассмотрим пример её практического использования:
// Пример получения строкового представления GUID прямо в запросе 1С
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Реализация.Ссылка КАК Ссылка,
| УникальныйИдентификатор(Реализация.Ссылка) КАК ТекстовыйGUID
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ
| Реализация.Проведен = ИСТИНА";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// В переменной ТекстовыйGUID будет лежать готовая строка формата "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
Сообщить("Документ: " + Выборка.Ссылка + " имеет GUID: " + Выборка.ТекстовыйGUID);
КонецЦикла;
Этот механизм значительно упрощает разработку сложных аналитических отчетов в СКД и интеграционных решений, где сопоставление данных происходит по текстовым идентификаторам внешних систем.
Проанализировав особенности работы платформы «1С:Предприятие» с GUID, мы можем зафиксировать следующие ключевые правила:
УстановитьСсылкуНового()), либо при редких аппаратных сбоях времени на сервере приложений во время автогенерации последовательных UUID версии 1.