Database First! О распространённых ошибках использования РСУБД / Николай Самохвалов (Postila)

Sdílet
Vložit
  • čas přidán 15. 01. 2018
  • Приглашаем на конференцию Saint HighLoad++ 2024, которая пройдет 24 и 25 июня в Санкт-Петербурге!
    Программа, подробности и билеты по ссылке: vk.cc/cuyIqx
    --------
    --------
    РИТ++ 2017, HighLoad Junior
    Тезисы:
    junior.highload.ru/2017/abstra...
    Любой Full Stack Developer сегодня обязан иметь в своём арсенале опыт и умение работы хотя бы с одной популярной РСУБД. Но без понимания основ - того, какие задачи решают СУБД, как происходит работа с данными, какие есть базовые возможности для этой работы, - такие умения превращаются в воздушный замок, быстро разрушающийся при росте проекта.
    Этот доклад - попытка разбудить интерес слушателей к тщательному изучению основ теории и практики реляционных баз данных и к применению всей мощи РСУБД по прямому назначению.
    ...

Komentáře • 34

  • @alzasr
    @alzasr Před 4 lety +23

    Спасибо за доклад. Моё мнение:
    Согласен с тезисом "проверки должны быть как можно ближе к данным", но не согласен что все проверки должны быть в СУБД. Валидация данных - это часть бизнес логики, получается что бизнес логика размазывается с application layer на СУБД. Это минус, поскольку теперь бизнес логика находится ещё в одном месте, а она должна находится как можно более кучно.
    Кроме того, структура БД не версионируется, для версионирования приходится писать миграции с откатом. И если для структуры данных более менее всё понятно и уже устаканилось, то для хранимок и валидаторов всё сложнее. Усложняется переключение между разными версиями проекта.
    Любые проверки, независимо где они находятся, это процессорное время и память. Application layer масштабируется на раз, а DB layer, особенно мастернода, значительно сложнее (про это был последний вопрос, но из-за акцента на CSV докладчик не ответил на него).
    На многих слайдах, когда необходимо реализовать дополнительную функциональность (например админку), рисуется схема с прямым доступам к СУБД из допфункциональности, но ведь можно сделать программную прослойку с API, которая будет оперировать бизнес сущностями, таким образом изолировав потребителя от реализации хранения данных.
    Для реализации логики в СУБД нужно знать особенности СУБД, т.е. повышается требования к скилам программиста.
    Утверждение, что SQL легко читаем - ложно, много раз встречал десятиэтажные SQL запросы с подзапросами, которые очень сложно было понять, SQL - это язык, на нём можно писать ясно, а можно запутанно.
    Утверждение "db first" (сначала попробуй сделать на СУБД) это из лагеря DBA, если смотреть продукт в целом, нужно находить баланс. Переносить логику в СУБД нужно тогда, когда это оправдано. Ясно что реализовывать уникальные ключи средствами application layer неэффективно. Но и проверять что пользователь использует "достаточно сложный пароль" в СУБД не стоит. О переносе агрегации и фильтрации данных в СУБД решать нужно в каждом частном случае, ведь можно ускорить отдельный клиентский запрос (речь не про SQL запрос, а запрос в терминах бизнес задачи), но затормозить всю систему в целом.

    • @Ipat639
      @Ipat639 Před rokem

      Этот коммент информативнее чем сам доклад😂,
      Добавлю ещё что докладчик предложил использовать адрес эл.почты в качестве первичного ключа, я с этим категорично не согласен, не учитывается возможный процесс где пользователь может свою эл.почту поменять. Первичные ключи всётаки должны быть абстрагированны от сущностей.
      Автору надо было сделать больший упор на 3нф и прочее

    • @DemiGoodUA
      @DemiGoodUA Před 11 měsíci +1

      @@Ipat639 так же не понял любви автора к вещественным праймери ключам, ведь то что сегодня уникально завтра уже нет, прогнозировать развитие продукта наперед мы не можем

  • @denis-suleimanov
    @denis-suleimanov Před 6 lety +39

    Когда пошли примеры - запись отвратная. На экране не видно ничего, сплошной засвет, а переключить вид на сплитскрин монтажник видать не догадался.

    • @NikolaySamokhvalov
      @NikolaySamokhvalov Před 6 lety +6

      да, не очень вышло местами. вот слайды: www.dropbox.com/s/y0h6toonhpbd11h/DatabaseFirst_RIT_HLj_Samokhvalov.pdf?dl=0

    • @denis-suleimanov
      @denis-suleimanov Před 6 lety

      Благодарю. Если можно, то задам вопрос: Вы в докладе несколько раз упоминаете хранимки, и, насколько я понял вашу философию отношения к БД и СУБД, хранимки это хорошо, это нужно юзать. Но ведь с ними столько проблем: от разделения логики между приложением и БД до версионирования и тестирования. Может быть посоветуете какие-то best practice как готовить хранимки? (Постгрес в приоритете)

    • @NikolaySamokhvalov
      @NikolaySamokhvalov Před 6 lety +9

      Конечно. Xранимки - НЕ ЗЛО.
      Злом их принято считать традиционно, потому что они в некоторых популярных опенсорсных СУБД работали очень плохо.
      По вашим вопросам. Я пока вижу два пункта, про разделение логики и про «готовку» (версионировение, тестирование)
      1) дело в том, что часть логики давно «перетащил» на себя фронтэнд (клиент стал толстым - мобилки, реакт и т.д.).
      Выходит, что всё равно приходится «париться» и разделять бизнес-логику. Толстого апп-слоя в архитектуре давно уже не существует как класса, это всё осталось в девяностых и нулевых. Так вот, мой тезис в том, что если вы заберёте всё, что можно забрать из так называемой «бизнес-логики» на фронт, то очень большой кусок из того, что остаётся, - это типичные задачи для СУБД. Валидация данных, поддержка их в согласованном виде и тд.
      В некоторых случаях можно пойти дальше и прибить (или почти прибить) app layer, раздербанив бизнес-логику на две части. Одна ушла во фронт (тут и спорить нечего, т.к. все так уже делают и кучу всего напридумывали, чтобы UX был лучше), а другую можно смело делать в самом Постгресе. SQL превосходен для работы с данными! Реально, в некоторых случаях вместо команды рубистов можно обойтись силами одного инженера с хорошим знанием SQL -- ставите PostgREST и всё делаете на хранимках, выходит быстро и качественно. API готов, можно сосредоточиться на приложении. Об этом я рассказывал на РИТ 2016, кстати.
      2) Версионирование (принято называть "миграциями схемы БД"). Этому много уделено внимания было на наших встречах #RuPostgres. Посмотрите видео в канале RuPostgres, там была встреча в ЛАНИТ про liquibase и в Яндексе про их систему миграций.
      Сам использую sqitch.org и очень рекомендую. Легко встроить в любой стек.
      У рельсов ок использовать встроенную систему, с некоторыми оговорками.
      Насчёт тестирования. В sqitch встроены базовые возможности (verify-скрипты, см. доки на сайте, есть примеры). Я обычно делаю кучу тестов с помощью анонимных plpgsql-конструкций (do $$ blabla $$ language plpgsql;).
      Ещё есть целый фреймворк pgTap, автор тот же, что и у sqitch.
      Есть ещё куча вариантов писать миграции для БД.
      На хранимках уже тыщу лет работает скайп (мы авторов, кстати, привозили ещё году в 2008 на Highload, можно поискать материалы), и Яндекс.Почта мигрировала с Оракла на Постгрес очень успешно (см. доклады на #RuPostgres и PgCon), опять же во многом благодаря хранимкам и pl/proxy.

    • @denis-suleimanov
      @denis-suleimanov Před 6 lety

      Благодарю за столь развернутый ответ.

  • @NikolaySamokhvalov
    @NikolaySamokhvalov Před 6 lety +11

    Спасибо за отзывы, вопросы и плюсики! Слайды, если надо: www.dropbox.com/s/y0h6toonhpbd11h/DatabaseFirst_RIT_HLj_Samokhvalov.pdf?dl=1

    • @NikolaySamokhvalov
      @NikolaySamokhvalov Před rokem

      Upd: docs.google.com/presentation/d/1rlNNFy-p-mlbJr3NJcFLMmJ0C81VE99kA_SZvJNFq5s/edit

  • @hakooplayplay3212
    @hakooplayplay3212 Před 3 lety +2

    мда... сначала когда были просто списки которые проговаривал автор - показывали слайды, а как пошли примеры кода - нет... где логика?

  • @GlebWritesCode
    @GlebWritesCode Před 4 lety

    Интересный подход. Какие проекты применяют его на практике?

  • @wolazant
    @wolazant Před 6 lety

    Николай упоминал в докладе pdf'ку на 200 страниц, видимо с презентацией, где её можно посмотреть?

    • @NikolaySamokhvalov
      @NikolaySamokhvalov Před 6 lety

      а не напомните контекст?

    • @NikolaySamokhvalov
      @NikolaySamokhvalov Před 5 lety +1

      www.slideshare.net/samokhvalov/database-first,
      www.pgcon.org/2013/schedule/attachments/269_tour-of-postgresql-data-types.pdf
      andreas.scherbaum.la/writings/Tour_de_Data_Types_-_FOSDEM_2017.pdf

  • @michaelpetrov4965
    @michaelpetrov4965 Před 3 lety +1

    Доклад интересный, хоть и не со всем согласен. Но показывать оратора, когда обсуждают код на слайдах - минус.

  • @coraxster
    @coraxster Před 6 lety +3

    Как этот sql на 50 строк тестировать?

    • @NikolaySamokhvalov
      @NikolaySamokhvalov Před 6 lety +3

      Как обычно, в CI.
      pgTap,
      sqitch / verify,
      анонимные конструкции do $$ ... $$ language plpgsql, в них используйте assert с продуманными сообщениями.

  • @asvitin
    @asvitin Před 6 lety +2

    Хорошее выступление. Спасибо.
    Есть некоторые
    1)
    Предлагаемое решение второго примера может быть получше
    WITH ordered_weather AS (
    SELECT id
    , year
    , month
    , created
    , weather_is_fine
    , MIN(created) OVER(PARTITION BY year, month) AS min_created
    , ROW_NUMBER() OVER(PARTITION BY year, month ORDER BY id DESC) AS rn
    FROM Moscow_weather
    )
    SELECT id
    , year
    , month
    , min_created AS created
    , weather_is_fine
    FROM ordered_weather
    WHERE rn = 1;
    2) На мой вгляд проверки должны быть не только возле слоя хранения данных. Должно быть 3 уровня проверок.
    2.1 Простые на самом раннем этапе(как можно ближе к входным параметрам)
    2.2 Любые по сложности во время обработке на среднем слое. В простых случаях их можно не реализовывать
    2.3 Не сложные в виде ограничений целостности на уровне БД возле самих данных. Триггера нельзя применять(ибо это одно из самых больших бед в БД), т.е. сложные проверки отметаются. Им только на среднем слое место.

    • @NikolaySamokhvalov
      @NikolaySamokhvalov Před 6 lety +1

      Спасибо за отзыв!
      По пунктам. С первым согласен - да, оконными функциями в данном случае получается лаконичнее, чем плясками с массивами!
      Со вторым - ну что тут скажешь, основную мысль доклада, выходит, не полностью донёс.
      "Триггера нельзя применять(ибо это одно из самых больших бед в БД)" - это заблуждение. Расскажите это тем, кто пишет какие-нибудь серьёзные вещи. Например, АБСки (банковские системы).

    • @asvitin
      @asvitin Před 6 lety

      Николай, благодарю за ответ!
      Мне кажется, что я писал достаточно серьезные вещи (работал с базами крупнейшего сотового оператора СНГ и крупнейшего ритейлера России), в высоконагруженной среде и достаточно большими объемами данных(100 Тб+).
      Как-то я занимался детальным анализом производительности системы, в которой на ключевой сущности, состоящей из мастер таблицы и таблицы деталей(100+ млд строк), сумарно было создано около 50 триггеров, некоторые из которых по 1500+ строк кода. Помимо анализа кода, профилировки, трассировки, я делал различные эксперементы замеряя на сколько меняется производительность типовых операций с таблицами от наличия индесков, контрейнтов и триггеров. Триггеры - вне конкуренции по влиянию на производительность.
      На низком уровне, даже идеально написанные построчные Триггера вынуждены проводить для каждой строки некоторое перключение контекста выполнения(проверял на Оракле, но я не представляю как эту особенность обойти), это значительно сокращает производительность batch обработки(наподобие INSERT SELECT, UPDATE многих строк, MERGE, DELETE многих строк). Ситуация становиться хуже, если триггера не идеально написаны.
      Я вкусил триггерный ад по полной и, думаю, что представляю, о чем говорю.
      Некоторые мои коллеги пришли из банкоской сферы(разрабатывали АБС) и их мнение полностью совпадало с моим по поводу триггеров.
      Я всецело поддерживаю наличие слоя храннимых процедур, где идеально размещать логику работы с (большими) масивами данных, и инкапулировать обращения к БД, скрывая детали реализации. Я полностью "за" наличие как можно большего числа ограничений целостноти на БД (они не только данные выверяют, но и помогают оптимизатору), но вот с триггерами ни как не могу подружиться.
      Извиняюсь, за дискуссию. Но именно в ней, вроде как, должна зарождаться истина. :)
      Еще раз спасибо за выступление!

    • @NikolaySamokhvalov
      @NikolaySamokhvalov Před 6 lety

      Алексей Свитин «Как-то я занимался детальным анализом производительности системы...» А как именно вы оценивали вклад триггеров? Интересно, что с чем сравнивали

    • @asvitin
      @asvitin Před 6 lety

      1. Трассировка. По трейсам видно сколько времени уходит на выполнение тех или иных запросов в рамках триггеров, а сколько на саму операцию модификации строки. Анализировал трейсы через OraSRP.
      2. Профилировка. По ней можно понять сколько времени каждая строка PL/SQL кода выполнялась. Имея итоговое время выполнения запроса можно посчитать влияние триггера. Использовал самописные запросы для анализа HProfiler таблиц. Ничего нормального в сети на тот момент не нашел.
      3. Созавал много копий идентичных структур с одинаковым набором данных. Затем накидывал FK, индексы, констренты, триггера в разных комбинациях на эти копии. И проводил тесты построчной вставки (с включенной и выключенной FOR оптимизацией), BULK вставки, обновлений и удалений. Но основной упор был на вставку, так как там основная логика.
      Разница с триггерами и без была настолько огромной, что сама операция размещения стоки в таблице составляла ничтожную долю процента относительно общего времени выполнения.
      Если бы вместо триггеров использовалась пакетная обработка(вставка идет именно блоками данных) через хранимки( у того же Оракла с этим все очень хорошо), и логика была бы разделена( а не смешана в триггеры на все случаи жизни) то по моему скромному мнению, производительность была значительно выше. Но уйти от триггеров, когда их много и основная логика в них , это очень сложная задача.

    • @NikolaySamokhvalov
      @NikolaySamokhvalov Před 6 lety

      Ну надо смотреть, конечно, что конкретно в тех триггерах было. На мой взгляд, метка «триггеры=зло» это то же самое, что и «транзакции=зло». Давайте переформулируем. «Длинные транзакции - зло» и «долгие триггеры - зло».
      Интересно, конечно, какой оверхед на инсёрт даёт триггер-пустышка в Оракле. Для постгреса я по-быстрому проверил, вышло в районе 6%:
      Ок, у нас есть некоторый триггер, который что-то делает с данными. 6% оверхед на то, что он просто существует. Плюс какой-то (скорее всего бОльший) оверхед, если он что-то ещё и по правде делает. Конечно, особенно, если при этом участвуют другие таблицы.
      Теперь мысленно представим, что мы делаем то же самое, но на уровне приложения. Вот тут кроится забавное - очень часто разработчики делают операции с данными намного менее оптимально, чем если бы это было в триггере. СУБД относительно мало что стоит прогуляться за данными в какой-нибудь индекс. Или пересчитать данные у себя. В случае слоя приложения очего легко наступить на грабли сетевой сложности.
      Мой основной тезис в том, что надо сначала рассматривать работу ближе к данным. Нет, не всегда. Но ОЧЕНЬ часто. Нужно анализировать, конечно. Кроме того, если вам нужно быстро провести транзакцию, ну закиньте задание в отдельную таблицу и разгребайте её асинхронно (с помощью "select ... for update skip locked" это делается очень эффективно в несколько потоков). Асинхронные транзакции в Оракле тоже помогают такие схемы иметь, а сегодня вот в Постгрес 11 закоммитили (ура!) www.postgresql.org/message-id/E1edcRB-0004zs-B6@gemulon.postgresql.org
      И ещё. Вы правильно отмечаете, что часто нужно батчами работу вести для эффективности. Верно. Только это ж никак не конфликтует с работой на стороне СУБД и триггерами. Наоборот. Для этого есть statement-based triggers, правда, работать с ними можно стало нормально только недавно, с 10ки, когда добавили transition tables www.depesz.com/2017/06/02/waiting-for-postgresql-10-implement-syntax-for-transition-tables-in-after-triggers/
      > Если бы вместо триггеров использовалась пакетная обработка
      похоже, на это ответил предыдущим абзацем
      > и логика была бы разделена( а не смешана в триггеры на все случаи жизни)
      а вот тут не очень понимаю. Наверное, речь про пакеты ? Это, конечно, очень многие просят - на юзервойсе тема номер 1 postgresql.uservoice.com/forums/21853-general

  • @rogozhka-racing
    @rogozhka-racing Před 6 lety +10

    Нежелание паковать логику в БД не от недоверия и не потому что MySQL плохой, а потому, что архитектура в вебе может измениться моментально(в т.ч. от нагрузки изменившейся на 2 порядка) и слоника придется попросить на выход, как бы хорошо не справлялся с целостностью данных. На замену кластер из микросервисов с логикой в коде нормальных языков, с покрытием тестами и дебагом, а не логикой в суррогатных языках хранимок и ограничений таблиц.

    • @NikolaySamokhvalov
      @NikolaySamokhvalov Před 6 lety +2

      Всё смешалось. Написано почти без грамматических ошибок, но логика не прослеживается, какой-то клубок мыслей.
      Кто сказал, что между целостностью и микросервисами надо выбирать что-то одно? Смотрите на опыт Zalando, было много на Highload. Кстати, советовать всем подряд микросервисную архитектуру - медвежья услуга, послушайте внимательно тех же Zalando.
      Далее, кто сказал, что тестами не нужно покрывать хранимки? Sqitch, pgTap или же любой ваш любимый фреймворк + анонимный plpgsql-код (do $$ ... $$ language plpgsql) и всё уезжает в CI.
      Дебаг - есть дебаггер для pl/pgsql, но честно, когда вы последний раз пользовались именно дебаггером, а не принтлайнингом для вашего любимого python/ruby/java/php?
      Строгая схема (там, где есть возможность её задать), ограничения целостности и хранимки - не враги, а помощники для быстрорастущего проекта.

  • @user-fr5tt6cu4q
    @user-fr5tt6cu4q Před 2 lety +2

    Просто у многих на sql мозгов не хватает. Когда у тебя 10и этажные запросы, в голове очень сложно уложить такие выборки. И начинается всякая хрень типа Орм, nosql и прочей дичи

  • @Ipat639
    @Ipat639 Před rokem

    Так вот кто сделал МирТесен из которого невозможно выйти и заспамил почту, прям жесть была, не делайте так)

  • @vladimirgrishin290
    @vladimirgrishin290 Před 4 lety

    масиквел!

  • @02krysnik
    @02krysnik Před rokem

    русский Ричард Хендрикс )

  • @troepolik
    @troepolik Před 4 lety +3

    какие-то баяны нарассказывал...