Search
Write a publication
Pull to refresh
8
0
Алексей @UltimaSol

Разработчик

Send message

Масштабируемость, нестандартные бизнес - правила, сложность интеграции с существующими фреймворками (например, с системой отчетов)

Кстати, про системы отчетов: Power BI

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

В статье выше описано кардинально е улучшение, если вдуматься: метаданные + данные на 700 млн строк и оно работает.

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

Если позволите, поделюсь опытом. Я участвовал в более полусотни проектов на конструкторе Интеграм, у которого под капотом IDEAV, и могу сказать, что в код конструктора залезать нет необходимости.

Графический интерфейс можно натянуть любой — на реакте, Vue или обычном HTML+js+css. Можно делать SPA с бэкендом в Интеграме, но также в конструкторе есть шаблонизатор, который можно использовать для server-side rendering.

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

Здесь есть демка на тему больших таблиц и поиска по любому полю, скрины из её копии
https://ideav.pro/sber

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

Тем не менее, это ближайший аналог к теме статьи
https://ru.wikipedia.org/wiki/Нейронный_процессор

Очевидно, вы в самом начале пути и до первого пивота вам ещё пару лет работать. Хорошо, что вы сразу делаете ставку на архитектора, ибо ddl и crud - это меньше 1% трудоемкости в вашем проекте, а вот архитектурные задачи всё равно будет решать человек со складом ума программиста.

Постарался исправить перечисленные моменты

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

Вон оно как. Казалось бы, кого волнуют изыскания какого-то там ещё одного строителя конструктора… Прямо бросил тень на весь мир разработчиков СУБД.
Что вы воспринимаете как критику? Я уберу или перефразирую.

Например, сделаю так:
Как мы ожидали, работа с небольшими наборами данных, например, по отдельному счету или клиенту, в конструкторе выглядит достаточно комфортно (время отклика в пределах секунды), в отличие от традиционной таблицы, где отклика приходится ждать минутами.
Эм, причем здесь какие-то другие статьи, если я говорю про утверждения в данной статье?

Вы сравнивали, и вам там в комментариях указали на недостатки вашего сравнения.

Нет предела совершенству, я учту комментарии и в следующий раз, возможно, получится лучше. Но всегда будет критика. Я сюда за ней пришел, кстати.

Ваша методика измерений неправильная. Вы случайно или намеренно подменяете понятия и делаете неправильные выводы.

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

или этот:
Итак, мы можем использовать конструктор для небольших и средних таблиц, требующих интенсивного поиска и агрегацию по произвольным атрибутам, а большие неиндексированные объекты хранить в плоских традиционных таблицах, вызывать из стороннего хранилища или специализированных баз данных (Hadoop и прочих NoSQL).


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

Это паранойя.

Ранее я сравнивал таблицы с частичными индексами: здесь,
а также была статья про полностью проиндексированные атрибуты, где это целесообразно,
и теперь в этой заметке я показал, как быть, если данных совсем много, так много, что бизнес их не индексирует вовсе, предпочитая подождать 1-2 минуты при необходимости.

Я специально неоднократно упоминаю, что конструктор в этом случае применять не следует, но делаю замеры и фиксирую их.
Я про это и говорю. Это не недостаток решения «традиционная таблица», это неправильная настройка системы. Которое решается правильной настройкой за несколько минут, а не переходом на вашу систему с полным переносом данных в другой формат хранения.

Вы это серьезно — неправильная настройка системы?
Статья не ищет ответа на вопрос «как правильно настроить систему» и не агитирует переходить на новую систему, а исследует поведение различных решений.

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

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

У конструктора есть индекс и по этим 12.5 млн, поэтому он сразу найдет нужные записи и обработает их — также всего одну штуку. Это выйдет заметно быстрее.

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

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

Получится. Смотрим, что в запросе используется номер счета, выполняем запрос на добавление индекса по этому полю. Всё. Сам запрос да, может занимать больше времени, в зависимости от количества данных. Но меньше, чем переносить все данные в вашу систему.

Не получится. Вот типичный случай: сотрудники банка работают с картотекой (долги клиентов), при этом несколько отделов рассматривают разные атрибуты на разных стадиях и категориях задолженностей. Всего там около 40 атрибутов. Вы предлагаете им всем создавать индексы по нужным им атрибутам?

В Production, повторюсь, системе, где любое изменение проходит процесс оценки, приоритизации, разработки, тестирования, затем документируется, планируется в релиз (между регулярными мораториями на изменения) и только после этого всего устанавливается.
Если вы подозреваете обман в этой или любой другой моей заметке, то свяжитесь со мной лично, разберем всё по скайпу (я и ранее так предлагал), и если это таки обман, то тогда расскажете об этом здесь всем.

Это неправда. Скорее всего, вы или тот кто это делал просто неправильно что-то настроили. Возможно даже намеренно, чтобы ваша система выглядела лучше.

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

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

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

