Могут ли объекты разных типов данных в 1С иметь одинаковый GUID и к каким последствиям это приводит?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При организации обменов данными, сложной выгрузке документов или синхронизации через внешнее соединение COM и веб-сервисы разработчики нередко сталкиваются с ситуацией, когда один документ-источник порождает в базе-приемнике сразу два документа различных типов метаданных. Зачастую для упрощения повторной синхронизации обоим объектам приемника назначают одинаковый УникальныйИдентификатор (GUID), взятый у исходного объекта. Проанализируем, как платформа 1С:Предприятие относится к совпадению идентификаторов у разных типов данных, как это устроено на уровне СУБД и с какими подводными камнями можно столкнуться на практике.

Как устроена ссылка и хранение идентификаторов в платформе 1С

Рассмотрим внутреннюю механику работы ссылочного типа платформы. В системе 1С:Предприятие ссылка не сводится исключительно к шестнадцатибайтному значению GUID. Полноценная ссылка состоит из двух компонентов: типа объекта метаданных и непосредственно уникального идентификатора.

Разберем, как эти данные размещаются в реляционных таблицах базы данных на уровне СУБД (PostgreSQL, MS SQL Server и др.):

  1. Раздельные физические таблицы: Каждый прикладной объект метаданных (например, документ конкретного вида или справочник) хранится в отдельной таблице. Колонка _IDRRef выступает первичным ключом только в пределах этой конкретной таблицы. Ограничений уникальности между разными таблицами СУБД не накладывает, поэтому один и тот же бинарный ключ может законно существовать в разных таблицах.
  2. Поля составного типа: Если в базе настроен реквизит составного ссылочного типа, СУБД выделяет под него три отдельные колонки: _TYPE (признак типа), _RTRef (идентификатор метаданных таблицы) и _RRRef (шестнадцатибайтный УИД). Благодаря связке _RTRef и _RRRef ссылки разных видов метаданных с одинаковым GUID никогда не склеиваются и не конфликтуют в запросах.
  3. Момент времени документа: Значение типа МоментВремени формируется на основе даты документа и его ссылки. Так как ссылка включает в себя идентификатор метаданных, сортировка по моменту времени в запросах и журналах документов работает строго детерминировано и повторяемо.

Таким образом, штатные механизмы платформы — Тестирование и исправление (ТИИ), индексация, соединения таблиц в запросах и механизмы ссылочной целостности — продолжают работать полностью штатно.

Потенциальные риски и скрытые проблемы

Несмотря на то что сама платформа 1С корректно изолирует объекты разных таблиц, проблемы могут возникнуть в сопутствующей инфраструктуре, алгоритмах интеграции и пользовательском коде. Выясним, где могут появиться ошибки:

  1. Двусторонняя синхронизация: Если в будущем потребуется настроить обратный обмен из приемника в источник, алгоритмам поиска станет трудно определить, какой именно документ приемника соответствует исходному документу, если сопоставление опирается только на УИД без явного указания типа.
  2. Внешние сервисы, шины данных и DWH: При передаче данных во внешние системы (Data Lake, Kafka, ClickHouse, RabbitMQ), где идентификатором сущности является простой строковый UUID без метаданных 1С, возникнет коллизия. Помещение записей о разных документах с одинаковым ID в одну общую таблицу фактов или витрину данных приведет к ошибке дублирования первичного ключа (duplicate key error) либо перезаписи данных.
  3. Сериализация через XMLСтрока: Функция платформы XMLСтрока(Ссылка) возвращает лишь строковый GUID. Если внешняя интеграция использует данную функцию для генерации глобального идентификатора без добавления префикса типа метаданных, уникальность ключа теряется.
  4. Самописные алгоритмы разбора навигационных ссылок: Если в конфигурации присутствуют алгоритмы, вырезающие GUID из навигационной ссылки и пытающиеся найти объект во всей базе без указания менеджера конкретного объекта, возникнет неоднозначность.

Варианты решения задачи

Рассмотрим подробнее практические подходы к организации создания связанных объектов в базе-приемнике.

Подход 1. Оставить одинаковые GUID с контролем типа данных

Если интеграция работает строго в одну сторону, не взаимодействует с внешними хранилищами без поддержки типизации, а поиск объектов всегда выполняется через менеджер конкретного документа, данный подход допустим. В таком случае в коде поиска всегда явно задается тип метаданных:


// Поиск выполняется строго через менеджер нужного документа
УИД = Новый УникальныйИдентификатор(СтрокаИдентификатора);
СсылкаНаПриход = Документы.ПриходныйКассовыйОрдер.ПолучитьСсылку(УИД);
СсылкаНаРеализацию = Документы.РеализацияТоваровУслуг.ПолучитьСсылку(УИД);

Так как каждый менеджер обращается исключительно к собственной таблице, поиск отработает корректно и без конфликтов.

Подход 2. Назначение детерминированного производного GUID

Если требуется гарантировать уникальность GUID во всей базе и исключить коллизии во внешних системах, сохранив возможность повторной загрузки без ведения регистров, сгенерируем производный идентификатор. Для одного документа оставим оригинальный УИД источника, а для второго создадим новый, вычисленный алгоритмически на основе исходного GUID и имени метаданных.

Применим метод УстановитьСсылкуНового() перед записью создаваемого объекта:


// Создаем производный детерминированный GUID для второго документа
Хеш = Новый ХешированиеДанных(ХешФункция.MD5);
Хеш.Добавить(Строка(УИДИсточника) + "_СписаниеБезналичныхДенежныхСредств");
СтрокаХеша = Хеш.ХешСумма;

// Формируем корректный формат GUID: 8-4-4-4-12 символов
ШаблонGUID = СтрШаблон("%1-%2-%3-%4-%5",
    Лев(СтрокаХеша, 8),
    Сред(СтрокаХеша, 9, 4),
    Сред(СтрокаХеша, 13, 4),
    Сред(СтрокаХеша, 17, 4),
    Прав(СтрокаХеша, 12)
);

НовыйУИД = Новый УникальныйИдентификатор(ШаблонGUID);
НоваяСсылка = Документы.СписаниеБезналичныхДенежныхСредств.ПолучитьСсылку(НовыйУИД);

ДокументОбъект = Документы.СписаниеБезналичныхДенежныхСредств.СоздатьДокумент();
ДокументОбъект.УстановитьСсылкуНового(НоваяСсылка);

// Заполнение реквизитов документа
ДокументОбъект.Дата = ТекущаяДатаСеанса();
ДокументОбъект.Записать();

Такой подход обеспечивает повторяемость: при повторной выгрузке алгоритм сгенерирует точно такой же идентификатор, что исключит появление дублей и устранит совпадение GUID с другими таблицами.

Подход 3. Использование регистра соответствий (стандарт БСП)

Разберем наиболее надежный и архитектурно правильный способ, применяемый в Библиотеке стандартных подсистем (БСП). Для связи сущностей «один-ко-многим» каждому объекту в базе-приемнике присваивается собственный случайный GUID, а связь сохраняется в регистре сведений (по аналогии с типовым регистром СоответствияОбъектовИнформационныхБаз).

Схема реализации по шагам:

  1. При первой загрузке создаются документы со стандартными новыми ссылками платформы.
  2. В регистр соответствий записывается связь: идентификатор источника, тип метаданных приемника и полученная ссылка приемника.
  3. При повторной загрузке система выполняет поиск ссылки через регистр соответствий по идентификатору источника и имени таблицы. Если запись найдена — обновляется существующий документ, если нет — создается новый с фиксацией соответствия.

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

← На главную