Ограничение доступа на уровне записей (RLS) — одна из самых ресурсоемких операций в системе 1С:Предприятие. Часто перед разработчиками встает задача ограничить видимость контрагентов для конкретного пользователя или роли, разрешив доступ только к определенным группам (папкам). В данной статье мы разберем, почему «наивные» способы реализации этой задачи могут привести к падению производительности, и рассмотрим наиболее эффективные методы настройки прав доступа.
Рассмотрим ситуацию, когда разработчик пытается проверить вхождение элемента в группу, перебирая уровни иерархии вручную. Проанализируем пример кода, который часто встречается в «быстрых» решениях:
ГДЕ ВЫБОР
КОГДА (&ОграничениеКА ЕСТЬ NULL) И (&ОграничениеКА2 ЕСТЬ NULL) ТОГДА ИСТИНА
КОГДА (Контрагент.Родитель В (&ОграничениеКА)) ТОГДА ЛОЖЬ
КОГДА (Контрагент.Родитель.Родитель В (&ОграничениеКА)) ТОГДА ЛОЖЬ
КОГДА (Контрагент.Родитель.Родитель.Родитель В (&ОграничениеКА)) ТОГДА ЛОЖЬ
ИНАЧЕ ИСТИНА
КОНЕЦ
Почему такой подход считается крайне неудачным? Во-первых, он жестко ограничивает глубину вложенности. Если пользователь создаст подпапку на пятом уровне, ограничение перестанет работать. Во-вторых, с точки зрения СУБД, каждое обращение через точку (Родитель.Родитель) порождает левое соединение (LEFT JOIN). В результате простой запрос на выборку контрагентов превращается в «монстра» с десятком соединений, что катастрофически замедляет работу системы при увеличении количества записей.
Для работы с иерархическими справочниками в языке запросов 1С предусмотрен специальный оператор В ИЕРАРХИИ. Он позволяет проверить принадлежность элемента к группе на любом уровне вложенности одним условием. Разберем, как должен выглядеть правильный шаблон RLS:
ТекущаяТаблица ГДЕ (НЕ ТекущаяТаблица.Ссылка В ИЕРАРХИИ (&СписокЗапрещенныхГрупп))
Использование этого оператора позволяет системе 1С оптимизировать запрос на уровне SQL, используя специальные алгоритмы работы с иерархией. Это избавляет нас от необходимости знать точную структуру папок в справочнике Контрагенты.
Выясним причину, по которой не стоит хранить сложные вычисления внутри самого текста RLS. RLS выполняется при каждом обращении к таблице. Если в условии RLS будет сложный запрос, система будет выполнять его тысячи раз в день. Вместо этого мы можем использовать ПараметрыСеанса.
Алгоритм действий следующий:
ПараметрыСеанса.ДоступныеГруппыКонтрагентов.Проанализируем пример такого условия:
ГДЕ Ссылка В ИЕРАРХИИ (&ПараметрыСеанса.ДоступныеГруппыКонтрагентов)
Это значительно снижает нагрузку на базу данных, так как список групп подставляется в запрос в готовом виде.
В современных конфигурациях, таких как 1С:Управление торговлей 11 или Бухгалтерия предприятия 3.0, реализован механизм Библиотеки стандартных подсистем (БСП). Рассмотрим подробнее, как работает производительный режим RLS в этих системах.
Вместо прямой проверки иерархии папок, БСП использует вспомогательные таблицы — регистры сведений (например, КлючиДоступаКОбъектам). Система заранее рассчитывает, к каким объектам у пользователя есть доступ, и записывает это в кэш. В этом случае ограничение по двум папкам настраивается через Группы доступа:
Группа доступа.Это самый «чистый» и поддерживаемый метод, так как он не требует написания кода на языке запросов и легко администрируется в пользовательском режиме.
Если иерархия справочника часто меняется (бухгалтеры перемещают контрагентов между папками), то привязка прав к структуре папок становится ненадежной. Посмотрим на альтернативу — сегментацию.
Мы можем создать дополнительный реквизит у контрагента (например, РегионДоступа) или использовать механизм Сегменты партнеров (в УТ 11). В RLS мы будем проверять не положение в дереве групп, а значение этого реквизита:
ГДЕ ДополнительныйРеквизит = &ЗначениеИзНастроекПользователя
Это делает систему прав независимой от того, как визуально организован справочник в интерфейсе.
Для того чтобы RLS не «тормозил» систему, придерживайтесь следующих правил:
Родитель или ваши дополнительные реквизиты), обязательно должны быть индексированы.Консоль запросов с установленной галочкой «Выполнить с учетом RLS». Это позволит вам увидеть итоговый SQL-запрос, который отправляется на сервер.ИЛИ в тексте RLS, тем быстрее СУБД построит план запроса.Таким образом, мы выяснили, что наиболее эффективным и современным способом является использование механизмов БСП или работа через параметры сеанса с оператором В ИЕРАРХИИ. Это обеспечивает гибкость настройки и высокую скорость работы программы даже при больших объемах данных.