Аналитика по остаткам в SSAS: MDX, Snapshot и Many-To-Many. Часть вторая. / Microsoft Business Intelligence /

Аналитика по остаткам в SSAS: MDX, Snapshot и Many-To-Many. Часть вторая. / Microsoft Business Intelligence / Аналитика

Что такое mdx?

Файл .mdx имеет тот же синтаксис что и Markdown, но позволяет импортировать интерактивные компоненты JSX и встраивать их в ваш контент. Поддержка компонентов Vue находиться в альфе. Для того, чтобы начать работать с MDX, достаточно установить “Create React App”. Есть плагины для Next.js и Gatsby. Следующая версия Docusaurus (версия 2) также будет иметь встроенную поддержку.

Mdex’s deflationary tokenomics keeps mdx sustainable

MDEX’s tokenomics follows a “repurchase and burn” model, which decreases the circulating supply of the MDX token over time, driving up its value. This model keeps the value of MDX sustainable over the long run. Its tokenomics are also further supported by the “repurchase and reward” model, which further incentivizes MDX holders to keep their tokens.

On top of yield rewards, MDX tokens can also be used to participate in the governance mechanism of one of the fastest-growing DEXs in the market. Holders can propose and vote on the listing of a token on the MDEX market or collateralization of any other asset.

Check out Uniswap here.

Check out SushiSwap here.

Learn more about DEXs here.

Read about crypto on the CMC blog.

Storybook

Storybook позиционирует себя как «среда разработки UI компонентов». Вместо того, чтобы писать примеры компонентов внутри файлов Markdown или MDX, вы пишете истории внутри файлов Javascript. История документируют конкретное состояние компонента. Например, у компонента могут быть истории для состояния загрузки и отключенного состояния (disabled).

storiesOf('Button', module)
  .add('disabled', () => (
    <Button disabled>lorem ipsum</Button>
  ))

Storybook гораздо сложнее чем Styleguidist и Docz. Но при этом это самый популярный вариант, на Github у проекта более 36 000 звезд. Это проект с открытым исходным кодом, в нем участвует 657 участников и сопровождают штатные сотрудники. Его использует Airbnb, Algolia, Atlassian, Lyft и Salesforce.

В будущем релизе будут фишки из Docz и внедряется MDX.

# Button

Some _notes_ about your button written with **markdown syntax**.

<Story name="disabled">
  <Button disabled>lorem ipsum</Button>
</Story>

Новые функции Storybook’а появятся постепенно в течение следующих нескольких месяцев и, по-видимому, это станет большим шагом вперед.

Styleguidist

Как и в Docz, примеры пишутся, используя синтаксис Markdown. Styleguidist использует блоки кода Markdown (тройные кавычки) в обычных файлах .md файлах, а не в MDX.

