Pull to refresh
25
0

.NET — разработчик

Send message

Звучит как то... По-работодательски?;-)

Боже, это прекрасно. Скорее в новости!

КЛАДР/ФИАС туда же добавьте

О, одноразовые коды! Это ещё более надёжно, да!
Ну, otp можно генерить и на компе, и на специальном токене. Всяко лучше чем смс.

Не факт. Специально для вас только что погонял бенчмарк на той же модели и получил такой результат:


AsSplitQuery    2   3.814 ms    0.3040 ms   0.8917 ms
CustomQueries   2   3.803 ms    0.1896 ms   0.5441 ms
AsSplitQuery    5   3.934 ms    0.2411 ms   0.7070 ms
CustomQueries   5   3.784 ms    0.1974 ms   0.5758 ms
AsSplitQuery    10  3.952 ms    0.2094 ms   0.5941 ms
CustomQueries   10  4.531 ms    0.2756 ms   0.8083 ms
AsSplitQuery    100 6.610 ms    0.2997 ms   0.8696 ms
CustomQueries   100 6.751 ms    0.3558 ms   1.0492 ms

Разница на уровне статистической погрешности.
Вторая колонка — количество элементов во вложенной коллекции

В ef core так тоже можно! Видимо SQL получится таким же, кроме случаев когда выбирается коллекция родительских элементов, тут нас догонит проблема N+1

Не всегда, иногда удобно выделить базовую абстракцию и потом подсовывать в нее разные IQueryable<>. Это отлично работает для атомарных сущностей или вытаскивания "целиком".
Для вытаскивания проекции — безусловно лучше наклепать отдельный метод, чтобы не тащить лишку. Но тут вопрос альтернативной стоимости — что будет в итоге проще поддерживать.

Более надёжный чем смс — TOTP.
Смс только как fallback. К сожалению, смски до сих пор считают надёжным вторым фактором.

Безусловно вы правы.
Давайте рассмотрим pros-contras этого решения?
Contras:


  • Невозможно обеспечить целостность данных там где это критично. Транзакция будет существовать только в своём контексте
  • Ещё один мультипликатор в расчёт степени параллелилизма. То есть до этого были параллельные запросы от одного пользователя, несколько пользователей одновременно, так еще и бэкенд сам генерирует параллельные запросы к БД на каждый единичный входящий запрос.
  • Кастомный код репозитория под каждую сущность. То есть даже CRUD надо писать ручками.

Pros:


  • быстрее не больше чем на выполнение базового запроса выборки из родительской таблицы.

Какое применение у такого подхода может быть? Ну что-то где критически важна латентность, где данные нужны максимально быстро и при этом есть гарантия не положить контроллер диска и не заткнуть СУБД. А нужна ли в таком случае РСУБД как первичный источник данных? Может посмотреть на что-то не реляционное и in-memory? Redis, например.


Буст с 34 секунд до 5,5 мс уже неплох, параллельные запросы дадут еще -1-2 мс, но читаемость и поддерживаемость кода будут куда хуже.

На здоровье!
Да, второй запрос без JOIN действительно отработает быстрее, чем запрос с JOIN, хотя есть у меня подозрения, что умный оптимизатор сведет разницу на нет.
Тут другой момент, кроме того что код становится жутко не типовым и требует дополнительных приседаний (см. ниже), его можно запустить параллельно только если мы знаем ID, по которому и сделали бы JOIN. А это не всегда так на момент начала выполнения запроса. Что если мы выбираем не по условию p.id = 42, а по условию p.rank > 100500? В этом случае никакой параллельности и без JOIN-ов мы не получим.


Про приседания. Пусть у нас этих сущностей не 2 и не 8 (как в бенчмарке), а 100? При этом у каждой своя структура, свои коллекции. Пока не представляю, как можно написать простой шаблонный репозиторий, в который мы бы подкладывали только IQueryable<>. Тут и утонуть можно.


Что касается параллельного создания контекстов — операция не совсем бесплатная, это дополнительный коннект к БД. Не проводил измерений, но сдаётся мне создание нового коннекта обходится недёшево, иначе зачем бы их пулировать? Ну и да, много параллельных запросов плохо сказываются на работоспособности СХД, можно очень сильно заткнуть очередь диска.


Не говорю, что split queries — серебряная пуля, но решение красивое и здорово, что оно теперь внутри EF Core.

Если навигационные свойства не загружать принудительно при помощи Include() и не обращаться к ним, то они и не будут загружаться из БД. Когда полученная DAL модель не используется целиком, а только некоторая ее проекция (например родительская сущность + 1 вложенная коллекция), остальные вложенные коллекции не вычитываются из БД.


Лучше — это выбрать именно по c.parentpostid и заполнить коллекцию уже в памяти приложения? Да, вы правы это будет ЕЩЁ быстрее. Но те крошки которые мы соберем в этом случае имеют trade off — сильно сложный и разветвлённый код на DAL слое.


Выполнить 2 запроса параллельно в ef core нельзя, DbContext не потокобезопасный. Насколько я помню он даже select не позволяет выполнить пока не закончится предыдущий запрос. Технически можно было бы создать новый и выполнить второй запрос из него, но опять же — очень сильные приседания, с неизвестным результатом. Когда будет задача ловить миллисекунды — обязательно попробуем :-)

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

С какими? При каких условиях? В каком количестве?

Потому что в лесу вам не получится показать рекламу на карте. Пользуйтесь OSM, будьте свободным!
Я тоже этого каждый раз опасаюсь, а потом оказывается, что в жизни реально нужно 5-10 специальных методов в 20% репозиториев в проекте.
Иногда надо просто принять что, набор данных на 100 записей из 5-7 полей лучше отфильтровать на слое бизнес-логики, а не пытаться сделать все в БД и получать дырявые абстракции. Но тут конечно, надо быть осторожным. Такие таблицы иногда могут вырасти)

В общем золотой пули нет, и каждый раз надо смотреть на баланс трудозатрат на разработку, тестирование и поддержку «красивого решения» и профита которое оно даст.
Никак.
И не надо. Только поисковую выдачу захламляет.

Цифры в смсках — не настоящая 2ФА. Посмотрите на технологии TOTP и HOTP.

Кризис в фудтехе. Пиццы стали едой богачей...

Для создания мотивации ещё и штрафовать тех, кто провалил "учения". Можно даже "тренеров" взять на аутсорс.

Information

Rating
Does not participate
Registered
Activity

Specialization

Backend Developer
Lead
C#