При проектировании архитектуры базы данных в 1С перед разработчиком часто встает дилемма: использовать ли встроенный механизм подчиненности (свойство Владелец в метаданных справочника) или создать обычный реквизит со ссылкой на другой объект. На первый взгляд, оба варианта реализуют связь «один-ко-многим», однако дьявол кроется в деталях реализации на уровне платформы, СУБД и бизнес-логики. Рассмотрим подробнее, как сделать правильный выбор, проанализируем технические последствия и разберем методические рекомендации.
Когда мы указываем в свойствах справочника объект-владелец, платформа 1С берет на себя управление целым рядом автоматических функций. Разберем по шагам, что именно мы получаем «из коробки»:
Серии кодов в значение В пределах владельца. Это позволяет разным владельцам иметь подчиненные элементы с одинаковыми кодами. Платформа сама контролирует этот процесс. Попытка имитировать это на собственных реквизитах потребует написания кода в процедуре ПередЗаписью и может создать проблемы с блокировками таблиц при конкурентной работе.Контрагент и БанковскийСчет, и счет подчинен контрагенту, механизм Связи параметров выбора отработает автоматически. Пользователь увидит только те счета, которые принадлежат выбранному контрагенту.Использование обычного реквизита (например, Контрагент в справочнике Договоры вместо стандартного владельца) — это подход, который все чаще встречается в современных типовых конфигурациях (ERP, УТ 11). Разберем, почему архитекторы сознательно отказываются от удобств стандартной подчиненности:
Владелец нельзя назначить ОпределяемыйТип. Это ограничивает возможности разработчиков расширений. Если мы создаем тиражное решение, использование собственного реквизита с определяемым типом позволит внедренцам легко добавлять новые виды «владельцев» без изменения основной конфигурации.Посмотрим на ситуацию со стороны базы данных. При включении стандартной подчиненности платформа 1С автоматически создает составные индексы в таблицах СУБД. Обычно это комбинации вида Владелец + Код или Владелец + Наименование. Это обеспечивает максимально быструю выборку данных именно в контексте конкретного владельца.
Если же мы создаем свой реквизит и просто ставим ему флаг Индексировать, создается одиночный индекс. Для достижения аналогичной производительности на больших объемах данных (например, миллионы записей) нам придется вручную настраивать свойство Индексировать дополнительные поля для создания составных индексов, что усложняет поддержку системы.
Также стоит учесть работу RLS (Restriction at Row Level). Ограничение доступа на уровне записей часто опирается на связи объектов. Платформа оптимизирует запросы RLS, если они используют стандартное поле Владелец. При использовании кастомных реквизитов запросы могут стать более «тяжелыми», так как оптимизатору СУБД сложнее построить оптимальный план без предопределенных связей.
Рассмотрим конкретные примеры, чтобы понять логику выбора.
Сценарий А: Объект не имеет смысла без владельца.
Пример: БанковскиеСчета контрагента. Существование «ничейного» банковского счета в системе абсурдно. Здесь идеально подходит стандартная подчиненность. Это гарантирует целостность данных: удалили контрагента — удалились счета, а коды счетов будут уникальны в разрезе организации.
Сценарий Б: Объект является самостоятельной сущностью, но связан с другим.
Пример: Договоры в современных версиях ERP. Договор может быть заключен с одним юрлицом (контрагентом), но относиться к общему холдингу (партнеру). Иногда требуется сменить контрагента в договоре без создания нового элемента. В этом случае лучше использовать собственный реквизит. Это дает необходимую гибкость для бизнес-логики.
Проанализируем пример кода для имитации связи, если вы выбрали вариант с собственным реквизитом. Чтобы обеспечить фильтрацию в форме выбора, нам потребуется настроить Связи параметров выбора в свойствах реквизита формы или документа:
// В свойствах реквизита "Договор" устанавливаем связь по полю "Контрагент"
// Путь к данным: Объект.Контрагент
// Параметр выбора: Отбор.Контрагент
А для реализации каскадной пометки на удаление придется задействовать подписку на событие:
Процедура ПриУстановкеПометкиУдаленияВладельца(Источник, Отказ, ПометкаУдаления) Экспорт
// Если пометили владельца, ищем всех "подчиненных" по нашему реквизиту
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Справочник.ПодчиненныйГдеРеквизит ГДЕ МойРеквизитВладелец = &Владелец";
Запрос.УстановитьПараметр("Владелец", Источник.Ссылка);
// ... логика установки пометки удаления для найденных элементов
КонецПроцедуры
Подведем итог. Стандартная подчиненность — это инструмент для жестких, иерархических связей, где важна целостность и автоматизация «из коробки». Собственный реквизит — выбор для гибких архитектур, где связь между объектами может меняться, быть ситуативной или требовать расширения через механизмы определяемых типов. В типовых решениях 1С наблюдается тренд: чем сложнее бизнес-логика сущности, тем чаще разработчики отдают предпочтение собственным реквизитам вместо стандартного механизма Владелец.