Как определяется уникальность записей в периодическом регистре сведений, подчиненном регистратору

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

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

Понятие ключа записи и общие принципы уникальности

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

Рассмотрим, из чего формируется этот ключ в зависимости от настроек регистра:

  1. Для независимых непериодических регистров: Ключ состоит только из значений Измерений.
  2. Для независимых периодических регистров: Ключ включает в себя Период + Измерения.
  3. Для подчиненных регистратору непериодических регистров: Ключ формируется из пары Регистратор + Измерения.
  4. Для подчиненных регистратору периодических регистров: Ключ включает триаду Период + Регистратор + Измерения.

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

Влияет ли регистратор на уникальность на самом деле?

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

Разберем по шагам: физически в таблице SQL для подчиненного регистра записи будут считаться разными, если у них разные регистраторы. Однако, если мы попытаемся записать две строки с одинаковыми измерениями и одинаковым периодом в рамках одного документа (одного регистратора), система выдаст ошибку уникальности, так как ключ Период + Регистратор + Измерения полностью совпадет.

Рассмотрим пример кода, который иллюстрирует попытку записи в подчиненный регистр:


НаборЗаписей = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(СсылкаНаДокумент);

НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Период = ДатаЗаписи;
НоваяЗапись.Номенклатура = СсылкаТовар;
НоваяЗапись.Цена = 100;

// Если мы добавим еще одну такую же запись в этот же набор:
ЕщеОднаЗапись = НаборЗаписей.Добавить();
ЕщеОднаЗапись.Период = ДатаЗаписи;
ЕщеОднаЗапись.Номенклатура = СсылкаТовар;
ЕщеОднаЗапись.Цена = 200;

// При попытке записи возникнет ошибка "Запись с такими ключевыми полями уже существует"
НаборЗаписей.Записать();

Особенности периодичности «Позиция регистратора»

Выясним, зачем нужна настройка «Позиция регистратора» и как она влияет на уникальность. В 1С существует несколько вариантов периодичности: «Год», «Квартал», «Месяц», «День», «Секунда» и «Позиция регистратора».

Если мы установим периодичность «День», то время в поле Период будет игнорироваться (автоматически приводиться к 00:00:00). Это значит, что один регистратор не сможет сделать две разные записи по одной номенклатуре в разные часы одного дня — их ключи будут конфликтовать.

Настройка «Позиция регистратора» — это наиболее точный режим. В этом случае Период записи в точности соответствует моменту времени документа. Это сочетание даты, времени и ссылки на документ. Рассмотрим преимущества этого подхода:

Проблемы производительности виртуальных таблиц

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

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

  1. Найти максимальную дату (период) для данных измерений.
  2. Если на эту дату есть несколько регистраторов, найти среди них тот, который имеет большую «позицию» (учитывая уникальный идентификатор ссылки).
  3. Выбрать ресурсы именно из этой строки.

На уровне SQL это часто порождает тройную вложенность подзапросов. Если такой срез соединяется в запросе с большой таблицей (например, с остатками товаров), оптимизатор SQL может не справиться с «проталкиванием предикатов», что приведет к полному сканированию таблицы (Table Scan) вместо использования индекса.

Обход уникальности через измерения: стоит ли это делать?

Иногда встречается совет: «Если нужно внести несколько записей на один период, добавьте Регистратор в состав Измерений». Разберем, почему это плохое решение.

Добавление ссылки на документ в измерения действительно сделает каждую запись уникальной. Но при этом виртуальные таблицы перестают работать корректно. Срез последних больше не будет возвращать одну актуальную цену. Поскольку Регистратор стал измерением, система будет считать, что цена от «Документа №1» и цена от «Документа №2» — это разные, независимые сущности (как цены для разных складов). В итоге СрезПоследних вернет все записи всех документов, что делает использование регистра сведений бессмысленным.

Выводы и рекомендации

Подведем итог нашему исследованию механизмов уникальности:

Помните, что правильный выбор структуры регистра на этапе проектирования избавляет от множества проблем с производительностью и достоверностью данных в будущем.

← На главную