Обновить
-9
0
Сергей Устинов @SergeyUstinov

Финансы / ERP / SQL и BI

Отправить сообщение
Согласен.
Я об этом и говорю — именно создание корректной и полной (но не обязательно детальной) логической модели данных (ERD) позволяет грамотно нарезать на модули систему.
До тех пор, пока не получена корректная (нормализованная) и достаточно полная схема БД — как можно говорить о корректной доменной модели?

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

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

Какие сущности будут нужны:
Товары
Покупатели
Поставщики
Места хранения

Заказы продажи
Заказы покупки

Операции с товарами — поступления, отгрузки, перемещения

Это и есть концептуальная модель данных (по крайней мере с моей точки зрения).

Предположим, порезали на модули на этом этапе.

И дальше пишем код и параллельно делаем логическую и физическую схему данных.

И тут натыкаемся на замечательную вещь. У заказа продажи есть такая особенность, что утвержденный заказ создает «резерв» товаров — уменьшает «свободный остаток» товаров на складе. А, предположим, остатки товаров и все контроли, связанные с товарами (нельзя отгрузить больше товаров, чем есть в наличии и т.п.), мы реализовали в модуле «товародвижения», а заказы продажи в модуле «продажи»…
То есть два куска очень тесно связанных данных оказались в разных модулях, что может доставить много «приятных» минут.
И на уровне концептуальной модели подобные приколы увидеть нельзя.
:)))
Разошлись в терминологии.
Я говорил о Conceptual data model и Logical data model
То есть сперва делаем Conceptual data model, потом рисуем первую версию Logical data model (без кучи деталей), потом режем на модули, потом рисуем для каждого модуля Logical data model с большей детализацией, но всё еще без типов данных и не все поля перечислены, потом рисуем структуру классов java (то есть «натягиваем» код на схему бд, а не наоборот).
И в дальнейшем, параллельно с реализацией классов java, создаем Physical data model (sql скрипты, которые непосредственно создают таблицы, ограничения, индексы и т.д.)
Типы полей в ERD БД очень часто вообще не указываются. Диаграмму надо рисовать в первую очередь для нормализации (денормализации), а типы данных для этой задачи не важны.
Схема БД (ERD) — это в первую очередь логическая структура данных, а не физическая. Вы её точно ни с чем не путаете?
ERP системы, бухгалтерия, торговля, логистика и т.п. Реляционные СУБД создавались в первую очередь в расчете на такие задачи, и очень хорошо для таких задач подходят.

Сервис по аренде автомобилей относится к этому «типу» приложений.
А тот же инстаграмм — это уже другой тип приложений.
:)))
Возможно. Мне проще сразу рисовать схему бд.

Но главное, что я хотел подчеркнуть — сперва создаем схему бд, потом, на основе схемы бд — классы java. Иначе в таких системах будет сплошной ой.

И, кстати, если создавать что-то похожее на инстаграм, то подход «от схемы БД» будет неправильным. Там другие требования к работе с данными и те же объектные БД будут прекрасно работать. И разрабатывать архитектуру надо по другому.

То есть подход к разработке архитектуры очень сильно зависит от типа разрабатываемого приложения.
Почему именно от ERD БД, а не от ERD предметной области? Ведь БД нужна для хранения данных о доменных объектах, а не наоборот, не БД определяет состав полей доменных объектов

Потому что ERD предметной области — это нечто достаточно эфемерное, что нельзя непосредственно воплотить в артефактах системы. А ERD БД — это вполне конкретная вещь, которую можно напрямую трансформировать в SQL код создания объектов БД, можно нормализовать и т.д. А как, например, нормализовать ERD предметной области? :)))

Как я вижу создание микросервисов для такой задачи:
Рисуем укрупненную ERD предметной области. Под неё рисуем укрупненную ERD базы и анализируем связи — где можно разрезать на микросервисы. При этом также думаем и о прочих аспектах работы пользователя с системой, но отталкиваемся именно от схемы БД.
При дроблении на микросервисы сразу же думаем, нет ли уже готовых кусков. Например, для машин и покупателей из этого примера смотрим на решения из сферы MDM — Product information management (PIM) и Customer Information Management (CIM). Изобретение велосипедов всегда чревато проблемами. :)))

