Size: a a a

Node.js — русскоговорящее сообщество

2019 November 22

Ð

Ð in Node.js — русскоговорящее сообщество
Grigorii K. Shartsev
Смотря что считать логикой.
Одно дело — это перекидывать в ХП / триггеры логику.
Другое — перекидывать в транзации / поддержание косистентности и прочее, что дают РБД
а какую именно логику нельзя/неудобно перекидывать в триггеры? может я просто не то называю логикой.
источник

Б

Богдан in Node.js — русскоговорящее сообщество
John Doe
ORM это не библиотека, это слой в архитектуре приложения, который решает проблему сохранения и вытаскивание бизнес объектов из хранилища. Сама по себе библиотека автоматически не становится ORM, даже если в её описании так сказано. Миграции тоже с ORM не связаны.
Скорее всего ты используешь библиотеки по типу Sequalize как удобный инструмент доступа к таблицам бд, а не как ORM слой (мне кажется таких большинство).
Советую изучить что такое на самом деле ORM, что такое Active Record, Data Mapper, Repository
ORM это способ абстрагироваться от базы данных и упростить работу с данными. Обычный бэк-разработчик хочет писать логику обработки данных а не задумываться об трехэтажных джойнах или подзапросах. Например приходит запрос на бэк и юзеру нужно проверить заархивирована ли папка в которой находится задача (папка содержит борды, борд содержит проекты а проект задачи) и в зависимости от этого выполнить те или иные изменения. С орм такую логику можно просто записать как  
if (task.project.board.folder.archived) {
 task.update({ someField:  ...})
} else {
 task.project.update({ someField: ...})
}

А сколько джойнов или подзапросов пришлось бы писать вручную без орм и насколько будет читаема логика работы с данными сквозь эти джойны?
источник

Ð

Ð in Node.js — русскоговорящее сообщество
боязнь джойнов сродни боязни регулярных выражений :) Неопытному глазу выглядит непонятно, а не понимание как с ними работать вызывает иллюзии о нелбходимости трехэтажности. На практике словари, не содержащие критически актуальные данные, подтягиваются не джойном, а из кэша в приложении. А джойны нужны чтобы сделать фильтры по полям нескольких таблиц. В указанном примере джойнов вообще не нужно, нужна одна процедура, которая делает ряд селектов с ифами, а потом апдейт. Правильный орм сгенерирует такой же скл алгоритм, хорошо еще если завернет его в транзакцию с нужным уровнем изоляции. Если нет - поздравляю, вы сделали себе бомбу замедленного действия, которая срабатывает на хайлоаде в условиях гонок
источник

JD

John Doe in Node.js — русскоговорящее сообщество
Богдан
ORM это способ абстрагироваться от базы данных и упростить работу с данными. Обычный бэк-разработчик хочет писать логику обработки данных а не задумываться об трехэтажных джойнах или подзапросах. Например приходит запрос на бэк и юзеру нужно проверить заархивирована ли папка в которой находится задача (папка содержит борды, борд содержит проекты а проект задачи) и в зависимости от этого выполнить те или иные изменения. С орм такую логику можно просто записать как  
if (task.project.board.folder.archived) {
 task.update({ someField:  ...})
} else {
 task.project.update({ someField: ...})
}

А сколько джойнов или подзапросов пришлось бы писать вручную без орм и насколько будет читаема логика работы с данными сквозь эти джойны?
ORM это не query builder. То что у библиотек позиционирующих себя как ORM слой идёт много чего удобного из коробки не значит это это неотъемлемая часть ORM. ORM можно сделать и на сырых запросах, потому что это архитекторный слой смысл которого маппить объекты в реляуионную базу. Оно так и расшифровывается object relation mapping
источник

JD

John Doe in Node.js — русскоговорящее сообщество
Богдан
ORM это способ абстрагироваться от базы данных и упростить работу с данными. Обычный бэк-разработчик хочет писать логику обработки данных а не задумываться об трехэтажных джойнах или подзапросах. Например приходит запрос на бэк и юзеру нужно проверить заархивирована ли папка в которой находится задача (папка содержит борды, борд содержит проекты а проект задачи) и в зависимости от этого выполнить те или иные изменения. С орм такую логику можно просто записать как  
if (task.project.board.folder.archived) {
 task.update({ someField:  ...})
} else {
 task.project.update({ someField: ...})
}

А сколько джойнов или подзапросов пришлось бы писать вручную без орм и насколько будет читаема логика работы с данными сквозь эти джойны?
Посмотри не на Active Record, а на Data Mapper. Там уже модели не сохраняют сами себя и этого удобства нет как у тебя в коде
источник

