Обновить
49
7.3
Alex Gusev @flancer

Я кодирую, потому что я кодирую…

Отправить сообщение

Посмотрел на MySQL (10.1.34-MariaDB) — действительно, есть ощутимые задержки при изменении структуры таблицы (взял навскидку таблицу с самым большим кол-вом строк и самую большую по объёму данных из имеющихся на локалке):


table: report_viewed_product_index
rows: 1,384,812
size: 57,245,696 bytes
ALTER TABLE report_viewed_product_index ADD habrotest varchar(100) NULL;
time: 18.177s

table: sales_order_item
rows: 185,011
size: 118,161,408 bytes
ALTER TABLE sales_order_item ADD habrotest varchar(100) NULL;
time: 9.271s

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

Стесняюсь спросить, но не могу не уточнить, а вы с какой конкретно RDBMS имели дело и каким образом добавляли атрибут к объекту колонку к таблице? Очень хочется узнать всё-таки, какая из RDBMS так тормозит на ALTER TABLE.

is currently blocked by...

Печаль :( Значит, будем выкручиваться через соглашения на уровне проектов. В Magento 2, походу, для этого в модуле оформляется отдельный фолдер ./Api/, в который выкладываются интерфейсы, публичные с точки зрения модуля. Т.е., сторонние пользователи функционала, предоставляемого модулем, должны использовать только то, что находится в этом фолдере, а всё остальное — на свой страх и риск (разрабы модуля могут трогать остальной код модуля когда вздумается и сам себе злобный буратин, если завязался на что-то вне ./Api/).

А при чём тут ERP? Вернее, при чём тут таблицы и колонки RDBMS, если некая коммерческая ERP добавляет новый атрибут к объекту? Это вопросы к авторам "коммерческой ERP" — что за логику они реализовали на десятки минут и почему нужно выгонять пользователей. Уверяю вас, такого же эффекта разрабы ERP могли добиться и на NoSQL-базах, и на файловой системе, и, если постараются, в оперативной памяти и при гораздо меньших объёмах данных. Вы как-то слишком широко обобщили свой негативный опыт с ERP сразу на все РСУБД.

А при каких размерах таблиц (кол-во записей, размер в байтах) данный эффект (ждать десятки минут) возникает?

можно сделать приватные для модуля классы

Вот с этим согласен, это приятная плюшка, которую было бы неплохо иметь и в PHP. Но эта проблема решается на уровне conventions в проекте.

невозможности на лету добавить атрибут для конкретного факта.

Я правильно понимаю, что вы пытаетесь добавить колонку в таблицу в реляционной СУБД? А почему эта операция занимает столько времени и с такими сложностями (нужно выгнать пользователей и ждать десятки минут)? Или "атрибут" и "факт" имеют какие-то другие смыслы в данном контексте?

Нет, не похоже. Проблемы с адресацией элементов кода в проекте это не решает.

Могу. Например, в JS/Python любую функцию проекта можно однозначно адресовать вот таким вот образом без привязки к файловой системе и без использования namespace'ов.

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

Раз привязки к файловой системе нет, где его искать непонятно.

Каждый composer compatible модуль привязывает (autoload) свой namespace к собственной файловой структуре в файле composer.json (аналог package.json в npm). В результате composer (менеджер зависимостей в PHP) при сборке проекта из отдельных модулей создаёт карту соответствия пространств имён фрагментам файловой системы. После чего вам достаточно подключить в вашем головном файле автозагрузчик, который и использует эту карту:


<?php
require_once __DIR__ . '/../vendor/autoload.php';

и вы можете создавать новые классы, основываясь на их именах:


$dbalCfg = new \Doctrine\DBAL\Configuration();

или


use Doctrine\DBAL\Configuration;

$dbalCfg = new Configuration();

или


use Doctrine\DBAL\Configuration as Config;

$dbalCfg = new Config();

Карта обновляется по мере подключения/отключения модулей


composer require vendor/module

и может быть использована также и IDE для поиска исходников по имени класса.

Я специально нигде ни в статье, ни в комментах не использовал use, вы сами первый его написали (можете проверить по Ctrl+F) :) Но если после этого, кому-то что-то стало понятнее, то и хорошо.

Через composer.json оно, конечно, лучше, но я не стал плодить сущности в примере :) Тем более, что в конечном итоге оно всё равно окажется в ./vendor/composer/autoload_classmap.php. А так ваше замечание совершенно справедливо, в папке ./vendor/composer лучше не делать изменения ручками.

Да, троечка с namespace'ами. Вы реабилитировали Yii в моих глазах, спасибо :)

Вы по ходу дела плавно подменили первоначальную проблему "сложно уникально адресовать два класса с одинаковым названием, не привязываясь к файлам, в котором они определены" другой — "мне нужно импортировать два класса с одинаковым названием и это не решается алиасами" :)


Дело в том, что в PHP-проекте я могу написать:


$init = new \Doctrine\DBAL\Event\Listeners\MysqlSessionInit()

без того, чтобы использовать import или require. При этом я не должен знать о том, в каком каталоге находится файл, в котором находится исходный код. Именно потому, что в PHP/Java/TypeScript/… есть директива namespace. А в JS/Python этой директивы нет, вы её никогда не использовали и не понимаете для чего она вообще может быть нужна. Если вам она не нужна, то это говорит только о том, что вы ещё не достигли своего предела сложности в JS/Python.

Что такое doctrine/DBAL и doctrine/ORM? Каталог, файл или некоторая строковая метка для поиска пути к исходникам по некоторому алгоритму?

Я не программирую на TypeScript, а в JS нет namespace'ов (поэтому они не выручат). Что касается PHP, то вот два класса с одинаковым именем Configuration, конфликт которых "разводят" namespace'ы (оба класса, что характерно, находятся в файлах Configuration.php):



Для того, чтобы создать объекты этих классов в современном PHP-приложении мне достаточно знать их полные имена, все остальное делает менеджер зависимостей (autoloading).

Вы правильно сказали — "не попадают в глобальный скоуп". В JS вообще нет namespace'ов в смысле логической группировки элементов кода. Есть scope. Именно поэтому на JS'е сложно писать сложные проекты — сложно уникально адресовать два класса с одинаковым названием, не привязываясь к файлам, в котором они определены. А в PHP можно. И в Java можно. И в Typescript можно (если я правильно понял).

Сможет. Если прописать в ./vendor/composer/autoload_classmap.php


'Prophecy\\Call\\CallCenter' => $vendorDir . '/bla/bla/bla.php',

Пространства имён не привязаны к языку. В Java нет жестких требований по расположению файлов — вы указываете их местоположение в CLASSPATH при запуске приложения.


И пространства имён не являются обязательной фичей для достижения "максимальной сложности приложений". Я пытался донести мысль, что пространство имён при прочих равных условиях (например, язык и квалификация разработчика) позволяют создавать более сложные приложения, чем без них. Вы можете писать на PHP без использования namespace, некоторые до сих пор так и делают. Но в таких пакетах, как Zend2, Symfony, Laravel — используются namespaces.


Кстати, в Yii и CodeIgniter, к моему удивлению, не используют пространства имён. В результате в Yii имена файлов выглядят так:


image


А в CodeIgniter так:


image


Обратите внимание на префиксы в названиях файлов — разрабы вынуждены обеспечивать уникальность имени каждого файла в пределах проекта (по сути, вручную, не используя средств языка, вводят пространства CDb и DB_). Да, для 1000 файлов они выкрутятся (какой ценой?), а для 300 млн.?


Если вдруг решите попрограммировать на PHP, не начинайте с Yii и CodeIgniter ;)

Информация

В рейтинге
827-й
Откуда
Рига, Латвия, Латвия
Дата рождения
Зарегистрирован
Активность

Специализация

Фулстек разработчик
Ведущий
От 3 000 €
JavaScript
HTML
CSS
Node.js
Vue.js
Веб-разработка
Progressive Web Apps
PostgreSQL
MySQL
GitHub