Как в 1С:Предприятие формируются уникальные идентификаторы и как ими управлять

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

Вопрос формирования уникальных идентификаторов (UUID или GUID) является фундаментальным для понимания того, как платформа 1С обеспечивает уникальность объектов в базе данных и как это влияет на производительность всей системы. В рамках данной статьи мы подробно разберем механизмы генерации идентификаторов, выясним, почему разные методы платформы выдают разные результаты, и проанализируем, как правильно создавать идентификаторы вне среды 1С.

Механизмы генерации UUID в платформе 1С

Для начала проанализируем два основных способа получения нового идентификатора средствами встроенного языка. Несмотря на то что результат в обоих случаях выглядит как строка из 36 символов, алгоритмы их получения существенно различаются. Рассмотрим их подробнее.

  1. Использование конструктора Новый УникальныйИдентификатор(). До версии платформы 8.3.18 этот метод генерировал идентификатор, который был близок к версии 4 стандарта RFC 4122, но имел свои особенности. Начиная с версии 8.3.18, платформа перешла на честную реализацию UUID v4. Это означает, что идентификатор формируется на основе криптографически стойкого генератора случайных чисел. В таком GUID почти все биты (за исключением версии и варианта) являются случайными.
  2. Метод ОбъектМетаданных.ПолучитьСсылку().УникальныйИдентификатор. Этот механизм работает иначе. Платформа генерирует так называемый последовательный идентификатор, который концептуально близок к UUID v1. Он базируется на временной метке и идентификаторе узла (MAC-адресе). Использование этого метода позволяет получать идентификаторы, которые идут друг за другом в хронологическом порядке.

Выясним причину такого разделения. Последовательные идентификаторы критически важны для производительности СУБД при массовой вставке данных, в то время как полностью случайные идентификаторы удобны для разовых операций, где порядок не имеет значения.

Структура идентификатора версии 1 (Sequential UUID)

Разберем, из чего состоит последовательный идентификатор, который мы получаем через ПолучитьСсылку(). Согласно стандарту, он включает в себя:

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

Особенности хранения идентификаторов в SQL-базе (Byte Swapping)

Проанализируем, как 1С записывает УникальныйИдентификатор в таблицы базы данных. Это один из самых интересных моментов. Если вы сделаете прямой SQL-запрос к таблице справочника, вы увидите, что в поле _IDRRef (тип BINARY(16)) данные лежат не в том порядке, в котором их показывает интерфейс 1С. Для сопоставления физических имен таблиц и полей СУБД с объектами конфигурации можно использовать инструмент для трансляции SQL-запросов в термины метаданных 1С.

Это сделано для оптимизации кластерного индекса. В стандартном UUID v1 самые быстроменяющиеся части (младшие разряды времени) стоят в начале. Если записывать их «как есть», то каждая новая запись будет попадать в случайное место индекса, что приведет к катастрофической фрагментации страниц данных на диске. Чтобы этого избежать, 1С применяет алгоритм перестановки байтов (Byte Swapping):

Алгоритм трансформации выглядит следующим образом: группы байтов, отвечающие за время (первые три блока UUID), перемещаются в конец, а более стабильные группы (4-я и 5-я) перемещаются в начало. Таким образом, с точки зрения SQL-сервера, новые идентификаторы становятся возрастающими, и вставка происходит преимущественно в конец индекса. Это позволяет избежать «page splits» (расщепления страниц) и поддерживает высокую скорость записи.

Создание уникального идентификатора вне 1С

Если перед нами стоит задача сгенерировать УникальныйИдентификатор во внешней системе (например, на Python, C# или прямо в SQL) для последующей загрузки в 1С, мы должны придерживаться определенных правил.

Вариант А: Случайная генерация (аналог v4). Если вы загружаете небольшое количество объектов, можно использовать стандартные функции генерации GUID в вашем языке программирования. Например, в SQL Server это функция NEWID(). Платформа 1С без проблем примет такой идентификатор, так как проверка уникальности производится по факту записи. Однако помните о производительности: при вставке миллионов строк со случайными GUID индекс базы данных начнет «тормозить».

Вариант Б: Последовательная генерация (аналог v1). Для массовой загрузки данных лучше использовать последовательные GUID. В MS SQL Server для этого предусмотрена функция NEWSEQUENTIALID(). Рассмотрим пример кода на SQL, который можно использовать в хранимых процедурах для подготовки данных:


DECLARE @MyGuid UNIQUEIDENTIFIER;
SET @MyGuid = NEWSEQUENTIALID();
-- Теперь этот GUID можно передавать в 1С или писать в таблицу

При использовании внешней генерации важно помнить, что 1С хранит ссылки в формате BINARY(16). Если вы формируете данные для прямой вставки в SQL-таблицы (что крайне не рекомендуется, но иногда практикуется), вам придется вручную реализовать алгоритм перестановки байтов, принятый в 1С, иначе система не сможет правильно сопоставить ссылку и объект.

Можно ли изменить правила формирования в самой 1С?

Выясним, насколько гибко можно настраивать этот процесс в самой платформе. Ответ однозначный: изменить внутренний алгоритм платформы нельзя. Мы не можем заставить метод Новый УникальныйИдентификатор() выдавать последовательные значения, а ПолучитьСсылку() — случайные. Эти правила жестко зашиты в ядро платформы.

Однако мы можем «назначать» свой идентификатор объекту. Посмотрим на примере, как это сделать программно при создании нового элемента справочника:


// Создадим свой идентификатор (например, полученный из внешней системы)
МойUID = Новый УникальныйИдентификатор("550e8400-e29b-41d4-a716-446655440000");

// Создадим ссылку заранее, используя этот UID
НоваяСсылка = Справочники.Контрагенты.ПолучитьСсылку(МойUID);

// Создадим объект и назначим ему подготовленную ссылку
НовыйОбъект = Справочники.Контрагенты.СоздатьЭлемент();
НовыйОбъект.УстановитьСсылкуНового(НоваяСсылка);

// Заполним данные и запишем
НовыйОбъект.Наименование = "Внешний Контрагент";
НовыйОбъект.Записать();

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

Влияние на производительность и фрагментацию

Проанализируем ситуацию с точки зрения системного администратора и разработчика БД. Использование случайных идентификаторов (v4) ведет к следующим проблемам:

Поэтому, если вы проектируете систему интеграции, всегда старайтесь генерировать идентификаторы последовательно. В 1С это достигается использованием метода ПолучитьСсылку() без параметров — в этом случае платформа сама заботится о «правильности» идентификатора для SQL-сервера. Если же фрагментация индексов в базе уже возникла из-за некорректных вставок, для регламентного обслуживания подойдёт скрипт адаптивного обновления индексов MS SQL.

Резюме

Подводя итог, отметим, что УникальныйИдентификатор в 1С — это не просто случайный набор знаков. В современных версиях платформы (8.3.18+) мы имеем дело с четким разделением на случайные (v4) и последовательные (v1) GUID. Понимание механизма Byte Swapping при хранении в СУБД позволяет эффективно проектировать системы обмена данными и избегать деградации производительности при росте базы данных. Мы рассмотрели способы управления этим процессом и выяснили, что, хотя правила платформы изменить нельзя, мы обладаем всеми инструментами для назначения собственных идентификаторов.

← На главную