Ð

Ð in Node.js — русскоговорящее сообщество
John Doe
ORM это не query builder. То что у библиотек позиционирующих себя как ORM слой идёт много чего удобного из коробки не значит это это неотъемлемая часть ORM. ORM можно сделать и на сырых запросах, потому что это архитекторный слой смысл которого маппить объекты в реляуионную базу. Оно так и расшифровывается object relation mapping
да, именно. И необходимость иметь именно объекты с методами вместо каждой строки результата - она сомнительна.
источник

Ð

Ð in Node.js — русскоговорящее сообщество
хуже всего, если орм не умеет фетчить частичные данные, и тебе надо сначала получить все объекты полностью, а потом собрать результат по одному полю из них. Ужасно неэффективно и некрасиво.
источник

GS

Grigorii K. Shartsev in Node.js — русскоговорящее сообщество
Ð
боязнь джойнов сродни боязни регулярных выражений :) Неопытному глазу выглядит непонятно, а не понимание как с ними работать вызывает иллюзии о нелбходимости трехэтажности. На практике словари, не содержащие критически актуальные данные, подтягиваются не джойном, а из кэша в приложении. А джойны нужны чтобы сделать фильтры по полям нескольких таблиц. В указанном примере джойнов вообще не нужно, нужна одна процедура, которая делает ряд селектов с ифами, а потом апдейт. Правильный орм сгенерирует такой же скл алгоритм, хорошо еще если завернет его в транзакцию с нужным уровнем изоляции. Если нет - поздравляю, вы сделали себе бомбу замедленного действия, которая срабатывает на хайлоаде в условиях гонок
Дело не в боязни джоинов.
Без проблем пишу сложные запросы, хоть с горой джойнов, подзапросов, группоровкой, аггрегацией и оконных функций.

Но на выходе с SQL я получаю плоские строки, и мапить всё это в иерархию объектов, чтобы потом удобно с ними работать — вообще не хочу.

Аналогично наоборот, разбивать объекты, чтобы потом иерархию инсертить/обновлять, дёргая из sql "дай последний инсертед id" и всё такое тоже вообще не хочется
источник

Ð

Ð in Node.js — русскоговорящее сообщество
Grigorii K. Shartsev
Дело не в боязни джоинов.
Без проблем пишу сложные запросы, хоть с горой джойнов, подзапросов, группоровкой, аггрегацией и оконных функций.

Но на выходе с SQL я получаю плоские строки, и мапить всё это в иерархию объектов, чтобы потом удобно с ними работать — вообще не хочу.

Аналогично наоборот, разбивать объекты, чтобы потом иерархию инсертить/обновлять, дёргая из sql "дай последний инсертед id" и всё такое тоже вообще не хочется
как получать выход - это на  твое усмотрение, ты можешь выдавать jsonы если они тебе нравятся
источник

Ð

Ð in Node.js — русскоговорящее сообщество
можешь даже хранить jsonы если они не нарушают нормальную форму, и строить индексы по отдельным их ключам, как в монгодб
источник

GS

Grigorii K. Shartsev in Node.js — русскоговорящее сообщество
Ð
как получать выход - это на  твое усмотрение, ты можешь выдавать jsonы если они тебе нравятся
Что, SQL научился сам в объекты маппить?
Речь не про значения полей.
источник

Ð

Ð in Node.js — русскоговорящее сообщество
научиться научился, но необходимость этого весьма узкая и редкая, на практике все что надо встраивать в виде дерева - встраивается из кэша уже в ноде
источник

Б

Богдан in Node.js — русскоговорящее сообщество
Ð
боязнь джойнов сродни боязни регулярных выражений :) Неопытному глазу выглядит непонятно, а не понимание как с ними работать вызывает иллюзии о нелбходимости трехэтажности. На практике словари, не содержащие критически актуальные данные, подтягиваются не джойном, а из кэша в приложении. А джойны нужны чтобы сделать фильтры по полям нескольких таблиц. В указанном примере джойнов вообще не нужно, нужна одна процедура, которая делает ряд селектов с ифами, а потом апдейт. Правильный орм сгенерирует такой же скл алгоритм, хорошо еще если завернет его в транзакцию с нужным уровнем изоляции. Если нет - поздравляю, вы сделали себе бомбу замедленного действия, которая срабатывает на хайлоаде в условиях гонок
Я не знаток в оптимизациях sql запросов просто замечу что данную логику где происходит обращение к полям по цепочке (task.project.board.folder.someField) а также обновление в зависимости от прочтитанных данных (а также может быть еще куча другой логики) нужно выполнить одной serializable-транзакцией чтобы сохранилась консистетность данных. Если это будет 3 отдельных селекта вместо одного джойна то получится что такая транзакция будет выполняться дольше из-за сетевых раундрипов к бд. А за это время может быть запущена другая паралельная транзакция и эти транзакции будут конфликтовать а значит откатываться и ретраится.
В идеале всю эту логику чтения и обработки данных хорошая орм должна сконвертировать в сохраняемую процедуру и загрузить в базу (вместе и if-ами и циклами и другой логикой) и тогда вся эта логика будет выполняться внутри самой базы данных без сетевого пинг-понга между клиентом который удерживает транзакцию и в итоге кофликтов между транзакцями будет намного меньше
источник

