24.06.2021, 21:22 | #1 |
Moderator
|
EAV-модель и хэширование.
Столкнулся с задачей разработки чего-то, что напоминает о финансовых аналитиках в D365 (конкретно таблицы DimensionAttributeSet/DimensionAttributeSetItem).
Требуется во многие таблицы в разных частях системы засунуть ссылки на некоторый набор аттрибутов. (Табличка эдак полей из 5-6, в среднем на одну сущность вешается порядка 7-10 аттрибутов, но попадаются и вырожденные случаи с 1 аттрибутом или с 400-500). Моя первая идея состояла в том, чтобы сделать что-то типа клона таблицы DocuRef. Просто добавляем в табличку с аттрибутами refTable и refRecId и живем дальше. (Пожалуй добавлю - я прекрасно знаю о всех проблемах с моделью EAV. Но здесь она вполне применима, поскольку аттрибуты используются только для просмотра/редактирования пользователем и потом для экспорта в некую внешнюю систему. Запросов по этим данным точно не будет. Можно меня не аггитировать против EAV). Однако по некотором размышлении, я пришел к выводу что эдак табличка с аттрибутами будет очень уж пухнуть. Аттрибуты прикрепляются к многим записям и при этом еще и часто наследуются и копируются между объектами. Так что могу представить что за год табличка с аттрибутами запросто может вырасти эдак мегабайтов на 300-400. При этом в большинстве случаев, число комбинаций значений аттрибутов - конечное. Вероятно таких комбинаций будет порядка 5-7 тысяч и за год будет прибавляться от силы тысяча. Появилась идея сделать отдельную табличку, где у меня только два поля - RecId и Hash. Смысл таблички - отдельная уникальная комбинация аттрибутов и их значений. Все остальные таблицы на нее ссылаются по RecId. (То есть - примерно как это со стандартной таблицей DimensionAttributeSet работает). Когда пользователь просматривает/редактирует аттрибуты, это происходит во временной таблице, куда мы при открытии формы закачиваем релевантные данные из настоящей таблицы аттрибутов. Когда форма закрывается, мы закачиваем содержимое всех значимых полей всех записей на форме в memoryStream и потом рассчитываем из него hash. Если запись с тем же самым hashем нашлась, то мы ничего не записываем, а просто вешаем ссылку на уже существуюшую запись. Если запись не нашлась - создаем новую запись в табличке с комбинациями аттрибутов и потом записываем сами аттрибуты. Потом вешаем ссылочку на новую запись. Если все хорошо работает, то получаем автоматическое сжатие таблицы аттрибутов, поскольку для одинаковых комбинаций аттрибутов записи создаваться не будут. Возникает два вопроса:
|
|