Как стать автором
Обновить
3
Карма
0
Рейтинг

Пользователь

  • Подписчики
  • Подписки

Идеальный каталог, базовая библиотека

del хабр чет подвисает, задублировалось

Идеальный каталог, базовая библиотека

В вашем примере заведомо в проигрышной позиции JSONB т.к. для него вы выбрали GIN индекс, тогда как для EAV hash. Если я правильно понял ваш юзкейс.

Я не очень понял ваш тезис про "проигрышную позицию". Я вам процитировал документацию постгри, в которой сказано, что другие индексы для JSONB полезны только для прямого сравнения документов, а не поиска по ним. Если это неверная информация, то мне было бы интересно почитать и про это тоже. В целом меня интересуют оба подхода с самыми эффектиными индексами. Не важно, что это именно будет.

Но опять таки все зависит от исходных задач и профиля нагрузки на БД — серебренной пули не бывает.

Современный PostgreSQL имеет JSONB. Который мне кажется будет предпочтительнее к использованию на текущий момент, чем EAV.

Так все таки JSONB или не бывает? Мой вопрос возник именно потому, что изначальное утверждение было достаточно безапелляционным, поэтому мне стали интересны какие-то подтверждения этого тезиса. Потому что на горизонте есть подобного рода задачи.

Идеальный каталог, базовая библиотека

Jsonb поддерживает не только GIN индексы (btree и hash также поддерживаются).

Тип jsonb также поддерживает индексы btree и hash. Они полезны, только если требуется проверять равенство JSON-документов в целом. Порядок сортировки btree для типа jsonb редко имеет большое значение, но для полноты он приводится ниже:

В вашем вопросе будет сравниваться производительность индекса с индексом без относительно кто был источником данных (EAV или JSONB — не важно).

Именно. В этом и суть вопроса. Но я на него все еще не получил ответ. Есть ли у вас бенчмарки, которые подтверждают ваши тезисы?

Производительность EAV схем всегда была ключевой проблемой.

Современный PostgreSQL имеет JSONB. Который мне кажется будет предпочтительнее к использованию на текущий момент, чем EAV.

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

Идеальный каталог, базовая библиотека

Я знаю, поэтому я и указал в скобках GIN. мой вопрос не про возможность, а про производительность.

Идеальный каталог, базовая библиотека

А есть сравнение производительности поиска по json (через GIN) и поиска в EAV (где, полагаю, достаточно какого-нибудь хеша)? Ну т.е. например задача, найти все сущности у которых не заполнен (отсутствует значение) атрибут X.

Распознавание волейбольного мяча на видео с дрона

Не уверен что найду сходу исходники, статью можно найти здесь

Распознавание волейбольного мяча на видео с дрона

Помимо нейросеток я бы предложил и более «дубовые» подходы, но идея все та же — зная положение мяча на N предыдущих кадрах, можно не пытаться искать его на всем изображении, а искать его в достаточно «ограниченном подходе. Можно почитать на эту тему например вот en.wikipedia.org/wiki/Particle_filter

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

З.Ы Делал диплом, только трекал не мяч, а спортсменов

Хватит организовывать код по типу файлов

en.wikipedia.org/wiki/Java_Classloader
Во всяких сях тоже есть
en.wikipedia.org/wiki/Dynamic_loading#In_C/C++
ну и пхп, да. может еще где-то есть, не знаю

Хватит организовывать код по типу файлов

На самом деле, интерес в том, что если у вас кухня производит борщи 24\7 — то оно так и случится. Просто обывательская кухня этим не занимается в таком режиме, там больше фишек и появляются доп. абстракции, что ложка для борща не просто существует и хранится, а берется из репозитория ложек, который имплементирован в виде ящика на кухне.

Хватит организовывать код по типу файлов

Потому что делать просто DDD в вакууме — сложно. Неплохо его соединять с другими техниками, навроде слоистой архитектуры. и тогда этот Shared (который безусловно нужен) просто отъезжает в правильный слой вместо доменного кода

Хватит организовывать код по типу файлов

На самом деле на большинство этих тезисов уже есть ответ — он называется classloader. Потому что уже сейчас вы можете определить один и тот же класс в пакете локально и в пакете, скажем, из подключаемой библиотеки. Окинуть взглядом конечно в таком случае сложно, но это праблема любой работы с зависимостями. В контроле версий изменения не нужно. В худшем случае решается гитмодулями, в лучшем — нормальным менеджером зависимостей.

