#51 ORM vs SQL — Дебаты: что побеждает в реальных проектах? Александр Вершилов

друзья привет с вами подкаст Организованное программирование я его ведущий Кирилл Макевнин и сегодня у меня в гостях Александр Вершилов а с которым мы поговорим неожиданно про ОРМ саша известен в миру как специалист по Хаски а-а наверное один из главных в русскоязычном или вообще главный в русскоязычном так сказать небос небосводе так сказать комьюнити вот и мне даже перед тем как мы начали ну когда я Саша тебя пригласил ты там мне в твиттере написал я разговаривал с разными людьми они такие: "О не очень очень неожиданно тебя видеть в таком амплуа что такие раз прорм пришли поговорить" но и сказали что это даже интересно потому что ну про Хаскиль все уже всё плюс-минус слышали вот а сегодня мы с тобой поговорим об этом хотя кстати про Хаски всё равно мне надо выпуск будет сделать от меня его ждут и я его ещё пока ещё не сделал собственно привет
привет приятно сюда очень прийти и что ты пригласил раз уж коснулись Хаскеля естественно мы его коснёмся и здесь куда уж без него вообще мне тоже немножко неожиданно здесь говорить про Урм когда я увидел в Твиттере то что а ты спрашиваешь не хочет ли кто-нибудь а чтобы рассказать почему РМ - это не очень хорошо естественно я захотел отозваться потому что ну в со в своей работе обычно редко используем такие библиотеки а редко используем УРМ и очень часто с коллегами приходится дискутировать вот как раз на стороне того почему это плохо
добро или зло
да с другой стороны как только я отозвался я сразу заметилтил ну представил вообще какие аргументы я могу привести и понял что в общем-то все аргументы которые я могу перевести в стандартном объектноориентированном мире очень многие из них разбиваются и на них есть хороший ответы поэтому в в данной баттле двух Якадзу
да в этом баттле я честно говорю что я буду адвокатом дьявола я буду представлять эту роль но это не та роль в которую я до конца верю и на самом деле если у меня спросят вот использовать не использовать то при прочих равных для большинства языков я скажу: "Конечно используйте но помните что ну а дальше весь вот этот вот выпуск который будет" да да да ну а в принципе можем заканчивать уже я кстати так и не сказал да я сказал поговорить про ОРМ но не объяснил вообще мы хотели поговорить про ОРМ в формате дебатов то есть Саша топит против ОРМ я топлю за ОРМ понятное дело что мы как инженеры с примерно похожим опытом кстати в программирования там 15-17 лет что-то в таком духе у нас всё-таки довольно спокойно к этому отношение да есть инструменты мне честно мне вообще пофиг я вот если в этой экосистеме так я пишу так если в этой экосистеме так я пишу так но это нужно единственное сразу предупрежу вот как примерно было с выпуском по ТД а там в процессе просто мы вроде хотели дебаты да дебаты не получились но они не получились не потому что мы облажались а в данном случае просто во время разговора стало понятно что всё-таки надо больше про тестирование поговорить потому что слишком много базисных вещей которые надо было синхронизировать ну нельзя типа говорить про очень высокоуровневую вещи не имея какой-то общей базы это слишком будет неправильно поэтому я как бы в какой-то смысле думаю повторить и здесь ровно то же самое мы не знаем получится ли у нас с Сашей это прямо дебаты поэтому с одной стороны мы так заявляем а дальше как пойдёт так что не обессудьте куда вырулим туда вырулим да давай начнём наверное с чего с того что ну в целом-то люди как будто бы знают да что такое но просто ещё на всякий случай у нас значит есть данные в базе и помимо классического DBA нет а по-разному называется database access layer DBAL они называют да это в любом случае слой который у тебя присутствует независимо ни от чего просто потому что тебе надо связываться с базой ну как-то туда запросы посылать да и этот слой есть всегда и везде в некоторых случаях он более-менее в некоторых языках кстати он более продуманный когда знаешь придумывают единый интерфейс доступа с разными адаптерами к разным базам данных в некоторых языках всё гораздо печальнее там просто вот понапихали независимых адаптеров и у тебя нет то есть тебе нужна типа библиотека не встроенная там не как некая стандартная либо или ещё что-нибудь тебе нужна прямо отдельная либо которую кто-то пилит которая унифицирует не во всех языках кстати это есть вот например в ноди вообще нет такого у тебя нету а DBL а единого да интерфейса у тебя есть ормки которые это внутри себя предоставляют но вот чтобы какой-то общий такой знаешь выделенный такого нет это всё немножко поплыло последнее время по одной простой причине что развелось огромное количество облачных базданных и базданных которые устроены немножко по-другому и поэтому красота этих всех адаптеров которые просто на классические знаешь эти скельные базы данных она немножко стала теряться и поэтому появились новые челленджи которыми сталкиваются современные рынки ну это так просто общая такая вводная история
я здесь немножко удивлён потому что ну проabase Access Layer естественно нам придётся поговорить и ну библиотеки ну самый известные ОДBC которые Object Database Connector который мне казалось что байндинги и связь к ней есть прямо практически в любых языках ну потому что это сишный интерфейс а к си привязываться умеет ну подавляющее большинство языков которые работают на не в браузере а вот поэтому я подозревал что оно есть везде
а у тебя в PHP это PDO и то он тоже появился не сразу
ну он причём я тебе даже смешную штуку скажу вот там есть в PHP PDO есть например да который представляет такой общий уровень ему много лет при этом помнишь на госслугах недавно запустили тестирование по языкам сертификации я для прикола зашёл и именно PHP выбрал думаю ну давай вот его отвечу во-первых как бы это основа PHP ну логично про по языку надо вопросы ну ладно там по HTML были вопросы и CSS о'кей
но там был вопрос типа показывают конкретный адаптер причём не пдошный а как раз вот знаешь вот именно имплементацию которая была ещё до появления ПДО показывают коннект с параметрами четыре вида и спрашивают какой из них правильный ты можешь себе представить что происходит я я вспомнил что я с этой штукой работал в 2008 году последний раз типа вот на таком уровне
я начинал с ПХП эти истории помню как раз помню появление ПДО и как наконец-то этим можно пользоваться и жить стало немножечко проще
а в Хаскиле есть кстати DBL
есть бандинги к ОДBC есть много стандартных у ДБЦ очень удобно особенно когда нужно неожиданно к какому-нибудь Ораклу коннектиться к которому естественно никто библиотек не написал специфических и тогда можно работать через ОДБ естественно а там многом поскольку это коннектор ко всем базам то возникают все проблемы связанные с этим то есть мы можем работать только с общим подмножеством а всё что выходит конкретной базе начинаются прыжки через горящие кольца как и СРМ которым мы дойдём
ну да вот это просто такой базис некий который вот в везде присутствует поэтому грубо говоря даже если нет в языке общепринятого вот этого слоя то те люди которые реализуют УРМ но они какое-то подобие пишут потому что им нужна возможность свичить базы и дальше появляется да УRМ им он как бы гораздо более высокоуровневый это не просто передал как в DBL запрос получил statйтмент и там его разбираешь ручками да с какими-то преобразованиями в зависимости того динамический или статически типизированный язык там где-то тебе надо класс делать и маппинг происходит где-то ты просто не знаю ассоциативный массив получил мапу и с ней работаешь да в зависимости от языка чуть-чуть по-разному а УRМ это всё абстрагирует и делает ещё более высокоуровня у нас появляются несколько слоёв и вот тут перед тем как мы опять же перейдём нужно знаешь наверное что зацепить я бы вот с чего начал очень разные люди очень по-разному понимают что такое ОРМ и это очень сильно зависит от конкретной экосистемы мы как-то знаешь когда Джаву обсуждали SpringБД знаешь эти есть истории про поводу там что типа они делают какие-то непредсказуемые запросы там а кастомизация и так далее вот вот это всё хочется пообсуждать в том числе связав это с тем что мы подразумеваем под УRМ потому что есть датамаперы есть активрекорды они все ещё очень сильно по-разному могут работать есть просто quyбиilder и для некоторые думают что это и есть и является ли это частью его или нет вот поэтому давай я наверное тебе вопрос задам сначала для тебя УRM что включает какие элементы
для меня R включает обязательная вещь object relation mapping собственно это возможность отображения данных а из выделения данных между в доменной моделью в языке и таблицами базы данных это может быть как связь один к одному ну то есть что у нас есть какой-нибудь класс там или объект и он отображается на какую-нибудь таблицу может быть какие-то более сложные структуры вот это вот самое главное ядро без чего мы обм говорить не можем ну иначе это что-то другое соответственно и туда входят дополнительная вещь это quyilder это абстракция над тем как мы строим запросы то есть что мы используем некоторую объектную модель некоторый DSL который позволяет нам не использовать SQL как есть дальше ну вот этот вот механизм отображения автоматического сбора разбора параметров и результатов абстракция для управления транзакциями сессиями здесь можно так и так называть и это то что обязательно входит по-моему а дальше могут быть дополнительные вещи которые уже не обязательный атрибут это система кэширования система какого-нибудь батчинга запросов в общем всё что наворачивается дополнительно но уже не является особенностью какой-нибудь конкретной экосистемы и решает вот эти вопросы
угу у меня сразу вопрос по поводу маппинга смотри вот если ты работаешь в Джаве допустим я думаю что это касается любого статически типизированного языка ты даже работая напрямую как бы с базой данных через коннектора а у тебя мапинг есть ты не можешь просто взять данные и получить тебе всё равно нужно указать класс правильным образом создать поля для того чтобы у тебя происходила эта трансляция ну у тебя физически нет такой штуки как объект в джаваскрипте как ассоциативный массив PHP и так далее да то есть тебе всё равно нужен класс поэтому у тебя как бы даже если нету RМ как минимум трансляция из базы в код она уже на самом деле работает по принципам то есть как бы по твоему определению это уже есть ORM а вот в обратную сторону да в обратную сторону тебе SQL запрос оно само не напишет поэтому тебе надо из этого объекта всё извлечь и вставить но прямой маппинг есть
да ну но он должен быть как - это штука объединяющая себе все вот эти вот атрибуты а соответственно если у меня его нету то это нем если у меня такой мапинг есть это ВРМ в том же самом Хаскеле почему не использовать ВРМ потому что на самом деле все вот эти вот атрибуты которые были перечислены они на самом деле в том или ином виде нужны и полезны но они могут предоставляться как одним фрейворокам который всё в себе содержит идёт на какие-то компромиссы свои так может быть можно собирать из отдельных библиотек ну и подбирать какое-то решение которое нужно вот на самом деле я фанат такого подхода забегая вперёд грубо говоря из кусочков собрали себе УРM который отвечает именно тем требованиям которые возникают в проекте вроде бы всё кажется дополнительных атрибутов которые прямо ОРМ обязан иметь я наверное не могу сказать но наверняка что-нибудь вспомним пока говорить будем я скажу сразу ОРМ не будет УРМ если там нет связей потому что у тебя извлечение данных по связям - это очень важная часть которую если отсутствует ты как бы не понимаешь нафига тебе тогда это надо потому что это очень большое сокращение да
у меня это не явно было в в предположении что мы мапим доменную модель на таблице но действительно это правильно проговорить да и часто там бывает валидация тут по-разному да в разных системах по-разному например есть вообще в каком-нибудь Ларавеле в PHP там вообще валидация вынесена на уровень реквестов то есть ты даже проверка уникальности имейла и так далее она не является вот частью этой системы где-то ты это вешаешь это внешний механизм как в той же Джаве а спринге у тебя там это Джакарта какая-нибудь да и это не является частью самой Рэмки это отдельная история которая с ней соединяется
вот и у тебя есть другие ОRМ там какой-нибудь RUB там или ещё где-нибудь где у тебя вообще валидация просто часть самой Рэмки и соответственно там всё проверяется на самом деле валидации уровней просто должно быть несколько и на уровне реквеста и на уровне модели это просто разные механизмы но в целом это довольно важная тоже часть потому что без валидации аля из серии проверить уникальность там какого-то поля что оно должно быть уникальным ну честно говоря тебе сразу придётся кучу рукопашки писать то есть с точки зрения такого просто дикса - это довольно важная история но тогда смотри я перед тем как копать ты интересную вещь сказал что у тебя восприятие что queryбиilder не обязателен то есть типа ты можешь построить объектнореляционный маппинг без необходимости вообще присутствия крибилдера что правда да ты можешь напрямую
угу
ну типа дополнение но во-первых всё-таки мы никогда наверное такого не видели то есть у тебя любая ОRM строится вокруг какого-то квеyбилдера но он там всегда присутствует да то есть его не делают а во-вторых я бы знаешь наверное хотел сказать так что вообще первый уровень взаимодействия с любой базой данных то есть я за что я за то что там всегда должен быть минимум quyбиilder просто Никита если ты помнишь в где-то в той переписке написал что или где-то кстати подкаст я его смотрел он такой он клажуюст там понятно он у него вообще там всё свободное и всё можно никаких ограничений и он как раз с кем-то спорил на тему того что да строчки клеить с SQL вообще не проблема мне нравится и вообще это классное решение не согласен вообще и считаю что это неправильно потому что когда ты встречаешься в своей жизни с какой-то маломальской фильтрацией где тебе надо эндами орами собирать эскеэльку ну это жесть честно тебе скажу во-первых в целом сам процесс сбора во-вторых качество ну валидация контроль там типы и всё остальное едет по одному месту и я например считаю что SQL всё-таки в первую очередь нужен хороший QY builder который надо использовать даже если вы не используете ОРМ почему потому что все те претензии которые обычно крм предъявляют они редко касаются билдера да то есть они обычно говорят: "Вот непредсказуемый запрос ну билдер делает только ровно то что вы хотите да а там ну ещё какие-то вещи касаемые ну вот типа вот создаём много объектов билдер не создаёт никаких объектов он делает там то что ему скажет он просто SQL генерит" вот вот у меня такой поинт по поводу билдера
я тогда наверное сделаю контрпоит для того чтобы здесь было интереснее на самом деле ну сначала наш пример сначала я соглашусь я соглашусь с тем что когда как только начинается много фильтрации то query builder прямо сильно помогает то есть если у нас есть какой-то основной запрос а дальше нам нужно накидать разных в рлимитов а ещё бы хорошо не джойнить лишние таблички если мы понимаем что они здесь не не нужны будут и тогда прям ну если у нас условия например предполагает что мы дотягиваем данные с другой таблицы и в этом случае если у нас нету какого-то билдера тяжело а вот к этому вернусь чуть-чуть у нас на самом деле используется библиотека которой пишется честный чистый SQL почему иногда это бывает полезно потому что основной паттерн у нас происходит у нас на самом деле не так много в и не докидываются то есть мы э у нас не редко возникают случаи когда нужно сделать запрос потом пофильтровать его либо совсем по одному условию либо совсем по-другому чаще просто передаются некоторые параметры в фиксированные значения и в этом случае как какой сценарий вообще работы пишется SQL благо у нас э разработчики знают SQL после этого оно вставляется в датагрип там или ещё куда-нибудь а дальше анализируется вообще сложность запроса как оно идёт все экспленны и вот всё просто как есть запрос доводится до того что он отвечает всем пожеланиям которые хочется сделать и вставляется в код как есть при этом дальше его можно вписать в отладку туда можно добавить каким-нибудь комментарием какую-нибудь уникальную строчку так чтобы его можно было найти в исходном коде откуда он вообще взялся что это такое и после этого можно легко отлаживать если например мы видим что какая-то проблема с приложением можно посмотреть логи посмотреть какие запросы идут вставить этот запрос как есть и не возвращаться в исходный код и не думать а что у нас вообще собралось и этот сценарий он прям очень удобный и очень хороший естественно всё всё ломаете в том месте где я согласился и как только начинается что-то прямо нестандартное то каждый раз приходится думать а обходные пути для этого конечно есть но они все под вопросом без крибилдера начинаются сложности вот
хотите расти как разработчик не в одиночку а вместе с сильным сообществом вступайте и в Hexetк Clлубub это закрытое пространство для тех кто уже в профессии хочет развиваться дальше здесь помогают определить уровень построить персональный план развития и дают обратную связь менторы из индустрии в том числе из зарубежных компаний в клубе живые разговоры о технологиях собеседованиях работе в компаниях карьерном росте и нетворке есть отдельные топики с историями участников отзывами о работодателях отчётами менторов и планами развития люди приходят в клуб чтобы расти и помогают другим делать то же самое ну кстати по поводу логов сразу тебе скажу а для меня ты как раз как человек который на рельсах писал много там вот DX очень на высоком уровне и у тебя история про то что любой запрос в базу логируется в лог ну и в девелопменте и в продакшене в зависимости от того какой-то уровень выставляется и ты тебе не нужно никуда ходить ты прямо видишь более того он тебе прямо пишет откуда это всё пришло модельки там и так далее в каком контроллере это было вызвано то есть там глубина как бы трейса не трейса скажем а метаинфы очень высокая то есть я такого особо нигде не видел и кстати в этом плане меня всегда поражает какой-нибудь там м спрингвуд в котором по дефолту этого нет и ты реально чувствуешь себя как без рук и я первое что я делаю когда ставлю спрингб я такой гуглю эту опцию потому что я никогда не помню какая она да чтобы включить запросы в лог по крайней мере она есть вот а во многих экосистемах действительно вот его нет и я встречаюсь когда ну вот с сталкиваюсь с людьми они действительно даже когда такого паттерна не знают это их удивляет что так вообще можно было ну потому что там там логер внутри логер
а второе смотри здесь ещё такой есть момент интересный касаемый вообще типов а то есть представь вот вы таки не хочется конечно к Хаскелю всё это сводить но как пример там ну неважно какой язык да на раз там го
если ты делаешь то как ты сейчас рассказываешь ну у тебя выбора нет чтоб тебе тесты писать надо ну потому что там же просто может быть опечатка в SQL запросе банальная
это прекрасно делается на самом деле мы это называем explain тестами у нас есть механизм который собирает все написанные запросы и во время ну и во время когда запускаются тесты он прогоняет на них эксплей то есть у всех все параметры типизированные поэтому мы можем генерировать случайное э случайное значение из того из подходящего домена вот и соответственно запускается Xplain из этого мы во-первых видим что во запрос в принципе валидный потому что иначе он свалится а дополнительно ну это мы тестировали но итоги так не делаем дополнительно мы на самом деле можем проверять то какие индексы используются не используются там используется ли у нас там full search ну секскаcan и валить тест в случае если у нас например перестали использоваться нужные индексы так что вот проблема того что опечатки есть на самом деле её достаточно дёшево чинить и получить ещё и дополнительные плюсы
ну это при условии что у тебя скиль прямо совсем отделён потому что у многих как бы даже если несмотря на то что не используют ORM это не означает что у них это прямо такой слой прямо с который можно совершенно выделить особенно там где много нечистого кода прямо скажем да у тебя побочные эффекты это где-нибудь внутри в кишках напрямую кто-то нахерачил там конечно ну очевидно вообще никаких шансов нет и такого происходит мало то есть во-первых этот подход требует дисциплины видишь я такой пошли дебаты на самом деле это хорошо а второе ещё прикольное хотел сказать не просто так у вас не зашёл этот подход с оценкой индексов и всего остального потому что с инженерной точки зрения это вообще не рабочий подход ну типа просто контролируем результативность у нас в разработке софта принято по-другому из-за очень динамической среды потому что всё меняется и ты сам знаешь то есть грубо говоря мы не пытаемся превентивно посмотреть какие индексы там используются и так далее во-первых это зависит от данных текущей версии базданных там миллиард всяких разных параметров и поэтому мы используем все инструменты а аля как они правильно называются которые ну типа там и и так далее которые трекают прямо сейчас у тебя что происходит в реалтаме в продакшене
собирают всё это и показывают статистику причём там намного больше чем просто сложность запроса у тебя может быть запрос кривой косой не используют индексе но на постоянной табличке которая там не меняется и и он происходит один раз в админке да а при этом у тебя есть запрос гораздо более простой но зато вызывается 5 млн раз там в секунду
вот и реально очень сильно влияет на на то что происходит и поэтому такая система она обычно намного более эффективная потому что ты и так ты и заранее можешь увидеть у тебя редко бывает такое что запрос с ходу начинает уничтожать твою систему да то есть эта деградация идёт достаточно медленно ну и вы сами ты сам как сказал вы не используете эту штуку а вы кстати юзаете какой-то аналог для контроля медленных запросов объёма запросов ну типа в центре вот например
у нас отчёты по статистике запросов таблиц э генерируются приходят и по на основе них алерты ну и соответственно часть интересного дампится в прометей для прямо важных запросов которые мы смотрим вот ну и соответственно да ну у нас у нас сами делаем и плюс вот вся статистика которая у нас используется Постгрос если смотреть по бестпрактисам мониторинга Постгрос на их вики то соответственно там есть достаточно большое количество запрос этих полезных запросов как смотреть и статистик соответственно по ним делается выборка и присылается такой отчётик
а мне знаете что интересно а у вас а чем обусловлен выбор как бы рукопашности потому что ну вот мы взяли там тот же самый сентри да я имею в виду сентри никак он же выполняет несколько королей просто может быть кто-то слышит меня не понимает причём здесь с Нентери сенent - это же не только трекер ошибок у него ещё это APM или ARM называется я забыл вот это вот когда трекается производительность да то есть причём он очень глубоко это смотрит и на уровне там вызова функций и на уровне скеэля и фронтENд вам проверяет и так далее и поэтому он показывает это не просто из серии Медленный запрос он показывает вам в каких запросах как часто это вызывается и так далее то есть он собирает очень комплексную статистику которую только одной базой получить невозможно ну потому что у вас запрос может вызываться часто но он например только в админке ну понимаешь да там вот много такого
и получается это самое дешёвое решение которое ну 100% рабочее я понимаю что если например у вас есть требования ну не знаю secкюрити и тонтри себе можно поставить или у вас такие объёмы что вам как-то надо по-другому но мне кажется для типовых проектов это выше крыши а тот проект которым ты занимаешься он он какой-то супермеганагруженный или почему или это так исторически сложилось
исторически скорее исторически сложилось отсутствие хороших ну чтобы собирать много информации нужно чтобы были хорошие бандинги и а хорошо проходиться по всему коду ну то есть хорошие бандинги для языка а для языка типа хаски хороших их тут не буде автоматической инструментации не будет для того чтобы всё это получить хорошо поскольку не будет автоматической инструментации нужно будет писать это вручную в одном случае мы пишем вручную и в другом случае вручную но если сделать штуку которая соберёт статистику и всё отошлёт это час работы и задача в крон на на на ночь то здесь в любом случае количество работы которое в это будет сделано оно будет больше хотя я подозреваю ну если делать нормальную телеметрию скорее всего это будет open телеметри и соответственно весь тек который с этим идёт
кстати слушай а знаешь сейчас что вдруг понял вот мы пока с тобой говорили а если брать прямо конкретно Хаскель и проблему Рэмов там вот я же буквально некоторое время назад сказал ну типа просто лог пишешь как бы и всё ну в Хаскиле-то хрен ты лок напишешь если ты начнёшь это делать у тебя сразу А везде попрёт с самого низа
мы делаем запрос в базы данных у нас уже
на уровне а ну да в принципе на этом уровне можно да
здесь мы точно не потеря Ну во-первых если очень хочется писать лог всегда можно и отправить его куда-нибудь в чистом коде и выдатьре вот результат а что мы насчитали а вот лог который к этому идёт в любом случае мы окажемся в какой-то момент в месте где у нас разрешены эффекты если наш сервис не только даже если наш сервис только в консольку выводит и ничего не возвращает результат который кем-то другим выведется в консольку всё равно мы можем вместе с этим при притащить чистое значение которое будет слагировано естественно в этом случае мы не сможем сказать в какое время оно было вот но это больше такая ситуация в том же самом Хаскеле если очень хочется что-то повыводить и поделать какие-то дополнительные эффекты это можно сделать лучше конечно не делать плохих вещей не то то да того что не приветствуется но это никогда не будет проблемой что вот мы застопоримся и не сможем что-то интересное для отладки получить
ну то же самое вот отправка телеметрии да то есть это вполне можно воткнуть потому что это скорее всего и придётся Нет ну в чистый код вряд ли это придётся пихать это надо как раз пихать в тех местах где эффекты начинаются то есть когда мы запрос базу делаем да
чистый код тоже наверное интересно некоторые вещи пихать например там какие-нибудь спаны с информацией в какую ветку мы зашли а вот но единственное что нужно понимать что в чистом коде особенно в ленивом языке порядок в исполнения может быть немножко не тем который предполагает человек привыкший работать в языках с аппликативных это называется в общем со строгим порядком вычисления э и это может и как бы чтение логов может приводить к неожиданностям честно скажу что обратноя верно когда много лет поработаешь в ленивом языке и начинаешь читать э логи отладку там в строгих языках тоже возникают неожиданности вот и не предполагать что оно на самом деле исполняется так вот ну это палка о двух концах в любом случае дело привычки итого если подвести черту под историей с Сquйрибилдером я бы по дефолту всегда его использовал и я даже пока наверное не встречал в своей жизни ситуации при которых вот я бы понял что вот здесь нельзя никак я имею виду в прикладных вот если мы прикладные используем понятно что библиотечки - это немножко другая история там и какой-нибудь системный софт но вот когда мы прикладной какую-нибудь берём историю то тоби минимум
у меня небольшой вопрос про quyilder особенно про языки где легко его сделать хорошо расширяемо так скажем дата базоспецифичные вещи насколько хорошо там поддерживаются потому что вот ну встречаясь с разными quyдерами а в некоторых легко попасть в ситуацию что база данных поддерживает какую-нибудь фичу а её в крибилдере никаким образом разумным не выразить
о вот тут я тебе хочу прикольную вещь рассказать а я сегодня буду адвокатом как знаешь меня всё время говорят: "Кирилл ноль ноль выпусков когда Кирилл не упоминал Рейлс" да вот такая вот история и будет ноль вы Да и ноль выпусков когда Кирилл не упоминал Дризл я стал фанатом этого УРМ я думаю что вполне возможно ребята которые его делают может быть даже смотрят выпуски и им привет большой они молодцы а смотри существует же несколько подходов да learn ones use блин как же там нет write on use everywhere да вот этот подход это вот как бы более такой классический подход к котором все привыкли из серии мы делаем единую абстракцию и там как-то вот обходим эти все углы мое то в этом плане любой тебя вообще никак не ограничивает нет такогобир сказал нет я буду тебе мешать делать запросы то есть ты например у тебя там допусти селект какой-нибудь есть да есть у тебя есть там способ это описывать каким-то простым способом именно самого верибра а есть например вариант селектора не селектора в смысле а селек написать метод не знаю передав либо туда другие параметры там перегрузка будет либо это просто selectро какой-нибудь да типа сырой и ты туда просто тупо строчку вставляешь как хочешь а иногда можно просто в таком случае просто отказаться от квебилдера то есть если ты отказываешься от крибилдера то кверибилдеру вообще не причём потому что ты просто тупо напрямую лезешь да а если ты его используешь то как правило просто у тебя каждый элемент он позволяет себя тупо кастомно описать как угодно ну там уже в зависимости от утобства языка но вот например чем мне нравится Дрил это ORM нового поколения скажем так они относительно недавно появились и они работают по-другому там вообще много плюшек и те как аскелисту это бы всё понравилось на самом деле то есть представь у тебя такой уровень типизации что ты просто не можешь например джоийн сделать на табличке которые реально не сйны ну нельзя сжойнить по параметрам он тебе просто на уровне типов ошибку покажет вот это мягко говоря круто я тебе хочу сказать
вот и как там устроено они не делают quyilder универсальным в плане того что у тебя есть возможность использовать то есть грубо говоря есть такое понятие ещё learn once use everywh React Native например да он же не говорит что один раз написал
и оно типа везде работает он говорит: "Смотри под Android свои примитивы подаёт свои примитивы"
угу
это вот вот его подход то есть ты просто используешь в нужных местах примитивы конкретной базы данных и они как бы развиваются просто независимо это отдельный тупо пакет в котором есть вот возможности конкретной базы данных
и это очень круто работает ну там просто типизация при этом обеспечивается у тебя понятно что опять же конечно можно сказать что ну найти в посгресе не знаю какие-нибуд там супер костомные типы данных там вот и там какой-то алгебраический тип данных собрал вот и такой: "Ой а у меня нету функциональности" ну возможно нет ну ты страдать в любом случае будешь кстати то есть если ты такую штуку делаешь какая разница где ты будешь страдать всё равно если её не заимплементили
пострадать придётся
я кстати помню мы были проекты в которых мы очень много этим пользовались и конечно я потом а вот кстати тут ещё могу преимущество у РМ такое классное сказать а то есть были проекты в которых знаешь ну надо тебе массивчик то есть такой ну не хочу связь я делать вот в Поскгресе прикольно есть массивчик хочу вот здесь вот массивчик фигануть
или здесь вот ещё что-нибудь такое хочу там с координатами например да там много всяких интересных штук есть IP-адреса какие-нибудь обычный же путь какой если ты такой нем minded человек такой: "О сейчас я туда херану" ну и потом пошла вот эта вся рукопашка это же как-то надо там парсить разбирать и всё равно что-то с этим придумывать ну потому что оно тебе не вернётся в том формате в котором ты хочешь да там у тебя есть определённые требования к преобразованиям и вот мне в этом плане очень нравятся урмки многие которых знаешь как сделано то есть допустим у тебя появляются ну допустим теги ты хочешь их как массив хранить и не париться так вот ты можешь просто в модельке сказать что вот это полете ну оно во множеном числе потому что теги serлай то есть просто сериалайте то есть получается что на уровне модельки ты с ним работаешь как с обычным массивом в коде при этом туда он на самом деле знаешь что делает он просто его тупо в джейсончике или в ямле складывает то есть там даже не массив с точки зрения типа
о'кей
и это очень круто потому что этим очень удобно и легко управлять то есть тебе не надо понимаешь менять схему базы данных тебе не надо ничего придумывать ты в любой момент можешь свичнуться и для тебя это полностью прозрачно понятное дело что если в каком-то крайнем случае вот тебе нужно либо для производительности либо ты там выборки хочешь делать по этой штуке да ну потому что есть запросы то конечно тебе придётся в самом посресе делать но по дефолту я предпочитаю то что дают у Рэмки- это вот сериализацию данных любого формата фактически в Причём кстати знаешь что прикольно я чаще всего этим пользуюсь как раз в рельсовой Ормке ты можешь прямо указать сериализатор иди сериализатор то есть как конкретно упаковать и как конкретно распаковать вот вы как такие проблемы решаете ну если что я я же ээ должен адвокатить против ормок если что это не фича эта фича есть в ормках и она хорошая но это не является как бы эксклюзивной эксклюзивной особенностью потому что например ну опять же будет много про Хаски в этом месте а в целом там есть библиотеки вот как раз низкоуровневые например которой мы пользуемся но оно как работает у нас есть вот эта вот возможность задать запрос которое по умолчанию просто запрос и дальше туда передаётся билдер который связывает а параметры которые в хаскеле типов данных с тем как это передастся в Постгрес уже в бинарном протоколе собственно сериализаторы и точно также десериализатор который описывает как данные которые пришли от Постгроса превращаются в то в те структуры данных которые используются в языке ну и соответственно там вот есть возможность указать как и массивы так это мы может сразу передаём в Jon jon be ну и соответственно вся эта магия решается причём если я правильно помню оно ещё даже расширяемо при большом желании можно завести свой тип проверить что да это вот тег того типа который я хочу описать передать реализатор и прямо в бинарный протокол как постгс ожидает это сложить мы правда такое никогда не использовали поэтому я здесь осторожно говорю но в целом главное что ну она специфичная для постгреса библиотека то есть перепрыгнуть на майсколе не получится но зато все возможности использования а массивов джейсонов jon айпишников там их ренджей оно всё из коробки появляется при этом не накладывая какие-нибудь дополнительные ограничения ну или особенности дизайна так скажем
да ну это вот при условии если тебе нужны действительно костомные поля именно внутри посгреса а вот например если ты просто обычное стринговое поле сделал тебе как раз нужен сериализатор десериализатор да на него если ты хочешь там допустим хранить список
то я так понимаю что всё-таки в дефолтном коннекторе к базе у тебя нет такой фичи он просто ждёт как бы плейсхолдер и ты туда должен подставить ну если это строка ты должен подставить строку соответственно фактически сам процесс сериализации тебе нужно ручками делать правильно или у тебя интерфейс там интерфейс вообще чистый то есть если это чисто по то есть когда мы как в библиотеке мы делаем этот place for там доллар доллармер параметра а а дальше мы должны соответственно в этом параметре сложить бинарное представление вот того что а параметра этого самого и если это массив то соответственно оно делается с этим с тегом массива и соответственно дальше идут данные как они бинарно постгресом сериализуются и есть сериализаторы для всех вещей то есть если у нас это список интов там или список джейсонов то мы прямо и говорим что это список джейсонов и его и передаём ну ещё по поверх этой библиотеки естественно мы стали переизобретать ВРМ потому что без этого никуда то есть на
Я к этому вёл да что вы что-то там точно накрутили чтобы это автоматизировать а
на самом деле там чтобы это упростить мы просто по типу значения можем понимать его сериализатор который к нему подходит поэтому человеку ничего не нужно писать не нужно писать сериализатор сам передал в типе у него лежит строка ушла строка список строк оно автоматом становится списком строк без необходимости изменять код и лезть во много разных мест
да ну это ваш как бы уже то есть по сути вы работаете уже с некой обёрткой которую вы там наколбасили как я и говорил я фанат подхода что нехорошо брать уже готового РМ где всё придумали за вас а нужно подобрать можно подобрать то что подходит конкретным проектам
я знаешь что понял я сейчас тебя слушаю я понял что моя философия жизни - это Прохор Шаляпин от программирования не знаешь такого чувака ну он очень известный в плане он певец и у него такая философия там в исте просто очень вирусится всегда на тему того что работа подождёт работать не надо и вот у меня философия что если кто-то другой эту работу сделал и хочет сделать то пусть он этим и занимается а мы будем брать готовое
тут сложность сделать самому или выучить как сделал другой и дальше это использовать оно работает когда проект достаточно простой где нету никаких-то каких-то особенностей и э который попадает вот в такую хорошую колею которая уже проторена естественно переизобретать ничего наверное не стоит но если проект находится в состоянии когда не факт что он находится в этой колее когда или он точно не находится или не очевидно что не появится каких-нибудь требований и особенностей которые его оттуда выбьют то здесь уже можно заранее подумать и возможно решение взять готовое не будет оптимальным
по мне это редкая ситуация в Хаскеле чаще опять же потому что там стандартизированных решений такого уровня крайне мало и нету общей насмотренности по сообществу а что я имею в виду вот если ты например а допустим приходишь в Springбд такой: "Вот я с нуля делаю я ещё не уверен поэтому будем писать сами" ты просто специалистов с рынка не возьмёшь они скажут: "Ребята вы там с ума сошли я не буду с вами работать" например точно также Hexlet изначально мы использовали Bootstrap и до сих пор используем как этот UI фреймворк да потому что если бы мы писали вёрстку сами это была бы катастрофа потому что это всё своё надо помнить разбираться это тысячи строк а то и больше надо тоже придумать утилиты короче ты бы что-то всё равно придумывал а тут приходит человек и ты ему говоришь: "Вот есть дока которую поддерживаем не мы мы делаем всё по доке" да это даёт нам определённые ограничения но нас они устраивают мы с ними согласны поэтому здесь ещё очень важен контекст если у тебя инструмент является дефолтным в индустрии то люди его знают они знают его баги они знают его проблемы воркунды и вообще всю свою жизнь положили на то чтобы работать с этой ормкой вот и поэтому я считаю что эффективность как бы в целом намного менее важна чем знаешь как не то чтобы повторяемость а промышленность давай так вот я слово промышленный буду использовать да вот если какая-то штука является промышленным стандартом и по ней надо стек Overflow там 500.000 вопросов ответов и все штуки ну сам понимаешь да
здесь я спориться абсолютно точно не буду потому что дефолтный выбор он часто полезный вот ещё мы тут мельком коснулись одну тему которую мы не включили в состав но возможно его стоит включать вот то что мы взяли и сменили тип с одного там со строки на список - это миграция соответственно должны ли миграции быть частью ВРМ что ты по этому поводу думаешь и по поводу вот собственно автоматических миграций
я единственное сейчас когда буду отвечать ещё скажу про такую вещь я знаю то что люди которые нас слушают очень ждут когда мы начнём ра обсуждать самые для них такие животрепеще вопросы касаемые производительности генерации объектов предсказуемости запроса и так далее сразу скажу что ребят мы сейчас разберём такие около темы которые попроще где меньше всего там всяких нюансов и потом пойдём уже в вот в эти темы поглубже второй час будем про них общаться да про миграции классно потому что действительно забыли я считаю что миграции должны быть частью Ормки они очень много могут давать гигантское количество разной автоматизации и например меня просто бесконечно бесит и я постоянно с этим страдаю это миграции в той же Джаве которые вообще отдельные и платные даже для определённых фич и ты каждый раз когда их ставишь это не не очевидно не просто там есть конфигурации вообще тебе в принципе надо про это думать и там не всё идеально мягко говоря понятно что если вы такой махровый джави который каждый день с этим сталкиваетесь а мне так иногда говорят типа Кирилл там нет никаких проблем есть а там проблемы есть я просто не хочу сейчас вот прямо перечислять но там много связано с с генерацией начального там состояния там дифы и так далее там есть XMLный формат не XMLный вот а короче все фреймворки ОРМнки стандартные которые есть они как правило миграции в себе содержат но есть нюанс тут очень важно понимать существует два подхода вообще к ормам и они очень разные помимо того что сами бывают разные типа active record или там data mapпер да у тебя есть ещё
кодф и dataф как кстати с API да у тебя есть там дизайнф и кодф
самые банальные примитивные и вполне работающие Ормки они построены по принципу dataф то есть ты сначала должен написать миграцию данных сам всё это определяешь а потом в своей ормке у тебя есть два кстати тоже варианта первое если это статический язык как правило ты там явно должен пойти все эти поля добавить указать но вообще-то есть и другой подход это например в супердинамических языках типа рубей где у тебя вообще магия там может твориться любая ты знаешь как они вообще устроены для некоторых людей это просто шок то есть ты создаёшь модель например какой-нибудь юзер и она физически пустая а при этом у тебя все методы есть и всё работает и оно обновляется в соответствии с базой данных
и люди не задумываются некоторые они как бы воспринятю это как данность и я иногда знаешь спрашиваю я говорю: "А вы знаете как это вообще внутри-то происходит?" Они такие типа вообще ноль идей и ответ там такой что в Хаскиле ну это даже если бы очень хотели вы бы наверное никогда в жизни не сделали да и вообще в большинстве языков во время загрузки класса там есть ну как бы знаешь такое рефлексия встроена прямо в язык очень глубо глубоко у тебя во время загрузки класса прямо лоудинга есть прямо колбк который внутримки имплеменчен что как только грузится какой-то класс модельки ну это типа класс наследуемый от базового класса допустим ну это один из вариантов мы делаем describe запрос в базу достаём всю метаинформацию и на лету генерируем все методы со всеми валидациями вообще со всем то есть даже эта штука чтобы ты понимал берёт ограничения из базы данных может брать ну например там лимит типа строки по количеству символов и тут же повесить такую валидацию минимальную на это поле и у тебя получается что присутствие этой ормки оно нулевое у тебя просто вот пусто всё то есть у тебя просто классы созданы из двух строчек
а при этом всё работает да есть много всяких вопросов к тому что а как дебажить а грепать там и так далее а автокомплиты то есть да в таком случае конечно те же LSP устроены сильно сложнее то есть например в рельсе когда у тебя грузится эта вся фигня там чтобы с этим поработать в тестах или при автокомплитах у тебя ЛСП приложение прямо поднимает внутрь чтобы собрать эту информацию типа какие методы у класса и это сильно сложнее чем статический анализ правильно ведь вот но я имею в виду что такое существует да а есть обратная история когда у тебя код First это например Джанга это у тебя Entityфреймворк это вот этот дри кстати тоже там устроен пример так ты сначала заходишь в модельку делаешь изменения а потом такой говоришь: "Сгенерируеть миграцию" эта штука обладает тоже своими проблемами часто то есть например большинство таких систем не распознаёт переименования но тут я могу порекомендовать опять же этот дризл который меня поражает тем что он реально их понимает и он прямо знаешь ты когда запускаешь сгенерить миграцию он прямо тебе говорит:
"Смотри у тебя тут значит вот это добавилось удалилось а вот это поле переименовалось ты хочешь чтобы мы его как бы ренеймame сделали или ты хочешь чтобы у тебя как бы это два было разных поля и ты как бы можешь выбрать он тебе генерирует миграцию и и Но здесь ты как бы сначала код должен обновлять тоже свои плюсы свои минусы есть обычно минусами как раз называют именно чейндж который может быть не всегда правильно понят этой системой поэтому рукопашка нужна простите что я так долго говорю потому что надо эту систему объяснить мне кажется как это всё работает и есть ещё одна история непосредственно про то как делаются миграции то есть когда особенно data First потому что с код First там автоматизация ну очень высокого уровня да с data First как правило там пишут SQL up SQL down да
но например несколько лет назад по-моему опять же не то что я там хочу рельсы сильно рекламировать но просто я поскольку это вижу одни из первых либо вообще первые внедрили знаешь какую штуку во-первых там когда генерится миграция она использует язык прямо написан на самих рубх такой универсальный как раз чтобы не зависеть от базы данных
что тебя не ограничивает писать esкели и они в какой-то момент знаешь как сделали что типа слушайте раз у нас есть такой язык и мы пишем там up какой-то а почему бы не написать дау автоматически и фактически миграции изменились в такое понятие что больше ты там не два метода up downу пишешь ты пишешь один ровно метод change и у тебя на любую миграцию up если она сгенерирована именно этим языком у тебя автоматически генерируется обратная миграция ну в смысле она даже не генерируется она просто может выполниться потому что он в динамике это определяет ну понимаешь он читает эту дсэльку исполняет видит запрос и генерирует обратный
и вопрос может ли при такая система работать если она не интегрирована с Урмкой ну как будто бы нет скорее всего не может но у меня здесь всегда возникали вопросы и сложности вполне которые вполне возможно имеют решение что обычно ну с обмиграциями назад иногда бывают интересные вещи когда миграция не знаю забывает часть данных или мы решили финально что-нибудь дропнуть то тогда делать миграцию обратно мы конечно можем но немножко неполную то есть если мы дропнули какую-нибудь нотнал колонку без дефолта а то сделать мимиграцию назад у нас шансов мало ну и про миграции назад во всяком случае не для разработки это отдельная история про которую кажется были выпуски и разговоры и там можно всё время говорить но во всяком случае вокруг миграции обычно идёт некоторая история что там мы например сначала мигрируем у нас старый код может работать с новой версией базы у нас то есть что мы можем если что просто откатить версию при этом с базой уже ничего делать не надо ну и база мирно идёт вперёд а код её догоняет и когда у нас не знаю нету эрмки нету интеграции всё понятно то есть мы посидели подумали написали миграцию наверх подумали что да действительно она у нас не приведёт к простоям не вызовем случайно никакую операцию которая залочит базу надолго и при этом возможно мы её делаем даже параллельно мы написали миграцию не знаю дополняющую колонку запустили фоновую Джобу которая проставила все данные потом обновили приложение в общем история очень понятная э с ОРМом эта история становится немножко интереснее ну конечно если cдф то всё понятно мы просто напишем код оно у нас разумно отразится в нашу систему и мы всё увидим но в Дафст вопросов как будто бы больше становится
а мне почему-то наоборот показалось с датафest у тебя же практически такая же история то есть ты просто находишься в том в точно таком же формате мышления то есть я пишу миграцию и я должен очень хорошо понимать вот уже инженерные практики что только вперёд zero down time deployment соответственно я должен всё сделать правильно
а вот код Фёст может тебя обмануть из-за простоты удобства и лёгкости ты такой просто пошёл в модельки что-то поправил он тебе говорит сгенерить миграцию и ты такой не глядя да и у тебя там ренеameйм появился и то есть если ты а это недопустимо и получается что поэтому кстати тоже вот надо иногда поправляться вот когда всё это рассказывал а конечно опытные разработчики скажут: "Кирилл что-то ты херню какую-то говоришь в продакшене всё равно так нельзя" да потому что чаще всего это нужно в девелопменте то есть вы как бы накатили такие поняли: "Ой ложанул откатил" поэтому вот эти вот откаты миграций в продакшене вообще-то не происходят они не нужны для продакна они нужны только для девелопмента да в продакшене только вперёд даже если мы удаляемся да то есть это тоже новая миграция у нас гит подход в этой всей истории поэтому короче мне почему-то кажется кот Фёст вот опаснее в этом смысле потому что он тебя немножко успокаивает и ты такой типа привыкаешь и если на автомате работать мне кажется можно случайно не заметить что ты что-нибудь переименовал потому что с датафст ты так не сделаешь ты сам пишешь ты такой: "О может я не прав
я неправильно использовал кодфёст и датафст когда я говорил я полностью согла" нам свичнул да как раз свичнул да дада
ребят напишите кстати вот те кто просто в моей жизни я всё-таки на практике больше data first подход использовал а и тот же самый Springbot кстати там вот GPA там тоже Dataф то есть очень многие так делают cдф - это более такие скажем продвинутые системы кто ими много пользуется скажите возникают реально ли у вас с этим проблемы или нет и насколько они реально могут вот видеть потому что мы же-то просто в рамках одной модели сейчас это обсуждали а ведь бывают более сложные концепции связи в forке и так далее насколько там всё это работает и насколько это не вызывает у вас проблем то есть типа страдаете ли вы короче от такого подхода или нет потому что я от датафст в целом-то не страдаю ну у вас по сути же то же самое то есть неважно есть у тебя УRМ или нет у тебя это же то же самое
ну у нас чисто датафст аккуратненько пишем следим за тем как мигрироваться будет как это как идут изменения данных и как идут изменения в коде
который это использует кстати нельзя про миграции ещё не сказать про аа то как они ещё должны работать есть такая забавная штука: наличие возможность удаления миграций короче очень многие системы миграции они пошли от от были скопированы с Rails когда они вышли там в 2006 или в 2007 году потому что это была первая как бы allcusive система которая вот содержала все компоненты повлияющи влияющие на всех остальных и не все скопировали правильно я просто вот с PHP в этом много сталкивался там вот есть Laraвеelль который долгое время не делал такой файлик который называется схема а ну типа схема то есть в чём идея я не знаю насколько ты с этим сталкивался или нет то есть грубо говоря когда у тебя есть миграции появляются и же в какой-то момент останотся слишком много и тебе чтобы повторить например тестовое окружение при запуске тестов там например тестовая база или вообще с нуля накатить проект а ну по сути ему надо просто с самого начала до самого конца всё это выполнять а люди могут там легко использовать какие-нибуд модели которые уже типа всё они там удалили из проекта ещё что-нибудь какой-нибудь код специфический и более того если у тебя их становится слишком много ну во-первых долго во-вторых они просто мешают хочется эти файлы удалить и в рельсе с самого начала было сделано нормально у тебя когда выполняется каждый раз миграция у тебя автоматом обновляется файлик который фактически держит текущую схему и в которой указана последняя применённая миграция там её идентификатор и соответственно получается что фактически на накат новой системы с нуля это тесты или это девелопмент это мы а грузим схему б накатываем донакатывая миграции которые были не накачаны при этом всё остальное ты можешь просто легко грохнуть в любой момент вообще ничего не произойдёт и это было довольно забавно когда я наблюдал прямо много лет в Ларавеле как постоянно об этом писали в Ишюсах типа ребят ну хорош давайте добавим и основатель значит постоянно говорил: "Нет это не может быть кор фигнёй" типа сами разбирайтесь
и и люди создавали какие-то костыли ещё что-то чтобы эти миграции удалять то есть просто физически нельзя было из проекта удалять миграции прикинь вот ты 10 лет делаешь проект а миграцию ни одну удалить нельзя и выяснялось что они сами всё это имплементили а потом конечно он под напором сдался и сделал не знаю как в других экосистемах но вот в тех где этого нет это конечно беда
в самый первый фреймворк который у нас был на ПХП свой у нас как раз вот была примерно вот ну у нас была уже правильная история то есть у нас была схема и у нас были вот эти вот набор миграций соответственно если база инициализировалась то она инициализировалась со схемой схема обновлялась естественно это было давно и неправда и тогда и и файл схема обновлялся руками то есть человек писал миграцию должен был обновить схему
да о ну это было очень давно была очень маленькая команда вообще что такая тема была это уже был огромный прогресс в тот момент что это какие-то там ше года го Да да да да да тогда вообще в PHP просто не существовало миграров и я помню что в 2000 если не ошибаюсь в девятом году Quid Base подрубал для того чтобы хоть как-то оно работало и реально работало да
у нас была система на мейк-файлах прекрасно работала вот очень прикольно ну мне кажется миграции в принципе разобрали я не знаю эли за то чтобы они были вместе хотя опять же смотри вот интересно допустим если ты не используешь РМ вот вы не используете УRM да а какой миграции делаете вы используете готовую систему миграции или вы свою написали
у нас на самом деле своя но 10 строк кода примерно собственно вот примерно тот же механизм со схемой и версиями в базе данных контроль что применялось что бы не применялось при выкладке новой версии анализируется что не что в каком порядке не добрано и добирается вот
я должен признаться в одной штуки я вспомнил сейчас только что короче это был 2009 год десятый то есть я ещё не на тот момент я уже программировал 3 года но это такой знаешь такой типичный PHP разработчик который сидит там где-то пилит сайты на кастомных Цмэсках поэтому я с хорошими практиками ещё не то чтобы был сильно знаком
и на тот момент я работал в одном стартапе и знаешь в чём прикол как раз там я внедрил в какой-то момент BASE а до этого целый год знаешь как я делал и это была самая магия которой мне приходилось учить новых разработчиков когда я уходил передавать эти сакральные знания короче я знаешь что делал я брал структуру базы данных которая у меня прямо сейчас в моём компе я брал структуру базы данных которая в продакшене я в эту приблукала див но она показывала див не полный и там как бы там не всё было правильно сделано и у меня день деплоя - это был день когда я сидел с утра и тратил 3-4 часа может не может быть меньше ладно вру может час но смысл в том что это был очень такой процесс где я должен внимательно был посмотреть написать этот файлик и вот этот файлик мы шли исполняли на серваке вот такой вот я был отморозок
прекрасно понимаю так я помню прямо учил что ребята это очень важная процедура тут нельзя как бы ошибаться там знаешь что в чём [ __ ] была я вспоминаю это у нас MyQL был и соответственно у тебя транзакционного ДДля не было и у меня были ситуации когда я ложал
я начинал исполнять эти миграции и я где-то там понимаешь что-то ошибся и они где-то наполовине падали угу
а поскольку я ещё тогда вот это вот типа только вперёд не до конца осознавал это приводило ну не то что каждый раз но были моменты когда я короче потел и мне было очень плохо вот не делайте так но я кстати слышал что некоторые до сих пор так делают ты не поверишь
не удивлюсь а у нас вот без этих фреймворков самая страшная ситуация возникает ну единица раз возникала это когда ну какая-нибудь проблема продакшн и нужно поправить в базе структуру индексы что-нибудь ещё вот вот прямо сейчас потому что пользователи страдают им плохо и в этом случае иногда при ну соответственно происходит что база данных которая в продакшене она рассинхронизована с тем что есть и соответственно если вдруг кто-то что-то забыл и не перенёс потом как это как миграцию ну понятно миграция всеs ifзистся и прочее что если уж руками что-то сделали то сразу перенесли но если вдруг где-то не хватило внимания там времени что-то ещё вполне нормальная ситуация то вот приходится вполне может приходится между системами смотреть диф и разбираться а что же там пошло не так почему здесь работает а здесь не работает ну не знаю не не самая лучшая практика но я не знаю что делать лучше особенно в моменте когда починить нужно прямо сейчас и там каждая минута на счету
а тебе не кажется что это я так понимаю что это вопрос производительности и тебе не кажется что это следствие как раз отсутствия вот того контроля о котором я говорил то есть речь не о том просто смотреть запросики с эксплейном а вот именно общие ответы запросов чистота и так далее вот в тех системах которые автоматом это всё собирают а тут примерно ж понят то есть если проблема возникает то по логам и всему абсолютно понятно где она есть причём возникает оно обычно тоже ну не знаю какое-нибудь событие происходят огромное количество пользователей новых или пользователи начали использовать какой-то новый паттерн там не знаю что-то появилось раньше никогда этого не дела
кнопка понятно какая-нибудь новая
да там не знаю новая кнопка но новые задачи там ещё что-нибудь новое а вот а на предварительном нагрузочном тестировании тоже как-то ну не додумали слушай а
не угадали как пользователи себя вести будут
ну допустим а что миграцию-то всё-таки не сделать вы же наверное не секунда в секунду надо ну сделали в вашем коде миграцию и деплойнулись
не знаю у людей час времени на выполнение того что они должны ну вот вот реально час а а после этого запустили какое-нибудь событие которое у нас происходит там пришли пользователи у них есть час на то чтобы проделать всю свою работу
а не не вдавайсь в то что мы делаем вот соответственно у них что-то не работает понятно что ну вот этот час им можно продлить на какое-то время но такое весьма разумное поэтому иногда бывает что вот прямо сейчас ну учитывая что если как если время компиляции всё прочее быстро в принципе можно сразу накатить а ну накатить через миграции и прогнать нормальный и правильный релиз а вполне возможно сценарий такой что а вот здесь добавить индекс а станет ли оно лучше потому что когда заранее не угадаешь запускать э весь этот процесс может быть весьма дорого php ставил дебак на продакшене
да да
ну нам это не везёт да надо
а сколько у вас занимает скажи пожалуйста вот например вот у тебя надо задеплоить сейчас сколько время займёт ну сборки нет то есть он не собран
если сборки нету то это вызовется build и всё то есть это там десятки секунд максимум ну пока все ходы перезапустятся а там проблема в том что как бы что-то поменяли и нужно перебилживать а если перебилживать то это будет зависеть от того есть ли всё в кшах C если всё в кша есть то соответственно от времени сборки приложения а им Хаски не всегда может похвастаться
будем считать что в нормальной ситуации непрегруженного C я наверное думаю десяток минут полчаса максимум вот в плохих ситуациях может больше но тогда когда нужно делать релизы можно проследить за тем чтобы плохой ситуации не было
м ну ты это имеешь в виду сборка без прогона тестов и всего остального потому что у нас сборка тоже минут 20 может идти но там большую часть времени - это тесты это сборка фронтэнда вот это всё то есть с прогоном базовых тестов без прогона етуе тестов и всего такого
м у нас
больше ты хочешь сказать что большая часть времени компиляция занимает
большая часть времени занимает компиляция пакет удивлён мне кажется в докере уж точно это должно быть меньше из проблем ну вообще интересно конечно мне кажется если бы мы только это оставили а ну во-первых у нас нет компиляции нам уже как бы нам в принципе не надо главный код туда закинул как бы и всё будет работать вот так вот видите динамические языки имеют свои плюсы да прикольно хорошо давай слушай давай тогда переходить дальше в Я бы перешёл знаешь к чему к запросам
да вот это прямо самая запашная вещь да что ой я вот постоянно это слышу
и и у меня всё время в голове вопрос: "С чем вы работаете а что ты пишешь одно а он там тебе выдаёт значит что-то вообще абсолютно другое не так и не туда" ты согласен ну ты как бы да то есть для тебя это существующая проблема наверное нужно вспомнить статью Вьетнампрограммирования где где как раз про вот это вот ОРМ написано такая достаточно известная статья и если поискать это то там на стек Overflow много вопросов про это на на Редите там тоже а всё ещё а всё ещё ОM является вьетнамом программирование и так оно раз в несколько лет повторяется и вот там как раз э там несколько проблем подсвечено одно - это вот сложность отображения а объектной модели в модель СQэля второе - это как раз вот эти вот запросы но здесь наверное можно разбить на несколько частей для того чтобы лучше проговорить про что мы говорим потому что здесь неудачно для нас мы начали с quyдеров а поэтому мы сразу можем сказать что проблемы нету и здесь как раз разговор больше проекте
но на уровнебилдера нет правильно е давай сразу определимся query builder если он у вас типа генерит не то что вы его просите это вообще очень странный quryбиilder я бы его классифицировал как какой-то другой э инструмент потому чтодер - это всё-таки то что вот вы хотите то он вам и делает
ровно так
да
а а вот это вот actтив рекорды автоматическое подтягивание соответственно там выделяют несколько проблем а про которые можно поговорить которые сразу в голову возникают человек который не знаю не работает каждый день сма пользуетсядером
прости я понял надо про перед тем как про это говорить прони to manyни связь сказать потому что кое-что от неё зависит а
угу эээ я не хочу чтобы мы разбивались с темы но просто это тоже будет сейчас часть вот ты когда сказал сложность отображения а я я подумал сразу вот о чём часто люди как бы знаешь как себя воспринимают вот есть сущность сущности manyни to manyни и они воспринимают это что промежуточная табличка она вот не отображается на мою значит объекты и надо вообще её скрывать и у тебя в каждую РМ всегда есть альтернативные варианты типа промежуточная табличка как существующая реальный объект и второе - это прямая связь вот опыт рельсовый очень прикольно показывает потому что у них прямо этот знаешь такой как бы эволюция фреймворка что вот эта штука от неё просто отказались в какой-то момент по по сути когда она типа прячется потому что штука посередине всегда сущность либо может в неё превратиться я классический пример приведу вот который вот у нас просто без остановки у тебя есть любая сущность и есть usер курсю usеer
угу
у тебя есть мер это ни фига не промежуточная табличка у тебя есть э статус завершённости у тебя есть дата начала и так далее это самостоятельная полностью сущность и поэтому например я живу в парадигме независимо от наличие РМа что у тебя не бывает связующих табличек у тебя всё является сущностью вот мне кажется важное замечание потому что оно вот базовую штуку очень сильно определяет вот у тебя такое же восприятие или нет у меня у меня нету ОРМ но у меня такое же восприятие и такой же опыт что в большинстве случаев когда нам нужны связи эти связующие таблички ID один ID другой всегда будут содержать дополнительную мета минимум метаинформацию
да да даже сейчас её нет она потом появится ну ладно я могу один пример привести где этого никогда не происходит это теги ну вот эта связь как бы тегов да да тоже можно докинуть что-нибудь вроде когда был создан кем был создан если это не в отдельных табличках
аудирование аудирование можно да сделать
да про это тоже кстати можно поговорить и и из Deleted которое виртуальное удаление которое тоже интересная тема для ОM если нужно но к этому потом вернёмся если хватит время давай давай
вот собственно проблемы одна из проблем - это проблема такого начинающего программиста её называют 1 + N это когда мы делаем какую-нибудь достаём сущность а потом в форе достаём ещё все её связи и соответственно что генерирует радостное N +1 запрос и медленно работает а и это называют одной из проблем а часто и я видел когда люди пишут э запросы которые именно так и выглядят естественно когда весь код ээ когда пишешь код который напоминает обычный код на языке программирования э том которым ты пишешь использовать for э и прочие контрольные механизмы - это прямо то что хочется делать и легко забыть о том что в базе данных это не то что хочется в базе данных это первая проблема вторая проблема - это различные способы лейзилога а что тоже называют проблемой ну то есть у нас есть сущность а мы идём делаем запрос он уходит в орэмку он уходит в базу данных база данных радостно возвращает во-первых возвращает всю сущность что тоже проблема а не проблема для сильно динамических языков типа рельсов типа рубе но для тех языков где статические структуры и где нету открытых классов и какой-то вот возможности собрать объект прямо на ходу а это легко может быть проблемой потому что широкие таблицы - это частая история там
да
ну юнионы немножко могут как бы помогать в принципе но ты прав это и попытка как бы под каждую ситуацию генерить новые типы тоже охренеешь на самом деле поэтому всё заканчивается обычно очень тупо и кстати это часто высмеивают в твиттере показывая какой-нибудь тайpeрипт где у тебя все поляла просто без остановки и всё и у тебя никаких гарантий ни в чём да это уже гораздо больше проблема потому что в базе данных-то они должны быть ненулаable и делать связь в базы данных желательно чтобы данные туда некорректные не попадали потому что если необходимая структура не будет поддерживаться ну
с данными если сломать данные это самое страшное
это кстати вот это вообще проблематика а вот в динамических языках просто проблемы нет ну ну как её нет то есть у тебя при этом ты теряешь статическую самое главное типа безопасность да но проблемы нет ты просто пишешь и пишешь то в статике это реально геморрой потому что именно здесь у тебя проявляется как ты их комбинируешь между собой один ты делаешь разные и ты можешь у тебя блин может быть такое количество этих типов да на то чтобы разные выборки содержать это просто капец честно говоря задолбывает когда ты думаешь такой писать в очередной тип или не писать очередной тип
угу
ещё 150 похожих на каждую модель да
да и чтобы закончить вот после про ленивую загрузку соответственно понятно если у нас есть внешние связи то и нам они не нужны то дальше уже у фреймворка ормки есть различные способы решения одно из них - это ленивая загрузка нам данные не нужны мы сохраняем информацию о том что вот они будут а потом когда мы если мы её дёрнем то они подгрузятся и это приводит как раз вот к тому что если так используется то это легко может привести к неожиданным запросам в неожиданном месте мы как бы подгрузили данные а потом они у нас в случайные моменты будут догружаться соответственно это случайный запрос увеличивается их количество и вот это выглядит как проблема если это случается
готов поспорить готов поспорить это мне напоминает подход вообще такой философский подход Хаскеля и всех остальных большинства остальных языков когда люди которые пишут на Хаскеле помнишь такая статья была как чувак сказал что он типа сдался и перешёл на Кложу и счастлив что типа в Хаскеле ты сначала должен доказать долгом свою модель впроектировать и после этого она заработает сразу и вся а в остальных языках ты как бы можешь накидать любую херню которая работает плохо а потом её как бы там подпорками доводить до нормального состояния глобально у меня например отношение к проблеме N +1 что это ну то есть первично чтобы я как программист мог херачить а эта штука она решается несколькими путями во-первых ну если ты достаточно опытный программист ты это всегда видишь и понимаешь что скорее всего будет во-вторых я работаю всегда в системах в которых есть автоматизированные инструменты которые сразу тебе показывают что есть N +1 я тебе более того скажу у меня вот в рельсе есть такой инструмент гем булет называется у него прямо есть шесть опций: показывать арт слать в консой слать просто в лог то есть он и в браузере работает и тут а падать при короче выводить в тестах и третье вообще эксепшены бросать и не работать если такая фигня происходит вот просто представь что даже в этом случае то есть я мог бы это сделать у нас всё покрыто тестами и то я этого не включаю потому что я знаю что у меня на продакшене есть се на плю1,1 и я ничего не собираюсь с этим делать потому что есть места в которых я понимаю что я этот код завтра перепишу я его запустил только для того чтобы просто сделать какую-то очень а историю такую знаешь эксперимент а-тест мне просто по-быстрому надо было вывести чтобы проверить реакцию людей и более того это касается не только меня потому что могут меня обвинить сказать: "Кирилл ну ты типа сам там дисциплинированный типа разберёшься" нет это хорошо работает и в других местах более того например если бы я понимал что я Facebook какой-нибудь делаю
Угу
ну ладно там конечно другие бы технологии были но но допустим то я бы конечно включил этот механизм типа бросаем эксепшены и никого туда не пускаем здесь есть ещё один интересный нюанс всё-таки эта тема чуть глубже и она не такая однозначная смотри есть фреймворки в которых сейчас три кейса разберу первый кейс когда у тебя есть серверная шаблонизация вот серверная шаблонизация действительно самая опасная вещь почему кстати в современном мире не все это понимают кто знаешь вот как бы передавал данные с контроллеров вовьюху ты вовь Вьюху реально передаёшь объект а там у тебя всякие хелперы ты это можешь там в разных местах и у тебя реально получается оно очень сильно размазывается и ты у тебя неявно ну например ты ещё в объект засунул какой-то метод который там какую-нибудь проверку делает там в кошмар это может превращаться который требует переработки довольно большой структуры кода там не недостаточно джоийн какой-нибудь сделать да то есть очень серьёзная переработка
и это действительно самая такая экстремальная ситуация когда это мешает больше всего но например когда ты работаешь чисто по опишке и отдаёшь данные эта же проблема становится гораздо менее проблемная потому что у тебя компактность высокая то есть у тебя есть ровно один сериализатор в конкретном месте который дёрнул всё что надо и поэтому тебе поправить это в 1.000 раз проще и тебе никуда больше смотреть не надо ты чётко знаешь что вот в этой опишке посты сериализуются вот в этой штуке и она вот только здесь это делает как бы решается вообще легко и третий кейс если кто-то работал с урмкой в эликсире например она называется ты Экта
угу
у тебя вообще нет объекта из которого ты можешь эту связь выдернуть каждый раз когда тебе надо достать такие данные ты должен сам явно прописать там через этот пайп что хочу вытащить такую связь и получается грубо говоря у тебя вообще не существует лейзи у тебя либо ты дёргаешь либо не дёргаешь и получается что у тебя ОРМ связи все дела но контроль полностью на твоей стороне и это тоже прекрасный кстати пример который говорит о том что эти два мира можно соединить и работать очень хорошо мне нравилось
если что я как бы перечислил для аудитории основные проблемы которые есть ээ я не готов под ними подписываться потому что по идее все эти проблемы имеют очень понятное решение и последовательное то есть на на самом деле даже та же самая N + 1 проблема она решается очень понятным чисто механическим преобразованием будь то УРМ будь то без ВРМ то есть нам нужно переходить от методов работающих ну напрямую работа как работающим со множествами и всё а база данных счастлива программист ну пострадает там первые несколько часов пока попривыкнет а потом тоже счастлив будет потому что ну так даже думать об этом удобнее с ленивостью но я не знаю я подозреваю что это решается нормально только ну вот как раз нормальным разбиением на слой работы с базой данных главное здесь то есть самое опасное что я вижу если мы живём в каком-нибудь контроллере и делаем неожиданное Иоредине ну то есть мы сделали запрос получили данные не знаю отправили данные на соседний сервер а потом случайно ещё что-то для отладки догрузили что лениво догрузилось и в итоге у нас получится что у нас транзакция не закончилась ну если мы явно её если она явно не ограничена и мы сами с того не понимая просто за счёт того что от программиста спрятано вот много слоёв не заметили что сделали что-то неожиданное что можем радостно заблочить базу данных транзакцию пока наш сервер а оживёт и вот сокрытие вот этих вот деталей которые очень необязательный но частый атрибут орго писать для того чтобы было проще между базами свечиться оно может приводить к такому естественно опять же это опыт программиста и набор хороших практик не делай так а оно этим оно лечится монитори да
и ревью хотя бы или одно падение сер сервиса потом все запомнят ну да те всем ошибок
поэтому мне не кажется это прямо большой
угу прилетает просто там лок тайм-аут какой-нибудь да и ты такой: "О что-то мы здесь тупанули" да
ну хуже если там не знаю к базе данных заняты все коннекты начинают быть потому что не знаю что-нибудь там у нас плохо отвечает
ну справедливости ради ты абсолютно прав то есть когда много абстракций это действительно приводит к таким вещам мне кажется тут вот баланс тоже и что у тебя за проект насколько это критично потому что обычно ну я например се не работаю с высоконагруженными проектами да я прекрасно понимаю что я могу себе такие вещи позволить и даже где я понимаю просто не париться и по мере необходимости вычленять но при этом естественно если бы это было какой-то не знаю сервис который там суперкритично должен это делать не факт что я от Рэмке отказался просто речь была бы про то что уровень внимательности и там каких-то правил было бы может быть больше потому что есть ещё и другие причины по которым мы это всё используем и какие за нас решают ну кстати могу пример ещё интересный привести буквально вот на днях фиксил как раз у нас смотрю у меня значит прилетает эпtion при регистрации ну это типовая история просто мы это не фиксили а это вообще кстати openсоourсный проект на котором сейчас работаю значит прилетает exception что значит в базе стоит уникальность на email для пользователя и естественно а эта уникальность ещё проставлена в Рэмке но ОРМКА не может гарантировать что запрос не уйдёт потому что у тебя просто это на уровне со ну софта а в параллель могут пойти запросы потому что там типа сект в это время второй запрос селект и они оба короче проскакивают да и один из них но один из них всё-таки упирается в индекс в базе и у тебя бросается эксепionн это часто бывает при двойном быстром клике да если у тебя там
ну короче это не избежать совсем невозможно это всегда будет происходить если опять же читать доку нормально любую по базам они там говорят insert for update и так далее там куча всяких разных вот этих есть подходов а да которые такие с блокировками да локальными которые я не помню просто название этих штук но в общем которые позволяют тебе это делать так чтобы эксепшена не было
но а я считаю что в данном случае то есть во-первых у Ремы часто предоставляют очень классные механизмы для этого find or update find or create и так далее и они очень часто именно так хитро устроены внутри то есть это не просто последовательный селект а потом и сорт это именно вот вот такие комбо причём многие программисты даже наверное про существование таких опций-то не знают да что вообще так можно делать и вот проблема что если ты работаешь с СQлем напрямую я считаю что он вообще никак не поможет человеку ну догадываться что в данных ситуациях надо так себя ну так делать потому что это всё равно вопрос квалификации то есть если ты понимаешь что в данном случае у тебя есть уникальность в базе ты не имеешь права делать селект а потом инсерт
угу
ну в смысле ты можешь и скажешь: "Да и хер с ним как бы кто-то там тупанёт все остальные будет нормально" но с точки зрения вот именно правильности паттерн должен быть другой и я не верю что те кто пишет SQL делают правильный паттерн я пытаюсь при отобразить это на свой опыт а потому что у нас одна из причин почему используется у нас SQL прямой потому что для того чтобы все эти паттерны можно было применять причём по месту хотим мы там сделать не знаю insert on conflict хотим мы делать select for update причём указывая то как какая какой именно уровень доступа у нас нужен а что хотим мы там окей или просто соответственно и мы и также мы очень внимательно смотрим на уровень изоляции то есть мы там не грубо говоря везде сериалайбл воткнули и радостно верим что у нас всё будет хорошо и быстро работать и хорошо будет быстро уже вряд ли
быстро вряд ли да
а мы здесь уже следим именно за теми уровнями изоляции которые мы действительно хотим и соответственно думаем об этом и вот я сейчас пытаюсь вспомнить что такое ощущение что действительно практически все разработчики которые приходили когда первый раз с этим сталкивались это действительно была проблема которую вылавливали или на ревью ну или они видели просто в коде что рядом так написано приходили с вопросом: "А почему и что куда смотреть изучали и дальше использовали"
согласись довольно сакральные знания да то есть вот так вот по дефолту разработчики таких штук почти не знают что вот так надо хитро делать это требует
практика собеседования показывает что действительно не знают и я бы не ожидал от каждого нового человека что он по умолчанию это сделает я более того я не ожидаю от Урмки что она по умолчанию сделает вот как мне нужно в данный момент
не сдела Нет ну она делает ровно то что ты говоришь да если ты файн делаешь очевидно будет селект просто такое ощущение что как будто возможно ты просто не сталкивался с ормами в которых это встроено вот как я показываю пример сейчас но это не значит что там всё реализовано я с ходу сейчас не скажу но очень многие вещи реализованы но тут конечно без доки нельзя то есть если ты не читал Доку ты конечно не догадаешься что он так делает я поверю что там есть стандартные случаи ну основные случаи там какой-нибудь что select for update с каким-нибудь уровнем изоляции логичным вот вполне возможно даже какой-нибудь дополнительной опции это всё наконфигурировать можно но уровень сложности уровень знания опций будет ну плюс-минус сравним с тем что э пойти читать про уровни изоляции в доку базы данных
что возможно всё равно даже при использовании УRМки может быть полезно а какие-нибудь всякие хитрые выборки там боль быстрые подсчёты общего количества там или селекты итеративные которые делаются через пару связанных запросов это я вообще не представляю как ормки могут выглядеть ну это те вещи которые каждый раз когда делаешь нужно заново идти в доку смотреть потому что я как бы меня спросят я из головы не воспроизведу я знаю куда нужно идти читать ну ты помнишь да что это скорее уровень уже больше крибилдера то есть это даже нем это вопрос качества крутости крибилдера и тут всё-таки иишки так сказать внесли плюсик в сторону особенно типизированных классных вот этих билдеров потому что я когда вот работаю последнее время и скидываю просто на любой сложный запрос как мне кажется
это всё в чат GPT
он мне просто отдаёт я вставляю оно работает и при этом это не в смысле выглядит как знаешь там пятиэтажная [ __ ] нет компактная тука тут правда стоит знаешь есть ещбавный элемент вом этом я за разумную денормализацию и знаешь какую иммутабельность в структуре базах насколько это возможно то есть не чейнджи а добавлениями то есть например я тебе пример приведу вот у нас есть например программа курс урок там практика и так далее вот например переноса урока из одного курса в другой не существует физически существует новый курс ой новый урок в даже если он такой же ну сам понимаешь каким плюсом минусом это можешь приводить но да
во-первых это никак не влияет на производственный процесс с точки зрения людей но знаешь как это сильно влияет поскольку выборок огромное количество вокруг уроков просто гигантское количество они очень часто сложные
но у меня в уроке благодаря тому что он всегда привязан только к одному курсу в рамках одной тре этой структуры денормализованы просто все айдишники ну вот просто все их семь или восемь штук там дополнительных и я могу делать всё что угодно поэтому у меня концепция очень простая что если я вижу сложный запрос не аналитический аналитическая - это вообще отдельная история я сначала пытаюсь понять с точки зрения денормализации а ну мы вообще всё правильно сделали по той по той концепции в которой мы программируем и часто оказывается что мы неправильно сделали и поэтому общий объём запросов на хекслите например вот такого уровня ну не знаю процента три может быть два угу
вот где вот надо вот прямо было воткнуть что-то и то потому что может поленились иногда знаешь такие: "А хер с ним"
ну у нас очень похожая история у нас тоженорма как на самом деле у нас данные есть которые типа аля админка управления и такое там они э нормализованы по разным причинам и есть то что видят пользователи смотрят взаимодействуют с этим ну и собственно гдес основные данные вот они точно также разумно денормализованы соответственно там точно так же копируются по возможности э они по возможности иммутабельные ну кроме таких не знаю где какие-нибудь счётчики идут которые ну
которые нужно пересчитывать каждый раз как если делать не изменяемо и если они выводятся пользователю ну и нужен нужен быстрый доступ то там вот это вот изменяемо причём их можно всегда перестроить по другим структурам данных на тот случай если вдруг системы обнаружили что что-то пошло не так из-за денормализации то тогда у на то у нас алерт и возможность их пересчитать есть и точно также у нас полностью запрещено удаление ну то есть мы стараемся что у нас есть флаг логического удаления кстати вот это вот мне тоже всегда интересно как сэрмками это решается потому что ну в нашем случае на уровне данных структурах языка которые мы используем этого не видно то есть этот флаг существует именно только на уровне базы данных и на уровне слоёв запросов которые взаимодействуют с базой данных а весь пользовательской код там какого-нибудь поля из Delit или что-нибудь такого его нигде нет а насколько я понимаю что если пользоваться РМкой то скорее всего всё-таки оно будет прорастать минимум до транспортного уровня не ну понятно что ну это понимаешь вот то что у тебя там находится под капотом методов которые представляет себе УРМКА или к ней какие-то расширения это же вообще без разницы неважно это там где-то совсем глубоко или нет потому что ты уже на этот уровень всё равно не ходишь ну только для какого-то супердебага а реализовано очень по-разному бывает где-то встроено во фреймворк и там надо просто какой-нибудь подключить не знаю там exнtion встроенный прямо опять скать и активировать у тебя delete начинает работать по-другому но я кстати вот тут не могу не сказать ещё одну интересную вещь у меня был доклад такой ментальное программирование ты ты наверное не смотрел его да он когда-то очень классно прямо пошёл по ми знаешь так по конфам что меня приглашали я с ним выступал как знаешь на гастролях на разных конференциях и там одну интересную вещь я сказал по поводу там очень много концепций которые такие очень фундаментальные я считаю и очень важные для всех разработчиков одна из них - это нельзя менять дефолты то есть например в Омах в большинстве Delete - это удаление и очень часто в Ормках прямо встроено такой механизм ты говоришь: "Включить софт delete" и у тебя с этой секунды Delete
начинает проставлять флаг но делает это только для этой модельки ну и дальше ты понимаешь да к чему это приводит ты ты всегда боишься потому что ты не знаешь к чему это приведёт а если ты новый человек ты просто не знаешь к чему это приведёт и ты можешь наткнуться угу

