Вопрос формирования уникальных идентификаторов (UUID или GUID) является фундаментальным для понимания того, как платформа 1С обеспечивает уникальность объектов в базе данных и как это влияет на производительность всей системы. В рамках данной статьи мы подробно разберем механизмы генерации идентификаторов, выясним, почему разные методы платформы выдают разные результаты, и проанализируем, как правильно создавать идентификаторы вне среды 1С.
Для начала проанализируем два основных способа получения нового идентификатора средствами встроенного языка. Несмотря на то что результат в обоих случаях выглядит как строка из 36 символов, алгоритмы их получения существенно различаются. Рассмотрим их подробнее.
Новый УникальныйИдентификатор(). До версии платформы 8.3.18 этот метод генерировал идентификатор, который был близок к версии 4 стандарта RFC 4122, но имел свои особенности. Начиная с версии 8.3.18, платформа перешла на честную реализацию UUID v4. Это означает, что идентификатор формируется на основе криптографически стойкого генератора случайных чисел. В таком GUID почти все биты (за исключением версии и варианта) являются случайными.ОбъектМетаданных.ПолучитьСсылку().УникальныйИдентификатор. Этот механизм работает иначе. Платформа генерирует так называемый последовательный идентификатор, который концептуально близок к UUID v1. Он базируется на временной метке и идентификаторе узла (MAC-адресе). Использование этого метода позволяет получать идентификаторы, которые идут друг за другом в хронологическом порядке.Выясним причину такого разделения. Последовательные идентификаторы критически важны для производительности СУБД при массовой вставке данных, в то время как полностью случайные идентификаторы удобны для разовых операций, где порядок не имеет значения.
Разберем, из чего состоит последовательный идентификатор, который мы получаем через ПолучитьСсылку(). Согласно стандарту, он включает в себя:
Рассмотрим важный нюанс: платформа 1С не обращается к операционной системе за каждым новым GUID. Для оптимизации сервер приложений запрашивает у системы или генерирует самостоятельно «пулы» (блоки) идентификаторов. Если мы создаем объекты в одном сеансе или в рамках одного рабочего процесса, они будут иметь очень близкие значения. Однако при перезагрузке сервера или при работе в кластере с несколькими процессами в последовательности могут возникать «разрывы».
Проанализируем, как 1С записывает УникальныйИдентификатор в таблицы базы данных. Это один из самых интересных моментов. Если вы сделаете прямой SQL-запрос к таблице справочника, вы увидите, что в поле _IDRRef (тип BINARY(16)) данные лежат не в том порядке, в котором их показывает интерфейс 1С. Для сопоставления физических имен таблиц и полей СУБД с объектами конфигурации можно использовать инструмент для трансляции SQL-запросов в термины метаданных 1С.
Это сделано для оптимизации кластерного индекса. В стандартном UUID v1 самые быстроменяющиеся части (младшие разряды времени) стоят в начале. Если записывать их «как есть», то каждая новая запись будет попадать в случайное место индекса, что приведет к катастрофической фрагментации страниц данных на диске. Чтобы этого избежать, 1С применяет алгоритм перестановки байтов (Byte Swapping):
Алгоритм трансформации выглядит следующим образом: группы байтов, отвечающие за время (первые три блока UUID), перемещаются в конец, а более стабильные группы (4-я и 5-я) перемещаются в начало. Таким образом, с точки зрения SQL-сервера, новые идентификаторы становятся возрастающими, и вставка происходит преимущественно в конец индекса. Это позволяет избежать «page splits» (расщепления страниц) и поддерживает высокую скорость записи.
Если перед нами стоит задача сгенерировать УникальныйИдентификатор во внешней системе (например, на 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С, иначе система не сможет правильно сопоставить ссылку и объект.
Выясним, насколько гибко можно настраивать этот процесс в самой платформе. Ответ однозначный: изменить внутренний алгоритм платформы нельзя. Мы не можем заставить метод Новый УникальныйИдентификатор() выдавать последовательные значения, а ПолучитьСсылку() — случайные. Эти правила жестко зашиты в ядро платформы.
Однако мы можем «назначать» свой идентификатор объекту. Посмотрим на примере, как это сделать программно при создании нового элемента справочника:
// Создадим свой идентификатор (например, полученный из внешней системы)
МойUID = Новый УникальныйИдентификатор("550e8400-e29b-41d4-a716-446655440000");
// Создадим ссылку заранее, используя этот UID
НоваяСсылка = Справочники.Контрагенты.ПолучитьСсылку(МойUID);
// Создадим объект и назначим ему подготовленную ссылку
НовыйОбъект = Справочники.Контрагенты.СоздатьЭлемент();
НовыйОбъект.УстановитьСсылкуНового(НоваяСсылка);
// Заполним данные и запишем
НовыйОбъект.Наименование = "Внешний Контрагент";
НовыйОбъект.Записать();
Этот прием позволяет нам полностью контролировать УникальныйИдентификатор объекта, обходя стандартные правила платформы. Главное условие — этот идентификатор должен быть действительно уникальным в рамках данного справочника, иначе мы получим ошибку нарушения уникальности при записи.
Проанализируем ситуацию с точки зрения системного администратора и разработчика БД. Использование случайных идентификаторов (v4) ведет к следующим проблемам:
Поэтому, если вы проектируете систему интеграции, всегда старайтесь генерировать идентификаторы последовательно. В 1С это достигается использованием метода ПолучитьСсылку() без параметров — в этом случае платформа сама заботится о «правильности» идентификатора для SQL-сервера. Если же фрагментация индексов в базе уже возникла из-за некорректных вставок, для регламентного обслуживания подойдёт скрипт адаптивного обновления индексов MS SQL.
Подводя итог, отметим, что УникальныйИдентификатор в 1С — это не просто случайный набор знаков. В современных версиях платформы (8.3.18+) мы имеем дело с четким разделением на случайные (v4) и последовательные (v1) GUID. Понимание механизма Byte Swapping при хранении в СУБД позволяет эффективно проектировать системы обмена данными и избегать деградации производительности при росте базы данных. Мы рассмотрели способы управления этим процессом и выяснили, что, хотя правила платформы изменить нельзя, мы обладаем всеми инструментами для назначения собственных идентификаторов.