n

nikolay in Node.js — русскоговорящее сообщество
Ð
можешь даже хранить jsonы если они не нарушают нормальную форму, и строить индексы по отдельным их ключам, как в монгодб
Я как-то так сделал, ради эксперимента. Меня потом пинали всей конторой 😄  Каких-то явных минусов я так и не увидел, за исключением того, что сложно руками потом таблицу менять. Просто было лень создавать кучу полей , с которыми кроме записи в БД и чтения из БД ничего не делалось 😄
источник

GS

Grigorii K. Shartsev in Node.js — русскоговорящее сообщество
Богдан
Я не знаток в оптимизациях sql запросов просто замечу что данную логику где происходит обращение к полям по цепочке (task.project.board.folder.someField) а также обновление в зависимости от прочтитанных данных (а также может быть еще куча другой логики) нужно выполнить одной serializable-транзакцией чтобы сохранилась консистетность данных. Если это будет 3 отдельных селекта вместо одного джойна то получится что такая транзакция будет выполняться дольше из-за сетевых раундрипов к бд. А за это время может быть запущена другая паралельная транзакция и эти транзакции будут конфликтовать а значит откатываться и ретраится.
В идеале всю эту логику чтения и обработки данных хорошая орм должна сконвертировать в сохраняемую процедуру и загрузить в базу (вместе и if-ами и циклами и другой логикой) и тогда вся эта логика будет выполняться внутри самой базы данных без сетевого пинг-понга между клиентом который удерживает транзакцию и в итоге кофликтов между транзакцями будет намного меньше
Нет, вот тут sequelize не даёт ничего
источник

Ð

Ð in Node.js — русскоговорящее сообщество
Богдан
Я не знаток в оптимизациях sql запросов просто замечу что данную логику где происходит обращение к полям по цепочке (task.project.board.folder.someField) а также обновление в зависимости от прочтитанных данных (а также может быть еще куча другой логики) нужно выполнить одной serializable-транзакцией чтобы сохранилась консистетность данных. Если это будет 3 отдельных селекта вместо одного джойна то получится что такая транзакция будет выполняться дольше из-за сетевых раундрипов к бд. А за это время может быть запущена другая паралельная транзакция и эти транзакции будут конфликтовать а значит откатываться и ретраится.
В идеале всю эту логику чтения и обработки данных хорошая орм должна сконвертировать в сохраняемую процедуру и загрузить в базу (вместе и if-ами и циклами и другой логикой) и тогда вся эта логика будет выполняться внутри самой базы данных без сетевого пинг-понга между клиентом который удерживает транзакцию и в итоге кофликтов между транзакцями будет намного меньше
не совсем так, нужно просто прямо в сессии начать транзакцию и в конце сделать коммит, не знаю будет ли орм это делать или нет, но по идее должна, без этого никак. Другое дело если кодер сам это делает внутри одной функции, тогда он сам обязан начинать и кончать транзакцию, орм просто не сможет узнать что он сделал несколько действий
источник

Ð

Ð in Node.js — русскоговорящее сообщество
в моем случае делается проще - транзакция записывается в бд в виде функции с параметрами, и все. Ты ее никак не запорешь, даже если придется подключиться к проду через терминал и выполнить что-то вручную.
источник

GS

Grigorii K. Shartsev in Node.js — русскоговорящее сообщество
Ð
в моем случае делается проще - транзакция записывается в бд в виде функции с параметрами, и все. Ты ее никак не запорешь, даже если придется подключиться к проду через терминал и выполнить что-то вручную.
В виде функции - в смысле ХП?
источник

Ð

Ð in Node.js — русскоговорящее сообщество
да
источник

YZ

Yaroslav Zhymkov in Node.js — русскоговорящее сообщество
Хотелось бы услышать, как вы разделяете датамапер и актив рекордс
источник