08.12.2014, 12:01 | #21 |
Участник
|
Цитата:
Сообщение от Ivanhoe
Согласен с Raven Melancholic по поводу "на бумаге".
Также, чтобы особо не теоретизировать (а судя по поставленной задаче, речь идет про концепцию а не строгую теорию), я бы выделил следующие шаги: 1. Нарисовать на бумаге отчет - выделить факты и разрезы. В вашем примере количество сотрудников - это факт, а не свойство разреза. 2. Нарисовать на бумаге структуру хранилища - таблицы фактов, таблицы разрезов и их связи. Определил ключи (скорее всего - естественные, т.к. пользователю должно быть прозрачно с каким элементом разреза он работает). 3. Продумать техническую реализацию хранилища. При этом нужно понимать, что классическое хранилище нужно тогда, когда у вас много систем для построения общих отчетов (и в таком случае надо понимать, как вы будете поддерживать хранилище при изменении требований или систем-источников). Если это не так и все данные есть в Аксе, то можно пойти по пути примеров стандартных кубов - данные брать из основной OLTP-базы. Если важно уменьшить нагрузку на основную БД - выделить копию БД (зеркало) для этих целей. |
|
08.12.2014, 12:13 | #22 |
Участник
|
Ткаже, как уже было замечено прежде, хранилище прежде всего характеризует историчность данных и анализ в разрезе этой историчности.
Хороший пример был приведён выше, когда мы анализируем сумму продаж по 2012му году мы, в случае факта на таблицы сотрудники, не знаем сколько было работников в 2012м году, так как таблица была приведена в соответствие к текущему состоянию в источнике. |
|
08.12.2014, 12:22 | #23 |
Участник
|
1-й пункт делает, конечно, бизнес. Иначе ничего не взлетит.
В случае с сотрудниками, по-хорошему, нужно брать за основу таблицу назначений (приемов на работу, переводов, увольнений). Если ее нет, а есть "просто список сотрудников" - тогда вам нужно в любом случае где-то хранить факт по количеству - или отдельная процедура и таблица в Аксе, либо специальная функция для DWH, которая считает количество по таблице сотрудников каждую ночь и пишет в свою таблицу фактов.
__________________
Ivanhoe as is.. |
|
08.12.2014, 12:35 | #24 |
Участник
|
Цитата:
Сообщение от Ivanhoe
1-й пункт делает, конечно, бизнес. Иначе ничего не взлетит.
В случае с сотрудниками, по-хорошему, нужно брать за основу таблицу назначений (приемов на работу, переводов, увольнений). Если ее нет, а есть "просто список сотрудников" - тогда вам нужно в любом случае где-то хранить факт по количеству - или отдельная процедура и таблица в Аксе, либо специальная функция для DWH, которая считает количество по таблице сотрудников каждую ночь и пишет в свою таблицу фактов. |
|
08.12.2014, 15:01 | #25 |
Участник
|
Ну и нормально. Нет данных - отчет покажет "пусто". Если бизнес считает, что это неверно - пусть предоставит данные, а вы их куда-нибудь загрузите - в Аксу, в DWH, да хоть руками вбить в OLAP, если рассматриваете writeback.
__________________
Ivanhoe as is.. |
|
08.12.2014, 15:56 | #26 |
MCTS
|
А чем не устраивает составной ключ в хранилище данных? Например, кубы от MS SQL вполне хорошо работают с составными ключами.
__________________
I could tell you, but then I would have to bill you. |
|
08.12.2014, 17:39 | #27 |
Участник
|
Цитата:
Не надо придумывать себе проблемы, чтобы потом их героически преодолевать. С составными ключами слишком сложно работать. По любому будет "перекодировка" справочников при заливке из транзакционной базы Axapta в базу хранилища. Ну, и не надо "мудрить". Стандартный автоинкремент в качестве суррогатного ключа. Можно то же Idetntity или SequenceName, если речь идет о MS SQL. Если несколько клиентов Axapta должны рассматриваться как один клиент в отчете, то обязательно таблица перекодировки. Не надо пытаться как-то "разрулить" это в рамках одной таблицы. Отдельная таблица-справочник для хранилища и отдельная таблица-перекодировщик с кодами соответствия Axapta-хранилища. Вот в этой таблице-перекодировщике можно "изгаляться" как угодно... Примерно это выглядит так Справочник хранилища Id - identity - идентификатор записи для связи с другими таблицами хранилища AccountCode - код, под которым должна отображаться нужная сущность в отчете AccountName - название, которое должно отображаться в отчете (...) - прочие реквизиты справочника для формирования разрезов Ограничения Id - PrimaryKey AccountCode - альтернативный ключ. Дублирование запрещено! Таблица-перекодировщик AccountCode_DWH - код, под которым должна отображаться нужная сущность в отчете. Поле AccountCode в справочнике хранилища (DWH - Data Warehouse) DataAreaId - код компании в Axapta AccountCode - код Axapta (...) - прочие поля для однозначной идентификации записи в Axapta в таблице-перекодировщике никаких ограничений! Может дублироваться что угодно и как угодно! Соответственно, логика загрузки 1. По набору идентификаторов Axapta ищем нужный код в таблице-перекодировщике 2. По найденному альтернативному ключу ищем нужный код в справочнике хранилища
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
|
За это сообщение автора поблагодарили: Cardagant (2). |
08.12.2014, 18:01 | #28 |
Участник
|
2 Владимир Максимов
Спасибо большое за содержательный ответ. Вариант красивый. Этот способ подразумевает, таблицу-перекодировщик для каждого измерения? Как это выглядит сложно. не подойдёт ли в качестве алгоритма перекодировки нечто предлагаемое выше типа HASBYTES(). Возможно в данном случае будет возможно обойтись пере таблиц-перекодировщиков? |
|
08.12.2014, 18:34 | #29 |
Участник
|
Цитата:
Спасибо Владимир Максимов, описал проблему будто мысли прочёл. Правда, всё связано с атомарностью. Составные ключи сложны при работе с измерениями в хранилище. |
|
08.12.2014, 19:31 | #30 |
MCTS
|
Цитата:
Цитата:
Если несколько клиентов Axapta должны рассматриваться как один клиент в отчете, то обязательно таблица перекодировки.
__________________
I could tell you, but then I would have to bill you. |
|
08.12.2014, 19:47 | #31 |
Участник
|
Цитата:
Но! Создать собственный суррогатный ключ для хранилища необходимо в любом случае, вне зависимости от необходимости перекодировки. "Внешний" по отношению к базе данных идентификатор - это всегда потенциальные проблемы идентификации. Поэтому всегда, в любой базе данных, идентификатор записи, используемый для обеспечения ссылочной целостности должен формироваться исключительно средствами самой базы данных. Тот идентификатор, который приходит из-вне (в данном случае из Axapta) может служить максимум альтернативным ключом. Но ни в коем случае не Primary Key! Тут одно из двух. Либо относительно сложный алгоритм наполнения хранилища, либо сложный алгоритм формирования измерений и мер внутри куба. Лично я предпочитаю относительно сложный алгоритм наполнения, но предельно простой алгоритм формирования куба. Код наполнения я могу контролировать. А как оно внутри куба "тикает" - не очень понятно... Да и сложный алгоритм формирования измерений приводит к замедлению работы с кубом, что обесценивает сам факт его использования... Цитата:
Предположим, пользователь хочет чтобы в отчете вместо двух разных номенклатур отображалась одна. Без таблицы перекодировки Вы этого сделать не сможете. У Вас ведь HASBYTES() для разных значений ItemId сформирует разное значение хеша. Значит, это так и останутся две разных записи справочника. Не будет объединения. А с таблицей перекодировщиком Вы имеет примерно следующее Перекодировка ItemId_1 --> ItemId_10 ItemId_2 --> ItemId_10 Справочник хранилища ItemId_10 -> 10 Разумеется, если задачи объединения разных сущностей не стоит, то можно и без таблицы-перекодировщика обойтись. Однако собственный суррогатный ключ все-равно нужен. Почему, описал выше. Кроме того, факт наличия суррогатного ключа позволит безболезненно добавить таблицу-перекодировщик, если в будущем в этом возникнет необходимость Ну, а каким именно образом формировать этот суррогатный ключ: Identity, HASBYTES() , GUID() - это уже вопрос личных предпочтений и особенностей постановки задачи
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
08.12.2014, 19:59 | #32 |
Участник
|
Цитата:
Ну, это вариант, близкий к фантастическому Чтобы наши люди да не "извратились"! Не может такого быть
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
09.12.2014, 11:22 | #33 |
Участник
|
Цитата:
Я также не вижу проблему составного ключа. И да, компания - отдельное измерение. И даже если коды клиентов совпадут - можно будет это увидеть в разрезе компаний.
__________________
Ivanhoe as is.. |
|
09.12.2014, 11:39 | #34 |
Участник
|
Цитата:
И если у номенклатуры с кодом "0001" я хочу установить отображаемое имя как Наименование номенклатуры для иерархии кодов номенклатур, какое имя будет выбрано, если, к примеру номенклатур с кодом "0001" штук 5 или даже 10 в разрезе компаний? Или Вы считаете, что должны быть 2 отдельных иерархии по кодам и по имени? Тогда это возвращает к вопросу о суммировании абсолютно несовместимых номенклатур при кросс-компаниях. Последний раз редактировалось Cardagant; 09.12.2014 в 12:01. |
|
09.12.2014, 12:19 | #35 |
Участник
|
Посмотрите, как в стандарте сделан справочник номенклатур, что такое Используемый продукт, а что такое просто продукт. Именно для кросс-компани там и введен единый код продукта. Посмотрите уже на стандартные кубы. Аккуратно и с точки зрения бизнеса, а не разработчика.
Ну и в целом надо смотреть на конкретный отчет - смотрится он в разрезе компаний, с фильтрацией по компаниям или вообще без учета компаний. В зависимости от этого и будут решаться вопросы по кодам продуктов, клиентов и т.п.
__________________
Ivanhoe as is.. |
|
09.12.2014, 12:45 | #36 |
Участник
|
Цитата:
Сообщение от Ivanhoe
Посмотрите, как в стандарте сделан справочник номенклатур, что такое Используемый продукт, а что такое просто продукт. Именно для кросс-компани там и введен единый код продукта. Посмотрите уже на стандартные кубы. Аккуратно и с точки зрения бизнеса, а не разработчика.
Ну и в целом надо смотреть на конкретный отчет - смотрится он в разрезе компаний, с фильтрацией по компаниям или вообще без учета компаний. В зависимости от этого и будут решаться вопросы по кодам продуктов, клиентов и т.п. |
|
09.12.2014, 14:17 | #37 |
Участник
|
Если говорим про клиентов / поставщиков то можно за ключ взять PartyId. В таком случае ГАК и будет тем самым общим справочником контрагентов. А если в ГАК две записи - значит и контрагенты разные. Ну по крайней мере такая логика в AX 2012.
__________________
Ivanhoe as is.. |
|
09.12.2014, 15:13 | #38 |
Участник
|
Цитата:
Сообщение от Cardagant
Только что рассмотрел не номенклатуру, а измерения Клиентов и Поставщиков. Стандарт для всех иерархий атрибутов будь то ключ или обыная иерархия типа Группа клиентов / поставщиков пишут составной ключ DataArea+Поле ключа. Значит, стандарт не подразумевает обединением одинаковых кодов или названий ли групп в единый элемент в разрезе компаний, что в принципе логично, так как это могут быть разные клиенты или поставщики или разные группы с этим кодом.(о чём мы до этого вели дискуссию)
Собственно, для решения проблемы и создаются разные базы данных. Одна - для ведения документов в Axapta, другая - для формирования отчетов (кубов). Эти базы данных имеют принципиально разную структуру "Составной ключ" - это "неизбежное зло" в рамках существующей идеологии Axapta. Раз "в принципе" есть разделение по компаниям, то очевидно, любой ключ в Axapta в своем составе должен иметь ссылку на компанию. Иначе как делить данные по компаниям-то? С другой стороны, для DWH и кубов компания - это всего лишь одно из измерений. Именно в таблице фактов. Ну, и зачем тащить это измерение в таблицу измерений (в справочники)? Чтобы было? Составной ключ очень усложняет дальнейшую работу с отчетом. Кроме того, есть еще второстепенная (хотя, как сказать) проблема - это лавинообразный рост объемов (в байтах) любых хранилищ, работающих с составным ключом. Причем как DWH, так и собственно кубов. Как следствие, также лавинообразно увеличивается время процессинга (пересчета) кубов.
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
09.12.2014, 15:37 | #39 |
Участник
|
Цитата:
Совсем не переносить составной ключ ведь нельзя. Последний раз редактировалось Cardagant; 09.12.2014 в 15:59. |
|
09.12.2014, 16:57 | #40 |
MCTS
|
Цитата:
Сообщение от Владимир Максимов
Кроме того, есть еще второстепенная (хотя, как сказать) проблема - это лавинообразный рост объемов (в байтах) любых хранилищ, работающих с составным ключом. Причем как DWH, так и собственно кубов. Как следствие, также лавинообразно увеличивается время процессинга (пересчета) кубов.
__________________
I could tell you, but then I would have to bill you. |
|