```js
<Button onClick={() => console.log('clicked')>Push Me</Button>

Блоки кода в Markdown обычно просто показывают код. При использовании Styleguidist любой блок кода с тегом языка js, jsx или javascript будет отображаться как компонент React. Как и в Docz, код редактируемый — вы можете менять свойства и мгновенно видеть результат.

Styleguidist автоматически создаст таблицу свойств из PropTypes, Flow или Typescript объявлений.

Styleguidist сейчас поддердживает React и Vue.

Where can you buy mdex (mdx)?

Mdex is trading on markets including Huobi Global, Gate.io and the MDEX exchange, among others.

Learn more about how to buy crypto here.

Аналитика по остаткам в ssas: mdx, snapshot и many-to-many. часть вторая. / microsoft business intelligence /

Часть Вторая. Реализация через semiadditive measures
(Начало – здесь:https://www.sql.ru/blogs/dklmnmsbi/1450)

Итак, наша новая задача – кардинально увеличить производительность запросов, в которых выводятся наши остатки (не поймите выражение “наши остатки” неправильно 🙂 ).

План – такой:

а)Делаем расчет в реляционной базе остатков, которые образуются после каждого “Движения”.

б)Делаем в SSAS таблицу фактов, в которой для каждого сочетания “Товар – Склад” (при добавлении других измерении естественно гранулярность подсчета меняется), и для каждого дня, когда есть ненулевой остаток, подсчитаны текущие значения.

в)Делаем в SSAS на основе этой таблицы полуаддитивные меры с остатками. Привязка к измерениям остается тривиальной.

г)Тестируем отчетность. Убеждаемся что значения новой меры совпадает со старой, меняем используемую меру в существующих отчетах.

д)Наблюдаем удовлетворенные лица пользователей. Идем в кассу за премией.

Детали реализации
а)Для хранения подсчитанного остатка мы создадим отдельную таблицу.

CREATETABLE[dbo].[L_MOVE_REM]([C_MOVE][int]PRIMARYKEYREFERENCES[dbo].[L_MOVE]([C_MOVE]),/*ссылка на проводку, которая сформировала остаток*/[C_MOVE_NEXT][int]NULLREFERENCES[dbo].[L_MOVE]([C_MOVE]),/*ссылка на следующую проводку по этому сочитанию Товар- Склад - (и т.д. в зависимости от гранулярности)-нужно для оптимизации запроса*/[MOVE_REM][decimal](18, 3)NOTNULL,/*остаток который образовался после "движения товара" в жизни, ну или "проводки" в учетной системе*/)

Сам расчет производим следующим скриптом:

Скрипт для расчета нарастающего итога и остатков
USE Inventory;truncatetable L_MOVE_REM
DECLARE @RunningTotal decimal(18,3)declare @tmp_moves table(C_MOVE int, MOVE_DATE DATE, QTY DECIMAL(18,3), QTY_ROLLING decimal(18,3));DECLARE @C_PRODUCT int, @C_WARE_HOUSE INT;declare @cnt int;set @cnt=0;DECLARE @mess varchar(100);DECLARE CRS CURSORFORselect   m.C_PRODUCT,m.C_WARE_HOUSE
from L_MOVE m groupby  m.C_PRODUCT,m.C_WARE_HOUSE --having COUNT(*)  between 5 and 10;OPEN CRS;--цикл по всем сочетаниям "Товар-Склад"FETCHNEXTFROM CRS
INTO @C_PRODUCT, @C_WARE_HOUSE
WHILE@@FETCH_STATUS = 0 
BEGINset @cnt=@cnt 1;set @mess=CAST(@cnt asvarchar(10));raiserror(@mess,5,10)withnowait;deletefrom @tmp_moves;insert @tmp_moves(C_MOVE, MOVE_DATE, QTY)--SELECTmax(m.c_move)as MIN_C_MOVE /*НА конец  ДНЯ СЧИТАЕМ, поэтому соотносим остаток с последней проводокой задень если их несколько*/,  
M.MOVE_DATE,sum(m.MOVE_QTY  *casewhen m.DTCR=0 then 1 else-1 end)from L_MOVE m 
 where  m.C_PRODUCT=@C_PRODUCT  and m.C_WARE_HOUSE=@C_WARE_HOUSE
 groupby m.MOVE_DATE orderby  m.MOVE_DATE asc;----SET @RunningTotal = 0 
UPDATE @tmp_moves SET @RunningTotal = QTY_ROLLING = @RunningTotal   QTY FROM @tmp_moves;--считаем остаток через "нарастающий итог"with cte_rn as(/*джойним по порядковому номеру чтобы наити следующее значение остатка*/select m.*,ROW_NUMBER()over(orderby move_date asc)as RN from  @tmp_moves m), cte_joined_to_next as(select  m.*, mnext.C_MOVE as C_MOVE_NEXT from cte_rn m leftjoin cte_rn mnext on m.RN=mnext.RN-1)insertL_MOVE_REM(C_MOVE, C_MOVE_NEXT,MOVE_REM)select mm.C_MOVE, mm.C_MOVE_NEXT, mm.QTY_ROLLING from cte_joined_to_next mm;--FETCHNEXTFROM CRS
INTO @C_PRODUCT, @C_WARE_HOUSE
   ENDCLOSE CRS;DEALLOCATE CRS;--------

Подозреваю, что такой способ подсчета не является оптимальным по производительности, к тому же здесь используется не вполне задокументированный способ подсчета нарастающего итога
(UPDATE @tmp_moves SET @RunningTotal = QTY_ROLLING = @RunningTotal QTY FROM @tmp_moves;).
С благодарностью приму варианты реализации подсчета без таких “кул-хаков”.

б) Таблица фактов для SSAS
У нас есть подсчитанные значения всех остатков на те дни, когда этот остаток был изменен.
Но нам для таблицы фактов нужны все дни, в том числе те, когда движения не происходили.
Чтобы облегчить себе жизнь при дальнейшем развитии системы,мы делаем некоторые вспомогательные функции и вьюхи

ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ и вьюхи
CREATEFUNCTION[dbo].[udfDateToInteger](@DateDATE)returnsint--для превращения дат в интовые ключи -удобные для использования в качестве ключа измеренияasbeginreturnYear(@Date)*10000 Month(@Date)*100 Day(@Date);end
GO

GO
CREATEFUNCTION[dbo].[udf_GetDateRange](--просто выводим перечень последовательных дат из заданного диапазона
	@DATE_BEGIN DATE,
	@DATE_END DATE)RETURNS  @RETTABLE TABLE(DATE_CURRENT DATE)ASBEGINdeclare @i intdeclare @dat datetimeset @i=0
set @dat=@DATE_BEGIN;while @dat<=@DATE_END
beginINSERTINTO @RETTABLE VALUES(@dat);set @i=@i 1;set @dat=DATEADD("d",@i,@DATE_BEGIN)endreturn;END
GO
CREATEVIEW[dbo].[vOlapMoveRemByPeriods]asselect 
 m.C_MOVE,
m.MOVE_DATE as DATE_BEGIN,coalesce(DATEADD(DAY,-1,mnext.move_date),cast(getdate()asdate))as DATE_END,--dbo.udfDateToInteger(m.MOVE_DATE) as DATE_BEGIN_KEY,  dbo.udfDateToInteger(coalesce(DATEADD(DAY, -1,mnext.move_date), cast(getdate() as date))) as DATE_END_KEY,
  m.C_PRODUCT, m.C_WARE_HOUSE,mr.MOVE_REM 
  from L_MOVE_REM  mr join L_MOVE m on m.C_MOVE=mr.C_MOVE leftjoin L_MOVE mnext on mnext.C_MOVE=mr.C_MOVE_NEXT
GO

И с помощью этих функций формируем запрос для таблицы фактов F_REM_FOR_EVERY_DAY,которая по сути представляет собой некий “Вычисляемый snapshop на конец дня”.

SELECT m.C_MOVE, dbo.udfDateToInteger(daterange.DATE_CURRENT)as DATE_REM_KEY,
m.C_PRODUCT, m.C_WARE_HOUSE,m.MOVE_REM 
FROM vOlapMoveRemByPeriods m
CROSS APPLY dbo.udf_GetDateRange(m.DATE_BEGIN,m.DATE_END) daterange

в)Строим в SSAS на этот раз уже физическую меру “Остаток” (REM_FOR_EVERY_DAY) с AggregateFunction=LastChild

Получается такая картина:

Картинка с другого сайта.

г)Тестируем через сравнение с значениями остатка по старой, вычисляемой мере, например таким запросом

select{[DimWareHouses].[WareHouseParent].&[110119643]}*{[cmRemByINCOME_OUTCOME],[REM_FOR_EVERY_DAY]}on 0,
non empty [DimDate].[Hierarchy].[Month].&[202111].Children on 1 
from[Inventory-Cube]

Убедившись что значения новой (физической) и старой (вычисляемой) мерой совпадают, выдумываем запрос посложнее и смотрим в профайлере производительность.

Изменяем название меры в существующих отчетах

д)Забираем в кассе премию и .. задумываемся еще немного.

.

Продолжение – следует.

(SSAS проект и скрипт для создания метаданных в реляционной базе можно взять здесь:

https://www.dropbox.com/s/e42ueesskoexk83/Inventory-SSAS-Project.zip

)

—————-

Кальманович Дмитрий.

Документирование компонентов: docz, storybook и styleguidist

Гайдлайны, дизайн системы, библиотеки компонентов — как бы вы их ни называли, но это стало очень популярным в последнее время. Появление компонентных фреймворков, таких, как React и инструментов, упомянутых здесь — позволило превратить их из тщеславных проектов в полезные инструменты.

Storybook, Docz и Styleguidist — делают одно и тоже: отображают интерактивные элементы и документируют их API. Проект может иметь десятки или даже сотни компонентов — все с различными состояниями и стилями. Если вы хотите, чтобы компоненты использовались повторно, люди должны знать, что они существуют.

Эти инструменты предоставляют удобный способ просмотра различных состояний. Может быть трудно воспроизвести каждое состояние компонента в контексте реального приложения. Вместо того, чтобы щелкать по реальному приложению, стоит разработать отдельный компонент. Можно смоделировать труднодоступные состояния (например, состояние загрузки).

Наряду с визуальной демонстрацией различных состояний и списком свойств часто необходимо писать общее описание контента — обоснования дизайна, кейсы использования или описание результатов пользовательского тестирования. Markdown очень прост для изучения — в идеале гайдлайны должен быть совместным ресурсом для дизайнеров и разработчиков. Docz, Styleguidist и Storybook предлагают способ легкого смешивания Markdown с компонентами.

Другие варианты создания контента

Docusaurus специально разработан для создания документации. Конечно, есть миллион и один способ сделать сайт — вы можете развернуть свое собственное решение на любом языке, CMS или воспользоваться генератором статического сайта.

Например, документация для React, дизайн система IBM, Apollo и Ghost CMS используют Gatsby — это генератор статических сайтов, который часто используют для блогов. Если вы работаете с Vue, то VuePress для вас станет хорошим вариантом. Другой вариант — использовать генератор, написанный на Python — MkDocs.

Многомерные кубы


Так что же все-таки эти многомерные кубы?

Представим себе 3-х мерное пространство, у которого по осям Время, Товары и Покупатели.

Точка в таком пространстве будет задавать факт того, что кто-то из покупателей в каком-то месяце купил какой-то конкретный товар.

Фактически, плоскость (или множество всех таких точек) и будет являться кубом, а, соответственно, Время, Товары и Покупатели – его измерениями.Представить (и нарисовать) четырехмерный и более куб немного сложнее, но суть от этого не меняется, а главное, для OLAP систем совершенно неважно в скольких измерениях вы будете работать (в разумных пределах, конечно).

Немного mdx


Итак, в чем же прелесть MDX – скорее всего в том, что описывать нужно не то как мы хотим выбрать данные, а

что именно

мы хотим.

Например,

SELECT{ [Measures].[Units] } ON COLUMNS,{ [Time].[June, 2009], [Time].[July, 2009] } ONROWSFROM [Sales]WHERE ([Product].[iPhone], [Country].[Mozambik])

* This source code was highlighted with Source Code Highlighter.

Что означает – хочу количество iPhone-ов, проданных в июне и июле в Мозамбике.При этом я описываю какие именно данные я хочу и как именно я хочу их увидеть в отчете.Красиво, не правда ли?

А вот чуть посложнее:

WITH MEMBER AverageSpend AS[Measures].[Amount] / [Measures].[TransactionCount]SELECT{ AverageSpend } ON COLUMNS,{ [Customer].[Sex].

* This source code was highlighted with Source Code Highlighter.

Фактически, вначале определяем формулу подсчета «среднего размера покупки» и пытаемся сравнить – кто же (какой пол), за один заход в магазин Apple, тратит больше денег.

Сам язык чрезвычайно интересен и для изучения и для использования, и, пожалуй, заслуживает немало обсуждений.

Немного подробнее о возможностях

Быстрый доступ к данным

Собственно быстрый доступ к данным, независимо от размеров массива, и является основой OLAP систем. Так как основной упор именно на этом, хранилище данных обычно строится по принципам, отличным от принципов реляционных баз данных.

Здесь, время на выборку простых данных измеряется в долях секунды, а запрос, превышающий несколько секунд, скорее всего, требует оптимизации.

ПреагрегацияКроме быстрой выборки существующих данных, также предоставляется возможность преагрегировать «наиболее вероятно-используемые» значения. Например, если мы имеем ежедневные записи о продажах какого-то товара, система может преагрегировать нам также месячные и квартальные суммы продаж, а значит, если мы запросим данные помесячно или поквартально, система нам мгновенно выдаст результат.

Почему же преагрегация происходит не всегда – потому, что теоретически возможных комбинаций товаров/времени/и т.д. может быть огромное количество, а значит, нужно иметь четкие правила для каких элементов агрегация будет построена, а для каких нет. Вообще тема учета этих правил и собственно непосредственного дизайна агрегаций довольно обширна и сама по себе заслуживает отдельную статью.

ИерархииЗакономерно, что анализируя данные и строя конечные отчеты, возникает потребность учитывать то, что месяцы состоят из дней, а сами образуют кварталы, а города входят в области, которые в свою очередь являются частью регионов или стран.

Работа с временемТак как в основном анализ данных происходит на временных участках, именно времени в OLAP системах выделено особое значение, а значит, просто определив для системы, где у нас тут время, в дальнейшем можно с легкостью пользоваться функциями типа Year To Date, Month To Date (период от начала года/месяца и до текущей даты), Parallel Period (в этот же день или месяц, но в прошлом году) и т.п.

Язык доступа к многомерным даннымMDX (Multidimensional Expressions) — язык запросов для простого и эффективного доступа к многомерным структурам данных. И этим все сказано – внизу будет несколько примеров.

Key Performance Indicators (KPI)Ключевые показатели эффективности — это финансовая и нефинансовая система оценки, которая помогает организации определить достижение стратегических целей. Ключевые показатели эффективности могут быть достаточно просто определены в OLAP системах и использоваться в отчетах.

Дата майнингИнтеллектуальный анализ данных (Data Mining) — по сути, выявление скрытых закономерностей или взаимосвязей между переменными в больших массивах данных. Английский термин «Data Mining» не имеет однозначного перевода на русский язык (добыча данных, вскрытие данных, информационная проходка, извлечение данных/информации) поэтому в большинстве случаев используется в оригинале.

Многоуровневое кэшированиеСобственно для обеспечения наиболее высокой скорости доступа к данным, кроме хитрых структур данных и преагрегаций, OLAP системы поддерживают многоуровневое кэширование. Кроме кэширования простых запросов, также кэшируются части вычитанных из хранилища данных, агрегированные значения, вычисленные значения.

Поддержка мультиязычностиДа-да-да. Как минимум Analysis Services 2005/2008 (правда, Enterprise Edition) нативно поддерживают мультиязычность. Достаточно привести перевод строковых параметров ваших данных, и клиенту, указавшему свой язык, будут приходить локализированные данные.

Токен mdex

MDEX имеет одноименной нативный токен, используемый для обеспечения для займов или главного инструмента кредитования. MDEX можно использовать в доходном фермерстве, для стейкинга или просто им оплачивать торговые комиссии на бирже. Крупные держатели MDEX могут управлять экосистемой проекта и предлагать свои идеи.

Общая эмиссия MDX составляет 1 млрд монет, из которых 10% направляются разработчикам, 7% – ранним инвесторам инвесторов, 3% – для продвижения биржи на рынке криптовалют. Остальные 80% будут направляться майнерам ликвидности.

MDEX является 232-м крупнейшим активом на рынке с капитализацией $300 млн. Поэтому проблем с его приобретением не должно возникнуть. MDEX можно приобрести на таких централизованных биржах, как Huobi, Gate или непосредственно на платформе Mdex.

Подведем итоги

Главная цель Mdex – это позволить простым участникам рынка присоединяться к пулам ликвидности для получения пассивного дохода, которые собственно и будут стимулировать ликвидность на бирже.

Внимание! Риски инвестирования в новые DeFi-токены всегда были и будут, поэтому вкладывайте в MDEX только те средства, потеря которых не скажется на вашем благосостоянии.

 1,561

Итоги

Преимущества библиотеки паттернов превозносятся в миллионах статей на Medium. Когда все сделано хорошо, они облегчают создание смежных продуктов и поддержание идентичности. Конечно, ни один из этих инструментов не поможет волшебным образом создать дизайн систему.

От переводчика. Это мой первый опыт на Хабре. Если вы нашли какие-то не точности, или есть предложения по улучшению статьи — пишите в личку.

Заключение

На самом деле, данная статья очень мало покрывает даже базовых понятий, я бы назвал ее «appetizer» — возможность заинтересовать хабра-сообщество данной тематикой и развивать ее дальше. Что же касается развития – тут огромное непаханое поле, а я буду рад ответить на все интересующие вопросы.

P.S. Это мой первый пост об OLAP и первая публикацию на Хабре — буду очень признателен за конструктивный фидбек.Update: Перенес в SQL, перенесу в OLAP как только разрешат создавать новые блоги.

Дополнительный анализ:  Анализ отчетности важен для
Оцените статью
Аналитик-эксперт
Добавить комментарий