После дробления на микросервисы рисуем уже детальные ERD баз (для каждого микросервиса свою схему, чтобы в дальнейшем можно было хранить все данные как в одном инстансе сервера БД для всех микросервисов, так и в множестве разных инстансов). Можно даже сразу подумать о возможном горизонтальном разбиении данных — даже запустив 100 екземпляров микросервиса, можно легко столкнуться с недостаточной производительностью. Ведь в любом случае надо контролировать, чтобы одна и та же физическая машина не была зарезервирована в одно и то же время для разных поездок. А это означает, что БД очень легко может стать узким местом. А при неудачном разбиении на микросервисы для решения такой проблемы может потребоваться переразбиение на микросервисы с нуля и переписывание большей части кода.

И только потом, когда для каждого микросервиса, который будем создавать (часть можно позаимствовать в готовом виде), продумана схема БД, надо начинать продумывать классы java, которые будут оптимально работать именно с такими данными. И эти классы наверняка будут не такими, как описаны в статье.

Мне кажется, что большая часть описанных проблем возникает из-за того, что пытаемся создать модель классов, а структура БД является «вспомогательной» (ORM).
Но сам по себе описанный проект ближе к тем задачам, для которых разрабатывались реляционные базы. И логичнее продумывать архитектуру не от классов java, а от er диаграммы базы. В таком случае большей части описанных проблем не появится. А если вспомнить о прочих проблемах, которые приносит за собой ORM, то описанный подход выглядит как сплошная проблема.
Чтобы сделать более красивый вывод.
Или вопрос звучит как: «Почему таблицу, а не табличную переменную?»
Я с табличными переменными обычно не работаю, в основном с временными таблицами. Вот и создал временную таблицу.
Select… Into… в данном случае работать не будет — мы селект выполняем 100 раз.
Какая табличная переменная?
Вот первый вариант (просто написал «в лоб», обычно циклы для таких задач не использую):
declare @i int;
set @i = 1;

WHILE @i <= 100 
BEGIN 

select 
case
when cast(@i as decimal) / 3 = round ((cast(@i as decimal) / 3), 0) and cast(@i as decimal) / 5 = round ((cast(@i as decimal) / 5), 0) then 'FizzBuzz'
when cast(@i as decimal) / 5 = round ((cast(@i as decimal) / 5), 0) then 'Buzz'
when cast(@i as decimal) / 3 = round ((cast(@i as decimal) / 3), 0) then 'Fizz'
else cast (@i as nvarchar)
end as [Result]
;
set @i = @i + 1;

END 


Вывод не понравился и немного доработал.
А иначе вывод некрасивый :)))

Result
------------------------------
1

(1 row(s) affected)

Result
------------------------------
2

(1 row(s) affected)

Result
------------------------------
Fizz

(1 row(s) affected)

Result
------------------------------
4

(1 row(s) affected)

Result
------------------------------
Buzz

(1 row(s) affected)

Result
------------------------------
Fizz

(1 row(s) affected)

и т.д.
— T SQL
declare @i int;
set @i = 1;

CREATE TABLE #test ([Step] int, [Result] nvarchar (10));

WHILE @i <= 100
BEGIN

INSERT INTO #test
select
@i as [Step]
,case
when cast(@i as decimal) / 3 = round ((cast(@i as decimal) / 3), 0) and cast(@i as decimal) / 5 = round ((cast(@i as decimal) / 5), 0) then 'FizzBuzz'
when cast(@i as decimal) / 5 = round ((cast(@i as decimal) / 5), 0) then 'Buzz'
when cast(@i as decimal) / 3 = round ((cast(@i as decimal) / 3), 0) then 'Fizz'
else cast (@i as nvarchar)
end as [Result]
;
set @i = @i + 1;

END

select [Result] from #test;