del илистрой там зависимости от того что ты используешь должен быть отдельная штука которая это делает поэтому мы как правило подключаем конечный автомат прямо который просто отдельно он там описывается прямо в модельки Delete не delлит и у него он генерирует обычно ещё свои методы и соответственно ты этим пользуешься
обычно мы прямо явно пишем аркав и он архивирует его то есть мы вообще слово delete не используем просто это ментальную ещё ловушку создаёт ну неправильная язык из-за которого потом ломается когда ты общаешься с людьми которые с тобой не в теме и тебе надо уточнять вы про какой делит я уж не говорю про то что вот вообще про удаление глобально по закону удалять нельзя часто данные потому что ты помнишь да как минимум полгода обязан их там хранить все дела поэтому конечно да удаления в общем-то тоже по большому счёту нет есть деперсонализация я бы так это назвал то есть мы просто чистим всё про пользователя и остаются просто сырые данные видишь как слушай кстати когда мы с тобой собирались про всё это говорить я тебе честно скажу я забыл про все эти нюансы в том плане что мы об этом поговорим реально тема вообще-то очень глубокая и большая мне кажется а ребята которые только особенно свои первые шаги в разработке вот там первый год-два делают мне кажется они очень много интересного должны были услышать в том что мы рассказываем потому что эти вещи они как бы годами да накапливаются
да оно оно как-то накапливается становится частью Ну как-то это очевидно вроде бы само собой разумеющееся хотя по факту таким не является
и у меня в этом плане смешной вопрос для тебя у меня просто с РМами ещё знаешь какая связь помимо того что я их много использовал я же писал свою РМ и для того чтобы их писать я очень глубоко изучал существующий поэтому например я очень неплохо знаю как Kberрнеate внутри устроен прямо а как устроен догм не ой господи короче доктрина в PHP прямо всей кишки
сейчас мы вот с тобой тоже вернёмся но я тебе хотел задать один вопрос и заодно нашим зрителям допустим у вас есть моделька и в ней есть конструктор и в этом конструкторе вы то есть давайте предположим что на вход человек получает дату рождения и этот конструктор эту дату рождения всё время увеличивает на один год вперёд просто каждый раз когда ты её туда передаёшь угу
ну и ну как бы во внутреннее поле перед сохранением просто тупо прибавляет год
угу
сейчас я тебе значит вопрос с подвохом когда ты создал объект сам очевидно ты вызвал конструктор передал туда дату рождения он увеличил после этого ты сохраняешь в базу данных после этого ты делаешь выборку из базы данных вопрос: какой год рождения там будет
подозреваю что в большинстве случаев будет тот который в базе данных лежит без увеличения да это абсолютно правильно только так правильно проектировать а вопрос как это достигается
сборка объекта без вы без вызова конструктора через
Да у тебя это это одна из наиважнейших концепций всех УРМ про которую тоже не все знают потому что это для строителей УРМ у тебя ОРМ обязана создавать впечатление то есть это прямо её смысл что у тебя не существует никакой базы данных то есть у тебя объект как бы вот в об ты его в память загрузил и он таким остаётся всегда при любом раскладе именно поэтому внутри УРМ существует много очень интересных ну механик которые для людей иногда не очевидны ну во-первых при конструировании объектов когда выборку делаешь у тебя никакие сетры конструкторы никогда не вызыка не вызывают там полностью всё на рефлексии построено угу