В остальных случай класслоадер принимает решения откуда что загрузить, уведомить ли пользователя о конфликте имен и\или классов и тд.

Чистим пхпшный код с помощью DTO

В 5.3.0 эта проблема исправлена


О, вот это уже интересно, спасибо!

Чистим пхпшный код с помощью DTO

Мне еще не довелось близко поработать с этими атрибутами, но что если атрибут уже занят? Судя по коду он может быть только один и там может быть какой-то другой атрибут уже.

Но, впрочем, проблемы вы так и не решили. У вас на каждый аргумент будет вызываться парсинг всего входящего документа

Чистим пхпшный код с помощью DTO

Ну я поэтому и сказал, что штука хорошая, но ограниченная. Тут конечно отдельный вопрос, почему когда один аргумент — штука предназначена, а когда возникло желание добавить второй аргумент — внезапно перестала таким быть, но это уже холивар

Чистим пхпшный код с помощью DTO

А можете какой-то кейс привести


Ну вот вы выше пример написали, он хорош. Но теперь масштабируйте его. Представьте, что у вас в запросе приходит

{"user": {"name": "test", "email": null}, "fruit": {"type": "apple", "color": "red"}}


И сигнатура стала

public function userAction(User $user, Fruit $fruit): void


Т.е. у вас есть прямое сопоставление полей в объекте запроса на параметры контроллера. В этом случае вам надо будет где-то организовать парсинг отдельно от резолвера, ну либо парсить его дважды (трижды, и тд, от числа аргументов), а там могут быть большие документы

Типичная ситуация для работы с каким-нибудь RPC-подобным протоколом. Да, это можно обойти, сделав какой-нибудь UserActionRequestDto и поменяв сигнатуру на

public function userAction(UserActionRequestDto $request): void


Но это уже все менее удобно — нужно писать под каждый контроллер дтошку, больше по сигнатуре не видно с чем он работает и тд.

Чистим пхпшный код с помощью DTO

Чаще всего то, что каждый вызов резолвера независим. И нужно либо делать предварительный парсинг (что в целом сводит на нет всю полезность резолвера, т.к.в этот же момент можно и в реквест заинжектить все что нужно), либо парсить в каждом резолвере (что как бы зачем).

Также резолверы не очень хорошо применимы, когда нужно работать с типизированными массивами, а вариадик применить нельзя (например у вас контроллер принимает два массива в каждом из которых должны лежать инстансы определенного типа. Когда массив один - еще можно обойти эту проблему вариадиком, а когда два - только грустно ждать дженериков и\или хачить аннотациями или создавать типизированные коллекции вместо массивов под каждый кейс.

Чистим пхпшный код с помощью DTO

value resolver — это штука годная только для контроллеров. она хоть и мощная, но ограниченная в возможностях. тот же json ей толком не попарсишь. Сериалайзер\формы — это более универсальный инструмент, но работающий уже после роутинга (что тоже ограничивает их возможности)

PHP Дайджест № 201 (15 – 29 марта 2021)

Не так понял вашу мысль, да, подумал что вы сетуете на хранение реквеста в DI в любом виде. Еще же есть вариант писать стейтлесс приложения, чтобы вся логика получала реквест через аргументы вызова, например (примерно как всяческие middleware), подумал что вы об этом

PHP Дайджест № 201 (15 – 29 марта 2021)

С этим нет никакой проблемы. В контейнере, если прочитать внимательно, лежит не реквест, а реквест стек (реквестов на самом деле уже сейчас в симфоне может быть несколько одновременно, т.к. есть т.н. subrequests для рендера фрагментов, внутренних форвардов и пр.)


В этот самый стек реквест пушится на старте его обработки ядром https://github.com/symfony/http-kernel/blob/5.x/HttpKernel.php#L129
И попается оттуда при завершении его обработки
https://github.com/symfony/http-kernel/blob/5.x/HttpKernel.php#L207


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

PHP Дайджест № 201 (15 – 29 марта 2021)

В симфоне тоже реквест стек лежит в контейнере. Это кажется нормальным. Вопрос не в том, в di или нет, а в том, каким образом оно инициализиуется.
Копнул — да, все фасады работают как синглтоны github.com/laravel/framework/blob/8.x/src/Illuminate/Support/Facades/Facade.php
Т.е. при работе через фасад какой-то реквест будет закэширован в синглтоне

Информация

В рейтинге
4,022-й
Зарегистрирован
Активность