Потратил 20 минут… Плохо…
К сожалению, в таком виде этот вывод понятен в основном тем, кто интересовался AI и что то читал по этой теме. А большинству людей, пусть и технически грамотных, это ни о чем не говорит… (((
Возможно, имеет смысл добавить небольшое «практическое» описание выводов в более понятной форме. Например, что могут и чего не могут сделать технологии ИИ сейчас и в ближайшем будущем.

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

Вот пример такого спора:
http://itc.ua/news/glava-minfina-ssha-ne-schitaet-chto-robotyi-nesut-ugrozu-chelovecheskoy-ekonomike/
Я пытался объяснить в комментариях, что текущий ИИ не то же самое, что описывают фантасты, но у меня плохо получилось…
Вот я и хочу уточнить — а как именно ваш сервис помогает решить конкретно эту проблему — недостаточная гибкость производственных графиков, построенных на основе прогноза? Можно какой-то условный пример с цифрами?
Вы описали конкретную проблему — завод, товар А с пиком продаж, нехватка товара… Как конкретно эту задачу поможет решить ваш сервис?
Какая в данном случае цепь и где именно надо хранить запас?
Какой тип товара А и какая стратегия управления?
Какие диапазоны значений для товара А?
И самое главное — как это всё помогает решить проблему с неожиданным пиком продаж?
«Но в течении недели, например в Чт, завод может производить то, в чем пока нет необходимость при этом, не производить «товар А», пик продаж которого по непонятным причинам произошел в первую неделю месяца… А в плане производства — только на вторую неделю, соответственно и сырье заказано на вторую неделю… И даже если есть сырье, остаются ограничения по очередность(пример на красках: нельзя более светлые, производить после более темных), или переналадке(с текущего типа продукции переход на тип А занимает 2 смены, что сломает и производительность и собственно текущий план производства) или другие. Возникает вопрос — а что делать, сломать график и делать то что хочет клиент, производя ущерб всей системе, или игнорировать и придерживаться графика, вставив «товар А» за первой же возможности(чтобы минимизировать потери производительности).»

То есть ваш сервис решает данную проблему?
Тогда можно уточнить — а как именно?
Хм. А детальное описание алгоритма и модулей интеграции есть? В таком виде — это просто красивые слова.
Прекрасная статья!
Сидишь в 10 вечера, думаешь, как сделать не совсем очевидный отчет. Чтобы подстегнуть придумывание — лезешь на Хабр и читаешь такую статью.
И внезапно до тебя доходит, что хотя об NK автоматах ты раньше не слышал (или слышал и забыл) — статью ты прекрасно понимаешь и даже «нутром» ощущаешь эту границу связности 2…
И в результате приходит целых ТРИ мысли:
1. Понимаешь, как именно можно реализовать нужный отчет без больших извращений.
2. Задумываешься, что детям надо помочь в приобретении нейроинтерфейсов, чтобы они посчитали (и смогли оплатить) генные коррекции уже для своих детей.
3. Принимаешь решение, что надо уменьшить у себя процент ассоциативных цепочек, которые связывают между собой слова «секс» и «мозг». В частности, надо побыстрее доделать отчет и идти домой к жене, а не читать статьи на Хабре. :)))
Сама по себе принципиальная возможность разделения логики сомнения не вызывает. Но хорошей реализации такого разделения я пока не видел.
Причина в том, что логика может быть достаточно сложной. Например, было простое предупреждение, что заказ нельзя отгрузить, так как у клиента недостаточно кредитного лимита. Бралась текущая задолженность, к ней прибавлялась сумма заказа и результат сравнивался с кредитным лимитом. Если меньше или равен — то можно отгружать, если больше кредитного лимита — нельзя. Потом появилась идея для некоторых товаров (которые надо распродать) не учитывать их стоимость при расчете кредитного лимита. И правило должно было выглядеть так: если у клиента кредитный лимит больше нуля и нет просроченной задолженности, то сравниваем с кредитным лимитом только не распродажные товары, а распродажные товары из текущего заказа и предыдущих заказов в сравнении не участвуют. Это тоже можно описать функцией, но это намного более сложная функция получалась… И вообще такую проверку наверно надо не на уровне интерфейса делать, а на сервере. Но в первом варианте все было просто и легко реализовывалось на уровне интерфейса.

Если вы можете привести примеры систем, где удалось удачно реализовать описываемое вами разделение логики — укажите ссылку. Было бы интересно почитать.

И возможно стоит чуть подробнее описать «Hybrid Application». В таком виде, как сейчас, не совсем понятно, что скрывается за некоторыми терминами. Например, чем три вида логики друг от друга отличаются.

Информация

В рейтинге
Не участвует
Откуда
München, Bayern, Германия
Дата рождения
Зарегистрирован
Активность