рефлексии нету ты не можешь нормально это реализовать соответственно у тебя проблемы
а второе интересное ты замечал что все урмки делают одну и ту же интересную вещь после сохранения данных в базу инсерта они всегда селект
угу всегда ты знаешь почему
потому что в базе данных могут быть триггеры и всякая радость а которая изменяет данные
да да да и им надо это соответственно сделать и поэтому опять же если человек с нуля это смотрит он такой начинает думать: "А как это выключить?" Так что ну мало ли что-то пошло не так да вот такие вот интересные вещи есть про Ормки хорошо мы с тобой готовы поговорить про недетерминированность запроса значит люди жалуются я бы сказал так наверное это один из самых больших вот таких претензий кремкам что мол ты ни хрена не знаешь что он там вообще сделает я думаю что люди которые так говорят имеют в виду очень конкретные урмки которые так себе позволяют сейчас я расскажу прикол один это как раз ленивый неленивый язык знаешь это шеф и папет помнишь системы
да помню такие
у тебя шеф последовательный или а папе он такой типа вычисляет зависимости или тераформ тоже самый они вычисляют зависимости и порядок выполнения он строится на основе вот зависимости которые там поставили ты можешь их сам описывать в docker compе да и но при этом типа кажется что логически это вообще-то разумно да что он делает вот как надо на практике это всегда оказывается жопой потому что ты не ожидаешь оно может облажаться и ты никогда не понимаешь что происходит и есть ОРМ которые по такому принципу работали а может быть работают сейчас
и у людей из-за этого возникло как бы ощущение что это все урм так работают и поэтому каждый раз когда я слышу эту претензию я такой не очень понимаю о чём ребята говорят ну в смысле я логически понимаю я знаю тебя Урм там вот Hberрней подобное делают
но всем с которыми я работал они так не делают они делают ровно то что ты как бы им сказал если ты взял сущность ты её говоришь сейф она сохраняется
почему м там так работает объясню там есть ещё одна особенность active Record он тупой как дрова да у тебя есть сущность сейф как бы пошёл а но значит ребята из Джавы простите что я вас сейчас упоминаю потому что это к ним больше относится и к тому что вокруг этого они скажут так но это значит нарушает сил responsibility поэтому тебе нужен датамапер у тебя вообще за сохранение отмечает entтименеджер он соответственно грубо говоря когда ты меняешь объекты там есть такой механизм check он внутри как бы проверяет типа что у тебя изменилось и не изменилось
и в датамаперах он не внутри модельки находится он находится снаружи их аж там три или четыре и они все очень тяжёлые то есть это кстати одна из претензий к ормам потому что когда ты говоришь ты же не говоришь сохранить эту модельку ты говоришь просто флаш
а у него внутри есть некий индекс в котором он хранит всё что там типа этоти маapпы там unit of work такие понятия если ты читал фаулера знаешь эти паттерны все как это там устроено работает короче смысл в том что он начинает чекать включая все зависимости что происходит и это может приводить к очень к очень тяжёлым циклическим вот этим вот конструкциям чтобы всё это выяснить и потом в конце концов это очень умная система такая: "Так а теперь я сейчас классно фигану этот запросик так чтобы было максимально эффективно" и человек смотрит влог и у него глаза на лоб лезут потому что он не понимает что происходит вот и я считаю что вот эта проблема она вот конкретной Урмки то есть она не является проблемой блин ормов это проблема конкретной Урмки которая решила так сделать потому что в тех местах где у вас всё тупое как дрова а запросы будут тупые как дрова и понятные
здесь я в целом согласен э наверное из того что чуть-чуть добавить вот ну примерно понятно откуда это всё берётся собственно берётся оно как из принципов в принципе программирования что как бы как бы хорошо правильного программирования также из попыток сделать эффективнее то есть у нас есть некоторая промежуточная сессия с которой мы работаем где мы отмечаем что мы загрузили что мы изменили и после этого мы хотим максимально эффективные запросы сделать которые уже возможно не повторяют те действия которые как мы добились до этого состояния а уже просто флашат итоговое состояние и вот это вот очень страшный кусок ОРМа который не обязан существовать который может заменяться на другие а которого может в принципе не быть и который действительно ну он непредсказуемый что там будет мы заранее сказать скорее всего не можем вот и понятно какую проблему он решает но при этом кажется что её решить хорошо нельзя моя практика во всяком случае показывает что даже если это не касается свой РМКИ а касается в целом найти вот этот вот список изменений если система и структура данных не оптимизированого под это а под такой поиск и добавление обновлений а то тогда ничего хорошего не будет ну или это будет весьма очень сложной архитектурной задачей для большинства проектов решение этой задачи будет сравнимо со сложностью всего остального проекта который пишут с помощью этой технологии
декларативности добиться полной - это сложная задача но самое смешное что есть места в которых это сработало я тоже знаешь в какой-то момент пришёл к выводу вот на основе шефа на основе вот всех ой на основе папита на основе вот таких умок и других похожих систем что ну вообще сложно ну почти невероятно добиться эффективной вот такой системы чтобы она ещё всем понятно была и классная почти нигде а потом знаешь что выходит потом выходит Тероформ и у них это получается он же он он же классен этим у тебя порядок определения твоих ресурсов вообще может быть рандомный это удобно и вот на моей памяти это один из немногих инструментов где это очень в тему и очень хорошо работает и наверное это потому что всё-таки в отличие скле у тебя просто тупые API вызовы которые не джойнтся никак и у тебя нельзя комбинации получить более сложную систему
там да мне кажется что так плюс сами ресурсы которые существуют они гораздо более простые ну конечно
ну некоторые там наворачивают я тебе хочу сказать когда ты же наверное видел тоже что там можно творить с этими зависимостями в целом и всё равно иногда приходится указывать но по-моему оно нет такого что кто-то бы сказал: "Ой блин кошмар я тут разобраться не могу и вообще кошмар в каком порядке происходит" да а хотя на самом деле возможно после этого блока кто-то напишет что не ребят вы неправильно поняли речь идёт именно как раз про выборки когда ты там user тоfriends и он тебе там сходит за выборкой но здесь я тем более не понимаю в чём проблема потому что ну ты явно как бы знаешь что ты связь тянешь и у тебя связь эта выполнится ну здесь единственная может быть неожиданность что вот я не тянул не тянул а потом какой-нибудь другой Вася все Вася извините пожалуйста я это не личное написал имя первого друга посмотреть и у нас неожиданно начало до этого мы не знаю там айдишники только друзей смотрели и отдавали их в опишку и у нас ничего не джойнилось мы просто получили список а тут кто-то сделал минимальное изменение а для отладки например там вы email первого отдать и у нас неожиданно пошёл большой джоийн а мы этого не ожидали количество изменения которые сделали оно будет ну совершенно не соотноситься с изменением сложности запросов потому что они где-то в другом месте при этом выглядеть оно может быть совершенно безобидно потому что например у нас было написано friends.id который не приводит к запросу потому что данные у нас уже есть а заменили Friends ID на Friends user потому что так читать удобнее в логах будет и у нас изменился сильно запрос
это абсолютная правда это действительно иногда даже знаешь как бывает вот ты user.com допустим да связь с компанией и тебе нужен только айдишник и ты прямо понимаешь что если у тебя й не реализован нормальный который там хитрый опять же это оче из-за этого РМКИ чтобы вы понимали мегасложные создания чтобы вот это всё работало это правда это нельзя легко сделать и поэтому ты прямо такой: "Нет надо писать user подчёркивание ID
потому что иначе у тебя может этот запрос прыгнуть" и да вот это добавляет конечно такой косвенной сложности здесь же ещё есть одна интересная вещь а если плавно дальше идти знаешь вот где я бы сам накинул на Урмки
угу
давай так а тут два вопроса первый наверное просто про генерацию объектов и дальше вот про вообще объекты и синхронизацию состояния вот я тут прямо проблема большая да значит ещё одна претензия крмкам - это я делаю выборку и у меня там много объектов ну типа вот эта конвертация это и правда конвертация объекты тудаобратно со всякими сериалайзерами- это вообще-то [ __ ] но блин я А сколько вы данных-то достаёте то есть я понимаю что если мне надо сгенерировать сивеску какую-нибудь или там ещё отчёт на 5 Гб ну ладно не 5 100 Мб мне надо сгенерировать там очевидно надо ну прямо сказать там есть такие понятие по-моему дегидрация что ли он как называется когда ты говоришь вообще не оборачиваю в объект верни мне просто набор данных есть такой механизм в продвинутых умках и поэтому получается ты просто это убираешь но это бывает крайне редко потому что у тебя этих объектов ну сколько ты на страничке 100 штук вывел элементов
ну да
ну вряд ли сильно больше да даже если это подгружаемый Аякс короче вот мне кажется что эта проблема немножко либо специфична для какого-то фреймворка либо надумана во многих местах потому что там где у тебя выборка идёт не знаю десятков тысяч объектов но это явно не интерфейсы и не мобильные приложения главное чтобы люди документы не складывали в базу данных что в принципе тоже можно и может хотеться ну то есть чтобы у нас какой-нибудь байта не возникло и файлик на 2 ГБ вполне себе
ну то есть база база данных это делать умеют и в принципе в этом может быть смысл то есть если нужно чтобы изменение файла и данных было гарантировано в одной транзакции то базы данных это предоставляют это умеют мы так не делаем но это вполне себе возможная штука понятно что в большинстве разумных систем а будет отдельно складываться на S3 там будет лежать только файлик но можно предположить системой и для этого могут быть бизнес-требования где так делать нельзя и тогда естественно это приведёт к проблеме но в этом случае кажется придётся просто вторую написать второй класс в котором не будут перечислены все поля и всё так что здесь решение тоже понятно ну да то есть как бы с одной стороны конечно можно говорить что это проблема у РМки но с другой стороны нельзя одновременно решить все проблемы она решает базовые если вам надо она позволяет ну о'кей давай не упаковывать в модели но скорее всего ты это делаешь не для того чтобы обновлять то есть то ради чегока з где сильнее всего работает когда ты начинаешь там манипулировать данными а скорее ты просто хочешь их тупо выбрать чтобы там не знаю опять же в файлик положить да и тогда тебе объекты-то и не нужны особо со всеми этими сложными трансляциями про обновление кстати тоже есть интересный момент предположим что у нас есть пользователь какой-нибудь и тут пользователь открыл с двух устройств и на одном устройстве поменял себе имя а на другом себе поменял фамилию и нажал сохранить соответственно дальше возможна вполне себе разумная ситуация которая скорее всего по умолчанию произойдёт если ничего специального не сделать но если что поправь меня когда в рамках одной модельки мы загрузим данные с базы мы посмотрим что изменилось имя мы обновим всё и пошлём обратно а в это время есть другой пользователь ну другой запрос пользователя который тоже выбрал данные из Да данные из базы сохранил всё и отправил и причём порядок в котором они придут он будет немножечко ну то есть мы можем вытащить сначала данные в одной потом сохранить данные в другой потом сохранить данные в первой и в итоге порядок и результат может быть немножко неожиданным наверное с именем и фамилия- это плохой пример потому что здесь как бы последний выиграл но вполне возможно если мы будем говорить не с данными пользователями а с какими-нибудь финансовыми транзакциями или чем-нибудь таким а то мы можем легко оказаться в ситуации когда у нас должен быть не последний выиграл а когда у нас должно быть объединение данных вот насколько это проблема с РМКАми
слушай ну с двух разных устройств объединение мне кажется это довольно ну очень специфично вообще мне кажется это не про ОРМ ум знаешь что тебе предоставляет вот это тоже классно кстати не все про это знают я даже недавно видео на канале нашем делал на эту тему что вот есть редакция и они одновременно там статью правят да ну ты понимаешь ты можешь зайти в статью ты правишь и кто-то заходит в статью и и что делать
и опять же если правильные книжки читать и значит разбираться в вопросе правильно человек сразу ответит он говорит: "О тут у вас два вида блокировок: либо оптимистическая оптимистичная либо пессимистичная" соответственно в зависимости ситуации то или то прикол в том что Рмки поддерживают обычно этот механизм прямо из коробки то есть ты можешь просто говорить какую блокировку ты хочешь использовать в случае оптимистической оптимистичной блокировки тебе надо просто будет поле для версии добавить и он сам всё это будет чекать но это немножко другой вопрос понимаешь да это не транзакции в базе в смысле не деньги перевод это вопрос именно вот такой
угу без Урмки это надо ручками делать и это не сказал бы что надо делать потому что это автоматизируемая штука и очень приятно когда он умеет это сделать сам а вот когда речь про транзакции и вот то что ты объясняешь мне кажется тут уровень вообще ни при чём это полностью рукопашная история которую ты должен понимать как ты упакуешь там в транзакции не знаю даже блин банально порядок операций то есть надо не просто там знаешь циферку уменьшать увеличивать у тебя же обычно изменение денег всегда это новая запись поэтому это разруливается на совершенно другом уровне
здесь мне тяжело сказать потому что и меня это в заранее заготовленном не было а пример на ходу который
да полностью по
если прямо менять поле с деньгами вот прямо циферку это в принципе плохой паттерн независимо ни от чего это как раз вопрос квалификации специалиста да то есть а есть по-моему классная статья я вот её хотел перевести на Хабор положить прямо вот посвящённая этому что никогда не мутируйте данных ведите лог изменений ну понятно что никогда это не совсем правда но это похоже на ивентсорсинг то есть у вас события
и например для многих ситуаций это действительно так и должно быть начинает от банальных лайков нельзя плюсовать увеличивать вы например там уникальность не обеспечите и так далее просто мы даже по-моему в прошлый раз разговаривали вот на подкасте с про ТД что ли там а нет до этого по-моему был подкаст там как раз вот мой гость он рассказывал о том что он по неопытности делал эээнд и как раз цифру с деньгами он сделал в виде числа и соответственно у него как-то один раз там к нему пришли значит заказчик говорит: "А где мои деньги?" А он такой: "А у меня даже как бы в базе нет ничего потому что я просто плюсовал минусовал ему пришлось идти в страйк и там смотреть как бы эту информацию но после этого он переделал но вот это такой классический
косяк новичка поэтому РМ тут ну так очень вторичную роль играет
сейчас я попытаюсь переформулировать наверное проблему а если у нас есть частичное обновление структуры данных а то хочется следить за тем что мы обновили только то что ну обновили только то что мы действительно обновляем ну то есть грубо говоря если я прислал изменения [ __ ] возвращаясь к профилю дурацкий пример но пусть будет если я прислал изменение фамилии то у меня изменилась фамилия неважно что а всё остальное осталось в базе как есть ой слушай ты прям напомнил да я понял твой кейс и ты мне напомнил одну прикольную историю которая есть в Джаве с которой я столкнулся когда Пишку писал там с маперами ой это очень смешно было короче смотри там как раз с апдейтом есть такой довольно забавный прикол когда ты описываешь мапер что вот тебе приходит на вход данные допустим форма где-то есть да и у тебя в этой форме ну как у тебя устроено вообще в форме в этом блин я сейчас немножко короче там действительно происходила такая штука что приходили данные не потому что их нет а потому что они были в форме но они почему-то были нулами сейчас я что-то забыл как видимо их не трогали или что-нибудь такое
их не трогали но почему-то они именно были пустые вот я сейчас не помню но это причём стандартная история то есть это видим блин я не помню короче их не надо менять да а нет вру по-другому их не было но трансформер у тебя таким образом устроен что он эти данные короче добавлял я просто помню что мне приходилось там искать решение оно есть которое позволяет как раз их не указывать но короче с точки зрения ORМ очень важно что если ты хочешь чтобы какие-то данные не менялись ты должен понимать как у тебя работает механизм чек вот этот и как правило он довольно примитивно работает в смысле логики то есть внутри это может быть сложным а в смысле логики он простой ну не надо никогда обновлять то поле которое ты не хочешь трогать и тогда при сейве оно в инсерт просто не попадёт ну я не знаю если ты это имел в виду ну примерно это потому что не во всех но во некоторых эта проблема есть ты герит со всеми полями всегда
да он ну он делает себе селект он сначала когда когда получает структуру он подтягивает себе всё потом генерирует новую и всё сохраняет у ну это претензия наверное к тем кто вот этот механизм реализовывал чека внутреннего что менять что не менять говорю там даже в рамках одного фреймворка часто бывает особенно дата маперов прямо выбор можно такой вариант такой вариант такой вариант
тут сложно тут дёти чек проверить что менять что не менять без оптимистичной блокировки ну бе какого-то уровня блокировок то есть если мы делаем сразу select for update тогда о'кей но тогда вопрос что будет с другой транзакцией которая одновременно хочет сделать она там либо упадёт либо ну либо ждать будет если ждать будет это в принципе увеличит нагрузку но решение как бы достаточно понятное будет а вот если без этого делать то тогда логично встретить неожиданности потому что Дётичек просто не видит что пока сделала другая транзакция в зависимости от уровня изоляции либо никогда и свалится транзакция либо пока-то они закомите но что точно наверное стоит сказать про ОРМ вообще подобные штуки независимо даже на каком уровне вы это используете они конечно не могут шариться между разными запросами то есть у вас юзер здесь юзер там вообще никакой связи между собой не имеют то есть надо вообще в этом плане надо думать просто что у вас есть запрос и есть данные в базе которые мы меняем запросом а то что там промежуточные какой-то абстракция видеорем вообще не с этой позиции вот внешней по отношению к запросу не имеет никакого значения
но здесь есть нюанс
и вот тут вот я считаю что главная сложность и проблема вот мы к этому подошли где я хочу сам сказать про самую жопу со всеми ормами самая [ __ ] со всеми орэмами что вот эти вот особенно вот этот объектный именно в объектных кстати языках именно там где у тебя есть mutable state где у тебя есть связи лейзи когда у тебя коллекция на самом деле это прокси который при вызове там фетчится не фетчится в зависимости от того ты его загрузил полностью не полностью а если туда ты хочешь что-то добавить как это должно отразиться в какой момент сейв потом сейв только этой сущности либо связанных короче всё это ад а который работает только по одной простой причине большинство приложений где используется являются клиент серверными а у этой штуки всегда обычно очень короткий цикл типа поменяли там что-то в базе засейвились и ушли если бы это всё работало в событийной системе где у тебя объекты постоянно живут мы бы все просто померли потому что пользоваться этим было бы невозможно потому что а существуют вот эти попытки как бы знаешь типа Иссери давайте мы внутри внедрим идентиity map и будем контролировать каждый объект что вот он именно в этом
был 100% единственном экземпляре а потом ты делаешь какую-нибудь выборку по там ну без ID например допу ну короче ты можешь сделать такую выборку при которой он не сможет это сопоставить
угу через joint что-нибудь там часть данных и в итоге это всё приводит к месиву у тебя например есть коллекция и ты в неё можешь что-то добавить вот он должен в базу добавлять или нет а если у тебя эта коллекция не была прямо сейчас загружена из памяти он должен её вообще-то загрузить или нет и у тебя в итоге часто бывает так что например ты добавляешь там в юзера какую-то сущность а эта сущность где-то рядом ты у неё типа да берёшь юзер а юзера там нет потому что это другой объект и вот а там есть типа знаешь даже правила такие что если у вас двунаправленные связи то правильно добавлять значит объект вот в эту сущность потому что внутри ты добавляешь его в обратную сторону но опять же даже в этом случае у тебя могут быть ещё какие-то третьи сущности где есть эти коллекции через какие-нибудь прокси связи где их вдруг не окажется и тебе приходится иногда делать такое что ты пишешь user тоfriends и там знаешь такой параметр ну по крайней мере те умки которые я видел так позволяют делать force refфреш что-нибудь в таком духе чтобы он сходил и забрал потому что ты что-то туда сейчас только что добавил самое главное что я хочу по этой штуке сказать она не просто нерешаемая то есть абсолютно все урмки я это утверждаю готов спорить бажны в этом отношении то есть вы всегда можете именно оопшные вы всегда можете завести в состояние когда у вас окажется что здесь объекта не оказалось или здесь что-то не загружено или здесь неправильная вот эта синхронизация стейта
и эта проблема самое главное нерешаемая в принципе в рамках вот именно мутабельного вот этого подхода
угу
вот всё точка а и это является тем самым где попытка максимально объектно работать вот типа я сейчас вот так вот всё приводит всегда к краху поэтому единственное что нас спасает что у нас цикл жизни очень короткий всё просто умерло и мы такие радостные продолжаем работать дальше особенно представь ты делаешь delт а у тебя эта же сущность находится в другой коллекции и что должно произойти она что из той коллекции что ли исчезнет это так не работает
не представляю как это могло бы работать даже на самом деле здесь ещё легко добавить дополнительный уровень что обычно только оно является клиентом и всё а как бы иногда бывает не только так иногда там не знаю в базу данных ещё кто-нибудь пришёл не самый лучший паттерн но с которым надо жить не знаю там нашли ошибку пошли поправили данные кто-нибудь и теперь идти все кэширы фрешить все приложения перезапускать или что-нибудь такое это явно не то что хочется и кажется что если это что это становится совсем не нет в принципе это решаемая проблема есть подходы можно подписаться на события можно знать что в базе меняется рефрешить там индексы сбрасывать стейт но сложность этой системы будет расти просто колоссально
и и так эти Урм они бесконечно сложные говорю вот ты заходишь в любую Турмку заходишь в вышюсы у тебя багов по синхронизации состояния там десятилетиями они там хранятся и никто это не фиксит потому что я понимаю что это ну это нереально это тебе такую сложность надо внутрь заводить у меня ответ очень простой я долго как бы за всю свою карьеру поскольку с этим постоянно сталкивался и думал тоже об этом с инженерной точки зрения типа что можно сделать какие альтернативы реальное понимание пришло только тогда когда я конечно функциональщину копнул потому что я понял что сама проблема она э попытка вот это натянуть а давайте вот объекты вот это вот смотрите у нас всё такое вот само синкается и так далее это просто так не работает у тебя мутабельное состояние всегда приводит вот к таким проблемам и единственный способ этого избежать - это типа посмотреть над это под другим углом мы не создаём систему которая всё вот так вот а мы говорим: "А давайте мы отказываемся от мутабельности и воспринимаем это как данные анормальные" и вам не обязательно для этого Хаски идти возможно Хаскель как раз плохая идея потому что будете страдать а вот если пойти в тот же самый эликсир и попробовать экто на котором я это прочувствовал вы просто понимаете что у вас во-первых сама система в 1.000 раз проще потому что вот этого всего нету нагромождения так и проблемы такой не существует то есть вы чётко понимаете что у вас нету там никакой коллекции из метода да да то есть если вы хотите он выборку из баз сделает если надо там вот та коллекция которую вы создали она та которая есть она не поменяется никаким образом то есть к ней нет отношение что это юзер у которого я сейчас возьму френдов а вот они как там поменялись они значит обновятся то есть у вас просто взгляд на проблему меняется и всё становится сильно проще кроме одного да действительно кода чуть больше это правда то есть вот такие вот штуки они требуют всё-таки чуть больше кода но уровень сложности при этом сразу падает конечно катастрофически вот этот весь геморрой уходит
мне кажется даже спорная ситуация будет ли сильно меньше кода кода будет меньше в простом случае
то есть пока работать по простым крудом который будет недолго а ну потому что как только система начнёт
не у тебя связи всё-таки много чего позволяет у тебя вот знаешь вот это хождение по связям с возможностями там как-то им манипулировать на самом деле вот как раз чем сложнее становится тем больше себе позволяют тут именно говорю проблема начинает проявляться не в том когда ты выборки делаешь выборки можно потерпеть а вот именно ты начинаешь там обновлять много в разных местах и ожидаешь синхронизации вот это конечно хрень полная так ни у кого не сработает но есть люди которые пытаются это пофиксить и строят всё более и более сложную РМ я думаю что кстати одна из причин почему вот эти монстры типа Хибернейта люди просто ненавидеть в какой-то момент начали и говорить что не я больше не буду потому что ты как раз ничего не понимаешь что там с объектами происходит хм была попытка идентити мап встроить в Active Record рельсовый угадай чем она закончилась я кстати был среди тех кто топил за то что это надо они в какой-то момент сказали: "Идите нахер мы её не будем встраивать" то есть был даже полреквест это сделали а потом как пошли вот эти кейсы
они такие: "Не всем спасибо расходимся" и всё её не встроили туда вот такие дела
хорошо мне кажется как будто вот с моей точки зрения я все остальные основные штуки проговорил которые хотел проговорить у тебя есть ещё какие-то элементы
нет у меня наверное нету дополнительного про Хаски уже слишком много поговорили так что ничего докидывать здесь не буду так что всё
да я знаешь что ожидаю после такого разговора это меня всегда прикалывает приходят ребята из Сишарпа и говорят: "У нас всё это было 10 лет назад у нас есть Линк он всё умеет"
не Линк конечно это классно я согласен абсолютно и да и Entтифреймворк классный вообще у меня тоже вопросов к этому нет но я знаю что люди стити фреймворка уходят и кричат что он задрал так что там тоже есть проблемы и я правда как бы давно с этим не пересекался поэтому не знаю в каком состоянии там сейчас всё ребят напишите довольны ли вы своими фреймворками м ормаами в которых вы работаете выбираете вы то или иное решение кстати не могу не сказать вот этот вот гошники которые ходят и всем рассказывают что у нас такой язык где у Рэмы там принципиально не нужны я буду с вами сражаться до самого конца потому что я не согласен так что выходите на бой кто там хочет про Рэмки и про вот эти все фреймворки поговорить да батл про фрвоки кстати надо сделать да про А вот и но остальные вроде как-то более-менее всего используют давайте тоже об этом разговаривать ребят вам большое всем спасибо что слушали саш тебе спасибо что ты пришёл спасибо что пригласил и спасибо слушателям
да не забывайте подписываться на мой канал Организованное программирование где мы соответственно все эти вещи обсуждаем всем спасибо пока

Creators and Guests

Александр Вершилов
Guest
Александр Вершилов
Разработчик с 15-летним опытом, руководитель отдела разработки в Сириус.Курсах. Приверженец функционального программирования, не боится странных языков вроде Haskell и всегда ищет, как сделать сложное — просто и понятно.
#51 ORM vs SQL — Дебаты: что побеждает в реальных проектах? Александр Вершилов
Broadcast by