При эксплуатации систем на базе 1С:Предприятие разработчики часто сталкиваются с ситуацией: после миграции серверной части на новое оборудование или в облако привычная сортировка в запросах по полю Ссылка начинает вести себя непредсказуемо. Документы, созданные сегодня, внезапно оказываются в начале списка, хотя должны быть в конце, а старые записи «улетают» вниз. На первый взгляд это кажется программным сбоем, но на самом деле мы имеем дело с особенностями работы СУБД и алгоритмами генерации уникальных идентификаторов.
В этой статье мы подробно разберем, почему нельзя полагаться на сортировку по ссылке для определения хронологии, как на это влияет аппаратная часть сервера и какие инструменты платформы 1С помогут нам гарантированно получить правильный порядок записей.
Для начала проанализируем, что представляет собой Ссылка. В системе 1С это уникальный идентификатор (UUID/GUID) длиной 128 бит. Платформа использует UUID версии 1 (time-based), который генерируется на основе временной метки и уникального идентификатора узла. Структура этого идентификатора включает в себя:
Когда мы переносим сервер 1С на новое «железо», у него меняется сетевая карта, а значит, и MAC-адрес. Поскольку этот адрес является частью каждого нового генерируемого UUID, «хвост» идентификатора становится другим. Важный момент: если шестнадцатеричное значение MAC-адреса нового сервера меньше, чем у старого, то с точки зрения двоичного сравнения новые ссылки могут оказаться «меньше» старых. Именно поэтому при выполнении команды УПОРЯДОЧИТЬ ПО Ссылка новые документы начинают отображаться в начале списка.
Давайте посмотрим на ситуацию со стороны системы управления базами данных. Большинство корпоративных систем 1С работают под управлением MS SQL Server. В этой СУБД тип данных UNIQUEIDENTIFIER (в котором хранятся ссылки 1С) сортируется специфическим образом.
SQL Server при сравнении GUID отдает приоритет последней группе байтов (тем самым 6 байтам, где зашит Node ID или MAC-адрес). Это сделано для оптимизации, но для разработчика 1С это означает следующее: изменение оборудования — это критический сдвиг. Как только меняется MAC-адрес сервера, вся логика «визуального» возрастания ссылок полностью ломается. Ссылка перестает быть инкрементальным значением, на которое можно опираться при построении отчетов или выборок.
Самый простой и эффективный способ исправить ситуацию в запросах — использовать зарезервированное слово АВТОУПОРЯДОЧИВАНИЕ. Рассмотрим подробнее, как это работает внутри платформы.
Когда вы добавляете это условие в конец запроса, 1С перестает просто сортировать записи по двоичному коду ссылки. Вместо этого платформа анализирует метаданные объекта и подставляет правила сортировки, определенные в конфигураторе:
УПОРЯДОЧИТЬ ПО Дата, Ссылка.УПОРЯДОЧИТЬ ПО Наименование или УПОРЯДОЧИТЬ ПО Код (в зависимости от настроек основного представления).Проанализируем пример запроса, который решит проблему автора темы:
ВЫБРАТЬ
РеализацияТоваровУслуг.Ссылка КАК Ссылка,
РеализацияТоваровУслуг.Дата КАК Дата,
РеализацияТоваровУслуг.Номер КАК Номер
ИЗ
Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
УПОРЯДОЧИТЬ ПО
Ссылка
АВТОУПОРЯДОЧИВАНИЕ
Использование этого механизма гарантирует, что даже если ссылки имеют «неправильный» с точки зрения хронологии порядок байтов, документы сначала будут выстроены по дате, а ссылка будет использоваться только как вспомогательный критерий для документов, записанных в одну и ту же секунду.
Если нам нужно найти «самый последний» созданный документ среди нескольких типов (как описывал автор в сообщении 10), нам стоит вспомнить о понятии МоментВремени. Этот объект в 1С объединяет дату/время и ссылку, позволяя однозначно позиционировать объект на оси времени.
При создании сложных запросов, где нужно получить срез последних данных или определить порядок следования документов с одинаковым временем, мы рекомендуем использовать явную сортировку по двум полям. Выясним, как это выглядит в коде:
ВЫБРАТЬ
Продажи.Ссылка,
Продажи.Дата
ИЗ
(ВЫБРАТЬ Ссылка, Дата ИЗ Документ.АктВыполненныхРабот
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ Ссылка, Дата ИЗ Документ.РеализацияТоваровУслуг) КАК Продажи
УПОРЯДОЧИТЬ ПО
Продажи.Дата,
Продажи.Ссылка
Такой подход делает ваш код независимым от того, на каком сервере работает база и какой MAC-адрес у сетевой карты. Помните: упорядочивание по ссылке — это «черный ящик». Оно пригодно только в одном случае — если вам абсолютно не важен порядок, но нужно, чтобы он был детерминированным (одинаковым при каждом запуске запроса).
Стоит также упомянуть, что начиная с версии 8.3, 1С:Предприятие старается генерировать так называемые «последовательные» ссылки. Это необходимо для борьбы с фрагментацией индексов в СУБД. Когда новые записи вставляются в конец индекса, база работает быстрее. Однако эта последовательность гарантируется только в рамках работы одной операционной системы и одного экземпляра сервера.
Как только вы переносите базу или просто перезагружаете сервер, алгоритм генерации может начать новую последовательность из другого диапазона. Это еще раз подтверждает правило: никогда не используйте Ссылка как единственный критерий хронологического порядка.
Подводя итог нашему анализу, сформулируем основные правила работы с упорядочиванием данных в 1С:
Ссылка для получения последнего созданного элемента. Ссылка — это идентификатор, а не счетчик.Дата.АВТОУПОРЯДОЧИВАНИЕ.МоментВремени, а не просто дату.Соблюдение этих принципов позволит вам создавать отказоустойчивые системы, которые не «сломаются» при плановом переезде на новый сервер или обновлении оборудования.