Ну это же халтура! Никому не нужен объект «Запись книжки». Когда ищу по имени, мне нужен список объектов «Абоненты», а когда приходит входящий звонок, отображается карточка объекта «Телефонный номер». Объект «Запись книжки» — лишняя сущность. Да ещё и снабжённая суррогатным ключом.
Прочувствуйте пожалуйста красоту идеи ситуационно-зависимого проецирования набора фактов на объекты, с которыми работает логика и пользователи. С одной стороны зашли — один набор объектов, с другой стороны зашли — другой набор, с третьей — третий. На одних и тех же фактах. Данные в базе хранятся естественным для них образом. Объекты выстраиваются опять же естественным для них, объектов, образом. То, что одно другому один-в-один не соответствует — да и не очень-то хотелось. ORM требует, чтобы соответствовало, и в результате у нас или база кривая, или миллион строк невменяемого кода, или и то, и другое вместе. Ребята, зачем?
Вообще, контрагент — это покупатель ИЛИ продавец. А у Вас "И".
Что касается makemigrations/migrate, то оно по-любому не потянуло бы мою сложную переукладку данных. Всё равно пришлось бы собственно перенос данных рисовать вручную, и делался бы он не групповыми запросами, а пообъектно. То есть в десятки раз дольше. Или сотни.
А в каком виде держать данные в памяти, если вы запретили объекты?
Это где же я запрещал объекты? Более того, я специально акцентировал внимание на том, что они — наша неизбежность.
И как же частичная статическая проверка запросов компилятором и контекстные подсказки от IDE? Избыточно и совсем не нужно?
Это, конечно, вкусно, но честное слово, жить без этого можно. Впрочем, если следовать подходу «объекты как проекции фактов, а в базе факты», то будут вам и проверки компилятором, и подсказки от IDE.
Нет, не построено. В первом приближении класс — это множество, а экземпляр — это элемент. Но если копнуть глубже, начинаются чудеса. Например, оказывается, что у нас с операциями пересечения и объединения множеств? Вот есть, например, два класса — Customer и Vendor. Как их будем объединять и пересекать? Какие-то странные множества. Теория множеств, в которых определена только операция разбиения на подмножества (наследование). Немножко странно всё это.
Об ETL или об автоматическом апдейте структуры базы?
Второе
Вот я, например, пару недель назад учинил рефакторинг структуры базы (очень хотелось разогнать в пару десятков раз). Написание весьма хитрой миграции у меня заняло пару часов. Почему-то уверен, что через ковыряние во всяких миграционных тонких настройках в духе джанговского каталога «migrations» отняло бы гораздо больше времени, сил и нервов, и всё равно в результате не дало бы той стопроцентной уверенности, которую я получил вручную.
Как построить объекты для приведённого издевательского примера про имена и номера телефонов? Объект «запись в книжке» в целом бесполезен. Полезные объекты — Абонент (у которого может быть несколько номеров) и Номер (который может использоваться несколькими абонентами). Ни одна ORM не потянет мэппинг двух классов на одну таблицу.
Вы скажете, что это извращение. Возможно, но в дизайне баз данных ещё и не такие извращения иногда доводится крутить, при этом, что характерно, оставаясь в рамках высочайших стандартов нормализации данных.
Спасибо за интересную ссылочку. Хотя при прочтении этой статьи может возникнуть ложное ощущение, что проблема в том, что технология РБД лет на 40 отстала от прогресса.
Что касается соломенных чучелок, то не очень понимаю, почему Вы увидели только эти Вами перечисленные. Главное чучелко — это то, что невозможно по-настоящему крепко подружить математику и не-математику. ООП, кстати, это совсем даже не плохо. Я этого не говорил. Сам им с удовольствием пользуюсь. Просто не надо его абсолютизировать и возводить в догму. Не годится оно для этого.
безопасность запросов
Инъекции? Ну, не знаю. Как-то совсем давно не вписывал значения в прикладном коде прямо в SQL-строку, отправляемую на сервер. Что с ORM, что без. Как-то сразу приучил себя предохраняться.
оптимизация обращений к СУБД (каскадное конструирование запроса, отложенное выполнение)
Чисто по практике: рефакторинг с отказом от ORM зачастую в разы улучшает производительность именно за счёт более оптимизированной работы с СУБД.
миграции!
А что миграции? Вы о чём? Об ETL или об автоматическом апдейте структуры базы?
С нормализацией в данном случае, что удивительно, всё в порядке. Старая добрая веками прекрасно зарекомендовавшая себя технология бумажного блокнотика.
Несколько записей по одному и тому же имени абонента — нормальная ситуация. Нужно только исключить ситуацию, когда пользователь под именем «Маша» записывает десять разных Маш. Решается на уровне пользовательского интерфейса.
Совершенно верно. Когда я, например, разбираюсь с тем, что там как разложено в NoSQL-базе, всё равно рисую старую добрую ER-диаграмму. Народ сначала смотрит дико, а потом втыкает, что это действительно удобно и наглядно.
В принципе, все технологии программирования, включая ОППшные, замкнуты друг на друга через Тьюринг-полноту. Впрочем, не суть, и Вы, наверно, не об этом.
Сложность убивает, раздели ее на части и ты победишь
но потреяешь системность. То есть поделия будут не системами, а кучками разрозненного мусора. Собрать в единое целое в результате, конечно же, удастся, но только только ценой удесятирения объёма кода.
В статье много про то, какой Продакт умный, красивый, ловкий, коммуникабельный и т.д., и т.п., но совсем не раскрыто, зачем вообще эта штатная единица нужна. Чем ум и красота продакта отличается от ума/красоты проджекта? Тимлида? Эккаунта? Любого другого чего-угодно-менеджера или -лида?
Проблема отделения важного от второстепенного, ИМХО, не имеет решения в общем виде.
Мне кажется, чего сейчас не хватает — это практической энциклопедии, которая бы отталкивалась от «пустого мира». Представьте себе, что вы попали в необитаемый мир, идентичный Земле, но только совсем без цивилизации. Единственное, что у вас есть из нашей цивилизации — это полноценный широкополосный доступ в наш человеческий Интернет. К вечеру захотелось пожрать. Гуглим «как поймать рыбку» и получаем подробные обзоры удочек, лесок и крючков разных производителей, и сразу кучу выгодных предложений заказать это всё в Амазоне и на Али-экспресс. Но у нас нет ни амазона, ни алиэкспресса. У нас вокруг куча разных руд и прочих природных материалов, но мы не знаем, что с этим делать. Мы умеем только заказывать готовый товар с доставкой на дом.
Как опознают железную руду? Какие существуют способы сделать из неё железо? Как превращают песок в стекло? Как хлопок превратить в ткань? И так вплоть до реактивного двигателя, компьютера и смываемой втулки туалетной бумаги.
То есть навернуть уровень абстракции. Как говорится, мы всегда так делаем.
Ну ОК, навернули. Дальше начинается прикольное:
1. Оказывается, вместе с Weapon в JSON полезно закатывать объекты, на которые weapon ссылается. Например, если Damage у нас не общий, а для каждого врага разный (огнемёт лавовому монстру только в радость), то в Weapon у нас массив объектов, в которых Damage и ссылка на тип врага. Кое-что из свойств врага, кстати, тоже оказывается полезно закатать в JSON. Как всегда происходит в подобных случаях, наш новый прекрасный уровень абстракции начинает усложняться, разрастаться, и в результате сам превращается в монстра хуже лавового.
2. Нежданчик. Оказывается, нам нужно иногда генерить разные JSONы. Ну то есть для хранения один, для сайта другой, для отправки в налоговую инспекцию по электронному документообороту третий, для годового отчёта Вельзевулу четвёртый. Будем усложнять уровень абстракции?
Это у нас только JSON. А есть ещё отображение, динамика, печать на бланке, контроль консистентности, репликация и штучки три интеграции с другими системами по ETL (как водится, в обе стороны, и совсем не через JSON). В какой-то момент времени мы титаническими усилиями приходим к тому, что со всем справились. Но тут вдруг возникает необходимость (не «хотелка», а именно суровая необходимость) добавить новую сущность. Какое-нибудь Remedy. По аналогии с Weapon. Мы смотрим, как у нас обвешан загадочными гроздьями мета-штук Weapon и понимаем, что зря пошли в программисты.
Буква «S» в наборе «SOLID» прямым текстом говорит нам, что не должно быть так, чтобы объект сам себя менеджил, провайдил, гетил, сетил, ридил, райтил, валидэйтил, энкодил, декодил, диспетчил. Это бы прямо нарушало принцип «single responsibility». SOLID — святое. Догма. Принимается без дискуссии и включения мозга. Вот и городим зоопарк.
Который является частью… ну да, сертификата.
Странно получается. По сути, файл с расширением «cer» — это публичный ключ. Этот ключ дополнен подписью удостоверяющего центра, которая подтверждает, что бинарные данные ключа соответствуют описательным полям (субъект, мэйл, то-сё). Но самая мякотка, суть и смысл существования этого файла — всё же ключ. Всё остальное, в том числе подпись УЦ — это дополнительные данные разной степени полезности.
Почему же ключ не назвать ключом? Почему мы стабильно запрягаем телегу впереди лошади? Почему допускаем понятийную путаницу?
Когда генерится ключевая пара, мы имеем два ключа — секретный и публичный. Публичный мы можем снабдить сертификатом соответствия. А можем и не снабжать. Можем снабдить, но оформить отдельным файликом. Почему бы и нет? Заливка ключа и сертификата к нему в один файл — это всего лишь один из возможных вариантов. В том же Биткоине, например, асимметричная криптография используется вовсю, но никаких сертификаций там отродясь нет.
Прочувствуйте пожалуйста красоту идеи ситуационно-зависимого проецирования набора фактов на объекты, с которыми работает логика и пользователи. С одной стороны зашли — один набор объектов, с другой стороны зашли — другой набор, с третьей — третий. На одних и тех же фактах. Данные в базе хранятся естественным для них образом. Объекты выстраиваются опять же естественным для них, объектов, образом. То, что одно другому один-в-один не соответствует — да и не очень-то хотелось. ORM требует, чтобы соответствовало, и в результате у нас или база кривая, или миллион строк невменяемого кода, или и то, и другое вместе. Ребята, зачем?
Это какая-то совсем чёрная магия. Для контроля типов и составления контекстной подсказки сгодится, но какое ожидать поведение от таких объектов?
Вообще, контрагент — это покупатель ИЛИ продавец. А у Вас "И".
Что касается makemigrations/migrate, то оно по-любому не потянуло бы мою сложную переукладку данных. Всё равно пришлось бы собственно перенос данных рисовать вручную, и делался бы он не групповыми запросами, а пообъектно. То есть в десятки раз дольше. Или сотни.
Это, конечно, вкусно, но честное слово, жить без этого можно. Впрочем, если следовать подходу «объекты как проекции фактов, а в базе факты», то будут вам и проверки компилятором, и подсказки от IDE.
Вот я, например, пару недель назад учинил рефакторинг структуры базы (очень хотелось разогнать в пару десятков раз). Написание весьма хитрой миграции у меня заняло пару часов. Почему-то уверен, что через ковыряние во всяких миграционных тонких настройках в духе джанговского каталога «migrations» отняло бы гораздо больше времени, сил и нервов, и всё равно в результате не дало бы той стопроцентной уверенности, которую я получил вручную.
Вы скажете, что это извращение. Возможно, но в дизайне баз данных ещё и не такие извращения иногда доводится крутить, при этом, что характерно, оставаясь в рамках высочайших стандартов нормализации данных.
Что касается соломенных чучелок, то не очень понимаю, почему Вы увидели только эти Вами перечисленные. Главное чучелко — это то, что невозможно по-настоящему крепко подружить математику и не-математику. ООП, кстати, это совсем даже не плохо. Я этого не говорил. Сам им с удовольствием пользуюсь. Просто не надо его абсолютизировать и возводить в догму. Не годится оно для этого.
Инъекции? Ну, не знаю. Как-то совсем давно не вписывал значения в прикладном коде прямо в SQL-строку, отправляемую на сервер. Что с ORM, что без. Как-то сразу приучил себя предохраняться.
Чисто по практике: рефакторинг с отказом от ORM зачастую в разы улучшает производительность именно за счёт более оптимизированной работы с СУБД.
А что миграции? Вы о чём? Об ETL или об автоматическом апдейте структуры базы?
Несколько записей по одному и тому же имени абонента — нормальная ситуация. Нужно только исключить ситуацию, когда пользователь под именем «Маша» записывает десять разных Маш. Решается на уровне пользовательского интерфейса.
В статье много про то, какой Продакт умный, красивый, ловкий, коммуникабельный и т.д., и т.п., но совсем не раскрыто, зачем вообще эта штатная единица нужна. Чем ум и красота продакта отличается от ума/красоты проджекта? Тимлида? Эккаунта? Любого другого чего-угодно-менеджера или -лида?
Мне кажется, чего сейчас не хватает — это практической энциклопедии, которая бы отталкивалась от «пустого мира». Представьте себе, что вы попали в необитаемый мир, идентичный Земле, но только совсем без цивилизации. Единственное, что у вас есть из нашей цивилизации — это полноценный широкополосный доступ в наш человеческий Интернет. К вечеру захотелось пожрать. Гуглим «как поймать рыбку» и получаем подробные обзоры удочек, лесок и крючков разных производителей, и сразу кучу выгодных предложений заказать это всё в Амазоне и на Али-экспресс. Но у нас нет ни амазона, ни алиэкспресса. У нас вокруг куча разных руд и прочих природных материалов, но мы не знаем, что с этим делать. Мы умеем только заказывать готовый товар с доставкой на дом.
Как опознают железную руду? Какие существуют способы сделать из неё железо? Как превращают песок в стекло? Как хлопок превратить в ткань? И так вплоть до реактивного двигателя, компьютера и смываемой втулки туалетной бумаги.
Ну ОК, навернули. Дальше начинается прикольное:
1. Оказывается, вместе с Weapon в JSON полезно закатывать объекты, на которые weapon ссылается. Например, если Damage у нас не общий, а для каждого врага разный (огнемёт лавовому монстру только в радость), то в Weapon у нас массив объектов, в которых Damage и ссылка на тип врага. Кое-что из свойств врага, кстати, тоже оказывается полезно закатать в JSON. Как всегда происходит в подобных случаях, наш новый прекрасный уровень абстракции начинает усложняться, разрастаться, и в результате сам превращается в монстра хуже лавового.
2. Нежданчик. Оказывается, нам нужно иногда генерить разные JSONы. Ну то есть для хранения один, для сайта другой, для отправки в налоговую инспекцию по электронному документообороту третий, для годового отчёта Вельзевулу четвёртый. Будем усложнять уровень абстракции?
Это у нас только JSON. А есть ещё отображение, динамика, печать на бланке, контроль консистентности, репликация и штучки три интеграции с другими системами по ETL (как водится, в обе стороны, и совсем не через JSON). В какой-то момент времени мы титаническими усилиями приходим к тому, что со всем справились. Но тут вдруг возникает необходимость (не «хотелка», а именно суровая необходимость) добавить новую сущность. Какое-нибудь Remedy. По аналогии с Weapon. Мы смотрим, как у нас обвешан загадочными гроздьями мета-штук Weapon и понимаем, что зря пошли в программисты.
Странно получается. По сути, файл с расширением «cer» — это публичный ключ. Этот ключ дополнен подписью удостоверяющего центра, которая подтверждает, что бинарные данные ключа соответствуют описательным полям (субъект, мэйл, то-сё). Но самая мякотка, суть и смысл существования этого файла — всё же ключ. Всё остальное, в том числе подпись УЦ — это дополнительные данные разной степени полезности.
Почему же ключ не назвать ключом? Почему мы стабильно запрягаем телегу впереди лошади? Почему допускаем понятийную путаницу?
Когда генерится ключевая пара, мы имеем два ключа — секретный и публичный. Публичный мы можем снабдить сертификатом соответствия. А можем и не снабжать. Можем снабдить, но оформить отдельным файликом. Почему бы и нет? Заливка ключа и сертификата к нему в один файл — это всего лишь один из возможных вариантов. В том же Биткоине, например, асимметричная криптография используется вовсю, но никаких сертификаций там отродясь нет.