Одним из наиболее массовых примеров применения периодических регистров сведений является организация хранения истории изменения некоторых данных, связанных с объектами. В 1С:Предприятии 7.7 для этого использовались периодические реквизиты справочников. При проектировании регистров сведений возникают серьезные вопросы с тем, как правильно отражать данные предметной области в структуре регистров.
Регистр сведений в 1С:Предприятии 8 может содержать несколько измерений, ресурсов и реквизитов. Возникает вопрос, сколько нужно создавать регистров сведений, чтобы хранить несколько значений, которые изменяются во времени. Можно создать один регистр на все значения и создать в нем несколько ресурсов, а можно создать по отдельному регистру для каждого значения, включив в каждый из них по одному ресурсу. Особенно актуально этот вопрос стоит при переносе решений из 1С:Предприятия 7.7, когда регистры сведений должны заменить периодические реквизиты.
Каждый регистр сведений представляет собой отдельную таблицу. В периодическом регистре сведений каждая запись содержит информацию о том, что с такого-то момента времени по такой-то комбинации измерений ресурсы имеют такие-то значения. При этом значение каждого ресурса обязательно записывается и с точки зрения модели регистра считается установленным с указанного момента. В записи регистра сведений нельзя отметить, что значение какого-то ресурса не менялось. При получении среза регистра (состояния ресурсов на некоторый момент времени) будут найдены последние записи по комбинациям измерений и выданы их ресурсы.
При создании регистров нет единого правила, например, «делать один регистр» или «делать много регистров». При проектировании периодического регистра следует руководствоваться тем, что каждая запись должна отражать в базе данных факт установки значений всех ресурсов на некоторый момент времени. Следует подчеркнуть, что запись регистра будет отражать факт установки пользователем значений всех ресурсов, независимо от их предыдущих значений.
При проектировании регистра нужно проанализировать то, как реально меняются значения во времени и выработать определенную модель отражения в базе данных изменения значений. Очень важно, чтобы отражение предметной области регистром сведений правильно понималось пользователем. От этого во многом зависит адекватность использования регистра.
Рассмотрим классический пример регистра, хранящего курсы валют. По каждой валюте нам нужно хранить курс и кратность. Мы можем сделать два регистра: один для хранения истории изменения курсов, другой для хранения истории изменения кратности. Но можем сделать и один регистр, хранящий в каждой записи и значение курса, и значение кратности. Очевидно, что кратность будет меняться значительно реже. Вместе с тем, один регистр будет проще реализовывать, и с ним будет проще работать пользователю. Возможны оба варианта. В первом — мы будем считать, что есть отдельный факт установки курса и отдельный факт установки кратности. Разумеется, они могут редактироваться в одной форме или записываться одним документом, но пользователь, посмотрев на списки регистров, должен будет понять, что история изменений хранится независимо. Во втором — мы будем считать, что есть один факт установки курса и кратности. Пользователь при вводе нового курса должен будет ввести и новую кратность. Конечно, мы можем реализовать сервис подстановки при вводе новой записи предыдущей кратности, чтобы не заполнять ее каждый раз, но важно, чтобы пользователь и в процессе ввода записи и процессе просмотра списка понимал, что каждая запись устанавливает оба значения, действие которых начинается с указанного момента.
В некоторых случаях несколько значений однозначно связаны между собой, и отдельная история их изменений бессмысленна. Например, данные паспорта (серия, номер, дата выдачи и т.д.) практически всегда меняются вместе. Однако часто значения, по которым будет храниться история изменений, могут объединяться с целью уменьшения количества независимо хранимых историй (как в примере с курсом и кратностью). Особенно целесообразно провести такое объединение, если значений, по которым нужно хранить историю, достаточно много. Желательно, чтобы такая группировка производилась на основании некоторой смысловой общности значений. И очень важно, чтобы эта группировка была наглядно представлена пользователю. Например, если создается периодический регистр сведений, хранящий цену товара и стандартную скидку, то следует в форме редактирования записи (или соответственно документа, с помощью которого редактируется регистр сведений) четко указать, что устанавливается новая цена и новая скидка, действующие с такой-то даты.
Заметим, что группировка нескольких значений в одном регистре сведений целесообразна не только с точки зрения уменьшения количества таблиц и повышения производительности. Пользователю во многих случаях удобнее иметь дело с единым фактом изменения нескольких значений, чем с отдельными историями.
Еще одним моментом, который следует учитывать при проектировании регистров сведений, является потенциальная возможность введения новых измерений. Например, если мы храним в периодическом регистре сведений цену товара, то мы в дальнейшем можем ввести еще одно измерение — тип цены, чтобы использовать несколько цен, типы которых будет создавать пользователь. В 1С:Предприятии 7.7 при использовании периодических реквизитов такое было практически невозможно. В 1С:Предприятии 8 такое изменение не будет очень сложным. Однако, при проектировании структуры регистров следует изначально учитывать возможность такого развития. В частности, это может являться критерием для определения возможности группировки в один регистр истории изменения нескольких значений. Если потенциальная возможность введения новых измерений потребует разделения регистра, то, возможно, следует изначально сделать два регистра. Например, может быть нецелесообразно смешивать в одном регистре хранение цен и минимального складского запаса.
Так как регистр сведений в базе данных представляет собой одну таблицу, то достаточно легко оценить положительные и отрицательные стороны того или иного решения, принятого при проектировании его структуры с точки зрения производительности.
Наличие большого количества регистров сведений может снизить производительность системы, если нужно будет получать данные объекта и данные связанных с ним периодических регистров сведений на некоторый момент. Очевидно, что получение среза в одном регистре с большим количеством ресурсов будет быстрее.
Запись нескольких регистров сведений также будет медленнее, чем одной записи с несколькими ресурсами.
Если из-за необходимости отражения частого изменения значения одного из ресурсов будет вводиться большое количество записей, то объем базы данных будет расти ощутимее, если в данном регистре будет много ресурсов. Особенно это может существенно сказаться на объеме базы данных, если одним из ресурсов будет являться хранилище значения, в котором будет храниться картинка или бинарные данные. Такие данные целесообразно выделять в отдельный регистр.