Это всё и показано в таблице.

1 минута для выборки 1 записи (и гораздо меньшее время в «конструкторе») позволяют предположить, что для решения этой проблемы нужно было просто создать нужный индекс,

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

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

это несколько минут на изучение сторонним специалистом и один запрос в БД.

Так, за несколько минут, не получится в Production системе.
Будет выглядеть следующим образом.

Тип Чек в редакторе типов, для которого номер, локальное дата-время пользователя и сдвиг заполняются автоматически.


Список чеков


Создание чека — вносим только сумму, остальное заполнено


Отчет по чекам


Результат выполнения отчета


Да, в запросе есть функции. Правило Интеграла: «Не сложнее Экселя», то есть не возбраняется использовать простейшие формулы и функции, если нужно, как большинство это делают в Экселе.

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

Разумеется, штатными средствами Маженты или опубликованными до этой статьи. Ваши скрипты миграции мы в этом случае учитывать не можем.
Хорошо, я нашел таблицу eav_entity_int, в которой есть все поля и индексы.
Теперь проверим пункты 4 и 5 опросника для этой таблицы: покажите как в этой системе описаны типы, используемые для создания других типов и их реквизитов, которые описывают наборы связанных данных. В этой же таблице или любой другой, удовлетворяющей пунктам 1 и 2.
Время хранится серверное для всех timestamp.
У конструктора есть несколько внутренних контекстных значений, доступных по именам: пользователь, его ID, временной сдвиг относительно сервера и другие. Их можно использовать в построителе запросов или сохранять в базе при регистрации чеков, например.
Если нужно, в запросе будет учтён сдвиг — прибавлен ко времени для приведения серверного времени к локальному пользовательскому. Сервер вычислит это, выполняя запрос.
Вы про это спрашивали?
Рисунок в начале статьи, где показано, что на начальном этапе развития системы, когда в ней немного данных, запросов и пользователей, накладные расходы в несколько раз превышают расходы в традиционно построенной базе данных
Сам запрос целиком и полностью будет выполнен на стороне БД (а конструктором только правильно сформирован)
Возьмите EAV Entity и проверьте по опроснику.

Взял здесь, проверяю, несмотря на очевидно иное предназначение этой таблицы, нежели в описанном мной конструкторе.
Итак,
1. Все данные хранятся в одной таблице (см. также п.3.), содержащей как минимум следующие поля: ID, Parent ID, Type ID, Value
Структура и индексы
        /**
         * Create table 'eav_entity'
         */
        $table = $installer->getConnection()->newTable(
            $installer->getTable('eav_entity')
        )->addColumn(
            'entity_id</b>',
            \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
            null,
            ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
            'Entity Id'
        )->addColumn(
            'entity_type_id',
            \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
            null,
            ['unsigned' => true, 'nullable' => false, 'default' => '0'],
            'Entity Type Id'
        )->addColumn(
            'attribute_set_id',
            \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
            null,
            ['unsigned' => true, 'nullable' => false, 'default' => '0'],
            'Attribute Set Id'
        )->addColumn(
            'increment_id',
            \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
            50,
            ['nullable' => true, 'default' => null],
            'Increment Id'
        )->addColumn(
            'parent_id',
            \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
            null,
            ['unsigned' => true, 'nullable' => false, 'default' => '0'],
            'Parent Id'
        )->addColumn(
            'store_id',
            \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
            null,
            ['unsigned' => true, 'nullable' => false, 'default' => '0'],
            'Store Id'
        )->addColumn(
            'created_at',
            \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
            null,
            ['nullable' => false, 'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT],
            'Created At'
        )->addColumn(
            'updated_at',
            \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
            null,
            ['nullable' => false, 'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT_UPDATE],
            'Updated At'
        )->addColumn(
            'is_active',
            \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
            null,
            ['unsigned' => true, 'nullable' => false, 'default' => '1'],
            'Defines Is Entity Active'
        )->addIndex(
            $installer->getIdxName('eav_entity', ['entity_type_id']),
            ['entity_type_id']
        )->addIndex(
            $installer->getIdxName('eav_entity', ['store_id']),
            ['store_id']
        )->addForeignKey(
            $installer->getFkName('eav_entity', 'entity_type_id', 'eav_entity_type', 'entity_type_id'),
            'entity_type_id',
            $installer->getTable('eav_entity_type'),
            'entity_type_id',
            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
        )->addForeignKey(
            $installer->getFkName('eav_entity', 'store_id', 'store', 'store_id'),
            'store_id',
            $installer->getTable('store'),
            'store_id',
            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
        )->setComment(
            'Eav Entity'
        );
        $installer->getConnection()->createTable($table);



Вижу entity_id, entity_type_id, parent_id
Упс… Value не нашел.
1
23 ...

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity