Что такое ORM наоборот?
Давайте я для начала попробую озвучить основные плюсы использования ORM для реляционных баз как я их вижу.
Disclamer: я имел не очень большой опыт с ORM и было это довольно давно, поэтому озвучу базовые моменты. Возможно, я где-то неправ или существуют интересные фичи, о которых мне стоило бы знать. Если да, расскажите, пожалуйста об этом в чате канала.
1) Все пишется на одном языке, который знает разработчик любого грейда
2) Схема базы описываться в коде приложения, т.е. мы имеем один источник правды
3) Одна модель - один релейшен. CRUD может сгенерировать сам фреймворк.
4) Запросы собираются в коде и полностью соответствуют схеме
5) ORM все знает про маппинг типов базы в типы языка программирования
6) Вся логика в приложении, база только хранит данные
Из 2 и 4 следует еще один плюс - при миграции сложно будет все сломать.
Насколько я понимаю, без типизации сломать таки будет несложно, но давайте предположим, что мы все пишем на языках с явной типизацией. (хехе)
Не будем выявлять слабые места в этом списке. Лучше посмотрим на текущую ситуацию с разработкой приложений с использованием реляционных баз на чистом SQL.
Очевидные минусы:
1) Нужно знать +1 язык программирования (SQL)
2) Нужно разбираться в тонкостях работы используемой базы
3) Маппинг типов может зависеть от используемой библиотеки и об этом нужно знать
4) Приходится писать избыточный код - один раз на SQL и в приложении, чтобы отдать данные потребителю.
И самое неприятное - НЕТ НИКАКОЙ ГАРАНТИИ СООТВЕТВИЯ ЗАПРОСОВ И СХЕМЫ, а так же ТИПОВ РЕЗУЛЬТАТА ЗАПРОСА И ТИПОВ ВНУТРИ ПРИЛОЖЕНИЯ.
Каждые изменения в схеме влекут за собой ручную проверку, много тестов, переписывание типов и схем для протоколов.
А плюсы?
1) Можно максимально гибко использовать возможности базы
2) В большинстве случаев можно избежать проблемы N+1, что очень благотворно сказывается на производительности приложения и бюджете на железо
3) Вычисления рядом с данными делаются намного быстрее, чем те же вычисления в приложении
Кроме того, нормализация данных не подразумевает, что мы запихиваем одну доменную сущность в одну таблицу. Т.е. CRUD, затрагивающий 1 таблицу практически никогда не имеет смысла.
Создание или изменение бизнес сущности генерирует изменения в нескольких таблицах. Если выполнять все эти операции в одном запросе c common table expression, то все это выполнится (или нет) в пределах 1 транзакции. Иначе нам придётся реализовывать все нужные шаги в приложении с соответствующим количеством сетевых взаимодействий.
Но как же нам быть, если мы по какой-то причине уже хорошо знаем SQL, умеем CTE, LATERAL, FILTER, IS DISTINCT OF и знаем как оптимизировать count, но нам надоело контролировать целостность руками и писать кучу лишнего кода внутри приложения только для того, чтобы прокинуть данные от базы к клиенту?
Я предлагаю взять лучшее от обоих миров: пишем на SQL, а (почти) весь код приложения будет генерироваться автоматически!
Что нам для этого понадобится?
1) DDL в одном или нескольких файлах
2) Каждый отдельный DML-запрос придется теперь не собирать в коде приложения, а хранить в виде отдельного файла
3) Какое-то соглашение по именованию объектов в сгенерированном коде: как бы будем генерить имена типов, контроллеров, моделей и всего остального
4) Шаблоны кода для интересующего нас языка программирования
5) Маппер типов базы в типа интересующего нас языка программирования
Берем DDL, DML, извлекаем из DML метадату о результате (типы, nullability, класс количества строк), генерируем код (+ схемы, + тесты) и экономим больше половины рабочего времени!
Бонусом идут:
1) Автоматический контроль за изменением типов возвращаемых запросом значений при рефакторинге базы или запроса
2) Автоматический контроль за соответствием типов в запросе и коде приложения
3) Интеграция в CI
4) Все бенефиты статического анализатора holistic.dev :)
Ну как?
Post #636
1.12K